diff --git a/DEPS b/DEPS index 643a3bc..11ccddb4 100644 --- a/DEPS +++ b/DEPS
@@ -162,11 +162,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '7c47d41067d485f90171999dc3845f5b5dc069de', + 'skia_revision': '578c88f047ec70174bc1ea8ebcb39ce7819478aa', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '4189eaead251db2cdfe66608bbde727e8214f6f0', + 'v8_revision': '3fe6946dbcba1f55acbb2771da585c25d85e14e6', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -174,11 +174,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '8ac49e182aa03e90fd11c925b3e1018cf3652e0a', + 'angle_revision': '916720b02c7640894b4597fb84a8ef50bbd38315', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': '5a5ffe52a944a4068f2297ec404b7b5e9a9b9e03', + 'swiftshader_revision': 'd94d6a3d11038ee4e6a963cfb8c4d18468be3bde', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -281,7 +281,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'spv_tools_revision': 'c0e9807094ef6e345ef0a4d5f17af81af063cd27', + 'spv_tools_revision': 'ad7f2c5c4c7f51360e9e079109a9217aa5ba5cc0', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -867,7 +867,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '0e85f633c7c4364f4d616e9e13dce2c9a9dd518e', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '0910f787ebc0fc4b39b9bf9aaf4c980baaca293a', 'src/third_party/devtools-node-modules': Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'), @@ -1414,7 +1414,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'abaae129d9a0c6e1e092067e0b105475df43352e', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '9805913bb53727e37495fe6cea28dcef48c1457a', + Var('webrtc_git') + '/src.git' + '@' + '626f7ff2bb8d75715cefdee986271f90902525ae', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1455,7 +1455,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@e1fb182f7519158cf1f4e08e57e88973c31e763b', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@da5dbc1bca3eea407ef5bbe73c4e741e8db62be3', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/renderer/aw_content_renderer_client.cc b/android_webview/renderer/aw_content_renderer_client.cc index 5bd544e..183aace5 100644 --- a/android_webview/renderer/aw_content_renderer_client.cc +++ b/android_webview/renderer/aw_content_renderer_client.cc
@@ -209,7 +209,6 @@ content::RenderFrame* render_frame, const blink::WebURLError& error, const std::string& http_method, - bool ignoring_cache, std::string* error_html) { std::string err; if (error.reason() == net::ERR_TEMPORARILY_THROTTLED)
diff --git a/android_webview/renderer/aw_content_renderer_client.h b/android_webview/renderer/aw_content_renderer_client.h index a50b394a..8efbe5d 100644 --- a/android_webview/renderer/aw_content_renderer_client.h +++ b/android_webview/renderer/aw_content_renderer_client.h
@@ -42,7 +42,6 @@ void PrepareErrorPage(content::RenderFrame* render_frame, const blink::WebURLError& error, const std::string& http_method, - bool ignoring_cache, std::string* error_html) override; uint64_t VisitedLinkHash(const char* canonical_url, size_t length) override; bool IsLinkVisited(uint64_t link_hash) override;
diff --git a/ash/assistant/assistant_controller.cc b/ash/assistant/assistant_controller.cc index 8f9123c..20398f5 100644 --- a/ash/assistant/assistant_controller.cc +++ b/ash/assistant/assistant_controller.cc
@@ -362,7 +362,7 @@ void AssistantController::BindStateController( mojo::PendingReceiver<mojom::AssistantStateController> receiver) { - assistant_state_controller_.BindRequest(std::move(receiver)); + assistant_state_controller_.BindReceiver(std::move(receiver)); } void AssistantController::BindVolumeControl(
diff --git a/ash/public/cpp/assistant/assistant_state.cc b/ash/public/cpp/assistant/assistant_state.cc index c8e276d..aa8fa85 100644 --- a/ash/public/cpp/assistant/assistant_state.cc +++ b/ash/public/cpp/assistant/assistant_state.cc
@@ -6,6 +6,13 @@ #include <ostream> #include <sstream> +#include <utility> + +#include "ash/public/mojom/assistant_state_controller.mojom.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/receiver_set.h" +#include "mojo/public/cpp/bindings/remote_set.h" namespace ash { namespace { @@ -29,9 +36,9 @@ g_assistant_state = nullptr; } -void AssistantState::BindRequest( - mojom::AssistantStateControllerRequest request) { - bindings_.AddBinding(this, std::move(request)); +void AssistantState::BindReceiver( + mojo::PendingReceiver<mojom::AssistantStateController> receiver) { + receivers_.Add(this, std::move(receiver)); } void AssistantState::NotifyStatusChanged(mojom::AssistantState state) { @@ -39,8 +46,8 @@ return; UpdateAssistantStatus(state); - remote_observers_.ForAllPtrs( - [state](auto* observer) { observer->OnAssistantStatusChanged(state); }); + for (auto& observer : remote_observers_) + observer->OnAssistantStatusChanged(state); } void AssistantState::NotifyFeatureAllowed(mojom::AssistantAllowedState state) { @@ -48,9 +55,8 @@ return; UpdateFeatureAllowedState(state); - remote_observers_.ForAllPtrs([state](auto* observer) { + for (auto& observer : remote_observers_) observer->OnAssistantFeatureAllowedChanged(state); - }); } void AssistantState::NotifyLocaleChanged(const std::string& locale) { @@ -58,8 +64,8 @@ return; UpdateLocale(locale); - remote_observers_.ForAllPtrs( - [locale](auto* observer) { observer->OnLocaleChanged(locale); }); + for (auto& observer : remote_observers_) + observer->OnLocaleChanged(locale); } void AssistantState::NotifyArcPlayStoreEnabledChanged(bool enabled) { @@ -67,9 +73,8 @@ return; UpdateArcPlayStoreEnabled(enabled); - remote_observers_.ForAllPtrs([enabled](auto* observer) { + for (auto& observer : remote_observers_) observer->OnArcPlayStoreEnabledChanged(enabled); - }); } void AssistantState::NotifyLockedFullScreenStateChanged(bool enabled) { @@ -77,16 +82,17 @@ return; UpdateLockedFullScreenState(enabled); - remote_observers_.ForAllPtrs([enabled](auto* observer) { + for (auto& observer : remote_observers_) observer->OnLockedFullScreenStateChanged(enabled); - }); } void AssistantState::AddMojomObserver( - mojom::AssistantStateObserverPtr observer) { - auto* observer_ptr = observer.get(); - remote_observers_.AddPtr(std::move(observer)); - InitializeObserverMojom(observer_ptr); + mojo::PendingRemote<mojom::AssistantStateObserver> pending_observer) { + auto remote = + mojo::Remote<mojom::AssistantStateObserver>(std::move(pending_observer)); + mojom::AssistantStateObserver* observer = remote.get(); + remote_observers_.Add(std::move(remote)); + InitializeObserverMojom(observer); } } // namespace ash
diff --git a/ash/public/cpp/assistant/assistant_state.h b/ash/public/cpp/assistant/assistant_state.h index 60d76e6..e5d702b 100644 --- a/ash/public/cpp/assistant/assistant_state.h +++ b/ash/public/cpp/assistant/assistant_state.h
@@ -10,8 +10,10 @@ #include "ash/public/cpp/assistant/assistant_state_base.h" #include "ash/public/mojom/assistant_state_controller.mojom.h" #include "base/macros.h" -#include "mojo/public/cpp/bindings/binding_set.h" -#include "mojo/public/cpp/bindings/interface_ptr_set.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/receiver_set.h" +#include "mojo/public/cpp/bindings/remote_set.h" namespace ash { @@ -25,7 +27,8 @@ AssistantState(); ~AssistantState() override; - void BindRequest(mojom::AssistantStateControllerRequest request); + void BindReceiver( + mojo::PendingReceiver<mojom::AssistantStateController> receiver); void NotifyStatusChanged(mojom::AssistantState state); void NotifyFeatureAllowed(mojom::AssistantAllowedState state); void NotifyLocaleChanged(const std::string& locale); @@ -33,12 +36,13 @@ void NotifyLockedFullScreenStateChanged(bool enabled); // ash::mojom::AssistantStateController: - void AddMojomObserver(mojom::AssistantStateObserverPtr observer) override; + void AddMojomObserver(mojo::PendingRemote<mojom::AssistantStateObserver> + pending_observer) override; private: - mojo::BindingSet<mojom::AssistantStateController> bindings_; + mojo::ReceiverSet<mojom::AssistantStateController> receivers_; - mojo::InterfacePtrSet<mojom::AssistantStateObserver> remote_observers_; + mojo::RemoteSet<mojom::AssistantStateObserver> remote_observers_; DISALLOW_COPY_AND_ASSIGN(AssistantState); };
diff --git a/ash/public/mojom/assistant_state_controller.mojom b/ash/public/mojom/assistant_state_controller.mojom index 3edb73e..89562b0 100644 --- a/ash/public/mojom/assistant_state_controller.mojom +++ b/ash/public/mojom/assistant_state_controller.mojom
@@ -62,5 +62,5 @@ // which notifies changes of Assistant status and settings. interface AssistantStateController { // Add an observer. - AddMojomObserver(AssistantStateObserver observer); + AddMojomObserver(pending_remote<AssistantStateObserver> observer); };
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index f6dd1c8e..f45a10e3 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -8902595185658947296 \ No newline at end of file +8902538642837937216 \ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 92d4dce8..1851a1d 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -8902598355793962064 \ No newline at end of file +8902537788302949008 \ No newline at end of file
diff --git a/chrome/VERSION b/chrome/VERSION index 00057d7..1141254f 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=79 MINOR=0 -BUILD=3910 +BUILD=3911 PATCH=0
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index 1228c4d9..b460078 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -767,7 +767,6 @@ "java/src/org/chromium/chrome/browser/identity/UniqueIdentificationGenerator.java", "java/src/org/chromium/chrome/browser/identity/UniqueIdentificationGeneratorFactory.java", "java/src/org/chromium/chrome/browser/identity/UuidBasedUniqueIdentificationGenerator.java", - "java/src/org/chromium/chrome/browser/incognito/IncognitoDisclosureActivity.java", "java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationManager.java", "java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationService.java", "java/src/org/chromium/chrome/browser/incognito/IncognitoTabHost.java",
diff --git a/chrome/android/chrome_test_java_sources.gni b/chrome/android/chrome_test_java_sources.gni index 006166e..b782775 100644 --- a/chrome/android/chrome_test_java_sources.gni +++ b/chrome/android/chrome_test_java_sources.gni
@@ -110,7 +110,6 @@ "javatests/src/org/chromium/chrome/browser/crash/PureJavaExceptionReporterTest.java", "javatests/src/org/chromium/chrome/browser/crypto/CipherFactoryTest.java", "javatests/src/org/chromium/chrome/browser/customtabs/ClientManagerTest.java", - "javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityIncognitoTest.java", "javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java", "javatests/src/org/chromium/chrome/browser/customtabs/CustomTabExternalNavigationTest.java", "javatests/src/org/chromium/chrome/browser/customtabs/CustomTabFromChromeExternalNavigationTest.java", @@ -195,7 +194,6 @@ "javatests/src/org/chromium/chrome/browser/identity/SettingsSecureBasedIdentificationGeneratorTest.java", "javatests/src/org/chromium/chrome/browser/identity/UniqueIdentificationGeneratorFactoryTest.java", "javatests/src/org/chromium/chrome/browser/identity/UuidBasedUniqueIdentificationGeneratorTest.java", - "javatests/src/org/chromium/chrome/browser/incognito/IncognitoDisclosureDialogAppearanceTest.java", "javatests/src/org/chromium/chrome/browser/incognito/IncognitoNotificationServiceTest.java", "javatests/src/org/chromium/chrome/browser/incognito/IncognitoTabLauncherTest.java", "javatests/src/org/chromium/chrome/browser/infobar/InfoBarAppearanceTest.java",
diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml index d84c2170..0397e82 100644 --- a/chrome/android/java/AndroidManifest.xml +++ b/chrome/android/java/AndroidManifest.xml
@@ -503,11 +503,6 @@ {% endfor %} {% endif %} - <activity android:name="org.chromium.chrome.browser.incognito.IncognitoDisclosureActivity" - android:theme="@style/Theme.Chromium.Activity.Fullscreen.Transparent" - android:exported="false"> - </activity> - <!-- ChromeTabbedActivity related --> <activity android:name="org.chromium.chrome.browser.ChromeTabbedActivity" android:theme="@style/Theme.Chromium.TabbedMode"
diff --git a/chrome/android/java/monochrome_public_bundle__base_bundle_module.AndroidManifest.expected b/chrome/android/java/monochrome_public_bundle__base_bundle_module.AndroidManifest.expected index e5cdbdc3..71cf43bf 100644 --- a/chrome/android/java/monochrome_public_bundle__base_bundle_module.AndroidManifest.expected +++ b/chrome/android/java/monochrome_public_bundle__base_bundle_module.AndroidManifest.expected
@@ -953,10 +953,6 @@ android:name="org.chromium.chrome.browser.browserservices.ClearDataDialogActivity" android:theme="@style/Theme.Chromium.ClearDataDialogActivity"/> <activity - android:exported="false" - android:name="org.chromium.chrome.browser.incognito.IncognitoDisclosureActivity" - android:theme="@style/Theme.Chromium.Activity.Fullscreen.Transparent"/> - <activity android:exported="true" android:name="org.chromium.chrome.browser.browserservices.ManageTrustedWebActivityDataActivity" android:theme="@style/Theme.Chromium.Activity.Fullscreen.Transparent">
diff --git a/chrome/android/java/res/layout/incognito_disclosure_dialog_content.xml b/chrome/android/java/res/layout/incognito_disclosure_dialog_content.xml deleted file mode 100644 index 7f4644d..0000000 --- a/chrome/android/java/res/layout/incognito_disclosure_dialog_content.xml +++ /dev/null
@@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:padding="25dp" - android:orientation="vertical"> - <TextView - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/incognito_disclosure_text" - android:textAppearance="@style/TextAppearance.BlackBodyDefault"/> - <CheckBox - android:id="@+id/incognito_disclosure_close_incognito_checkbox" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginTop="15dp" - android:layout_marginStart="-5dp" - android:text="@string/incognito_disclosure_checkbox_text" - android:textAppearance="@style/TextAppearance.BlackBodyDefault"/> -</LinearLayout> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/sharing_device_picker.xml b/chrome/android/java/res/layout/sharing_device_picker.xml index c16f78a..add0900 100644 --- a/chrome/android/java/res/layout/sharing_device_picker.xml +++ b/chrome/android/java/res/layout/sharing_device_picker.xml
@@ -4,6 +4,7 @@ found in the LICENSE file. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> @@ -55,7 +56,7 @@ android:layout_height="wrap_content" android:layout_width ="match_parent" android:contentDescription="@string/sharing_no_devices_available_text" - android:src="@drawable/shared_clipboard_zero_state"/> + app:srcCompat="@drawable/shared_clipboard_zero_state"/> <TextView android:layout_width="match_parent"
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/AppIndexingUtil.java b/chrome/android/java/src/org/chromium/chrome/browser/AppIndexingUtil.java index 10abb7c..a9d92f7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/AppIndexingUtil.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/AppIndexingUtil.java
@@ -59,7 +59,9 @@ @Override public void onPageLoadFinished(final Tab tab, String url) { extractCopylessPasteMetadata(tab); - getAppIndexingReporter().reportWebPageView(url, tab.getTitle()); + if (!SysUtils.isLowEndDevice()) { + getAppIndexingReporter().reportWebPageView(url, tab.getTitle()); + } } }; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java b/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java index 50bf979..53f9ded 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java
@@ -17,15 +17,10 @@ import android.os.StrictMode; import android.support.annotation.IntDef; -import androidx.browser.customtabs.CustomTabsIntent; -import androidx.browser.customtabs.CustomTabsSessionToken; -import androidx.browser.customtabs.TrustedWebUtils; - import org.chromium.base.ApplicationStatus; import org.chromium.base.CommandLine; import org.chromium.base.ContextUtils; import org.chromium.base.StrictModeContext; -import org.chromium.base.library_loader.LibraryProcessType; import org.chromium.base.metrics.CachedMetrics; import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider.CustomTabsUiType; import org.chromium.chrome.browser.browserservices.SessionDataHolder; @@ -36,13 +31,11 @@ import org.chromium.chrome.browser.customtabs.PaymentHandlerActivity; import org.chromium.chrome.browser.customtabs.SeparateTaskCustomTabActivity; import org.chromium.chrome.browser.firstrun.FirstRunFlowSequencer; -import org.chromium.chrome.browser.incognito.IncognitoDisclosureActivity; import org.chromium.chrome.browser.instantapps.InstantAppsHandler; import org.chromium.chrome.browser.metrics.MediaNotificationUma; import org.chromium.chrome.browser.multiwindow.MultiWindowUtils; import org.chromium.chrome.browser.notifications.NotificationPlatformBridge; import org.chromium.chrome.browser.partnercustomizations.PartnerBrowserCustomizations; -import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.searchwidget.SearchActivity; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.util.FeatureUtilities; @@ -51,7 +44,6 @@ import org.chromium.chrome.browser.vr.VrModuleProvider; import org.chromium.chrome.browser.webapps.ActivityAssigner; import org.chromium.chrome.browser.webapps.WebappLauncherActivity; -import org.chromium.content_public.browser.BrowserStartupController; import org.chromium.ui.widget.Toast; import org.chromium.webapk.lib.client.WebApkValidator; @@ -59,6 +51,10 @@ import java.lang.annotation.RetentionPolicy; import java.util.UUID; +import androidx.browser.customtabs.CustomTabsIntent; +import androidx.browser.customtabs.CustomTabsSessionToken; +import androidx.browser.customtabs.TrustedWebUtils; + /** * Dispatches incoming intents to the appropriate activity based on the current configuration and * Intent fired. @@ -407,20 +403,6 @@ // Create and fire a launch intent. Intent launchIntent = createCustomTabActivityIntent(mActivity, mIntent); - boolean hasOffTheRecordProfile = - BrowserStartupController.get(LibraryProcessType.PROCESS_BROWSER) - .isFullBrowserStarted() - && Profile.getLastUsedProfile().hasOffTheRecordProfile(); - - boolean shouldShowIncognitoDisclosure = - CustomTabIntentDataProvider.isValidExternalIncognitoIntent(launchIntent) - && hasOffTheRecordProfile; - - if (shouldShowIncognitoDisclosure) { - IncognitoDisclosureActivity.launch(mActivity, launchIntent); - return; - } - // Allow disk writes during startActivity() to avoid strict mode violations on some // Samsung devices, see https://crbug.com/796548. try (StrictModeContext ignored = StrictModeContext.allowDiskWrites()) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java index 5ec213b..ada6c10 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
@@ -25,10 +25,8 @@ import android.util.Pair; import android.view.KeyEvent; import android.view.ViewGroup; -import android.view.WindowManager; import org.chromium.base.ApiCompatibilityUtils; -import org.chromium.base.CommandLine; import org.chromium.base.VisibleForTesting; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordUserAction; @@ -37,7 +35,6 @@ import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.ChromeApplication; import org.chromium.chrome.browser.ChromeFeatureList; -import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.KeyboardShortcuts; import org.chromium.chrome.browser.LaunchIntentDispatcher; @@ -59,8 +56,6 @@ import org.chromium.chrome.browser.dependency_injection.ChromeActivityCommonsModule; import org.chromium.chrome.browser.firstrun.FirstRunSignInProcessor; import org.chromium.chrome.browser.gsa.GSAState; -import org.chromium.chrome.browser.incognito.IncognitoTabHost; -import org.chromium.chrome.browser.incognito.IncognitoTabHostRegistry; import org.chromium.chrome.browser.infobar.InfoBarContainer; import org.chromium.chrome.browser.night_mode.NightModeStateProvider; import org.chromium.chrome.browser.night_mode.NightModeUtils; @@ -157,9 +152,6 @@ } }; - @Nullable - private IncognitoTabHost mIncognitoTabHost; - @Override protected Drawable getBackgroundDrawable() { int initialBackgroundColor = mIntentDataProvider.getInitialBackgroundColor(); @@ -212,10 +204,6 @@ mSession = mIntentDataProvider.getSession(); - if (mIntentDataProvider.isIncognito()) { - initializeIncognito(); - } - CustomTabNavigationBarController.updateNavigationBarColor(this, mIntentDataProvider); } @@ -228,17 +216,6 @@ return COLOR_SCHEME_LIGHT; } - private void initializeIncognito() { - mIncognitoTabHost = new IncognitoCustomTabHost(); - IncognitoTabHostRegistry.getInstance().register(mIncognitoTabHost); - - if (!CommandLine.getInstance().hasSwitch( - ChromeSwitches.ENABLE_INCOGNITO_SNAPSHOTS_IN_ANDROID_RECENTS)) { - // Disable taking screenshots and seeing snapshots in recents - getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE); - } - } - @Override public boolean shouldAllocateChildConnection() { return mTabController.shouldAllocateChildConnection(); @@ -369,11 +346,6 @@ @Override protected void onDestroyInternal() { super.onDestroyInternal(); - - if (mIncognitoTabHost != null) { - IncognitoTabHostRegistry.getInstance().unregister(mIncognitoTabHost); - } - if (mTaskDescriptionHelper != null) mTaskDescriptionHelper.destroy(); } @@ -650,23 +622,6 @@ && publisherUrlPackage.equals(mConnection.getClientPackageNameForSession(mSession)); } - private class IncognitoCustomTabHost implements IncognitoTabHost { - - public IncognitoCustomTabHost() { - assert mIntentDataProvider.isIncognito(); - } - - @Override - public boolean hasIncognitoTabs() { - return !isFinishing(); - } - - @Override - public void closeAllIncognitoTabs() { - mNavigationController.finish(CustomTabActivityNavigationController.FinishReason.OTHER); - } - } - @Override protected CustomTabActivityComponent createComponent( ChromeActivityCommonsModule commonsModule) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java index 635db4f..3b4aa41 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
@@ -34,7 +34,6 @@ import androidx.browser.trusted.sharing.ShareData; import androidx.browser.trusted.sharing.ShareTarget; -import org.chromium.base.CommandLine; import org.chromium.base.Log; import org.chromium.base.VisibleForTesting; import org.chromium.base.metrics.RecordUserAction; @@ -42,7 +41,6 @@ import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.ChromeApplication; import org.chromium.chrome.browser.ChromeFeatureList; -import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.ChromeVersionInfo; import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider; @@ -289,7 +287,8 @@ IntentUtils.safeGetIntExtra(intent, EXTRA_UI_TYPE, CustomTabsUiType.DEFAULT); mUiType = verifiedUiType(requestedUiType); - mIsIncognito = isIncognitoForPaymentsFlow(intent) || isValidExternalIncognitoIntent(intent); + // Currently incognito is only supported for payments. + mIsIncognito = isIncognitoForPaymentsFlow(intent); CustomTabColorSchemeParams params = getColorSchemeParams(intent, colorScheme); retrieveCustomButtons(intent, context); @@ -493,36 +492,10 @@ } private boolean isIncognitoForPaymentsFlow(Intent intent) { - return incognitoRequested(intent) && isTrustedIntent() && isOpenedByChrome() - && isForPaymentRequest(); - } - - public static boolean isValidExternalIncognitoIntent(Intent intent) { - if (!CommandLine.getInstance().hasSwitch(ChromeSwitches.ENABLE_INCOGNITO_CUSTOM_TABS)) { - return false; - } - - if (!incognitoRequested(intent)) { - return false; - } - - return isVerifiedFirstPartyIntent(intent) - || CommandLine.getInstance().hasSwitch( - ChromeSwitches.ALLOW_INCOGNITO_CUSTOM_TABS_FROM_THIRD_PARTY); - } - - private static boolean incognitoRequested(Intent intent) { - return IntentUtils.safeGetBooleanExtra( + boolean incognitoRequested = IntentUtils.safeGetBooleanExtra( intent, IntentHandler.EXTRA_OPEN_NEW_INCOGNITO_TAB, false); - } - - private static boolean isVerifiedFirstPartyIntent(Intent intent) { - CustomTabsSessionToken sessionToken = - CustomTabsSessionToken.getSessionTokenFromIntent(intent); - String packageNameFromSession = - CustomTabsConnection.getInstance().getClientPackageNameForSession(sessionToken); - return !TextUtils.isEmpty(packageNameFromSession) - && ExternalAuthUtils.getInstance().isGoogleSigned(packageNameFromSession); + return incognitoRequested && isTrustedIntent() && isOpenedByChrome() + && isForPaymentRequest(); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoDisclosureActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoDisclosureActivity.java deleted file mode 100644 index e4a675f..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoDisclosureActivity.java +++ /dev/null
@@ -1,119 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.incognito; - -import android.content.Context; -import android.content.Intent; -import android.content.res.Resources; -import android.os.Bundle; -import android.support.annotation.Nullable; -import android.support.v7.app.AppCompatActivity; -import android.view.View; -import android.widget.CheckBox; - -import org.chromium.base.task.AsyncTask; -import org.chromium.chrome.R; -import org.chromium.chrome.browser.modaldialog.AppModalPresenter; -import org.chromium.chrome.browser.profiles.Profile; -import org.chromium.ui.modaldialog.ModalDialogManager; -import org.chromium.ui.modaldialog.ModalDialogManager.ModalDialogType; -import org.chromium.ui.modaldialog.ModalDialogProperties; -import org.chromium.ui.modelutil.PropertyModel; - -/** - * Activity that shows a dialog with a warning before opening an incognito Custom Tab when - * incognito tabs are already present. - * If user chooses to proceed, opens the custom tab. - */ -public class IncognitoDisclosureActivity extends AppCompatActivity { - private static final String EXTRA_CUSTOM_TAB_INTENT = "extra_custom_tab_intent"; - - /** Launches the activity */ - public static void launch(Context context, Intent customTabIntent) { - Intent intent = new Intent(context, IncognitoDisclosureActivity.class); - intent.putExtra(EXTRA_CUSTOM_TAB_INTENT, customTabIntent); - context.startActivity(intent); - } - - private boolean mCloseIncognitoTabs; - - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - View contentView = - getLayoutInflater().inflate(R.layout.incognito_disclosure_dialog_content, null); - CheckBox checkBox = - contentView.findViewById(R.id.incognito_disclosure_close_incognito_checkbox); - checkBox.setOnCheckedChangeListener((view, isChecked) -> mCloseIncognitoTabs = isChecked); - - Resources resources = getResources(); - PropertyModel model = new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS) - .with(ModalDialogProperties.CONTROLLER, mDialogController) - .with(ModalDialogProperties.TITLE, resources, - R.string.incognito_disclosure_title) - .with(ModalDialogProperties.CUSTOM_VIEW, contentView) - .with(ModalDialogProperties.POSITIVE_BUTTON_TEXT, resources, - R.string.ok_got_it) - .with(ModalDialogProperties.NEGATIVE_BUTTON_TEXT, resources, - R.string.cancel) - .build(); - - new ModalDialogManager(new AppModalPresenter(this), ModalDialogType.APP) - .showDialog(model, ModalDialogType.APP); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - mOpenCustomTabAfterCleanUpTask.cancel(true); - } - - private void openCustomTabActivity() { - startActivity(getIntent().getParcelableExtra(EXTRA_CUSTOM_TAB_INTENT)); - finish(); - } - - private final ModalDialogProperties.Controller mDialogController = - new ModalDialogProperties.Controller() { - @Override - public void onClick(PropertyModel model, int buttonType) { - if (buttonType == ModalDialogProperties.ButtonType.NEGATIVE) { - finish(); - return; - } - if (mCloseIncognitoTabs) { - mOpenCustomTabAfterCleanUpTask.executeOnExecutor( - AsyncTask.THREAD_POOL_EXECUTOR); - } else { - openCustomTabActivity(); - } - } - - @Override - public void onDismiss(PropertyModel model, int dismissalCause) { - finish(); - } - }; - - private AsyncTask<Void> mOpenCustomTabAfterCleanUpTask = new AsyncTask<Void>() { - @Override - protected void onPreExecute() { - IncognitoUtils.closeAllIncognitoTabs(); - Profile.getLastUsedProfile().getOffTheRecordProfile().destroyWhenAppropriate(); - } - - @Override - protected Void doInBackground() { - IncognitoUtils.deleteIncognitoStateFiles(); - return null; - } - - @Override - protected void onPostExecute(Void result) { - openCustomTabActivity(); - } - }; -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PhotoPickerDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PhotoPickerDialog.java index ac466f21..be18d329 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PhotoPickerDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PhotoPickerDialog.java
@@ -23,7 +23,8 @@ * UI for the photo chooser that shows on the Android platform as a result of * <input type=file accept=image > form element. */ -public class PhotoPickerDialog extends AlertDialog { +public class PhotoPickerDialog + extends AlertDialog implements PhotoPickerToolbar.PhotoPickerToolbarDelegate { // Our context. private Context mContext; @@ -89,7 +90,7 @@ mListenerWrapper = new PhotoPickerListenerWrapper(listener); // Initialize the main content view. - mCategoryView = new PickerCategoryView(context, multiSelectionAllowed); + mCategoryView = new PickerCategoryView(context, multiSelectionAllowed, this); mCategoryView.initialize(this, mListenerWrapper, mimeTypes); setView(mCategoryView); } @@ -119,6 +120,14 @@ } } + /** + * Cancels the dialog in response to a back navigation. + */ + @Override + public void onNavigationBackCallback() { + cancel(); + } + @VisibleForTesting public PickerCategoryView getCategoryViewForTesting() { return mCategoryView;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PhotoPickerToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PhotoPickerToolbar.java index 8ba16f1..3d2be56d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PhotoPickerToolbar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PhotoPickerToolbar.java
@@ -7,11 +7,9 @@ import android.content.Context; import android.util.AttributeSet; import android.widget.Button; -import android.widget.TextView; import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.R; -import org.chromium.chrome.browser.widget.TintedDrawable; import org.chromium.chrome.browser.widget.selection.SelectableListToolbar; import java.util.List; @@ -20,38 +18,64 @@ * Handles toolbar functionality for the Photo Picker class. */ public class PhotoPickerToolbar extends SelectableListToolbar<PickerBitmap> { + /** + * A delegate that handles dialog actions. + */ + public interface PhotoPickerToolbarDelegate { + /** + * Called when the back arrow is clicked in the toolbar. + */ + void onNavigationBackCallback(); + } + + // A delegate to notify when the dialog should close. + PhotoPickerToolbarDelegate mDelegate; + public PhotoPickerToolbar(Context context, AttributeSet attrs) { super(context, attrs); } + /** + * Set the {@PhotoPickerToolbarDelegate} for this toolbar. + */ + public void setDelegate(PhotoPickerToolbarDelegate delegate) { + mDelegate = delegate; + } + + /** + * Shows the Back arrow navigation button in the upper left corner. + */ + public void showBackArrow() { + setNavigationButton(NAVIGATION_BUTTON_BACK); + } + @Override protected void onFinishInflate() { super.onFinishInflate(); - - setNavigationIcon(TintedDrawable.constructTintedDrawable( - getContext(), R.drawable.btn_close, R.color.default_icon_color)); setNavigationContentDescription(R.string.close); - - TextView up = (TextView) mNumberRollView.findViewById(R.id.up); - TextView down = (TextView) mNumberRollView.findViewById(R.id.down); - ApiCompatibilityUtils.setTextAppearance(up, R.style.TextAppearance_BlackHeadline); - ApiCompatibilityUtils.setTextAppearance(down, R.style.TextAppearance_BlackHeadline); } @Override - protected void setNavigationButton(int navigationButton) {} - - @Override - protected void showSelectionView( - List<PickerBitmap> selectedItems, boolean wasSelectionEnabled) { - switchToNumberRollView(selectedItems, wasSelectionEnabled); + public void onNavigationBack() { + super.onNavigationBack(); + mDelegate.onNavigationBackCallback(); } @Override public void onSelectionStateChange(List<PickerBitmap> selectedItems) { super.onSelectionStateChange(selectedItems); + int selectCount = selectedItems.size(); Button done = (Button) findViewById(R.id.done); done.setEnabled(selectedItems.size() > 0); + + if (selectCount > 0) { + ApiCompatibilityUtils.setTextAppearance(done, R.style.TextAppearance_Body_Inverse); + } else { + ApiCompatibilityUtils.setTextAppearance( + done, R.style.TextAppearance_BlackDisabledText3); + + showBackArrow(); + } } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerBitmapView.java b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerBitmapView.java index 3fb92cd..7aa89e4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerBitmapView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerBitmapView.java
@@ -139,8 +139,9 @@ @Override public void onClick() { - if (mBitmapDetails == null) + if (mBitmapDetails == null) { return; // Clicks are disabled until initialize() has been called. + } if (isGalleryTile()) { mCategoryView.showGallery(); @@ -173,6 +174,8 @@ @Override public void onSelectionStateChange(List<PickerBitmap> selectedItems) { + super.onSelectionStateChange(selectedItems); + // If the user cancels the dialog before this object has initialized, // the SelectionDelegate will try to notify us that all selections have // been cleared. However, we don't need to process that message and, in @@ -187,12 +190,6 @@ boolean selected = selectedItems.contains(mBitmapDetails); boolean checked = super.isChecked(); - // In single-selection mode, the list needs to be updated to account for items that were - // checked before but no longer are (because something else was selected). - if (!mCategoryView.isMultiSelectAllowed() && !selected && checked) { - super.toggle(); - } - boolean needsResize = selected != checked; int size = selected && !checked ? mCategoryView.getImageSize() - 2 * mBorder : mCategoryView.getImageSize();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerCategoryView.java b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerCategoryView.java index 6e54850..b8d53814 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerCategoryView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerCategoryView.java
@@ -161,7 +161,8 @@ * @param multiSelectionAllowed Whether to allow the user to select more than one image. */ @SuppressWarnings("unchecked") // mSelectableListLayout - public PickerCategoryView(Context context, boolean multiSelectionAllowed) { + public PickerCategoryView(Context context, boolean multiSelectionAllowed, + PhotoPickerToolbar.PhotoPickerToolbarDelegate delegate) { super(context); mActivity = (ChromeActivity) context; mMultiSelectionAllowed = multiSelectionAllowed; @@ -184,6 +185,8 @@ R.layout.photo_picker_toolbar, mSelectionDelegate, titleId, 0, 0, null, false, false); toolbar.setNavigationOnClickListener(this); + toolbar.setDelegate(delegate); + toolbar.showBackArrow(); Button doneButton = (Button) toolbar.findViewById(R.id.done); doneButton.setOnClickListener(this); mVideoView = findViewById(R.id.video_player);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java index 37077f7..1ae699c8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java
@@ -34,7 +34,7 @@ import org.chromium.components.signin.identitymanager.ClearAccountsAction; import org.chromium.components.signin.identitymanager.CoreAccountInfo; import org.chromium.components.signin.identitymanager.IdentityManager; -import org.chromium.components.signin.identitymanager.PrimaryAccountMutator; +import org.chromium.components.signin.identitymanager.IdentityMutator; import org.chromium.components.signin.metrics.SigninAccessPoint; import org.chromium.components.signin.metrics.SigninReason; import org.chromium.components.signin.metrics.SignoutDelete; @@ -132,6 +132,12 @@ boolean mBlockedOnAccountSeeding; /** + * Contains the full Core account info, which can be retrieved only once account seeding is + * complete + */ + CoreAccountInfo mCoreAccountInfo; + + /** * @param account The account to sign in to. * @param activity Reference to the UI to use for dialogs. Null means forced signin. * @param callback Called when the sign-in process finishes or is cancelled. Can be null. @@ -194,7 +200,7 @@ private final Context mContext; private final AccountTrackerService mAccountTrackerService; private final IdentityManager mIdentityManager; - private final PrimaryAccountMutator mPrimaryAccountMutator; + private final IdentityMutator mIdentityMutator; private final AndroidSyncSettings mAndroidSyncSettings; private final ObserverList<SignInStateObserver> mSignInStateObservers = new ObserverList<>(); private final ObserverList<SignInAllowedObserver> mSignInAllowedObservers = @@ -249,7 +255,7 @@ mNativeSigninManagerAndroid = nativeSigninManagerAndroid; mAccountTrackerService = accountTrackerService; mIdentityManager = identityManager; - mPrimaryAccountMutator = identityManager.getPrimaryAccountMutator(); + mIdentityMutator = identityManager.getIdentityMutator(); mAndroidSyncSettings = androidSyncSettings; mSigninAllowedByPolicy = @@ -465,6 +471,14 @@ Log.w(TAG, "Ignoring sign in progress request as no pending sign in."); return; } + // TODO(crbug.com/1002056) When changing SignIn signature to use CoreAccountInfo, change the + // following line to use it instead of retrieving from IdentityManager. + mSignInState.mCoreAccountInfo = + mIdentityManager.findExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress( + mSignInState.mAccount.name); + + // CoreAccountInfo must be set and valid to progress + assert mSignInState.mCoreAccountInfo != null; if (mSignInState.isActivityInvisible()) { abortSignIn(); @@ -472,7 +486,7 @@ } Log.d(TAG, "Checking if account has policy management enabled"); - fetchAndApplyCloudPolicy(mSignInState.mAccount.name, this::onPolicyFetchedBeforeSignIn); + fetchAndApplyCloudPolicy(mSignInState.mCoreAccountInfo, this::onPolicyFetchedBeforeSignIn); } @VisibleForTesting @@ -486,15 +500,9 @@ private void finishSignIn() { // This method should be called at most once per sign-in flow. - assert mSignInState != null; + assert mSignInState != null && mSignInState.mCoreAccountInfo != null; - // TODO(crbug.com/1002056) When changing SignIn signature to use CoreAccountInfo, change the - // following line to use it instead of retrieving from IdentityManager. - if (!mPrimaryAccountMutator.setPrimaryAccount( - mIdentityManager - .findExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress( - mSignInState.mAccount.name) - .getId())) { + if (!mIdentityMutator.setPrimaryAccount(mSignInState.mCoreAccountInfo.getId())) { Log.w(TAG, "Failed to set the PrimaryAccount in IdentityManager, aborting signin"); abortSignIn(); return; @@ -502,15 +510,16 @@ // Cache the signed-in account name. This must be done after the native call, otherwise // sync tries to start without being signed in natively and crashes. - ChromeSigninController.get().setSignedInAccountName(mSignInState.mAccount.name); - enableSync(mSignInState.mAccount); + ChromeSigninController.get().setSignedInAccountName( + mSignInState.mCoreAccountInfo.getName()); + enableSync(mSignInState.mCoreAccountInfo.getAccount()); if (mSignInState.mCallback != null) { mSignInState.mCallback.onSignInComplete(); } // Trigger token requests via native. - logInSignedInUser(); + mIdentityMutator.reloadAccountsFromSystem(); if (mSignInState.isInteractive()) { // If signin was a user action, record that it succeeded. @@ -536,7 +545,7 @@ * Implements {@link IdentityManager.Observer}: take action when primary account is set. * Simply verify that the request is ongoing (mSignInState != null), as only SigninManager * should update IdentityManager. This is triggered by the call to - * PrimaryAccountMutator.setPrimaryAccount + * IdentityMutator.setPrimaryAccount */ @VisibleForTesting @Override @@ -628,7 +637,7 @@ // User data will be wiped in disableSyncAndWipeData(), called from // onPrimaryAccountcleared(). - mPrimaryAccountMutator.clearPrimaryAccount(ClearAccountsAction.DEFAULT, signoutSource, + mIdentityMutator.clearPrimaryAccount(ClearAccountsAction.DEFAULT, signoutSource, // Always use IGNORE_METRIC for the profile deletion argument. Chrome // Android has just a single-profile which is never deleted upon // sign-out. @@ -642,11 +651,6 @@ return SigninManagerJni.get().getManagementDomain(mNativeSigninManagerAndroid); } - @VisibleForTesting - void logInSignedInUser() { - SigninManagerJni.get().logInSignedInUser(mNativeSigninManagerAndroid); - } - public void clearLastSignedInUser() { SigninManagerJni.get().clearLastSignedInUser(mNativeSigninManagerAndroid); } @@ -731,8 +735,14 @@ * @param callback The callback that will receive true if the account is managed, false * otherwise. */ + // TODO(crbug.com/1002408) Update API to use CoreAccountInfo instead of email public void isAccountManaged(String email, final Callback<Boolean> callback) { - SigninManagerJni.get().isAccountManaged(mNativeSigninManagerAndroid, email, callback); + assert email != null; + CoreAccountInfo account = + mIdentityManager.findExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress( + email); + assert account != null; + SigninManagerJni.get().isAccountManaged(mNativeSigninManagerAndroid, account, callback); } public static String extractDomainName(String email) { @@ -750,9 +760,9 @@ return !ExternalAuthUtils.getInstance().isGooglePlayServicesMissing(context); } - private void fetchAndApplyCloudPolicy(String username, final Runnable callback) { + private void fetchAndApplyCloudPolicy(CoreAccountInfo account, final Runnable callback) { SigninManagerJni.get().fetchAndApplyCloudPolicy( - mNativeSigninManagerAndroid, username, callback); + mNativeSigninManagerAndroid, account, callback); } private void stopApplyingCloudPolicy() { @@ -786,19 +796,17 @@ void clearLastSignedInUser(long nativeSigninManagerAndroid); - void logInSignedInUser(long nativeSigninManagerAndroid); - String extractDomainName(String email); boolean isMobileIdentityConsistencyEnabled(); void fetchAndApplyCloudPolicy( - long nativeSigninManagerAndroid, String username, Runnable callback); + long nativeSigninManagerAndroid, CoreAccountInfo account, Runnable callback); void stopApplyingCloudPolicy(long nativeSigninManagerAndroid); - void isAccountManaged( - long nativeSigninManagerAndroid, String username, Callback<Boolean> callback); + void isAccountManaged(long nativeSigninManagerAndroid, CoreAccountInfo account, + Callback<Boolean> callback); String getManagementDomain(long nativeSigninManagerAndroid);
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd index 09d17e0..7713636 100644 --- a/chrome/android/java/strings/android_chrome_strings.grd +++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -3975,17 +3975,6 @@ Show original </message> - <!-- Incognito disclosure dialog --> - <message name="IDS_INCOGNITO_DISCLOSURE_TITLE" desc="Title of incognito disclosure dialog." translateable="false"> - Warning - </message> - <message name="IDS_INCOGNITO_DISCLOSURE_TEXT" desc="Text for incognito disclosure dialog." translateable="false"> - You are about to open an Incognito Custom Tab, while having other incognito tabs active.\n\nIncognito Custom Tabs share the same profile, so you risk giving access to your Incognito data. - </message> - <message name="IDS_INCOGNITO_DISCLOSURE_CHECKBOX_TEXT" desc="Text for checkbox inviting to close incognito tabs in incognito disclosure dialog." translateable="false"> - Close other incognito tabs - </message> - <!-- Autofill Assistant preferences --> <message name="IDS_PREFS_AUTOFILL_ASSISTANT_TITLE" desc="Title for the Autofill Assistant preferences screen. [CHAR-LIMIT=32]"> Google Assistant in Chrome
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityIncognitoTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityIncognitoTest.java deleted file mode 100644 index 5b5b132..0000000 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityIncognitoTest.java +++ /dev/null
@@ -1,149 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.customtabs; - -import android.content.Intent; -import android.graphics.Color; -import android.support.test.InstrumentationRegistry; -import android.support.test.filters.SmallTest; -import android.view.MenuItem; - -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.chromium.base.Callback; -import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.Feature; -import org.chromium.chrome.R; -import org.chromium.chrome.browser.ChromeSwitches; -import org.chromium.chrome.browser.IntentHandler; -import org.chromium.chrome.browser.incognito.IncognitoNotificationService; -import org.chromium.chrome.browser.test.ScreenShooter; -import org.chromium.chrome.browser.toolbar.top.CustomTabToolbar; -import org.chromium.chrome.browser.util.ColorUtils; -import org.chromium.chrome.test.ChromeJUnit4ClassRunner; -import org.chromium.content_public.browser.test.util.CriteriaHelper; -import org.chromium.content_public.browser.test.util.TestThreadUtils; - -import java.util.concurrent.ExecutionException; - -import androidx.browser.customtabs.CustomTabsIntent; - -/** - * Instrumentation tests for {@link CustomTabActivity} launched in incognito mode. - */ -@RunWith(ChromeJUnit4ClassRunner.class) -@CommandLineFlags.Add({ChromeSwitches.FORCE_FIRST_RUN_FLOW_COMPLETE_FOR_TESTING, - ChromeSwitches.ENABLE_INCOGNITO_CUSTOM_TABS, - ChromeSwitches.ALLOW_INCOGNITO_CUSTOM_TABS_FROM_THIRD_PARTY, - ChromeSwitches.ENABLE_INCOGNITO_SNAPSHOTS_IN_ANDROID_RECENTS}) -public class CustomTabActivityIncognitoTest { - @Rule - public CustomTabActivityTestRule mCustomTabActivityTestRule = new CustomTabActivityTestRule(); - @Rule - public final ScreenShooter mScreenShooter = new ScreenShooter(); - - private CustomTabActivity mActivity; - - @Test - @SmallTest - public void tabIsIncognito() throws Exception { - launchIncognitoCustomTab(); - - Assert.assertTrue(mActivity.getActivityTab().isIncognito()); - } - - @Test - @SmallTest - @Feature({"UiCatalogue"}) - public void toolbarHasIncognitoThemeColor() throws Exception { - launchIncognitoCustomTab(); - - Assert.assertEquals(getIncognitoThemeColor(), getToolbarColor()); - - mScreenShooter.shoot("Incognito Custom Tab"); - } - - @Test - @SmallTest - public void ignoresCustomizedToolbarColor() throws Exception { - launchIncognitoCustomTab( - intent -> intent.putExtra(CustomTabsIntent.EXTRA_TOOLBAR_COLOR, Color.RED)); - - Assert.assertEquals(getIncognitoThemeColor(), getToolbarColor()); - } - - @Test - @SmallTest - @Feature({"UiCatalogue"}) - public void openInBrowserMenuItemHasCorrectTitle() throws Exception { - launchIncognitoCustomTab(); - - CustomTabsTestUtils.openAppMenuAndAssertMenuShown(mActivity); - - String menuTitle = mCustomTabActivityTestRule.getMenu() - .findItem(R.id.open_in_browser_id) - .getTitle() - .toString(); - Assert.assertEquals(mActivity.getString(R.string.menu_open_in_incognito_chrome), menuTitle); - - mScreenShooter.shoot("Incognito Custom Tab Menu"); - } - - @Test - @SmallTest - public void incognitoNotificationClosesCustomTab() throws Exception { - launchIncognitoCustomTab(); - - IncognitoNotificationService.getRemoveAllIncognitoTabsIntent(mActivity) - .getPendingIntent() - .send(); - - CriteriaHelper.pollUiThread(mActivity::isFinishing); - } - - @Test - @SmallTest - public void doesNotHaveAddToHomeScreenMenuItem() throws Exception { - launchIncognitoCustomTab(); - CustomTabsTestUtils.openAppMenuAndAssertMenuShown(mActivity); - - MenuItem item = mCustomTabActivityTestRule.getMenu().findItem(R.id.add_to_homescreen_id); - Assert.assertTrue(item == null || !item.isVisible()); - } - - private void launchIncognitoCustomTab() throws InterruptedException { - launchIncognitoCustomTab(null); - } - - private void launchIncognitoCustomTab(Callback<Intent> additionalIntentModifications) - throws InterruptedException { - Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent( - InstrumentationRegistry.getTargetContext(), "http://www.google.com"); - - intent.putExtra(IntentHandler.EXTRA_OPEN_NEW_INCOGNITO_TAB, true); - if (additionalIntentModifications != null) { - additionalIntentModifications.onResult(intent); - } - - mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent); - - mActivity = mCustomTabActivityTestRule.getActivity(); - } - - private int getIncognitoThemeColor() throws ExecutionException { - return TestThreadUtils.runOnUiThreadBlocking( - () -> ColorUtils.getDefaultThemeColor(mActivity.getResources(), true)); - } - - private int getToolbarColor() throws ExecutionException { - return TestThreadUtils.runOnUiThreadBlocking(() -> { - CustomTabToolbar toolbar = mActivity.findViewById(R.id.toolbar); - return toolbar.getBackground().getColor(); - }); - } -}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoDisclosureDialogAppearanceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoDisclosureDialogAppearanceTest.java deleted file mode 100644 index fa58384..0000000 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoDisclosureDialogAppearanceTest.java +++ /dev/null
@@ -1,38 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.incognito; - -import android.support.test.filters.MediumTest; -import android.support.test.rule.ActivityTestRule; - -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.chromium.base.test.util.Feature; -import org.chromium.chrome.browser.test.ScreenShooter; -import org.chromium.chrome.test.ChromeJUnit4ClassRunner; - -/** - * Tests for the appearance of Incognito Disclosure Dialog. - */ -@RunWith(ChromeJUnit4ClassRunner.class) -public class IncognitoDisclosureDialogAppearanceTest { - @Rule - public ActivityTestRule<IncognitoDisclosureActivity> mActivityTestRule = - new ActivityTestRule<>(IncognitoDisclosureActivity.class, true, true); - - @Rule - public ScreenShooter mScreenShooter = new ScreenShooter(); - - @Test - @MediumTest - @Feature({"CustomTabs"}) - public void shootAppearanceOfDialog() { - Assert.assertNotNull(mActivityTestRule.getActivity()); - mScreenShooter.shoot("Incognito disclosure dialog"); - } -}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninManagerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninManagerTest.java index 150d4efb..fdf127d8 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninManagerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninManagerTest.java
@@ -37,7 +37,7 @@ import org.chromium.components.signin.identitymanager.CoreAccountId; import org.chromium.components.signin.identitymanager.CoreAccountInfo; import org.chromium.components.signin.identitymanager.IdentityManager; -import org.chromium.components.signin.identitymanager.PrimaryAccountMutator; +import org.chromium.components.signin.identitymanager.IdentityMutator; import org.chromium.components.signin.metrics.SignoutReason; import org.chromium.components.sync.AndroidSyncSettings; @@ -55,7 +55,7 @@ private AccountTrackerService mAccountTrackerService; private IdentityManager mIdentityManager; - private PrimaryAccountMutator mPrimaryAccountMutator; + private IdentityMutator mIdentityMutator; private SigninManager mSigninManager; private CoreAccountInfo mAccount; @@ -69,10 +69,10 @@ mAccountTrackerService = mock(AccountTrackerService.class); - mPrimaryAccountMutator = mock(PrimaryAccountMutator.class); + mIdentityMutator = mock(IdentityMutator.class); mIdentityManager = - spy(new IdentityManager(0 /* nativeIdentityManager */, mPrimaryAccountMutator)); + spy(new IdentityManager(0 /* nativeIdentityManager */, mIdentityMutator)); AndroidSyncSettings androidSyncSettings = mock(AndroidSyncSettings.class); @@ -192,7 +192,7 @@ mIdentityManager.onPrimaryAccountCleared(mAccount); return null; }) - .when(mPrimaryAccountMutator) + .when(mIdentityMutator) .clearPrimaryAccount(anyInt(), anyInt(), anyInt()); mSigninManager.signOut(SignoutReason.SIGNOUT_TEST); @@ -221,8 +221,8 @@ doReturn(account) .when(mIdentityManager) .findExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress(any()); - doReturn(true).when(mPrimaryAccountMutator).setPrimaryAccount(any()); - doNothing().when(mNativeMock).logInSignedInUser(anyLong()); + doReturn(true).when(mIdentityMutator).setPrimaryAccount(any()); + doNothing().when(mIdentityMutator).reloadAccountsFromSystem(); mSigninManager.onFirstRunCheckDone(); // Allow sign-in.
diff --git a/chrome/app/chrome_command_ids.h b/chrome/app/chrome_command_ids.h index 219ef53..57e1dc6 100644 --- a/chrome/app/chrome_command_ids.h +++ b/chrome/app/chrome_command_ids.h
@@ -70,11 +70,11 @@ #define IDC_OPEN_IN_PWA_WINDOW 34053 -// Hosted app commands +// Web app window commands #define IDC_COPY_URL 34060 #define IDC_OPEN_IN_CHROME 34061 #define IDC_SITE_SETTINGS 34062 -#define IDC_HOSTED_APP_MENU_APP_INFO 34063 +#define IDC_WEB_APP_MENU_APP_INFO 34063 #if defined(OS_CHROMEOS) // Terminal system app commands
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index b8bb72aa..0806671 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -4449,7 +4449,7 @@ </message> </if> - <message name="IDS_HOSTED_APPMENU_TOOLTIP"> + <message name="IDS_WEB_APP_MENU_BUTTON_TOOLTIP"> Customize and control <ph name="APP_NAME">$1<ex>GMail</ex></ph> </message>
diff --git a/chrome/app/generated_resources_grd/IDS_WEB_APP_MENU_BUTTON_TOOLTIP.png.sha1 b/chrome/app/generated_resources_grd/IDS_WEB_APP_MENU_BUTTON_TOOLTIP.png.sha1 new file mode 100644 index 0000000..3ea6538 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_WEB_APP_MENU_BUTTON_TOOLTIP.png.sha1
@@ -0,0 +1 @@ +d076f811306a736e903b451388516fa260d27ac2 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp index 270433c..09818d4 100644 --- a/chrome/app/os_settings_strings.grdp +++ b/chrome/app/os_settings_strings.grdp
@@ -39,7 +39,7 @@ Preferred search engine </message> <message name="IDS_OS_SETTINGS_SEARCH_ENGINE_TOOLTIP" desc="Tooltip in OS settings explaining that search engine is used in both the Chrome browser and the Chrome OS app launcher."> - Used by Chrome browser and <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> launcher + Used by Chrome browser and <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> Launcher </message> <!-- Files Page (OS settings) -->
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index 48aa744..96db5847 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -2755,8 +2755,9 @@ Show language options </message> <if expr="chromeos"> + <!-- Ends with "." because a "Learn more" link appears next to it. --> <message name="IDS_SETTINGS_LANGUAGES_LANGUAGES_LIST_ORDERING_INSTRUCTIONS" desc="Explanatory message about ordering the list of languages."> - Add languages or reorder list + Add languages or reorder list. </message> <!-- The non-Chrome OS string is in settings_google_chrome_strings.grdp --> <message name="IDS_SETTINGS_LANGUAGES_IS_DISPLAYED_IN_THIS_LANGUAGE" desc="The label for a language that is currently used as the UI display language.">
diff --git a/chrome/browser/android/signin/signin_manager_android.cc b/chrome/browser/android/signin/signin_manager_android.cc index f9a6e7d2..1aa4640 100644 --- a/chrome/browser/android/signin/signin_manager_android.cc +++ b/chrome/browser/android/signin/signin_manager_android.cc
@@ -165,13 +165,6 @@ ClearLastSignedInUserForProfile(profile_); } -void SigninManagerAndroid::LogInSignedInUser(JNIEnv* env) { - // With the account consistency enabled let the account Reconcilor handles - // everything. - // TODO(https://crbug.com/930094): Determine the right long-term flow here. - identity_manager_->LegacyReloadAccountsFromSystem(); -} - bool SigninManagerAndroid::IsSigninAllowed() const { return signin_allowed_.GetValue(); } @@ -218,21 +211,9 @@ void SigninManagerAndroid::FetchAndApplyCloudPolicy( JNIEnv* env, - const JavaParamRef<jstring>& j_username, + const base::android::JavaParamRef<jobject>& j_account_info, const base::android::JavaParamRef<jobject>& j_callback) { - std::string username = - base::android::ConvertJavaStringToUTF8(env, j_username); - DCHECK(!username.empty()); - // TODO(bsazonov): Remove after migrating the sign-in flow to CoreAccountId. - // ExtractDomainName Dchecks that username is a valid email, in practice - // this checks that @ is present and is not the last character. - gaia::ExtractDomainName(username); - CoreAccountInfo account = - identity_manager_ - ->FindExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress( - username) - .value(); - + CoreAccountInfo account = ConvertFromJavaCoreAccountInfo(env, j_account_info); auto callback = base::BindOnce(base::android::RunRunnableAndroid, base::android::ScopedJavaGlobalRef<jobject>(j_callback)); @@ -274,19 +255,13 @@ void SigninManagerAndroid::IsAccountManaged( JNIEnv* env, - const JavaParamRef<jstring>& j_username, + const JavaParamRef<jobject>& j_account_info, const JavaParamRef<jobject>& j_callback) { + CoreAccountInfo account = ConvertFromJavaCoreAccountInfo(env, j_account_info); base::android::ScopedJavaGlobalRef<jobject> callback(env, j_callback); - std::string username = - base::android::ConvertJavaStringToUTF8(env, j_username); - - base::Optional<CoreAccountInfo> account = - identity_manager_ - ->FindExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress( - username); RegisterPolicyWithAccount( - account.value_or(CoreAccountInfo{}), + account, base::BindOnce( [](base::android::ScopedJavaGlobalRef<jobject> callback, const base::Optional<ManagementCredentials>& credentials) {
diff --git a/chrome/browser/android/signin/signin_manager_android.h b/chrome/browser/android/signin/signin_manager_android.h index fc1c3df7..7233281 100644 --- a/chrome/browser/android/signin/signin_manager_android.h +++ b/chrome/browser/android/signin/signin_manager_android.h
@@ -45,8 +45,6 @@ base::android::ScopedJavaLocalRef<jobject> GetJavaObject(); - void LogInSignedInUser(JNIEnv* env); - void ClearLastSignedInUser(JNIEnv* env); jboolean IsSigninAllowedByPolicy(JNIEnv* env) const; @@ -57,14 +55,15 @@ // the policy if necessary. void FetchAndApplyCloudPolicy( JNIEnv* env, - const base::android::JavaParamRef<jstring>& username, + const base::android::JavaParamRef<jobject>& j_account_info, const base::android::JavaParamRef<jobject>& j_callback); void StopApplyingCloudPolicy(JNIEnv* env); - void IsAccountManaged(JNIEnv* env, - const base::android::JavaParamRef<jstring>& j_username, - const base::android::JavaParamRef<jobject>& j_callback); + void IsAccountManaged( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& j_account_info, + const base::android::JavaParamRef<jobject>& j_callback); base::android::ScopedJavaLocalRef<jstring> GetManagementDomain(JNIEnv* env);
diff --git a/chrome/browser/apps/app_service/arc_apps.cc b/chrome/browser/apps/app_service/arc_apps.cc index a32a951..be844b1 100644 --- a/chrome/browser/apps/app_service/arc_apps.cc +++ b/chrome/browser/apps/app_service/arc_apps.cc
@@ -162,8 +162,8 @@ ArcAppListPrefs* prefs = ArcAppListPrefs::Get(profile_); if (prefs) { prefs->RemoveObserver(this); - arc_icon_once_loader_.StopObserving(prefs); } + arc_icon_once_loader_.StopObserving(prefs); } void ArcApps::Connect(apps::mojom::SubscriberPtr subscriber,
diff --git a/chrome/browser/apps/app_service/arc_icon_once_loader.cc b/chrome/browser/apps/app_service/arc_icon_once_loader.cc index 08dc475..727c203 100644 --- a/chrome/browser/apps/app_service/arc_icon_once_loader.cc +++ b/chrome/browser/apps/app_service/arc_icon_once_loader.cc
@@ -133,14 +133,26 @@ } } -ArcIconOnceLoader::ArcIconOnceLoader(Profile* profile) : profile_(profile) { +ArcIconOnceLoader::ArcIconOnceLoader(Profile* profile) + : profile_(profile), stop_observing_called_(false) { ArcAppListPrefs::Get(profile)->AddObserver(this); } -ArcIconOnceLoader::~ArcIconOnceLoader() = default; +ArcIconOnceLoader::~ArcIconOnceLoader() { + // Check that somebody called StopObserving. We can't call StopObserving here + // in the destructor, because we need a ArcAppListPrefs* prefs, and for + // tests, the prefs pointer for a profile can change over time (e.g. by + // ArcAppListPrefsFactory::RecreateServiceInstanceForTesting). + // + // See also ArcApps::Shutdown. + DCHECK(stop_observing_called_); +} void ArcIconOnceLoader::StopObserving(ArcAppListPrefs* prefs) { - prefs->RemoveObserver(this); + stop_observing_called_ = true; + if (prefs) { + prefs->RemoveObserver(this); + } } void ArcIconOnceLoader::LoadIcon(
diff --git a/chrome/browser/apps/app_service/arc_icon_once_loader.h b/chrome/browser/apps/app_service/arc_icon_once_loader.h index 486ce9d..0a6f7a71 100644 --- a/chrome/browser/apps/app_service/arc_icon_once_loader.h +++ b/chrome/browser/apps/app_service/arc_icon_once_loader.h
@@ -31,6 +31,8 @@ // Each AppIconLoader instance is for only one icon size. class ArcIconOnceLoader : public ArcAppListPrefs::Observer { public: + // The constructor caller is responsible for calling StopObserver before + // destroying this. explicit ArcIconOnceLoader(Profile* profile); ~ArcIconOnceLoader() override; @@ -57,6 +59,7 @@ using SizeAndCompression = std::pair<int32_t, apps::mojom::IconCompression>; Profile* const profile_; + bool stop_observing_called_; std::map<SizeAndCompression, std::unique_ptr<SizeSpecificLoader>> size_specific_loaders_;
diff --git a/chrome/browser/apps/app_service/extension_apps.cc b/chrome/browser/apps/app_service/extension_apps.cc index a9ad356..df358ac3 100644 --- a/chrome/browser/apps/app_service/extension_apps.cc +++ b/chrome/browser/apps/app_service/extension_apps.cc
@@ -9,11 +9,13 @@ #include <vector> #include "ash/public/cpp/app_list/app_list_metrics.h" +#include "ash/public/cpp/shelf_types.h" #include "base/bind.h" #include "base/callback.h" #include "base/strings/string16.h" #include "chrome/browser/apps/app_service/app_icon_factory.h" #include "chrome/browser/apps/app_service/launch_util.h" +#include "chrome/browser/apps/launch_service/launch_service.h" #include "chrome/browser/chromeos/extensions/gfx_utils.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/extensions/extension_service.h" @@ -24,6 +26,7 @@ #include "chrome/browser/ui/app_list/extension_uninstaller.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/chrome_pages.h" +#include "chrome/browser/ui/extensions/app_launch_params.h" #include "chrome/browser/ui/extensions/extension_enable_flow.h" #include "chrome/browser/ui/extensions/extension_enable_flow_delegate.h" #include "chrome/browser/web_applications/components/externally_installed_web_app_prefs.h" @@ -67,6 +70,33 @@ CONTENT_SETTINGS_TYPE_NOTIFICATIONS, }; +std::string GetSourceFromAppListSource(ash::ShelfLaunchSource source) { + switch (source) { + case ash::LAUNCH_FROM_APP_LIST: + return std::string(extension_urls::kLaunchSourceAppList); + case ash::LAUNCH_FROM_APP_LIST_SEARCH: + return std::string(extension_urls::kLaunchSourceAppListSearch); + default: + return std::string(); + } +} + +ash::ShelfLaunchSource ConvertLaunchSource( + apps::mojom::LaunchSource launch_source) { + switch (launch_source) { + case apps::mojom::LaunchSource::kUnknown: + case apps::mojom::LaunchSource::kFromParentalControls: + return ash::LAUNCH_FROM_UNKNOWN; + case apps::mojom::LaunchSource::kFromAppListGrid: + case apps::mojom::LaunchSource::kFromAppListGridContextMenu: + return ash::LAUNCH_FROM_APP_LIST; + case apps::mojom::LaunchSource::kFromAppListQuery: + case apps::mojom::LaunchSource::kFromAppListQueryContextMenu: + case apps::mojom::LaunchSource::kFromAppListRecommendation: + return ash::LAUNCH_FROM_APP_LIST_SEARCH; + } +} + } // namespace namespace apps { @@ -228,7 +258,24 @@ break; } - apps_util::Launch(app_id, event_flags, launch_source, display_id); + // The app will be created for the currently active profile. + AppLaunchParams params = CreateAppLaunchParamsWithEventFlags( + profile_, extension, event_flags, + apps::mojom::AppLaunchSource::kSourceAppLauncher, display_id); + ash::ShelfLaunchSource source = ConvertLaunchSource(launch_source); + if ((source == ash::LAUNCH_FROM_APP_LIST || + source == ash::LAUNCH_FROM_APP_LIST_SEARCH) && + app_id == extensions::kWebStoreAppId) { + // Get the corresponding source string. + std::string source_value = GetSourceFromAppListSource(source); + + // Set an override URL to include the source. + GURL extension_url = extensions::AppLaunchInfo::GetFullLaunchURL(extension); + params.override_url = net::AppendQueryParameter( + extension_url, extension_urls::kWebstoreSourceField, source_value); + } + + apps::LaunchService::Get(profile_)->OpenApplication(params); } void ExtensionApps::SetPermission(const std::string& app_id,
diff --git a/chrome/browser/browser_switcher/browser_switcher_service_browsertest.cc b/chrome/browser/browser_switcher/browser_switcher_service_browsertest.cc index 360310c..bcbe6bbe 100644 --- a/chrome/browser/browser_switcher/browser_switcher_service_browsertest.cc +++ b/chrome/browser/browser_switcher/browser_switcher_service_browsertest.cc
@@ -791,6 +791,77 @@ } IN_PROC_BROWSER_TEST_F(BrowserSwitcherServiceTest, + PRE_CacheFileCorrectOnStartup) { + SetUseIeSitelist(true); + BrowserSwitcherServiceWin::SetIeemSitelistUrlForTesting(kAValidUrl); + + content::URLLoaderInterceptor interceptor( + base::BindRepeating(&ReturnValidXml)); + + // Execute everything and check "cache.dat" file contents. + BrowserSwitcherServiceFactory::GetForBrowserContext(browser()->profile()); + base::RunLoop run_loop; + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce( + [](base::FilePath cache_file_path, base::OnceClosure quit) { + base::ScopedAllowBlockingForTesting allow_blocking; + ASSERT_TRUE(base::PathExists(base::FilePath(cache_file_path))); + std::move(quit).Run(); + }, + cache_file_path(), run_loop.QuitClosure()), + action_timeout()); + run_loop.Run(); +} + +IN_PROC_BROWSER_TEST_F(BrowserSwitcherServiceTest, CacheFileCorrectOnStartup) { + SetUseIeSitelist(true); + // Never refresh the sitelist. We want to check the state of cache.dat after + // startup, not after the sitelist is downloaded. + BrowserSwitcherServiceWin::SetFetchDelayForTesting( + base::TimeDelta::FromHours(24)); + BrowserSwitcherServiceWin::SetIeemSitelistUrlForTesting(kAValidUrl); + + content::URLLoaderInterceptor interceptor( + base::BindRepeating(&ReturnValidXml)); + + // Execute everything and check "cache.dat" file contents. + BrowserSwitcherServiceFactory::GetForBrowserContext(browser()->profile()); + base::RunLoop run_loop; + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce( + [](base::FilePath cache_file_path, + base::FilePath sitelist_cache_file_path, base::OnceClosure quit) { + base::ScopedAllowBlockingForTesting allow_blocking; + base::File file(cache_file_path, + base::File::FLAG_OPEN | base::File::FLAG_READ); + ASSERT_TRUE(file.IsValid()); + + const char expected_output[] = + "1\n" + "\n" + "\n" + "\n" + "\n" + "1\n" + "docs.google.com\n" + "0\n"; + + std::unique_ptr<char[]> buffer(new char[file.GetLength() + 1]); + buffer.get()[file.GetLength()] = '\0'; + file.Read(0, buffer.get(), file.GetLength()); + EXPECT_EQ(std::string(expected_output), std::string(buffer.get())); + + std::move(quit).Run(); + }, + cache_file_path(), sitelist_cache_file_path(), + run_loop.QuitClosure()), + action_timeout()); + run_loop.Run(); +} + +IN_PROC_BROWSER_TEST_F(BrowserSwitcherServiceTest, DeletesSitelistCacheOnStartup) { base::ScopedAllowBlockingForTesting allow_blocking;
diff --git a/chrome/browser/browser_switcher/browser_switcher_service_win.cc b/chrome/browser/browser_switcher/browser_switcher_service_win.cc index 27414d9..196725c6 100644 --- a/chrome/browser/browser_switcher/browser_switcher_service_win.cc +++ b/chrome/browser/browser_switcher/browser_switcher_service_win.cc
@@ -192,6 +192,9 @@ if (prefs().UseIeSitelist()) sitelist()->SetIeemSitelist( ParsedXml(prefs().GetCachedIeemSitelist(), base::nullopt)); + if (!prefs().IsEnabled()) + return; + SavePrefsToFile(); } void BrowserSwitcherServiceWin::OnAllRulesetsParsed() {
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 1e9fd93d..0f01b13 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -131,6 +131,7 @@ #include "chrome/browser/signin/chrome_signin_proxying_url_loader_factory.h" #include "chrome/browser/signin/chrome_signin_url_loader_throttle.h" #include "chrome/browser/signin/header_modification_delegate_on_ui_thread_impl.h" +#include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/site_isolation/site_isolation_policy.h" #include "chrome/browser/speech/chrome_speech_recognition_manager_delegate.h" #include "chrome/browser/speech/tts_controller_delegate_impl.h" @@ -251,7 +252,7 @@ #include "components/safe_browsing/features.h" #include "components/safe_browsing/password_protection/password_protection_navigation_throttle.h" #include "components/security_interstitials/content/origin_policy_ui.h" -#include "components/signin/public/base/signin_pref_names.h" +#include "components/signin/public/identity_manager/identity_manager.h" #include "components/spellcheck/spellcheck_buildflags.h" #include "components/startup_metric_utils/browser/startup_metric_host_impl.h" #include "components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h" @@ -4592,11 +4593,9 @@ base::CreateSingleThreadTaskRunner({BrowserThread::UI}))); } - bool is_off_the_record = profile->IsOffTheRecord(); - bool is_signed_in = !is_off_the_record && - !profile->GetPrefs() - ->GetString(prefs::kGoogleServicesUserAccountId) - .empty(); + signin::IdentityManager* identity_manager = + IdentityManagerFactory::GetForProfile(profile); + bool is_signed_in = identity_manager && identity_manager->HasPrimaryAccount(); chrome::mojom::DynamicParams dynamic_params = { profile->GetPrefs()->GetBoolean(prefs::kForceGoogleSafeSearch), @@ -4605,7 +4604,7 @@ variations::VariationsHttpHeaderProvider::GetInstance() ->GetClientDataHeader(is_signed_in)}; result.push_back(std::make_unique<GoogleURLLoaderThrottle>( - is_off_the_record, std::move(dynamic_params))); + profile->IsOffTheRecord(), std::move(dynamic_params))); result.push_back(std::make_unique<ProtocolHandlerThrottle>( ProtocolHandlerRegistryFactory::GetForBrowserContext(browser_context)));
diff --git a/chrome/browser/chromeos/apps/apk_web_app_service.cc b/chrome/browser/chromeos/apps/apk_web_app_service.cc index 8743813..1cd231a0 100644 --- a/chrome/browser/chromeos/apps/apk_web_app_service.cc +++ b/chrome/browser/chromeos/apps/apk_web_app_service.cc
@@ -12,8 +12,10 @@ #include "chrome/browser/chromeos/apps/apk_web_app_service_factory.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" #include "chrome/browser/web_applications/components/externally_installed_web_app_prefs.h" #include "chrome/browser/web_applications/components/web_app_constants.h" +#include "chrome/browser/web_applications/components/web_app_helpers.h" #include "chrome/common/chrome_features.h" #include "components/arc/mojom/app.mojom.h" #include "components/arc/session/connection_holder.h" @@ -23,6 +25,7 @@ #include "extensions/browser/extension_system.h" #include "extensions/browser/uninstall_reason.h" #include "extensions/common/extension.h" +#include "url/gurl.h" namespace { @@ -45,6 +48,8 @@ const char kWebAppToApkDictPref[] = "web_app_apks"; const char kPackageNameKey[] = "package_name"; const char kShouldRemoveKey[] = "should_remove"; +constexpr char kLastAppId[] = "last_app_id"; +constexpr char kPinIndex[] = "pin_index"; // Default icon size in pixels to request from ARC for an icon. const int kDefaultIconSize = 192; @@ -116,6 +121,60 @@ } } +void ApkWebAppService::UpdateShelfPin( + const arc::mojom::ArcPackageInfo* package_info) { + std::string new_app_id; + // Compute the current app id. It may have changed if the package has been + // updated from an Android app to a web app, or vice versa. + if (!package_info->web_app_info.is_null()) { + new_app_id = web_app::GenerateAppIdFromURL( + GURL(package_info->web_app_info->start_url)); + } else { + // Get the first app in the package. If there are multiple apps in the + // package there is no way to determine which app is more suitable to + // replace the previous web app shortcut. For simplicity we will just use + // the first one. + std::unordered_set<std::string> apps = + arc_app_list_prefs_->GetAppsForPackage(package_info->package_name); + if (!apps.empty()) + new_app_id = *apps.begin(); + } + + // Query for the old app id, which is cached in the package dict to ensure it + // isn't overwritten before this method can run. + const base::Value* last_app_id_value = arc_app_list_prefs_->GetPackagePrefs( + package_info->package_name, kLastAppId); + + std::string last_app_id; + if (last_app_id_value && last_app_id_value->is_string()) + last_app_id = last_app_id_value->GetString(); + + if (new_app_id != last_app_id && !new_app_id.empty()) { + arc_app_list_prefs_->SetPackagePrefs(package_info->package_name, kLastAppId, + base::Value(new_app_id)); + if (!last_app_id.empty()) { + auto* launcher_controller = ChromeLauncherController::instance(); + if (!launcher_controller) + return; + int index = launcher_controller->PinnedItemIndexByAppID(last_app_id); + // The previously installed app has been uninstalled or hidden, in this + // instance get the saved pin index and pin at that place. + if (index == ChromeLauncherController::kInvalidIndex) { + const base::Value* saved_index = arc_app_list_prefs_->GetPackagePrefs( + package_info->package_name, kPinIndex); + if (!(saved_index && saved_index->is_int())) + return; + launcher_controller->PinAppAtIndex(new_app_id, saved_index->GetInt()); + arc_app_list_prefs_->SetPackagePrefs( + package_info->package_name, kPinIndex, + base::Value(ChromeLauncherController::kInvalidIndex)); + } else { + launcher_controller->ReplacePinnedItem(last_app_id, new_app_id); + } + } + } +} + void ApkWebAppService::Shutdown() { // Can be null in tests. if (arc_app_list_prefs_) { @@ -156,6 +215,10 @@ if (is_now_web_app == was_previously_web_app) return; + // Only call this function if there has been a state change from web app to + // Android app or vice-versa. + UpdateShelfPin(&package_info); + if (was_previously_web_app) { // The package was a web app, but now isn't. Remove the web app. OnPackageRemoved(package_info.package_name, true /* uninstalled */);
diff --git a/chrome/browser/chromeos/apps/apk_web_app_service.h b/chrome/browser/chromeos/apps/apk_web_app_service.h index 94e16f7..695fa25 100644 --- a/chrome/browser/chromeos/apps/apk_web_app_service.h +++ b/chrome/browser/chromeos/apps/apk_web_app_service.h
@@ -61,6 +61,11 @@ // ApkWebAppInstaller::Install(). void UninstallWebApp(const web_app::AppId& web_app_id); + // If the app has updated from a web app to Android app or vice-versa, + // this function pins the new app in the old app's place on the shelf if it + // was pinned prior to the update. + void UpdateShelfPin(const arc::mojom::ArcPackageInfo* package_info); + // KeyedService: void Shutdown() override;
diff --git a/chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer.cc b/chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer.cc index 87f609b..5a5bbb2 100644 --- a/chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer.cc +++ b/chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer.cc
@@ -40,7 +40,7 @@ queue_->RemoveObserver(this); } -void ArcCertInstaller::InstallArcCerts( +std::set<std::string> ArcCertInstaller::InstallArcCerts( const std::vector<net::ScopedCERTCertificate>& certificates, InstallArcCertsCallback callback) { VLOG(1) << "ArcCertInstaller::InstallArcCerts"; @@ -52,7 +52,7 @@ pending_status_ = true; } - required_cert_names_.clear(); + std::set<std::string> required_cert_names; callback_ = std::move(callback); for (const auto& nss_cert : certificates) { @@ -64,14 +64,15 @@ std::string cert_name = x509_certificate_model::GetCertNameOrNickname(nss_cert.get()); + required_cert_names.insert(cert_name); InstallArcCert(cert_name, nss_cert); } - // Cleanup |known_cert_names_| according to |required_cert_names_|. + // Cleanup |known_cert_names_| according to |required_cert_names|. for (auto it = known_cert_names_.begin(); it != known_cert_names_.end();) { auto cert_name = it++; - if (!required_cert_names_.count(*cert_name)) + if (!required_cert_names.count(*cert_name)) known_cert_names_.erase(cert_name); } @@ -79,13 +80,14 @@ std::move(callback_).Run(pending_status_); pending_status_ = true; } + + return required_cert_names; } void ArcCertInstaller::InstallArcCert( const std::string& name, const net::ScopedCERTCertificate& nss_cert) { VLOG(1) << "ArcCertInstaller::InstallArcCert " << name; - required_cert_names_.insert(name); // Do not install certificate if already exists. if (known_cert_names_.count(name)) @@ -134,8 +136,8 @@ } // If the cert installation is failed, save the status and remove from the - // |known_cert_names_| to be able to re-try the installation when the - // |Refresh| is called again. + // |known_cert_names_|. Use the |pending_status_| to notify clients should + // re-try installation. if (command->status() != policy::RemoteCommandJob::Status::SUCCEEDED) { LOG(ERROR) << "Failed to install certificate " << pending_commands_[command->unique_id()];
diff --git a/chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer.h b/chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer.h index 1599443..b9891fd 100644 --- a/chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer.h +++ b/chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer.h
@@ -9,6 +9,7 @@ #include <memory> #include <set> #include <string> +#include <vector> #include "base/memory/weak_ptr.h" #include "components/policy/core/common/remote_commands/remote_command_job.h" @@ -40,9 +41,11 @@ using InstallArcCertsCallback = base::OnceCallback<void(bool result)>; // Install missing certificates via ARC remote commands. + // + // Return set of the names of certificates required being installed on ARC. // Return false via |callback| in case of any error, and true otherwise. // Made virtual for override in test. - virtual void InstallArcCerts( + virtual std::set<std::string> InstallArcCerts( const std::vector<net::ScopedCERTCertificate>& certs, InstallArcCertsCallback callback); @@ -67,9 +70,6 @@ // The |pending_status_| is returned via |callback_|. bool pending_status_ = true; - // Names of certificates required to be installed on ARC. - std::set<std::string> required_cert_names_; - // Names of certificates installed or pending to be installed on ARC. std::set<std::string> known_cert_names_;
diff --git a/chrome/browser/chromeos/arc/enterprise/cert_store/arc_smart_card_manager_bridge.cc b/chrome/browser/chromeos/arc/enterprise/cert_store/arc_smart_card_manager_bridge.cc index 3b44d12..957d788 100644 --- a/chrome/browser/chromeos/arc/enterprise/cert_store/arc_smart_card_manager_bridge.cc +++ b/chrome/browser/chromeos/arc/enterprise/cert_store/arc_smart_card_manager_bridge.cc
@@ -10,9 +10,12 @@ #include "base/callback.h" #include "base/logging.h" #include "base/memory/singleton.h" +#include "chrome/browser/chromeos/arc/policy/arc_policy_bridge.h" #include "chrome/browser/chromeos/certificate_provider/certificate_provider_service.h" #include "chrome/browser/chromeos/certificate_provider/certificate_provider_service_factory.h" #include "components/arc/arc_browser_context_keyed_service_factory_base.h" +#include "components/policy/core/common/policy_map.h" +#include "components/policy/core/common/policy_namespace.h" #include "net/cert/x509_util_nss.h" namespace arc { @@ -49,10 +52,16 @@ return ArcSmartCardManagerBridgeFactory::GetForBrowserContext(context); } +// static +BrowserContextKeyedServiceFactory* ArcSmartCardManagerBridge::GetFactory() { + return ArcSmartCardManagerBridgeFactory::GetInstance(); +} + ArcSmartCardManagerBridge::ArcSmartCardManagerBridge( content::BrowserContext* context, ArcBridgeService* bridge_service) : ArcSmartCardManagerBridge( + context, bridge_service, chromeos::CertificateProviderServiceFactory::GetForBrowserContext( context) @@ -60,10 +69,12 @@ std::make_unique<ArcCertInstaller>(context)) {} ArcSmartCardManagerBridge::ArcSmartCardManagerBridge( + content::BrowserContext* context, ArcBridgeService* bridge_service, std::unique_ptr<chromeos::CertificateProvider> certificate_provider, std::unique_ptr<ArcCertInstaller> installer) - : arc_bridge_service_(bridge_service), + : context_(context), + arc_bridge_service_(bridge_service), certificate_provider_(std::move(certificate_provider)), installer_(std::move(installer)), weak_ptr_factory_(this) { @@ -103,7 +114,17 @@ certificates.push_back(std::move(nss_cert)); } - installer_->InstallArcCerts(std::move(certificates), std::move(callback)); + std::set<std::string> new_required_cert_names = + installer_->InstallArcCerts(std::move(certificates), std::move(callback)); + if (required_cert_names_ != new_required_cert_names) { + required_cert_names_ = new_required_cert_names; + ArcPolicyBridge* const policy_bridge = + ArcPolicyBridge::GetForBrowserContext(context_); + if (policy_bridge) { + policy_bridge->OnPolicyUpdated(policy::PolicyNamespace(), + policy::PolicyMap(), policy::PolicyMap()); + } + } } } // namespace arc
diff --git a/chrome/browser/chromeos/arc/enterprise/cert_store/arc_smart_card_manager_bridge.h b/chrome/browser/chromeos/arc/enterprise/cert_store/arc_smart_card_manager_bridge.h index c94bf3a..068f15e 100644 --- a/chrome/browser/chromeos/arc/enterprise/cert_store/arc_smart_card_manager_bridge.h +++ b/chrome/browser/chromeos/arc/enterprise/cert_store/arc_smart_card_manager_bridge.h
@@ -6,6 +6,8 @@ #define CHROME_BROWSER_CHROMEOS_ARC_ENTERPRISE_CERT_STORE_ARC_SMART_CARD_MANAGER_BRIDGE_H_ #include <memory> +#include <set> +#include <vector> #include "base/memory/weak_ptr.h" #include "chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer.h" @@ -15,6 +17,8 @@ #include "components/keyed_service/core/keyed_service.h" #include "net/cert/scoped_nss_types.h" +class BrowserContextKeyedServiceFactory; + namespace content { class BrowserContext; @@ -33,11 +37,15 @@ static ArcSmartCardManagerBridge* GetForBrowserContext( content::BrowserContext* context); + // Return the factory instance for this class. + static BrowserContextKeyedServiceFactory* GetFactory(); + ArcSmartCardManagerBridge(content::BrowserContext* context, ArcBridgeService* bridge_service); // This constructor is public only for testing. ArcSmartCardManagerBridge( + content::BrowserContext* context, ArcBridgeService* bridge_service, std::unique_ptr<chromeos::CertificateProvider> certificate_provider, std::unique_ptr<ArcCertInstaller> installer); @@ -47,15 +55,29 @@ // SmartCardManagerHost overrides. void Refresh(RefreshCallback callback) override; + std::vector<std::string> get_required_cert_names() const { + return std::vector<std::string>(required_cert_names_.begin(), + required_cert_names_.end()); + } + + void set_required_cert_names_for_testing( + const std::vector<std::string>& cert_names) { + required_cert_names_ = + std::set<std::string>(cert_names.begin(), cert_names.end()); + } + private: void DidGetCerts(RefreshCallback callback, net::ClientCertIdentityList cert_identities); + content::BrowserContext* const context_; ArcBridgeService* const arc_bridge_service_; // Owned by ArcServiceManager. std::unique_ptr<chromeos::CertificateProvider> certificate_provider_; std::unique_ptr<ArcCertInstaller> installer_; + std::set<std::string> required_cert_names_; + base::WeakPtrFactory<ArcSmartCardManagerBridge> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(ArcSmartCardManagerBridge);
diff --git a/chrome/browser/chromeos/arc/enterprise/cert_store/arc_smart_card_manager_bridge_unittest.cc b/chrome/browser/chromeos/arc/enterprise/cert_store/arc_smart_card_manager_bridge_unittest.cc index ce976a4..869eb95 100644 --- a/chrome/browser/chromeos/arc/enterprise/cert_store/arc_smart_card_manager_bridge_unittest.cc +++ b/chrome/browser/chromeos/arc/enterprise/cert_store/arc_smart_card_manager_bridge_unittest.cc
@@ -2,17 +2,22 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <set> #include <string> #include <vector> +#include "base/bind.h" #include "base/memory/ptr_util.h" #include "base/threading/sequenced_task_runner_handle.h" #include "chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer.h" #include "chrome/browser/chromeos/arc/enterprise/cert_store/arc_smart_card_manager_bridge.h" +#include "chrome/browser/chromeos/arc/policy/arc_policy_bridge.h" #include "chrome/browser/chromeos/certificate_provider/certificate_provider.h" #include "chrome/common/net/x509_certificate_model_nss.h" #include "chrome/test/base/testing_profile.h" #include "components/arc/session/arc_bridge_service.h" +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" +#include "components/keyed_service/core/keyed_service.h" #include "components/policy/core/common/remote_commands/remote_commands_queue.h" #include "content/public/test/browser_task_environment.h" #include "crypto/rsa_private_key.h" @@ -108,10 +113,30 @@ std::unique_ptr<policy::RemoteCommandsQueue> queue) : ArcCertInstaller(profile, std::move(queue)) {} MOCK_METHOD2(InstallArcCerts, - void(const std::vector<net::ScopedCERTCertificate>& certs, - InstallArcCertsCallback callback)); + std::set<std::string>( + const std::vector<net::ScopedCERTCertificate>& certs, + InstallArcCertsCallback callback)); }; +class MockArcPolicyBridge : public ArcPolicyBridge { + public: + MockArcPolicyBridge(content::BrowserContext* context, + ArcBridgeService* bridge_service, + policy::PolicyService* policy_service) + : ArcPolicyBridge(context, bridge_service, policy_service) {} + MOCK_METHOD3(OnPolicyUpdated, + void(const policy::PolicyNamespace& ns, + const policy::PolicyMap& previous, + const policy::PolicyMap& current)); +}; + +std::unique_ptr<KeyedService> BuildPolicyBridge( + ArcBridgeService* bridge_service, + content::BrowserContext* profile) { + return std::make_unique<MockArcPolicyBridge>(profile, bridge_service, + nullptr); +} + } // namespace class ArcSmartCardManagerBridgeTest : public testing::Test { @@ -123,8 +148,12 @@ provider_ = new FakeCertificateProvider(); installer_ = new StrictMock<MockArcCertInstaller>( &profile_, std::make_unique<policy::RemoteCommandsQueue>()); + policy_bridge_ = static_cast<MockArcPolicyBridge*>( + ArcPolicyBridge::GetFactory()->SetTestingFactoryAndUse( + &profile_, + base::BindRepeating(&BuildPolicyBridge, bridge_service_.get()))); bridge_ = std::make_unique<ArcSmartCardManagerBridge>( - bridge_service_.get(), base::WrapUnique(provider_), + &profile_, bridge_service_.get(), base::WrapUnique(provider_), base::WrapUnique(installer_)); } @@ -136,16 +165,18 @@ FakeCertificateProvider* provider() { return provider_; } MockArcCertInstaller* installer() { return installer_; } + MockArcPolicyBridge* policy_bridge() { return policy_bridge_; } ArcSmartCardManagerBridge* bridge() { return bridge_.get(); } private: content::BrowserTaskEnvironment browser_task_environment_; - TestingProfile profile_; std::unique_ptr<ArcBridgeService> bridge_service_; + TestingProfile profile_; FakeCertificateProvider* provider_; // Owned by |bridge_|. MockArcCertInstaller* installer_; // Owned by |bridge_|. + MockArcPolicyBridge* policy_bridge_; // Not owned. std::unique_ptr<ArcSmartCardManagerBridge> bridge_; @@ -162,6 +193,7 @@ .WillOnce( WithArg<1>(Invoke([](base::OnceCallback<void(bool result)> callback) { std::move(callback).Run(true); + return std::set<std::string>(); }))); bridge()->Refresh(base::BindOnce([](bool result) { EXPECT_TRUE(result); })); } @@ -174,10 +206,12 @@ ASSERT_TRUE(provider()->SetCertificates(cert_names)); EXPECT_CALL(*installer(), InstallArcCerts(EqualsClientCertIdentityList(cert_names), _)) - .WillOnce( - WithArg<1>(Invoke([](base::OnceCallback<void(bool result)> callback) { + .WillOnce(WithArg<1>( + Invoke([&cert_names](base::OnceCallback<void(bool result)> callback) { std::move(callback).Run(true); + return std::set<std::string>(cert_names.begin(), cert_names.end()); }))); + EXPECT_CALL(*policy_bridge(), OnPolicyUpdated(_, _, _)); bridge()->Refresh(base::BindOnce([](bool result) { EXPECT_TRUE(result); })); }
diff --git a/chrome/browser/chromeos/arc/policy/arc_policy_bridge.cc b/chrome/browser/chromeos/arc/policy/arc_policy_bridge.cc index 23dc339..778b2ce 100644 --- a/chrome/browser/chromeos/arc/policy/arc_policy_bridge.cc +++ b/chrome/browser/chromeos/arc/policy/arc_policy_bridge.cc
@@ -18,6 +18,7 @@ #include "base/strings/string_util.h" #include "base/values.h" #include "chrome/browser/chromeos/arc/arc_session_manager.h" +#include "chrome/browser/chromeos/arc/enterprise/cert_store/arc_smart_card_manager_bridge.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/policy/developer_tools_policy_handler.h" #include "chrome/browser/policy/profile_policy_connector.h" @@ -44,6 +45,7 @@ constexpr char kArcCaCerts[] = "caCerts"; constexpr char kPolicyCompliantJson[] = "{ \"policyCompliant\": true }"; +constexpr char kArcRequiredKeyPairs[] = "requiredKeyPairs"; // invert_bool_value: If the Chrome policy and the ARC policy with boolean value // have opposite semantics, set this to true so the bool is inverted before @@ -214,10 +216,24 @@ filtered_policies->Set(kArcCaCerts, std::move(ca_certs)); } -std::string GetFilteredJSONPolicies(const policy::PolicyMap& policy_map, - const PrefService* profile_prefs, - const std::string& guid, - bool is_affiliated) { +void AddRequiredKeyPairs(const ArcSmartCardManagerBridge* smart_card_manager, + base::DictionaryValue* filtered_policies) { + if (!smart_card_manager) + return; + std::unique_ptr<base::ListValue> cert_names( + std::make_unique<base::ListValue>()); + for (const auto& name : smart_card_manager->get_required_cert_names()) { + cert_names->GetList().emplace_back(name); + } + filtered_policies->Set(kArcRequiredKeyPairs, std::move(cert_names)); +} + +std::string GetFilteredJSONPolicies( + const policy::PolicyMap& policy_map, + const PrefService* profile_prefs, + const std::string& guid, + bool is_affiliated, + const ArcSmartCardManagerBridge* smart_card_manager) { base::DictionaryValue filtered_policies; // Parse ArcPolicy as JSON string before adding other policies to the // dictionary. @@ -275,6 +291,8 @@ filtered_policies.SetString("guid", guid); + AddRequiredKeyPairs(smart_card_manager, &filtered_policies); + std::string policy_json; JSONStringValueSerializer serializer(&policy_json); serializer.Serialize(filtered_policies); @@ -354,6 +372,11 @@ return ArcPolicyBridgeFactory::GetForBrowserContextForTesting(context); } +// static +BrowserContextKeyedServiceFactory* ArcPolicyBridge::GetFactory() { + return ArcPolicyBridgeFactory::GetInstance(); +} + base::WeakPtr<ArcPolicyBridge> ArcPolicyBridge::GetWeakPtr() { return weak_ptr_factory_.GetWeakPtr(); } @@ -542,9 +565,12 @@ const Profile* const profile = Profile::FromBrowserContext(context_); const user_manager::User* const user = chromeos::ProfileHelper::Get()->GetUserByProfile(profile); + const ArcSmartCardManagerBridge* smart_card_manager = + ArcSmartCardManagerBridge::GetForBrowserContext(context_); return GetFilteredJSONPolicies(policy_map, profile->GetPrefs(), - instance_guid_, user->IsAffiliated()); + instance_guid_, user->IsAffiliated(), + smart_card_manager); } void ArcPolicyBridge::OnReportComplianceParseSuccess(
diff --git a/chrome/browser/chromeos/arc/policy/arc_policy_bridge.h b/chrome/browser/chromeos/arc/policy/arc_policy_bridge.h index 6d00a43..c4ab57a 100644 --- a/chrome/browser/chromeos/arc/policy/arc_policy_bridge.h +++ b/chrome/browser/chromeos/arc/policy/arc_policy_bridge.h
@@ -23,6 +23,8 @@ #include "components/policy/core/common/policy_namespace.h" #include "components/policy/core/common/policy_service.h" +class BrowserContextKeyedServiceFactory; + namespace base { class Value; } @@ -107,6 +109,9 @@ static ArcPolicyBridge* GetForBrowserContextForTesting( content::BrowserContext* context); + // Return the factory instance for this class. + static BrowserContextKeyedServiceFactory* GetFactory(); + base::WeakPtr<ArcPolicyBridge> GetWeakPtr(); ArcPolicyBridge(content::BrowserContext* context, @@ -173,6 +178,7 @@ ArcBridgeService* const arc_bridge_service_; // Owned by ArcServiceManager. policy::PolicyService* policy_service_ = nullptr; + bool is_managed_ = false; // HACK(b/73762796): A GUID that is regenerated whenever |this| is created,
diff --git a/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc b/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc index 83e2179..2967c1c 100644 --- a/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc +++ b/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc
@@ -12,6 +12,7 @@ #include "base/memory/ptr_util.h" #include "base/run_loop.h" #include "base/values.h" +#include "chrome/browser/chromeos/arc/enterprise/cert_store/arc_smart_card_manager_bridge.h" #include "chrome/browser/chromeos/arc/policy/arc_policy_bridge.h" #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/policy/developer_tools_policy_handler.h" @@ -22,10 +23,13 @@ #include "components/arc/session/arc_bridge_service.h" #include "components/arc/test/connection_holder_util.h" #include "components/arc/test/fake_policy_instance.h" +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" +#include "components/keyed_service/core/keyed_service.h" #include "components/policy/core/common/mock_policy_service.h" #include "components/policy/core/common/policy_map.h" #include "components/policy/core/common/policy_namespace.h" #include "components/policy/core/common/policy_types.h" +#include "components/policy/core/common/remote_commands/remote_commands_queue.h" #include "components/policy/policy_constants.h" #include "components/sync_preferences/testing_pref_service_syncable.h" #include "components/user_manager/scoped_user_manager.h" @@ -73,6 +77,9 @@ constexpr char kPolicyCompliantResponse[] = "{ \"policyCompliant\": true }"; +constexpr char kFakeCertName[] = "cert_name"; +constexpr char kRequiredKeyPairFormat[] = "\"requiredKeyPairs\":[%s%s%s]"; + MATCHER_P(ValueEquals, expected, "value matches") { return *expected == *arg; } @@ -168,6 +175,8 @@ profile_ = testing_profile_manager_->CreateTestingProfile("user@gmail.com"); ASSERT_TRUE(profile_); + smart_card_manager_ = GetArcSmartCardManager(); + // TODO(hidehiko): Use Singleton instance tied to BrowserContext. policy_bridge_ = std::make_unique<ArcPolicyBridge>( profile_, bridge_service_.get(), &policy_service_); @@ -184,6 +193,7 @@ bridge_service_->policy()->CloseInstance(policy_instance_.get()); policy_instance_.reset(); policy_bridge_->RemoveObserver(&observer_); + testing_profile_manager_.reset(); } protected: @@ -212,12 +222,29 @@ Mock::VerifyAndClearExpectations(&observer_); } + // Specifies a testing factory for ArcSmartCardManagerBridge and returns + // instance. + // Returns nullptr by default. + // Override if the test wants to use a real smart card manager. + virtual ArcSmartCardManagerBridge* GetArcSmartCardManager() { + return static_cast<ArcSmartCardManagerBridge*>( + ArcSmartCardManagerBridge::GetFactory()->SetTestingFactoryAndUse( + profile(), + base::BindRepeating( + [](content::BrowserContext* profile) + -> std::unique_ptr<KeyedService> { return nullptr; }))); + } + ArcPolicyBridge* policy_bridge() { return policy_bridge_.get(); } const std::string& instance_guid() { return instance_guid_; } FakePolicyInstance* policy_instance() { return policy_instance_.get(); } policy::PolicyMap& policy_map() { return policy_map_; } base::RunLoop& run_loop() { return run_loop_; } TestingProfile* profile() { return profile_; } + ArcBridgeService* bridge_service() { return bridge_service_.get(); } + ArcSmartCardManagerBridge* smart_card_manager() { + return smart_card_manager_; + } private: content::BrowserTaskEnvironment task_environment_; @@ -227,8 +254,9 @@ std::unique_ptr<TestingProfileManager> testing_profile_manager_; base::RunLoop run_loop_; TestingProfile* profile_; - std::unique_ptr<ArcBridgeService> bridge_service_; + ArcSmartCardManagerBridge* smart_card_manager_; // Not owned. + std::unique_ptr<ArcPolicyBridge> policy_bridge_; std::string instance_guid_; MockArcPolicyBridgeObserver observer_; @@ -262,6 +290,23 @@ const bool is_affiliated_; }; +// Tests required key pair policy. +class ArcPolicyBridgeRequiredKeyPairTest : public ArcPolicyBridgeTest { + protected: + ArcSmartCardManagerBridge* GetArcSmartCardManager() override { + return static_cast<ArcSmartCardManagerBridge*>( + ArcSmartCardManagerBridge::GetFactory()->SetTestingFactoryAndUse( + profile(), base::BindRepeating( + [](ArcBridgeService* bridge_service, + content::BrowserContext* profile) + -> std::unique_ptr<KeyedService> { + return std::make_unique<ArcSmartCardManagerBridge>( + profile, bridge_service, nullptr, nullptr); + }, + bridge_service()))); + } +}; + TEST_F(ArcPolicyBridgeTest, UnmanagedTest) { policy_bridge()->OverrideIsManagedForTesting(false); GetPoliciesAndVerifyResult(""); @@ -568,4 +613,25 @@ ArcPolicyBridgeAffiliatedTest, testing::Bool()); +// Tests that if smart card manager is non-null, the required key pair policy is +// set to the required certificate list. +TEST_F(ArcPolicyBridgeRequiredKeyPairTest, RequiredKeyPairsBasicTest) { + EXPECT_TRUE(smart_card_manager()); + + // One certificate is required to be installed. + smart_card_manager()->set_required_cert_names_for_testing( + std::vector<std::string>({kFakeCertName})); + GetPoliciesAndVerifyResult( + "{\"guid\":\"" + instance_guid() + "\"," + + base::StringPrintf(kRequiredKeyPairFormat, "\"", kFakeCertName, "\"") + + "}"); + + // An empty list is required to be installed. + smart_card_manager()->set_required_cert_names_for_testing( + std::vector<std::string>()); + GetPoliciesAndVerifyResult( + "{\"guid\":\"" + instance_guid() + "\"," + + base::StringPrintf(kRequiredKeyPairFormat, "", "", "") + "}"); +} + } // namespace arc
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc index 858a07ce..b97ee859 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -42,16 +42,6 @@ return *this; } - TestCase& EnableDriveFs() { - enable_drivefs.emplace(true); - return *this; - } - - TestCase& DisableDriveFs() { - enable_drivefs.emplace(false); - return *this; - } - TestCase& EnableDocumentsProvider() { enable_arc = true; enable_documents_provider.emplace(true); @@ -117,9 +107,6 @@ if (test.tablet_mode) name.append("_TabletMode"); - if (test.enable_drivefs.value_or(false)) - name.append("_DriveFs"); - if (test.files_ng) name.append("_FilesNg"); @@ -135,7 +122,6 @@ const char* test_case_name = nullptr; GuestMode guest_mode = NOT_IN_GUEST_MODE; bool tablet_mode = false; - base::Optional<bool> enable_drivefs; base::Optional<bool> enable_myfiles_volume; base::Optional<bool> enable_documents_provider; base::Optional<bool> enable_format_dialog; @@ -186,11 +172,6 @@ bool GetTabletMode() const override { return GetParam().tablet_mode; } - bool GetEnableDriveFs() const override { - return GetParam().enable_drivefs.value_or( - FileManagerBrowserTestBase::GetEnableDriveFs()); - } - bool GetEnableDocumentsProvider() const override { return GetParam().enable_documents_provider.value_or( FileManagerBrowserTestBase::GetEnableDocumentsProvider()); @@ -248,14 +229,11 @@ TestCase("fileDisplayDownloads"), TestCase("fileDisplayDownloads").InGuestMode(), TestCase("fileDisplayDownloads").TabletMode(), - TestCase("fileDisplayDrive").DisableDriveFs(), - TestCase("fileDisplayDrive").TabletMode().DisableDriveFs(), - TestCase("fileDisplayDrive").TabletMode().EnableDriveFs(), - TestCase("fileDisplayDrive").EnableDriveFs(), - TestCase("fileDisplayDriveOffline").Offline().EnableDriveFs(), - TestCase("fileDisplayDriveOnline").EnableDriveFs(), - TestCase("fileDisplayDriveOnline").DisableDriveFs(), - TestCase("fileDisplayComputers").EnableDriveFs(), + TestCase("fileDisplayDrive").TabletMode(), + TestCase("fileDisplayDrive"), + TestCase("fileDisplayDriveOffline").Offline(), + TestCase("fileDisplayDriveOnline"), + TestCase("fileDisplayComputers"), TestCase("fileDisplayMtp"), TestCase("fileDisplayUsb"), TestCase("fileDisplayUsbPartition"), @@ -264,11 +242,8 @@ TestCase("fileDisplayWithoutDownloadsVolume").DontMountVolumes(), TestCase("fileDisplayWithoutVolumes").DontMountVolumes(), TestCase("fileDisplayWithoutVolumesThenMountDownloads") - .DontMountVolumes(), - TestCase("fileDisplayWithoutVolumesThenMountDrive") - .DontMountVolumes() - .EnableDriveFs(), + TestCase("fileDisplayWithoutVolumesThenMountDrive").DontMountVolumes(), TestCase("fileDisplayWithoutDrive").DontMountVolumes(), TestCase("fileDisplayWithoutDriveThenDisable").DontMountVolumes(), TestCase("fileDisplayMountWithFakeItemSelected"), @@ -288,8 +263,7 @@ FilesAppBrowserTest, ::testing::Values(TestCase("videoOpenDownloads").InGuestMode(), TestCase("videoOpenDownloads"), - TestCase("videoOpenDrive").DisableDriveFs(), - TestCase("videoOpenDrive").EnableDriveFs())); + TestCase("videoOpenDrive"))); WRAPPED_INSTANTIATE_TEST_SUITE_P( OpenAudioFiles, /* open_audio_files.js */ @@ -299,8 +273,7 @@ TestCase("audioOpenCloseDrive"), TestCase("audioOpenDownloads").InGuestMode(), TestCase("audioOpenDownloads"), - TestCase("audioOpenDrive").DisableDriveFs(), - TestCase("audioOpenDrive").EnableDriveFs(), + TestCase("audioOpenDrive"), TestCase("audioAutoAdvanceDrive"), TestCase("audioRepeatAllModeSingleFileDrive"), TestCase("audioNoRepeatModeSingleFileDrive"), @@ -314,19 +287,17 @@ FilesAppBrowserTest, ::testing::Values(TestCase("imageOpenDownloads").InGuestMode(), TestCase("imageOpenDownloads"), - TestCase("imageOpenDrive").DisableDriveFs(), - TestCase("imageOpenDrive").EnableDriveFs(), + TestCase("imageOpenDrive"), TestCase("imageOpenGalleryOpenDownloads"), - TestCase("imageOpenGalleryOpenDrive").DisableDriveFs(), - TestCase("imageOpenGalleryOpenDrive").EnableDriveFs())); + TestCase("imageOpenGalleryOpenDrive"))); WRAPPED_INSTANTIATE_TEST_SUITE_P( OpenSniffedFiles, /* open_sniffed_files.js */ FilesAppBrowserTest, ::testing::Values(TestCase("pdfOpenDownloads"), - TestCase("pdfOpenDrive").EnableDriveFs(), + TestCase("pdfOpenDrive"), TestCase("textOpenDownloads"), - TestCase("textOpenDrive").EnableDriveFs())); + TestCase("textOpenDrive"))); // NaCl fails to compile zip plugin.pexe too often on ASAN, crbug.com/867738 // The tests are flaky on the debug bot and always time out first and then pass @@ -345,13 +316,11 @@ ZipCase("zipFileOpenDownloadsMacOs"), ZipCase("zipFileOpenDownloadsWithAbsolutePaths"), ZipCase("zipFileOpenDownloadsEncryptedCancelPassphrase"), - ZipCase("zipFileOpenDrive").DisableDriveFs(), - ZipCase("zipFileOpenDrive").EnableDriveFs(), + ZipCase("zipFileOpenDrive"), ZipCase("zipFileOpenUsb"), ZipCase("zipCreateFileDownloads").InGuestMode(), ZipCase("zipCreateFileDownloads"), - ZipCase("zipCreateFileDrive").DisableDriveFs(), - ZipCase("zipCreateFileDrive").EnableDriveFs(), + ZipCase("zipCreateFileDrive"), ZipCase("zipCreateFileUsb"))); WRAPPED_INSTANTIATE_TEST_SUITE_P( @@ -362,110 +331,65 @@ TestCase("createFolderDownloads").InGuestMode(), TestCase("createFolderDownloads"), TestCase("createFolderNestedDownloads"), - TestCase("createFolderDrive").DisableDriveFs(), - TestCase("createFolderDrive").EnableDriveFs())); + TestCase("createFolderDrive"))); WRAPPED_INSTANTIATE_TEST_SUITE_P( KeyboardOperations, /* keyboard_operations.js */ FilesAppBrowserTest, ::testing::Values(TestCase("keyboardDeleteDownloads").InGuestMode(), TestCase("keyboardDeleteDownloads"), - TestCase("keyboardDeleteDrive").DisableDriveFs(), - TestCase("keyboardDeleteDrive").EnableDriveFs(), + TestCase("keyboardDeleteDrive"), TestCase("keyboardDeleteFolderDownloads").InGuestMode(), TestCase("keyboardDeleteFolderDownloads"), - TestCase("keyboardDeleteFolderDrive").DisableDriveFs(), - TestCase("keyboardDeleteFolderDrive").EnableDriveFs(), + TestCase("keyboardDeleteFolderDrive"), TestCase("keyboardCopyDownloads").InGuestMode(), TestCase("keyboardCopyDownloads"), - TestCase("keyboardCopyDrive").DisableDriveFs(), - TestCase("keyboardCopyDrive").EnableDriveFs(), + TestCase("keyboardCopyDrive"), TestCase("keyboardSelectDriveDirectoryTree"), TestCase("keyboardDisableCopyWhenDialogDisplayed"), TestCase("keyboardOpenNewWindow"), TestCase("keyboardOpenNewWindow").InGuestMode(), TestCase("renameFileDownloads").InGuestMode(), TestCase("renameFileDownloads"), - TestCase("renameFileDrive").DisableDriveFs(), - TestCase("renameFileDrive").EnableDriveFs(), + TestCase("renameFileDrive"), TestCase("renameNewFolderDownloads").InGuestMode(), TestCase("renameNewFolderDownloads"), - TestCase("renameNewFolderDrive").DisableDriveFs(), - TestCase("renameNewFolderDrive").EnableDriveFs())); + TestCase("renameNewFolderDrive"))); WRAPPED_INSTANTIATE_TEST_SUITE_P( ContextMenu, /* context_menu.js for file list */ FilesAppBrowserTest, ::testing::Values( - TestCase("checkDeleteEnabledForReadWriteFile").DisableDriveFs(), - TestCase("checkDeleteDisabledForReadOnlyDocument").DisableDriveFs(), - TestCase("checkDeleteDisabledForReadOnlyFile").DisableDriveFs(), - TestCase("checkDeleteDisabledForReadOnlyFolder").DisableDriveFs(), - TestCase("checkRenameEnabledForReadWriteFile").DisableDriveFs(), - TestCase("checkRenameDisabledForReadOnlyDocument").DisableDriveFs(), - TestCase("checkRenameDisabledForReadOnlyFile").DisableDriveFs(), - TestCase("checkRenameDisabledForReadOnlyFolder").DisableDriveFs(), - TestCase("checkShareEnabledForReadWriteFile").DisableDriveFs(), - TestCase("checkShareEnabledForReadOnlyDocument").DisableDriveFs(), - TestCase("checkShareDisabledForStrictReadOnlyDocument") - .DisableDriveFs(), - TestCase("checkShareEnabledForReadOnlyFile").DisableDriveFs(), - TestCase("checkShareEnabledForReadOnlyFolder").DisableDriveFs(), - TestCase("checkCopyEnabledForReadWriteFile").DisableDriveFs(), - TestCase("checkCopyEnabledForReadOnlyDocument").DisableDriveFs(), - TestCase("checkCopyDisabledForStrictReadOnlyDocument").DisableDriveFs(), - TestCase("checkCopyEnabledForReadOnlyFile").DisableDriveFs(), - TestCase("checkCopyEnabledForReadOnlyFolder").DisableDriveFs(), - TestCase("checkCutEnabledForReadWriteFile").DisableDriveFs(), - TestCase("checkCutDisabledForReadOnlyDocument").DisableDriveFs(), - TestCase("checkCutDisabledForReadOnlyFile").DisableDriveFs(), - TestCase("checkCutDisabledForReadOnlyFolder").DisableDriveFs(), - TestCase("checkPasteIntoFolderEnabledForReadWriteFolder") - .DisableDriveFs(), - TestCase("checkPasteIntoFolderDisabledForReadOnlyFolder") - .DisableDriveFs(), - TestCase("checkContextMenusForInputElements"), - TestCase("checkNewFolderEnabledInsideReadWriteFolder").DisableDriveFs(), - TestCase("checkNewFolderDisabledInsideReadOnlyFolder").DisableDriveFs(), - TestCase("checkPasteEnabledInsideReadWriteFolder").DisableDriveFs(), - TestCase("checkPasteDisabledInsideReadOnlyFolder").DisableDriveFs())); - -WRAPPED_INSTANTIATE_TEST_SUITE_P( - ContextMenu2, /* context_menu.js for file list */ - FilesAppBrowserTest, - ::testing::Values( - TestCase("checkDeleteEnabledForReadWriteFile").EnableDriveFs(), - TestCase("checkDeleteDisabledForReadOnlyDocument").EnableDriveFs(), - TestCase("checkDeleteDisabledForReadOnlyFile").EnableDriveFs(), - TestCase("checkDeleteDisabledForReadOnlyFolder").EnableDriveFs(), - TestCase("checkRenameEnabledForReadWriteFile").EnableDriveFs(), - TestCase("checkRenameDisabledForReadOnlyDocument").EnableDriveFs(), - TestCase("checkRenameDisabledForReadOnlyFile").EnableDriveFs(), - TestCase("checkRenameDisabledForReadOnlyFolder").EnableDriveFs(), - TestCase("checkShareEnabledForReadWriteFile").EnableDriveFs(), - TestCase("checkShareEnabledForReadOnlyDocument").EnableDriveFs(), - TestCase("checkShareDisabledForStrictReadOnlyDocument").EnableDriveFs(), - TestCase("checkShareEnabledForReadOnlyFile").EnableDriveFs(), - TestCase("checkShareEnabledForReadOnlyFolder").EnableDriveFs(), - TestCase("checkCopyEnabledForReadWriteFile").EnableDriveFs(), - TestCase("checkCopyEnabledForReadOnlyDocument").EnableDriveFs(), - TestCase("checkCopyDisabledForStrictReadOnlyDocument").EnableDriveFs(), - TestCase("checkCopyEnabledForReadOnlyFile").EnableDriveFs(), - TestCase("checkCopyEnabledForReadOnlyFolder").EnableDriveFs(), - TestCase("checkCutEnabledForReadWriteFile").EnableDriveFs(), - TestCase("checkCutDisabledForReadOnlyDocument").EnableDriveFs(), - TestCase("checkCutDisabledForReadOnlyFile").EnableDriveFs(), - TestCase("checkCutDisabledForReadOnlyFolder").EnableDriveFs(), - TestCase("checkPasteIntoFolderEnabledForReadWriteFolder") - .EnableDriveFs(), - TestCase("checkPasteIntoFolderDisabledForReadOnlyFolder") - .EnableDriveFs(), - TestCase("checkInstallWithLinuxDisabledForDebianFile").EnableDriveFs(), - TestCase("checkInstallWithLinuxEnabledForDebianFile").EnableDriveFs(), - TestCase("checkNewFolderEnabledInsideReadWriteFolder").EnableDriveFs(), - TestCase("checkNewFolderDisabledInsideReadOnlyFolder").EnableDriveFs(), - TestCase("checkPasteEnabledInsideReadWriteFolder").EnableDriveFs(), - TestCase("checkPasteDisabledInsideReadOnlyFolder").EnableDriveFs(), + TestCase("checkDeleteEnabledForReadWriteFile"), + TestCase("checkDeleteDisabledForReadOnlyDocument"), + TestCase("checkDeleteDisabledForReadOnlyFile"), + TestCase("checkDeleteDisabledForReadOnlyFolder"), + TestCase("checkRenameEnabledForReadWriteFile"), + TestCase("checkRenameDisabledForReadOnlyDocument"), + TestCase("checkRenameDisabledForReadOnlyFile"), + TestCase("checkRenameDisabledForReadOnlyFolder"), + TestCase("checkShareEnabledForReadWriteFile"), + TestCase("checkShareEnabledForReadOnlyDocument"), + TestCase("checkShareDisabledForStrictReadOnlyDocument"), + TestCase("checkShareEnabledForReadOnlyFile"), + TestCase("checkShareEnabledForReadOnlyFolder"), + TestCase("checkCopyEnabledForReadWriteFile"), + TestCase("checkCopyEnabledForReadOnlyDocument"), + TestCase("checkCopyDisabledForStrictReadOnlyDocument"), + TestCase("checkCopyEnabledForReadOnlyFile"), + TestCase("checkCopyEnabledForReadOnlyFolder"), + TestCase("checkCutEnabledForReadWriteFile"), + TestCase("checkCutDisabledForReadOnlyDocument"), + TestCase("checkCutDisabledForReadOnlyFile"), + TestCase("checkCutDisabledForReadOnlyFolder"), + TestCase("checkPasteIntoFolderEnabledForReadWriteFolder"), + TestCase("checkPasteIntoFolderDisabledForReadOnlyFolder"), + TestCase("checkInstallWithLinuxDisabledForDebianFile"), + TestCase("checkInstallWithLinuxEnabledForDebianFile"), + TestCase("checkNewFolderEnabledInsideReadWriteFolder"), + TestCase("checkNewFolderDisabledInsideReadOnlyFolder"), + TestCase("checkPasteEnabledInsideReadWriteFolder"), + TestCase("checkPasteDisabledInsideReadOnlyFolder"), TestCase("checkDownloadsContextMenu"), TestCase("checkPlayFilesContextMenu"), TestCase("checkLinuxFilesContextMenu"), @@ -508,8 +432,7 @@ TestCase("openQuickViewScrollHtml"), TestCase("openQuickViewBackgroundColorText"), TestCase("openQuickViewBackgroundColorHtml"), - TestCase("openQuickViewDrive").DisableDriveFs(), - TestCase("openQuickViewDrive").EnableDriveFs(), + TestCase("openQuickViewDrive"), TestCase("openQuickViewAndroid"), TestCase("openQuickViewDocumentsProvider").EnableDocumentsProvider(), TestCase("openQuickViewCrostini"), @@ -552,13 +475,11 @@ TestCase("dirRenameToEmptyString").InGuestMode(), TestCase("dirRenameToEmptyString"), TestCase("dirRenameToExisting").InGuestMode(), - TestCase("dirRenameToExisting").EnableDriveFs(), + TestCase("dirRenameToExisting"), TestCase("dirRenameRemovableWithKeyboard"), TestCase("dirRenameRemovableWithKeyboard").InGuestMode(), - TestCase("dirRenameRemovableWithKeyboard").EnableDriveFs(), TestCase("dirRenameRemovableWithContentMenu"), TestCase("dirRenameRemovableWithContentMenu").InGuestMode(), - TestCase("dirRenameRemovableWithContentMenu").EnableDriveFs(), TestCase("dirCreateWithContextMenu"), TestCase("dirCreateWithKeyboard"), TestCase("dirCreateWithoutChangingCurrent"), @@ -590,65 +511,42 @@ WRAPPED_INSTANTIATE_TEST_SUITE_P( DriveSpecific, /* drive_specific.js */ FilesAppBrowserTest, - ::testing::Values( - TestCase("driveOpenSidebarOffline").DisableDriveFs(), - TestCase("driveOpenSidebarOffline").EnableDriveFs(), - TestCase("driveOpenSidebarSharedWithMe").DisableDriveFs(), - TestCase("driveOpenSidebarSharedWithMe").EnableDriveFs(), - TestCase("driveAutoCompleteQuery").DisableDriveFs(), - TestCase("driveAutoCompleteQuery").EnableDriveFs(), - TestCase("drivePinFileMobileNetwork").DisableDriveFs(), - TestCase("drivePinFileMobileNetwork").EnableDriveFs(), - TestCase("driveClickFirstSearchResult").DisableDriveFs(), - TestCase("driveClickFirstSearchResult").EnableDriveFs(), - TestCase("drivePressEnterToSearch").DisableDriveFs(), - TestCase("drivePressEnterToSearch").EnableDriveFs(), - TestCase("drivePressClearSearch").EnableDriveFs(), - TestCase("drivePressCtrlAFromSearch").DisableDriveFs(), - TestCase("drivePressCtrlAFromSearch").EnableDriveFs(), - TestCase("driveBackupPhotos").DisableDriveFs(), - TestCase("driveBackupPhotos").EnableDriveFs(), - TestCase("driveAvailableOfflineGearMenu").DisableDriveFs(), - TestCase("driveAvailableOfflineGearMenu").EnableDriveFs(), - TestCase("driveAvailableOfflineDirectoryGearMenu"), - TestCase("driveLinkToDirectory").EnableDriveFs(), - TestCase("driveLinkOpenFileThroughLinkedDirectory").EnableDriveFs(), - TestCase("driveLinkOpenFileThroughTransitiveLink").EnableDriveFs())); + ::testing::Values(TestCase("driveOpenSidebarOffline"), + TestCase("driveOpenSidebarSharedWithMe"), + TestCase("driveAutoCompleteQuery"), + TestCase("drivePinFileMobileNetwork"), + TestCase("driveClickFirstSearchResult"), + TestCase("drivePressEnterToSearch"), + TestCase("drivePressClearSearch"), + TestCase("drivePressCtrlAFromSearch"), + TestCase("driveBackupPhotos"), + TestCase("driveAvailableOfflineGearMenu"), + TestCase("driveAvailableOfflineDirectoryGearMenu"), + TestCase("driveLinkToDirectory"), + TestCase("driveLinkOpenFileThroughLinkedDirectory"), + TestCase("driveLinkOpenFileThroughTransitiveLink"))); WRAPPED_INSTANTIATE_TEST_SUITE_P( Transfer, /* transfer.js */ FilesAppBrowserTest, - ::testing::Values( - TestCase("transferFromDriveToDownloads").DisableDriveFs(), - TestCase("transferFromDriveToDownloads").EnableDriveFs(), - TestCase("transferFromDownloadsToMyFiles"), - TestCase("transferFromDownloadsToMyFilesMove"), - TestCase("transferFromDownloadsToDrive").DisableDriveFs(), - TestCase("transferFromDownloadsToDrive").EnableDriveFs(), - TestCase("transferFromSharedToDownloads").DisableDriveFs(), - TestCase("transferFromSharedToDownloads").EnableDriveFs(), - TestCase("transferFromSharedToDrive").DisableDriveFs(), - TestCase("transferFromSharedToDrive").EnableDriveFs(), - TestCase("transferFromOfflineToDownloads").DisableDriveFs(), - TestCase("transferFromOfflineToDownloads").EnableDriveFs(), - TestCase("transferFromOfflineToDrive").DisableDriveFs(), - TestCase("transferFromOfflineToDrive").EnableDriveFs(), - TestCase("transferFromTeamDriveToDrive").DisableDriveFs(), - TestCase("transferFromTeamDriveToDrive").EnableDriveFs(), - TestCase("transferFromDriveToTeamDrive").DisableDriveFs(), - TestCase("transferFromDriveToTeamDrive").EnableDriveFs(), - TestCase("transferFromTeamDriveToDownloads").DisableDriveFs(), - TestCase("transferFromTeamDriveToDownloads").EnableDriveFs(), - TestCase("transferHostedFileFromTeamDriveToDownloads").DisableDriveFs(), - TestCase("transferHostedFileFromTeamDriveToDownloads").EnableDriveFs(), - TestCase("transferFromDownloadsToTeamDrive").DisableDriveFs(), - TestCase("transferFromDownloadsToTeamDrive").EnableDriveFs(), - TestCase("transferBetweenTeamDrives").DisableDriveFs(), - TestCase("transferBetweenTeamDrives").EnableDriveFs(), - TestCase("transferDragAndDrop"), - TestCase("transferDragAndHover"), - TestCase("transferFromDownloadsToDownloads"), - TestCase("transferDeletedFile"))); + ::testing::Values(TestCase("transferFromDriveToDownloads"), + TestCase("transferFromDownloadsToMyFiles"), + TestCase("transferFromDownloadsToMyFilesMove"), + TestCase("transferFromDownloadsToDrive"), + TestCase("transferFromSharedToDownloads"), + TestCase("transferFromSharedToDrive"), + TestCase("transferFromOfflineToDownloads"), + TestCase("transferFromOfflineToDrive"), + TestCase("transferFromTeamDriveToDrive"), + TestCase("transferFromDriveToTeamDrive"), + TestCase("transferFromTeamDriveToDownloads"), + TestCase("transferHostedFileFromTeamDriveToDownloads"), + TestCase("transferFromDownloadsToTeamDrive"), + TestCase("transferBetweenTeamDrives"), + TestCase("transferDragAndDrop"), + TestCase("transferDragAndHover"), + TestCase("transferFromDownloadsToDownloads"), + TestCase("transferDeletedFile"))); WRAPPED_INSTANTIATE_TEST_SUITE_P( RestorePrefs, /* restore_prefs.js */ @@ -668,17 +566,12 @@ WRAPPED_INSTANTIATE_TEST_SUITE_P( ShareAndManageDialog, /* share_and_manage_dialog.js */ FilesAppBrowserTest, - ::testing::Values(TestCase("shareFileDrive").DisableDriveFs(), - TestCase("shareFileDrive").EnableDriveFs(), - TestCase("shareDirectoryDrive").DisableDriveFs(), - TestCase("shareDirectoryDrive").EnableDriveFs(), + ::testing::Values(TestCase("shareFileDrive"), + TestCase("shareDirectoryDrive"), TestCase("shareHostedFileDrive"), - TestCase("manageHostedFileDrive").DisableDriveFs(), - TestCase("manageHostedFileDrive").EnableDriveFs(), - TestCase("manageFileDrive").DisableDriveFs(), - TestCase("manageFileDrive").EnableDriveFs(), - TestCase("manageDirectoryDrive").DisableDriveFs(), - TestCase("manageDirectoryDrive").EnableDriveFs(), + TestCase("manageHostedFileDrive"), + TestCase("manageFileDrive"), + TestCase("manageDirectoryDrive"), TestCase("shareFileTeamDrive"), TestCase("shareDirectoryTeamDrive"), TestCase("shareHostedFileTeamDrive"), @@ -698,32 +591,27 @@ FilesAppBrowserTest, ::testing::Values(TestCase("traverseDownloads").InGuestMode(), TestCase("traverseDownloads"), - TestCase("traverseDrive").DisableDriveFs(), - TestCase("traverseDrive").EnableDriveFs())); + TestCase("traverseDrive"))); WRAPPED_INSTANTIATE_TEST_SUITE_P( Tasks, /* tasks.js */ FilesAppBrowserTest, ::testing::Values(TestCase("executeDefaultTaskDownloads"), TestCase("executeDefaultTaskDownloads").InGuestMode(), - TestCase("executeDefaultTaskDrive").DisableDriveFs(), - TestCase("executeDefaultTaskDrive").EnableDriveFs(), + TestCase("executeDefaultTaskDrive"), TestCase("defaultTaskForPdf"), TestCase("defaultTaskForTextPlain"), TestCase("defaultTaskDialogDownloads"), TestCase("defaultTaskDialogDownloads").InGuestMode(), - TestCase("defaultTaskDialogDrive").DisableDriveFs(), - TestCase("defaultTaskDialogDrive").EnableDriveFs(), + TestCase("defaultTaskDialogDrive"), TestCase("genericTaskIsNotExecuted"), TestCase("genericTaskAndNonGenericTask"))); WRAPPED_INSTANTIATE_TEST_SUITE_P( FolderShortcuts, /* folder_shortcuts.js */ FilesAppBrowserTest, - ::testing::Values(TestCase("traverseFolderShortcuts").DisableDriveFs(), - TestCase("traverseFolderShortcuts").EnableDriveFs(), - TestCase("addRemoveFolderShortcuts").DisableDriveFs(), - TestCase("addRemoveFolderShortcuts").EnableDriveFs())); + ::testing::Values(TestCase("traverseFolderShortcuts"), + TestCase("addRemoveFolderShortcuts"))); WRAPPED_INSTANTIATE_TEST_SUITE_P( SortColumns, /* sort_columns.js */ @@ -741,11 +629,9 @@ TestCase("tabindexFocusDownloads").InGuestMode(), TestCase("tabindexFocusBreadcrumbBackground"), TestCase("tabindexFocusDirectorySelected"), - TestCase("tabindexOpenDialogDrive").WithBrowser().DisableDriveFs(), TestCase("tabindexOpenDialogDownloads").WithBrowser(), TestCase("tabindexOpenDialogDownloads").WithBrowser().InGuestMode(), - TestCase("tabindexSaveFileDialogDrive").WithBrowser().DisableDriveFs(), - TestCase("tabindexSaveFileDialogDrive").WithBrowser().EnableDriveFs(), + TestCase("tabindexSaveFileDialogDrive").WithBrowser(), TestCase("tabindexSaveFileDialogDownloads").WithBrowser(), TestCase("tabindexSaveFileDialogDownloads") .WithBrowser() @@ -767,48 +653,19 @@ TestCase("saveFileDialogPanelsDisabled").WithBrowser(), TestCase("openFileDialogCancelDownloads").WithBrowser(), TestCase("openFileDialogEscapeDownloads").WithBrowser(), - TestCase("openFileDialogDrive").WithBrowser().DisableDriveFs(), - TestCase("openFileDialogDrive") - .WithBrowser() - .InIncognito() - .DisableDriveFs(), - TestCase("openFileDialogDrive").WithBrowser().EnableDriveFs(), - TestCase("openFileDialogDrive") - .WithBrowser() - .InIncognito() - .EnableDriveFs(), + TestCase("openFileDialogDrive").WithBrowser(), + TestCase("openFileDialogDrive").WithBrowser().InIncognito(), TestCase("saveFileDialogDrive").WithBrowser(), TestCase("saveFileDialogDrive").WithBrowser().InIncognito(), - TestCase("openFileDialogDriveFromBrowser") - .WithBrowser() - .EnableDriveFs(), - TestCase("openFileDialogDriveFromBrowser") - .WithBrowser() - .DisableDriveFs(), - TestCase("openFileDialogDriveHostedDoc").WithBrowser().EnableDriveFs(), - TestCase("openFileDialogDriveHostedDoc").WithBrowser().DisableDriveFs(), - TestCase("openFileDialogDriveHostedNeedsFile") - .WithBrowser() - .EnableDriveFs(), - TestCase("saveFileDialogDriveHostedNeedsFile") - .WithBrowser() - .EnableDriveFs(), - TestCase("openFileDialogDriveHostedNeedsFile") - .WithBrowser() - .DisableDriveFs(), - TestCase("openFileDialogCancelDrive").WithBrowser().DisableDriveFs(), - TestCase("openFileDialogCancelDrive").WithBrowser().EnableDriveFs(), - TestCase("openFileDialogEscapeDrive").WithBrowser().DisableDriveFs(), - TestCase("openFileDialogEscapeDrive").WithBrowser().EnableDriveFs(), - TestCase("openFileDialogDriveOffline") - .WithBrowser() - .Offline() - .EnableDriveFs(), + TestCase("openFileDialogDriveFromBrowser").WithBrowser(), + TestCase("openFileDialogDriveHostedDoc").WithBrowser(), + TestCase("openFileDialogDriveHostedNeedsFile").WithBrowser(), + TestCase("saveFileDialogDriveHostedNeedsFile").WithBrowser(), + TestCase("openFileDialogCancelDrive").WithBrowser(), + TestCase("openFileDialogEscapeDrive").WithBrowser(), + TestCase("openFileDialogDriveOffline").WithBrowser().Offline(), TestCase("saveFileDialogDriveOffline").WithBrowser().Offline(), - TestCase("openFileDialogDriveOfflinePinned") - .WithBrowser() - .Offline() - .EnableDriveFs(), + TestCase("openFileDialogDriveOfflinePinned").WithBrowser().Offline(), TestCase("saveFileDialogDriveOfflinePinned").WithBrowser().Offline(), TestCase("openFileDialogDefaultFilter").WithBrowser(), TestCase("saveFileDialogDefaultFilter").WithBrowser(), @@ -817,25 +674,19 @@ WRAPPED_INSTANTIATE_TEST_SUITE_P( CopyBetweenWindows, /* copy_between_windows.js */ FilesAppBrowserTest, - ::testing::Values( - TestCase("copyBetweenWindowsLocalToDrive").DisableDriveFs(), - TestCase("copyBetweenWindowsLocalToDrive").EnableDriveFs(), - TestCase("copyBetweenWindowsLocalToUsb"), - TestCase("copyBetweenWindowsUsbToDrive").DisableDriveFs(), - TestCase("copyBetweenWindowsUsbToDrive").EnableDriveFs(), - TestCase("copyBetweenWindowsDriveToLocal").DisableDriveFs(), - TestCase("copyBetweenWindowsDriveToLocal").EnableDriveFs(), - TestCase("copyBetweenWindowsDriveToUsb").DisableDriveFs(), - TestCase("copyBetweenWindowsDriveToUsb").EnableDriveFs(), - TestCase("copyBetweenWindowsUsbToLocal"))); + ::testing::Values(TestCase("copyBetweenWindowsLocalToDrive"), + TestCase("copyBetweenWindowsLocalToUsb"), + TestCase("copyBetweenWindowsUsbToDrive"), + TestCase("copyBetweenWindowsDriveToLocal"), + TestCase("copyBetweenWindowsDriveToUsb"), + TestCase("copyBetweenWindowsUsbToLocal"))); WRAPPED_INSTANTIATE_TEST_SUITE_P( GridView, /* grid_view.js */ FilesAppBrowserTest, ::testing::Values(TestCase("showGridViewDownloads"), TestCase("showGridViewDownloads").InGuestMode(), - TestCase("showGridViewDrive").DisableDriveFs(), - TestCase("showGridViewDrive").EnableDriveFs(), + TestCase("showGridViewDrive"), TestCase("showGridViewButtonSwitches"), TestCase("showGridViewKeyboardSelectionA11y"), TestCase("showGridViewMouseSelectionA11y"))); @@ -862,8 +713,7 @@ ::testing::Values( TestCase("showHiddenFilesDownloads"), TestCase("showHiddenFilesDownloads").InGuestMode(), - TestCase("showHiddenFilesDrive").DisableDriveFs(), - TestCase("showHiddenFilesDrive").EnableDriveFs(), + TestCase("showHiddenFilesDrive"), TestCase("showPasteIntoCurrentFolder"), TestCase("showSelectAllInCurrentFolder"), TestCase("showToggleHiddenAndroidFoldersGearMenuItemsInMyFiles"), @@ -925,16 +775,12 @@ WRAPPED_INSTANTIATE_TEST_SUITE_P( Recents, /* recents.js */ FilesAppBrowserTest, - ::testing::Values( - TestCase("recentsDownloads"), - TestCase("recentsDrive").DisableDriveFs(), - TestCase("recentsDrive").EnableDriveFs(), - TestCase("recentsCrostiniNotMounted"), - TestCase("recentsCrostiniMounted"), - TestCase("recentsDownloadsAndDrive").DisableDriveFs(), - TestCase("recentsDownloadsAndDrive").EnableDriveFs(), - TestCase("recentsDownloadsAndDriveWithOverlap").DisableDriveFs(), - TestCase("recentsDownloadsAndDriveWithOverlap").EnableDriveFs())); + ::testing::Values(TestCase("recentsDownloads"), + TestCase("recentsDrive"), + TestCase("recentsCrostiniNotMounted"), + TestCase("recentsCrostiniMounted"), + TestCase("recentsDownloadsAndDrive"), + TestCase("recentsDownloadsAndDriveWithOverlap"))); WRAPPED_INSTANTIATE_TEST_SUITE_P( Metadata, /* metadata.js */ @@ -942,12 +788,9 @@ ::testing::Values( TestCase("metadataDocumentsProvider").EnableDocumentsProvider(), TestCase("metadataDownloads"), - TestCase("metadataDrive").DisableDriveFs(), - TestCase("metadataDrive").EnableDriveFs(), - TestCase("metadataTeamDrives").DisableDriveFs(), - TestCase("metadataTeamDrives").EnableDriveFs(), - TestCase("metadataLargeDrive").DisableDriveFs(), - TestCase("metadataLargeDrive").EnableDriveFs())); + TestCase("metadataDrive"), + TestCase("metadataTeamDrives"), + TestCase("metadataLargeDrive"))); WRAPPED_INSTANTIATE_TEST_SUITE_P( Search, /* search.js */ @@ -978,223 +821,4 @@ TestCase("formatDialogNameInvalid").EnableFormatDialog(), TestCase("formatDialogGearMenu").EnableFormatDialog())); -// Structure to describe an account info. -struct TestAccountInfo { - const char* const gaia_id; - const char* const email; - const char* const hash; - const char* const display_name; -}; - -enum { - DUMMY_ACCOUNT_INDEX = 0, - PRIMARY_ACCOUNT_INDEX = 1, - SECONDARY_ACCOUNT_INDEX_START = 2, -}; - -static const TestAccountInfo kTestAccounts[] = { - {"gaia-id-d", "__dummy__@invalid.domain", "hashdummy", "Dummy Account"}, - {"gaia-id-a", "alice@invalid.domain", "hashalice", "Alice"}, - {"gaia-id-b", "bob@invalid.domain", "hashbob", "Bob"}, - {"gaia-id-c", "charlie@invalid.domain", "hashcharlie", "Charlie"}, -}; - -// Test fixture class for testing multi-profile features. -class MultiProfileFilesAppBrowserTest : public FileManagerBrowserTestBase { - public: - MultiProfileFilesAppBrowserTest() = default; - - protected: - // Enables multi-profiles. - void SetUpCommandLine(base::CommandLine* command_line) override { - FileManagerBrowserTestBase::SetUpCommandLine(command_line); - // Logs in to a dummy profile (For making MultiProfileWindowManager happy; - // browser test creates a default window and the manager tries to assign a - // user for it, and we need a profile connected to a user.) - command_line->AppendSwitchASCII(chromeos::switches::kLoginUser, - kTestAccounts[DUMMY_ACCOUNT_INDEX].email); - command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile, - kTestAccounts[DUMMY_ACCOUNT_INDEX].hash); - // Don't require policy for our sessions - this is required because - // this test creates a secondary profile synchronously, so we need to - // let the policy code know not to expect cached policy. - command_line->AppendSwitchASCII(chromeos::switches::kProfileRequiresPolicy, - "false"); - } - - // Logs in to the primary profile of this test. - void SetUpOnMainThread() override { - const TestAccountInfo& info = kTestAccounts[PRIMARY_ACCOUNT_INDEX]; - - AddUser(info, true); - FileManagerBrowserTestBase::SetUpOnMainThread(); - } - - // Loads all users to the current session and sets up necessary fields. - // This is used for preparing all accounts in PRE_ test setup, and for testing - // actual login behavior. - void AddAllUsers() { - for (size_t i = 0; i < base::size(kTestAccounts); ++i) { - // The primary account was already set up in SetUpOnMainThread, so skip it - // here. - if (i == PRIMARY_ACCOUNT_INDEX) - continue; - AddUser(kTestAccounts[i], i >= SECONDARY_ACCOUNT_INDEX_START); - } - } - - // Returns primary profile (if it is already created.) - Profile* profile() override { - Profile* const profile = - chromeos::ProfileHelper::GetProfileByUserIdHashForTest( - kTestAccounts[PRIMARY_ACCOUNT_INDEX].hash); - return profile ? profile : FileManagerBrowserTestBase::profile(); - } - - // Adds a new user for testing to the current session. - void AddUser(const TestAccountInfo& info, bool log_in) { - base::ScopedAllowBlockingForTesting allow_blocking; - const AccountId account_id( - AccountId::FromUserEmailGaiaId(info.email, info.gaia_id)); - user_manager::User* user = - user_manager::User::CreateRegularUserForTesting(account_id); - static_cast<user_manager::UserManagerBase*>( - user_manager::UserManager::Get()) - ->AddUserRecordForTesting(user); - if (log_in) { - session_manager::SessionManager::Get()->CreateSession(account_id, - info.hash, false); - } - chromeos::ProfileHelper::Get()->SetUserToProfileMappingForTesting( - user, profile()); - user_manager::UserManager::Get()->SaveUserDisplayName( - account_id, base::UTF8ToUTF16(info.display_name)); - Profile* profile = - chromeos::ProfileHelper::GetProfileByUserIdHashForTest(info.hash); - signin::IdentityManager* identity_manager = - IdentityManagerFactory::GetForProfile(profile); - if (!identity_manager->HasPrimaryAccount()) - signin::MakePrimaryAccountAvailable(identity_manager, info.email); - } - - GuestMode GetGuestMode() const override { return NOT_IN_GUEST_MODE; } - - bool GetEnableDriveFs() const override { return false; } - - const char* GetTestCaseName() const override { - return test_case_name_.c_str(); - } - - std::string GetFullTestCaseName() const override { return test_case_name_; } - - const char* GetTestExtensionManifestName() const override { - return "file_manager_test_manifest.json"; - } - - void set_test_case_name(const std::string& name) { test_case_name_ = name; } - - private: - std::string test_case_name_; - - DISALLOW_COPY_AND_ASSIGN(MultiProfileFilesAppBrowserTest); -}; - -IN_PROC_BROWSER_TEST_F(MultiProfileFilesAppBrowserTest, PRE_BasicDownloads) { - AddAllUsers(); -} - -IN_PROC_BROWSER_TEST_F(MultiProfileFilesAppBrowserTest, BasicDownloads) { - AddAllUsers(); - // Sanity check that normal operations work in multi-profile. - set_test_case_name("keyboardCopyDownloads"); - StartTest(); -} - -IN_PROC_BROWSER_TEST_F(MultiProfileFilesAppBrowserTest, PRE_BasicDrive) { - AddAllUsers(); -} - -IN_PROC_BROWSER_TEST_F(MultiProfileFilesAppBrowserTest, BasicDrive) { - AddAllUsers(); - // Sanity check that normal operations work in multi-profile. - set_test_case_name("keyboardCopyDrive"); - StartTest(); -} - -// Test fixture class for testing migration to DriveFS. -class DriveFsFilesAppBrowserTest : public FileManagerBrowserTestBase { - public: - DriveFsFilesAppBrowserTest() = default; - - protected: - GuestMode GetGuestMode() const override { return NOT_IN_GUEST_MODE; } - - const char* GetTestCaseName() const override { - return test_case_name_.c_str(); - } - - std::string GetFullTestCaseName() const override { return test_case_name_; } - - const char* GetTestExtensionManifestName() const override { - return "file_manager_test_manifest.json"; - } - - void set_test_case_name(const std::string& name) { test_case_name_ = name; } - - bool GetEnableDriveFs() const override { - return !base::StringPiece( - ::testing::UnitTest::GetInstance()->current_test_info()->name()) - .starts_with("PRE"); - } - - base::FilePath GetDriveDataDirectory() { - return profile()->GetPath().Append("drive/v1"); - } - - private: - std::string test_case_name_; - - DISALLOW_COPY_AND_ASSIGN(DriveFsFilesAppBrowserTest); -}; - -IN_PROC_BROWSER_TEST_F(DriveFsFilesAppBrowserTest, PRE_MigratePinnedFiles) { - set_test_case_name("PRE_driveMigratePinnedFile"); - StartTest(); -} - -IN_PROC_BROWSER_TEST_F(DriveFsFilesAppBrowserTest, MigratePinnedFiles) { - set_test_case_name("driveMigratePinnedFile"); - StartTest(); - - base::ScopedAllowBlockingForTesting allow_io; - EXPECT_TRUE(base::IsDirectoryEmpty(GetDriveDataDirectory())); -} - -IN_PROC_BROWSER_TEST_F(DriveFsFilesAppBrowserTest, PRE_RecoverDirtyFiles) { - set_test_case_name("PRE_driveRecoverDirtyFiles"); - StartTest(); - - { - base::ScopedAllowBlockingForTesting allow_io; - - // Create a non-dirty file in the cache. - base::WriteFile(GetDriveDataDirectory().Append("files/foo"), "data", 4); - } -} - -IN_PROC_BROWSER_TEST_F(DriveFsFilesAppBrowserTest, RecoverDirtyFiles) { - set_test_case_name("driveRecoverDirtyFiles"); - StartTest(); - - base::ScopedAllowBlockingForTesting allow_io; - EXPECT_TRUE(base::IsDirectoryEmpty(GetDriveDataDirectory())); -} - -IN_PROC_BROWSER_TEST_F(DriveFsFilesAppBrowserTest, LaunchWithoutOldDriveData) { - base::ScopedAllowBlockingForTesting allow_io; - - // After starting up, GCache/v1 should still be empty. - EXPECT_TRUE(base::IsDirectoryEmpty(GetDriveDataDirectory())); -} - } // namespace file_manager
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc index 1c110744..e99e1982 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
@@ -1534,12 +1534,6 @@ disabled_features.emplace_back(features::kNativeSmb); } - if (IsDriveFsTest()) { - enabled_features.emplace_back(chromeos::features::kDriveFs); - } else { - disabled_features.emplace_back(chromeos::features::kDriveFs); - } - if (IsArcTest()) { arc::SetArcAvailableCommandLineForTesting(command_line); } @@ -1712,10 +1706,6 @@ return false; } -bool FileManagerBrowserTestBase::GetEnableDriveFs() const { - return true; -} - bool FileManagerBrowserTestBase::GetEnableDocumentsProvider() const { return false; } @@ -1827,11 +1817,6 @@ return; } - if (name == "getDriveFsEnabled") { - *output = IsDriveFsTest() ? "true" : "false"; - return; - } - if (name == "zipArchiverLoaded") { if (IsZipTest()) { LOG(INFO) << "Preloading zip archiver NaCl module";
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.h b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.h index 8a6bca5b..36632a0 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.h +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.h
@@ -59,7 +59,6 @@ // Optional overrides for each File Manager test extension type. virtual bool GetTabletMode() const; - virtual bool GetEnableDriveFs() const; virtual bool GetEnableDocumentsProvider() const; virtual bool GetEnableArc() const; virtual bool GetEnableFormatDialog() const; @@ -87,9 +86,6 @@ // Returns true if the test runs in tablet mode. bool IsTabletModeTest() const { return GetTabletMode(); } - // Returns true if the test requires DriveFS. - bool IsDriveFsTest() const { return GetEnableDriveFs(); } - // Returns true if the test requires Android documents providers. bool IsDocumentsProviderTest() const { return GetEnableDocumentsProvider(); }
diff --git a/chrome/browser/chromeos/policy/display_resolution_handler_browsertest.cc b/chrome/browser/chromeos/policy/display_resolution_handler_browsertest.cc index 6c239a6..6a5ca1e 100644 --- a/chrome/browser/chromeos/policy/display_resolution_handler_browsertest.cc +++ b/chrome/browser/chromeos/policy/display_resolution_handler_browsertest.cc
@@ -283,7 +283,8 @@ DISALLOW_COPY_AND_ASSIGN(DeviceDisplayResolutionTest); }; -IN_PROC_BROWSER_TEST_P(DeviceDisplayResolutionTest, Internal) { +// crbug.com/1000694. +IN_PROC_BROWSER_TEST_P(DeviceDisplayResolutionTest, DISABLED_Internal) { const PolicyValue policy_value = GetParam(); EXPECT_EQ(kDefaultDisplayScale, GetScaleOfInternalDisplay()) @@ -300,7 +301,9 @@ << "Scale of primary display after policy"; } -IN_PROC_BROWSER_TEST_P(DeviceDisplayResolutionTest, ResizeExternalDisplay) { +// crbug.com/1000694. +IN_PROC_BROWSER_TEST_P(DeviceDisplayResolutionTest, + DISABLED_ResizeExternalDisplay) { const PolicyValue policy_value = GetParam(); AddExternalDisplay(); @@ -328,7 +331,9 @@ << "Primary display scale after resizing external"; } -IN_PROC_BROWSER_TEST_P(DeviceDisplayResolutionTest, ConnectExternalDisplay) { +// crbug.com/1000694. +IN_PROC_BROWSER_TEST_P(DeviceDisplayResolutionTest, + DISABLED_ConnectExternalDisplay) { const PolicyValue policy_value = GetParam(); SetPolicy(policy_value); @@ -348,7 +353,9 @@ << "Primary display scale after connecting external"; } -IN_PROC_BROWSER_TEST_P(DeviceDisplayResolutionTest, SetAndUnsetPolicy) { +// crbug.com/1000694. +IN_PROC_BROWSER_TEST_P(DeviceDisplayResolutionTest, + DISABLED_SetAndUnsetPolicy) { const PolicyValue policy_value = GetParam(); AddExternalDisplay(); SetPolicy(policy_value); @@ -441,7 +448,8 @@ << "Initial primary display scale after policy set"; } -IN_PROC_BROWSER_TEST_P(DisplayResolutionBootTest, Reboot) { +// crbug.com/1000694. +IN_PROC_BROWSER_TEST_P(DisplayResolutionBootTest, DISABLED_Reboot) { const PolicyValue policy_value = GetParam(); AddExternalDisplay(); @@ -494,7 +502,9 @@ DISALLOW_COPY_AND_ASSIGN(DeviceDisplayResolutionRecommendedTest); }; -IN_PROC_BROWSER_TEST_P(DeviceDisplayResolutionRecommendedTest, Internal) { +// crbug.com/1000694. +IN_PROC_BROWSER_TEST_P(DeviceDisplayResolutionRecommendedTest, + DISABLED_Internal) { const PolicyValue policy_value = GetParam(); EXPECT_EQ(kDefaultDisplayResolution, GetResolutionOfInternalDisplay()) << "Initial primary display resolution before policy"; @@ -518,8 +528,9 @@ << "Scale of internal display after user operation"; } +// crbug.com/1000694. IN_PROC_BROWSER_TEST_P(DeviceDisplayResolutionRecommendedTest, - ResizeExternalDisplay) { + DISABLED_ResizeExternalDisplay) { const PolicyValue policy_value = GetParam(); AddExternalDisplay();
diff --git a/chrome/browser/extensions/active_tab_apitest.cc b/chrome/browser/extensions/active_tab_apitest.cc index ba85bf4..c005973 100644 --- a/chrome/browser/extensions/active_tab_apitest.cc +++ b/chrome/browser/extensions/active_tab_apitest.cc
@@ -9,7 +9,6 @@ #include "base/macros.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" -#include "base/test/scoped_feature_list.h" #include "chrome/browser/extensions/extension_action_runner.h" #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/extensions/extension_service.h" @@ -30,7 +29,6 @@ #include "net/base/filename_util.h" #include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/embedded_test_server.h" -#include "services/network/public/cpp/features.h" #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/extensions/extension_tab_util_delegate_chromeos.h" @@ -40,51 +38,24 @@ namespace extensions { namespace { -enum class TestMode { - kWithBlinkCors, - kWithOutOfBlinkCors, -}; - -class ExtensionActiveTabTest : public ExtensionApiTest, - public testing::WithParamInterface<TestMode> { +class ExtensionActiveTabTest : public ExtensionApiTest { public: ExtensionActiveTabTest() = default; // ExtensionApiTest override: - void SetUp() override { - std::vector<base::Feature> enabled_features; - std::vector<base::Feature> disabled_features; - if (ShouldEnableOutOfBlinkCors()) { - enabled_features.push_back(network::features::kOutOfBlinkCors); - } else { - disabled_features.push_back(network::features::kOutOfBlinkCors); - } - scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features); - ExtensionApiTest::SetUp(); - } - void SetUpOnMainThread() override { ExtensionApiTest::SetUpOnMainThread(); // Map all hosts to localhost. host_resolver()->AddRule("*", "127.0.0.1"); - - ASSERT_EQ(ShouldEnableOutOfBlinkCors(), - base::FeatureList::IsEnabled(network::features::kOutOfBlinkCors)); } private: - bool ShouldEnableOutOfBlinkCors() const { - TestMode mode = GetParam(); - return mode == TestMode::kWithOutOfBlinkCors; - } - - base::test::ScopedFeatureList scoped_feature_list_; DISALLOW_COPY_AND_ASSIGN(ExtensionActiveTabTest); }; -IN_PROC_BROWSER_TEST_P(ExtensionActiveTabTest, ActiveTab) { +IN_PROC_BROWSER_TEST_F(ExtensionActiveTabTest, ActiveTab) { ASSERT_TRUE(StartEmbeddedTestServer()); ExtensionTestMessageListener background_page_ready("ready", @@ -177,7 +148,7 @@ } } -IN_PROC_BROWSER_TEST_P(ExtensionActiveTabTest, ActiveTabCors) { +IN_PROC_BROWSER_TEST_F(ExtensionActiveTabTest, ActiveTabCors) { ASSERT_TRUE(StartEmbeddedTestServer()); ExtensionTestMessageListener background_page_ready("ready", @@ -209,13 +180,6 @@ } } -INSTANTIATE_TEST_SUITE_P(WithBlinkCors, - ExtensionActiveTabTest, - testing::Values(TestMode::kWithBlinkCors)); -INSTANTIATE_TEST_SUITE_P(WithOutOfBlinkCors, - ExtensionActiveTabTest, - testing::Values(TestMode::kWithOutOfBlinkCors)); - // Tests the behavior of activeTab and its relation to an extension's ability to // xhr file urls and inject scripts in file frames. IN_PROC_BROWSER_TEST_F(ExtensionApiTest, FileURLs) {
diff --git a/chrome/browser/extensions/background_xhr_browsertest.cc b/chrome/browser/extensions/background_xhr_browsertest.cc index 1a506089..e1bbdb6 100644 --- a/chrome/browser/extensions/background_xhr_browsertest.cc +++ b/chrome/browser/extensions/background_xhr_browsertest.cc
@@ -11,7 +11,6 @@ #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/task/post_task.h" -#include "base/test/scoped_feature_list.h" #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/extensions/extension_browsertest.h" #include "chrome/browser/extensions/extension_with_management_policy_apitest.h" @@ -36,7 +35,6 @@ #include "net/ssl/client_cert_store.h" #include "net/ssl/ssl_server_config.h" #include "net/test/embedded_test_server/embedded_test_server.h" -#include "services/network/public/cpp/features.h" #include "url/gurl.h" namespace extensions { @@ -45,11 +43,6 @@ constexpr const char kWebstoreDomain[] = "cws.com"; -enum class TestMode { - kWithoutAny, - kWithOutOfBlinkCors, -}; - std::unique_ptr<net::ClientCertStore> CreateNullCertStore() { return nullptr; } @@ -122,28 +115,11 @@ "test_http_auth.html", embedded_test_server()->GetURL("/auth-basic"))); } -class BackgroundXhrWebstoreTest : public ExtensionApiTestWithManagementPolicy, - public testing::WithParamInterface<TestMode> { +class BackgroundXhrWebstoreTest : public ExtensionApiTestWithManagementPolicy { public: BackgroundXhrWebstoreTest() = default; ~BackgroundXhrWebstoreTest() override = default; - void SetUp() override { - std::vector<base::Feature> enabled_features; - std::vector<base::Feature> disabled_features; - switch (GetParam()) { - case TestMode::kWithoutAny: - disabled_features.push_back(network::features::kOutOfBlinkCors); - break; - case TestMode::kWithOutOfBlinkCors: - enabled_features.push_back(network::features::kOutOfBlinkCors); - break; - } - scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features); - - ExtensionApiTestWithManagementPolicy::SetUp(); - } - void SetUpCommandLine(base::CommandLine* command_line) override { ExtensionApiTest::SetUpCommandLine(command_line); // TODO(devlin): For some reason, trying to fetch an HTTPS url in this test @@ -205,13 +181,12 @@ } private: - base::test::ScopedFeatureList scoped_feature_list_; DISALLOW_COPY_AND_ASSIGN(BackgroundXhrWebstoreTest); }; // Extensions should not be able to XHR to the webstore. -IN_PROC_BROWSER_TEST_P(BackgroundXhrWebstoreTest, XHRToWebstore) { +IN_PROC_BROWSER_TEST_F(BackgroundXhrWebstoreTest, XHRToWebstore) { const Extension* extension = LoadXhrExtension("<all_urls>"); GURL webstore_launch_url = extension_urls::GetWebstoreLaunchURL(); @@ -229,7 +204,7 @@ } // Extensions should not be able to XHR to the webstore regardless of policy. -IN_PROC_BROWSER_TEST_P(BackgroundXhrWebstoreTest, XHRToWebstorePolicy) { +IN_PROC_BROWSER_TEST_F(BackgroundXhrWebstoreTest, XHRToWebstorePolicy) { { ExtensionManagementPolicyUpdater pref(&policy_provider_); pref.AddPolicyAllowedHost( @@ -254,7 +229,7 @@ // Extensions should not be able to bypass same-origin despite declaring // <all_urls> for hosts restricted by enterprise policy. -IN_PROC_BROWSER_TEST_P(BackgroundXhrWebstoreTest, PolicyBlockedXHR) { +IN_PROC_BROWSER_TEST_F(BackgroundXhrWebstoreTest, PolicyBlockedXHR) { { ExtensionManagementPolicyUpdater pref(&policy_provider_); pref.AddPolicyBlockedHost("*", "*://*.example.com"); @@ -277,7 +252,7 @@ } // Verify that policy blocklists apply to XHRs done from injected scripts. -IN_PROC_BROWSER_TEST_P(BackgroundXhrWebstoreTest, PolicyContentScriptXHR) { +IN_PROC_BROWSER_TEST_F(BackgroundXhrWebstoreTest, PolicyContentScriptXHR) { TestExtensionDir test_dir; test_dir.WriteManifest(R"( { @@ -339,7 +314,7 @@ // Make sure the blocklist and allowlist update for both Default and Individual // scope policies. Testing with all host permissions granted (<all_urls>). -IN_PROC_BROWSER_TEST_P(BackgroundXhrWebstoreTest, PolicyUpdateXHR) { +IN_PROC_BROWSER_TEST_F(BackgroundXhrWebstoreTest, PolicyUpdateXHR) { const Extension* extension = LoadXhrExtension("<all_urls>"); GURL example_url = @@ -391,7 +366,7 @@ // Make sure the allowlist entries added due to host permissions are removed // when a more generic blocklist policy is updated and contains them. // This tests the default policy scope update. -IN_PROC_BROWSER_TEST_P(BackgroundXhrWebstoreTest, PolicyUpdateDefaultXHR) { +IN_PROC_BROWSER_TEST_F(BackgroundXhrWebstoreTest, PolicyUpdateDefaultXHR) { const Extension* extension = LoadXhrExtension("*://public.example.com/*"); GURL example_url = @@ -420,7 +395,7 @@ // Make sure the allowlist entries added due to host permissions are removed // when a more generic blocklist policy is updated and contains them. // This tests an individual policy scope update. -IN_PROC_BROWSER_TEST_P(BackgroundXhrWebstoreTest, PolicyUpdateIndividualXHR) { +IN_PROC_BROWSER_TEST_F(BackgroundXhrWebstoreTest, PolicyUpdateIndividualXHR) { const Extension* extension = LoadXhrExtension("*://public.example.com/*"); GURL example_url = @@ -446,7 +421,7 @@ ExecuteFetch(extension, public_example_url)); } -IN_PROC_BROWSER_TEST_P(BackgroundXhrWebstoreTest, XHRAnyPortPermission) { +IN_PROC_BROWSER_TEST_F(BackgroundXhrWebstoreTest, XHRAnyPortPermission) { const Extension* extension = LoadXhrExtension("http://example.com:*/*"); GURL permitted_url_to_fetch = @@ -456,7 +431,7 @@ ::testing::HasSubstr("<head><title>OK</title></head>")); } -IN_PROC_BROWSER_TEST_P(BackgroundXhrWebstoreTest, +IN_PROC_BROWSER_TEST_F(BackgroundXhrWebstoreTest, XHRPortSpecificPermissionAllow) { const Extension* extension = LoadXhrExtension( "http://example.com:" + @@ -469,7 +444,7 @@ ::testing::HasSubstr("<head><title>OK</title></head>")); } -IN_PROC_BROWSER_TEST_P(BackgroundXhrWebstoreTest, +IN_PROC_BROWSER_TEST_F(BackgroundXhrWebstoreTest, XHRPortSpecificPermissionBlock) { const Extension* extension = LoadXhrExtension( "http://example.com:" + @@ -482,11 +457,4 @@ ExecuteFetch(extension, not_permitted_url_to_fetch)); } -INSTANTIATE_TEST_SUITE_P(WithoutAny, - BackgroundXhrWebstoreTest, - testing::Values(TestMode::kWithoutAny)); -INSTANTIATE_TEST_SUITE_P(WithOutOfBlinkCors, - BackgroundXhrWebstoreTest, - testing::Values(TestMode::kWithOutOfBlinkCors)); - } // namespace extensions
diff --git a/chrome/browser/extensions/service_worker_apitest.cc b/chrome/browser/extensions/service_worker_apitest.cc index fdb6b751..a052df2c 100644 --- a/chrome/browser/extensions/service_worker_apitest.cc +++ b/chrome/browser/extensions/service_worker_apitest.cc
@@ -314,7 +314,9 @@ // The extension is installed and loaded during this step and it registers // an event listener for tabs.onCreated event. The step also verifies that tab // creation correctly fires the listener. -IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, PRE_Basic) { +// +// Disabled due to flakiness: https://crbug.com/1003244. +IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, DISABLED_PRE_Basic) { ExtensionTestMessageListener newtab_listener("CREATED", false); newtab_listener.set_failure_message("CREATE_FAILED"); ExtensionTestMessageListener worker_listener("WORKER_RUNNING", false); @@ -339,7 +341,9 @@ // tabs.onCreated event listener to the extension without explicitly loading the // extension. This is because the extension registered a listener before browser // restarted in PRE_Basic. -IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, Basic) { +// +// Disabled due to flakiness: https://crbug.com/1003244. +IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, DISABLED_Basic) { ExtensionTestMessageListener newtab_listener("CREATED", false); newtab_listener.set_failure_message("CREATE_FAILED"); const GURL url = embedded_test_server()->GetURL("/extensions/test_file.html"); @@ -1811,8 +1815,9 @@ } } +// Disabled due to flakiness: https://crbug.com/1003244. IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, - TabsOnUpdatedSpanning) { + DISABLED_TabsOnUpdatedSpanning) { ExtensionTestMessageListener ready_listener("Script started regular", true); // Open an incognito window. @@ -2042,8 +2047,9 @@ << message_; } +// Disabled due to flakiness: https://crbug.com/1003244. IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, - PRE_FilteredEventsAfterRestart) { + DISABLED_PRE_FilteredEventsAfterRestart) { ExtensionTestMessageListener listener_added("ready", false); const Extension* extension = LoadExtensionWithFlags( test_data_dir_.AppendASCII("service_worker/worker_based_background/" @@ -2063,8 +2069,10 @@ // tabs.onCreated event listener to the extension without explicitly loading the // extension. This is because the extension registered a listener for // tabs.onMoved before browser restarted in PRE_EventsAfterRestart. +// +// Disabled due to flakiness: https://crbug.com/1003244. IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, - FilteredEventsAfterRestart) { + DISABLED_FilteredEventsAfterRestart) { // Verify there is no RenderProcessHost for the extension. // TODO(crbug.com/971309): This is currently broken because the test // infrastructure opens a tab, which dispatches an event to our
diff --git a/chrome/browser/loader/cors_origin_access_list_browsertest.cc b/chrome/browser/loader/cors_origin_access_list_browsertest.cc index 4969a33d..d13e398 100644 --- a/chrome/browser/loader/cors_origin_access_list_browsertest.cc +++ b/chrome/browser/loader/cors_origin_access_list_browsertest.cc
@@ -43,16 +43,12 @@ // Tests end to end functionality of CORS access origin allow lists. class CorsOriginAccessListBrowserTest : public InProcessBrowserTest { - public: - CorsOriginAccessListBrowserTest() { - scoped_feature_list_.InitWithFeatures( - // Enabled features - {network::features::kOutOfBlinkCors}, - // Disabled features - {}); - } - protected: + CorsOriginAccessListBrowserTest() { + // This test verifies if the CorsOriginAccessList works with OOR-CORS. + scoped_feature_list_.InitAndEnableFeature( + network::features::kOutOfBlinkCors); + } std::unique_ptr<content::TitleWatcher> CreateWatcher() { // Register all possible result strings here. std::unique_ptr<content::TitleWatcher> watcher =
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index ce7a864..ec077690 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -498,6 +498,7 @@ // Deprecated 9/2019 const char kGoogleServicesUsername[] = "google.services.username"; +const char kGoogleServicesUserAccountId[] = "google.services.user_account_id"; // Register prefs used only for migration (clearing or moving to a new key). void RegisterProfilePrefsForMigration( @@ -576,6 +577,7 @@ registry->RegisterDictionaryPref(kHintLoadedCounts); registry->RegisterStringPref(kGoogleServicesUsername, std::string()); + registry->RegisterStringPref(kGoogleServicesUserAccountId, std::string()); } } // namespace @@ -1188,4 +1190,5 @@ // Added 9/2019 profile_prefs->ClearPref(kGoogleServicesUsername); + profile_prefs->ClearPref(kGoogleServicesUserAccountId); }
diff --git a/chrome/browser/process_resource_usage.cc b/chrome/browser/process_resource_usage.cc index 0bedcbd..cde68d36 100644 --- a/chrome/browser/process_resource_usage.cc +++ b/chrome/browser/process_resource_usage.cc
@@ -14,9 +14,9 @@ #include "content/public/common/resource_usage_reporter_type_converters.h" ProcessResourceUsage::ProcessResourceUsage( - content::mojom::ResourceUsageReporterPtr service) + mojo::PendingRemote<content::mojom::ResourceUsageReporter> service) : service_(std::move(service)), update_in_progress_(false) { - service_.set_connection_error_handler( + service_.set_disconnect_handler( base::Bind(&ProcessResourceUsage::RunPendingRefreshCallbacks, base::Unretained(this))); } @@ -35,7 +35,7 @@ void ProcessResourceUsage::Refresh(const base::Closure& callback) { DCHECK(thread_checker_.CalledOnValidThread()); - if (!service_ || service_.encountered_error()) { + if (!service_ || !service_.is_connected()) { if (!callback.is_null()) base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback); return;
diff --git a/chrome/browser/process_resource_usage.h b/chrome/browser/process_resource_usage.h index 4d8b2a1..e441dc1a 100644 --- a/chrome/browser/process_resource_usage.h +++ b/chrome/browser/process_resource_usage.h
@@ -12,6 +12,8 @@ #include "base/macros.h" #include "base/threading/thread_checker.h" #include "content/public/common/resource_usage_reporter.mojom.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/platform/web_cache.h" // Provides resource usage information about a child process. @@ -24,31 +26,31 @@ // manager. // // To create: -// 1. Create a content::mojom::ResourceUsageReporterPtr and obtain an -// InterfaceRequest<> -// using -// mojo::MakeRequest. +// 1. Create a mojo::PendingRemote<content::mojom::ResourceUsageReporter> and +// obtain a mojo::PendingReceiver<> using InitWithNewPipeAndPassReceiver(). // 2. Use the child process's service registry to connect to the service using -// the InterfaceRequest<>. Note, ServiceRegistry is thread hostile and -// must always be accessed from the same thread. However, InterfaceRequest<> +// the mojo::PendingReceiver<>. Note, ServiceRegistry is thread hostile and +// must always be accessed from the same thread. However, PendingReceiver<> // can be passed safely between threads, and therefore a task can be posted // to the ServiceRegistry thread to connect to the remote service. -// 3. Pass the content::mojom::ResourceUsageReporterPtr to the constructor. +// 3. Pass the mojo::PendingRemote<content::mojom::ResourceUsageReporter> to the +// constructor. // // Example: // void Foo::ConnectToService( -// mojo::InterfaceRequest<content::mojom::ResourceUsageReporter> req) { +// mojo::PendingReceiver<content::mojom::ResourceUsageReporter> +// receiver) { // content::ServiceRegistry* registry = host_->GetServiceRegistry(); // registry->ConnectToRemoteService(std::move(req)); // } // // ... -// content::mojom::ResourceUsageReporterPtr service; -// mojo::InterfaceRequest<content::mojom::ResourceUsageReporter> request = -// mojo::MakeRequest(&service); +// mojo::PendingRemote<content::mojom::ResourceUsageReporter> service; +// mojo::PendingReceiver<content::mojom::ResourceUsageReporter> receiver = +// service.InitWithNewPipeAndPassReceiver(); // base::PostTask( // FROM_HERE, {content::BrowserThread::IO}, -// base::Bind(&Foo::ConnectToService, this, base::Passed(&request))); +// base::Bind(&Foo::ConnectToService, this, base::Passed(&receiver))); // resource_usage_.reset(new ProcessResourceUsage(std::move(service))); // ... // @@ -58,7 +60,7 @@ public: // Must be called from the same thread that created |service|. explicit ProcessResourceUsage( - content::mojom::ResourceUsageReporterPtr service); + mojo::PendingRemote<content::mojom::ResourceUsageReporter> service); ~ProcessResourceUsage(); // Refresh the resource usage information. |callback| is invoked when the @@ -79,7 +81,7 @@ void RunPendingRefreshCallbacks(); - content::mojom::ResourceUsageReporterPtr service_; + mojo::Remote<content::mojom::ResourceUsageReporter> service_; bool update_in_progress_; base::circular_deque<base::Closure> refresh_callbacks_;
diff --git a/chrome/browser/resources/chromeos/camera/src/css/main.css b/chrome/browser/resources/chromeos/camera/src/css/main.css index 1f3a410..f38b6a7c 100644 --- a/chrome/browser/resources/chromeos/camera/src/css/main.css +++ b/chrome/browser/resources/chromeos/camera/src/css/main.css
@@ -83,8 +83,8 @@ -webkit-appearance: none; } -button:focus::after, -input:focus::after { +body.tab-navigation button:focus::after, +body.tab-navigation input:focus::after { border: 2px solid rgba(37, 129, 223, 0.7); border-radius: 4px; bottom: -3px; @@ -101,8 +101,8 @@ } .circle button, -.circle button:focus::after, -.circle input:focus::after { +body.tab-navigation .circle button:focus::after, +body.tab-navigation .circle input:focus::after { border-radius: 50%; } @@ -271,7 +271,7 @@ z-index: 1; } -.mode-item>input:focus::after { +body.tab-navigation .mode-item>input:focus::after { display: none; } @@ -281,7 +281,7 @@ text-shadow: none; } -.mode-item>input:focus + span::after { +body.tab-navigation .mode-item>input:focus + span::after { border: 2px solid rgba(37, 129, 223, 0.7); border-radius: 20px/50%; bottom: -7px; @@ -1182,7 +1182,7 @@ transition: border-width 100ms ease-in; } -.menu-item:focus::after { +body.tab-navigation .menu-item:focus::after { left: 2px; right: 2px; } @@ -1313,13 +1313,13 @@ padding: 6px 18px; } -.dialog-buttons button:focus { +body.tab-navigation .dialog-buttons button:focus { background-color: rgb(37, 129, 223); border-color: rgb(37, 129, 223); color: white; } -.dialog-buttons button:focus::after { +body.tab-navigation .dialog-buttons button:focus::after { border: none; }
diff --git a/chrome/browser/resources/chromeos/camera/src/js/nav.js b/chrome/browser/resources/chromeos/camera/src/js/nav.js index 5ea489e..9f148b5 100644 --- a/chrome/browser/resources/chromeos/camera/src/js/nav.js +++ b/chrome/browser/resources/chromeos/camera/src/js/nav.js
@@ -45,6 +45,13 @@ .forEach( (element) => cca.util.makeUnfocusableByMouse( /** @type {!HTMLElement} */ (element))); + document.body.addEventListener('keydown', (e) => { + if (e.key === 'Tab') { + cca.state.set('tab-navigation', true); + } + }); + document.body.addEventListener( + 'pointerdown', () => cca.state.set('tab-navigation', false)); }; /**
diff --git a/chrome/browser/resources/chromeos/login/enterprise_enrollment.css b/chrome/browser/resources/chromeos/login/enterprise_enrollment.css index 3694faa..6ca9628 100644 --- a/chrome/browser/resources/chromeos/login/enterprise_enrollment.css +++ b/chrome/browser/resources/chromeos/login/enterprise_enrollment.css
@@ -14,12 +14,16 @@ display: none; } -#oauth-enroll-step-contents { - color: #666; +#oauth-enroll-step-contents, +#oauth-enroll-step-contents > div { height: 100%; width: 100%; } +#oauth-enroll-step-contents { + color: #666; +} + #step-error { display: table; height: 480px; @@ -28,10 +32,10 @@ #oauth-enroll-auth-view { display: block; - height: 560px; + height: 100%; overflow: hidden; padding: 0; - width: 768px; + width: 100%; } #oauth-enroll-learn-more-link {
diff --git a/chrome/browser/resources/print_preview/polymer3/demo.js b/chrome/browser/resources/print_preview/polymer3/demo.js index ca9f053f..0f505bc 100644 --- a/chrome/browser/resources/print_preview/polymer3/demo.js +++ b/chrome/browser/resources/print_preview/polymer3/demo.js
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'chrome://resources/cr_elements/action_link_css.m.js'; import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.m.js'; import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; import 'chrome://resources/cr_elements/cr_checkbox/cr_checkbox.m.js'; @@ -22,6 +23,7 @@ import 'chrome://resources/cr_elements/icons.m.js'; import 'chrome://resources/cr_elements/md_select_css.m.js'; import 'chrome://resources/cr_elements/policy/cr_tooltip_icon.m.js'; +import 'chrome://resources/js/action_link.js'; import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js'; import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -29,7 +31,7 @@ class HelloPolymer3Element extends PolymerElement { static get template() { return html` - <style include="md-select"> + <style include="md-select action-link"> cr-toggle { display: inline-block; } @@ -144,6 +146,8 @@ <div> <cr-link-row class="hr" label="Hello Link Row"></cr-link-row> </div> + + <a is="action-link">I am an action link</a> `; }
diff --git a/chrome/browser/resources/quota_internals/OWNERS b/chrome/browser/resources/quota_internals/OWNERS index 597882c..84d5cb66 100644 --- a/chrome/browser/resources/quota_internals/OWNERS +++ b/chrome/browser/resources/quota_internals/OWNERS
@@ -1 +1,4 @@ -tzik@chromium.org \ No newline at end of file +file://storage/browser/quota/OWNERS + +# TEAM: storage-dev@chromium.org +# COMPONENT: Blink>Storage>Quota
diff --git a/chrome/browser/signin/mirror_browsertest.cc b/chrome/browser/signin/mirror_browsertest.cc index 488859b..56acfbbd 100644 --- a/chrome/browser/signin/mirror_browsertest.cc +++ b/chrome/browser/signin/mirror_browsertest.cc
@@ -115,8 +115,8 @@ // and not because it was on a secure Google domain. // This is a regression test for crbug.com/588492. IN_PROC_BROWSER_TEST_F(MirrorBrowserTest, MirrorRequestHeader) { - browser()->profile()->GetPrefs()->SetString( - prefs::kGoogleServicesUserAccountId, "account_id"); + browser()->profile()->GetPrefs()->SetString(prefs::kGoogleServicesAccountId, + "account_id"); base::Lock lock; // Map from the path of the URLs that test server sees to the request header.
diff --git a/chrome/browser/task_manager/providers/child_process_task.cc b/chrome/browser/task_manager/providers/child_process_task.cc index 5603218..9f03849a 100644 --- a/chrome/browser/task_manager/providers/child_process_task.cc +++ b/chrome/browser/task_manager/providers/child_process_task.cc
@@ -28,6 +28,8 @@ #include "content/public/common/process_type.h" #include "extensions/browser/extension_registry.h" #include "extensions/common/extension_set.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "ui/base/l10n/l10n_util.h" @@ -116,7 +118,8 @@ // BrowserChildProcessHost whose unique ID is |unique_child_process_id|. void ConnectResourceReporterOnIOThread( int unique_child_process_id, - content::mojom::ResourceUsageReporterRequest resource_reporter) { + mojo::PendingReceiver<content::mojom::ResourceUsageReporter> + resource_reporter) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); content::BrowserChildProcessHost* host = @@ -132,11 +135,12 @@ // |unique_child_process_id|. ProcessResourceUsage* CreateProcessResourcesSampler( int unique_child_process_id) { - content::mojom::ResourceUsageReporterPtr usage_reporter; - base::PostTask(FROM_HERE, {content::BrowserThread::IO}, - base::BindOnce(&ConnectResourceReporterOnIOThread, - unique_child_process_id, - mojo::MakeRequest(&usage_reporter))); + mojo::PendingRemote<content::mojom::ResourceUsageReporter> usage_reporter; + base::PostTask( + FROM_HERE, {content::BrowserThread::IO}, + base::BindOnce(&ConnectResourceReporterOnIOThread, + unique_child_process_id, + usage_reporter.InitWithNewPipeAndPassReceiver())); return new ProcessResourceUsage(std::move(usage_reporter)); }
diff --git a/chrome/browser/task_manager/providers/web_contents/renderer_task.cc b/chrome/browser/task_manager/providers/web_contents/renderer_task.cc index d5d0d51..964ee46 100644 --- a/chrome/browser/task_manager/providers/web_contents/renderer_task.cc +++ b/chrome/browser/task_manager/providers/web_contents/renderer_task.cc
@@ -21,6 +21,7 @@ #include "content/public/browser/render_process_host.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_delegate.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "ui/base/l10n/l10n_util.h" @@ -33,7 +34,7 @@ // |render_process_host|. ProcessResourceUsage* CreateRendererResourcesSampler( content::RenderProcessHost* render_process_host) { - content::mojom::ResourceUsageReporterPtr service; + mojo::PendingRemote<content::mojom::ResourceUsageReporter> service; BindInterface(render_process_host, &service); return new ProcessResourceUsage(std::move(service)); }
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 9e94e7a..f80bd6a 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -2753,12 +2753,6 @@ "views/frame/contents_layout_manager.h", "views/frame/contents_web_view.cc", "views/frame/contents_web_view.h", - "views/frame/hosted_app_button_container.cc", - "views/frame/hosted_app_button_container.h", - "views/frame/hosted_app_menu_button.cc", - "views/frame/hosted_app_menu_button.h", - "views/frame/hosted_app_origin_text.cc", - "views/frame/hosted_app_origin_text.h", "views/frame/immersive_mode_controller.cc", "views/frame/immersive_mode_controller.h", "views/frame/immersive_mode_controller_factory_views.cc", @@ -3164,6 +3158,12 @@ "views/translate/translate_icon_view.h", "views/update_recommended_message_box.cc", "views/update_recommended_message_box.h", + "views/web_apps/web_app_frame_toolbar_view.cc", + "views/web_apps/web_app_frame_toolbar_view.h", + "views/web_apps/web_app_menu_button.cc", + "views/web_apps/web_app_menu_button.h", + "views/web_apps/web_app_origin_text.cc", + "views/web_apps/web_app_origin_text.h", "views/webauthn/authenticator_ble_pin_entry_sheet_view.cc", "views/webauthn/authenticator_ble_pin_entry_sheet_view.h", "views/webauthn/authenticator_client_pin_entry_sheet_view.cc",
diff --git a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc index 6d8b2b0d9..e08a5cf 100644 --- a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc +++ b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc
@@ -32,6 +32,7 @@ #include "chrome/browser/ui/app_list/arc/arc_default_app_list.h" #include "chrome/browser/ui/app_list/arc/arc_package_syncable_service.h" #include "chrome/browser/ui/app_list/arc/arc_pai_starter.h" +#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" #include "chrome/grit/generated_resources.h" #include "chromeos/constants/chromeos_features.h" #include "components/arc/arc_prefs.h" @@ -65,6 +66,7 @@ constexpr char kNotificationsEnabled[] = "notifications_enabled"; constexpr char kPackageName[] = "package_name"; constexpr char kPackageVersion[] = "package_version"; +constexpr char kPinIndex[] = "pin_index"; constexpr char kPermissionStates[] = "permission_states"; constexpr char kSticky[] = "sticky"; constexpr char kShortcut[] = "shortcut"; @@ -1493,6 +1495,18 @@ AddApp(*app); } + arc::ArcAppScopedPrefUpdate update(prefs_, package_name, + arc::prefs::kArcPackages); + base::DictionaryValue* package_dict = update.Get(); + if (!apps_to_remove.empty()) { + auto* launcher_controller = ChromeLauncherController::instance(); + if (launcher_controller) { + int pin_index = + launcher_controller->PinnedItemIndexByAppID(*apps_to_remove.begin()); + package_dict->SetInteger(kPinIndex, pin_index); + } + } + for (const auto& app_id : apps_to_remove) RemoveApp(app_id); }
diff --git a/chrome/browser/ui/app_list/arc/arc_app_unittest.cc b/chrome/browser/ui/app_list/arc/arc_app_unittest.cc index 2a89be2..2ea2d90 100644 --- a/chrome/browser/ui/app_list/arc/arc_app_unittest.cc +++ b/chrome/browser/ui/app_list/arc/arc_app_unittest.cc
@@ -13,6 +13,7 @@ #include <vector> #include "ash/public/cpp/app_list/app_list_config.h" +#include "ash/public/cpp/shelf_model.h" #include "base/bind.h" #include "base/files/file_path.h" #include "base/files/file_util.h" @@ -51,6 +52,7 @@ #include "chrome/browser/ui/app_list/test/fake_app_list_model_updater.h" #include "chrome/browser/ui/app_list/test/test_app_list_controller_delegate.h" #include "chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h" +#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" #include "chrome/test/base/testing_profile.h" #include "chromeos/constants/chromeos_switches.h" #include "components/arc/arc_prefs.h" @@ -227,6 +229,8 @@ arc::SetArcAlwaysStartWithoutPlayStoreForTesting(); } + model_ = std::make_unique<ash::ShelfModel>(); + extensions::ExtensionServiceTestBase::SetUp(); InitializeExtensionService(ExtensionServiceInitParams()); service_->Init(); @@ -235,16 +239,25 @@ arc_test_.SetUp(profile_.get()); CreateBuilder(); + CreateLauncherController()->Init(); + // Validating decoded content does not fit well for unit tests. ArcAppIcon::DisableSafeDecodingForTesting(); } void TearDown() override { + launcher_controller_.reset(); arc_test_.TearDown(); ResetBuilder(); extensions::ExtensionServiceTestBase::TearDown(); } + ChromeLauncherController* CreateLauncherController() { + launcher_controller_ = std::make_unique<ChromeLauncherController>( + profile_.get(), model_.get()); + return launcher_controller_.get(); + } + protected: // Notifies that initial preparation is done, profile is ready and it is time // to initialize ARC subsystem. @@ -520,6 +533,8 @@ std::unique_ptr<FakeAppListModelUpdater> model_updater_; std::unique_ptr<test::TestAppListControllerDelegate> controller_; std::unique_ptr<ArcAppModelBuilder> builder_; + std::unique_ptr<ChromeLauncherController> launcher_controller_; + std::unique_ptr<ash::ShelfModel> model_; DISALLOW_COPY_AND_ASSIGN(ArcAppModelBuilderTest); };
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc index 5f8adc4..50b691be 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc
@@ -789,6 +789,45 @@ model_->UnpinAppWithID(app_id); } +void ChromeLauncherController::ReplacePinnedItem( + const std::string& old_app_id, + const std::string& new_app_id) { + if (!model_->IsAppPinned(old_app_id)) + return; + const int index = model_->ItemIndexByAppID(old_app_id); + + const ash::ShelfID new_shelf_id(new_app_id); + ash::ShelfItem item; + item.type = ash::TYPE_PINNED_APP; + item.id = new_shelf_id; + + // Remove old_app at index and replace with new app. + model_->RemoveItemAt(index); + model_->AddAt(index, item); +} + +void ChromeLauncherController::PinAppAtIndex(const std::string& app_id, + int target_index) { + if (target_index < 0) + return; + + const ash::ShelfID new_shelf_id(app_id); + ash::ShelfItem item; + item.type = ash::TYPE_PINNED_APP; + item.id = new_shelf_id; + + model_->AddAt(target_index, item); +} + +int ChromeLauncherController::PinnedItemIndexByAppID( + const std::string& app_id) { + if (model_->IsAppPinned(app_id)) { + ash::ShelfID shelf_id(app_id); + return model_->ItemIndexByID(shelf_id); + } + return kInvalidIndex; +} + AppIconLoader* ChromeLauncherController::GetAppIconLoaderForApp( const std::string& app_id) { for (const auto& app_icon_loader : app_icon_loaders_) {
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.h b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.h index 5a4e7a0..30c1e56 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.h +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.h
@@ -67,6 +67,9 @@ private app_list::AppListSyncableService::Observer, private sync_preferences::PrefServiceSyncableObserver { public: + // The value used for indicating that an index position doesn't exist. + static const int kInvalidIndex = -1; + // Returns the single ChromeLauncherController instance. static ChromeLauncherController* instance() { return instance_; } @@ -247,6 +250,17 @@ bool IsAppPinned(const std::string& app_id); void UnpinAppWithID(const std::string& app_id); + // Unpins app item with |old_app_id| and pins app |new_app_id| in its place. + void ReplacePinnedItem(const std::string& old_app_id, + const std::string& new_app_id); + + // Pins app with |app_id| at |target_index|. + void PinAppAtIndex(const std::string& app_id, int target_index); + + // Converts |app_id| to shelf_id and calls ShelfModel function ItemIndexbyID + // to get index of item with id |app_id| or -1 if it's not pinned. + int PinnedItemIndexByAppID(const std::string& app_id); + // Whether the controller supports a Show App Info flow. bool CanDoShowAppInfoFlow();
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc index 28291fa..9fb35d8e 100644 --- a/chrome/browser/ui/browser_command_controller.cc +++ b/chrome/browser/ui/browser_command_controller.cc
@@ -754,7 +754,7 @@ browser_, browser_->tab_strip_model()->GetActiveWebContents()->GetVisibleURL()); break; - case IDC_HOSTED_APP_MENU_APP_INFO: { + case IDC_WEB_APP_MENU_APP_INFO: { content::WebContents* const web_contents = browser_->tab_strip_model()->GetActiveWebContents(); if (web_contents) { @@ -994,8 +994,7 @@ command_updater_.UpdateCommandEnabled(IDC_COPY_URL, is_web_app); command_updater_.UpdateCommandEnabled(IDC_OPEN_IN_CHROME, is_web_app); command_updater_.UpdateCommandEnabled(IDC_SITE_SETTINGS, is_web_app); - command_updater_.UpdateCommandEnabled(IDC_HOSTED_APP_MENU_APP_INFO, - is_web_app); + command_updater_.UpdateCommandEnabled(IDC_WEB_APP_MENU_APP_INFO, is_web_app); // Window management commands command_updater_.UpdateCommandEnabled(IDC_SELECT_NEXT_TAB, normal_window);
diff --git a/chrome/browser/ui/extensions/hosted_app_browsertest.cc b/chrome/browser/ui/extensions/hosted_app_browsertest.cc index c0328b4..c33e7465 100644 --- a/chrome/browser/ui/extensions/hosted_app_browsertest.cc +++ b/chrome/browser/ui/extensions/hosted_app_browsertest.cc
@@ -1630,7 +1630,7 @@ GetPageInfoDialogCreatedCallbackForTesting() = base::BindOnce( [](bool* dialog_created) { *dialog_created = true; }, &dialog_created); - chrome::ExecuteCommand(app_browser, IDC_HOSTED_APP_MENU_APP_INFO); + chrome::ExecuteCommand(app_browser, IDC_WEB_APP_MENU_APP_INFO); EXPECT_TRUE(dialog_created);
diff --git a/chrome/browser/ui/layout_constants.cc b/chrome/browser/ui/layout_constants.cc index 3b48afc..2561162b 100644 --- a/chrome/browser/ui/layout_constants.cc +++ b/chrome/browser/ui/layout_constants.cc
@@ -39,9 +39,9 @@ return touch_ui ? 36 : 28; case BOOKMARK_BAR_NTP_HEIGHT: return touch_ui ? GetLayoutConstant(BOOKMARK_BAR_HEIGHT) : 39; - case HOSTED_APP_MENU_BUTTON_SIZE: + case WEB_APP_MENU_BUTTON_SIZE: return 24; - case HOSTED_APP_PAGE_ACTION_ICON_SIZE: + case WEB_APP_PAGE_ACTION_ICON_SIZE: // We must limit the size of icons in the title bar to avoid vertically // stretching the container view. return 16;
diff --git a/chrome/browser/ui/layout_constants.h b/chrome/browser/ui/layout_constants.h index eb6a2fdf..663a6973 100644 --- a/chrome/browser/ui/layout_constants.h +++ b/chrome/browser/ui/layout_constants.h
@@ -34,11 +34,11 @@ BOOKMARK_BAR_NTP_PADDING, #endif - // The size of the app menu button in a hosted app browser window. - HOSTED_APP_MENU_BUTTON_SIZE, + // The size of the app menu button in a web app browser window. + WEB_APP_MENU_BUTTON_SIZE, - // The size of page action icons in a hosted app title bar. - HOSTED_APP_PAGE_ACTION_ICON_SIZE, + // The size of page action icons in a web app title bar. + WEB_APP_PAGE_ACTION_ICON_SIZE, // The vertical padding between the edge of a location bar bubble and its // contained text.
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc index 3e87eb4..469db2c 100644 --- a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc +++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
@@ -251,7 +251,7 @@ // Hide the manage passwords bubble if currently shown. if (IsShowingBubble()) - TabDialogs::FromWebContents(web_contents())->HideManagePasswordsBubble(); + HidePasswordBubble(); else ClearPopUpFlagForBubble(); @@ -493,6 +493,10 @@ void ManagePasswordsUIController::OnLeakDialogHidden() { dialog_controller_.reset(); + if (GetState() == password_manager::ui::PENDING_PASSWORD_UPDATE_STATE) { + bubble_status_ = BubbleStatus::SHOULD_POP_UP; + UpdateBubbleAndIconVisibility(); + } } bool ManagePasswordsUIController::AuthenticateUser() { @@ -524,6 +528,11 @@ form_manager->OnNeverClicked(); } +void ManagePasswordsUIController::HidePasswordBubble() { + if (TabDialogs* tab_dialogs = TabDialogs::FromWebContents(web_contents())) + tab_dialogs->HideManagePasswordsBubble(); +} + void ManagePasswordsUIController::UpdateBubbleAndIconVisibility() { // If we're not on a "webby" URL (e.g. "chrome://sign-in"), we shouldn't // display either the bubble or the icon. @@ -585,7 +594,7 @@ void ManagePasswordsUIController::OnVisibilityChanged( content::Visibility visibility) { if (visibility == content::Visibility::HIDDEN) - TabDialogs::FromWebContents(web_contents())->HideManagePasswordsBubble(); + HidePasswordBubble(); } // static @@ -621,9 +630,7 @@ GetPasswordStore(web_contents()); if (password_store) password_store->RemoveObserver(this); - TabDialogs* tab_dialogs = TabDialogs::FromWebContents(web_contents()); - if (tab_dialogs) - tab_dialogs->HideManagePasswordsBubble(); + HidePasswordBubble(); } void ManagePasswordsUIController::RequestAuthenticationAndReopenBubble() {
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller.h b/chrome/browser/ui/passwords/manage_passwords_ui_controller.h index 38a34edf..0ae8adf 100644 --- a/chrome/browser/ui/passwords/manage_passwords_ui_controller.h +++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller.h
@@ -158,6 +158,9 @@ virtual void SavePasswordInternal(); virtual void NeverSavePasswordInternal(); + // Hides the bubble if opened. Mocked in the tests. + virtual void HidePasswordBubble(); + // Called when a PasswordForm is autofilled, when a new PasswordForm is // submitted, or when a navigation occurs to update the visibility of the // manage passwords icon and bubble.
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc index 6945b91..35bed48 100644 --- a/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc +++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
@@ -15,6 +15,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/metrics/histogram_tester.h" #include "build/build_config.h" +#include "chrome/browser/ui/passwords/credential_leak_dialog_controller.h" #include "chrome/browser/ui/passwords/credential_manager_dialog_controller.h" #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h" #include "chrome/browser/ui/passwords/manage_passwords_icon_view.h" @@ -62,20 +63,24 @@ namespace { -// Number of dismissals that for sure supresses the bubble. -const int kGreatDissmisalCount = 10; +// A random URL. +constexpr char kExampleUrl[] = "http://example.com"; -class DialogPromptMock : public AccountChooserPrompt, - public AutoSigninFirstRunPrompt { +// Number of dismissals that for sure suppresses the bubble. +constexpr int kGreatDissmisalCount = 10; + +class CredentialManagementDialogPromptMock : public AccountChooserPrompt, + public AutoSigninFirstRunPrompt { public: - DialogPromptMock() = default; - MOCK_METHOD0(ShowAccountChooser, void()); MOCK_METHOD0(ShowAutoSigninPrompt, void()); MOCK_METHOD0(ControllerGone, void()); +}; - private: - DISALLOW_COPY_AND_ASSIGN(DialogPromptMock); +class PasswordLeakDialogMock : public CredentialLeakPrompt { + public: + MOCK_METHOD0(ShowCredentialLeakPrompt, void()); + MOCK_METHOD0(ControllerGone, void()); }; class TestManagePasswordsIconView : public ManagePasswordsIconView { @@ -110,6 +115,8 @@ AccountChooserPrompt*(CredentialManagerDialogController*)); MOCK_METHOD1(CreateAutoSigninPrompt, AutoSigninFirstRunPrompt*(CredentialManagerDialogController*)); + MOCK_METHOD1(CreateCredentialLeakPrompt, + CredentialLeakPrompt*(CredentialLeakDialogController*)); MOCK_CONST_METHOD0(HasBrowserWindow, bool()); MOCK_METHOD0(OnUpdateBubbleAndIconVisibility, void()); using ManagePasswordsUIController::DidFinishNavigation; @@ -118,11 +125,12 @@ void UpdateBubbleAndIconVisibility() override; void SavePasswordInternal() override {} void NeverSavePasswordInternal() override; + void HidePasswordBubble() override; bool ShowAuthenticationDialog() override { return true; } - bool opened_bubble_; - bool opened_automatic_bubble_; - bool are_passwords_revealed_in_opened_bubble_; + bool opened_bubble_ = false; + bool opened_automatic_bubble_ = false; + bool are_passwords_revealed_in_opened_bubble_ = false; }; TestManagePasswordsUIController::TestManagePasswordsUIController( @@ -163,6 +171,15 @@ OnLoginsChanged(list); } +void TestManagePasswordsUIController::HidePasswordBubble() { + opened_automatic_bubble_ = false; + are_passwords_revealed_in_opened_bubble_ = false; + if (std::exchange(opened_bubble_, false) && + !web_contents()->IsBeingDestroyed()) { + OnBubbleHidden(); + } +} + void CreateSmartBubbleFieldTrial() { using password_bubble_experiment::kSmartBubbleExperimentName; using password_bubble_experiment::kSmartBubbleThresholdParam; @@ -190,7 +207,9 @@ PasswordForm& test_federated_form() { return test_federated_form_; } FormData& submitted_form() { return submitted_form_; } FormData& observed_form() { return observed_form_; } - DialogPromptMock& dialog_prompt() { return dialog_prompt_; } + CredentialManagementDialogPromptMock& dialog_prompt() { + return dialog_prompt_; + } password_manager::PasswordManagerDriver& driver() { return driver_; } TestManagePasswordsUIController* controller() { @@ -234,7 +253,7 @@ FormData submitted_form_; FormData observed_form_; base::FieldTrialList field_trial_list_; - DialogPromptMock dialog_prompt_; + CredentialManagementDialogPromptMock dialog_prompt_; }; void ManagePasswordsUIControllerTest::SetUp() { @@ -278,7 +297,7 @@ // We need to be on a "webby" URL for most tests. EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility()); content::WebContentsTester::For(web_contents()) - ->NavigateAndCommit(GURL("http://example.com")); + ->NavigateAndCommit(GURL(kExampleUrl)); } void ManagePasswordsUIControllerTest::ExpectIconStateIs( @@ -454,7 +473,7 @@ // Test on the real controller. std::unique_ptr<content::WebContents> web_content(CreateTestWebContents()); content::WebContentsTester::For(web_content.get()) - ->NavigateAndCommit(GURL("http://example.com")); + ->NavigateAndCommit(GURL(kExampleUrl)); ManagePasswordsUIController::CreateForWebContents(web_content.get()); ManagePasswordsUIController* controller = ManagePasswordsUIController::FromWebContents(web_content.get()); @@ -677,7 +696,7 @@ TEST_F(ManagePasswordsUIControllerTest, ChooseCredentialLocal) { std::vector<std::unique_ptr<PasswordForm>> local_credentials; local_credentials.emplace_back(new PasswordForm(test_local_form())); - GURL origin("http://example.com"); + GURL origin(kExampleUrl); CredentialManagerDialogController* dialog_controller = nullptr; EXPECT_CALL(*controller(), CreateAccountChooser(_)) .WillOnce( @@ -710,7 +729,7 @@ TEST_F(ManagePasswordsUIControllerTest, ChooseCredentialLocalButFederated) { std::vector<std::unique_ptr<PasswordForm>> local_credentials; local_credentials.emplace_back(new PasswordForm(test_federated_form())); - GURL origin("http://example.com"); + GURL origin(kExampleUrl); CredentialManagerDialogController* dialog_controller = nullptr; EXPECT_CALL(*controller(), CreateAccountChooser(_)) .WillOnce( @@ -743,7 +762,7 @@ TEST_F(ManagePasswordsUIControllerTest, ChooseCredentialCancel) { std::vector<std::unique_ptr<PasswordForm>> local_credentials; local_credentials.emplace_back(new PasswordForm(test_local_form())); - GURL origin("http://example.com"); + GURL origin(kExampleUrl); CredentialManagerDialogController* dialog_controller = nullptr; EXPECT_CALL(*controller(), CreateAccountChooser(_)) .WillOnce( @@ -769,7 +788,7 @@ TEST_F(ManagePasswordsUIControllerTest, ChooseCredentialPrefetch) { std::vector<std::unique_ptr<PasswordForm>> local_credentials; local_credentials.emplace_back(new PasswordForm(test_local_form())); - GURL origin("http://example.com"); + GURL origin(kExampleUrl); // Simulate requesting a credential during prefetch. The tab has no associated // browser. Nothing should happen. @@ -785,7 +804,7 @@ test_local_form().is_public_suffix_match = true; std::vector<std::unique_ptr<PasswordForm>> local_credentials; local_credentials.emplace_back(new PasswordForm(test_local_form())); - GURL origin("http://example.com"); + GURL origin(kExampleUrl); CredentialManagerDialogController* dialog_controller = nullptr; EXPECT_CALL(*controller(), CreateAccountChooser(_)) .WillOnce( @@ -1278,3 +1297,34 @@ EXPECT_TRUE(success); #endif } + +TEST_F(ManagePasswordsUIControllerTest, UpdateBubbleAfterLeakCheck) { + std::unique_ptr<PasswordFormManager> test_form_manager(CreateFormManager()); + EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility()); + controller()->OnUpdatePasswordSubmitted(std::move(test_form_manager)); + EXPECT_TRUE(controller()->opened_automatic_bubble()); + + // Leak detection dialog hides the bubble. + PasswordLeakDialogMock dialog_prompt; + CredentialLeakDialogController* dialog_controller = nullptr; + EXPECT_CALL(*controller(), CreateCredentialLeakPrompt) + .WillOnce(DoAll(SaveArg<0>(&dialog_controller), Return(&dialog_prompt))); + EXPECT_CALL(dialog_prompt, ShowCredentialLeakPrompt); + controller()->OnCredentialLeak( + password_manager::CreateLeakType(password_manager::IsSaved(true), + password_manager::IsReused(true), + password_manager::IsSyncing(false)), + GURL(kExampleUrl)); + // The bubble is gone. + EXPECT_FALSE(controller()->opened_bubble()); + + // Close the dialog. + EXPECT_CALL(dialog_prompt, ControllerGone); + EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility()); + dialog_controller->OnAcceptDialog(); + + // The update bubble is back. + EXPECT_TRUE(controller()->opened_automatic_bubble()); + ExpectIconAndControllerStateIs( + password_manager::ui::PENDING_PASSWORD_UPDATE_STATE); +}
diff --git a/chrome/browser/ui/passwords/password_dialog_prompts.h b/chrome/browser/ui/passwords/password_dialog_prompts.h index 722823e..23b7b412 100644 --- a/chrome/browser/ui/passwords/password_dialog_prompts.h +++ b/chrome/browser/ui/passwords/password_dialog_prompts.h
@@ -33,7 +33,10 @@ // element. The dialog should close. virtual void ControllerGone() = 0; protected: + AccountChooserPrompt() = default; virtual ~AccountChooserPrompt() = default; + + DISALLOW_COPY_AND_ASSIGN(AccountChooserPrompt); }; // A platform-independent interface for the autosignin promo. @@ -46,7 +49,10 @@ // element. The dialog should close. virtual void ControllerGone() = 0; protected: + AutoSigninFirstRunPrompt() = default; virtual ~AutoSigninFirstRunPrompt() = default; + + DISALLOW_COPY_AND_ASSIGN(AutoSigninFirstRunPrompt); }; // A platform-independent interface for the credentials leaked prompt. @@ -60,7 +66,10 @@ virtual void ControllerGone() = 0; protected: + CredentialLeakPrompt() = default; virtual ~CredentialLeakPrompt() = default; + + DISALLOW_COPY_AND_ASSIGN(CredentialLeakPrompt); }; // Factory function for AccountChooserPrompt on desktop platforms.
diff --git a/chrome/browser/ui/toolbar/app_menu_model.cc b/chrome/browser/ui/toolbar/app_menu_model.cc index 4eb6064..bb361dcf 100644 --- a/chrome/browser/ui/toolbar/app_menu_model.cc +++ b/chrome/browser/ui/toolbar/app_menu_model.cc
@@ -635,7 +635,7 @@ } LogMenuAction(MENU_ACTION_SITE_SETTINGS); break; - case IDC_HOSTED_APP_MENU_APP_INFO: + case IDC_WEB_APP_MENU_APP_INFO: if (!uma_action_recorded_) UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.AppInfo", delta); LogMenuAction(MENU_ACTION_APP_INFO);
diff --git a/chrome/browser/ui/view_ids.h b/chrome/browser/ui/view_ids.h index d5f920a..3838b1d 100644 --- a/chrome/browser/ui/view_ids.h +++ b/chrome/browser/ui/view_ids.h
@@ -22,7 +22,7 @@ VIEW_ID_CLOSE_BUTTON, VIEW_ID_WINDOW_ICON, VIEW_ID_WINDOW_TITLE, - VIEW_ID_HOSTED_APP_BUTTON_CONTAINER, + VIEW_ID_WEB_APP_FRAME_TOOLBAR, // Tabs within a window/tab strip, counting from the left. VIEW_ID_TAB_0,
diff --git a/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_win.cc b/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_win.cc index 33a86548..ab775e7 100644 --- a/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_win.cc +++ b/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_win.cc
@@ -393,9 +393,9 @@ //////////////////////////////////////////////////////////////////////////////// // BrowserDesktopWindowTreeHostWin, private: bool BrowserDesktopWindowTreeHostWin::IsOpaqueHostedAppFrame() const { - // TODO(https://crbug.com/868239): Support Windows 7 Aero glass for hosted app + // TODO(https://crbug.com/868239): Support Windows 7 Aero glass for web-app // window titlebar controls. - return browser_view_->IsBrowserTypeHostedApp() && + return browser_view_->IsBrowserTypeWebApp() && base::win::GetVersion() < base::win::Version::WIN10; }
diff --git a/chrome/browser/ui/views/frame/browser_frame_mac.mm b/chrome/browser/ui/views/frame/browser_frame_mac.mm index 2e0f6ec9..76ca641 100644 --- a/chrome/browser/ui/views/frame/browser_frame_mac.mm +++ b/chrome/browser/ui/views/frame/browser_frame_mac.mm
@@ -295,7 +295,7 @@ base::scoped_nsobject<NativeWidgetMacNSWindow> ns_window; if (browser_view_->IsBrowserTypeNormal() || - browser_view_->IsBrowserTypeHostedApp()) { + browser_view_->IsBrowserTypeWebApp()) { params->window_class = remote_cocoa::mojom::WindowClass::kBrowser; params->style_mask |= NSFullSizeContentViewWindowMask; @@ -303,7 +303,7 @@ params->titlebar_appears_transparent = true; // Hosted apps draw their own window title. - if (browser_view_->IsBrowserTypeHostedApp()) + if (browser_view_->IsBrowserTypeWebApp()) params->window_title_hidden = true; } else { params->window_class = remote_cocoa::mojom::WindowClass::kDefault;
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc index 9b44c40..bf7274b8 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc
@@ -15,8 +15,8 @@ #include "chrome/browser/ui/tabs/tab_types.h" #include "chrome/browser/ui/view_ids.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/frame/hosted_app_button_container.h" #include "chrome/browser/ui/views/tabs/tab_strip.h" +#include "chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.h" #include "chrome/browser/ui/web_applications/app_browser_controller.h" #include "chrome/common/chrome_features.h" #include "chrome/grit/theme_resources.h" @@ -133,7 +133,7 @@ } bool BrowserNonClientFrameView::CanDrawStrokes() const { - // Hosted apps should not draw strokes, as they don't have a tab strip. + // Web apps should not draw strokes, as they don't have a tab strip. return !browser_view_->browser()->app_controller(); } @@ -163,10 +163,10 @@ } void BrowserNonClientFrameView::UpdateFrameColor() { - // Only hosted app windows support dynamic frame colors set by HTML meta tags. - if (!hosted_app_button_container_) + // Only web-app windows support dynamic frame colors set by HTML meta tags. + if (!web_app_frame_toolbar_) return; - hosted_app_button_container_->UpdateCaptionColors(); + web_app_frame_toolbar_->UpdateCaptionColors(); SchedulePaint(); } @@ -210,11 +210,11 @@ void BrowserNonClientFrameView::Layout() { // BrowserView updates most UI visibility on layout based on fullscreen - // state. However, it doesn't have access to hosted_app_button_container_. Do + // state. However, it doesn't have access to |web_app_frame_toolbar_|. Do // it here. This is necessary since otherwise the visibility of ink drop // layers won't be updated; see crbug.com/964215. - if (hosted_app_button_container_) - hosted_app_button_container_->SetVisible(!frame_->IsFullscreen()); + if (web_app_frame_toolbar_) + web_app_frame_toolbar_->SetVisible(!frame_->IsFullscreen()); NonClientFrameView::Layout(); } @@ -230,19 +230,19 @@ } int BrowserNonClientFrameView::NonClientHitTest(const gfx::Point& point) { - if (hosted_app_button_container_) { - int hosted_app_component = - views::GetHitTestComponent(hosted_app_button_container_, point); - if (hosted_app_component != HTNOWHERE) - return hosted_app_component; - } + if (!web_app_frame_toolbar_) + return HTNOWHERE; + int web_app_component = + views::GetHitTestComponent(web_app_frame_toolbar_, point); + if (web_app_component != HTNOWHERE) + return web_app_component; return HTNOWHERE; } void BrowserNonClientFrameView::ResetWindowControls() { - if (hosted_app_button_container_) - hosted_app_button_container_->UpdateStatusIconsVisibility(); + if (web_app_frame_toolbar_) + web_app_frame_toolbar_->UpdateStatusIconsVisibility(); } bool BrowserNonClientFrameView::ShouldPaintAsActive( @@ -278,7 +278,7 @@ } void BrowserNonClientFrameView::ChildPreferredSizeChanged(views::View* child) { - if (browser_view()->initialized() && child == hosted_app_button_container_) + if (browser_view()->initialized() && child == web_app_frame_toolbar_) Layout(); } @@ -287,8 +287,8 @@ // the new tab button) needs to be recalculated. browser_view_->tabstrip()->FrameColorsChanged(); - if (hosted_app_button_container_) - hosted_app_button_container_->SetPaintAsActive(active); + if (web_app_frame_toolbar_) + web_app_frame_toolbar_->SetPaintAsActive(active); // Changing the activation state may change the visible frame color. SchedulePaint();
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view.h b/chrome/browser/ui/views/frame/browser_non_client_frame_view.h index eafa26e..fd763e5 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view.h +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view.h
@@ -14,7 +14,7 @@ class BrowserFrame; class BrowserView; -class HostedAppButtonContainer; +class WebAppFrameToolbarView; // A specialization of the NonClientFrameView object that provides additional // Browser-specific methods. @@ -127,8 +127,8 @@ int NonClientHitTest(const gfx::Point& point) override; void ResetWindowControls() override; - HostedAppButtonContainer* hosted_app_button_container_for_testing() { - return hosted_app_button_container_; + WebAppFrameToolbarView* web_app_frame_toolbar_for_testing() { + return web_app_frame_toolbar_; } protected: @@ -155,15 +155,15 @@ void OnProfileHighResAvatarLoaded( const base::FilePath& profile_path) override; - void set_hosted_app_button_container( - HostedAppButtonContainer* hosted_app_button_container) { - hosted_app_button_container_ = hosted_app_button_container; + void set_web_app_frame_toolbar( + WebAppFrameToolbarView* web_app_frame_toolbar) { + web_app_frame_toolbar_ = web_app_frame_toolbar; } - HostedAppButtonContainer* hosted_app_button_container() { - return hosted_app_button_container_; + WebAppFrameToolbarView* web_app_frame_toolbar() { + return web_app_frame_toolbar_; } - const HostedAppButtonContainer* hosted_app_button_container() const { - return hosted_app_button_container_; + const WebAppFrameToolbarView* web_app_frame_toolbar() const { + return web_app_frame_toolbar_; } private: @@ -188,8 +188,8 @@ // The BrowserView hosted within this View. BrowserView* browser_view_; - // Menu button and page status icons. Only used by hosted app windows. - HostedAppButtonContainer* hosted_app_button_container_ = nullptr; + // Menu button and page status icons. Only used by web-app windows. + WebAppFrameToolbarView* web_app_frame_toolbar_ = nullptr; ScopedObserver<TabStrip, BrowserNonClientFrameView> tab_strip_observer_;
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc index 325ff5bc..0653346e 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc
@@ -33,13 +33,13 @@ #include "chrome/browser/ui/layout_constants.h" #include "chrome/browser/ui/views/frame/browser_frame.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/frame/hosted_app_button_container.h" #include "chrome/browser/ui/views/frame/immersive_mode_controller.h" #include "chrome/browser/ui/views/frame/top_container_view.h" #include "chrome/browser/ui/views/profiles/profile_indicator_icon.h" #include "chrome/browser/ui/views/tab_icon_view.h" #include "chrome/browser/ui/views/tabs/tab_strip.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" +#include "chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.h" #include "chrome/browser/ui/web_applications/app_browser_controller.h" #include "chromeos/constants/chromeos_features.h" #include "content/public/browser/web_contents.h" @@ -174,8 +174,8 @@ frame_header_ = CreateFrameHeader(); - if (browser_view()->IsBrowserTypeHostedApp()) - SetUpForHostedApp(); + if (browser_view()->IsBrowserTypeWebApp()) + SetUpForWebApp(); browser_view()->immersive_mode_controller()->AddObserver(this); ash::SplitViewNotifier::Get()->AddObserver(this); @@ -223,10 +223,9 @@ Browser* browser = browser_view()->browser(); int header_height = frame_header_->GetHeaderHeight(); - if (hosted_app_button_container()) { - header_height = - std::max(header_height, - hosted_app_button_container()->GetPreferredSize().height()); + if (web_app_frame_toolbar()) { + header_height = std::max( + header_height, web_app_frame_toolbar()->GetPreferredSize().height()); } if (browser_view()->IsTabStripVisible()) return header_height - browser_view()->GetTabStripHeight(); @@ -246,11 +245,11 @@ if (!UsePackagedAppHeaderStyle(browser_view()->browser())) { active_color = GetFrameColor(kActive); inactive_color = GetFrameColor(kInactive); - } else if (browser_view()->IsBrowserTypeHostedApp()) { + } else if (browser_view()->IsBrowserTypeWebApp()) { active_color = browser_view()->browser()->app_controller()->GetThemeColor(); } else if (!browser_view()->browser()->deprecated_is_app()) { // TODO(crbug.com/836128): Remove when System Web Apps flag is removed, as - // the above Hosted App branch will render the theme color. + // the above web-app branch will render the theme color. active_color = base::FeatureList::IsEnabled(chromeos::features::kSplitSettings) ? SK_ColorWHITE @@ -296,7 +295,7 @@ SkColor active_color = views::FrameCaptionButton::GetButtonColor(ash::kDefaultFrameColor); - // Hosted apps apply a theme color if specified by the extension. + // Web apps apply a theme color if specified by the extension. Browser* browser = browser_view()->browser(); base::Optional<SkColor> theme_color = browser->app_controller()->GetThemeColor(); @@ -306,7 +305,7 @@ if (active) return active_color; - // Add the container for extra hosted app buttons (e.g app menu button). + // Add the container for extra web-app buttons (e.g app menu button). const float inactive_alpha_ratio = views::FrameCaptionButton::GetInactiveButtonColorAlphaRatio(); return SkColorSetA(active_color, inactive_alpha_ratio * SK_AlphaOPAQUE); @@ -411,8 +410,8 @@ if (profile_indicator_icon_) LayoutProfileIndicator(); - if (hosted_app_button_container()) { - hosted_app_button_container()->LayoutInContainer( + if (web_app_frame_toolbar()) { + web_app_frame_toolbar()->LayoutInContainer( 0, caption_button_container_->x(), 0, painted_height); } @@ -511,8 +510,8 @@ const bool should_show_caption_buttons = ShouldShowCaptionButtons(); caption_button_container_->SetVisible(should_show_caption_buttons); caption_button_container_->UpdateCaptionButtonState(true /*=animate*/); - if (hosted_app_button_container()) - hosted_app_button_container()->SetVisible(should_show_caption_buttons); + if (web_app_frame_toolbar()) + web_app_frame_toolbar()->SetVisible(should_show_caption_buttons); if (enabled) { // Enter immersive mode if the feature is enabled and the widget is not @@ -546,8 +545,8 @@ // TabIconViewModel: bool BrowserNonClientFrameViewAsh::ShouldTabIconViewAnimate() const { - // Hosted apps use their app icon and shouldn't show a throbber. - if (browser_view()->IsBrowserTypeHostedApp()) + // Web apps use their app icon and shouldn't show a throbber. + if (browser_view()->IsBrowserTypeWebApp()) return false; // This function is queried during the creation of the window as the @@ -613,8 +612,8 @@ // their layers. auto* container = browser_view()->top_container(); container->AddChildViewAt(caption_button_container_, 0); - if (hosted_app_button_container()) - container->AddChildViewAt(hosted_app_button_container(), 0); + if (web_app_frame_toolbar()) + container->AddChildViewAt(web_app_frame_toolbar(), 0); if (back_button_) container->AddChildViewAt(back_button_, 0); @@ -623,8 +622,8 @@ void BrowserNonClientFrameViewAsh::OnImmersiveRevealEnded() { AddChildViewAt(caption_button_container_, 0); - if (hosted_app_button_container()) - AddChildViewAt(hosted_app_button_container(), 0); + if (web_app_frame_toolbar()) + AddChildViewAt(web_app_frame_toolbar(), 0); if (back_button_) AddChildViewAt(back_button_, 0); Layout(); @@ -672,8 +671,8 @@ int inset = 0; if (ShouldShowCaptionButtons()) inset += caption_button_container_->GetPreferredSize().width(); - if (hosted_app_button_container()) - inset += hosted_app_button_container()->GetPreferredSize().width(); + if (web_app_frame_toolbar()) + inset += web_app_frame_toolbar()->GetPreferredSize().width(); return inset; } @@ -695,8 +694,8 @@ void BrowserNonClientFrameViewAsh::OnOverviewOrSplitviewModeChanged() { const bool should_show_caption_buttons = ShouldShowCaptionButtons(); caption_button_container_->SetVisible(should_show_caption_buttons); - if (hosted_app_button_container()) - hosted_app_button_container()->SetVisible(should_show_caption_buttons); + if (web_app_frame_toolbar()) + web_app_frame_toolbar()->SetVisible(should_show_caption_buttons); // The entire frame should be repainted for v1 apps, since its visibility can // change (see also ShouldPaint()). Do not invoke this on normal browser @@ -724,16 +723,16 @@ return header; } -void BrowserNonClientFrameViewAsh::SetUpForHostedApp() { +void BrowserNonClientFrameViewAsh::SetUpForWebApp() { Browser* browser = browser_view()->browser(); if (!browser->app_controller()->HasTitlebarToolbar()) return; - // Add the container for extra hosted app buttons (e.g app menu button). - set_hosted_app_button_container(new HostedAppButtonContainer( + // Add the container for extra web app buttons (e.g app menu button). + set_web_app_frame_toolbar(new WebAppFrameToolbarView( frame(), browser_view(), GetCaptionColor(kActive), GetCaptionColor(kInactive))); - AddChildView(hosted_app_button_container()); + AddChildView(web_app_frame_toolbar()); } void BrowserNonClientFrameViewAsh::UpdateTopViewInset() {
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h index b87e88a..498130b 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h
@@ -22,7 +22,7 @@ #include "ui/aura/window_observer.h" namespace { -class HostedAppNonClientFrameViewAshTest; +class WebAppNonClientFrameViewAshTest; } class ProfileIndicatorIcon; @@ -141,11 +141,11 @@ V1BackButton); FRIEND_TEST_ALL_PREFIXES(BrowserNonClientFrameViewAshTest, ToggleTabletModeOnMinimizedWindow); - FRIEND_TEST_ALL_PREFIXES(HostedAppNonClientFrameViewAshTest, + FRIEND_TEST_ALL_PREFIXES(WebAppNonClientFrameViewAshTest, ActiveStateOfButtonMatchesWidget); FRIEND_TEST_ALL_PREFIXES(BrowserNonClientFrameViewAshTest, RestoreMinimizedBrowserUpdatesCaption); - FRIEND_TEST_ALL_PREFIXES(ImmersiveModeControllerAshHostedAppBrowserTest, + FRIEND_TEST_ALL_PREFIXES(ImmersiveModeControllerAshWebAppBrowserTest, FrameLayoutToggleTabletMode); FRIEND_TEST_ALL_PREFIXES(HomeLauncherBrowserNonClientFrameViewAshTest, TabletModeBrowserCaptionButtonVisibility); @@ -157,7 +157,7 @@ FRIEND_TEST_ALL_PREFIXES(NonHomeLauncherBrowserNonClientFrameViewAshTest, HeaderHeightForSnappedBrowserInSplitView); - friend class HostedAppNonClientFrameViewAshTest; + friend class WebAppNonClientFrameViewAshTest; // Returns whether the caption buttons should be visible. They are hidden, for // example, in overview mode and tablet mode. @@ -178,12 +178,12 @@ // Creates the frame header for the browser window. std::unique_ptr<ash::FrameHeader> CreateFrameHeader(); - // Creates views and does other setup for a hosted app. - void SetUpForHostedApp(); + // Creates views and does other setup for a web app. + void SetUpForWebApp(); - // Triggers the hosted app origin and icon animations, assumes the hosted - // app UI elements exist. - void StartHostedAppAnimation(); + // Triggers the web-app origin and icon animations, assumes the web-app UI + // elements exist. + void StartWebAppAnimation(); // Updates the kTopViewInset window property after a layout. void UpdateTopViewInset();
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc index a4395599..2e6ce8d 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc
@@ -48,8 +48,6 @@ #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h" #include "chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/frame/hosted_app_button_container.h" -#include "chrome/browser/ui/views/frame/hosted_app_menu_button.h" #include "chrome/browser/ui/views/frame/immersive_mode_controller.h" #include "chrome/browser/ui/views/frame/immersive_mode_controller_ash.h" #include "chrome/browser/ui/views/fullscreen_control/fullscreen_control_host.h" @@ -63,6 +61,8 @@ #include "chrome/browser/ui/views/toolbar/app_menu.h" #include "chrome/browser/ui/views/toolbar/extension_toolbar_menu_view.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" +#include "chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.h" +#include "chrome/browser/ui/views/web_apps/web_app_menu_button.h" #include "chrome/common/web_application_info.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" @@ -725,13 +725,13 @@ namespace { -class HostedAppNonClientFrameViewAshTest +class WebAppNonClientFrameViewAshTest : public TopChromeMdParamTest<BrowserActionsBarBrowserTest> { public: - HostedAppNonClientFrameViewAshTest() + WebAppNonClientFrameViewAshTest() : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {} - ~HostedAppNonClientFrameViewAshTest() override = default; + ~WebAppNonClientFrameViewAshTest() override = default; GURL GetAppURL() { return https_server_.GetURL("app.com", "/ssl/google.html"); @@ -741,10 +741,10 @@ Browser* app_browser_ = nullptr; BrowserView* browser_view_ = nullptr; ash::DefaultFrameHeader* frame_header_ = nullptr; - HostedAppButtonContainer* hosted_app_button_container_ = nullptr; + WebAppFrameToolbarView* web_app_frame_toolbar_ = nullptr; const std::vector<ContentSettingImageView*>* content_setting_views_ = nullptr; BrowserActionsContainer* browser_actions_container_ = nullptr; - views::Button* app_menu_button_ = nullptr; + views::Button* web_app_menu_button_ = nullptr; void SetUpCommandLine(base::CommandLine* command_line) override { TopChromeMdParamTest<BrowserActionsBarBrowserTest>::SetUpCommandLine( @@ -767,7 +767,7 @@ void SetUpOnMainThread() override { TopChromeMdParamTest<BrowserActionsBarBrowserTest>::SetUpOnMainThread(); - HostedAppButtonContainer::DisableAnimationForTesting(); + WebAppFrameToolbarView::DisableAnimationForTesting(); // Start secure local server. host_resolver()->AddRule("*", "127.0.0.1"); @@ -777,14 +777,16 @@ ASSERT_TRUE(embedded_test_server()->Start()); } - // |SetUpHostedApp()| must be called after |SetUpOnMainThread()| to make sure + // |SetUpWebApp()| must be called after |SetUpOnMainThread()| to make sure // the Network Service process has been setup properly. - void SetUpHostedApp() { + void SetUpWebApp() { WebApplicationInfo web_app_info; web_app_info.app_url = GetAppURL(); web_app_info.scope = GetAppURL().GetWithoutFilename(); web_app_info.theme_color = GetThemeColor(); + // TODO(alancutter): Use web_app::InstallManager instead of Extensions + // specific install path. const extensions::Extension* app = InstallBookmarkApp(web_app_info); content::TestNavigationObserver navigation_observer(GetAppURL()); navigation_observer.StartWatchingNewWebContents(); @@ -796,28 +798,25 @@ frame_header_ = static_cast<ash::DefaultFrameHeader*>(frame_view->frame_header_.get()); - hosted_app_button_container_ = - frame_view->hosted_app_button_container_for_testing(); - DCHECK(hosted_app_button_container_); - DCHECK(hosted_app_button_container_->GetVisible()); + web_app_frame_toolbar_ = frame_view->web_app_frame_toolbar_for_testing(); + DCHECK(web_app_frame_toolbar_); + DCHECK(web_app_frame_toolbar_->GetVisible()); content_setting_views_ = - &hosted_app_button_container_->GetContentSettingViewsForTesting(); + &web_app_frame_toolbar_->GetContentSettingViewsForTesting(); browser_actions_container_ = - hosted_app_button_container_->browser_actions_container_; - app_menu_button_ = hosted_app_button_container_->app_menu_button_; + web_app_frame_toolbar_->browser_actions_container_; + web_app_menu_button_ = web_app_frame_toolbar_->web_app_menu_button_; } AppMenu* GetAppMenu() { - return hosted_app_button_container_->app_menu_button_->app_menu(); + return web_app_frame_toolbar_->web_app_menu_button_->app_menu(); } - SkColor GetActiveColor() { - return hosted_app_button_container_->active_color_; - } + SkColor GetActiveColor() { return web_app_frame_toolbar_->active_color_; } bool GetPaintingAsActive() { - return hosted_app_button_container_->paint_as_active_; + return web_app_frame_toolbar_->paint_as_active_; } PageActionIconView* GetPageActionIcon(PageActionIconType type) { @@ -859,17 +858,17 @@ net::EmbeddedTestServer https_server_; content::ContentMockCertVerifier cert_verifier_; - DISALLOW_COPY_AND_ASSIGN(HostedAppNonClientFrameViewAshTest); + DISALLOW_COPY_AND_ASSIGN(WebAppNonClientFrameViewAshTest); }; } // namespace // Tests that the page info dialog doesn't anchor in a way that puts it outside -// of hosted app windows. This is important as some platforms don't support -// bubble anchor adjustment (see |BubbleDialogDelegateView::CreateBubble()|). -IN_PROC_BROWSER_TEST_P(HostedAppNonClientFrameViewAshTest, +// of web-app windows. This is important as some platforms don't support bubble +// anchor adjustment (see |BubbleDialogDelegateView::CreateBubble()|). +IN_PROC_BROWSER_TEST_P(WebAppNonClientFrameViewAshTest, PageInfoBubblePosition) { - SetUpHostedApp(); + SetUpWebApp(); // Resize app window to only take up the left half of the screen. views::Widget* widget = browser_view_->GetWidget(); gfx::Size screen_size = @@ -881,7 +880,7 @@ // Show page info dialog (currently PWAs use page info in place of an actual // app info dialog). - chrome::ExecuteCommand(app_browser_, IDC_HOSTED_APP_MENU_APP_INFO); + chrome::ExecuteCommand(app_browser_, IDC_WEB_APP_MENU_APP_INFO); // Check the bubble anchors inside the main app window even if there's space // available outside the main app window. @@ -892,61 +891,55 @@ EXPECT_TRUE(widget->GetWindowBoundsInScreen().Contains(page_info_bounds)); } -IN_PROC_BROWSER_TEST_P(HostedAppNonClientFrameViewAshTest, FocusableViews) { - SetUpHostedApp(); +IN_PROC_BROWSER_TEST_P(WebAppNonClientFrameViewAshTest, FocusableViews) { + SetUpWebApp(); EXPECT_TRUE(browser_view_->contents_web_view()->HasFocus()); browser_view_->GetFocusManager()->AdvanceFocus(false); - EXPECT_TRUE(app_menu_button_->HasFocus()); + EXPECT_TRUE(web_app_menu_button_->HasFocus()); browser_view_->GetFocusManager()->AdvanceFocus(false); EXPECT_TRUE(browser_view_->contents_web_view()->HasFocus()); } -IN_PROC_BROWSER_TEST_P(HostedAppNonClientFrameViewAshTest, +IN_PROC_BROWSER_TEST_P(WebAppNonClientFrameViewAshTest, ButtonVisibilityInOverviewMode) { - SetUpHostedApp(); - EXPECT_TRUE(hosted_app_button_container_->GetVisible()); + SetUpWebApp(); + EXPECT_TRUE(web_app_frame_toolbar_->GetVisible()); StartOverview(); - EXPECT_FALSE(hosted_app_button_container_->GetVisible()); + EXPECT_FALSE(web_app_frame_toolbar_->GetVisible()); EndOverview(); - EXPECT_TRUE(hosted_app_button_container_->GetVisible()); + EXPECT_TRUE(web_app_frame_toolbar_->GetVisible()); } -// Tests that a web app's theme color is set. -IN_PROC_BROWSER_TEST_P(HostedAppNonClientFrameViewAshTest, ThemeColor) { - SetUpHostedApp(); +IN_PROC_BROWSER_TEST_P(WebAppNonClientFrameViewAshTest, FrameThemeColorIsSet) { + SetUpWebApp(); aura::Window* window = browser_view_->GetWidget()->GetNativeWindow(); EXPECT_EQ(GetThemeColor(), window->GetProperty(ash::kFrameActiveColorKey)); EXPECT_EQ(GetThemeColor(), window->GetProperty(ash::kFrameInactiveColorKey)); EXPECT_EQ(gfx::kGoogleGrey200, GetActiveColor()); } -// Make sure that for hosted apps, the height of the frame doesn't exceed the +// Make sure that for web apps, the height of the frame doesn't exceed the // height of the caption buttons. -IN_PROC_BROWSER_TEST_P(HostedAppNonClientFrameViewAshTest, FrameSize) { - SetUpHostedApp(); +IN_PROC_BROWSER_TEST_P(WebAppNonClientFrameViewAshTest, FrameSize) { + SetUpWebApp(); const int inset = GetFrameViewAsh(browser_view_)->GetTopInset(false); EXPECT_EQ(inset, views::GetCaptionButtonLayoutSize( views::CaptionButtonLayoutSize::kNonBrowserCaption) .height()); - EXPECT_GE(inset, app_menu_button_->size().height()); - EXPECT_GE(inset, hosted_app_button_container_->size().height()); + EXPECT_GE(inset, web_app_menu_button_->size().height()); + EXPECT_GE(inset, web_app_frame_toolbar_->size().height()); } -// Test that the HostedAppButtonContainer is the designated toolbar button -// provider in this window configuration. -IN_PROC_BROWSER_TEST_P(HostedAppNonClientFrameViewAshTest, - ToolbarButtonProvider) { - SetUpHostedApp(); - EXPECT_EQ(browser_view_->toolbar_button_provider(), - hosted_app_button_container_); +IN_PROC_BROWSER_TEST_P(WebAppNonClientFrameViewAshTest, + IsToolbarButtonProvider) { + SetUpWebApp(); + EXPECT_EQ(browser_view_->toolbar_button_provider(), web_app_frame_toolbar_); } -// Test that the manage passwords icon appears in the title bar for hosted app -// windows. -IN_PROC_BROWSER_TEST_P(HostedAppNonClientFrameViewAshTest, - ManagePasswordsIcon) { - SetUpHostedApp(); +IN_PROC_BROWSER_TEST_P(WebAppNonClientFrameViewAshTest, + ShowManagePasswordsIcon) { + SetUpWebApp(); content::WebContents* web_contents = app_browser_->tab_strip_model()->GetActiveWebContents(); PageActionIconView* manage_passwords_icon = @@ -967,9 +960,8 @@ EXPECT_TRUE(manage_passwords_icon->GetVisible()); } -// Test that the zoom icon appears in the title bar for hosted app windows. -IN_PROC_BROWSER_TEST_P(HostedAppNonClientFrameViewAshTest, ZoomIcon) { - SetUpHostedApp(); +IN_PROC_BROWSER_TEST_P(WebAppNonClientFrameViewAshTest, ShowZoomIcon) { + SetUpWebApp(); content::WebContents* web_contents = app_browser_->tab_strip_model()->GetActiveWebContents(); zoom::ZoomController* zoom_controller = @@ -987,9 +979,8 @@ EXPECT_TRUE(ZoomBubbleView::GetZoomBubble()); } -// Test that the find icon appears in the title bar for hosted app windows. -IN_PROC_BROWSER_TEST_P(HostedAppNonClientFrameViewAshTest, FindIcon) { - SetUpHostedApp(); +IN_PROC_BROWSER_TEST_P(WebAppNonClientFrameViewAshTest, ShowFindIcon) { + SetUpWebApp(); PageActionIconView* find_icon = GetPageActionIcon(PageActionIconType::kFind); EXPECT_TRUE(find_icon); @@ -1000,9 +991,8 @@ EXPECT_TRUE(find_icon->GetVisible()); } -// Test that the find icon appears in the title bar for hosted app windows. -IN_PROC_BROWSER_TEST_P(HostedAppNonClientFrameViewAshTest, TranslateIcon) { - SetUpHostedApp(); +IN_PROC_BROWSER_TEST_P(WebAppNonClientFrameViewAshTest, ShowTranslateIcon) { + SetUpWebApp(); PageActionIconView* translate_icon = GetPageActionIcon(PageActionIconType::kTranslate); @@ -1018,55 +1008,55 @@ EXPECT_TRUE(translate_icon->GetVisible()); } -// Tests that the focus toolbar command focuses the app menu button in web app +// Tests that the focus toolbar command focuses the app menu button in web-app // windows. -IN_PROC_BROWSER_TEST_P(HostedAppNonClientFrameViewAshTest, +IN_PROC_BROWSER_TEST_P(WebAppNonClientFrameViewAshTest, BrowserCommandFocusToolbarAppMenu) { - SetUpHostedApp(); - EXPECT_FALSE(app_menu_button_->HasFocus()); + SetUpWebApp(); + EXPECT_FALSE(web_app_menu_button_->HasFocus()); chrome::ExecuteCommand(app_browser_, IDC_FOCUS_TOOLBAR); - EXPECT_TRUE(app_menu_button_->HasFocus()); + EXPECT_TRUE(web_app_menu_button_->HasFocus()); } // Tests that the focus toolbar command focuses content settings icons before -// the app menu button when present in web app windows. -IN_PROC_BROWSER_TEST_P(HostedAppNonClientFrameViewAshTest, +// the app menu button when present in web-app windows. +IN_PROC_BROWSER_TEST_P(WebAppNonClientFrameViewAshTest, BrowserCommandFocusToolbarGeolocation) { - SetUpHostedApp(); + SetUpWebApp(); ContentSettingImageView* geolocation_icon = GrantGeolocationPermission(); - EXPECT_FALSE(app_menu_button_->HasFocus()); + EXPECT_FALSE(web_app_menu_button_->HasFocus()); EXPECT_FALSE(geolocation_icon->HasFocus()); chrome::ExecuteCommand(app_browser_, IDC_FOCUS_TOOLBAR); - EXPECT_FALSE(app_menu_button_->HasFocus()); + EXPECT_FALSE(web_app_menu_button_->HasFocus()); EXPECT_TRUE(geolocation_icon->HasFocus()); } -// Tests that the show app menu command opens the app menu for web app windows. -IN_PROC_BROWSER_TEST_P(HostedAppNonClientFrameViewAshTest, +// Tests that the show app menu command opens the app menu for web-app windows. +IN_PROC_BROWSER_TEST_P(WebAppNonClientFrameViewAshTest, BrowserCommandShowAppMenu) { - SetUpHostedApp(); + SetUpWebApp(); EXPECT_EQ(nullptr, GetAppMenu()); chrome::ExecuteCommand(app_browser_, IDC_SHOW_APP_MENU); EXPECT_NE(nullptr, GetAppMenu()); } -// Tests that the focus next pane command focuses the app menu for web app +// Tests that the focus next pane command focuses the app menu for web-app // windows. -IN_PROC_BROWSER_TEST_P(HostedAppNonClientFrameViewAshTest, +IN_PROC_BROWSER_TEST_P(WebAppNonClientFrameViewAshTest, BrowserCommandFocusNextPane) { - SetUpHostedApp(); - EXPECT_FALSE(app_menu_button_->HasFocus()); + SetUpWebApp(); + EXPECT_FALSE(web_app_menu_button_->HasFocus()); chrome::ExecuteCommand(app_browser_, IDC_FOCUS_NEXT_PANE); - EXPECT_TRUE(app_menu_button_->HasFocus()); + EXPECT_TRUE(web_app_menu_button_->HasFocus()); } // Tests that the custom tab bar is focusable from the keyboard. -IN_PROC_BROWSER_TEST_P(HostedAppNonClientFrameViewAshTest, +IN_PROC_BROWSER_TEST_P(WebAppNonClientFrameViewAshTest, CustomTabBarIsFocusable) { - SetUpHostedApp(); + SetUpWebApp(); auto* browser_view = BrowserView::GetBrowserViewForBrowser(app_browser_); @@ -1077,27 +1067,26 @@ auto* custom_tab_bar = browser_view->toolbar()->custom_tab_bar(); chrome::ExecuteCommand(app_browser_, IDC_FOCUS_NEXT_PANE); - ASSERT_TRUE(app_menu_button_->HasFocus()); + ASSERT_TRUE(web_app_menu_button_->HasFocus()); EXPECT_FALSE(custom_tab_bar->close_button_for_testing()->HasFocus()); chrome::ExecuteCommand(app_browser_, IDC_FOCUS_NEXT_PANE); EXPECT_TRUE(custom_tab_bar->close_button_for_testing()->HasFocus()); } -// Tests that the focus previous pane command focuses the app menu for web app +// Tests that the focus previous pane command focuses the app menu for web-app // windows. -IN_PROC_BROWSER_TEST_P(HostedAppNonClientFrameViewAshTest, +IN_PROC_BROWSER_TEST_P(WebAppNonClientFrameViewAshTest, BrowserCommandFocusPreviousPane) { - SetUpHostedApp(); - EXPECT_FALSE(app_menu_button_->HasFocus()); + SetUpWebApp(); + EXPECT_FALSE(web_app_menu_button_->HasFocus()); chrome::ExecuteCommand(app_browser_, IDC_FOCUS_PREVIOUS_PANE); - EXPECT_TRUE(app_menu_button_->HasFocus()); + EXPECT_TRUE(web_app_menu_button_->HasFocus()); } // Tests that a web app's content settings icons can be interacted with. -IN_PROC_BROWSER_TEST_P(HostedAppNonClientFrameViewAshTest, - ContentSettingIcons) { - SetUpHostedApp(); +IN_PROC_BROWSER_TEST_P(WebAppNonClientFrameViewAshTest, ContentSettingIcons) { + SetUpWebApp(); for (auto* view : *content_setting_views_) EXPECT_FALSE(view->GetVisible()); @@ -1124,8 +1113,8 @@ } // Tests that a web app's browser action icons can be interacted with. -IN_PROC_BROWSER_TEST_P(HostedAppNonClientFrameViewAshTest, BrowserActions) { - SetUpHostedApp(); +IN_PROC_BROWSER_TEST_P(WebAppNonClientFrameViewAshTest, BrowserActions) { + SetUpWebApp(); // Even though 2 are visible in the browser, no extension actions should show. ToolbarActionsBar* toolbar_actions_bar = browser_actions_container_->toolbar_actions_bar(); @@ -1134,7 +1123,7 @@ EXPECT_EQ(0u, browser_actions_container_->VisibleBrowserActions()); // Show the menu. - SimulateClickOnView(app_menu_button_); + SimulateClickOnView(web_app_menu_button_); // All extension actions should always be showing in the menu. EXPECT_EQ(3u, GetAppMenu() @@ -1149,9 +1138,9 @@ } // Regression test for https://crbug.com/839955 -IN_PROC_BROWSER_TEST_P(HostedAppNonClientFrameViewAshTest, +IN_PROC_BROWSER_TEST_P(WebAppNonClientFrameViewAshTest, ActiveStateOfButtonMatchesWidget) { - SetUpHostedApp(); + SetUpWebApp(); ash::FrameCaptionButtonContainerView::TestApi test( GetFrameViewAsh(browser_view_)->caption_button_container_); EXPECT_TRUE(test.size_button()->paint_as_active()); @@ -1472,6 +1461,6 @@ INSTANTIATE_TEST_SUITE(BrowserNonClientFrameViewAshTest); INSTANTIATE_TEST_SUITE(ImmersiveModeBrowserViewTest); -INSTANTIATE_TEST_SUITE(HostedAppNonClientFrameViewAshTest); +INSTANTIATE_TEST_SUITE(WebAppNonClientFrameViewAshTest); INSTANTIATE_TEST_SUITE(BrowserNonClientFrameViewAshBackButtonTest); INSTANTIATE_TEST_SUITE(HomeLauncherBrowserNonClientFrameViewAshTest);
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc index 409b1aa..0bbe7f5 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc
@@ -154,7 +154,7 @@ EXPECT_EQ(nullptr, BrowserView::GetBrowserViewForBrowser(app_browser) ->frame() ->GetFrameView() - ->hosted_app_button_container_for_testing()); + ->web_app_frame_toolbar_for_testing()); } // Checks that the title bar for hosted app windows is hidden when in fullscreen
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.mm b/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.mm index 07c006e..edd7f1f 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.mm +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.mm
@@ -19,9 +19,9 @@ #include "chrome/browser/ui/views/frame/browser_frame.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/browser_view_layout.h" -#include "chrome/browser/ui/views/frame/hosted_app_button_container.h" #include "chrome/browser/ui/views/tabs/tab_strip.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" +#include "chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.h" #include "chrome/browser/ui/web_applications/app_browser_controller.h" #include "chrome/common/chrome_features.h" #include "chrome/common/chrome_switches.h" @@ -67,17 +67,17 @@ *show_fullscreen_toolbar_)]; } - if (browser_view->IsBrowserTypeHostedApp()) { + if (browser_view->IsBrowserTypeWebApp()) { if (browser_view->browser()->app_controller()->HasTitlebarToolbar()) { - set_hosted_app_button_container(new HostedAppButtonContainer( - frame, browser_view, GetCaptionColor(kActive), - GetCaptionColor(kInactive), kHostedAppMenuMargin)); - AddChildView(hosted_app_button_container()); + set_web_app_frame_toolbar( + AddChildView(std::make_unique<WebAppFrameToolbarView>( + frame, browser_view, GetCaptionColor(kActive), + GetCaptionColor(kInactive), kHostedAppMenuMargin))); } DCHECK(browser_view->ShouldShowWindowTitle()); - window_title_ = new views::Label(browser_view->GetWindowTitle()); - AddChildView(window_title_); + window_title_ = AddChildView( + std::make_unique<views::Label>(browser_view->GetWindowTitle())); } } @@ -128,11 +128,11 @@ } int BrowserNonClientFrameViewMac::GetTopInset(bool restored) const { - if (hosted_app_button_container()) { - DCHECK(browser_view()->IsBrowserTypeHostedApp()); + if (web_app_frame_toolbar()) { + DCHECK(browser_view()->IsBrowserTypeWebApp()); if (ShouldHideTopUIForFullscreen()) return 0; - return hosted_app_button_container()->GetPreferredSize().height() + + return web_app_frame_toolbar()->GetPreferredSize().height() + kHostedAppMenuMargin * 2; } @@ -298,7 +298,7 @@ void BrowserNonClientFrameViewMac::OnPaint(gfx::Canvas* canvas) { if (!browser_view()->IsBrowserTypeNormal() && - !browser_view()->IsBrowserTypeHostedApp()) { + !browser_view()->IsBrowserTypeWebApp()) { return; } @@ -321,8 +321,8 @@ int leading_x = kFramePaddingLeft; int trailing_x = width(); - if (hosted_app_button_container()) { - trailing_x = hosted_app_button_container()->LayoutInContainer( + if (web_app_frame_toolbar()) { + trailing_x = web_app_frame_toolbar()->LayoutInContainer( leading_x, trailing_x, 0, available_height); const int title_padding = base::checked_cast<int>(
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index 1a6c19a..3426a28 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -623,7 +623,7 @@ return browser_->tab_strip_model()->GetActiveWebContents(); } -bool BrowserView::IsBrowserTypeHostedApp() const { +bool BrowserView::IsBrowserTypeWebApp() const { return web_app::AppBrowserController::IsForWebAppBrowser(browser_.get()); }
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h index ee48ce1..3bf45ab 100644 --- a/chrome/browser/ui/views/frame/browser_view.h +++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -250,8 +250,8 @@ bool IsBrowserTypeNormal() const { return browser_->is_type_normal(); } // Returns true if the Browser object associated with this BrowserView is a - // for an installed hosted app. - bool IsBrowserTypeHostedApp() const; + // for an installed web app. + bool IsBrowserTypeWebApp() const; // Returns true if the top browser controls (a.k.a. top-chrome UIs) are // allowed to slide up and down with the gesture scrolls on the current tab's
diff --git a/chrome/browser/ui/views/frame/desktop_browser_frame_aura_linux.cc b/chrome/browser/ui/views/frame/desktop_browser_frame_aura_linux.cc index 4eef9fd..7f972678 100644 --- a/chrome/browser/ui/views/frame/desktop_browser_frame_aura_linux.cc +++ b/chrome/browser/ui/views/frame/desktop_browser_frame_aura_linux.cc
@@ -61,7 +61,7 @@ // Hosted app windows get a custom frame (if the desktop PWA experimental // feature is enabled). - if (browser_view()->IsBrowserTypeHostedApp()) + if (browser_view()->IsBrowserTypeWebApp()) return true; return false;
diff --git a/chrome/browser/ui/views/frame/glass_browser_frame_view.cc b/chrome/browser/ui/views/frame/glass_browser_frame_view.cc index b3fc6e7b..ee20f12 100644 --- a/chrome/browser/ui/views/frame/glass_browser_frame_view.cc +++ b/chrome/browser/ui/views/frame/glass_browser_frame_view.cc
@@ -14,11 +14,11 @@ #include "chrome/browser/themes/theme_properties.h" #include "chrome/browser/ui/view_ids.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/frame/hosted_app_button_container.h" #include "chrome/browser/ui/views/tabs/new_tab_button.h" #include "chrome/browser/ui/views/tabs/tab.h" #include "chrome/browser/ui/views/tabs/tab_strip.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" +#include "chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.h" #include "chrome/browser/ui/web_applications/app_browser_controller.h" #include "chrome/browser/win/titlebar_config.h" #include "content/public/browser/web_contents.h" @@ -115,12 +115,12 @@ browser_view->browser()->app_controller(); if (controller && controller->HasTitlebarToolbar()) { // TODO(alancutter): Avoid snapshotting GetCaptionColor() values here and - // call it on demand in HostedAppButtonContainer::UpdateIconsColor() via a + // call it on demand in WebAppFrameToolbarView::UpdateIconsColor() via a // delegate interface. - set_hosted_app_button_container(new HostedAppButtonContainer( - frame, browser_view, GetCaptionColor(kActive), - GetCaptionColor(kInactive))); - AddChildView(hosted_app_button_container()); + set_web_app_frame_toolbar( + AddChildView(std::make_unique<WebAppFrameToolbarView>( + frame, browser_view, GetCaptionColor(kActive), + GetCaptionColor(kInactive)))); } minimize_button_ = @@ -493,14 +493,13 @@ int GlassBrowserFrameView::TitlebarMaximizedVisualHeight() const { int maximized_height = display::win::ScreenWin::GetSystemMetricsInDIP(SM_CYCAPTION); - if (hosted_app_button_container()) { + if (web_app_frame_toolbar()) { // Adding 2px of vertical padding puts at least 1 px of space on the top and // bottom of the element. constexpr int kVerticalPadding = 2; - maximized_height = - std::max(maximized_height, - hosted_app_button_container()->GetPreferredSize().height() + - kVerticalPadding); + maximized_height = std::max( + maximized_height, web_app_frame_toolbar()->GetPreferredSize().height() + + kVerticalPadding); } return maximized_height; } @@ -541,8 +540,8 @@ } bool GlassBrowserFrameView::ShowCustomIcon() const { - // Hosted app windows don't include the window icon as per UI mocks. - return !hosted_app_button_container() && ShouldCustomDrawSystemTitlebar() && + // Web-app windows don't include the window icon as per UI mocks. + return !web_app_frame_toolbar() && ShouldCustomDrawSystemTitlebar() && browser_view()->ShouldShowWindowIcon(); } @@ -669,8 +668,8 @@ next_leading_x = window_icon_bounds.right() + kIconTitleSpacing; } - if (hosted_app_button_container()) { - next_trailing_x = hosted_app_button_container()->LayoutInContainer( + if (web_app_frame_toolbar()) { + next_trailing_x = web_app_frame_toolbar()->LayoutInContainer( next_leading_x, next_trailing_x, window_top, titlebar_visual_height); }
diff --git a/chrome/browser/ui/views/frame/glass_browser_frame_view_browsertest_win.cc b/chrome/browser/ui/views/frame/glass_browser_frame_view_browsertest_win.cc index e9cdc67..f9da929 100644 --- a/chrome/browser/ui/views/frame/glass_browser_frame_view_browsertest_win.cc +++ b/chrome/browser/ui/views/frame/glass_browser_frame_view_browsertest_win.cc
@@ -10,36 +10,38 @@ #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/views/frame/app_menu_button.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/frame/hosted_app_button_container.h" #include "chrome/browser/ui/views/page_action/omnibox_page_action_icon_container_view.h" +#include "chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.h" #include "chrome/common/web_application_info.h" #include "chrome/test/base/in_process_browser_test.h" #include "content/public/test/test_navigation_observer.h" -class HostedAppGlassBrowserFrameViewTest : public InProcessBrowserTest { +class WebAppGlassBrowserFrameViewTest : public InProcessBrowserTest { public: - HostedAppGlassBrowserFrameViewTest() = default; - ~HostedAppGlassBrowserFrameViewTest() override = default; + WebAppGlassBrowserFrameViewTest() = default; + ~WebAppGlassBrowserFrameViewTest() override = default; GURL GetAppURL() { return GURL("https://test.org"); } void SetUpOnMainThread() override { InProcessBrowserTest::SetUpOnMainThread(); - HostedAppButtonContainer::DisableAnimationForTesting(); + WebAppFrameToolbarView::DisableAnimationForTesting(); } // Windows 7 does not use GlassBrowserFrameView when Aero glass is not // enabled. Skip testing in this scenario. // TODO(https://crbug.com/863278): Force Aero glass on Windows 7 for this // test. - bool InstallAndLaunchHostedApp() { + bool InstallAndLaunchWebApp() { WebApplicationInfo web_app_info; web_app_info.app_url = GetAppURL(); web_app_info.scope = GetAppURL().GetWithoutFilename(); if (theme_color_) web_app_info.theme_color = *theme_color_; + // TODO(alancutter): Use web_app::InstallManager instead of Extensions + // specific install path. const extensions::Extension* app = extensions::browsertest_util::InstallBookmarkApp(browser()->profile(), web_app_info); @@ -57,10 +59,10 @@ return false; glass_frame_view_ = static_cast<GlassBrowserFrameView*>(frame_view); - hosted_app_button_container_ = - glass_frame_view_->hosted_app_button_container_for_testing(); - DCHECK(hosted_app_button_container_); - DCHECK(hosted_app_button_container_->GetVisible()); + web_app_frame_toolbar_ = + glass_frame_view_->web_app_frame_toolbar_for_testing(); + DCHECK(web_app_frame_toolbar_); + DCHECK(web_app_frame_toolbar_->GetVisible()); return true; } @@ -68,22 +70,22 @@ Browser* app_browser_ = nullptr; BrowserView* browser_view_ = nullptr; GlassBrowserFrameView* glass_frame_view_ = nullptr; - HostedAppButtonContainer* hosted_app_button_container_ = nullptr; + WebAppFrameToolbarView* web_app_frame_toolbar_ = nullptr; private: - DISALLOW_COPY_AND_ASSIGN(HostedAppGlassBrowserFrameViewTest); + DISALLOW_COPY_AND_ASSIGN(WebAppGlassBrowserFrameViewTest); }; -IN_PROC_BROWSER_TEST_F(HostedAppGlassBrowserFrameViewTest, ThemeColor) { - if (!InstallAndLaunchHostedApp()) +IN_PROC_BROWSER_TEST_F(WebAppGlassBrowserFrameViewTest, ThemeColor) { + if (!InstallAndLaunchWebApp()) return; EXPECT_EQ(glass_frame_view_->GetTitlebarColor(), *theme_color_); } -IN_PROC_BROWSER_TEST_F(HostedAppGlassBrowserFrameViewTest, NoThemeColor) { +IN_PROC_BROWSER_TEST_F(WebAppGlassBrowserFrameViewTest, NoThemeColor) { theme_color_ = base::nullopt; - if (!InstallAndLaunchHostedApp()) + if (!InstallAndLaunchWebApp()) return; EXPECT_EQ( @@ -91,20 +93,20 @@ ThemeProperties::GetDefaultColor(ThemeProperties::COLOR_FRAME, false)); } -IN_PROC_BROWSER_TEST_F(HostedAppGlassBrowserFrameViewTest, SpaceConstrained) { +IN_PROC_BROWSER_TEST_F(WebAppGlassBrowserFrameViewTest, SpaceConstrained) { theme_color_ = base::nullopt; - if (!InstallAndLaunchHostedApp()) + if (!InstallAndLaunchWebApp()) return; views::View* omnibox_page_action_icon_container = browser_view_->toolbar_button_provider() ->GetOmniboxPageActionIconContainerView(); EXPECT_EQ(omnibox_page_action_icon_container->parent(), - hosted_app_button_container_); + web_app_frame_toolbar_); views::View* menu_button = browser_view_->toolbar_button_provider()->GetAppMenuButton(); - EXPECT_EQ(menu_button->parent(), hosted_app_button_container_); + EXPECT_EQ(menu_button->parent(), web_app_frame_toolbar_); // Initially the page action icons are not visible, just the menu button has // width. @@ -119,13 +121,13 @@ EXPECT_GT(omnibox_page_action_icon_container->width(), 0); EXPECT_EQ(menu_button->width(), original_menu_button_width); - // Resize the HostedAppButtonContainer just enough to clip out the page action + // Resize the WebAppFrameToolbarView just enough to clip out the page action // icons. - hosted_app_button_container_->SetSize( - gfx::Size(hosted_app_button_container_->width() - + web_app_frame_toolbar_->SetSize( + gfx::Size(web_app_frame_toolbar_->width() - omnibox_page_action_icon_container->bounds().right(), - hosted_app_button_container_->height())); - hosted_app_button_container_->Layout(); + web_app_frame_toolbar_->height())); + web_app_frame_toolbar_->Layout(); // The page action icons should be clipped to 0 width while the app menu // button retains its full width. @@ -133,14 +135,13 @@ EXPECT_EQ(menu_button->width(), original_menu_button_width); } -IN_PROC_BROWSER_TEST_F(HostedAppGlassBrowserFrameViewTest, MaximizedLayout) { - if (!InstallAndLaunchHostedApp()) +IN_PROC_BROWSER_TEST_F(WebAppGlassBrowserFrameViewTest, MaximizedLayout) { + if (!InstallAndLaunchWebApp()) return; glass_frame_view_->frame()->Maximize(); static_cast<views::View*>(glass_frame_view_)->Layout(); DCHECK_GT(glass_frame_view_->window_title_for_testing()->x(), 0); - DCHECK_GT(glass_frame_view_->hosted_app_button_container_for_testing()->y(), - 0); + DCHECK_GT(glass_frame_view_->web_app_frame_toolbar_for_testing()->y(), 0); }
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc index 0ae0bf8..e820848e 100644 --- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc +++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc
@@ -17,12 +17,12 @@ #include "chrome/browser/ui/views/frame/browser_non_client_frame_view.h" #include "chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/frame/hosted_app_button_container.h" -#include "chrome/browser/ui/views/frame/hosted_app_menu_button.h" #include "chrome/browser/ui/views/frame/immersive_mode_controller_ash.h" #include "chrome/browser/ui/views/frame/top_container_view.h" #include "chrome/browser/ui/views/tabs/tab_strip.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" +#include "chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.h" +#include "chrome/browser/ui/views/web_apps/web_app_menu_button.h" #include "chrome/common/web_application_info.h" #include "chrome/test/base/ui_test_utils.h" #include "content/public/test/content_mock_cert_verifier.h" @@ -31,13 +31,13 @@ #include "ui/views/animation/test/ink_drop_host_view_test_api.h" #include "ui/views/window/frame_caption_button.h" -class ImmersiveModeControllerAshHostedAppBrowserTest +class ImmersiveModeControllerAshWebAppBrowserTest : public extensions::ExtensionBrowserTest { public: - ImmersiveModeControllerAshHostedAppBrowserTest() + ImmersiveModeControllerAshWebAppBrowserTest() : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {} - ~ImmersiveModeControllerAshHostedAppBrowserTest() override = default; + ~ImmersiveModeControllerAshWebAppBrowserTest() override = default; // InProcessBrowserTest override: void SetUpOnMainThread() override { @@ -112,10 +112,10 @@ } void VerifyButtonsInImmersiveMode(BrowserNonClientFrameViewAsh* frame_view) { - HostedAppButtonContainer* container = - frame_view->hosted_app_button_container_for_testing(); + WebAppFrameToolbarView* container = + frame_view->web_app_frame_toolbar_for_testing(); views::test::InkDropHostViewTestApi ink_drop_api( - container->app_menu_button_); + container->web_app_menu_button_); EXPECT_TRUE(container->GetContentSettingContainerForTesting()->layer()); EXPECT_EQ(views::InkDropHostView::InkDropMode::ON, ink_drop_api.ink_drop_mode()); @@ -127,7 +127,7 @@ } ImmersiveModeController* controller() { return controller_; } base::TimeDelta titlebar_animation_delay() { - return HostedAppButtonContainer::kTitlebarAnimationDelay; + return WebAppFrameToolbarView::kTitlebarAnimationDelay; } private: @@ -143,12 +143,12 @@ // used by the NetworkService. content::ContentMockCertVerifier cert_verifier_; - DISALLOW_COPY_AND_ASSIGN(ImmersiveModeControllerAshHostedAppBrowserTest); + DISALLOW_COPY_AND_ASSIGN(ImmersiveModeControllerAshWebAppBrowserTest); }; // Test the layout and visibility of the TopContainerView and web contents when -// a hosted app is put into immersive fullscreen. -IN_PROC_BROWSER_TEST_F(ImmersiveModeControllerAshHostedAppBrowserTest, Layout) { +// a web app is put into immersive fullscreen. +IN_PROC_BROWSER_TEST_F(ImmersiveModeControllerAshWebAppBrowserTest, Layout) { LaunchAppBrowser(); TabStrip* tabstrip = browser_view()->tabstrip(); ToolbarView* toolbar = browser_view()->toolbar(); @@ -159,7 +159,7 @@ ASSERT_FALSE(browser_view()->GetWidget()->IsFullscreen()); ASSERT_FALSE(controller()->IsEnabled()); - // The tabstrip is not visible for hosted apps. + // The tabstrip is not visible for web apps. EXPECT_FALSE(tabstrip->GetVisible()); EXPECT_TRUE(toolbar->GetVisible()); @@ -207,7 +207,7 @@ // Verify the immersive mode status is as expected in tablet mode (titlebars are // autohidden in tablet mode). -IN_PROC_BROWSER_TEST_F(ImmersiveModeControllerAshHostedAppBrowserTest, +IN_PROC_BROWSER_TEST_F(ImmersiveModeControllerAshWebAppBrowserTest, ImmersiveModeStatusTabletMode) { LaunchAppBrowser(); ASSERT_FALSE(controller()->IsEnabled()); @@ -258,7 +258,7 @@ // Verify that the frame layout is as expected when using immersive mode in // tablet mode. -IN_PROC_BROWSER_TEST_F(ImmersiveModeControllerAshHostedAppBrowserTest, +IN_PROC_BROWSER_TEST_F(ImmersiveModeControllerAshWebAppBrowserTest, FrameLayoutToggleTabletMode) { LaunchAppBrowser(); ASSERT_FALSE(controller()->IsEnabled()); @@ -297,7 +297,7 @@ // Verify that the frame layout for new windows is as expected when using // immersive mode in tablet mode. -IN_PROC_BROWSER_TEST_F(ImmersiveModeControllerAshHostedAppBrowserTest, +IN_PROC_BROWSER_TEST_F(ImmersiveModeControllerAshWebAppBrowserTest, FrameLayoutStartInTabletMode) { // Start in tablet mode ash::ShellTestApi().SetTabletModeEnabledForTest(true);
diff --git a/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc b/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc index 818808bf..b2cca4c 100644 --- a/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc +++ b/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc
@@ -13,13 +13,13 @@ #include "chrome/browser/ui/layout_constants.h" #include "chrome/browser/ui/views/frame/browser_frame.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/frame/hosted_app_button_container.h" #include "chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.h" #include "chrome/browser/ui/views/frame/opaque_browser_frame_view_platform_specific.h" #include "chrome/browser/ui/views/tab_icon_view.h" #include "chrome/browser/ui/views/tabs/new_tab_button.h" #include "chrome/browser/ui/views/tabs/tab_strip.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" +#include "chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.h" #include "chrome/browser/ui/web_applications/app_browser_controller.h" #include "chrome/grit/generated_resources.h" #include "chrome/grit/theme_resources.h" @@ -184,10 +184,10 @@ web_app::AppBrowserController* controller = browser_view()->browser()->app_controller(); if (controller && controller->HasTitlebarToolbar()) { - set_hosted_app_button_container(new HostedAppButtonContainer( - frame(), browser_view(), GetCaptionColor(kActive), - GetCaptionColor(kInactive))); - AddChildView(hosted_app_button_container()); + set_web_app_frame_toolbar( + AddChildView(std::make_unique<WebAppFrameToolbarView>( + frame(), browser_view(), GetCaptionColor(kActive), + GetCaptionColor(kInactive)))); } }
diff --git a/chrome/browser/ui/views/frame/opaque_browser_frame_view.h b/chrome/browser/ui/views/frame/opaque_browser_frame_view.h index dd0b91ad..75e8fa7 100644 --- a/chrome/browser/ui/views/frame/opaque_browser_frame_view.h +++ b/chrome/browser/ui/views/frame/opaque_browser_frame_view.h
@@ -124,7 +124,7 @@ OpaqueBrowserFrameViewLayout* layout() { return layout_; } private: - friend class HostedAppOpaqueBrowserFrameViewTest; + friend class WebAppOpaqueBrowserFrameViewTest; // Creates and returns a FrameCaptionButton with |this| as its listener. // Memory is owned by the caller.
diff --git a/chrome/browser/ui/views/frame/opaque_browser_frame_view_browsertest.cc b/chrome/browser/ui/views/frame/opaque_browser_frame_view_browsertest.cc index 43512195..5857667 100644 --- a/chrome/browser/ui/views/frame/opaque_browser_frame_view_browsertest.cc +++ b/chrome/browser/ui/views/frame/opaque_browser_frame_view_browsertest.cc
@@ -11,25 +11,25 @@ #include "chrome/browser/themes/theme_service_factory.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/frame/hosted_app_button_container.h" #include "chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.h" +#include "chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.h" #include "chrome/common/chrome_features.h" #include "chrome/common/web_application_info.h" #include "chrome/test/base/in_process_browser_test.h" #include "ui/views/test/test_views.h" -// Tests hosted app windows that use the OpaqueBrowserFrameView implementation +// Tests web-app windows that use the OpaqueBrowserFrameView implementation // for their non client frames. -class HostedAppOpaqueBrowserFrameViewTest : public InProcessBrowserTest { +class WebAppOpaqueBrowserFrameViewTest : public InProcessBrowserTest { public: - HostedAppOpaqueBrowserFrameViewTest() = default; - ~HostedAppOpaqueBrowserFrameViewTest() override = default; + WebAppOpaqueBrowserFrameViewTest() = default; + ~WebAppOpaqueBrowserFrameViewTest() override = default; static GURL GetAppURL() { return GURL("https://test.org"); } void SetUpOnMainThread() override { SetThemeMode(ThemeMode::kDefault); } - bool InstallAndLaunchHostedApp( + bool InstallAndLaunchWebApp( base::Optional<SkColor> theme_color = base::nullopt) { WebApplicationInfo web_app_info; web_app_info.app_url = GetAppURL(); @@ -61,10 +61,10 @@ opaque_browser_frame_view_ = static_cast<OpaqueBrowserFrameView*>(frame_view); - hosted_app_button_container_ = - opaque_browser_frame_view_->hosted_app_button_container_for_testing(); - DCHECK(hosted_app_button_container_); - DCHECK(hosted_app_button_container_->GetVisible()); + web_app_frame_toolbar_ = + opaque_browser_frame_view_->web_app_frame_toolbar_for_testing(); + DCHECK(web_app_frame_toolbar_); + DCHECK(web_app_frame_toolbar_->GetVisible()); return true; } @@ -90,68 +90,65 @@ } OpaqueBrowserFrameView* opaque_browser_frame_view_ = nullptr; - HostedAppButtonContainer* hosted_app_button_container_ = nullptr; + WebAppFrameToolbarView* web_app_frame_toolbar_ = nullptr; private: - DISALLOW_COPY_AND_ASSIGN(HostedAppOpaqueBrowserFrameViewTest); + DISALLOW_COPY_AND_ASSIGN(WebAppOpaqueBrowserFrameViewTest); }; -IN_PROC_BROWSER_TEST_F(HostedAppOpaqueBrowserFrameViewTest, NoThemeColor) { - if (!InstallAndLaunchHostedApp()) +IN_PROC_BROWSER_TEST_F(WebAppOpaqueBrowserFrameViewTest, NoThemeColor) { + if (!InstallAndLaunchWebApp()) return; - EXPECT_EQ(hosted_app_button_container_->active_color_for_testing(), + EXPECT_EQ(web_app_frame_toolbar_->active_color_for_testing(), gfx::kGoogleGrey900); } #if defined(OS_LINUX) && !defined(OS_CHROMEOS) -IN_PROC_BROWSER_TEST_F(HostedAppOpaqueBrowserFrameViewTest, SystemThemeColor) { +IN_PROC_BROWSER_TEST_F(WebAppOpaqueBrowserFrameViewTest, SystemThemeColor) { SetThemeMode(ThemeMode::kSystem); // The color here should be ignored in system mode. - ASSERT_TRUE(InstallAndLaunchHostedApp(SK_ColorRED)); + ASSERT_TRUE(InstallAndLaunchWebApp(SK_ColorRED)); - EXPECT_EQ(hosted_app_button_container_->active_color_for_testing(), + EXPECT_EQ(web_app_frame_toolbar_->active_color_for_testing(), gfx::kGoogleGrey900); } #endif // defined(OS_LINUX) && !defined(OS_CHROMEOS) -IN_PROC_BROWSER_TEST_F(HostedAppOpaqueBrowserFrameViewTest, LightThemeColor) { - if (!InstallAndLaunchHostedApp(SK_ColorYELLOW)) +IN_PROC_BROWSER_TEST_F(WebAppOpaqueBrowserFrameViewTest, LightThemeColor) { + if (!InstallAndLaunchWebApp(SK_ColorYELLOW)) return; - EXPECT_EQ(hosted_app_button_container_->active_color_for_testing(), + EXPECT_EQ(web_app_frame_toolbar_->active_color_for_testing(), gfx::kGoogleGrey900); } -IN_PROC_BROWSER_TEST_F(HostedAppOpaqueBrowserFrameViewTest, DarkThemeColor) { - if (!InstallAndLaunchHostedApp(SK_ColorBLUE)) +IN_PROC_BROWSER_TEST_F(WebAppOpaqueBrowserFrameViewTest, DarkThemeColor) { + if (!InstallAndLaunchWebApp(SK_ColorBLUE)) return; - EXPECT_EQ(hosted_app_button_container_->active_color_for_testing(), - SK_ColorWHITE); + EXPECT_EQ(web_app_frame_toolbar_->active_color_for_testing(), SK_ColorWHITE); } -IN_PROC_BROWSER_TEST_F(HostedAppOpaqueBrowserFrameViewTest, MediumThemeColor) { +IN_PROC_BROWSER_TEST_F(WebAppOpaqueBrowserFrameViewTest, MediumThemeColor) { // Use the theme color for Gmail. - if (!InstallAndLaunchHostedApp(SkColorSetRGB(0xd6, 0x49, 0x3b))) + if (!InstallAndLaunchWebApp(SkColorSetRGB(0xd6, 0x49, 0x3b))) return; - EXPECT_EQ(hosted_app_button_container_->active_color_for_testing(), - SK_ColorWHITE); + EXPECT_EQ(web_app_frame_toolbar_->active_color_for_testing(), SK_ColorWHITE); } -IN_PROC_BROWSER_TEST_F(HostedAppOpaqueBrowserFrameViewTest, - StaticTitleBarHeight) { - if (!InstallAndLaunchHostedApp()) +IN_PROC_BROWSER_TEST_F(WebAppOpaqueBrowserFrameViewTest, StaticTitleBarHeight) { + if (!InstallAndLaunchWebApp()) return; const int title_bar_height = GetRestoredTitleBarHeight(); EXPECT_GT(title_bar_height, 0); - // Add taller children to the hosted app button container. - const int container_height = hosted_app_button_container_->height(); - hosted_app_button_container_->AddChildView( + // Add taller children to the web app frame toolbar. + const int container_height = web_app_frame_toolbar_->height(); + web_app_frame_toolbar_->AddChildView( new views::StaticSizedView(gfx::Size(1, title_bar_height * 2))); opaque_browser_frame_view_->Layout(); - // The height of the hosted app button container and title bar should not be + // The height of the web app frame toolbar and title bar should not be // affected. - EXPECT_EQ(container_height, hosted_app_button_container_->height()); + EXPECT_EQ(container_height, web_app_frame_toolbar_->height()); EXPECT_EQ(title_bar_height, GetRestoredTitleBarHeight()); }
diff --git a/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.cc b/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.cc index 90d67940..36001d1 100644 --- a/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.cc +++ b/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.cc
@@ -13,7 +13,7 @@ #include "base/numerics/ranges.h" #include "base/stl_util.h" #include "build/build_config.h" -#include "chrome/browser/ui/views/frame/hosted_app_button_container.h" +#include "chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.h" #include "chrome/common/chrome_switches.h" #include "ui/gfx/font.h" #include "ui/views/controls/button/image_button.h" @@ -146,14 +146,13 @@ const int caption_button_height = DefaultCaptionButtonY(restored) + kCaptionButtonHeight + kCaptionButtonBottomPadding; - int hosted_app_button_height = 0; - if (hosted_app_button_container_) { - hosted_app_button_height = - hosted_app_button_container_->GetPreferredSize().height() + - kVerticalPadding; + int web_app_button_height = 0; + if (web_app_frame_toolbar_) { + web_app_button_height = + web_app_frame_toolbar_->GetPreferredSize().height() + kVerticalPadding; } return std::max(std::max(icon_height, caption_button_height), - hosted_app_button_height) + + web_app_button_height) + kContentEdgeShadowThickness; } @@ -300,7 +299,7 @@ bool should_show_title = delegate_->ShouldShowWindowTitle() && window_title_; int icon_y = 0; - if (should_show_icon || should_show_title || hosted_app_button_container_) { + if (should_show_icon || should_show_title || web_app_frame_toolbar_) { use_hidden_icon_location = false; // Our frame border has a different "3D look" than Windows'. Theirs has @@ -322,18 +321,17 @@ const int y = unavailable_px_at_top + (available_height - icon_height) / 2; icon_y = y; - if (hosted_app_button_container_) + if (web_app_frame_toolbar_) available_space_leading_x_ = y - kIconLeftSpacing; window_icon_bounds_ = gfx::Rect(available_space_leading_x_ + kIconLeftSpacing, y, size, size); available_space_leading_x_ += size + kIconLeftSpacing; minimum_size_for_buttons_ += size + kIconLeftSpacing; - if (hosted_app_button_container_) { - available_space_trailing_x_ = - hosted_app_button_container_->LayoutInContainer( - available_space_leading_x_, available_space_trailing_x_, 0, - available_height); + if (web_app_frame_toolbar_) { + available_space_trailing_x_ = web_app_frame_toolbar_->LayoutInContainer( + available_space_leading_x_, available_space_trailing_x_, 0, + available_height); } } @@ -346,8 +344,7 @@ window_title_->SetText(delegate_->GetWindowTitle()); // Extra space between icon and title. - int extra_space = - hosted_app_button_container_ ? icon_y - kIconTitleSpacing : 0; + int extra_space = web_app_frame_toolbar_ ? icon_y - kIconTitleSpacing : 0; int text_width = std::max( 0, available_space_trailing_x_ - kCaptionSpacing - available_space_leading_x_ - kIconTitleSpacing - extra_space); @@ -545,10 +542,9 @@ } window_title_ = static_cast<views::Label*>(view); break; - case VIEW_ID_HOSTED_APP_BUTTON_CONTAINER: - DCHECK_EQ(view->GetClassName(), HostedAppButtonContainer::kViewClassName); - hosted_app_button_container_ = - static_cast<HostedAppButtonContainer*>(view); + case VIEW_ID_WEB_APP_FRAME_TOOLBAR: + DCHECK_EQ(view->GetClassName(), WebAppFrameToolbarView::kViewClassName); + web_app_frame_toolbar_ = static_cast<WebAppFrameToolbarView*>(view); break; default: NOTREACHED() << "Unknown view id " << id;
diff --git a/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.h b/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.h index a95f154..2226a03 100644 --- a/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.h +++ b/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.h
@@ -13,7 +13,7 @@ #include "ui/views/layout/layout_manager.h" #include "ui/views/window/frame_buttons.h" -class HostedAppButtonContainer; +class WebAppFrameToolbarView; class OpaqueBrowserFrameViewLayoutDelegate; namespace views { @@ -219,7 +219,7 @@ views::View* window_icon_; views::Label* window_title_; - HostedAppButtonContainer* hosted_app_button_container_ = nullptr; + WebAppFrameToolbarView* web_app_frame_toolbar_ = nullptr; std::vector<views::FrameButton> leading_buttons_; std::vector<views::FrameButton> trailing_buttons_;
diff --git a/chrome/browser/ui/views/frame/terminal_system_app_menu_button_chromeos.cc b/chrome/browser/ui/views/frame/terminal_system_app_menu_button_chromeos.cc index 87cdfe0..99709b0 100644 --- a/chrome/browser/ui/views/frame/terminal_system_app_menu_button_chromeos.cc +++ b/chrome/browser/ui/views/frame/terminal_system_app_menu_button_chromeos.cc
@@ -13,7 +13,7 @@ TerminalSystemAppMenuButton::TerminalSystemAppMenuButton( BrowserView* browser_view) - : HostedAppMenuButton(browser_view) {} + : WebAppMenuButton(browser_view) {} TerminalSystemAppMenuButton::~TerminalSystemAppMenuButton() {}
diff --git a/chrome/browser/ui/views/frame/terminal_system_app_menu_button_chromeos.h b/chrome/browser/ui/views/frame/terminal_system_app_menu_button_chromeos.h index 99d7b72..5a5a188 100644 --- a/chrome/browser/ui/views/frame/terminal_system_app_menu_button_chromeos.h +++ b/chrome/browser/ui/views/frame/terminal_system_app_menu_button_chromeos.h
@@ -5,11 +5,11 @@ #ifndef CHROME_BROWSER_UI_VIEWS_FRAME_TERMINAL_SYSTEM_APP_MENU_BUTTON_CHROMEOS_H_ #define CHROME_BROWSER_UI_VIEWS_FRAME_TERMINAL_SYSTEM_APP_MENU_BUTTON_CHROMEOS_H_ -#include "chrome/browser/ui/views/frame/hosted_app_menu_button.h" +#include "chrome/browser/ui/views/web_apps/web_app_menu_button.h" class BrowserView; -class TerminalSystemAppMenuButton : public HostedAppMenuButton { +class TerminalSystemAppMenuButton : public WebAppMenuButton { public: explicit TerminalSystemAppMenuButton(BrowserView* browser_view); ~TerminalSystemAppMenuButton() override;
diff --git a/chrome/browser/ui/views/location_bar/custom_tab_bar_view.cc b/chrome/browser/ui/views/location_bar/custom_tab_bar_view.cc index 66a4e93..1c73984 100644 --- a/chrome/browser/ui/views/location_bar/custom_tab_bar_view.cc +++ b/chrome/browser/ui/views/location_bar/custom_tab_bar_view.cc
@@ -16,7 +16,6 @@ #include "chrome/browser/ui/page_info/page_info_dialog.h" #include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/frame/hosted_app_button_container.h" #include "chrome/browser/ui/web_applications/app_browser_controller.h" #include "chrome/grit/generated_resources.h" #include "components/security_interstitials/content/security_interstitial_tab_helper.h" @@ -36,6 +35,7 @@ #include "ui/views/background.h" #include "ui/views/controls/button/image_button.h" #include "ui/views/controls/button/image_button_factory.h" +#include "ui/views/controls/menu/menu_runner.h" #include "ui/views/layout/flex_layout.h" #include "ui/views/layout/flex_layout_types.h" #include "ui/views/style/typography.h"
diff --git a/chrome/browser/ui/views/payments/payment_request_completion_status_metrics_browsertest.cc b/chrome/browser/ui/views/payments/payment_request_completion_status_metrics_browsertest.cc index 3ae5881b..74e9a81 100644 --- a/chrome/browser/ui/views/payments/payment_request_completion_status_metrics_browsertest.cc +++ b/chrome/browser/ui/views/payments/payment_request_completion_status_metrics_browsertest.cc
@@ -496,8 +496,9 @@ using PaymentRequestInitiatedCompletionStatusMetricsTest = PaymentRequestBrowserTestBase; +// Disabled due to flakiness: https://crbug.com/1003253. IN_PROC_BROWSER_TEST_F(PaymentRequestInitiatedCompletionStatusMetricsTest, - Aborted_NotShown) { + DISABLED_Aborted_NotShown) { base::HistogramTester histogram_tester; NavigateTo("/initiated_test.html");
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view_base.cc b/chrome/browser/ui/views/profiles/profile_menu_view_base.cc index cd84957..9d8d515 100644 --- a/chrome/browser/ui/views/profiles/profile_menu_view_base.cc +++ b/chrome/browser/ui/views/profiles/profile_menu_view_base.cc
@@ -30,6 +30,7 @@ #include "ui/views/controls/scroll_view.h" #include "ui/views/controls/separator.h" #include "ui/views/controls/styled_label.h" +#include "ui/views/layout/fill_layout.h" #if !defined(OS_CHROMEOS) #include "chrome/browser/ui/views/profiles/profile_menu_view.h" @@ -62,6 +63,32 @@ return layout; } +std::unique_ptr<views::View> CreateBorderedBoxView( + std::unique_ptr<views::View> children_container) { + constexpr int kOuterMargin = 16; + constexpr int kBorderThickness = 1; + constexpr int kCornerRadius = 8; + const SkColor kBorderColor = + ui::NativeTheme::GetInstanceForNativeUi()->GetSystemColor( + ui::NativeTheme::kColorId_MenuSeparatorColor); + + // Add rounded rectangular border around children. + children_container->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); + children_container->SetBorder(views::CreateRoundedRectBorder( + kBorderThickness, kCornerRadius, kBorderColor)); + + // Create outer view with margin. + // The outer view is needed because |BoxLayout| doesn't support outer + // margins. + auto outer_view = std::make_unique<views::View>(); + outer_view->SetLayoutManager(std::make_unique<views::FillLayout>()); + outer_view->SetBorder(views::CreateEmptyBorder(gfx::Insets(kOuterMargin))); + outer_view->AddChildView(std::move(children_container)); + + return outer_view; +} + } // namespace // MenuItems-------------------------------------------------------------------- @@ -152,12 +179,15 @@ void ProfileMenuViewBase::SetIdentityInfo(const gfx::Image& image, const base::string16& title, const base::string16& subtitle) { + constexpr int kTopMargin = 16; constexpr int kImageToLabelSpacing = 4; identity_info_container_->RemoveAllChildViews(/*delete_children=*/true); identity_info_container_->SetLayoutManager( CreateBoxLayout(views::BoxLayout::Orientation::kVertical, views::BoxLayout::CrossAxisAlignment::kCenter)); + identity_info_container_->SetBorder( + views::CreateEmptyBorder(kTopMargin, 0, 0, 0)); views::ImageView* image_view = identity_info_container_->AddChildView( std::make_unique<views::ImageView>()); @@ -326,10 +356,14 @@ views::BoxLayout::Orientation::kVertical)); // Create and add new component containers in the correct order. + auto bordered_box_container = std::make_unique<views::View>(); identity_info_container_ = - components->AddChildView(std::make_unique<views::View>()); + bordered_box_container->AddChildView(std::make_unique<views::View>()); shortcut_features_container_ = - components->AddChildView(std::make_unique<views::View>()); + bordered_box_container->AddChildView(std::make_unique<views::View>()); + components->AddChildView( + CreateBorderedBoxView(std::move(bordered_box_container))); + selectable_profiles_container_ = components->AddChildView(std::make_unique<views::View>());
diff --git a/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views.cc b/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views.cc index c52d782..f83ebd4 100644 --- a/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views.cc +++ b/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views.cc
@@ -77,10 +77,15 @@ Browser* browser = chrome::FindBrowserWithWebContents(contents); if (!browser) return; + + BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser); + if (!browser_view->contents_border_widget()) { + if (!visible) + return; + InitContentsBorderWidget(contents); + } views::Widget* contents_border_widget = - BrowserView::GetBrowserViewForBrowser(browser)->contents_border_widget(); - if (!contents_border_widget) - return; + browser_view->contents_border_widget(); if (visible) contents_border_widget->Show(); else
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc index 228aa95d..8c1e2d1 100644 --- a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc +++ b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
@@ -2587,8 +2587,17 @@ EXPECT_FALSE(browser2->window()->IsMaximized()); } -IN_PROC_BROWSER_TEST_P(DetachToBrowserInSeparateDisplayTabDragControllerTest, - DragBrowserWindowWhenMajorityOfBoundsInSecondDisplay) { +// Crashes on ChromeOS. crbug.com/1003288 +#if defined(OS_CHROMEOS) +#define MAYBE_DragBrowserWindowWhenMajorityOfBoundsInSecondDisplay \ + DISABLED_CDragBrowserWindowWhenMajorityOfBoundsInSecondDisplay +#else +#define MAYBE_DragBrowserWindowWhenMajorityOfBoundsInSecondDisplay \ + DragBrowserWindowWhenMajorityOfBoundsInSecondDisplay +#endif +IN_PROC_BROWSER_TEST_P( + DetachToBrowserInSeparateDisplayTabDragControllerTest, + MAYBE_DragBrowserWindowWhenMajorityOfBoundsInSecondDisplay) { // Set the browser's window bounds such that the majority of its bounds // resides in the second display. const std::pair<Display, Display> displays =
diff --git a/chrome/browser/ui/views/web_apps/OWNERS b/chrome/browser/ui/views/web_apps/OWNERS new file mode 100644 index 0000000..1255a2c --- /dev/null +++ b/chrome/browser/ui/views/web_apps/OWNERS
@@ -0,0 +1 @@ +file://chrome/browser/web_applications/OWNERS
diff --git a/chrome/browser/ui/views/frame/hosted_app_ash_interactive_ui_test.cc b/chrome/browser/ui/views/web_apps/web_app_ash_interactive_ui_test.cc similarity index 74% rename from chrome/browser/ui/views/frame/hosted_app_ash_interactive_ui_test.cc rename to chrome/browser/ui/views/web_apps/web_app_ash_interactive_ui_test.cc index e973aa1..983f522 100644 --- a/chrome/browser/ui/views/frame/hosted_app_ash_interactive_ui_test.cc +++ b/chrome/browser/ui/views/web_apps/web_app_ash_interactive_ui_test.cc
@@ -8,22 +8,24 @@ #include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h" #include "chrome/browser/ui/exclusive_access/fullscreen_controller_test.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/frame/hosted_app_button_container.h" -#include "chrome/browser/ui/views/frame/hosted_app_menu_button.h" #include "chrome/browser/ui/views/frame/immersive_mode_controller_ash.h" #include "chrome/browser/ui/views/frame/top_container_view.h" +#include "chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.h" +#include "chrome/browser/ui/views/web_apps/web_app_menu_button.h" #include "chrome/common/web_application_info.h" #include "chrome/test/base/interactive_test_utils.h" -class HostedAppAshInteractiveUITest : public extensions::ExtensionBrowserTest { +class WebAppAshInteractiveUITest : public extensions::ExtensionBrowserTest { public: - HostedAppAshInteractiveUITest() = default; - ~HostedAppAshInteractiveUITest() override = default; + WebAppAshInteractiveUITest() = default; + ~WebAppAshInteractiveUITest() override = default; // InProcessBrowserTest override: void SetUpOnMainThread() override { WebApplicationInfo web_app_info; web_app_info.app_url = GURL("https://test.org"); + // TODO(alancutter): Use web_app::InstallManager instead of Extensions + // specific install path. const extensions::Extension* app = InstallBookmarkApp(web_app_info); Browser* browser = ExtensionBrowserTest::LaunchAppBrowser(app); @@ -33,10 +35,10 @@ ash::ImmersiveFullscreenControllerTestApi( static_cast<ImmersiveModeControllerAsh*>(controller_)->controller()) .SetupForTest(); - HostedAppButtonContainer::DisableAnimationForTesting(); + WebAppFrameToolbarView::DisableAnimationForTesting(); } - void CheckHostedAppMenuClickable() { + void CheckWebAppMenuClickable() { AppMenuButton* menu_button = browser_view_->toolbar_button_provider()->GetAppMenuButton(); @@ -61,16 +63,16 @@ ImmersiveModeController* controller_ = nullptr; private: - DISALLOW_COPY_AND_ASSIGN(HostedAppAshInteractiveUITest); + DISALLOW_COPY_AND_ASSIGN(WebAppAshInteractiveUITest); }; -// Test that the hosted app menu button opens a menu on click. -IN_PROC_BROWSER_TEST_F(HostedAppAshInteractiveUITest, MenuButtonClickable) { - CheckHostedAppMenuClickable(); +// Test that the web app menu button opens a menu on click. +IN_PROC_BROWSER_TEST_F(WebAppAshInteractiveUITest, MenuButtonClickable) { + CheckWebAppMenuClickable(); } -// Test that the hosted app menu button opens a menu on click in immersive mode. -IN_PROC_BROWSER_TEST_F(HostedAppAshInteractiveUITest, +// Test that the web app menu button opens a menu on click in immersive mode. +IN_PROC_BROWSER_TEST_F(WebAppAshInteractiveUITest, ImmersiveMenuButtonClickable) { FullscreenNotificationObserver waiter(browser()); chrome::ToggleFullscreenMode(browser()); @@ -80,5 +82,5 @@ controller_->GetRevealedLock( ImmersiveModeControllerAsh::ANIMATE_REVEAL_NO)); - CheckHostedAppMenuClickable(); + CheckWebAppMenuClickable(); }
diff --git a/chrome/browser/ui/views/frame/hosted_app_button_container.cc b/chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.cc similarity index 73% rename from chrome/browser/ui/views/frame/hosted_app_button_container.cc rename to chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.cc index fccfc9f..27aeb4f0 100644 --- a/chrome/browser/ui/views/frame/hosted_app_button_container.cc +++ b/chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/views/frame/hosted_app_button_container.h" +#include "chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.h" #include "base/feature_list.h" #include "base/metrics/histogram_macros.h" @@ -17,11 +17,11 @@ #include "chrome/browser/ui/view_ids.h" #include "chrome/browser/ui/views/extensions/extensions_toolbar_container.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/frame/hosted_app_menu_button.h" -#include "chrome/browser/ui/views/frame/hosted_app_origin_text.h" #include "chrome/browser/ui/views/location_bar/content_setting_image_view.h" #include "chrome/browser/ui/views/page_action/omnibox_page_action_icon_container_view.h" #include "chrome/browser/ui/views/toolbar/browser_actions_container.h" +#include "chrome/browser/ui/views/web_apps/web_app_menu_button.h" +#include "chrome/browser/ui/views/web_apps/web_app_origin_text.h" #include "chrome/browser/ui/web_applications/app_browser_controller.h" #include "components/content_settings/core/browser/cookie_settings.h" #include "components/content_settings/core/common/features.h" @@ -51,7 +51,7 @@ constexpr base::TimeDelta kContentSettingsFadeInDuration = base::TimeDelta::FromMilliseconds(500); -class HostedAppToolbarActionsBar : public ToolbarActionsBar { +class WebAppToolbarActionsBar : public ToolbarActionsBar { public: using ToolbarActionsBar::ToolbarActionsBar; @@ -73,7 +73,7 @@ } private: - DISALLOW_COPY_AND_ASSIGN(HostedAppToolbarActionsBar); + DISALLOW_COPY_AND_ASSIGN(WebAppToolbarActionsBar); }; int HorizontalPaddingBetweenItems() { @@ -83,23 +83,22 @@ } // namespace -const char HostedAppButtonContainer::kViewClassName[] = - "HostedAppButtonContainer"; +const char WebAppFrameToolbarView::kViewClassName[] = "WebAppFrameToolbarView"; -constexpr base::TimeDelta HostedAppButtonContainer::kTitlebarAnimationDelay; -constexpr base::TimeDelta HostedAppButtonContainer::kOriginFadeInDuration; -constexpr base::TimeDelta HostedAppButtonContainer::kOriginPauseDuration; -constexpr base::TimeDelta HostedAppButtonContainer::kOriginFadeOutDuration; +constexpr base::TimeDelta WebAppFrameToolbarView::kTitlebarAnimationDelay; +constexpr base::TimeDelta WebAppFrameToolbarView::kOriginFadeInDuration; +constexpr base::TimeDelta WebAppFrameToolbarView::kOriginPauseDuration; +constexpr base::TimeDelta WebAppFrameToolbarView::kOriginFadeOutDuration; // static -base::TimeDelta HostedAppButtonContainer::OriginTotalDuration() { +base::TimeDelta WebAppFrameToolbarView::OriginTotalDuration() { // TimeDelta.operator+ uses time_internal::SaturatedAdd() which isn't // constexpr, so this needs to be a function to not introduce a static // initializer. return kOriginFadeInDuration + kOriginPauseDuration + kOriginFadeOutDuration; } -class HostedAppButtonContainer::ContentSettingsContainer : public views::View { +class WebAppFrameToolbarView::ContentSettingsContainer : public views::View { public: explicit ContentSettingsContainer( ContentSettingImageView::Delegate* delegate); @@ -156,7 +155,7 @@ DISALLOW_COPY_AND_ASSIGN(ContentSettingsContainer); }; -HostedAppButtonContainer::ContentSettingsContainer::ContentSettingsContainer( +WebAppFrameToolbarView::ContentSettingsContainer::ContentSettingsContainer( ContentSettingImageView::Delegate* delegate) { views::BoxLayout& layout = *SetLayoutManager(std::make_unique<views::BoxLayout>( @@ -183,12 +182,11 @@ } } -HostedAppButtonContainer::HostedAppButtonContainer( - views::Widget* widget, - BrowserView* browser_view, - SkColor active_color, - SkColor inactive_color, - base::Optional<int> right_margin) +WebAppFrameToolbarView::WebAppFrameToolbarView(views::Widget* widget, + BrowserView* browser_view, + SkColor active_color, + SkColor inactive_color, + base::Optional<int> right_margin) : browser_view_(browser_view), active_color_(active_color), inactive_color_(inactive_color) { @@ -196,7 +194,7 @@ DCHECK(web_app::AppBrowserController::IsForWebAppBrowser( browser_view_->browser())); - SetID(VIEW_ID_HOSTED_APP_BUTTON_CONTAINER); + SetID(VIEW_ID_WEB_APP_FRAME_TOOLBAR); views::BoxLayout& layout = *SetLayoutManager(std::make_unique<views::BoxLayout>( @@ -211,8 +209,8 @@ auto* app_controller = browser_view_->browser()->app_controller(); if (app_controller->HasTitlebarAppOriginText()) { - hosted_app_origin_text_ = AddChildView( - std::make_unique<HostedAppOriginText>(browser_view->browser())); + web_app_origin_text_ = AddChildView( + std::make_unique<WebAppOriginText>(browser_view->browser())); } if (app_controller->HasTitlebarContentSettings()) { @@ -231,7 +229,7 @@ params.types_enabled.push_back(PageActionIconType::kNativeFileSystemAccess); if (base::FeatureList::IsEnabled(content_settings::kImprovedCookieControls)) params.types_enabled.push_back(PageActionIconType::kCookieControls); - params.icon_size = GetLayoutConstant(HOSTED_APP_PAGE_ACTION_ICON_SIZE); + params.icon_size = GetLayoutConstant(WEB_APP_PAGE_ACTION_ICON_SIZE); params.icon_color = GetCaptionColor(); params.between_icon_spacing = HorizontalPaddingBetweenItems(); params.browser = browser_view_->browser(); @@ -258,15 +256,15 @@ // TODO(crbug.com/998900): Create AppControllerUi class to contain this logic. #if defined(OS_CHROMEOS) if (app_controller->UseTitlebarTerminalSystemAppMenu()) { - app_menu_button_ = AddChildView( + web_app_menu_button_ = AddChildView( std::make_unique<TerminalSystemAppMenuButton>(browser_view)); } else { - app_menu_button_ = - AddChildView(std::make_unique<HostedAppMenuButton>(browser_view)); + web_app_menu_button_ = + AddChildView(std::make_unique<WebAppMenuButton>(browser_view)); } #else - app_menu_button_ = - AddChildView(std::make_unique<HostedAppMenuButton>(browser_view)); + web_app_menu_button_ = + AddChildView(std::make_unique<WebAppMenuButton>(browser_view)); #endif UpdateChildrenColor(); @@ -283,20 +281,20 @@ scoped_widget_observer_.Add(widget); } -HostedAppButtonContainer::~HostedAppButtonContainer() { +WebAppFrameToolbarView::~WebAppFrameToolbarView() { ImmersiveModeController* immersive_controller = browser_view_->immersive_mode_controller(); if (immersive_controller) immersive_controller->RemoveObserver(this); } -void HostedAppButtonContainer::UpdateStatusIconsVisibility() { +void WebAppFrameToolbarView::UpdateStatusIconsVisibility() { if (content_settings_container_) content_settings_container_->UpdateContentSettingViewsVisibility(); omnibox_page_action_icon_container_view_->UpdateAll(); } -void HostedAppButtonContainer::UpdateCaptionColors() { +void WebAppFrameToolbarView::UpdateCaptionColors() { const BrowserNonClientFrameView* frame_view = browser_view_->frame()->GetFrameView(); active_color_ = frame_view->GetCaptionColor( @@ -306,17 +304,17 @@ UpdateChildrenColor(); } -void HostedAppButtonContainer::SetPaintAsActive(bool active) { +void WebAppFrameToolbarView::SetPaintAsActive(bool active) { if (paint_as_active_ == active) return; paint_as_active_ = active; UpdateChildrenColor(); } -int HostedAppButtonContainer::LayoutInContainer(int leading_x, - int trailing_x, - int y, - int available_height) { +int WebAppFrameToolbarView::LayoutInContainer(int leading_x, + int trailing_x, + int y, + int available_height) { if (available_height == 0) { SetSize(gfx::Size()); return trailing_x; @@ -333,105 +331,102 @@ return bounds().x(); } -const char* HostedAppButtonContainer::GetClassName() const { +const char* WebAppFrameToolbarView::GetClassName() const { return kViewClassName; } -views::LabelButton* HostedAppButtonContainer::GetOverflowReferenceView() { - return app_menu_button_; +views::LabelButton* WebAppFrameToolbarView::GetOverflowReferenceView() { + return web_app_menu_button_; } -base::Optional<int> HostedAppButtonContainer::GetMaxBrowserActionsWidth() - const { +base::Optional<int> WebAppFrameToolbarView::GetMaxBrowserActionsWidth() const { // Our maximum size is 1 icon so don't specify a pixel-width max here. return base::Optional<int>(); } -bool HostedAppButtonContainer::CanShowIconInToolbar() const { +bool WebAppFrameToolbarView::CanShowIconInToolbar() const { return false; } std::unique_ptr<ToolbarActionsBar> -HostedAppButtonContainer::CreateToolbarActionsBar( +WebAppFrameToolbarView::CreateToolbarActionsBar( ToolbarActionsBarDelegate* delegate, Browser* browser, ToolbarActionsBar* main_bar) const { DCHECK_EQ(browser_view_->browser(), browser); - return std::make_unique<HostedAppToolbarActionsBar>(delegate, browser, - main_bar); + return std::make_unique<WebAppToolbarActionsBar>(delegate, browser, main_bar); } -SkColor HostedAppButtonContainer::GetContentSettingInkDropColor() const { +SkColor WebAppFrameToolbarView::GetContentSettingInkDropColor() const { return GetCaptionColor(); } -content::WebContents* HostedAppButtonContainer::GetContentSettingWebContents() { +content::WebContents* WebAppFrameToolbarView::GetContentSettingWebContents() { return browser_view_->GetActiveWebContents(); } ContentSettingBubbleModelDelegate* -HostedAppButtonContainer::GetContentSettingBubbleModelDelegate() { +WebAppFrameToolbarView::GetContentSettingBubbleModelDelegate() { return browser_view_->browser()->content_setting_bubble_model_delegate(); } -void HostedAppButtonContainer::OnContentSettingImageBubbleShown( +void WebAppFrameToolbarView::OnContentSettingImageBubbleShown( ContentSettingImageModel::ImageType type) const { UMA_HISTOGRAM_ENUMERATION( "HostedAppFrame.ContentSettings.ImagePressed", type, ContentSettingImageModel::ImageType::NUM_IMAGE_TYPES); } -void HostedAppButtonContainer::OnImmersiveRevealStarted() { +void WebAppFrameToolbarView::OnImmersiveRevealStarted() { // Don't wait for the fade in animation to make content setting icons visible // once in immersive mode. if (content_settings_container_) content_settings_container_->EnsureVisible(); } -SkColor HostedAppButtonContainer::GetPageActionInkDropColor() const { +SkColor WebAppFrameToolbarView::GetPageActionInkDropColor() const { return GetCaptionColor(); } content::WebContents* -HostedAppButtonContainer::GetWebContentsForPageActionIconView() { +WebAppFrameToolbarView::GetWebContentsForPageActionIconView() { return browser_view_->GetActiveWebContents(); } -BrowserActionsContainer* -HostedAppButtonContainer::GetBrowserActionsContainer() { +BrowserActionsContainer* WebAppFrameToolbarView::GetBrowserActionsContainer() { CHECK(!base::FeatureList::IsEnabled(features::kExtensionsToolbarMenu)); return browser_actions_container_; } -ToolbarActionView* HostedAppButtonContainer::GetToolbarActionViewForId( +ToolbarActionView* WebAppFrameToolbarView::GetToolbarActionViewForId( const std::string& id) { // TODO(pbos): Implement this for kExtensionsToolbarMenu. CHECK(!base::FeatureList::IsEnabled(features::kExtensionsToolbarMenu)); return browser_actions_container_->GetViewForId(id); } -views::View* HostedAppButtonContainer::GetDefaultExtensionDialogAnchorView() { +views::View* WebAppFrameToolbarView::GetDefaultExtensionDialogAnchorView() { // TODO(pbos): Implement this for kExtensionsToolbarMenu. CHECK(!base::FeatureList::IsEnabled(features::kExtensionsToolbarMenu)); return GetAppMenuButton(); } OmniboxPageActionIconContainerView* -HostedAppButtonContainer::GetOmniboxPageActionIconContainerView() { +WebAppFrameToolbarView::GetOmniboxPageActionIconContainerView() { return omnibox_page_action_icon_container_view_; } -AppMenuButton* HostedAppButtonContainer::GetAppMenuButton() { - return app_menu_button_; +AppMenuButton* WebAppFrameToolbarView::GetAppMenuButton() { + return web_app_menu_button_; } -gfx::Rect HostedAppButtonContainer::GetFindBarBoundingBox( +gfx::Rect WebAppFrameToolbarView::GetFindBarBoundingBox( int contents_height) const { if (!IsDrawn()) return gfx::Rect(); - gfx::Rect anchor_bounds = - app_menu_button_->ConvertRectToWidget(app_menu_button_->GetLocalBounds()); + gfx::Rect anchor_bounds = web_app_menu_button_->ConvertRectToWidget( + web_app_menu_button_->GetLocalBounds()); if (base::i18n::IsRTL()) { // Find bar will be left aligned so align to left edge of app menu button. int widget_width = GetWidget()->GetRootView()->width(); @@ -443,20 +438,20 @@ anchor_bounds.x() + anchor_bounds.width(), contents_height); } -void HostedAppButtonContainer::FocusToolbar() { +void WebAppFrameToolbarView::FocusToolbar() { SetPaneFocus(nullptr); } -views::AccessiblePaneView* HostedAppButtonContainer::GetAsAccessiblePaneView() { +views::AccessiblePaneView* WebAppFrameToolbarView::GetAsAccessiblePaneView() { return this; } -views::View* HostedAppButtonContainer::GetAnchorView() { - return app_menu_button_; +views::View* WebAppFrameToolbarView::GetAnchorView() { + return web_app_menu_button_; } -void HostedAppButtonContainer::OnWidgetVisibilityChanged(views::Widget* widget, - bool visibility) { +void WebAppFrameToolbarView::OnWidgetVisibilityChanged(views::Widget* widget, + bool visibility) { if (!visibility || !pending_widget_visibility_) return; pending_widget_visibility_ = false; @@ -465,74 +460,73 @@ content_settings_container_->SetUpForFadeIn(); animation_start_delay_.Start( FROM_HERE, kTitlebarAnimationDelay, this, - &HostedAppButtonContainer::StartTitlebarAnimation); + &WebAppFrameToolbarView::StartTitlebarAnimation); } } -gfx::Size HostedAppButtonContainer::CalculatePreferredSize() const { +gfx::Size WebAppFrameToolbarView::CalculatePreferredSize() const { // Prefer height consistency over accommodating edge case icons that may bump // up the container height (e.g. extension action icons with badges). // TODO(https://crbug.com/889745): Fix the inconsistent icon sizes found in // this container and turn this into a DCHECK that the conatiner height is the // same as the app menu button height. return gfx::Size(views::View::CalculatePreferredSize().width(), - app_menu_button_->GetPreferredSize().height()); + web_app_menu_button_->GetPreferredSize().height()); } -void HostedAppButtonContainer::ChildPreferredSizeChanged(views::View* child) { +void WebAppFrameToolbarView::ChildPreferredSizeChanged(views::View* child) { PreferredSizeChanged(); } -void HostedAppButtonContainer::ChildVisibilityChanged(views::View* child) { +void WebAppFrameToolbarView::ChildVisibilityChanged(views::View* child) { // Changes to layout need to be taken into account by the frame view. PreferredSizeChanged(); } -bool HostedAppButtonContainer::ShouldAnimate() const { +bool WebAppFrameToolbarView::ShouldAnimate() const { return !g_animation_disabled_for_testing && !browser_view_->immersive_mode_controller()->IsEnabled(); } -void HostedAppButtonContainer::StartTitlebarAnimation() { +void WebAppFrameToolbarView::StartTitlebarAnimation() { if (!ShouldAnimate()) return; - if (hosted_app_origin_text_) - hosted_app_origin_text_->StartFadeAnimation(); - app_menu_button_->StartHighlightAnimation(); - icon_fade_in_delay_.Start( - FROM_HERE, OriginTotalDuration(), this, - &HostedAppButtonContainer::FadeInContentSettingIcons); + if (web_app_origin_text_) + web_app_origin_text_->StartFadeAnimation(); + web_app_menu_button_->StartHighlightAnimation(); + icon_fade_in_delay_.Start(FROM_HERE, OriginTotalDuration(), this, + &WebAppFrameToolbarView::FadeInContentSettingIcons); } -void HostedAppButtonContainer::FadeInContentSettingIcons() { +void WebAppFrameToolbarView::FadeInContentSettingIcons() { if (content_settings_container_) content_settings_container_->FadeIn(); } -void HostedAppButtonContainer::DisableAnimationForTesting() { +void WebAppFrameToolbarView::DisableAnimationForTesting() { g_animation_disabled_for_testing = true; } -views::View* HostedAppButtonContainer::GetContentSettingContainerForTesting() { +views::View* WebAppFrameToolbarView::GetContentSettingContainerForTesting() { return content_settings_container_; } const std::vector<ContentSettingImageView*>& -HostedAppButtonContainer::GetContentSettingViewsForTesting() const { +WebAppFrameToolbarView::GetContentSettingViewsForTesting() const { return content_settings_container_->GetContentSettingViewsForTesting(); } -SkColor HostedAppButtonContainer::GetCaptionColor() const { +SkColor WebAppFrameToolbarView::GetCaptionColor() const { return paint_as_active_ ? active_color_ : inactive_color_; } -void HostedAppButtonContainer::UpdateChildrenColor() { +void WebAppFrameToolbarView::UpdateChildrenColor() { SkColor icon_color = GetCaptionColor(); - if (hosted_app_origin_text_) - hosted_app_origin_text_->SetTextColor(icon_color); + if (web_app_origin_text_) + web_app_origin_text_->SetTextColor(icon_color); if (content_settings_container_) content_settings_container_->SetIconColor(icon_color); omnibox_page_action_icon_container_view_->SetIconColor(icon_color); - app_menu_button_->SetColor(icon_color); + web_app_menu_button_->SetColor(icon_color); }
diff --git a/chrome/browser/ui/views/frame/hosted_app_button_container.h b/chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.h similarity index 78% rename from chrome/browser/ui/views/frame/hosted_app_button_container.h rename to chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.h index 7e209be..dacf528 100644 --- a/chrome/browser/ui/views/frame/hosted_app_button_container.h +++ b/chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_VIEWS_FRAME_HOSTED_APP_BUTTON_CONTAINER_H_ -#define CHROME_BROWSER_UI_VIEWS_FRAME_HOSTED_APP_BUTTON_CONTAINER_H_ +#ifndef CHROME_BROWSER_UI_VIEWS_WEB_APPS_WEB_APP_FRAME_TOOLBAR_VIEW_H_ +#define CHROME_BROWSER_UI_VIEWS_WEB_APPS_WEB_APP_FRAME_TOOLBAR_VIEW_H_ #include <memory> @@ -24,24 +24,20 @@ #include "ui/views/widget/widget.h" #include "ui/views/widget/widget_observer.h" -namespace { -class HostedAppNonClientFrameViewAshTest; -} - class AppMenuButton; class BrowserView; class ExtensionsToolbarContainer; -class HostedAppOriginText; -class HostedAppMenuButton; +class WebAppOriginText; +class WebAppMenuButton; -// A container for hosted app buttons in the title bar. -class HostedAppButtonContainer : public views::AccessiblePaneView, - public BrowserActionsContainer::Delegate, - public ContentSettingImageView::Delegate, - public ImmersiveModeController::Observer, - public PageActionIconView::Delegate, - public ToolbarButtonProvider, - public views::WidgetObserver { +// A container for web app buttons in the title bar. +class WebAppFrameToolbarView : public views::AccessiblePaneView, + public BrowserActionsContainer::Delegate, + public ContentSettingImageView::Delegate, + public ImmersiveModeController::Observer, + public PageActionIconView::Delegate, + public ToolbarButtonProvider, + public views::WidgetObserver { public: static const char kViewClassName[]; @@ -60,12 +56,12 @@ // |active_color| and |inactive_color| indicate the colors to use // for button icons when the window is focused and blurred respectively. - HostedAppButtonContainer(views::Widget* widget, - BrowserView* browser_view, - SkColor active_color, - SkColor inactive_color, - base::Optional<int> right_margin = base::nullopt); - ~HostedAppButtonContainer() override; + WebAppFrameToolbarView(views::Widget* widget, + BrowserView* browser_view, + SkColor active_color, + SkColor inactive_color, + base::Optional<int> right_margin = base::nullopt); + ~WebAppFrameToolbarView() override; void UpdateStatusIconsVisibility(); @@ -132,10 +128,10 @@ void ChildVisibilityChanged(views::View* child) override; private: - friend class HostedAppNonClientFrameViewAshTest; - friend class HostedAppGlassBrowserFrameViewTest; - friend class ImmersiveModeControllerAshHostedAppBrowserTest; - friend class HostedAppAshInteractiveUITest; + friend class WebAppNonClientFrameViewAshTest; + friend class WebAppGlassBrowserFrameViewTest; + friend class ImmersiveModeControllerAshWebAppBrowserTest; + friend class WebAppAshInteractiveUITest; // Duration to wait before starting the opening animation. static constexpr base::TimeDelta kTitlebarAnimationDelay = @@ -177,15 +173,15 @@ SkColor inactive_color_; // Owned by the views hierarchy. - HostedAppOriginText* hosted_app_origin_text_ = nullptr; + WebAppOriginText* web_app_origin_text_ = nullptr; ContentSettingsContainer* content_settings_container_ = nullptr; OmniboxPageActionIconContainerView* omnibox_page_action_icon_container_view_ = nullptr; BrowserActionsContainer* browser_actions_container_ = nullptr; ExtensionsToolbarContainer* extensions_container_ = nullptr; - HostedAppMenuButton* app_menu_button_ = nullptr; + WebAppMenuButton* web_app_menu_button_ = nullptr; - DISALLOW_COPY_AND_ASSIGN(HostedAppButtonContainer); + DISALLOW_COPY_AND_ASSIGN(WebAppFrameToolbarView); }; -#endif // CHROME_BROWSER_UI_VIEWS_FRAME_HOSTED_APP_BUTTON_CONTAINER_H_ +#endif // CHROME_BROWSER_UI_VIEWS_WEB_APPS_WEB_APP_FRAME_TOOLBAR_VIEW_H_
diff --git a/chrome/browser/ui/views/frame/hosted_app_menu_button.cc b/chrome/browser/ui/views/web_apps/web_app_menu_button.cc similarity index 69% rename from chrome/browser/ui/views/frame/hosted_app_menu_button.cc rename to chrome/browser/ui/views/web_apps/web_app_menu_button.cc index b0d72bdc..be41dab 100644 --- a/chrome/browser/ui/views/frame/hosted_app_menu_button.cc +++ b/chrome/browser/ui/views/web_apps/web_app_menu_button.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/views/frame/hosted_app_menu_button.h" +#include "chrome/browser/ui/views/web_apps/web_app_menu_button.h" #include "base/metrics/user_metrics.h" #include "base/strings/utf_string_conversions.h" @@ -10,9 +10,9 @@ #include "chrome/app/vector_icons/vector_icons.h" #include "chrome/browser/ui/layout_constants.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/frame/hosted_app_button_container.h" #include "chrome/browser/ui/views/toolbar/app_menu.h" #include "chrome/browser/ui/views/toolbar/toolbar_ink_drop_util.h" +#include "chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.h" #include "chrome/browser/ui/web_applications/app_browser_controller.h" #include "chrome/browser/ui/web_applications/web_app_menu_model.h" #include "chrome/grit/generated_resources.h" @@ -26,7 +26,7 @@ #include "ui/views/view_class_properties.h" #include "ui/views/window/hit_test_utils.h" -HostedAppMenuButton::HostedAppMenuButton(BrowserView* browser_view) +WebAppMenuButton::WebAppMenuButton(BrowserView* browser_view) : AppMenuButton(this), browser_view_(browser_view) { views::SetHitTestComponent(this, static_cast<int>(HTMENU)); @@ -42,12 +42,12 @@ browser_view->browser()->app_controller()->GetAppShortName()); SetAccessibleName(app_name); SetTooltipText( - l10n_util::GetStringFUTF16(IDS_HOSTED_APPMENU_TOOLTIP, app_name)); + l10n_util::GetStringFUTF16(IDS_WEB_APP_MENU_BUTTON_TOOLTIP, app_name)); constexpr int focus_mode_app_menu_button_size = 34; bool is_focus_mode = browser_view->browser()->is_focus_mode(); int size = is_focus_mode ? focus_mode_app_menu_button_size - : GetLayoutConstant(HOSTED_APP_MENU_BUTTON_SIZE); + : GetLayoutConstant(WEB_APP_MENU_BUTTON_SIZE); SetMinSize(gfx::Size(size, size)); SetHorizontalAlignment(gfx::ALIGN_CENTER); if (!is_focus_mode) { @@ -56,29 +56,29 @@ } } -HostedAppMenuButton::~HostedAppMenuButton() {} +WebAppMenuButton::~WebAppMenuButton() {} -void HostedAppMenuButton::SetColor(SkColor color) { +void WebAppMenuButton::SetColor(SkColor color) { SetImage(views::Button::STATE_NORMAL, gfx::CreateVectorIcon(kBrowserToolsIcon, color)); ink_drop_color_ = color; } -void HostedAppMenuButton::StartHighlightAnimation() { +void WebAppMenuButton::StartHighlightAnimation() { GetInkDrop()->SetHoverHighlightFadeDuration( - HostedAppButtonContainer::kOriginFadeInDuration); + WebAppFrameToolbarView::kOriginFadeInDuration); GetInkDrop()->SetHovered(true); GetInkDrop()->UseDefaultHoverHighlightFadeDuration(); highlight_off_timer_.Start(FROM_HERE, - HostedAppButtonContainer::kOriginFadeInDuration + - HostedAppButtonContainer::kOriginPauseDuration, - this, &HostedAppMenuButton::FadeHighlightOff); + WebAppFrameToolbarView::kOriginFadeInDuration + + WebAppFrameToolbarView::kOriginPauseDuration, + this, &WebAppMenuButton::FadeHighlightOff); } -void HostedAppMenuButton::OnMenuButtonClicked(views::Button* source, - const gfx::Point& point, - const ui::Event* event) { +void WebAppMenuButton::OnMenuButtonClicked(views::Button* source, + const gfx::Point& point, + const ui::Event* event) { Browser* browser = browser_view_->browser(); RunMenu(std::make_unique<WebAppMenuModel>(browser_view_, browser), browser, event && event->IsKeyEvent() @@ -86,24 +86,24 @@ : views::MenuRunner::NO_FLAGS, false); - // Add UMA for how many times the hosted app menu button are clicked. + // Add UMA for how many times the web app menu button are clicked. base::RecordAction( base::UserMetricsAction("HostedAppMenuButtonButton_Clicked")); } -SkColor HostedAppMenuButton::GetInkDropBaseColor() const { +SkColor WebAppMenuButton::GetInkDropBaseColor() const { return ink_drop_color_; } -void HostedAppMenuButton::FadeHighlightOff() { +void WebAppMenuButton::FadeHighlightOff() { if (!ShouldEnterHoveredState()) { GetInkDrop()->SetHoverHighlightFadeDuration( - HostedAppButtonContainer::kOriginFadeOutDuration); + WebAppFrameToolbarView::kOriginFadeOutDuration); GetInkDrop()->SetHovered(false); GetInkDrop()->UseDefaultHoverHighlightFadeDuration(); } } -const char* HostedAppMenuButton::GetClassName() const { - return "HostedAppMenuButton"; +const char* WebAppMenuButton::GetClassName() const { + return "WebAppMenuButton"; }
diff --git a/chrome/browser/ui/views/frame/hosted_app_menu_button.h b/chrome/browser/ui/views/web_apps/web_app_menu_button.h similarity index 70% rename from chrome/browser/ui/views/frame/hosted_app_menu_button.h rename to chrome/browser/ui/views/web_apps/web_app_menu_button.h index cbfd912..3a3b743 100644 --- a/chrome/browser/ui/views/frame/hosted_app_menu_button.h +++ b/chrome/browser/ui/views/web_apps/web_app_menu_button.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_VIEWS_FRAME_HOSTED_APP_MENU_BUTTON_H_ -#define CHROME_BROWSER_UI_VIEWS_FRAME_HOSTED_APP_MENU_BUTTON_H_ +#ifndef CHROME_BROWSER_UI_VIEWS_WEB_APPS_WEB_APP_MENU_BUTTON_H_ +#define CHROME_BROWSER_UI_VIEWS_WEB_APPS_WEB_APP_MENU_BUTTON_H_ #include "base/timer/timer.h" #include "chrome/browser/ui/views/frame/app_menu_button.h" @@ -13,12 +13,12 @@ class BrowserView; -// The 'app menu' button for the hosted app. -class HostedAppMenuButton : public AppMenuButton, - public views::MenuButtonListener { +// The 'app menu' button for a web app window. +class WebAppMenuButton : public AppMenuButton, + public views::MenuButtonListener { public: - explicit HostedAppMenuButton(BrowserView* browser_view); - ~HostedAppMenuButton() override; + explicit WebAppMenuButton(BrowserView* browser_view); + ~WebAppMenuButton() override; // Sets the color of the menu button icon and highlight. void SetColor(SkColor color); @@ -50,7 +50,7 @@ base::OneShotTimer highlight_off_timer_; - DISALLOW_COPY_AND_ASSIGN(HostedAppMenuButton); + DISALLOW_COPY_AND_ASSIGN(WebAppMenuButton); }; -#endif // CHROME_BROWSER_UI_VIEWS_FRAME_HOSTED_APP_MENU_BUTTON_H_ +#endif // CHROME_BROWSER_UI_VIEWS_WEB_APPS_WEB_APP_MENU_BUTTON_H_
diff --git a/chrome/browser/ui/views/frame/hosted_app_origin_text.cc b/chrome/browser/ui/views/web_apps/web_app_origin_text.cc similarity index 78% rename from chrome/browser/ui/views/frame/hosted_app_origin_text.cc rename to chrome/browser/ui/views/web_apps/web_app_origin_text.cc index cb41ba1e..c9aa1fc 100644 --- a/chrome/browser/ui/views/frame/hosted_app_origin_text.cc +++ b/chrome/browser/ui/views/web_apps/web_app_origin_text.cc
@@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/views/frame/hosted_app_origin_text.h" +#include "chrome/browser/ui/views/web_apps/web_app_origin_text.h" #include "base/bind.h" #include "base/i18n/rtl.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/views/chrome_typography.h" -#include "chrome/browser/ui/views/frame/hosted_app_button_container.h" +#include "chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.h" #include "chrome/browser/ui/web_applications/app_browser_controller.h" #include "ui/accessibility/ax_enums.mojom.h" #include "ui/accessibility/ax_node_data.h" @@ -24,7 +24,7 @@ } // namespace -HostedAppOriginText::HostedAppOriginText(Browser* browser) { +WebAppOriginText::WebAppOriginText(Browser* browser) { DCHECK(web_app::AppBrowserController::IsForWebAppBrowser(browser)); SetLayoutManager(std::make_unique<views::FillLayout>()); @@ -50,13 +50,13 @@ layer()->SetMasksToBounds(true); } -HostedAppOriginText::~HostedAppOriginText() = default; +WebAppOriginText::~WebAppOriginText() = default; -void HostedAppOriginText::SetTextColor(SkColor color) { +void WebAppOriginText::SetTextColor(SkColor color) { label_->SetEnabledColor(color); } -void HostedAppOriginText::StartFadeAnimation() { +void WebAppOriginText::StartFadeAnimation() { ui::Layer* label_layer = label_->layer(); // Current state will become the first animation keyframe. @@ -66,17 +66,17 @@ // Fade in. auto opacity_keyframe = ui::LayerAnimationElement::CreateOpacityElement( - 1, HostedAppButtonContainer::kOriginFadeInDuration); + 1, WebAppFrameToolbarView::kOriginFadeInDuration); opacity_keyframe->set_tween_type(kTweenType); opacity_sequence->AddElement(std::move(opacity_keyframe)); // Pause. opacity_sequence->AddElement(ui::LayerAnimationElement::CreatePauseElement( - 0, HostedAppButtonContainer::kOriginPauseDuration)); + 0, WebAppFrameToolbarView::kOriginPauseDuration)); // Fade out. opacity_keyframe = ui::LayerAnimationElement::CreateOpacityElement( - 0, HostedAppButtonContainer::kOriginFadeOutDuration); + 0, WebAppFrameToolbarView::kOriginFadeOutDuration); opacity_keyframe->set_tween_type(kTweenType); opacity_sequence->AddElement(std::move(opacity_keyframe)); @@ -84,18 +84,18 @@ base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, - base::BindOnce(&HostedAppOriginText::AnimationComplete, + base::BindOnce(&WebAppOriginText::AnimationComplete, weak_factory_.GetWeakPtr()), - HostedAppButtonContainer::OriginTotalDuration()); + WebAppFrameToolbarView::OriginTotalDuration()); NotifyAccessibilityEvent(ax::mojom::Event::kValueChanged, true); } -void HostedAppOriginText::AnimationComplete() { +void WebAppOriginText::AnimationComplete() { SetVisible(false); } -void HostedAppOriginText::GetAccessibleNodeData(ui::AXNodeData* node_data) { +void WebAppOriginText::GetAccessibleNodeData(ui::AXNodeData* node_data) { node_data->role = ax::mojom::Role::kApplication; node_data->SetName(label_->GetText()); }
diff --git a/chrome/browser/ui/views/frame/hosted_app_origin_text.h b/chrome/browser/ui/views/web_apps/web_app_origin_text.h similarity index 63% rename from chrome/browser/ui/views/frame/hosted_app_origin_text.h rename to chrome/browser/ui/views/web_apps/web_app_origin_text.h index 259bfd6..86ec4d0 100644 --- a/chrome/browser/ui/views/frame/hosted_app_origin_text.h +++ b/chrome/browser/ui/views/web_apps/web_app_origin_text.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_VIEWS_FRAME_HOSTED_APP_ORIGIN_TEXT_H_ -#define CHROME_BROWSER_UI_VIEWS_FRAME_HOSTED_APP_ORIGIN_TEXT_H_ +#ifndef CHROME_BROWSER_UI_VIEWS_WEB_APPS_WEB_APP_ORIGIN_TEXT_H_ +#define CHROME_BROWSER_UI_VIEWS_WEB_APPS_WEB_APP_ORIGIN_TEXT_H_ #include "base/memory/weak_ptr.h" #include "base/strings/string16.h" @@ -18,10 +18,10 @@ } // A URL's origin text with a fade in/out animation. -class HostedAppOriginText : public views::View { +class WebAppOriginText : public views::View { public: - explicit HostedAppOriginText(Browser* browser); - ~HostedAppOriginText() override; + explicit WebAppOriginText(Browser* browser); + ~WebAppOriginText() override; void SetTextColor(SkColor color); @@ -37,9 +37,9 @@ void AnimationComplete(); - base::WeakPtrFactory<HostedAppOriginText> weak_factory_{this}; + base::WeakPtrFactory<WebAppOriginText> weak_factory_{this}; - DISALLOW_COPY_AND_ASSIGN(HostedAppOriginText); + DISALLOW_COPY_AND_ASSIGN(WebAppOriginText); }; -#endif // CHROME_BROWSER_UI_VIEWS_FRAME_HOSTED_APP_ORIGIN_TEXT_H_ +#endif // CHROME_BROWSER_UI_VIEWS_WEB_APPS_WEB_APP_ORIGIN_TEXT_H_
diff --git a/chrome/browser/ui/web_applications/web_app_menu_model.cc b/chrome/browser/ui/web_applications/web_app_menu_model.cc index 1ce99df..f91c919 100644 --- a/chrome/browser/ui/web_applications/web_app_menu_model.cc +++ b/chrome/browser/ui/web_applications/web_app_menu_model.cc
@@ -28,7 +28,7 @@ void WebAppMenuModel::Build() { if (CreateActionToolbarOverflowMenu()) AddSeparator(ui::UPPER_SEPARATOR); - AddItemWithStringId(IDC_HOSTED_APP_MENU_APP_INFO, + AddItemWithStringId(IDC_WEB_APP_MENU_APP_INFO, IDS_APP_CONTEXT_MENU_SHOW_INFO); int app_info_index = GetItemCount() - 1; SetMinorText(app_info_index, web_app::AppBrowserController::FormatUrlOrigin(
diff --git a/chrome/browser/ui/webui/chromeos/terminal/terminal_source.cc b/chrome/browser/ui/webui/chromeos/terminal/terminal_source.cc index 2609acb..682bbc9 100644 --- a/chrome/browser/ui/webui/chromeos/terminal/terminal_source.cc +++ b/chrome/browser/ui/webui/chromeos/terminal/terminal_source.cc
@@ -38,6 +38,12 @@ return chrome::kChromeUITerminalHost; } +#if !BUILDFLAG(OPTIMIZE_WEBUI) +bool TerminalSource::AllowCaching() { + return false; +} +#endif + void TerminalSource::StartDataRequest( const std::string& path, const content::WebContents::Getter& wc_getter,
diff --git a/chrome/browser/ui/webui/chromeos/terminal/terminal_source.h b/chrome/browser/ui/webui/chromeos/terminal/terminal_source.h index b5acfde..78792491 100644 --- a/chrome/browser/ui/webui/chromeos/terminal/terminal_source.h +++ b/chrome/browser/ui/webui/chromeos/terminal/terminal_source.h
@@ -8,6 +8,8 @@ #include <string> #include "base/macros.h" +#include "build/buildflag.h" +#include "chrome/common/buildflags.h" #include "content/public/browser/url_data_source.h" #include "content/public/browser/web_contents.h" @@ -18,6 +20,9 @@ private: std::string GetSource() override; +#if !BUILDFLAG(OPTIMIZE_WEBUI) + bool AllowCaching() override; +#endif void StartDataRequest( const std::string& path,
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc index aa26f35..0c7b2eb 100644 --- a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc +++ b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
@@ -575,6 +575,7 @@ PrintPreviewUI* print_preview_ui = static_cast<PrintPreviewUI*>( print_preview_dialog->GetWebUI()->GetController()); print_preview_ui->source_is_modifiable_ = params.is_modifiable; + print_preview_ui->source_is_pdf_ = params.is_pdf; print_preview_ui->source_has_selection_ = params.has_selection; print_preview_ui->print_selection_only_ = params.selection_only; }
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui.h b/chrome/browser/ui/webui/print_preview/print_preview_ui.h index 2aca55e..1922e87b 100644 --- a/chrome/browser/ui/webui/print_preview/print_preview_ui.h +++ b/chrome/browser/ui/webui/print_preview/print_preview_ui.h
@@ -61,6 +61,8 @@ bool source_is_modifiable() const { return source_is_modifiable_; } + bool source_is_pdf() const { return source_is_pdf_; } + bool source_has_selection() const { return source_has_selection_; } bool print_selection_only() const { return print_selection_only_; } @@ -257,6 +259,9 @@ // Indicates whether the source document can be modified. bool source_is_modifiable_ = true; + // Indicates whether the source document is a PDF. + bool source_is_pdf_ = false; + // Indicates whether the source document has selection. bool source_has_selection_ = false;
diff --git a/chrome/browser/ui/webui/quota_internals/OWNERS b/chrome/browser/ui/webui/quota_internals/OWNERS index af94955..84d5cb66 100644 --- a/chrome/browser/ui/webui/quota_internals/OWNERS +++ b/chrome/browser/ui/webui/quota_internals/OWNERS
@@ -1,6 +1,4 @@ -tzik@chromium.org -jsbell@chromium.org -pwnall@chromium.org +file://storage/browser/quota/OWNERS # TEAM: storage-dev@chromium.org # COMPONENT: Blink>Storage>Quota
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index b1e76726..55fb9c1 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -1170,26 +1170,24 @@ content::RenderFrame* render_frame, const blink::WebURLError& web_error, const std::string& http_method, - bool ignoring_cache, std::string* error_html) { NetErrorHelper::Get(render_frame) ->PrepareErrorPage( error_page::Error::NetError(web_error.url(), web_error.reason(), web_error.has_copy_in_cache()), - http_method == "POST", ignoring_cache, error_html); + http_method == "POST", error_html); } void ChromeContentRendererClient::PrepareErrorPageForHttpStatusError( content::RenderFrame* render_frame, const GURL& unreachable_url, const std::string& http_method, - bool ignoring_cache, int http_status, std::string* error_html) { NetErrorHelper::Get(render_frame) ->PrepareErrorPage( error_page::Error::HttpError(unreachable_url, http_status), - http_method == "POST", ignoring_cache, error_html); + http_method == "POST", error_html); } void ChromeContentRendererClient::GetErrorDescription(
diff --git a/chrome/renderer/chrome_content_renderer_client.h b/chrome/renderer/chrome_content_renderer_client.h index 95ad438..7ed8cd3f 100644 --- a/chrome/renderer/chrome_content_renderer_client.h +++ b/chrome/renderer/chrome_content_renderer_client.h
@@ -115,12 +115,10 @@ void PrepareErrorPage(content::RenderFrame* render_frame, const blink::WebURLError& error, const std::string& http_method, - bool ignoring_cache, std::string* error_html) override; void PrepareErrorPageForHttpStatusError(content::RenderFrame* render_frame, const GURL& unreachable_url, const std::string& http_method, - bool ignoring_cache, int http_status, std::string* error_html) override;
diff --git a/chrome/renderer/net/net_error_helper.cc b/chrome/renderer/net/net_error_helper.cc index 97d0fbd..c868507 100644 --- a/chrome/renderer/net/net_error_helper.cc +++ b/chrome/renderer/net/net_error_helper.cc
@@ -341,10 +341,9 @@ void NetErrorHelper::PrepareErrorPage(const error_page::Error& error, bool is_failed_post, - bool is_ignoring_cache, std::string* error_html) { core_->PrepareErrorPage(GetFrameType(render_frame()), error, is_failed_post, - is_ignoring_cache, error_html); + error_html); } bool NetErrorHelper::ShouldSuppressErrorPage(const GURL& url) { @@ -545,10 +544,8 @@ network::SimpleURLLoader::kMaxBoundedStringDownloadSize); } -void NetErrorHelper::ReloadPage(bool bypass_cache) { - render_frame()->GetWebFrame()->StartReload( - bypass_cache ? blink::WebFrameLoadType::kReloadBypassingCache - : blink::WebFrameLoadType::kReload); +void NetErrorHelper::ReloadFrame() { + render_frame()->GetWebFrame()->StartReload(blink::WebFrameLoadType::kReload); } void NetErrorHelper::DiagnoseError(const GURL& page_url) {
diff --git a/chrome/renderer/net/net_error_helper.h b/chrome/renderer/net/net_error_helper.h index 5606f38..eb49632 100644 --- a/chrome/renderer/net/net_error_helper.h +++ b/chrome/renderer/net/net_error_helper.h
@@ -104,7 +104,6 @@ // loaded immediately. void PrepareErrorPage(const error_page::Error& error, bool is_failed_post, - bool is_ignoring_cache, std::string* error_html); // Returns whether a load for |url| in the |frame| the NetErrorHelper is @@ -141,7 +140,7 @@ void CancelFetchNavigationCorrections() override; void SendTrackingRequest(const GURL& tracking_url, const std::string& tracking_request_body) override; - void ReloadPage(bool bypass_cache) override; + void ReloadFrame() override; void DiagnoseError(const GURL& page_url) override; void DownloadPageLater() override; void SetIsShowingDownloadButton(bool show) override;
diff --git a/chrome/renderer/net/net_error_helper_core.cc b/chrome/renderer/net/net_error_helper_core.cc index 18696fd..572506e7 100644 --- a/chrome/renderer/net/net_error_helper_core.cc +++ b/chrome/renderer/net/net_error_helper_core.cc
@@ -396,12 +396,9 @@ } // namespace struct NetErrorHelperCore::ErrorPageInfo { - ErrorPageInfo(error_page::Error error, - bool was_failed_post, - bool was_ignoring_cache) + ErrorPageInfo(error_page::Error error, bool was_failed_post) : error(error), was_failed_post(was_failed_post), - was_ignoring_cache(was_ignoring_cache), needs_dns_updates(false), needs_load_navigation_corrections(false), is_finished_loading(false), @@ -410,7 +407,6 @@ // Information about the failed page load. error_page::Error error; bool was_failed_post; - bool was_ignoring_cache; // Information about the status of the error page. @@ -673,7 +669,6 @@ void NetErrorHelperCore::PrepareErrorPage(FrameType frame_type, const error_page::Error& error, bool is_failed_post, - bool is_ignoring_cache, std::string* error_html) { if (frame_type == MAIN_FRAME) { // If navigation corrections were needed before, that should have been @@ -681,8 +676,7 @@ DCHECK(!committed_error_page_info_ || !committed_error_page_info_->needs_load_navigation_corrections); - pending_error_page_info_.reset( - new ErrorPageInfo(error, is_failed_post, is_ignoring_cache)); + pending_error_page_info_.reset(new ErrorPageInfo(error, is_failed_post)); pending_error_page_info_->navigation_correction_params.reset( new NavigationCorrectionParams(navigation_correction_params_)); PrepareErrorPageForMainFrame(pending_error_page_info_.get(), error_html); @@ -811,8 +805,7 @@ pending_error_page_info_.reset( new ErrorPageInfo(committed_error_page_info_->error, - committed_error_page_info_->was_failed_post, - committed_error_page_info_->was_ignoring_cache)); + committed_error_page_info_->was_failed_post)); pending_error_page_info_->navigation_correction_response = ParseNavigationCorrectionResponse(corrections); @@ -860,11 +853,10 @@ error_info.error.stale_copy_in_cache()); } -void NetErrorHelperCore::Reload(bool bypass_cache) { - if (!committed_error_page_info_) { +void NetErrorHelperCore::Reload() { + if (!committed_error_page_info_) return; - } - delegate_->ReloadPage(bypass_cache); + delegate_->ReloadFrame(); } bool NetErrorHelperCore::MaybeStartAutoReloadTimer() { @@ -914,7 +906,7 @@ auto_reload_count_++; auto_reload_in_flight_ = true; - Reload(committed_error_page_info_->was_ignoring_cache); + Reload(); } void NetErrorHelperCore::PauseAutoReloadTimer() { @@ -977,7 +969,7 @@ case RELOAD_BUTTON: RecordEvent(error_page::NETWORK_ERROR_PAGE_RELOAD_BUTTON_CLICKED); navigation_from_button_ = RELOAD_BUTTON; - Reload(false); + Reload(); return; case MORE_BUTTON: // Visual effects on page are handled in Javascript code.
diff --git a/chrome/renderer/net/net_error_helper_core.h b/chrome/renderer/net/net_error_helper_core.h index 989e9c2f..bdd2f4a 100644 --- a/chrome/renderer/net/net_error_helper_core.h +++ b/chrome/renderer/net/net_error_helper_core.h
@@ -112,8 +112,8 @@ const GURL& tracking_url, const std::string& tracking_request_body) = 0; - // Starts a reload of the page in the observed frame. - virtual void ReloadPage(bool bypass_cache) = 0; + // Starts a reload of the observed frame. + virtual void ReloadFrame() = 0; // Run the platform diagnostics too for the specified URL. virtual void DiagnoseError(const GURL& page_url) = 0; @@ -169,7 +169,6 @@ void PrepareErrorPage(FrameType frame_type, const error_page::Error& error, bool is_failed_post, - bool is_ignoring_cache, std::string* error_html); // These methods handle tracking the actual state of the page. @@ -278,7 +277,7 @@ error_page::Error GetUpdatedError(const ErrorPageInfo& error_info) const; - void Reload(bool bypass_cache); + void Reload(); bool MaybeStartAutoReloadTimer(); void StartAutoReloadTimer(); void AutoReloadTimerFired();
diff --git a/chrome/renderer/net/net_error_helper_core_unittest.cc b/chrome/renderer/net/net_error_helper_core_unittest.cc index 009ad14..76c7e4dc 100644 --- a/chrome/renderer/net/net_error_helper_core_unittest.cc +++ b/chrome/renderer/net/net_error_helper_core_unittest.cc
@@ -170,7 +170,6 @@ update_count_(0), error_html_update_count_(0), reload_count_(0), - reload_bypassing_cache_count_(0), diagnose_error_count_(0), download_count_(0), list_visible_by_prefs_(true), @@ -202,10 +201,6 @@ int reload_count() const { return reload_count_; } - int reload_bypassing_cache_count() const { - return reload_bypassing_cache_count_; - } - int diagnose_error_count() const { return diagnose_error_count_; } const GURL& diagnose_error_url() const { return diagnose_error_url_; } @@ -294,9 +289,9 @@ core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME, NetErrorHelperCore::NON_ERROR_PAGE); std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetErrorForURL(error, url), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetErrorForURL(error, url), + false /* is_failed_post */, &html); EXPECT_FALSE(html.empty()); EXPECT_EQ(NetErrorStringForURL(error, url), html); @@ -310,23 +305,6 @@ DoErrorLoadOfURL(error, GURL(kFailedUrl)); } - void DoErrorReoadBypassingCache(net::Error error) { - const GURL url(kFailedUrl); - core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME, - NetErrorHelperCore::NON_ERROR_PAGE); - std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetErrorForURL(error, url), - false /* is_failed_post */, true /* is_ignoring_cache */, &html); - EXPECT_FALSE(html.empty()); - EXPECT_EQ(NetErrorStringForURL(error, url), html); - - core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME, - NetErrorHelperCore::ERROR_PAGE); - core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url()); - core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME); - } - void DoSuccessLoad() { core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME, NetErrorHelperCore::NON_ERROR_PAGE); @@ -437,11 +415,7 @@ request_body_.clear(); } - void ReloadPage(bool bypass_cache) override { - reload_count_++; - if (bypass_cache) - reload_bypassing_cache_count_++; - } + void ReloadFrame() override { reload_count_++; } void DiagnoseError(const GURL& page_url) override { diagnose_error_count_++; @@ -517,7 +491,6 @@ mutable std::unique_ptr<error_page::ErrorPageParams> last_error_page_params_; int reload_count_; - int reload_bypassing_cache_count_; int diagnose_error_count_; GURL diagnose_error_url_; int download_count_; @@ -575,9 +548,9 @@ // It fails, and an error page is requested. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_CONNECTION_RESET), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_CONNECTION_RESET), + false /* is_failed_post */, &html); // Should have returned a local error page. EXPECT_FALSE(html.empty()); EXPECT_EQ(NetErrorString(net::ERR_CONNECTION_RESET), html); @@ -602,9 +575,9 @@ // It fails, and an error page is requested. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_CONNECTION_RESET), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_CONNECTION_RESET), + false /* is_failed_post */, &html); // Should have returned a local error page. EXPECT_FALSE(html.empty()); EXPECT_EQ(NetErrorString(net::ERR_CONNECTION_RESET), html); @@ -628,9 +601,9 @@ // It fails, and an error page is requested. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_CONNECTION_RESET), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_CONNECTION_RESET), + false /* is_failed_post */, &html); core()->OnNetErrorInfo(error_page::DNS_PROBE_FINISHED_NXDOMAIN); // Should have returned a local error page. @@ -660,9 +633,9 @@ // It fails, and an error page is requested. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::SUB_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::SUB_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + false /* is_failed_post */, &html); // Should have returned a local error page. EXPECT_EQ(NetErrorString(net::ERR_NAME_NOT_RESOLVED), html); @@ -684,9 +657,9 @@ // It fails, and an error page is requested. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::SUB_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::SUB_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + false /* is_failed_post */, &html); // Should have returned a local error page. EXPECT_EQ(NetErrorString(net::ERR_NAME_NOT_RESOLVED), html); @@ -709,9 +682,9 @@ // It fails, and an error page is requested. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::SUB_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::SUB_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + false /* is_failed_post */, &html); core()->OnNetErrorInfo(error_page::DNS_PROBE_FINISHED_NXDOMAIN); // Should have returned a local error page. @@ -747,9 +720,9 @@ // It fails, and an error page is requested. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + false /* is_failed_post */, &html); // Should have returned a local error page indicating a probe may run. EXPECT_EQ(ProbeErrorString(error_page::DNS_PROBE_POSSIBLE), html); @@ -784,9 +757,9 @@ // It fails, and an error page is requested. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + false /* is_failed_post */, &html); // Should have returned a local error page indicating a probe may run. EXPECT_EQ(ProbeErrorString(error_page::DNS_PROBE_POSSIBLE), html); @@ -818,9 +791,9 @@ // It fails, and an error page is requested. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + false /* is_failed_post */, &html); // Should have returned a local error page indicating a probe may run. EXPECT_EQ(ProbeErrorString(error_page::DNS_PROBE_POSSIBLE), html); @@ -857,9 +830,9 @@ // It fails, and an error page is requested. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + false /* is_failed_post */, &html); // Should have returned a local error page indicating a probe may run. EXPECT_EQ(ProbeErrorString(error_page::DNS_PROBE_POSSIBLE), html); @@ -894,9 +867,9 @@ // doesn't affect the result. core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME, NetErrorHelperCore::NON_ERROR_PAGE); - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + false /* is_failed_post */, &html); EXPECT_EQ(ProbeErrorString(error_page::DNS_PROBE_POSSIBLE), html); core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME, NetErrorHelperCore::ERROR_PAGE); @@ -921,9 +894,9 @@ // It fails, and an error page is requested. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + false /* is_failed_post */, &html); // Should have returned a local error page indicating a probe may run. EXPECT_EQ(ProbeErrorString(error_page::DNS_PROBE_POSSIBLE), html); @@ -960,9 +933,9 @@ // It fails, and an error page is requested. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + false /* is_failed_post */, &html); // Should have returned a local error page indicating a probe may run. EXPECT_EQ(ProbeErrorString(error_page::DNS_PROBE_POSSIBLE), html); @@ -1002,9 +975,9 @@ // It fails, and an error page is requested. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - true /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + true /* is_failed_post */, &html); // Should have returned a local error page indicating a probe may run. EXPECT_EQ(ErrorToString(ProbeError(error_page::DNS_PROBE_POSSIBLE), true), html); @@ -1039,9 +1012,9 @@ // It fails, and an error page is requested. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + false /* is_failed_post */, &html); // Should have returned a local error page indicating a probe may run. EXPECT_EQ(ProbeErrorString(error_page::DNS_PROBE_POSSIBLE), html); @@ -1080,9 +1053,9 @@ // It fails, and an error page is requested. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + false /* is_failed_post */, &html); // Should have returned a local error page indicating a probe may run. EXPECT_EQ(ProbeErrorString(error_page::DNS_PROBE_POSSIBLE), html); @@ -1106,9 +1079,9 @@ NetErrorHelperCore::NON_ERROR_PAGE); // It fails, and an error page is requested. - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + false /* is_failed_post */, &html); // Should have returned a local error page indicating a probe may run. EXPECT_EQ(ProbeErrorString(error_page::DNS_PROBE_POSSIBLE), html); @@ -1141,9 +1114,9 @@ // It fails, and an error page is requested. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + false /* is_failed_post */, &html); // Should have returned a local error page indicating a probe may run. EXPECT_EQ(ProbeErrorString(error_page::DNS_PROBE_POSSIBLE), html); @@ -1160,9 +1133,9 @@ NetErrorHelperCore::NON_ERROR_PAGE); // It fails, and an error page is requested. - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + false /* is_failed_post */, &html); // Should have returned a local error page indicating a probe may run. EXPECT_EQ(ProbeErrorString(error_page::DNS_PROBE_POSSIBLE), html); @@ -1198,9 +1171,9 @@ // It fails, and an error page is requested. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + false /* is_failed_post */, &html); // Should have returned a local error page indicating a probe may run. EXPECT_EQ(ProbeErrorString(error_page::DNS_PROBE_POSSIBLE), html); @@ -1217,9 +1190,9 @@ NetErrorHelperCore::NON_ERROR_PAGE); // And fails. - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + false /* is_failed_post */, &html); // Should have returned a local error page indicating a probe may run. EXPECT_EQ(ProbeErrorString(error_page::DNS_PROBE_POSSIBLE), html); @@ -1255,8 +1228,7 @@ auto error = NetErrorForURL(net::ERR_NAME_NOT_RESOLVED, GURL(kFailedHttpsUrl)); core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, error, - false /* is_failed_post */, - false /* is_ignoring_cache */, &html); + false /* is_failed_post */, &html); auto probe_error = ProbeErrorForURL(error_page::DNS_PROBE_POSSIBLE, GURL(kFailedHttpsUrl)); @@ -1293,9 +1265,9 @@ // It fails. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + false /* is_failed_post */, &html); EXPECT_TRUE(html.empty()); EXPECT_FALSE(is_url_being_fetched()); EXPECT_FALSE(last_error_page_params()); @@ -1344,9 +1316,9 @@ // It fails, and corrections are requested. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + false /* is_failed_post */, &html); EXPECT_TRUE(html.empty()); // The blank page loads. @@ -1392,9 +1364,9 @@ // It fails, and corrections are requested. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_CONNECTION_FAILED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_CONNECTION_FAILED), + false /* is_failed_post */, &html); EXPECT_TRUE(html.empty()); // The blank page loads. @@ -1436,9 +1408,9 @@ // It fails, and corrections are requested. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + false /* is_failed_post */, &html); EXPECT_TRUE(html.empty()); // The blank page loads. @@ -1487,9 +1459,9 @@ // It fails, and corrections are requested. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + false /* is_failed_post */, &html); EXPECT_TRUE(html.empty()); // The blank page loads. @@ -1536,9 +1508,9 @@ // It fails, and corrections are requested. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + false /* is_failed_post */, &html); EXPECT_TRUE(html.empty()); // The blank page starts loading. @@ -1574,9 +1546,9 @@ // It fails, and corrections are requested. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + false /* is_failed_post */, &html); EXPECT_TRUE(html.empty()); // The blank page starts loading and is committed. @@ -1608,9 +1580,9 @@ // It fails, and corrections are requested. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + false /* is_failed_post */, &html); EXPECT_TRUE(html.empty()); // The blank page loads. @@ -1631,9 +1603,9 @@ EXPECT_FALSE(is_url_being_fetched()); // It fails, and corrections are requested again once a blank page is loaded. - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + false /* is_failed_post */, &html); EXPECT_TRUE(html.empty()); core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME, NetErrorHelperCore::ERROR_PAGE); @@ -1667,9 +1639,9 @@ // It fails, and corrections are requested. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + false /* is_failed_post */, &html); EXPECT_TRUE(html.empty()); // The blank page loads. @@ -1692,9 +1664,9 @@ NetErrorHelperCore::NON_ERROR_PAGE); // It fails, and corrections are requested again. - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + false /* is_failed_post */, &html); EXPECT_TRUE(html.empty()); // The blank page loads again. @@ -1739,9 +1711,9 @@ // It fails, and corrections are requested. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + false /* is_failed_post */, &html); EXPECT_TRUE(html.empty()); // The blank page loads. @@ -1781,9 +1753,9 @@ // It fails, and corrections are requested. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + false /* is_failed_post */, &html); EXPECT_TRUE(html.empty()); // The blank page loads. @@ -1827,9 +1799,9 @@ // It fails, and corrections are requested. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + false /* is_failed_post */, &html); EXPECT_TRUE(html.empty()); // The blank page loads. @@ -1875,9 +1847,9 @@ // It fails, and corrections are requested. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + false /* is_failed_post */, &html); EXPECT_TRUE(html.empty()); // The blank page loads. @@ -1919,9 +1891,9 @@ // It fails, and corrections are requested. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_CONNECTION_FAILED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_CONNECTION_FAILED), + false /* is_failed_post */, &html); EXPECT_TRUE(html.empty()); // The blank page loads. @@ -1956,9 +1928,9 @@ // It fails, and corrections are requested. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_CONNECTION_FAILED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_CONNECTION_FAILED), + false /* is_failed_post */, &html); EXPECT_TRUE(html.empty()); // The blank page loads. @@ -1993,9 +1965,9 @@ // It fails. std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_NAME_NOT_RESOLVED), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_NAME_NOT_RESOLVED), + false /* is_failed_post */, &html); EXPECT_TRUE(html.empty()); EXPECT_FALSE(is_url_being_fetched()); EXPECT_FALSE(last_error_page_params()); @@ -2091,29 +2063,10 @@ EXPECT_TRUE(timer()->IsRunning()); EXPECT_EQ(0, reload_count()); - EXPECT_EQ(0, reload_bypassing_cache_count()); timer()->Fire(); EXPECT_FALSE(timer()->IsRunning()); EXPECT_EQ(1, reload_count()); - EXPECT_EQ(0, reload_bypassing_cache_count()); - - DoSuccessLoad(); - - EXPECT_FALSE(timer()->IsRunning()); -} - -TEST_F(NetErrorHelperCoreAutoReloadTest, BypassingCache) { - DoErrorReoadBypassingCache(net::ERR_CONNECTION_RESET); - - EXPECT_TRUE(timer()->IsRunning()); - EXPECT_EQ(0, reload_count()); - EXPECT_EQ(0, reload_bypassing_cache_count()); - - timer()->Fire(); - EXPECT_FALSE(timer()->IsRunning()); - EXPECT_EQ(1, reload_count()); - EXPECT_EQ(1, reload_bypassing_cache_count()); DoSuccessLoad(); @@ -2175,7 +2128,7 @@ core()->PrepareErrorPage( NetErrorHelperCore::MAIN_FRAME, NetErrorForURL(net::ERR_CONNECTION_RESET, GURL(kFailedUrl)), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + false /* is_failed_post */, &html); core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME, NetErrorHelperCore::ERROR_PAGE); @@ -2269,9 +2222,9 @@ core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME, NetErrorHelperCore::NON_ERROR_PAGE); std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_CONNECTION_RESET), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_CONNECTION_RESET), + false /* is_failed_post */, &html); core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME, NetErrorHelperCore::ERROR_PAGE); core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url()); @@ -2293,9 +2246,9 @@ core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME, NetErrorHelperCore::NON_ERROR_PAGE); std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_CONNECTION_RESET), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_CONNECTION_RESET), + false /* is_failed_post */, &html); core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME, NetErrorHelperCore::ERROR_PAGE); core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url()); @@ -2314,9 +2267,9 @@ core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME, NetErrorHelperCore::NON_ERROR_PAGE); std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_CONNECTION_RESET), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_CONNECTION_RESET), + false /* is_failed_post */, &html); core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME, NetErrorHelperCore::ERROR_PAGE); EXPECT_FALSE(timer()->IsRunning()); @@ -2335,18 +2288,18 @@ core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME, NetErrorHelperCore::NON_ERROR_PAGE); std::string html; - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_CONNECTION_RESET), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_CONNECTION_RESET), + false /* is_failed_post */, &html); core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME, NetErrorHelperCore::ERROR_PAGE); core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url()); core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME); core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME, NetErrorHelperCore::NON_ERROR_PAGE); - core()->PrepareErrorPage( - NetErrorHelperCore::MAIN_FRAME, NetError(net::ERR_CONNECTION_RESET), - false /* is_failed_post */, false /* is_ignoring_cache */, &html); + core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME, + NetError(net::ERR_CONNECTION_RESET), + false /* is_failed_post */, &html); core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME, NetErrorHelperCore::ERROR_PAGE); EXPECT_FALSE(timer()->IsRunning()); @@ -2455,19 +2408,8 @@ TEST_F(NetErrorHelperCoreTest, ExplicitReloadSucceeds) { DoErrorLoad(net::ERR_CONNECTION_RESET); EXPECT_EQ(0, reload_count()); - EXPECT_EQ(0, reload_bypassing_cache_count()); core()->ExecuteButtonPress(NetErrorHelperCore::RELOAD_BUTTON); EXPECT_EQ(1, reload_count()); - EXPECT_EQ(0, reload_bypassing_cache_count()); -} - -TEST_F(NetErrorHelperCoreTest, ExplicitReloadDoNotBypassCache) { - DoErrorReoadBypassingCache(net::ERR_CONNECTION_RESET); - EXPECT_EQ(0, reload_count()); - EXPECT_EQ(0, reload_bypassing_cache_count()); - core()->ExecuteButtonPress(NetErrorHelperCore::RELOAD_BUTTON); - EXPECT_EQ(1, reload_count()); - EXPECT_EQ(0, reload_bypassing_cache_count()); } TEST_F(NetErrorHelperCoreTest, CanNotShowNetworkDiagnostics) {
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 91c482e..3dfd10b 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2279,10 +2279,10 @@ "../browser/ui/views/extensions/extension_dialog_bounds_browsertest.cc", "../browser/ui/views/frame/browser_frame_ash_browsertest.cc", "../browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc", - "../browser/ui/views/frame/hosted_app_ash_interactive_ui_test.cc", "../browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc", "../browser/ui/views/frame/top_controls_slide_controller_chromeos_browsertest.cc", "../browser/ui/views/plugin_vm/plugin_vm_launcher_view_browsertest.cc", + "../browser/ui/views/web_apps/web_app_ash_interactive_ui_test.cc", "../browser/ui/webui/chromeos/add_supervision/add_supervision_metrics_recorder_browsertest.cc", "../browser/ui/webui/chromeos/add_supervision/add_supervision_ui_browsertest.cc", "../browser/ui/webui/chromeos/login/discover/discover_browser_test.cc",
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn index b49c7435..9a876a2 100644 --- a/chrome/test/data/webui/BUILD.gn +++ b/chrome/test/data/webui/BUILD.gn
@@ -98,8 +98,6 @@ "webui_resource_async_browsertest.js", ] - gen_include_files = [ "a11y/accessibility_audit_rules.js" ] - extra_js_files = [ "test_browser_proxy.js", "settings/test_password_manager_proxy.js",
diff --git a/chrome/test/data/webui/a11y/accessibility_audit_rules.js b/chrome/test/data/webui/a11y/accessibility_audit_rules.js index 6c08d3e..5079576 100644 --- a/chrome/test/data/webui/a11y/accessibility_audit_rules.js +++ b/chrome/test/data/webui/a11y/accessibility_audit_rules.js
@@ -52,6 +52,7 @@ 'frame-title', 'heading-order', 'hidden-content', + 'href-no-hash', 'html-has-lang', 'html-lang-valid', 'image-alt',
diff --git a/chrome/test/data/webui/extensions/a11y/extensions_a11y_test.js b/chrome/test/data/webui/extensions/a11y/extensions_a11y_test.js index 11bc8789..fcb77c0 100644 --- a/chrome/test/data/webui/extensions/a11y/extensions_a11y_test.js +++ b/chrome/test/data/webui/extensions/a11y/extensions_a11y_test.js
@@ -56,16 +56,6 @@ return parentNode && parentNode.host && parentNode.host.tagName == 'CR-TOGGLE'; }, - - // TODO(crbug.com/1002620): this filter can be removed after - // addressing the bug - 'heading-order': function(nodeResult) { - // Filter out 'Heading levels do not increase by one' error when - // enumerating extensions - const expectedMarkup = '<div id="name" role="heading" aria-level="3" \ -class="clippable-flex-text">My extension 1</div>'; - return nodeResult['html'] === expectedMarkup; - }, }; } @@ -95,13 +85,7 @@ name: 'NoExtensions', /** @override */ - // TODO(crbug.com/1002627): when bug is addressed, this should be replaced - // with axeOptions: CrExtensionsA11yTest.axeOptions, - axeOptions: Object.assign({}, CrExtensionsA11yTest.axeOptions, { - 'rules': Object.assign({}, CrExtensionsA11yTest.axeOptions.rules, { - 'link-in-text-block': {enabled: false}, - }) - }), + axeOptions: CrExtensionsA11yTest.axeOptions, /** @override */ violationFilter: CrExtensionsA11yTest.violationFilter,
diff --git a/chrome/test/data/webui/management/a11y/management_a11y_test.js b/chrome/test/data/webui/management/a11y/management_a11y_test.js index bc54861..a89088c 100644 --- a/chrome/test/data/webui/management/a11y/management_a11y_test.js +++ b/chrome/test/data/webui/management/a11y/management_a11y_test.js
@@ -31,8 +31,6 @@ 'skip-link': {enabled: false}, // TODO(crbug.com/761461): enable after addressing flaky tests. 'color-contrast': {enabled: false}, - // TODO(crbug.com/1002623): remove this line after addressing bug - 'link-in-text-block': {enabled: false}, }, }; }
diff --git a/chrome/test/data/webui/settings/a11y/crostini_settings_subpage_a11y_test.js b/chrome/test/data/webui/settings/a11y/crostini_settings_subpage_a11y_test.js index c2a8327..f9349f2 100644 --- a/chrome/test/data/webui/settings/a11y/crostini_settings_subpage_a11y_test.js +++ b/chrome/test/data/webui/settings/a11y/crostini_settings_subpage_a11y_test.js
@@ -15,7 +15,7 @@ /** @override */ name: 'CROSTINI', /** @override */ - axeOptions: SettingsAccessibilityTest.axeOptionsExcludeLinkInTextBlock, + axeOptions: SettingsAccessibilityTest.axeOptions, /** @override */ setup: function() { settings.router.navigateTo(settings.routes.CROSTINI);
diff --git a/chrome/test/data/webui/settings/a11y/multidevice_a11y_test.js b/chrome/test/data/webui/settings/a11y/multidevice_a11y_test.js index 97c7759..1eb57f3 100644 --- a/chrome/test/data/webui/settings/a11y/multidevice_a11y_test.js +++ b/chrome/test/data/webui/settings/a11y/multidevice_a11y_test.js
@@ -32,7 +32,7 @@ /** @override */ name: 'MULTIDEVICE', /** @override */ - axeOptions: SettingsAccessibilityTest.axeOptionsExcludeLinkInTextBlock, + axeOptions: SettingsAccessibilityTest.axeOptions, /** @override */ setup: function() { settings.router.navigateTo(settings.routes.MULTIDEVICE);
diff --git a/chrome/test/data/webui/settings/a11y/multidevice_features_a11y_test.js b/chrome/test/data/webui/settings/a11y/multidevice_features_a11y_test.js index 5a0f2a07..841c3feb 100644 --- a/chrome/test/data/webui/settings/a11y/multidevice_features_a11y_test.js +++ b/chrome/test/data/webui/settings/a11y/multidevice_features_a11y_test.js
@@ -32,7 +32,7 @@ /** @override */ name: 'MULTIDEVICE_FEATURES_ACCESSIBILITY', /** @override */ - axeOptions: SettingsAccessibilityTest.axeOptionsExcludeLinkInTextBlock, + axeOptions: SettingsAccessibilityTest.axeOptions, /** @override */ setup: function() { settings.router.navigateTo(settings.routes.MULTIDEVICE_FEATURES);
diff --git a/chrome/test/data/webui/settings/a11y/settings_accessibility_test.js b/chrome/test/data/webui/settings/a11y/settings_accessibility_test.js index b871ad8..7d52614 100644 --- a/chrome/test/data/webui/settings/a11y/settings_accessibility_test.js +++ b/chrome/test/data/webui/settings/a11y/settings_accessibility_test.js
@@ -28,17 +28,6 @@ } }; -// TODO(crbug.com/1002627): This block prevents generation of a -// link-in-text-block browser-test. This can be removed once the bug is -// addressed, and usage should be replaced with -// SettingsAccessibilityTest.axeOptions -SettingsAccessibilityTest.axeOptionsExcludeLinkInTextBlock = - Object.assign({}, SettingsAccessibilityTest.axeOptions, { - 'rules': Object.assign({}, SettingsAccessibilityTest.axeOptions.rules, { - 'link-in-text-block': {enabled: false}, - }) - }); - // Default accessibility audit options. Specify in test definition to use. SettingsAccessibilityTest.violationFilter = { // Polymer components use aria-active-attribute.
diff --git a/chromecast/browser/cast_network_contexts.cc b/chromecast/browser/cast_network_contexts.cc index 3f74108..edb6c43 100644 --- a/chromecast/browser/cast_network_contexts.cc +++ b/chromecast/browser/cast_network_contexts.cc
@@ -97,7 +97,7 @@ network::mojom::NetworkContext* CastNetworkContexts::GetSystemContext() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (!system_network_context_ || system_network_context_.encountered_error()) { + if (!system_network_context_ || !system_network_context_.is_connected()) { // This should call into OnNetworkServiceCreated(), which will re-create // the network service, if needed. There's a chance that it won't be // invoked, if the NetworkContext has encountered an error but the @@ -167,8 +167,9 @@ // The system NetworkContext must be created first, since it sets // |primary_network_context| to true. - network_service->CreateNetworkContext(MakeRequest(&system_network_context_), - CreateSystemNetworkContextParams()); + network_service->CreateNetworkContext( + system_network_context_.BindNewPipeAndPassReceiver(), + CreateSystemNetworkContextParams()); } void CastNetworkContexts::OnLocaleUpdate() {
diff --git a/chromecast/browser/cast_network_contexts.h b/chromecast/browser/cast_network_contexts.h index 2077fc00..4cf050f 100644 --- a/chromecast/browser/cast_network_contexts.h +++ b/chromecast/browser/cast_network_contexts.h
@@ -110,7 +110,7 @@ const std::vector<std::string> cors_exempt_headers_list_; // The system NetworkContext. - network::mojom::NetworkContextPtr system_network_context_; + mojo::Remote<network::mojom::NetworkContext> system_network_context_; // URLLoaderFactory backed by the NetworkContext returned by // GetSystemContext(), so consumers don't all need to create their own
diff --git a/chromeos/services/assistant/assistant_state_proxy.cc b/chromeos/services/assistant/assistant_state_proxy.cc index d4ca3e3..bdfcab0 100644 --- a/chromeos/services/assistant/assistant_state_proxy.cc +++ b/chromeos/services/assistant/assistant_state_proxy.cc
@@ -7,14 +7,16 @@ #include <algorithm> #include <utility> +#include "ash/public/mojom/assistant_state_controller.mojom.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/remote.h" #include "services/service_manager/public/cpp/connector.h" namespace chromeos { namespace assistant { AssistantStateProxy::AssistantStateProxy() - : assistant_state_observer_binding_(this), - pref_connection_delegate_(std::make_unique<PrefConnectionDelegate>()) {} + : pref_connection_delegate_(std::make_unique<PrefConnectionDelegate>()) {} AssistantStateProxy::~AssistantStateProxy() { // Reset pref change registar. @@ -28,9 +30,10 @@ remote_controller.InitWithNewPipeAndPassReceiver()); assistant_state_controller_.Bind(std::move(remote_controller)); - ash::mojom::AssistantStateObserverPtr ptr; - assistant_state_observer_binding_.Bind(mojo::MakeRequest(&ptr)); - assistant_state_controller_->AddMojomObserver(std::move(ptr)); + mojo::PendingRemote<ash::mojom::AssistantStateObserver> observer; + assistant_state_observer_receiver_.Bind( + observer.InitWithNewPipeAndPassReceiver()); + assistant_state_controller_->AddMojomObserver(std::move(observer)); // Connect to pref service. auto pref_registry = base::MakeRefCounted<PrefRegistrySimple>();
diff --git a/chromeos/services/assistant/assistant_state_proxy.h b/chromeos/services/assistant/assistant_state_proxy.h index e8185211..d6e603fc 100644 --- a/chromeos/services/assistant/assistant_state_proxy.h +++ b/chromeos/services/assistant/assistant_state_proxy.h
@@ -15,8 +15,8 @@ #include "base/observer_list.h" #include "chromeos/services/assistant/pref_connection_delegate.h" #include "chromeos/services/assistant/public/mojom/assistant.mojom.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" namespace chromeos { namespace assistant { @@ -49,9 +49,10 @@ void OnPrefServiceConnected(std::unique_ptr<::PrefService> pref_service); - ash::mojom::AssistantStateControllerPtr assistant_state_controller_; - mojo::Binding<ash::mojom::AssistantStateObserver> - assistant_state_observer_binding_; + mojo::Remote<ash::mojom::AssistantStateController> + assistant_state_controller_; + mojo::Receiver<ash::mojom::AssistantStateObserver> + assistant_state_observer_receiver_{this}; std::unique_ptr<PrefService> pref_service_;
diff --git a/chromeos/services/assistant/service_unittest.cc b/chromeos/services/assistant/service_unittest.cc index e78e6464..270e20e 100644 --- a/chromeos/services/assistant/service_unittest.cc +++ b/chromeos/services/assistant/service_unittest.cc
@@ -144,7 +144,7 @@ void RequestAssistantStateController( mojo::PendingReceiver<ash::mojom::AssistantStateController> receiver) override { - assistant_state_->BindRequest(std::move(receiver)); + assistant_state_->BindReceiver(std::move(receiver)); } ash::AssistantState* const assistant_state_;
diff --git a/components/chromeos_camera/mojo_jpeg_encode_accelerator_service.cc b/components/chromeos_camera/mojo_jpeg_encode_accelerator_service.cc index d6328917..2600dcc 100644 --- a/components/chromeos_camera/mojo_jpeg_encode_accelerator_service.cc +++ b/components/chromeos_camera/mojo_jpeg_encode_accelerator_service.cc
@@ -23,7 +23,7 @@ #include "components/chromeos_camera/dmabuf_utils.h" #include "media/base/bind_to_current_loop.h" #include "media/base/video_frame.h" -#include "mojo/public/cpp/bindings/strong_binding.h" +#include "mojo/public/cpp/bindings/self_owned_receiver.h" #include "mojo/public/cpp/system/platform_handle.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/linux/native_pixmap_dmabuf.h" @@ -56,9 +56,11 @@ // static void MojoJpegEncodeAcceleratorService::Create( - chromeos_camera::mojom::JpegEncodeAcceleratorRequest request) { + mojo::PendingReceiver<chromeos_camera::mojom::JpegEncodeAccelerator> + receiver) { auto* jpeg_encoder = new MojoJpegEncodeAcceleratorService(); - mojo::MakeStrongBinding(base::WrapUnique(jpeg_encoder), std::move(request)); + mojo::MakeSelfOwnedReceiver(base::WrapUnique(jpeg_encoder), + std::move(receiver)); } MojoJpegEncodeAcceleratorService::MojoJpegEncodeAcceleratorService()
diff --git a/components/chromeos_camera/mojo_jpeg_encode_accelerator_service.h b/components/chromeos_camera/mojo_jpeg_encode_accelerator_service.h index 7db5439..ef0f41c 100644 --- a/components/chromeos_camera/mojo_jpeg_encode_accelerator_service.h +++ b/components/chromeos_camera/mojo_jpeg_encode_accelerator_service.h
@@ -15,6 +15,7 @@ #include "components/chromeos_camera/common/jpeg_encode_accelerator.mojom.h" #include "components/chromeos_camera/gpu_jpeg_encode_accelerator_factory.h" #include "components/chromeos_camera/jpeg_encode_accelerator.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" namespace chromeos_camera { @@ -25,7 +26,8 @@ public JpegEncodeAccelerator::Client { public: static void Create( - chromeos_camera::mojom::JpegEncodeAcceleratorRequest request); + mojo::PendingReceiver<chromeos_camera::mojom::JpegEncodeAccelerator> + receiver); ~MojoJpegEncodeAcceleratorService() override;
diff --git a/components/password_manager/core/browser/form_parsing/form_parser.cc b/components/password_manager/core/browser/form_parsing/form_parser.cc index e89925b..0083ec43 100644 --- a/components/password_manager/core/browser/form_parsing/form_parser.cc +++ b/components/password_manager/core/browser/form_parsing/form_parser.cc
@@ -947,6 +947,13 @@ result->only_for_fallback = significant_fields.is_fallback; result->submission_event = form_data.submission_event; + for (const FormFieldData& field : form_data.fields) { + if (field.form_control_type == "password" && + (field.properties_mask & FieldPropertiesFlags::AUTOFILLED)) { + result->form_has_autofilled_value = true; + } + } + // Set data related to specific fields. SetFields(significant_fields, result.get()); return result;
diff --git a/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc b/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc index 170aedf..447b6f3c 100644 --- a/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc +++ b/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc
@@ -97,6 +97,7 @@ bool fallback_only = false; SubmissionIndicatorEvent submission_event = SubmissionIndicatorEvent::NONE; base::Optional<bool> is_new_password_reliable; + bool form_has_autofilled_value = false; }; // Returns numbers which are distinct from each other within the scope of one @@ -374,6 +375,8 @@ EXPECT_EQ(*test_case.is_new_password_reliable, parsed_form->is_new_password_reliable); } + EXPECT_EQ(test_case.form_has_autofilled_value, + parsed_form->form_has_autofilled_value); CheckPasswordFormFields(*parsed_form, form_data, expected_ids); CheckAllValuesUnique(parsed_form->all_possible_passwords); @@ -1024,6 +1027,7 @@ {.form_control_type = "password", .is_readonly = true}, }, .number_of_all_possible_passwords = 3, + .form_has_autofilled_value = true, }, { .description_for_logging = "And passwords already filled by user or " @@ -1044,6 +1048,7 @@ {.form_control_type = "password", .is_readonly = true}, }, .number_of_all_possible_passwords = 3, + .form_has_autofilled_value = true, }, }); } @@ -1261,6 +1266,7 @@ .is_focusable = true}, }, .number_of_all_possible_passwords = 3, + .form_has_autofilled_value = true, }, { "Interactability for usernames is only considered before the first " @@ -1279,6 +1285,7 @@ .is_focusable = true}, {.form_control_type = "text", .is_focusable = true, .value = ""}, }, + .form_has_autofilled_value = true, }, { "Interactability also matters for HTML classifier.", @@ -1749,6 +1756,7 @@ }, .readonly_status = FormDataParser::ReadonlyPasswordFields::kNoneIgnored, + .form_has_autofilled_value = true, }, { "Some readonly passwords ignored.",
diff --git a/components/printing/common/print_messages.cc b/components/printing/common/print_messages.cc index 528773d8..6fa8435 100644 --- a/components/printing/common/print_messages.cc +++ b/components/printing/common/print_messages.cc
@@ -135,10 +135,10 @@ PrintHostMsg_RequestPrintPreview_Params:: PrintHostMsg_RequestPrintPreview_Params() : is_modifiable(false), + is_pdf(false), webnode_only(false), has_selection(false), - selection_only(false) { -} + selection_only(false) {} PrintHostMsg_RequestPrintPreview_Params:: ~PrintHostMsg_RequestPrintPreview_Params() {}
diff --git a/components/printing/common/print_messages.h b/components/printing/common/print_messages.h index a134a00..cf9f49f 100644 --- a/components/printing/common/print_messages.h +++ b/components/printing/common/print_messages.h
@@ -90,6 +90,7 @@ PrintHostMsg_RequestPrintPreview_Params(); ~PrintHostMsg_RequestPrintPreview_Params(); bool is_modifiable; + bool is_pdf; bool webnode_only; bool has_selection; bool selection_only; @@ -214,6 +215,7 @@ #if BUILDFLAG(ENABLE_PRINT_PREVIEW) IPC_STRUCT_TRAITS_BEGIN(PrintHostMsg_RequestPrintPreview_Params) IPC_STRUCT_TRAITS_MEMBER(is_modifiable) + IPC_STRUCT_TRAITS_MEMBER(is_pdf) IPC_STRUCT_TRAITS_MEMBER(webnode_only) IPC_STRUCT_TRAITS_MEMBER(has_selection) IPC_STRUCT_TRAITS_MEMBER(selection_only)
diff --git a/components/printing/renderer/print_render_frame_helper.cc b/components/printing/renderer/print_render_frame_helper.cc index 626edef..bf17ec1 100644 --- a/components/printing/renderer/print_render_frame_helper.cc +++ b/components/printing/renderer/print_render_frame_helper.cc
@@ -57,6 +57,7 @@ #include "third_party/blink/public/web/web_local_frame_client.h" #include "third_party/blink/public/web/web_navigation_control.h" #include "third_party/blink/public/web/web_plugin.h" +#include "third_party/blink/public/web/web_plugin_container.h" #include "third_party/blink/public/web/web_plugin_document.h" #include "third_party/blink/public/web/web_print_params.h" #include "third_party/blink/public/web/web_print_preset_options.h" @@ -352,6 +353,17 @@ return plugin && plugin->SupportsPaginatedPrint(); } +bool IsPrintingPdf(blink::WebLocalFrame* frame, const blink::WebNode& node) { + blink::WebPlugin* plugin; + if (node.IsNull()) { + plugin = GetPlugin(frame); + } else { + blink::WebPluginContainer* plugin_container = node.PluginContainer(); + plugin = plugin_container ? plugin_container->Plugin() : nullptr; + } + return plugin && plugin->IsPdfPlugin(); +} + #if BUILDFLAG(ENABLE_PRINT_PREVIEW) // Returns true if the current destination printer is PRINT_TO_PDF. bool IsPrintToPdfRequested(const base::DictionaryValue& job_settings) { @@ -2176,9 +2188,11 @@ if (!weak_this) return; const bool is_modifiable = print_preview_context_.IsModifiable(); + const bool is_pdf = print_preview_context_.IsPdf(); const bool has_selection = print_preview_context_.HasSelection(); PrintHostMsg_RequestPrintPreview_Params params; params.is_modifiable = is_modifiable; + params.is_pdf = is_pdf; params.has_selection = has_selection; switch (type) { case PRINT_PREVIEW_SCRIPTED: { @@ -2301,6 +2315,7 @@ source_frame_.Reset(web_frame); source_node_.Reset(); CalculateIsModifiable(); + CalculateIsPdf(); } void PrintRenderFrameHelper::PrintPreviewContext::InitWithNode( @@ -2312,6 +2327,7 @@ source_frame_.Reset(web_node.GetDocument().GetFrame()); source_node_ = web_node; CalculateIsModifiable(); + CalculateIsPdf(); } void PrintRenderFrameHelper::PrintPreviewContext::OnPrintPreview() { @@ -2435,6 +2451,11 @@ return is_modifiable_; } +bool PrintRenderFrameHelper::PrintPreviewContext::IsPdf() const { + DCHECK(state_ != UNINITIALIZED); + return is_pdf_; +} + bool PrintRenderFrameHelper::PrintPreviewContext::HasSelection() { return IsModifiable() && source_frame()->HasSelection(); } @@ -2507,10 +2528,13 @@ } void PrintRenderFrameHelper::PrintPreviewContext::CalculateIsModifiable() { - // The only kind of node we can print right now is a PDF node. is_modifiable_ = !IsPrintingNodeOrPdfFrame(source_frame(), source_node_); } +void PrintRenderFrameHelper::PrintPreviewContext::CalculateIsPdf() { + is_pdf_ = IsPrintingPdf(source_frame(), source_node_); +} + void PrintRenderFrameHelper::SetPrintPagesParams( const PrintMsg_PrintPages_Params& settings) { print_pages_params_ = std::make_unique<PrintMsg_PrintPages_Params>(settings);
diff --git a/components/printing/renderer/print_render_frame_helper.h b/components/printing/renderer/print_render_frame_helper.h index 71c0c15..e4edbee 100644 --- a/components/printing/renderer/print_render_frame_helper.h +++ b/components/printing/renderer/print_render_frame_helper.h
@@ -436,6 +436,7 @@ int GetNextPageNumber(); bool IsRendering() const; bool IsModifiable() const; + bool IsPdf() const; bool HasSelection(); bool IsLastPageOfPrintReadyMetafile() const; bool IsFinalPageRendered() const; @@ -474,6 +475,8 @@ void CalculateIsModifiable(); + void CalculateIsPdf(); + // Specifies what to render for print preview. FrameReference source_frame_; blink::WebNode source_node_; @@ -493,6 +496,10 @@ // True, if the document source is modifiable. e.g. HTML and not PDF. bool is_modifiable_ = true; + // True, if the document source is a PDF. Used to distinguish from + // other plugins such as Flash. + bool is_pdf_ = false; + // Specifies the total number of pages in the print ready metafile. int print_ready_metafile_page_count_ = 0;
diff --git a/components/signin/internal/identity_manager/BUILD.gn b/components/signin/internal/identity_manager/BUILD.gn index a6a8aa9..bfcb201 100644 --- a/components/signin/internal/identity_manager/BUILD.gn +++ b/components/signin/internal/identity_manager/BUILD.gn
@@ -22,8 +22,6 @@ "diagnostics_provider_impl.h", "gaia_cookie_manager_service.cc", "gaia_cookie_manager_service.h", - "mutable_profile_oauth2_token_service_delegate.cc", - "mutable_profile_oauth2_token_service_delegate.h", "oauth2_token_service_delegate_android.cc", "oauth2_token_service_delegate_android.h", "oauth_multilogin_helper.cc", @@ -73,6 +71,11 @@ if (is_android) { deps += [ "//components/signin/core/browser/android:jni_headers" ] + } else { + sources += [ + "mutable_profile_oauth2_token_service_delegate.cc", + "mutable_profile_oauth2_token_service_delegate.h", + ] } if (is_chromeos) { @@ -117,7 +120,6 @@ "account_info_util_unittest.cc", "account_tracker_service_unittest.cc", "gaia_cookie_manager_service_unittest.cc", - "mutable_profile_oauth2_token_service_delegate_unittest.cc", "oauth2_token_service_delegate_android_unittest.cc", "oauth_multilogin_helper_unittest.cc", "oauth_multilogin_token_fetcher_unittest.cc", @@ -167,6 +169,10 @@ deps += [ "//components/signin/public/identity_manager/ios:test_support" ] } + + if (!is_android) { + sources += [ "mutable_profile_oauth2_token_service_delegate_unittest.cc" ] + } } # This target contains test support that backs the test support for
diff --git a/components/signin/internal/identity_manager/android/BUILD.gn b/components/signin/internal/identity_manager/android/BUILD.gn index 4b51665..87a9e21d 100644 --- a/components/signin/internal/identity_manager/android/BUILD.gn +++ b/components/signin/internal/identity_manager/android/BUILD.gn
@@ -6,6 +6,6 @@ "//components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/CoreAccountId.java", "//components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/CoreAccountInfo.java", "//components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/IdentityManager.java", - "//components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/PrimaryAccountMutator.java", + "//components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/IdentityMutator.java", ] }
diff --git a/components/signin/internal/identity_manager/fake_profile_oauth2_token_service_delegate.cc b/components/signin/internal/identity_manager/fake_profile_oauth2_token_service_delegate.cc index bef96b8..65bbb978 100644 --- a/components/signin/internal/identity_manager/fake_profile_oauth2_token_service_delegate.cc +++ b/components/signin/internal/identity_manager/fake_profile_oauth2_token_service_delegate.cc
@@ -168,3 +168,11 @@ it->second->error = error; FireAuthErrorChanged(account_id, error); } + +#if defined(OS_ANDROID) +base::android::ScopedJavaLocalRef<jobject> +FakeProfileOAuth2TokenServiceDelegate::GetJavaObject() { + NOTREACHED(); + return base::android::ScopedJavaLocalRef<jobject>(); +} +#endif
diff --git a/components/signin/internal/identity_manager/fake_profile_oauth2_token_service_delegate.h b/components/signin/internal/identity_manager/fake_profile_oauth2_token_service_delegate.h index f47aa8f..d208752 100644 --- a/components/signin/internal/identity_manager/fake_profile_oauth2_token_service_delegate.h +++ b/components/signin/internal/identity_manager/fake_profile_oauth2_token_service_delegate.h
@@ -9,6 +9,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "build/build_config.h" #include "components/signin/internal/identity_manager/profile_oauth2_token_service_delegate.h" #include "google_apis/gaia/google_service_auth_error.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" @@ -73,6 +74,10 @@ void IssueRefreshTokenForUser(const CoreAccountId& account_id, const std::string& token); +#if defined(OS_ANDROID) + base::android::ScopedJavaLocalRef<jobject> GetJavaObject() override; +#endif + // Maps account ids to info. std::map<CoreAccountId, std::unique_ptr<AccountInfo>> refresh_tokens_;
diff --git a/components/signin/internal/identity_manager/oauth2_token_service_delegate_android.h b/components/signin/internal/identity_manager/oauth2_token_service_delegate_android.h index b55902b..00eedee 100644 --- a/components/signin/internal/identity_manager/oauth2_token_service_delegate_android.h +++ b/components/signin/internal/identity_manager/oauth2_token_service_delegate_android.h
@@ -38,7 +38,7 @@ static OAuth2TokenServiceDelegateAndroid* Create(); // Returns a reference to the corresponding Java OAuth2TokenService object. - base::android::ScopedJavaLocalRef<jobject> GetJavaObject(); + base::android::ScopedJavaLocalRef<jobject> GetJavaObject() override; // Called by the TestingProfile class to disable account validation in // tests. This prevents the token service from trying to look up system
diff --git a/components/signin/internal/identity_manager/primary_account_manager.cc b/components/signin/internal/identity_manager/primary_account_manager.cc index 73b788e3..e9af9b91 100644 --- a/components/signin/internal/identity_manager/primary_account_manager.cc +++ b/components/signin/internal/identity_manager/primary_account_manager.cc
@@ -53,8 +53,6 @@ registry->RegisterStringPref(prefs::kGoogleServicesLastUsername, std::string()); registry->RegisterStringPref(prefs::kGoogleServicesAccountId, std::string()); - registry->RegisterStringPref(prefs::kGoogleServicesUserAccountId, - std::string()); registry->RegisterBooleanPref(prefs::kAutologinEnabled, true); registry->RegisterListPref(prefs::kReverseAutologinRejectedEmailList); registry->RegisterBooleanPref(prefs::kSigninAllowed, true); @@ -78,7 +76,6 @@ base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); if (cmd_line->HasSwitch(switches::kClearTokenService)) { client_->GetPrefs()->ClearPref(prefs::kGoogleServicesAccountId); - client_->GetPrefs()->ClearPref(prefs::kGoogleServicesUserAccountId); } std::string pref_account_id = @@ -144,13 +141,6 @@ client_->GetPrefs()->SetString(prefs::kGoogleServicesAccountId, account_info.account_id.id); - // When this function is called from Initialize(), it's possible for - // |info.gaia| to be empty when migrating from a really old profile. - if (!account_info.gaia.empty()) { - client_->GetPrefs()->SetString(prefs::kGoogleServicesUserAccountId, - account_info.gaia); - } - // Go ahead and update the last signed in account info here as well. Once a // user is signed in the corresponding preferences should match. Doing it here // as opposed to on signin allows us to catch the upgrade scenario. @@ -295,7 +285,6 @@ ClearAuthenticatedAccountInfo(); client_->GetPrefs()->ClearPref(prefs::kGoogleServicesHostedDomain); client_->GetPrefs()->ClearPref(prefs::kGoogleServicesAccountId); - client_->GetPrefs()->ClearPref(prefs::kGoogleServicesUserAccountId); // Revoke all tokens before sending signed_out notification, because there // may be components that don't listen for token service events when the
diff --git a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate.h b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate.h index d22b7ea..67b93772 100644 --- a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate.h +++ b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate.h
@@ -20,6 +20,10 @@ #include "google_apis/gaia/oauth2_access_token_manager.h" #include "net/base/backoff_entry.h" +#if defined(OS_ANDROID) +#include "base/android/jni_android.h" +#endif + namespace network { class SharedURLLoaderFactory; } @@ -133,6 +137,9 @@ #endif #if defined(OS_ANDROID) + // Returns a reference to the corresponding Java object. + virtual base::android::ScopedJavaLocalRef<jobject> GetJavaObject() = 0; + // Triggers platform specific implementation for Android to reload accounts // from system. virtual void ReloadAccountsFromSystem(
diff --git a/components/signin/public/base/signin_pref_names.cc b/components/signin/public/base/signin_pref_names.cc index b2b92c1e..9d7f6b4f 100644 --- a/components/signin/public/base/signin_pref_names.cc +++ b/components/signin/public/base/signin_pref_names.cc
@@ -41,10 +41,9 @@ // double that should be converted into base::Time. const char kGaiaCookiePeriodicReportTime[] = "gaia_cookie.periodic_report_time"; -// Typically contains an obfuscated gaiaid and will match the value of -// kGoogleServicesUserAccountId. Some platforms and legacy clients may have +// Typically contains an obfuscated gaiaid. Some platforms may have // an email stored in this preference instead. This is transitional and will -// eventually be fixed, allowing the removal of kGoogleServicesUserAccountId. +// eventually be fixed. const char kGoogleServicesAccountId[] = "google.services.account_id"; // The profile's hosted domain; empty if unset; kNoHostedDomainFound if there @@ -68,10 +67,6 @@ const char kGoogleServicesSigninScopedDeviceId[] = "google.services.signin_scoped_device_id"; -// Obfuscated account ID that identifies the current user logged into sync and -// other google services. -const char kGoogleServicesUserAccountId[] = "google.services.user_account_id"; - // Local state pref containing a string regex that restricts which accounts // can be used to log in to chrome (e.g. "*@google.com"). If missing or blank, // all accounts are allowed (no restrictions).
diff --git a/components/signin/public/base/signin_pref_names.h b/components/signin/public/base/signin_pref_names.h index 49584f70..84887f4 100644 --- a/components/signin/public/base/signin_pref_names.h +++ b/components/signin/public/base/signin_pref_names.h
@@ -21,7 +21,6 @@ extern const char kGoogleServicesLastAccountId[]; extern const char kGoogleServicesLastUsername[]; extern const char kGoogleServicesSigninScopedDeviceId[]; -extern const char kGoogleServicesUserAccountId[]; extern const char kGoogleServicesUsernamePattern[]; extern const char kReverseAutologinRejectedEmailList[]; extern const char kSignedInWithCredentialProvider[];
diff --git a/components/signin/public/identity_manager/account_info.cc b/components/signin/public/identity_manager/account_info.cc index 424852d1..0a61b7d 100644 --- a/components/signin/public/identity_manager/account_info.cc +++ b/components/signin/public/identity_manager/account_info.cc
@@ -144,9 +144,22 @@ env, base::android::ConvertUTF8ToJavaString(env, account_id.id)); } +CoreAccountInfo ConvertFromJavaCoreAccountInfo( + JNIEnv* env, + const base::android::JavaRef<jobject>& j_core_account_info) { + CoreAccountInfo account; + account.account_id = ConvertFromJavaCoreAccountId( + env, signin::Java_CoreAccountInfo_getId(env, j_core_account_info)); + account.gaia = base::android::ConvertJavaStringToUTF8( + signin::Java_CoreAccountInfo_getGaiaId(env, j_core_account_info)); + account.email = base::android::ConvertJavaStringToUTF8( + signin::Java_CoreAccountInfo_getName(env, j_core_account_info)); + return account; +} + CoreAccountId ConvertFromJavaCoreAccountId( JNIEnv* env, - const base::android::JavaParamRef<jobject>& j_core_account_id) { + const base::android::JavaRef<jobject>& j_core_account_id) { CoreAccountId id; id.id = base::android::ConvertJavaStringToUTF8( signin::Java_CoreAccountId_getId(env, j_core_account_id));
diff --git a/components/signin/public/identity_manager/account_info.h b/components/signin/public/identity_manager/account_info.h index 91ae337b..0c7f93d 100644 --- a/components/signin/public/identity_manager/account_info.h +++ b/components/signin/public/identity_manager/account_info.h
@@ -90,10 +90,15 @@ JNIEnv* env, const CoreAccountId& account_id); -// Constructs a C++ CoreAccountId from the provided java CoreAccountId +// Constructs a C++ CoreAccountInfo from the provided Java CoreAccountInfo +CoreAccountInfo ConvertFromJavaCoreAccountInfo( + JNIEnv* env, + const base::android::JavaRef<jobject>& j_core_account_info); + +// Constructs a C++ CoreAccountId from the provided Java CoreAccountId CoreAccountId ConvertFromJavaCoreAccountId( JNIEnv* env, - const base::android::JavaParamRef<jobject>& j_core_account_id); + const base::android::JavaRef<jobject>& j_core_account_id); #endif #endif // COMPONENTS_SIGNIN_PUBLIC_IDENTITY_MANAGER_ACCOUNT_INFO_H_
diff --git a/components/signin/public/identity_manager/android/BUILD.gn b/components/signin/public/identity_manager/android/BUILD.gn index 9e837218..6b6ee93 100644 --- a/components/signin/public/identity_manager/android/BUILD.gn +++ b/components/signin/public/identity_manager/android/BUILD.gn
@@ -18,7 +18,7 @@ "java/src/org/chromium/components/signin/identitymanager/CoreAccountId.java", "java/src/org/chromium/components/signin/identitymanager/CoreAccountInfo.java", "java/src/org/chromium/components/signin/identitymanager/IdentityManager.java", - "java/src/org/chromium/components/signin/identitymanager/PrimaryAccountMutator.java", + "java/src/org/chromium/components/signin/identitymanager/IdentityMutator.java", ] annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
diff --git a/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/CoreAccountInfo.java b/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/CoreAccountInfo.java index 41f17c5..10aef56 100644 --- a/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/CoreAccountInfo.java +++ b/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/CoreAccountInfo.java
@@ -62,6 +62,7 @@ /** * Returns a unique identifier of the current account. */ + @CalledByNative public CoreAccountId getId() { return mId; } @@ -69,6 +70,7 @@ /** * Returns a name of the current account. */ + @CalledByNative public String getName() { return mAccount.name; } @@ -76,6 +78,7 @@ /** * Returns the string representation of the Gaia ID */ + @CalledByNative public String getGaiaId() { return mGaiaId; }
diff --git a/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/IdentityManager.java b/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/IdentityManager.java index d61aa8c5..f23c48a 100644 --- a/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/IdentityManager.java +++ b/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/IdentityManager.java
@@ -37,27 +37,26 @@ } private long mNativeIdentityManager; - private PrimaryAccountMutator mPrimaryAccountMutator; + private IdentityMutator mIdentityMutator; private final ObserverList<Observer> mObservers = new ObserverList<>(); /** * Called by native to create an instance of IdentityManager. - * @param primaryAccountMutator can be null if native's IdentityManager received a null - * PrimaryAccountMutator, this happens in tests. + * @param identityMutator can be null if native's IdentityManager received a null + * IdentityMutator, this happens in tests. */ @CalledByNative static private IdentityManager create( - long nativeIdentityManager, @Nullable PrimaryAccountMutator primaryAccountMutator) { + long nativeIdentityManager, @Nullable IdentityMutator identityMutator) { assert nativeIdentityManager != 0; - return new IdentityManager(nativeIdentityManager, primaryAccountMutator); + return new IdentityManager(nativeIdentityManager, identityMutator); } @VisibleForTesting - public IdentityManager( - long nativeIdentityManager, PrimaryAccountMutator primaryAccountMutator) { + public IdentityManager(long nativeIdentityManager, IdentityMutator identityMutator) { mNativeIdentityManager = nativeIdentityManager; - mPrimaryAccountMutator = primaryAccountMutator; + mIdentityMutator = identityMutator; } /** @@ -125,8 +124,8 @@ * Returns pointer to the object used to change the signed-in state of the * primary account. */ - public PrimaryAccountMutator getPrimaryAccountMutator() { - return mPrimaryAccountMutator; + public IdentityMutator getIdentityMutator() { + return mIdentityMutator; } @NativeMethods
diff --git a/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/PrimaryAccountMutator.java b/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/IdentityMutator.java similarity index 65% rename from components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/PrimaryAccountMutator.java rename to components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/IdentityMutator.java index 5a8b8ce..112d363 100644 --- a/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/PrimaryAccountMutator.java +++ b/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/IdentityMutator.java
@@ -10,18 +10,21 @@ import org.chromium.components.signin.metrics.SignoutReason; /** - * PrimaryAccountMutator is the interface to set and clear the primary account (see IdentityManager - * for more information). + * IdentityMutator is the write interface of IdentityManager, see identity_manager.h and + * primary_account_mutator.h for more information. */ -public class PrimaryAccountMutator { - private static final String TAG = "PrimaryAccountMuta"; +public class IdentityMutator { + private static final String TAG = "IdentityMutator"; private final long mNativePrimaryAccountMutator; + private final long mNativeIdentityManager; @CalledByNative - private PrimaryAccountMutator(long nativePrimaryAccountMutator) { + private IdentityMutator(long nativePrimaryAccountMutator, long nativeIdentityManager) { assert nativePrimaryAccountMutator != 0; + assert nativeIdentityManager != 0; mNativePrimaryAccountMutator = nativePrimaryAccountMutator; + mNativeIdentityManager = nativeIdentityManager; } /** @@ -33,8 +36,7 @@ * - there is not already a primary account set. */ public boolean setPrimaryAccount(CoreAccountId accountId) { - return PrimaryAccountMutatorJni.get().setPrimaryAccount( - mNativePrimaryAccountMutator, accountId); + return IdentityMutatorJni.get().setPrimaryAccount(mNativePrimaryAccountMutator, accountId); } /** @@ -43,15 +45,24 @@ */ public boolean clearPrimaryAccount(@ClearAccountsAction int action, @SignoutReason int sourceMetric, @SignoutDelete int deleteMetric) { - return PrimaryAccountMutatorJni.get().clearPrimaryAccount( + return IdentityMutatorJni.get().clearPrimaryAccount( mNativePrimaryAccountMutator, action, sourceMetric, deleteMetric); } + /** + * Reloads the accounts in the token service from the system accounts. This API calls + * ProfileOAuth2TokenServiceDelegate::ReloadAccountsFromSystem. + */ + public void reloadAccountsFromSystem() { + IdentityMutatorJni.get().reloadAccountsFromSystem(mNativeIdentityManager); + } + @NativeMethods interface Natives { public boolean setPrimaryAccount(long nativePrimaryAccountMutator, CoreAccountId accountId); public boolean clearPrimaryAccount(long nativePrimaryAccountMutator, @ClearAccountsAction int action, @SignoutReason int sourceMetric, @SignoutDelete int deleteMetric); + public void reloadAccountsFromSystem(long nativeIdentityManager); } }
diff --git a/components/signin/public/identity_manager/identity_manager.cc b/components/signin/public/identity_manager/identity_manager.cc index d5a87f55..50000fa 100644 --- a/components/signin/public/identity_manager/identity_manager.cc +++ b/components/signin/public/identity_manager/identity_manager.cc
@@ -25,6 +25,7 @@ #if defined(OS_ANDROID) #include "base/android/jni_string.h" #include "components/signin/internal/identity_manager/android/jni_headers/IdentityManager_jni.h" +#include "components/signin/internal/identity_manager/android/jni_headers/IdentityMutator_jni.h" #include "components/signin/internal/identity_manager/oauth2_token_service_delegate_android.h" #elif !defined(OS_IOS) #include "components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.h" @@ -105,12 +106,17 @@ UpdateUnconsentedPrimaryAccount(); #if defined(OS_ANDROID) - base::android::ScopedJavaLocalRef<jobject> java_primary_account_mutator = - primary_account_mutator_ ? primary_account_mutator_->GetJavaObject() - : nullptr; + base::android::ScopedJavaLocalRef<jobject> java_identity_mutator = + primary_account_mutator_ + ? Java_IdentityMutator_Constructor( + base::android::AttachCurrentThread(), + reinterpret_cast<intptr_t>(primary_account_mutator_.get()), + reinterpret_cast<intptr_t>(this)) + : nullptr; + java_identity_manager_ = Java_IdentityManager_create( base::android::AttachCurrentThread(), reinterpret_cast<intptr_t>(this), - java_primary_account_mutator); + java_identity_mutator); #endif } @@ -419,10 +425,7 @@ base::android::ScopedJavaLocalRef<jobject> IdentityManager::LegacyGetOAuth2TokenServiceJavaObject() { - OAuth2TokenServiceDelegateAndroid* delegate = - static_cast<OAuth2TokenServiceDelegateAndroid*>( - token_service_->GetDelegate()); - return delegate->GetJavaObject(); + return token_service_->GetDelegate()->GetJavaObject(); } base::android::ScopedJavaLocalRef<jobject> IdentityManager::GetJavaObject() { @@ -451,6 +454,10 @@ return nullptr; return ConvertToJavaCoreAccountInfo(env, account_info.value()); } + +void IdentityManager::ReloadAccountsFromSystem(JNIEnv* env) { + LegacyReloadAccountsFromSystem(); +} #endif PrimaryAccountManager* IdentityManager::GetPrimaryAccountManager() {
diff --git a/components/signin/public/identity_manager/identity_manager.h b/components/signin/public/identity_manager/identity_manager.h index 8e56dd3..1efedce 100644 --- a/components/signin/public/identity_manager/identity_manager.h +++ b/components/signin/public/identity_manager/identity_manager.h
@@ -464,6 +464,8 @@ FindExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress( JNIEnv* env, const base::android::JavaParamRef<jstring>& j_email) const; + + void ReloadAccountsFromSystem(JNIEnv* env); #endif private:
diff --git a/components/signin/public/identity_manager/primary_account_mutator.cc b/components/signin/public/identity_manager/primary_account_mutator.cc index 02b4b1e..7e691e43 100644 --- a/components/signin/public/identity_manager/primary_account_mutator.cc +++ b/components/signin/public/identity_manager/primary_account_mutator.cc
@@ -8,17 +8,11 @@ #if defined(OS_ANDROID) #include "base/android/jni_string.h" -#include "components/signin/internal/identity_manager/android/jni_headers/PrimaryAccountMutator_jni.h" #endif namespace signin { -PrimaryAccountMutator::PrimaryAccountMutator() { -#if defined(OS_ANDROID) - java_primary_account_mutator_ = Java_PrimaryAccountMutator_Constructor( - base::android::AttachCurrentThread(), reinterpret_cast<intptr_t>(this)); -#endif -} +PrimaryAccountMutator::PrimaryAccountMutator() {} PrimaryAccountMutator::~PrimaryAccountMutator() {} @@ -38,13 +32,6 @@ static_cast<signin_metrics::ProfileSignout>(source_metric), static_cast<signin_metrics::SignoutDelete>(delete_metric)); } - -base::android::ScopedJavaLocalRef<jobject> -PrimaryAccountMutator::GetJavaObject() { - DCHECK(java_primary_account_mutator_); - return base::android::ScopedJavaLocalRef<jobject>( - java_primary_account_mutator_); -} #endif } // namespace signin
diff --git a/components/sync/driver/glue/sync_engine_backend.cc b/components/sync/driver/glue/sync_engine_backend.cc index 0e6aa82..2469a38 100644 --- a/components/sync/driver/glue/sync_engine_backend.cc +++ b/components/sync/driver/glue/sync_engine_backend.cc
@@ -76,9 +76,13 @@ bool ShouldEnableUSSNigori() { // USS implementation of Nigori is not compatible with Directory // implementations of Passwords and Bookmarks. - return base::FeatureList::IsEnabled(switches::kSyncUSSNigori) && - base::FeatureList::IsEnabled(switches::kSyncUSSBookmarks) && - base::FeatureList::IsEnabled(switches::kSyncUSSPasswords); + // |kSyncUSSNigori| should be checked last, since check itself has side + // effect (only clients, which have feature-flag checked participate in the + // study). Otherwise, we will have different amount of clients in control and + // experiment groups. + return base::FeatureList::IsEnabled(switches::kSyncUSSBookmarks) && + base::FeatureList::IsEnabled(switches::kSyncUSSPasswords) && + base::FeatureList::IsEnabled(switches::kSyncUSSNigori); } } // namespace
diff --git a/components/viz/host/gpu_client.cc b/components/viz/host/gpu_client.cc index 2f40ee92..68d8768 100644 --- a/components/viz/host/gpu_client.cc +++ b/components/viz/host/gpu_client.cc
@@ -175,10 +175,11 @@ #endif // defined(OS_CHROMEOS) void GpuClient::CreateVideoEncodeAcceleratorProvider( - media::mojom::VideoEncodeAcceleratorProviderRequest vea_provider_request) { + mojo::PendingReceiver<media::mojom::VideoEncodeAcceleratorProvider> + vea_provider_receiver) { if (auto* gpu_host = delegate_->EnsureGpuHost()) { gpu_host->gpu_service()->CreateVideoEncodeAcceleratorProvider( - std::move(vea_provider_request)); + std::move(vea_provider_receiver)); } }
diff --git a/components/viz/host/gpu_client.h b/components/viz/host/gpu_client.h index a60e6ac..bf05f84 100644 --- a/components/viz/host/gpu_client.h +++ b/components/viz/host/gpu_client.h
@@ -62,8 +62,8 @@ override; #endif // defined(OS_CHROMEOS) void CreateVideoEncodeAcceleratorProvider( - media::mojom::VideoEncodeAcceleratorProviderRequest vea_provider_request) - override; + mojo::PendingReceiver<media::mojom::VideoEncodeAcceleratorProvider> + vea_provider_receiver) override; private: enum class ErrorReason {
diff --git a/components/viz/host/host_gpu_memory_buffer_manager_unittest.cc b/components/viz/host/host_gpu_memory_buffer_manager_unittest.cc index 2e9b715..ae10e53 100644 --- a/components/viz/host/host_gpu_memory_buffer_manager_unittest.cc +++ b/components/viz/host/host_gpu_memory_buffer_manager_unittest.cc
@@ -89,28 +89,33 @@ void CloseChannel(int32_t client_id) override {} #if defined(OS_CHROMEOS) void CreateArcVideoDecodeAccelerator( - arc::mojom::VideoDecodeAcceleratorRequest vda_request) override {} + mojo::PendingReceiver<arc::mojom::VideoDecodeAccelerator> vda_receiver) + override {} void CreateArcVideoEncodeAccelerator( - arc::mojom::VideoEncodeAcceleratorRequest vea_request) override {} + mojo::PendingReceiver<arc::mojom::VideoEncodeAccelerator> vea_receiver) + override {} void CreateArcVideoProtectedBufferAllocator( - arc::mojom::VideoProtectedBufferAllocatorRequest pba_request) override {} + mojo::PendingReceiver<arc::mojom::VideoProtectedBufferAllocator> + pba_receiver) override {} void CreateArcProtectedBufferManager( - arc::mojom::ProtectedBufferManagerRequest pbm_request) override {} + mojo::PendingReceiver<arc::mojom::ProtectedBufferManager> pbm_receiver) + override {} void CreateJpegDecodeAccelerator( - chromeos_camera::mojom::MjpegDecodeAcceleratorRequest jda_request) - override {} + mojo::PendingReceiver<chromeos_camera::mojom::MjpegDecodeAccelerator> + jda_receiver) override {} void CreateJpegEncodeAccelerator( - chromeos_camera::mojom::JpegEncodeAcceleratorRequest jea_request) - override {} + mojo::PendingReceiver<chromeos_camera::mojom::JpegEncodeAccelerator> + jea_receiver) override {} #endif // defined(OS_CHROMEOS) void CreateVideoEncodeAcceleratorProvider( - media::mojom::VideoEncodeAcceleratorProviderRequest request) override {} + mojo::PendingReceiver<media::mojom::VideoEncodeAcceleratorProvider> + receiver) override {} void CreateGpuMemoryBuffer(gfx::GpuMemoryBufferId id, const gfx::Size& size,
diff --git a/components/viz/service/gl/gpu_service_impl.cc b/components/viz/service/gl/gpu_service_impl.cc index 7603ec3..39630b3 100644 --- a/components/viz/service/gl/gpu_service_impl.cc +++ b/components/viz/service/gl/gpu_service_impl.cc
@@ -49,7 +49,7 @@ #include "media/gpu/ipc/service/gpu_video_decode_accelerator.h" #include "media/gpu/ipc/service/media_gpu_channel_manager.h" #include "media/mojo/services/mojo_video_encode_accelerator_provider.h" -#include "mojo/public/cpp/bindings/strong_binding.h" +#include "mojo/public/cpp/bindings/self_owned_receiver.h" #include "third_party/skia/include/gpu/GrContext.h" #include "third_party/skia/include/gpu/gl/GrGLAssembleInterface.h" #include "third_party/skia/include/gpu/gl/GrGLInterface.h" @@ -372,102 +372,109 @@ #if defined(OS_CHROMEOS) void GpuServiceImpl::CreateArcVideoDecodeAccelerator( - arc::mojom::VideoDecodeAcceleratorRequest vda_request) { + mojo::PendingReceiver<arc::mojom::VideoDecodeAccelerator> vda_receiver) { DCHECK(io_runner_->BelongsToCurrentThread()); main_runner_->PostTask( FROM_HERE, base::BindOnce( &GpuServiceImpl::CreateArcVideoDecodeAcceleratorOnMainThread, - weak_ptr_, std::move(vda_request))); + weak_ptr_, std::move(vda_receiver))); } void GpuServiceImpl::CreateArcVideoEncodeAccelerator( - arc::mojom::VideoEncodeAcceleratorRequest vea_request) { + mojo::PendingReceiver<arc::mojom::VideoEncodeAccelerator> vea_receiver) { DCHECK(io_runner_->BelongsToCurrentThread()); main_runner_->PostTask( FROM_HERE, base::BindOnce( &GpuServiceImpl::CreateArcVideoEncodeAcceleratorOnMainThread, - weak_ptr_, std::move(vea_request))); + weak_ptr_, std::move(vea_receiver))); } void GpuServiceImpl::CreateArcVideoProtectedBufferAllocator( - arc::mojom::VideoProtectedBufferAllocatorRequest pba_request) { + mojo::PendingReceiver<arc::mojom::VideoProtectedBufferAllocator> + pba_receiver) { DCHECK(io_runner_->BelongsToCurrentThread()); main_runner_->PostTask( FROM_HERE, base::BindOnce( &GpuServiceImpl::CreateArcVideoProtectedBufferAllocatorOnMainThread, - weak_ptr_, std::move(pba_request))); + weak_ptr_, std::move(pba_receiver))); } void GpuServiceImpl::CreateArcProtectedBufferManager( - arc::mojom::ProtectedBufferManagerRequest pbm_request) { + mojo::PendingReceiver<arc::mojom::ProtectedBufferManager> pbm_receiver) { DCHECK(io_runner_->BelongsToCurrentThread()); main_runner_->PostTask( FROM_HERE, base::BindOnce( &GpuServiceImpl::CreateArcProtectedBufferManagerOnMainThread, - weak_ptr_, std::move(pbm_request))); + weak_ptr_, std::move(pbm_receiver))); } void GpuServiceImpl::CreateArcVideoDecodeAcceleratorOnMainThread( - arc::mojom::VideoDecodeAcceleratorRequest vda_request) { + mojo::PendingReceiver<arc::mojom::VideoDecodeAccelerator> vda_receiver) { DCHECK(main_runner_->BelongsToCurrentThread()); - mojo::MakeStrongBinding(std::make_unique<arc::GpuArcVideoDecodeAccelerator>( - gpu_preferences_, protected_buffer_manager_), - std::move(vda_request)); + mojo::MakeSelfOwnedReceiver( + std::make_unique<arc::GpuArcVideoDecodeAccelerator>( + gpu_preferences_, protected_buffer_manager_), + std::move(vda_receiver)); } void GpuServiceImpl::CreateArcVideoEncodeAcceleratorOnMainThread( - arc::mojom::VideoEncodeAcceleratorRequest vea_request) { + mojo::PendingReceiver<arc::mojom::VideoEncodeAccelerator> vea_receiver) { DCHECK(main_runner_->BelongsToCurrentThread()); - mojo::MakeStrongBinding( + mojo::MakeSelfOwnedReceiver( std::make_unique<arc::GpuArcVideoEncodeAccelerator>(gpu_preferences_), - std::move(vea_request)); + std::move(vea_receiver)); } void GpuServiceImpl::CreateArcVideoProtectedBufferAllocatorOnMainThread( - arc::mojom::VideoProtectedBufferAllocatorRequest pba_request) { + mojo::PendingReceiver<arc::mojom::VideoProtectedBufferAllocator> + pba_receiver) { DCHECK(main_runner_->BelongsToCurrentThread()); auto gpu_arc_video_protected_buffer_allocator = arc::GpuArcVideoProtectedBufferAllocator::Create( protected_buffer_manager_); if (!gpu_arc_video_protected_buffer_allocator) return; - mojo::MakeStrongBinding(std::move(gpu_arc_video_protected_buffer_allocator), - std::move(pba_request)); + mojo::MakeSelfOwnedReceiver( + std::move(gpu_arc_video_protected_buffer_allocator), + std::move(pba_receiver)); } void GpuServiceImpl::CreateArcProtectedBufferManagerOnMainThread( - arc::mojom::ProtectedBufferManagerRequest pbm_request) { + mojo::PendingReceiver<arc::mojom::ProtectedBufferManager> pbm_receiver) { DCHECK(main_runner_->BelongsToCurrentThread()); - mojo::MakeStrongBinding( + mojo::MakeSelfOwnedReceiver( std::make_unique<arc::GpuArcProtectedBufferManagerProxy>( protected_buffer_manager_), - std::move(pbm_request)); + std::move(pbm_receiver)); } void GpuServiceImpl::CreateJpegDecodeAccelerator( - chromeos_camera::mojom::MjpegDecodeAcceleratorRequest jda_request) { + mojo::PendingReceiver<chromeos_camera::mojom::MjpegDecodeAccelerator> + jda_receiver) { DCHECK(io_runner_->BelongsToCurrentThread()); chromeos_camera::MojoMjpegDecodeAcceleratorService::Create( - std::move(jda_request)); + std::move(jda_receiver)); } void GpuServiceImpl::CreateJpegEncodeAccelerator( - chromeos_camera::mojom::JpegEncodeAcceleratorRequest jea_request) { + mojo::PendingReceiver<chromeos_camera::mojom::JpegEncodeAccelerator> + jea_receiver) { DCHECK(io_runner_->BelongsToCurrentThread()); chromeos_camera::MojoJpegEncodeAcceleratorService::Create( - std::move(jea_request)); + std::move(jea_receiver)); } #endif // defined(OS_CHROMEOS) void GpuServiceImpl::CreateVideoEncodeAcceleratorProvider( - media::mojom::VideoEncodeAcceleratorProviderRequest vea_provider_request) { + mojo::PendingReceiver<media::mojom::VideoEncodeAcceleratorProvider> + vea_provider_receiver) { DCHECK(io_runner_->BelongsToCurrentThread()); media::MojoVideoEncodeAcceleratorProvider::Create( - std::move(vea_provider_request), + std::move(vea_provider_receiver), base::BindRepeating(&media::GpuVideoEncodeAcceleratorFactory::CreateVEA), gpu_preferences_); }
diff --git a/components/viz/service/gl/gpu_service_impl.h b/components/viz/service/gl/gpu_service_impl.h index cdb9efa..ab4e1656 100644 --- a/components/viz/service/gl/gpu_service_impl.h +++ b/components/viz/service/gl/gpu_service_impl.h
@@ -117,24 +117,28 @@ void CloseChannel(int32_t client_id) override; #if defined(OS_CHROMEOS) void CreateArcVideoDecodeAccelerator( - arc::mojom::VideoDecodeAcceleratorRequest vda_request) override; + mojo::PendingReceiver<arc::mojom::VideoDecodeAccelerator> vda_receiver) + override; void CreateArcVideoEncodeAccelerator( - arc::mojom::VideoEncodeAcceleratorRequest vea_request) override; + mojo::PendingReceiver<arc::mojom::VideoEncodeAccelerator> vea_receiver) + override; void CreateArcVideoProtectedBufferAllocator( - arc::mojom::VideoProtectedBufferAllocatorRequest pba_request) override; + mojo::PendingReceiver<arc::mojom::VideoProtectedBufferAllocator> + pba_receiver) override; void CreateArcProtectedBufferManager( - arc::mojom::ProtectedBufferManagerRequest pbm_request) override; + mojo::PendingReceiver<arc::mojom::ProtectedBufferManager> pbm_receiver) + override; void CreateJpegDecodeAccelerator( - chromeos_camera::mojom::MjpegDecodeAcceleratorRequest jda_request) - override; + mojo::PendingReceiver<chromeos_camera::mojom::MjpegDecodeAccelerator> + jda_receiver) override; void CreateJpegEncodeAccelerator( - chromeos_camera::mojom::JpegEncodeAcceleratorRequest jea_request) - override; + mojo::PendingReceiver<chromeos_camera::mojom::JpegEncodeAccelerator> + jea_receiver) override; #endif // defined(OS_CHROMEOS) void CreateVideoEncodeAcceleratorProvider( - media::mojom::VideoEncodeAcceleratorProviderRequest vea_provider_request) - override; + mojo::PendingReceiver<media::mojom::VideoEncodeAcceleratorProvider> + vea_provider_receiver) override; void CreateGpuMemoryBuffer(gfx::GpuMemoryBufferId id, const gfx::Size& size, gfx::BufferFormat format, @@ -266,13 +270,14 @@ #if defined(OS_CHROMEOS) void CreateArcVideoDecodeAcceleratorOnMainThread( - arc::mojom::VideoDecodeAcceleratorRequest vda_request); + mojo::PendingReceiver<arc::mojom::VideoDecodeAccelerator> vda_receiver); void CreateArcVideoEncodeAcceleratorOnMainThread( - arc::mojom::VideoEncodeAcceleratorRequest vea_request); + mojo::PendingReceiver<arc::mojom::VideoEncodeAccelerator> vea_receiver); void CreateArcVideoProtectedBufferAllocatorOnMainThread( - arc::mojom::VideoProtectedBufferAllocatorRequest pba_request); + mojo::PendingReceiver<arc::mojom::VideoProtectedBufferAllocator> + pba_receiver); void CreateArcProtectedBufferManagerOnMainThread( - arc::mojom::ProtectedBufferManagerRequest pbm_request); + mojo::PendingReceiver<arc::mojom::ProtectedBufferManager> pbm_receiver); #endif // defined(OS_CHROMEOS) void RequestHDRStatusOnMainThread(RequestHDRStatusCallback callback);
diff --git a/content/browser/android/background_sync_network_observer_android.cc b/content/browser/android/background_sync_network_observer_android.cc index 26a2a796..3ca52ce6 100644 --- a/content/browser/android/background_sync_network_observer_android.cc +++ b/content/browser/android/background_sync_network_observer_android.cc
@@ -8,6 +8,7 @@ #include "base/task/post_task.h" #include "content/public/android/content_jni_headers/BackgroundSyncNetworkObserver_jni.h" #include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/service_worker_context.h" using base::android::JavaParamRef; @@ -17,11 +18,11 @@ scoped_refptr<BackgroundSyncNetworkObserverAndroid::Observer> BackgroundSyncNetworkObserverAndroid::Observer::Create( base::RepeatingCallback<void(network::mojom::ConnectionType)> callback) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); + DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); scoped_refptr<BackgroundSyncNetworkObserverAndroid::Observer> observer( new BackgroundSyncNetworkObserverAndroid::Observer(callback)); - base::PostTask( - FROM_HERE, {BrowserThread::UI}, + RunOrPostTaskOnThread( + FROM_HERE, BrowserThread::UI, base::BindOnce(&BackgroundSyncNetworkObserverAndroid::Observer::Init, observer)); return observer; @@ -51,8 +52,8 @@ const JavaParamRef<jobject>& jcaller, jint new_connection_type) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - base::PostTask( - FROM_HERE, {BrowserThread::IO}, + RunOrPostTaskOnThread( + FROM_HERE, ServiceWorkerContext::GetCoreThreadId(), base::BindOnce(callback_, static_cast<network::mojom::ConnectionType>( new_connection_type))); } @@ -60,13 +61,13 @@ BackgroundSyncNetworkObserverAndroid::Observer::Observer( base::RepeatingCallback<void(network::mojom::ConnectionType)> callback) : callback_(callback) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); + DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); } BackgroundSyncNetworkObserverAndroid::BackgroundSyncNetworkObserverAndroid( const base::Closure& network_changed_callback) : BackgroundSyncNetworkObserver(network_changed_callback) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); + DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); observer_ = Observer::Create( base::Bind(&BackgroundSyncNetworkObserverAndroid::OnConnectionChanged, @@ -74,7 +75,7 @@ } BackgroundSyncNetworkObserverAndroid::~BackgroundSyncNetworkObserverAndroid() { - DCHECK_CURRENTLY_ON(BrowserThread::IO); + DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); } void BackgroundSyncNetworkObserverAndroid::RegisterWithNetworkConnectionTracker(
diff --git a/content/browser/back_forward_cache_browsertest.cc b/content/browser/back_forward_cache_browsertest.cc index ff3b827..0a11baa 100644 --- a/content/browser/back_forward_cache_browsertest.cc +++ b/content/browser/back_forward_cache_browsertest.cc
@@ -1899,6 +1899,7 @@ EXPECT_TRUE(rfh_a->is_in_back_forward_cache()); } +// Regression test for https://crbug.com/993337. IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest, NavigateToTwoPagesOnSameSite) { ASSERT_TRUE(embedded_test_server()->Start()); @@ -1912,18 +1913,21 @@ // 2) Navigate to A2. EXPECT_TRUE(NavigateToURL(shell(), url_a2)); RenderFrameHostImpl* rfh_a2 = current_frame_host(); + RenderFrameDeletedObserver delete_rfh_a2(current_frame_host()); // 3) Navigate to B1. EXPECT_TRUE(NavigateToURL(shell(), url_b1)); EXPECT_TRUE(rfh_a2->is_in_back_forward_cache()); + RenderFrameHostImpl* rfh_b1 = current_frame_host(); // 4) Do a history navigation back to A1. - // TODO(https://crbug.com/993337): This causes "Check failed: !frame_widget_". - RenderProcessHost* process = rfh_a2->GetProcess(); - RenderProcessHostWatcher crash_observer( - process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); web_contents()->GetController().GoToIndex(0); - crash_observer.Wait(); + EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); + EXPECT_TRUE(rfh_b1->is_in_back_forward_cache()); + + // As a result, rfh_a2 is deleted. The history navigation tried to restore an + // entry using the same BrowsingInstance. They both can't live together. + delete_rfh_a2.WaitUntilDeleted(); } class GeolocationBackForwardCacheBrowserTest
diff --git a/content/browser/frame_host/interstitial_page_impl.cc b/content/browser/frame_host/interstitial_page_impl.cc index be1334c4..208f6543 100644 --- a/content/browser/frame_host/interstitial_page_impl.cc +++ b/content/browser/frame_host/interstitial_page_impl.cc
@@ -792,15 +792,17 @@ return Visibility::OCCLUDED; } -void InterstitialPageImpl::CreateNewWidget(int32_t render_process_id, - int32_t route_id, - mojom::WidgetPtr widget) { +void InterstitialPageImpl::CreateNewWidget( + int32_t render_process_id, + int32_t route_id, + mojo::PendingRemote<mojom::Widget> widget) { NOTREACHED() << "InterstitialPage does not support showing drop-downs."; } -void InterstitialPageImpl::CreateNewFullscreenWidget(int32_t render_process_id, - int32_t route_id, - mojom::WidgetPtr widget) { +void InterstitialPageImpl::CreateNewFullscreenWidget( + int32_t render_process_id, + int32_t route_id, + mojo::PendingRemote<mojom::Widget> widget) { NOTREACHED() << "InterstitialPage does not support showing full screen popups."; }
diff --git a/content/browser/frame_host/interstitial_page_impl.h b/content/browser/frame_host/interstitial_page_impl.h index 3843989..9445711 100644 --- a/content/browser/frame_host/interstitial_page_impl.h +++ b/content/browser/frame_host/interstitial_page_impl.h
@@ -25,6 +25,7 @@ #include "content/public/browser/render_widget_host.h" #include "content/public/browser/render_widget_host_observer.h" #include "content/public/browser/web_contents_observer.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "third_party/blink/public/mojom/renderer_preferences.mojom.h" #include "url/gurl.h" @@ -160,10 +161,11 @@ BrowserContext* browser_context) const override; void CreateNewWidget(int32_t render_process_id, int32_t route_id, - mojom::WidgetPtr widget) override; - void CreateNewFullscreenWidget(int32_t render_process_id, - int32_t route_id, - mojom::WidgetPtr widget) override; + mojo::PendingRemote<mojom::Widget> widget) override; + void CreateNewFullscreenWidget( + int32_t render_process_id, + int32_t route_id, + mojo::PendingRemote<mojom::Widget> widget) override; void ShowCreatedWidget(int process_id, int route_id, const gfx::Rect& initial_rect) override;
diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc index 30e765cc..8235e056 100644 --- a/content/browser/frame_host/navigation_controller_impl.cc +++ b/content/browser/frame_host/navigation_controller_impl.cc
@@ -2128,7 +2128,7 @@ bool NavigationControllerImpl::StartHistoryNavigationInNewSubframe( RenderFrameHostImpl* render_frame_host, - mojom::NavigationClientAssociatedPtrInfo* navigation_client) { + mojo::PendingAssociatedRemote<mojom::NavigationClient>* navigation_client) { NavigationEntryImpl* entry = GetEntryWithUniqueID(render_frame_host->nav_entry_id()); if (!entry) @@ -2536,6 +2536,20 @@ return; } + // By design, a page in the BackForwardCache is alone in its BrowsingInstance. + // History navigation might try to reuse a specific SiteInstance, already used + // by a page in the cache. This must not happen. It would fail creating the + // RenderFrame, because only one main document can live there. For this + // reason, the BackForwardCache is flushed. + // TODO(arthursonzogni): Flushing the entire cache is a bit overkill, this can + // be refined to only delete the page (if any) using the same + // BrowsingInstance. + if (pending_entry_->site_instance()) { + SiteInstance* current = root->current_frame_host()->GetSiteInstance(); + if (!current->IsRelatedSiteInstance(pending_entry_->site_instance())) + back_forward_cache_.Flush(); + } + // If we were navigating to a slow-to-commit page, and the user performs // a session history navigation to the last committed page, RenderViewHost // will force the throbber to start, but WebKit will essentially ignore the
diff --git a/content/browser/frame_host/navigation_controller_impl.h b/content/browser/frame_host/navigation_controller_impl.h index f01c4c5c..48075d6 100644 --- a/content/browser/frame_host/navigation_controller_impl.h +++ b/content/browser/frame_host/navigation_controller_impl.h
@@ -24,6 +24,7 @@ #include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_type.h" #include "content/public/browser/reload_type.h" +#include "mojo/public/cpp/bindings/pending_associated_remote.h" struct FrameHostMsg_DidCommitProvisionalLoad_Params; @@ -103,7 +104,8 @@ // navigation to the default src URL for the frame instead. bool StartHistoryNavigationInNewSubframe( RenderFrameHostImpl* render_frame_host, - mojom::NavigationClientAssociatedPtrInfo* navigation_client); + mojo::PendingAssociatedRemote<mojom::NavigationClient>* + navigation_client); // Navigates to a specified offset from the "current entry". Currently records // a histogram indicating whether the session history navigation would only
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc index 52f857a5..76310ca 100644 --- a/content/browser/frame_host/navigation_request.cc +++ b/content/browser/frame_host/navigation_request.cc
@@ -603,8 +603,8 @@ frame_tree_node, std::move(common_params), std::move(navigation_params), std::move(commit_params), browser_initiated, false /* from_begin_navigation */, false /* is_for_commit */, frame_entry, - entry, std::move(navigation_ui_data), nullptr, mojo::NullRemote(), - rfh_restored_from_back_forward_cache)); + entry, std::move(navigation_ui_data), mojo::NullAssociatedRemote(), + mojo::NullRemote(), rfh_restored_from_back_forward_cache)); if (frame_entry) { navigation_request->blob_url_loader_factory_ = @@ -637,7 +637,7 @@ int current_history_list_length, bool override_user_agent, scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory, - mojom::NavigationClientAssociatedPtrInfo navigation_client, + mojo::PendingAssociatedRemote<mojom::NavigationClient> navigation_client, mojo::PendingRemote<blink::mojom::NavigationInitiator> navigation_initiator, scoped_refptr<PrefetchedSignedExchangeCache> prefetched_signed_exchange_cache) { @@ -763,9 +763,8 @@ std::move(commit_params), !is_renderer_initiated, false /* from_begin_navigation */, true /* is_for_commit */, entry ? entry->GetFrameEntry(frame_tree_node) : nullptr, entry, - nullptr /* navigation_ui_data */, - mojom::NavigationClientAssociatedPtrInfo(), mojo::NullRemote(), - nullptr /* rfh_restored_from_back_forward_cache */)); + nullptr /* navigation_ui_data */, mojo::NullAssociatedRemote(), + mojo::NullRemote(), nullptr /* rfh_restored_from_back_forward_cache */)); // Update the state of the NavigationRequest to match the fact that the // navigation just committed. @@ -787,7 +786,7 @@ const FrameNavigationEntry* frame_entry, NavigationEntryImpl* entry, std::unique_ptr<NavigationUIData> navigation_ui_data, - mojom::NavigationClientAssociatedPtrInfo navigation_client, + mojo::PendingAssociatedRemote<mojom::NavigationClient> navigation_client, mojo::PendingRemote<blink::mojom::NavigationInitiator> navigation_initiator, RenderFrameHostImpl* rfh_restored_from_back_forward_cache) : frame_tree_node_(frame_tree_node), @@ -807,8 +806,8 @@ net_error_(net::OK), expected_render_process_host_id_(ChildProcessHost::kInvalidUniqueID), devtools_navigation_token_(base::UnguessableToken::Create()), - request_navigation_client_(nullptr), - commit_navigation_client_(nullptr), + request_navigation_client_(mojo::NullAssociatedRemote()), + commit_navigation_client_(mojo::NullAssociatedRemote()), rfh_restored_from_back_forward_cache_( rfh_restored_from_back_forward_cache) { DCHECK(browser_initiated || common_params_->initiator_origin.has_value()); @@ -2199,7 +2198,7 @@ // consistent with the URL being requested. commit_params_->origin_to_commit = url::Origin::Create(common_params_->url).DeriveNewOpaqueOrigin(); - if (IsPerNavigationMojoInterfaceEnabled() && request_navigation_client_ && + if (IsPerNavigationMojoInterfaceEnabled() && request_navigation_client_.is_bound()) { if (associated_site_instance_id_ == render_frame_host_->GetSiteInstance()->GetId()) { @@ -2267,7 +2266,7 @@ frame_tree_node_->TransferNavigationRequestOwnership(render_frame_host_); - if (IsPerNavigationMojoInterfaceEnabled() && request_navigation_client_ && + if (IsPerNavigationMojoInterfaceEnabled() && request_navigation_client_.is_bound()) { if (associated_site_instance_id_ == render_frame_host_->GetSiteInstance()->GetId()) { @@ -2622,19 +2621,17 @@ } void NavigationRequest::HandleInterfaceDisconnection( - mojom::NavigationClientAssociatedPtr* navigation_client, + mojo::AssociatedRemote<mojom::NavigationClient>* navigation_client, base::OnceClosure error_handler) { - navigation_client->set_connection_error_handler(std::move(error_handler)); + navigation_client->set_disconnect_handler(std::move(error_handler)); } void NavigationRequest::IgnoreInterfaceDisconnection() { - return request_navigation_client_.set_connection_error_handler( - base::DoNothing()); + return request_navigation_client_.set_disconnect_handler(base::DoNothing()); } void NavigationRequest::IgnoreCommitInterfaceDisconnection() { - return commit_navigation_client_.set_connection_error_handler( - base::DoNothing()); + return commit_navigation_client_.set_disconnect_handler(base::DoNothing()); } bool NavigationRequest::IsSameDocument() const { @@ -3082,7 +3079,7 @@ } void NavigationRequest::SetNavigationClient( - mojom::NavigationClientAssociatedPtrInfo navigation_client, + mojo::PendingAssociatedRemote<mojom::NavigationClient> navigation_client, int32_t associated_site_instance_id) { DCHECK(from_begin_navigation_ || common_params_->is_history_navigation_in_new_child_frame); @@ -3090,7 +3087,7 @@ if (!navigation_client.is_valid()) return; - request_navigation_client_ = mojom::NavigationClientAssociatedPtr(); + request_navigation_client_.reset(); request_navigation_client_.Bind(std::move(navigation_client)); // Binds the OnAbort callback
diff --git a/content/browser/frame_host/navigation_request.h b/content/browser/frame_host/navigation_request.h index b806051..89655bd 100644 --- a/content/browser/frame_host/navigation_request.h +++ b/content/browser/frame_host/navigation_request.h
@@ -30,6 +30,8 @@ #include "content/public/browser/navigation_type.h" #include "content/public/browser/render_process_host_observer.h" #include "content/public/common/previews_state.h" +#include "mojo/public/cpp/bindings/associated_remote.h" +#include "mojo/public/cpp/bindings/pending_associated_remote.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/system/data_pipe.h" #include "net/base/proxy_server.h" @@ -156,7 +158,7 @@ int current_history_list_length, bool override_user_agent, scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory, - mojom::NavigationClientAssociatedPtrInfo navigation_client, + mojo::PendingAssociatedRemote<mojom::NavigationClient> navigation_client, mojo::PendingRemote<blink::mojom::NavigationInitiator> navigation_initiator, scoped_refptr<PrefetchedSignedExchangeCache> @@ -449,7 +451,7 @@ // navigation in a subframe. This allows a browser-initiated NavigationRequest // to be canceled by the renderer. void SetNavigationClient( - mojom::NavigationClientAssociatedPtrInfo navigation_client, + mojo::PendingAssociatedRemote<mojom::NavigationClient> navigation_client, int32_t associated_site_instance_id); // Whether the new document created by this navigation will be loaded from a @@ -538,20 +540,21 @@ private: friend class NavigationRequestTest; - NavigationRequest(FrameTreeNode* frame_tree_node, - mojom::CommonNavigationParamsPtr common_params, - mojom::BeginNavigationParamsPtr begin_params, - mojom::CommitNavigationParamsPtr commit_params, - bool browser_initiated, - bool from_begin_navigation, - bool is_for_commit, - const FrameNavigationEntry* frame_navigation_entry, - NavigationEntryImpl* navitation_entry, - std::unique_ptr<NavigationUIData> navigation_ui_data, - mojom::NavigationClientAssociatedPtrInfo navigation_client, - mojo::PendingRemote<blink::mojom::NavigationInitiator> - navigation_initiator, - RenderFrameHostImpl* rfh_restored_from_back_forward_cache); + NavigationRequest( + FrameTreeNode* frame_tree_node, + mojom::CommonNavigationParamsPtr common_params, + mojom::BeginNavigationParamsPtr begin_params, + mojom::CommitNavigationParamsPtr commit_params, + bool browser_initiated, + bool from_begin_navigation, + bool is_for_commit, + const FrameNavigationEntry* frame_navigation_entry, + NavigationEntryImpl* navitation_entry, + std::unique_ptr<NavigationUIData> navigation_ui_data, + mojo::PendingAssociatedRemote<mojom::NavigationClient> navigation_client, + mojo::PendingRemote<blink::mojom::NavigationInitiator> + navigation_initiator, + RenderFrameHostImpl* rfh_restored_from_back_forward_cache); // NavigationURLLoaderDelegate implementation. void OnRequestRedirected( @@ -682,8 +685,9 @@ // Binds the given error_handler to be called when an interface disconnection // happens on the renderer side. // Only used with PerNavigationMojoInterface enabled. - void HandleInterfaceDisconnection(mojom::NavigationClientAssociatedPtr*, - base::OnceClosure error_handler); + void HandleInterfaceDisconnection( + mojo::AssociatedRemote<mojom::NavigationClient>*, + base::OnceClosure error_handler); // When called, this NavigationRequest will no longer interpret the interface // disconnection on the renderer side as an AbortNavigation. @@ -962,14 +966,14 @@ // case of a renderer initiated navigation. It is expected to be bound until // this navigation commits or is canceled. // Only valid when PerNavigationMojoInterface is enabled. - mojom::NavigationClientAssociatedPtr request_navigation_client_; + mojo::AssociatedRemote<mojom::NavigationClient> request_navigation_client_; base::Optional<int32_t> associated_site_instance_id_; // The NavigationClient interface used to commit the navigation. For now, this // is only used for same-site renderer-initiated navigation. // TODO(clamy, ahemery): Extend to all types of navigation. // Only valid when PerNavigationMojoInterface is enabled. - mojom::NavigationClientAssociatedPtr commit_navigation_client_; + mojo::AssociatedRemote<mojom::NavigationClient> commit_navigation_client_; // If set, any redirects to HTTP for this navigation will be upgraded to // HTTPS. This is used only on subframe navigations, when
diff --git a/content/browser/frame_host/navigator.cc b/content/browser/frame_host/navigator.cc index b1006648..d16c21b 100644 --- a/content/browser/frame_host/navigator.cc +++ b/content/browser/frame_host/navigator.cc
@@ -19,7 +19,7 @@ bool Navigator::StartHistoryNavigationInNewSubframe( RenderFrameHostImpl* render_frame_host, - mojom::NavigationClientAssociatedPtrInfo* navigation_client) { + mojo::PendingAssociatedRemote<mojom::NavigationClient>* navigation_client) { return false; } @@ -32,7 +32,7 @@ mojom::CommonNavigationParamsPtr common_params, mojom::BeginNavigationParamsPtr begin_params, scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory, - mojom::NavigationClientAssociatedPtrInfo navigation_client, + mojo::PendingAssociatedRemote<mojom::NavigationClient> navigation_client, mojo::PendingRemote<blink::mojom::NavigationInitiator> navigation_initiator, scoped_refptr<PrefetchedSignedExchangeCache> prefetched_signed_exchange_cache) {}
diff --git a/content/browser/frame_host/navigator.h b/content/browser/frame_host/navigator.h index cea80e7..73c75d2 100644 --- a/content/browser/frame_host/navigator.h +++ b/content/browser/frame_host/navigator.h
@@ -13,6 +13,7 @@ #include "content/common/content_export.h" #include "content/common/navigation_params.mojom.h" #include "content/public/browser/navigation_controller.h" +#include "mojo/public/cpp/bindings/pending_associated_remote.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "third_party/blink/public/web/web_triggering_event_info.h" #include "ui/base/window_open_disposition.h" @@ -86,7 +87,8 @@ // FrameNavigationEntry can't be found or the navigation fails. virtual bool StartHistoryNavigationInNewSubframe( RenderFrameHostImpl* render_frame_host, - mojom::NavigationClientAssociatedPtrInfo* navigation_client); + mojo::PendingAssociatedRemote<mojom::NavigationClient>* + navigation_client); // Navigation requests ------------------------------------------------------- @@ -150,7 +152,7 @@ mojom::CommonNavigationParamsPtr common_params, mojom::BeginNavigationParamsPtr begin_params, scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory, - mojom::NavigationClientAssociatedPtrInfo navigation_client, + mojo::PendingAssociatedRemote<mojom::NavigationClient> navigation_client, mojo::PendingRemote<blink::mojom::NavigationInitiator> navigation_initiator, scoped_refptr<PrefetchedSignedExchangeCache>
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc index a781313e..6a17a0e8 100644 --- a/content/browser/frame_host/navigator_impl.cc +++ b/content/browser/frame_host/navigator_impl.cc
@@ -196,7 +196,7 @@ bool NavigatorImpl::StartHistoryNavigationInNewSubframe( RenderFrameHostImpl* render_frame_host, - mojom::NavigationClientAssociatedPtrInfo* navigation_client) { + mojo::PendingAssociatedRemote<mojom::NavigationClient>* navigation_client) { return controller_->StartHistoryNavigationInNewSubframe(render_frame_host, navigation_client); } @@ -618,7 +618,7 @@ mojom::CommonNavigationParamsPtr common_params, mojom::BeginNavigationParamsPtr begin_params, scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory, - mojom::NavigationClientAssociatedPtrInfo navigation_client, + mojo::PendingAssociatedRemote<mojom::NavigationClient> navigation_client, mojo::PendingRemote<blink::mojom::NavigationInitiator> navigation_initiator, scoped_refptr<PrefetchedSignedExchangeCache> prefetched_signed_exchange_cache) {
diff --git a/content/browser/frame_host/navigator_impl.h b/content/browser/frame_host/navigator_impl.h index b941c0c..fce48a9 100644 --- a/content/browser/frame_host/navigator_impl.h +++ b/content/browser/frame_host/navigator_impl.h
@@ -57,7 +57,8 @@ bool was_within_same_document) override; bool StartHistoryNavigationInNewSubframe( RenderFrameHostImpl* render_frame_host, - mojom::NavigationClientAssociatedPtrInfo* navigation_client) override; + mojo::PendingAssociatedRemote<mojom::NavigationClient>* navigation_client) + override; void Navigate(std::unique_ptr<NavigationRequest> request, ReloadType reload_type, RestoreType restore_type) override; @@ -97,7 +98,7 @@ mojom::CommonNavigationParamsPtr common_params, mojom::BeginNavigationParamsPtr begin_params, scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory, - mojom::NavigationClientAssociatedPtrInfo navigation_client, + mojo::PendingAssociatedRemote<mojom::NavigationClient> navigation_client, mojo::PendingRemote<blink::mojom::NavigationInitiator> navigation_initiator, scoped_refptr<PrefetchedSignedExchangeCache>
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index e26fe6c..d830756 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -174,12 +174,9 @@ #include "media/mojo/services/media_interface_provider.h" #include "media/mojo/services/media_metrics_provider.h" #include "media/mojo/services/video_decode_perf_history.h" -#include "mojo/public/cpp/bindings/associated_remote.h" #include "mojo/public/cpp/bindings/interface_request.h" #include "mojo/public/cpp/bindings/message.h" #include "mojo/public/cpp/bindings/pending_associated_remote.h" -#include "mojo/public/cpp/bindings/pending_receiver.h" -#include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/self_owned_receiver.h" #include "mojo/public/cpp/bindings/strong_binding.h" #include "mojo/public/cpp/system/data_pipe.h" @@ -545,14 +542,14 @@ mojom::CommonNavigationParamsPtr common_params; mojom::BeginNavigationParamsPtr begin_navigation_params; scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory; - mojom::NavigationClientAssociatedPtrInfo navigation_client; + mojo::PendingAssociatedRemote<mojom::NavigationClient> navigation_client; mojo::PendingRemote<blink::mojom::NavigationInitiator> navigation_initiator; PendingNavigation( mojom::CommonNavigationParamsPtr common_params, mojom::BeginNavigationParamsPtr begin_navigation_params, scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory, - mojom::NavigationClientAssociatedPtrInfo navigation_client, + mojo::PendingAssociatedRemote<mojom::NavigationClient> navigation_client, mojo::PendingRemote<blink::mojom::NavigationInitiator> navigation_initiator); }; @@ -561,7 +558,7 @@ mojom::CommonNavigationParamsPtr common_params, mojom::BeginNavigationParamsPtr begin_navigation_params, scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory, - mojom::NavigationClientAssociatedPtrInfo navigation_client, + mojo::PendingAssociatedRemote<mojom::NavigationClient> navigation_client, mojo::PendingRemote<blink::mojom::NavigationInitiator> navigation_initiator) : common_params(std::move(common_params)), begin_navigation_params(std::move(begin_navigation_params)), @@ -889,8 +886,9 @@ weak_ptr_factory_.GetWeakPtr()))); if (widget_routing_id != MSG_ROUTING_NONE) { - mojom::WidgetPtr widget; - GetRemoteInterfaces()->GetInterface(&widget); + mojo::PendingRemote<mojom::Widget> widget; + GetRemoteInterfaces()->GetInterface( + widget.InitWithNewPipeAndPassReceiver()); if (!parent_) { // For main frames, the RenderWidgetHost is owned by the RenderViewHost. @@ -1949,8 +1947,9 @@ } if (created && GetLocalRenderWidgetHost()) { - mojom::WidgetPtr widget; - GetRemoteInterfaces()->GetInterface(&widget); + mojo::PendingRemote<mojom::Widget> widget; + GetRemoteInterfaces()->GetInterface( + widget.InitWithNewPipeAndPassReceiver()); GetLocalRenderWidgetHost()->SetWidget(std::move(widget)); GetLocalRenderWidgetHost()->SetFrameInputHandler( frame_input_handler_.get()); @@ -4181,7 +4180,7 @@ mojom::CommonNavigationParamsPtr common_params, mojom::BeginNavigationParamsPtr begin_params, mojo::PendingRemote<blink::mojom::BlobURLToken> blob_url_token, - mojom::NavigationClientAssociatedPtrInfo navigation_client, + mojo::PendingAssociatedRemote<mojom::NavigationClient> navigation_client, mojo::PendingRemote<blink::mojom::NavigationInitiator> navigation_initiator) { if (frame_tree_node_->render_manager()->is_attaching_inner_delegate()) { @@ -5944,11 +5943,11 @@ return result; } -mojom::NavigationClientAssociatedPtr +mojo::AssociatedRemote<mojom::NavigationClient> RenderFrameHostImpl::GetNavigationClientFromInterfaceProvider() { - mojom::NavigationClientAssociatedPtr navigation_client_ptr; - GetRemoteAssociatedInterfaces()->GetInterface(&navigation_client_ptr); - return navigation_client_ptr; + mojo::AssociatedRemote<mojom::NavigationClient> navigation_client_remote; + GetRemoteAssociatedInterfaces()->GetInterface(&navigation_client_remote); + return navigation_client_remote; } void RenderFrameHostImpl::NavigationRequestCancelled(
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index 2ddbd6d..988fcb43 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -58,6 +58,7 @@ #include "content/public/common/transferrable_url_loader.mojom.h" #include "media/mojo/mojom/interface_factory.mojom.h" #include "mojo/public/cpp/bindings/associated_remote.h" +#include "mojo/public/cpp/bindings/pending_associated_remote.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h" @@ -921,9 +922,9 @@ bool was_granted_media_access() { return was_granted_media_access_; } // Request a new NavigationClient interface from the renderer and returns the - // ownership of the AssociatedPtr. This is intended for use by the + // ownership of the mojo::AssociatedRemote. This is intended for use by the // NavigationRequest. Only used with PerNavigationMojoInterface enabled. - mojom::NavigationClientAssociatedPtr + mojo::AssociatedRemote<mojom::NavigationClient> GetNavigationClientFromInterfaceProvider(); // Called to signify the RenderFrameHostImpl that one of its ongoing @@ -1344,7 +1345,7 @@ mojom::CommonNavigationParamsPtr common_params, mojom::BeginNavigationParamsPtr begin_params, mojo::PendingRemote<blink::mojom::BlobURLToken> blob_url_token, - mojom::NavigationClientAssociatedPtrInfo navigation_client, + mojo::PendingAssociatedRemote<mojom::NavigationClient> navigation_client, mojo::PendingRemote<blink::mojom::NavigationInitiator> navigation_initiator) override; void SubresourceResponseStarted(const GURL& url,
diff --git a/content/browser/frame_host/render_widget_host_view_guest_unittest.cc b/content/browser/frame_host/render_widget_host_view_guest_unittest.cc index bcf22d5..e05d21e 100644 --- a/content/browser/frame_host/render_widget_host_view_guest_unittest.cc +++ b/content/browser/frame_host/render_widget_host_view_guest_unittest.cc
@@ -32,6 +32,7 @@ #include "content/test/mock_widget_impl.h" #include "content/test/test_render_view_host.h" #include "content/test/test_web_contents.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/ui_base_features.h" #include "ui/compositor/compositor.h" @@ -52,8 +53,9 @@ MockRenderProcessHost* process_host = new MockRenderProcessHost(browser_context_.get()); int32_t routing_id = process_host->GetNextRoutingID(); - mojom::WidgetPtr widget; - widget_impl_ = std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget)); + mojo::PendingRemote<mojom::Widget> widget; + widget_impl_ = std::make_unique<MockWidgetImpl>( + widget.InitWithNewPipeAndPassReceiver()); widget_host_ = new RenderWidgetHostImpl( &delegate_, process_host, routing_id, std::move(widget), false); @@ -138,8 +140,9 @@ web_contents_.get(), &browser_plugin_guest_delegate_); int32_t routing_id = process_host->GetNextRoutingID(); - mojom::WidgetPtr widget; - widget_impl_ = std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget)); + mojo::PendingRemote<mojom::Widget> widget; + widget_impl_ = std::make_unique<MockWidgetImpl>( + widget.InitWithNewPipeAndPassReceiver()); widget_host_ = new RenderWidgetHostImpl( &delegate_, process_host, routing_id, std::move(widget), false);
diff --git a/content/browser/histogram_controller.cc b/content/browser/histogram_controller.cc index 63a2051..789144c 100644 --- a/content/browser/histogram_controller.cc +++ b/content/browser/histogram_controller.cc
@@ -101,12 +101,18 @@ void HistogramController::SetHistogramMemory( T* host, base::WritableSharedMemoryRegion shared_region) { - content::mojom::ChildHistogramFetcherFactoryPtr - child_histogram_fetcher_factory; - content::mojom::ChildHistogramFetcherPtr child_histogram_fetcher; - content::BindInterface(host, &child_histogram_fetcher_factory); + mojo::PendingRemote<content::mojom::ChildHistogramFetcherFactory> + pending_child_histogram_fetcher_factory; + content::BindInterface(host, &pending_child_histogram_fetcher_factory); + + mojo::Remote<content::mojom::ChildHistogramFetcherFactory> + child_histogram_fetcher_factory( + std::move(pending_child_histogram_fetcher_factory)); + mojo::Remote<content::mojom::ChildHistogramFetcher> child_histogram_fetcher; + child_histogram_fetcher_factory->CreateFetcher( - std::move(shared_region), mojo::MakeRequest(&child_histogram_fetcher)); + std::move(shared_region), + child_histogram_fetcher.BindNewPipeAndPassReceiver()); InsertChildHistogramFetcherInterface(host, std::move(child_histogram_fetcher)); } @@ -114,10 +120,11 @@ template <class T> void HistogramController::InsertChildHistogramFetcherInterface( T* host, - content::mojom::ChildHistogramFetcherPtr child_histogram_fetcher) { + mojo::Remote<content::mojom::ChildHistogramFetcher> + child_histogram_fetcher) { // Broken pipe means remove this from the map. The map size is a proxy for // the number of known processes - child_histogram_fetcher.set_connection_error_handler(base::BindOnce( + child_histogram_fetcher.set_disconnect_handler(base::BindOnce( &HistogramController::RemoveChildHistogramFetcherInterface<T>, base::Unretained(this), base::Unretained(host))); GetChildHistogramFetcherMap<T>()[host] = std::move(child_histogram_fetcher);
diff --git a/content/browser/histogram_controller.h b/content/browser/histogram_controller.h index 76bb24c..5e123e9e 100644 --- a/content/browser/histogram_controller.h +++ b/content/browser/histogram_controller.h
@@ -13,6 +13,7 @@ #include "base/memory/singleton.h" #include "base/memory/writable_shared_memory_region.h" #include "content/common/histogram_fetcher.mojom.h" +#include "mojo/public/cpp/bindings/remote.h" namespace content { @@ -80,12 +81,13 @@ template <class T> using ChildHistogramFetcherMap = - std::map<T*, content::mojom::ChildHistogramFetcherPtr>; + std::map<T*, mojo::Remote<content::mojom::ChildHistogramFetcher>>; template <class T> void InsertChildHistogramFetcherInterface( T* host, - content::mojom::ChildHistogramFetcherPtr child_histogram_fetcher); + mojo::Remote<content::mojom::ChildHistogramFetcher> + child_histogram_fetcher); template <class T> content::mojom::ChildHistogramFetcher* GetChildHistogramFetcherInterface(
diff --git a/content/browser/loader/cors_file_origin_browsertest.cc b/content/browser/loader/cors_file_origin_browsertest.cc index 5bf96e6..3fe27e2 100644 --- a/content/browser/loader/cors_file_origin_browsertest.cc +++ b/content/browser/loader/cors_file_origin_browsertest.cc
@@ -13,7 +13,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/synchronization/waitable_event.h" #include "base/test/scoped_command_line.h" -#include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" @@ -31,7 +30,6 @@ #include "net/test/embedded_test_server/http_response.h" #include "net/test/embedded_test_server/request_handler_util.h" #include "services/network/public/cpp/cors/cors.h" -#include "services/network/public/cpp/features.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -45,33 +43,13 @@ using net::test_server::HttpRequest; using net::test_server::HttpResponse; -enum class CorsTestMode { - kInBlink, - kInNetworkService, -}; - // Tests end to end Origin header and CORS check behaviors without // --allow-file-access-from-files flag. -class CorsFileOriginBrowserTest - : public ContentBrowserTest, - public testing::WithParamInterface<CorsTestMode> { +class CorsFileOriginBrowserTest : public ContentBrowserTest { public: CorsFileOriginBrowserTest() : pass_string_(base::ASCIIToUTF16("PASS")), - fail_string_(base::ASCIIToUTF16("FAIL")) { - switch (GetParam()) { - case CorsTestMode::kInBlink: - scoped_feature_list_.InitWithFeatures( - {} /* enabled */, - {network::features::kOutOfBlinkCors} /* disabled */); - break; - case CorsTestMode::kInNetworkService: - scoped_feature_list_.InitWithFeatures( - {network::features::kOutOfBlinkCors} /* enabled */, - {} /*disabled */); - break; - } - } + fail_string_(base::ASCIIToUTF16("FAIL")) {} ~CorsFileOriginBrowserTest() override = default; protected: @@ -193,9 +171,6 @@ const base::string16 pass_string_; const base::string16 fail_string_; - base::test::ScopedFeatureList scoped_command_line_; - base::test::ScopedFeatureList scoped_feature_list_; - DISALLOW_COPY_AND_ASSIGN(CorsFileOriginBrowserTest); }; @@ -216,7 +191,7 @@ bool IsWebSecurityEnabled() const override { return false; } }; -IN_PROC_BROWSER_TEST_P(CorsFileOriginBrowserTest, +IN_PROC_BROWSER_TEST_F(CorsFileOriginBrowserTest, AccessControlAllowOriginIsNull) { std::unique_ptr<TitleWatcher> watcher = CreateWatcher(); EXPECT_TRUE(NavigateToURL( @@ -229,7 +204,7 @@ EXPECT_TRUE(is_preflight_requested()); } -IN_PROC_BROWSER_TEST_P(CorsFileOriginBrowserTest, +IN_PROC_BROWSER_TEST_F(CorsFileOriginBrowserTest, AccessControlAllowOriginIsFile) { std::unique_ptr<TitleWatcher> watcher = CreateWatcher(); EXPECT_TRUE(NavigateToURL( @@ -242,7 +217,7 @@ EXPECT_TRUE(is_preflight_requested()); } -IN_PROC_BROWSER_TEST_P(CorsFileOriginBrowserTest, AccessToSelfFileUrl) { +IN_PROC_BROWSER_TEST_F(CorsFileOriginBrowserTest, AccessToSelfFileUrl) { std::unique_ptr<TitleWatcher> watcher = CreateWatcher(); EXPECT_TRUE(NavigateToURL( shell(), @@ -253,7 +228,7 @@ EXPECT_EQ(fail_string(), watcher->WaitAndGetTitle()); } -IN_PROC_BROWSER_TEST_P(CorsFileOriginBrowserTest, AccessToAnotherFileUrl) { +IN_PROC_BROWSER_TEST_F(CorsFileOriginBrowserTest, AccessToAnotherFileUrl) { std::unique_ptr<TitleWatcher> watcher = CreateWatcher(); EXPECT_TRUE(NavigateToURL( shell(), @@ -271,7 +246,7 @@ #else #define MAYBE_UniversalAccessFromFileUrls UniversalAccessFromFileUrls #endif -IN_PROC_BROWSER_TEST_P(CorsFileOriginBrowserTest, +IN_PROC_BROWSER_TEST_F(CorsFileOriginBrowserTest, MAYBE_UniversalAccessFromFileUrls) { const char* kScript = R"( fetch($1) @@ -301,7 +276,7 @@ EXPECT_THAT(fetch_result, ::testing::HasSubstr("This page has a title")); } -IN_PROC_BROWSER_TEST_P(CorsFileOriginBrowserTestWithAllowFileAccessFromFiles, +IN_PROC_BROWSER_TEST_F(CorsFileOriginBrowserTestWithAllowFileAccessFromFiles, AccessControlAllowOriginIsNull) { std::unique_ptr<TitleWatcher> watcher = CreateWatcher(); EXPECT_TRUE(NavigateToURL( @@ -314,7 +289,7 @@ EXPECT_TRUE(is_preflight_requested()); } -IN_PROC_BROWSER_TEST_P(CorsFileOriginBrowserTestWithAllowFileAccessFromFiles, +IN_PROC_BROWSER_TEST_F(CorsFileOriginBrowserTestWithAllowFileAccessFromFiles, AccessControlAllowOriginIsFile) { std::unique_ptr<TitleWatcher> watcher = CreateWatcher(); EXPECT_TRUE(NavigateToURL( @@ -327,7 +302,7 @@ EXPECT_TRUE(is_preflight_requested()); } -IN_PROC_BROWSER_TEST_P(CorsFileOriginBrowserTestWithAllowFileAccessFromFiles, +IN_PROC_BROWSER_TEST_F(CorsFileOriginBrowserTestWithAllowFileAccessFromFiles, AccessToSelfFileUrl) { std::unique_ptr<TitleWatcher> watcher = CreateWatcher(); EXPECT_TRUE(NavigateToURL( @@ -339,7 +314,7 @@ EXPECT_EQ(pass_string(), watcher->WaitAndGetTitle()); } -IN_PROC_BROWSER_TEST_P(CorsFileOriginBrowserTestWithAllowFileAccessFromFiles, +IN_PROC_BROWSER_TEST_F(CorsFileOriginBrowserTestWithAllowFileAccessFromFiles, AccessToAnotherFileUrl) { std::unique_ptr<TitleWatcher> watcher = CreateWatcher(); EXPECT_TRUE(NavigateToURL( @@ -351,7 +326,7 @@ EXPECT_EQ(pass_string(), watcher->WaitAndGetTitle()); } -IN_PROC_BROWSER_TEST_P(CorsFileOriginBrowserTestWithDisableWebSecurity, +IN_PROC_BROWSER_TEST_F(CorsFileOriginBrowserTestWithDisableWebSecurity, AccessControlAllowOriginIsNull) { std::unique_ptr<TitleWatcher> watcher = CreateWatcher(); EXPECT_TRUE(NavigateToURL( @@ -364,7 +339,7 @@ EXPECT_FALSE(is_preflight_requested()); } -IN_PROC_BROWSER_TEST_P(CorsFileOriginBrowserTestWithDisableWebSecurity, +IN_PROC_BROWSER_TEST_F(CorsFileOriginBrowserTestWithDisableWebSecurity, AccessControlAllowOriginIsFile) { std::unique_ptr<TitleWatcher> watcher = CreateWatcher(); EXPECT_TRUE(NavigateToURL( @@ -377,7 +352,7 @@ EXPECT_FALSE(is_preflight_requested()); } -IN_PROC_BROWSER_TEST_P(CorsFileOriginBrowserTestWithDisableWebSecurity, +IN_PROC_BROWSER_TEST_F(CorsFileOriginBrowserTestWithDisableWebSecurity, AccessToSelfFileUrl) { std::unique_ptr<TitleWatcher> watcher = CreateWatcher(); EXPECT_TRUE(NavigateToURL( @@ -389,7 +364,7 @@ EXPECT_EQ(pass_string(), watcher->WaitAndGetTitle()); } -IN_PROC_BROWSER_TEST_P(CorsFileOriginBrowserTestWithDisableWebSecurity, +IN_PROC_BROWSER_TEST_F(CorsFileOriginBrowserTestWithDisableWebSecurity, AccessToAnotherFileUrl) { std::unique_ptr<TitleWatcher> watcher = CreateWatcher(); EXPECT_TRUE(NavigateToURL( @@ -401,24 +376,6 @@ EXPECT_EQ(pass_string(), watcher->WaitAndGetTitle()); } -INSTANTIATE_TEST_SUITE_P( - /* No test prefix */, - CorsFileOriginBrowserTest, - ::testing::Values(CorsTestMode::kInBlink, - CorsTestMode::kInNetworkService)); - -INSTANTIATE_TEST_SUITE_P( - /* No test prefix */, - CorsFileOriginBrowserTestWithAllowFileAccessFromFiles, - ::testing::Values(CorsTestMode::kInBlink, - CorsTestMode::kInNetworkService)); - -INSTANTIATE_TEST_SUITE_P( - /* No test prefix */, - CorsFileOriginBrowserTestWithDisableWebSecurity, - ::testing::Values(CorsTestMode::kInBlink, - CorsTestMode::kInNetworkService)); - } // namespace } // namespace content
diff --git a/content/browser/loader/cors_preflight_cache_browsertest.cc b/content/browser/loader/cors_preflight_cache_browsertest.cc index 0e90196..b6a07af 100644 --- a/content/browser/loader/cors_preflight_cache_browsertest.cc +++ b/content/browser/loader/cors_preflight_cache_browsertest.cc
@@ -9,7 +9,6 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/synchronization/lock.h" -#include "base/test/scoped_feature_list.h" #include "base/thread_annotations.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/content_browser_test.h" @@ -34,10 +33,7 @@ // Tests end to end behaviors on CORS preflight and its cache. class CorsPreflightCacheBrowserTest : public ContentBrowserTest { protected: - CorsPreflightCacheBrowserTest() { - scoped_feature_list_.InitWithFeatures({network::features::kOutOfBlinkCors}, - {}); - } + CorsPreflightCacheBrowserTest() = default; ~CorsPreflightCacheBrowserTest() override = default; void SetUpOnMainThread() override { @@ -84,7 +80,6 @@ return response; } - base::test::ScopedFeatureList scoped_feature_list_; net::EmbeddedTestServer cross_origin_test_server_; base::Lock lock_; @@ -104,6 +99,7 @@ EXPECT_EQ(1u, options_count()); EXPECT_EQ(1u, get_count()); + // Make another fetch request, and OPTIONS request hits the preflight cache. std::unique_ptr<TitleWatcher> watcher2 = std::make_unique<TitleWatcher>(shell()->web_contents(), kTestDone); EXPECT_TRUE(NavigateToURL( @@ -113,13 +109,16 @@ EXPECT_EQ(1u, options_count()); EXPECT_EQ(2u, get_count()); + // Make another fetch request with reload cache mode, and it should not hit + // the preflight cache. Only OOR-CORS mode take the cache mode count in. std::unique_ptr<TitleWatcher> watcher3 = std::make_unique<TitleWatcher>(shell()->web_contents(), kTestDone); EXPECT_TRUE(NavigateToURL( shell(), embedded_test_server()->GetURL(base::StringPrintf( "%s?;%d;reload", kTestPath, cross_origin_port())))); EXPECT_EQ(kTestDone, watcher3->WaitAndGetTitle()); - EXPECT_EQ(2u, options_count()); + EXPECT_EQ(network::features::ShouldEnableOutOfBlinkCors() ? 2u : 1u, + options_count()); EXPECT_EQ(3u, get_count()); }
diff --git a/content/browser/loader/cross_site_document_blocking_browsertest.cc b/content/browser/loader/cross_site_document_blocking_browsertest.cc index bfdc53f..e30ad2e 100644 --- a/content/browser/loader/cross_site_document_blocking_browsertest.cc +++ b/content/browser/loader/cross_site_document_blocking_browsertest.cc
@@ -506,8 +506,7 @@ }; enum class TestMode { - kWithoutOutOfBlinkCors, - kWithOutOfBlinkCors, + kWithCORBProtectionSniffing, kWithoutCORBProtectionSniffing, }; class CrossSiteDocumentBlockingTest @@ -516,17 +515,14 @@ public: CrossSiteDocumentBlockingTest() { switch (GetParam()) { - case TestMode::kWithoutOutOfBlinkCors: - scoped_feature_list_.InitAndDisableFeature( - network::features::kOutOfBlinkCors); - break; - case TestMode::kWithOutOfBlinkCors: + case TestMode::kWithCORBProtectionSniffing: scoped_feature_list_.InitAndEnableFeature( - network::features::kOutOfBlinkCors); + network::features::kCORBProtectionSniffing); break; case TestMode::kWithoutCORBProtectionSniffing: scoped_feature_list_.InitAndDisableFeature( network::features::kCORBProtectionSniffing); + break; } } ~CrossSiteDocumentBlockingTest() override = default; @@ -1479,13 +1475,10 @@ } } -INSTANTIATE_TEST_SUITE_P(WithoutOutOfBlinkCors, - CrossSiteDocumentBlockingTest, - ::testing::Values(TestMode::kWithoutOutOfBlinkCors)); - -INSTANTIATE_TEST_SUITE_P(WithOutOfBlinkCors, - CrossSiteDocumentBlockingTest, - ::testing::Values(TestMode::kWithOutOfBlinkCors)); +INSTANTIATE_TEST_SUITE_P( + WithCORBProtectionSniffing, + CrossSiteDocumentBlockingTest, + ::testing::Values(TestMode::kWithCORBProtectionSniffing)); INSTANTIATE_TEST_SUITE_P( WithoutCORBProtectionSniffing,
diff --git a/content/browser/navigation_browsertest.cc b/content/browser/navigation_browsertest.cc index 83e5bdc..1c45e64 100644 --- a/content/browser/navigation_browsertest.cc +++ b/content/browser/navigation_browsertest.cc
@@ -55,8 +55,8 @@ #include "content/test/content_browser_test_utils_internal.h" #include "content/test/did_commit_navigation_interceptor.h" #include "ipc/ipc_security_test_util.h" +#include "mojo/public/cpp/bindings/pending_associated_remote.h" #include "mojo/public/cpp/bindings/pending_receiver.h" -#include "mojo/public/cpp/bindings/pending_remote.h" #include "net/base/features.h" #include "net/base/filename_util.h" #include "net/base/load_flags.h" @@ -771,17 +771,17 @@ // termination. RenderProcessHostKillWaiter process_kill_waiter(rfh->GetProcess()); - mojom::NavigationClientAssociatedPtr navigation_client; + mojo::PendingAssociatedRemote<mojom::NavigationClient> navigation_client; if (IsPerNavigationMojoInterfaceEnabled()) { - auto navigation_client_request = - mojo::MakeRequestAssociatedWithDedicatedPipe(&navigation_client); + auto navigation_client_receiver = + navigation_client.InitWithNewEndpointAndPassReceiver(); rfh->frame_host_binding_for_testing().impl()->BeginNavigation( std::move(common_params), std::move(begin_params), mojo::NullRemote(), - navigation_client.PassInterface(), mojo::NullRemote()); + std::move(navigation_client), mojo::NullRemote()); } else { rfh->frame_host_binding_for_testing().impl()->BeginNavigation( std::move(common_params), std::move(begin_params), mojo::NullRemote(), - nullptr, mojo::NullRemote()); + mojo::NullAssociatedRemote(), mojo::NullRemote()); } EXPECT_EQ(bad_message::RFH_BASE_URL_FOR_DATA_URL_SPECIFIED, process_kill_waiter.Wait());
diff --git a/content/browser/renderer_host/cursor_manager_unittest.cc b/content/browser/renderer_host/cursor_manager_unittest.cc index 42ba564..e65b24a7 100644 --- a/content/browser/renderer_host/cursor_manager_unittest.cc +++ b/content/browser/renderer_host/cursor_manager_unittest.cc
@@ -16,6 +16,7 @@ #include "content/test/mock_render_widget_host_delegate.h" #include "content/test/mock_widget_impl.h" #include "content/test/test_render_view_host.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "testing/gtest/include/gtest/gtest.h" // CursorManager is only instantiated on Aura and Mac. @@ -51,9 +52,10 @@ static MockRenderWidgetHost* Create(RenderWidgetHostDelegate* delegate, RenderProcessHost* process, int32_t routing_id) { - mojom::WidgetPtr widget; + mojo::PendingRemote<mojom::Widget> widget; std::unique_ptr<MockWidgetImpl> widget_impl = - std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget)); + std::make_unique<MockWidgetImpl>( + widget.InitWithNewPipeAndPassReceiver()); return new MockRenderWidgetHost(delegate, process, routing_id, std::move(widget_impl), std::move(widget)); @@ -64,7 +66,7 @@ RenderProcessHost* process, int routing_id, std::unique_ptr<MockWidgetImpl> widget_impl, - mojom::WidgetPtr widget) + mojo::PendingRemote<mojom::Widget> widget) : RenderWidgetHostImpl(delegate, process, routing_id,
diff --git a/content/browser/renderer_host/input/mouse_latency_browsertest.cc b/content/browser/renderer_host/input/mouse_latency_browsertest.cc index 41ffc93..ec25374 100644 --- a/content/browser/renderer_host/input/mouse_latency_browsertest.cc +++ b/content/browser/renderer_host/input/mouse_latency_browsertest.cc
@@ -29,6 +29,7 @@ #include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test_utils.h" #include "content/shell/browser/shell.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "testing/gmock/include/gmock/gmock.h" namespace { @@ -77,7 +78,7 @@ TracingRenderWidgetHost(RenderWidgetHostDelegate* delegate, RenderProcessHost* process, int32_t routing_id, - mojom::WidgetPtr widget, + mojo::PendingRemote<mojom::Widget> widget, bool hidden) : RenderWidgetHostImpl(delegate, process, @@ -139,7 +140,7 @@ RenderWidgetHostDelegate* delegate, RenderProcessHost* process, int32_t routing_id, - mojom::WidgetPtr widget_interface, + mojo::PendingRemote<mojom::Widget> widget_interface, bool hidden) override { return std::make_unique<TracingRenderWidgetHost>( delegate, process, routing_id, std::move(widget_interface), hidden);
diff --git a/content/browser/renderer_host/mock_render_widget_host.cc b/content/browser/renderer_host/mock_render_widget_host.cc index 3cfdc06..c3c1b624 100644 --- a/content/browser/renderer_host/mock_render_widget_host.cc +++ b/content/browser/renderer_host/mock_render_widget_host.cc
@@ -81,9 +81,9 @@ RenderWidgetHostDelegate* delegate, RenderProcessHost* process, int32_t routing_id) { - mojom::WidgetPtr widget; + mojo::PendingRemote<mojom::Widget> widget; std::unique_ptr<MockWidgetImpl> widget_impl = - std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget)); + std::make_unique<MockWidgetImpl>(widget.InitWithNewPipeAndPassReceiver()); return new MockRenderWidgetHost(delegate, process, routing_id, std::move(widget_impl), std::move(widget)); @@ -102,7 +102,7 @@ RenderProcessHost* process, int routing_id, std::unique_ptr<MockWidgetImpl> widget_impl, - mojom::WidgetPtr widget) + mojo::PendingRemote<mojom::Widget> widget) : RenderWidgetHostImpl(delegate, process, routing_id,
diff --git a/content/browser/renderer_host/mock_render_widget_host.h b/content/browser/renderer_host/mock_render_widget_host.h index 8e82f2e5..481ec04 100644 --- a/content/browser/renderer_host/mock_render_widget_host.h +++ b/content/browser/renderer_host/mock_render_widget_host.h
@@ -14,6 +14,7 @@ #include "content/public/common/input_event_ack_state.h" #include "content/test/mock_widget_impl.h" #include "content/test/mock_widget_input_handler.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "third_party/blink/public/platform/web_input_event.h" namespace viz { @@ -90,7 +91,7 @@ RenderProcessHost* process, int routing_id, std::unique_ptr<MockWidgetImpl> widget_impl, - mojom::WidgetPtr widget); + mojo::PendingRemote<mojom::Widget> widget); std::unique_ptr<MockWidgetImpl> widget_impl_;
diff --git a/content/browser/renderer_host/render_message_filter.cc b/content/browser/renderer_host/render_message_filter.cc index 1ec165d..cdcdaa2 100644 --- a/content/browser/renderer_host/render_message_filter.cc +++ b/content/browser/renderer_host/render_message_filter.cc
@@ -129,9 +129,10 @@ std::move(callback).Run(render_widget_helper_->GetNextRoutingID()); } -void RenderMessageFilter::CreateNewWidget(int32_t opener_id, - mojom::WidgetPtr widget, - CreateNewWidgetCallback callback) { +void RenderMessageFilter::CreateNewWidget( + int32_t opener_id, + mojo::PendingRemote<mojom::Widget> widget, + CreateNewWidgetCallback callback) { int route_id = MSG_ROUTING_NONE; render_widget_helper_->CreateNewWidget(opener_id, std::move(widget), &route_id); @@ -140,7 +141,7 @@ void RenderMessageFilter::CreateFullscreenWidget( int opener_id, - mojom::WidgetPtr widget, + mojo::PendingRemote<mojom::Widget> widget, CreateFullscreenWidgetCallback callback) { int route_id = 0; render_widget_helper_->CreateNewFullscreenWidget(opener_id, std::move(widget),
diff --git a/content/browser/renderer_host/render_message_filter.h b/content/browser/renderer_host/render_message_filter.h index fec3f04..db421af7 100644 --- a/content/browser/renderer_host/render_message_filter.h +++ b/content/browser/renderer_host/render_message_filter.h
@@ -25,6 +25,7 @@ #include "content/public/common/widget_type.h" #include "gpu/config/gpu_info.h" #include "ipc/message_filter.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/gpu_memory_buffer.h" @@ -80,10 +81,10 @@ // mojom::RenderMessageFilter: void GenerateRoutingID(GenerateRoutingIDCallback routing_id) override; void CreateNewWidget(int32_t opener_id, - mojom::WidgetPtr widget, + mojo::PendingRemote<mojom::Widget> widget, CreateNewWidgetCallback callback) override; void CreateFullscreenWidget(int opener_id, - mojom::WidgetPtr widget, + mojo::PendingRemote<mojom::Widget> widget, CreateFullscreenWidgetCallback callback) override; void HasGpuProcess(HasGpuProcessCallback callback) override; #if defined(OS_LINUX)
diff --git a/content/browser/renderer_host/render_view_host_delegate.h b/content/browser/renderer_host/render_view_host_delegate.h index 9a5e428..8aafa18a 100644 --- a/content/browser/renderer_host/render_view_host_delegate.h +++ b/content/browser/renderer_host/render_view_host_delegate.h
@@ -16,6 +16,7 @@ #include "content/common/content_export.h" #include "content/common/render_message_filter.mojom.h" #include "content/common/widget.mojom.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "net/base/load_states.h" class GURL; @@ -132,12 +133,13 @@ // happen in response to ShowCreatedWidget. virtual void CreateNewWidget(int32_t render_process_id, int32_t widget_route_id, - mojom::WidgetPtr widget) {} + mojo::PendingRemote<mojom::Widget> widget) {} // Creates a full screen RenderWidget. Similar to above. - virtual void CreateNewFullscreenWidget(int32_t render_process_id, - int32_t widget_route_id, - mojom::WidgetPtr widget) {} + virtual void CreateNewFullscreenWidget( + int32_t render_process_id, + int32_t widget_route_id, + mojo::PendingRemote<mojom::Widget> widget) {} // Show the newly created widget with the specified bounds. // The widget is identified by the route_id passed to CreateNewWidget.
diff --git a/content/browser/renderer_host/render_view_host_factory.cc b/content/browser/renderer_host/render_view_host_factory.cc index 540a2d61..dde3ad44 100644 --- a/content/browser/renderer_host/render_view_host_factory.cc +++ b/content/browser/renderer_host/render_view_host_factory.cc
@@ -10,6 +10,7 @@ #include "base/memory/ptr_util.h" #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/renderer_host/render_widget_host_factory.h" +#include "mojo/public/cpp/bindings/pending_remote.h" namespace content { @@ -53,7 +54,7 @@ return new RenderViewHostImpl( instance, RenderWidgetHostFactory::Create(widget_delegate, instance->GetProcess(), - widget_routing_id, nullptr, + widget_routing_id, mojo::NullRemote(), /*hidden=*/true), delegate, routing_id, main_frame_routing_id, swapped_out, true /* has_initialized_audio_host */);
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc index d8b8b8d6..82e76d7 100644 --- a/content/browser/renderer_host/render_view_host_impl.cc +++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -855,14 +855,16 @@ ClosePageIgnoringUnloadEvents(); } -void RenderViewHostImpl::CreateNewWidget(int32_t widget_route_id, - mojom::WidgetPtr widget) { +void RenderViewHostImpl::CreateNewWidget( + int32_t widget_route_id, + mojo::PendingRemote<mojom::Widget> widget) { delegate_->CreateNewWidget(GetProcess()->GetID(), widget_route_id, std::move(widget)); } -void RenderViewHostImpl::CreateNewFullscreenWidget(int32_t widget_route_id, - mojom::WidgetPtr widget) { +void RenderViewHostImpl::CreateNewFullscreenWidget( + int32_t widget_route_id, + mojo::PendingRemote<mojom::Widget> widget) { delegate_->CreateNewFullscreenWidget(GetProcess()->GetID(), widget_route_id, std::move(widget)); }
diff --git a/content/browser/renderer_host/render_view_host_impl.h b/content/browser/renderer_host/render_view_host_impl.h index baf1e84..29c5523 100644 --- a/content/browser/renderer_host/render_view_host_impl.h +++ b/content/browser/renderer_host/render_view_host_impl.h
@@ -29,6 +29,7 @@ #include "content/public/browser/notification_observer.h" #include "content/public/browser/render_process_host_observer.h" #include "content/public/browser/render_view_host.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "net/base/load_states.h" #include "third_party/blink/public/web/web_ax_enums.h" #include "third_party/blink/public/web/web_console_message.h" @@ -180,10 +181,12 @@ } // Creates a new RenderWidget with the given route id. - void CreateNewWidget(int32_t route_id, mojom::WidgetPtr widget); + void CreateNewWidget(int32_t route_id, + mojo::PendingRemote<mojom::Widget> widget); // Creates a full screen RenderWidget. - void CreateNewFullscreenWidget(int32_t route_id, mojom::WidgetPtr widget); + void CreateNewFullscreenWidget(int32_t route_id, + mojo::PendingRemote<mojom::Widget> widget); // Send RenderViewReady to observers once the process is launched, but not // re-entrantly.
diff --git a/content/browser/renderer_host/render_view_host_unittest.cc b/content/browser/renderer_host/render_view_host_unittest.cc index ddb920a..31ef4c4 100644 --- a/content/browser/renderer_host/render_view_host_unittest.cc +++ b/content/browser/renderer_host/render_view_host_unittest.cc
@@ -30,6 +30,7 @@ #include "content/test/test_content_browser_client.h" #include "content/test/test_render_view_host.h" #include "content/test/test_web_contents.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "net/base/filename_util.h" #include "third_party/blink/public/platform/web_drag_operation.h" #include "ui/base/page_transition_types.h" @@ -84,9 +85,9 @@ TEST_F(RenderViewHostTest, CreateFullscreenWidget) { int32_t routing_id = process()->GetNextRoutingID(); - mojom::WidgetPtr widget; + mojo::PendingRemote<mojom::Widget> widget; std::unique_ptr<MockWidgetImpl> widget_impl = - std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget)); + std::make_unique<MockWidgetImpl>(widget.InitWithNewPipeAndPassReceiver()); test_rvh()->CreateNewFullscreenWidget(routing_id, std::move(widget)); }
diff --git a/content/browser/renderer_host/render_widget_helper.cc b/content/browser/renderer_host/render_widget_helper.cc index d711d4e..53abb69 100644 --- a/content/browser/renderer_host/render_widget_helper.cc +++ b/content/browser/renderer_host/render_widget_helper.cc
@@ -65,31 +65,32 @@ return (ci == g_widget_helpers.Get().end())? NULL : ci->second; } -void RenderWidgetHelper::CreateNewWidget(int opener_id, - mojom::WidgetPtr widget, - int* route_id) { +void RenderWidgetHelper::CreateNewWidget( + int opener_id, + mojo::PendingRemote<mojom::Widget> widget, + int* route_id) { *route_id = GetNextRoutingID(); base::PostTask(FROM_HERE, {BrowserThread::UI}, base::BindOnce(&RenderWidgetHelper::OnCreateWidgetOnUI, this, - opener_id, *route_id, widget.PassInterface())); + opener_id, *route_id, std::move(widget))); } -void RenderWidgetHelper::CreateNewFullscreenWidget(int opener_id, - mojom::WidgetPtr widget, - int* route_id) { +void RenderWidgetHelper::CreateNewFullscreenWidget( + int opener_id, + mojo::PendingRemote<mojom::Widget> widget, + int* route_id) { *route_id = GetNextRoutingID(); base::PostTask( FROM_HERE, {BrowserThread::UI}, base::BindOnce(&RenderWidgetHelper::OnCreateFullscreenWidgetOnUI, this, - opener_id, *route_id, widget.PassInterface())); + opener_id, *route_id, std::move(widget))); } -void RenderWidgetHelper::OnCreateWidgetOnUI(int32_t opener_id, - int32_t route_id, - mojom::WidgetPtrInfo widget_info) { - mojom::WidgetPtr widget; - widget.Bind(std::move(widget_info)); +void RenderWidgetHelper::OnCreateWidgetOnUI( + int32_t opener_id, + int32_t route_id, + mojo::PendingRemote<mojom::Widget> widget) { RenderViewHostImpl* host = RenderViewHostImpl::FromID( render_process_id_, opener_id); if (host) @@ -99,9 +100,7 @@ void RenderWidgetHelper::OnCreateFullscreenWidgetOnUI( int32_t opener_id, int32_t route_id, - mojom::WidgetPtrInfo widget_info) { - mojom::WidgetPtr widget; - widget.Bind(std::move(widget_info)); + mojo::PendingRemote<mojom::Widget> widget) { RenderViewHostImpl* host = RenderViewHostImpl::FromID( render_process_id_, opener_id); if (host)
diff --git a/content/browser/renderer_host/render_widget_helper.h b/content/browser/renderer_host/render_widget_helper.h index d38ca90..a6c7da70 100644 --- a/content/browser/renderer_host/render_widget_helper.h +++ b/content/browser/renderer_host/render_widget_helper.h
@@ -18,6 +18,7 @@ #include "content/public/browser/content_browser_client.h" #include "content/public/browser/global_request_id.h" #include "content/public/common/widget_type.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "ui/gfx/native_widget_types.h" namespace content { @@ -46,10 +47,10 @@ // IO THREAD ONLY ----------------------------------------------------------- void CreateNewWidget(int opener_id, - mojom::WidgetPtr, + mojo::PendingRemote<mojom::Widget>, int* route_id); void CreateNewFullscreenWidget(int opener_id, - mojom::WidgetPtr, + mojo::PendingRemote<mojom::Widget>, int* route_id); private: @@ -62,12 +63,12 @@ // Called on the UI thread to finish creating a widget. void OnCreateWidgetOnUI(int32_t opener_id, int32_t route_id, - mojom::WidgetPtrInfo widget); + mojo::PendingRemote<mojom::Widget> widget); // Called on the UI thread to create a fullscreen widget. void OnCreateFullscreenWidgetOnUI(int32_t opener_id, int32_t route_id, - mojom::WidgetPtrInfo widget); + mojo::PendingRemote<mojom::Widget> widget); int render_process_id_;
diff --git a/content/browser/renderer_host/render_widget_host_factory.cc b/content/browser/renderer_host/render_widget_host_factory.cc index bae8801..db3617c 100644 --- a/content/browser/renderer_host/render_widget_host_factory.cc +++ b/content/browser/renderer_host/render_widget_host_factory.cc
@@ -16,7 +16,7 @@ RenderWidgetHostDelegate* delegate, RenderProcessHost* process, int32_t routing_id, - mojom::WidgetPtr widget_interface, + mojo::PendingRemote<mojom::Widget> widget_interface, bool hidden) { if (factory_) { return factory_->CreateRenderWidgetHost(
diff --git a/content/browser/renderer_host/render_widget_host_factory.h b/content/browser/renderer_host/render_widget_host_factory.h index e197d53..1032e4a 100644 --- a/content/browser/renderer_host/render_widget_host_factory.h +++ b/content/browser/renderer_host/render_widget_host_factory.h
@@ -11,6 +11,7 @@ #include "base/macros.h" #include "content/common/content_export.h" #include "content/common/widget.mojom.h" +#include "mojo/public/cpp/bindings/pending_remote.h" namespace content { class RenderProcessHost; @@ -29,7 +30,7 @@ RenderWidgetHostDelegate* delegate, RenderProcessHost* process, int32_t routing_id, - mojom::WidgetPtr widget_interface, + mojo::PendingRemote<mojom::Widget> widget_interface, bool hidden); // Returns true if there is currently a globally-registered factory. @@ -45,7 +46,7 @@ RenderWidgetHostDelegate* delegate, RenderProcessHost* process, int32_t routing_id, - mojom::WidgetPtr widget_interface, + mojo::PendingRemote<mojom::Widget> widget_interface, bool hidden) = 0; // Registers your factory to be called when new RenderWidgetHostImpls are
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index ce5c2c9..22121a1c 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -340,11 +340,12 @@ /////////////////////////////////////////////////////////////////////////////// // RenderWidgetHostImpl -RenderWidgetHostImpl::RenderWidgetHostImpl(RenderWidgetHostDelegate* delegate, - RenderProcessHost* process, - int32_t routing_id, - mojom::WidgetPtr widget, - bool hidden) +RenderWidgetHostImpl::RenderWidgetHostImpl( + RenderWidgetHostDelegate* delegate, + RenderProcessHost* process, + int32_t routing_id, + mojo::PendingRemote<mojom::Widget> widget, + bool hidden) : delegate_(delegate), process_(process), routing_id_(routing_id), @@ -3093,12 +3094,14 @@ input_target_client_ = std::move(input_target_client); } -void RenderWidgetHostImpl::SetWidget(mojom::WidgetPtr widget) { - if (widget) { +void RenderWidgetHostImpl::SetWidget( + mojo::PendingRemote<mojom::Widget> widget_remote) { + if (widget_remote) { // If we have a bound handler ensure that we destroy the old input router. if (widget_input_handler_.is_bound()) SetupInputRouter(); + mojo::Remote<mojom::Widget> widget(std::move(widget_remote)); widget->SetupWidgetInputHandler( widget_input_handler_.BindNewPipeAndPassReceiver(), input_router_->BindNewHost());
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h index 5445df9..58df8df 100644 --- a/content/browser/renderer_host/render_widget_host_impl.h +++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -168,7 +168,7 @@ RenderWidgetHostImpl(RenderWidgetHostDelegate* delegate, RenderProcessHost* process, int32_t routing_id, - mojom::WidgetPtr widget_interface, + mojo::PendingRemote<mojom::Widget> widget_interface, bool hidden); ~RenderWidgetHostImpl() override; @@ -688,7 +688,7 @@ // Indicate the frame input handler is now available. void SetFrameInputHandler(mojom::FrameInputHandler*); - void SetWidget(mojom::WidgetPtr widget); + void SetWidget(mojo::PendingRemote<mojom::Widget> widget_remote); viz::mojom::InputTargetClient* input_target_client() { return input_target_client_.get();
diff --git a/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc b/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc index 4138930..ee6a030 100644 --- a/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc
@@ -22,6 +22,7 @@ #include "content/test/mock_render_widget_host_delegate.h" #include "content/test/mock_widget_impl.h" #include "content/test/test_render_view_host.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "services/viz/public/mojom/hit_test/input_target_client.mojom.h" #include "testing/gtest/include/gtest/gtest.h" @@ -199,9 +200,9 @@ process_host_root_ = std::make_unique<MockRenderProcessHost>(browser_context_.get()); - mojom::WidgetPtr widget_root; - widget_impl_root_ = - std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget_root)); + mojo::PendingRemote<mojom::Widget> widget_root; + widget_impl_root_ = std::make_unique<MockWidgetImpl>( + widget_root.InitWithNewPipeAndPassReceiver()); widget_host_root_ = std::make_unique<RenderWidgetHostImpl>( &delegate_, process_host_root_.get(), process_host_root_->GetNextRoutingID(), std::move(widget_root), false); @@ -233,9 +234,9 @@ child.process_host = std::make_unique<MockRenderProcessHost>(browser_context_.get()); - mojom::WidgetPtr widget_child; - child.widget_impl = - std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget_child)); + mojo::PendingRemote<mojom::Widget> widget_child; + child.widget_impl = std::make_unique<MockWidgetImpl>( + widget_child.InitWithNewPipeAndPassReceiver()); child.widget_host = std::make_unique<RenderWidgetHostImpl>( &delegate_, child.process_host.get(), child.process_host->GetNextRoutingID(), std::move(widget_child), false);
diff --git a/content/browser/renderer_host/render_widget_host_unittest.cc b/content/browser/renderer_host/render_widget_host_unittest.cc index 28653b1..b855d87 100644 --- a/content/browser/renderer_host/render_widget_host_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_unittest.cc
@@ -1902,9 +1902,9 @@ SimulateKeyboardEvent(WebInputEvent::kRawKeyDown); EXPECT_EQ(1u, host_->in_flight_event_count()); - mojom::WidgetPtr widget; + mojo::PendingRemote<mojom::Widget> widget; std::unique_ptr<MockWidgetImpl> widget_impl = - std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget)); + std::make_unique<MockWidgetImpl>(widget.InitWithNewPipeAndPassReceiver()); host_->SetWidget(std::move(widget)); EXPECT_EQ(0u, host_->in_flight_event_count()); } @@ -1920,9 +1920,9 @@ host_->ExpectForceEnableZoom(true); // Rebind should also update to the latest force_enable_zoom state. - mojom::WidgetPtr widget; + mojo::PendingRemote<mojom::Widget> widget; std::unique_ptr<MockWidgetImpl> widget_impl = - std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget)); + std::make_unique<MockWidgetImpl>(widget.InitWithNewPipeAndPassReceiver()); host_->SetWidget(std::move(widget)); SCOPED_TRACE("force_enable_zoom is true after rebind.");
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index 09e5895..ec0a205 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -2524,7 +2524,7 @@ if (GetInputMethod()) GetInputMethod()->OnCaretBoundsChanged(this); -#if defined(USE_X11) +#if defined(USE_X11) || (defined(USE_OZONE) && !defined(OS_CHROMEOS)) const TextInputManager::TextSelection* selection = GetTextInputManager()->GetTextSelection(focused_view); if (selection->selected_text().length()) { @@ -2532,7 +2532,7 @@ ui::ScopedClipboardWriter clipboard_writer(ui::ClipboardBuffer::kSelection); clipboard_writer.WriteText(selection->selected_text()); } -#endif // defined(USE_X11) +#endif // defined(USE_X11) || (defined(USE_OZONE) && !defined(OS_CHROMEOS)) } void RenderWidgetHostViewAura::SetPopupChild(
diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc index f97fbd3c..1baecec 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
@@ -80,6 +80,7 @@ #include "content/test/test_web_contents.h" #include "ipc/ipc_message.h" #include "ipc/ipc_test_sink.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/aura/client/aura_constants.h" @@ -392,9 +393,10 @@ static MockRenderWidgetHostImpl* Create(RenderWidgetHostDelegate* delegate, RenderProcessHost* process, int32_t routing_id) { - mojom::WidgetPtr widget; + mojo::PendingRemote<mojom::Widget> widget; std::unique_ptr<MockWidgetImpl> widget_impl = - std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget)); + std::make_unique<MockWidgetImpl>( + widget.InitWithNewPipeAndPassReceiver()); return new MockRenderWidgetHostImpl(delegate, process, routing_id, std::move(widget_impl), @@ -419,7 +421,7 @@ RenderProcessHost* process, int32_t routing_id, std::unique_ptr<MockWidgetImpl> widget_impl, - mojom::WidgetPtr widget) + mojo::PendingRemote<mojom::Widget> widget) : RenderWidgetHostImpl(delegate, process, routing_id,
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc b/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc index d426adda..11709774 100644 --- a/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc
@@ -38,6 +38,7 @@ #include "content/test/mock_render_widget_host_delegate.h" #include "content/test/mock_widget_impl.h" #include "content/test/test_render_view_host.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/frame/occlusion_state.h" #include "ui/base/ui_base_features.h" @@ -113,8 +114,9 @@ MockRenderProcessHost* process_host = new MockRenderProcessHost(browser_context_.get()); int32_t routing_id = process_host->GetNextRoutingID(); - mojom::WidgetPtr widget; - widget_impl_ = std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget)); + mojo::PendingRemote<mojom::Widget> widget; + widget_impl_ = std::make_unique<MockWidgetImpl>( + widget.InitWithNewPipeAndPassReceiver()); widget_host_ = new RenderWidgetHostImpl( &delegate_, process_host, routing_id, std::move(widget), false); view_ = RenderWidgetHostViewChildFrame::Create(widget_host_);
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm b/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm index 38ded99..4bdbb690 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm
@@ -20,6 +20,7 @@ #include "content/public/test/mock_render_process_host.h" #include "content/public/test/test_browser_context.h" #include "content/test/mock_widget_impl.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" @@ -142,9 +143,10 @@ @autoreleasepool { int32_t routing_id = process_host->GetNextRoutingID(); - mojom::WidgetPtr widget; + mojo::PendingRemote<mojom::Widget> widget; std::unique_ptr<MockWidgetImpl> widget_impl = - std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget)); + std::make_unique<MockWidgetImpl>( + widget.InitWithNewPipeAndPassReceiver()); RenderWidgetHostImpl* render_widget = new RenderWidgetHostImpl( &delegate, process_host, routing_id, std::move(widget), false);
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm index ed5c7d5..f64fa37 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
@@ -49,6 +49,7 @@ #include "content/test/test_render_view_host.h" #include "gpu/ipc/common/gpu_messages.h" #include "gpu/ipc/service/image_transport_surface.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest_mac.h" @@ -340,9 +341,10 @@ static MockRenderWidgetHostImpl* Create(RenderWidgetHostDelegate* delegate, RenderProcessHost* process, int32_t routing_id) { - mojom::WidgetPtr widget; + mojo::PendingRemote<mojom::Widget> widget; std::unique_ptr<MockWidgetImpl> widget_impl = - std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget)); + std::make_unique<MockWidgetImpl>( + widget.InitWithNewPipeAndPassReceiver()); return new MockRenderWidgetHostImpl(delegate, process, routing_id, std::move(widget_impl), @@ -361,7 +363,7 @@ RenderProcessHost* process, int32_t routing_id, std::unique_ptr<MockWidgetImpl> widget_impl, - mojom::WidgetPtr widget) + mojo::PendingRemote<mojom::Widget> widget) : RenderWidgetHostImpl(delegate, process, routing_id,
diff --git a/content/browser/renderer_host/text_input_client_mac_unittest.mm b/content/browser/renderer_host/text_input_client_mac_unittest.mm index fbc61b90..28d2c58 100644 --- a/content/browser/renderer_host/text_input_client_mac_unittest.mm +++ b/content/browser/renderer_host/text_input_client_mac_unittest.mm
@@ -21,6 +21,7 @@ #include "content/public/test/test_browser_context.h" #include "content/test/mock_widget_impl.h" #include "ipc/ipc_test_sink.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest_mac.h" @@ -57,9 +58,9 @@ RenderProcessHost* rph = process_factory_.CreateRenderProcessHost(&browser_context_, nullptr); int32_t routing_id = rph->GetNextRoutingID(); - mojom::WidgetPtr widget; - mock_widget_impl_ = - std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget)); + mojo::PendingRemote<mojom::Widget> widget; + mock_widget_impl_ = std::make_unique<MockWidgetImpl>( + widget.InitWithNewPipeAndPassReceiver()); widget_.reset(new RenderWidgetHostImpl(&delegate_, rph, routing_id, std::move(widget), false));
diff --git a/content/browser/security_exploit_browsertest.cc b/content/browser/security_exploit_browsertest.cc index f56a6e2..d34b62f 100644 --- a/content/browser/security_exploit_browsertest.cc +++ b/content/browser/security_exploit_browsertest.cc
@@ -52,6 +52,7 @@ #include "content/test/test_content_browser_client.h" #include "ipc/ipc_security_test_util.h" #include "mojo/core/embedder/embedder.h" +#include "mojo/public/cpp/bindings/pending_associated_remote.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/strong_associated_binding.h" #include "mojo/public/cpp/test_support/test_utils.h" @@ -435,9 +436,9 @@ shell(), embedded_test_server(), &duplicate_routing_id); EXPECT_NE(MSG_ROUTING_NONE, duplicate_routing_id); - mojom::WidgetPtr widget; + mojo::PendingRemote<mojom::Widget> widget; std::unique_ptr<MockWidgetImpl> widget_impl = - std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget)); + std::make_unique<MockWidgetImpl>(widget.InitWithNewPipeAndPassReceiver()); // Since this test executes on the UI thread and hopping threads might cause // different timing in the test, let's simulate a CreateNewWidget call coming @@ -1295,7 +1296,7 @@ mojom::CommonNavigationParamsPtr* common_params, mojom::BeginNavigationParamsPtr* begin_params, mojo::PendingRemote<blink::mojom::BlobURLToken>* blob_url_token, - mojom::NavigationClientAssociatedPtrInfo* navigation_client, + mojo::PendingAssociatedRemote<mojom::NavigationClient>* navigation_client, mojo::PendingRemote<blink::mojom::NavigationInitiator>* navigation_initiator) override { if (is_activated_) { @@ -1439,7 +1440,7 @@ mojom::CommonNavigationParamsPtr* common_params, mojom::BeginNavigationParamsPtr* begin_params, mojo::PendingRemote<blink::mojom::BlobURLToken>* blob_url_token, - mojom::NavigationClientAssociatedPtrInfo* navigation_client, + mojo::PendingAssociatedRemote<mojom::NavigationClient>* navigation_client, mojo::PendingRemote<blink::mojom::NavigationInitiator>* navigation_initiator) override { if (is_activated_) {
diff --git a/content/browser/service_worker/service_worker_test_utils.cc b/content/browser/service_worker/service_worker_test_utils.cc index f688f98..08952c1b 100644 --- a/content/browser/service_worker/service_worker_test_utils.cc +++ b/content/browser/service_worker/service_worker_test_utils.cc
@@ -26,7 +26,7 @@ #include "content/public/common/child_process_host.h" #include "content/public/common/transferrable_url_loader.mojom.h" #include "mojo/public/cpp/bindings/pending_associated_remote.h" -#include "mojo/public/cpp/bindings/strong_binding.h" +#include "mojo/public/cpp/bindings/self_owned_receiver.h" #include "net/base/io_buffer.h" #include "net/base/test_completion_callback.h" #include "net/http/http_response_info.h" @@ -99,7 +99,7 @@ ~FakeNavigationClient() override = default; private: - // mojom::NavigationClientPtr implementation: + // mojom::NavigationClient implementation: void CommitNavigation( mojom::CommonNavigationParamsPtr common_params, mojom::CommitNavigationParamsPtr commit_params, @@ -209,7 +209,7 @@ // crash. blink::mojom::ServiceWorkerProviderInfoForClientPtr received_info; base::RunLoop loop(base::RunLoop::Type::kNestableTasksAllowed); - mojo::MakeStrongBinding( + mojo::MakeSelfOwnedReceiver( std::make_unique<FakeNavigationClient>(base::BindOnce( [](base::OnceClosure quit_closure, blink::mojom::ServiceWorkerProviderInfoForClientPtr* out_info, @@ -218,7 +218,7 @@ std::move(quit_closure).Run(); }, loop.QuitClosure(), &received_info)), - mojo::MakeRequest(&navigation_client_)); + navigation_client_.BindNewPipeAndPassReceiver()); navigation_client_->CommitNavigation( CreateCommonNavigationParams(), CreateCommitNavigationParams(), network::ResourceResponseHead(), mojo::ScopedDataPipeConsumerHandle(),
diff --git a/content/browser/service_worker/service_worker_test_utils.h b/content/browser/service_worker/service_worker_test_utils.h index a35d1f6..1ef3df8 100644 --- a/content/browser/service_worker/service_worker_test_utils.h +++ b/content/browser/service_worker/service_worker_test_utils.h
@@ -23,6 +23,7 @@ #include "content/public/common/content_switches.h" #include "mojo/public/cpp/bindings/associated_remote.h" #include "mojo/public/cpp/bindings/pending_associated_receiver.h" +#include "mojo/public/cpp/bindings/remote.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/mojom/service_worker/service_worker_provider.mojom.h" #include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h" @@ -93,7 +94,7 @@ // do the same thing by establishing a // blink::mojom::EmbeddedWorkerInstanceClient connection if in the future we // really need to make |host_remote_| and |client_receiver_| usable for it. - mojom::NavigationClientPtr navigation_client_; + mojo::Remote<mojom::NavigationClient> navigation_client_; // Bound with content::ServiceWorkerProviderHost. The provider host will be // removed asynchronously when this remote is closed. mojo::AssociatedRemote<blink::mojom::ServiceWorkerContainerHost> host_remote_;
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 02d26b3e..72043cf 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -2982,24 +2982,27 @@ } } -void WebContentsImpl::CreateNewWidget(int32_t render_process_id, - int32_t widget_route_id, - mojom::WidgetPtr widget) { +void WebContentsImpl::CreateNewWidget( + int32_t render_process_id, + int32_t widget_route_id, + mojo::PendingRemote<mojom::Widget> widget) { CreateNewWidget(render_process_id, widget_route_id, /*is_fullscreen=*/false, std::move(widget)); } -void WebContentsImpl::CreateNewFullscreenWidget(int32_t render_process_id, - int32_t widget_route_id, - mojom::WidgetPtr widget) { +void WebContentsImpl::CreateNewFullscreenWidget( + int32_t render_process_id, + int32_t widget_route_id, + mojo::PendingRemote<mojom::Widget> widget) { CreateNewWidget(render_process_id, widget_route_id, /*is_fullscreen=*/true, std::move(widget)); } -void WebContentsImpl::CreateNewWidget(int32_t render_process_id, - int32_t route_id, - bool is_fullscreen, - mojom::WidgetPtr widget) { +void WebContentsImpl::CreateNewWidget( + int32_t render_process_id, + int32_t route_id, + bool is_fullscreen, + mojo::PendingRemote<mojom::Widget> widget) { RenderProcessHost* process = RenderProcessHost::FromID(render_process_id); // A message to create a new widget can only come from an active process for // this WebContentsImpl instance. If any other process sends the request,
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index cca7d7a..38bb027 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -54,6 +54,7 @@ #include "content/public/common/page_importance_signals.h" #include "content/public/common/resource_type.h" #include "content/public/common/three_d_api_types.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h" #include "net/base/load_states.h" #include "net/cookies/canonical_cookie.h" @@ -670,10 +671,11 @@ void UpdatePreferredSize(const gfx::Size& pref_size) override; void CreateNewWidget(int32_t render_process_id, int32_t route_id, - mojom::WidgetPtr widget) override; - void CreateNewFullscreenWidget(int32_t render_process_id, - int32_t widget_route_id, - mojom::WidgetPtr widget) override; + mojo::PendingRemote<mojom::Widget> widget) override; + void CreateNewFullscreenWidget( + int32_t render_process_id, + int32_t widget_route_id, + mojo::PendingRemote<mojom::Widget> widget) override; void ShowCreatedWidget(int process_id, int widget_route_id, const gfx::Rect& initial_rect) override; @@ -1397,7 +1399,7 @@ void CreateNewWidget(int32_t render_process_id, int32_t route_id, bool is_fullscreen, - mojom::WidgetPtr widget); + mojo::PendingRemote<mojom::Widget> widget); // Helper for ShowCreatedWidget/ShowCreatedFullscreenWidget. void ShowCreatedWidget(int process_id,
diff --git a/content/child/child_histogram_fetcher_impl.cc b/content/child/child_histogram_fetcher_impl.cc index f881a6a..feff7fb3 100644 --- a/content/child/child_histogram_fetcher_impl.cc +++ b/content/child/child_histogram_fetcher_impl.cc
@@ -14,7 +14,7 @@ #include "base/single_thread_task_runner.h" #include "content/child/child_process.h" #include "ipc/ipc_sender.h" -#include "mojo/public/cpp/bindings/strong_binding.h" +#include "mojo/public/cpp/bindings/self_owned_receiver.h" #include "mojo/public/cpp/system/platform_handle.h" namespace content { @@ -24,14 +24,16 @@ ChildHistogramFetcherFactoryImpl::~ChildHistogramFetcherFactoryImpl() {} void ChildHistogramFetcherFactoryImpl::Create( - content::mojom::ChildHistogramFetcherFactoryRequest request) { - mojo::MakeStrongBinding(std::make_unique<ChildHistogramFetcherFactoryImpl>(), - std::move(request)); + mojo::PendingReceiver<content::mojom::ChildHistogramFetcherFactory> + receiver) { + mojo::MakeSelfOwnedReceiver( + std::make_unique<ChildHistogramFetcherFactoryImpl>(), + std::move(receiver)); } void ChildHistogramFetcherFactoryImpl::CreateFetcher( base::WritableSharedMemoryRegion shared_memory, - content::mojom::ChildHistogramFetcherRequest request) { + mojo::PendingReceiver<content::mojom::ChildHistogramFetcher> receiver) { if (shared_memory.IsValid()) { // This message must be received only once. Multiple calls to create a // global allocator will cause a CHECK() failure. @@ -43,9 +45,8 @@ if (global_allocator) global_allocator->CreateTrackingHistograms(global_allocator->Name()); - content::mojom::ChildHistogramFetcherPtr child_histogram_interface; - mojo::MakeStrongBinding(std::make_unique<ChildHistogramFetcherImpl>(), - std::move(request)); + mojo::MakeSelfOwnedReceiver(std::make_unique<ChildHistogramFetcherImpl>(), + std::move(receiver)); } ChildHistogramFetcherImpl::ChildHistogramFetcherImpl() {}
diff --git a/content/child/child_histogram_fetcher_impl.h b/content/child/child_histogram_fetcher_impl.h index 68860d9..2327b9e 100644 --- a/content/child/child_histogram_fetcher_impl.h +++ b/content/child/child_histogram_fetcher_impl.h
@@ -13,6 +13,7 @@ #include "base/memory/writable_shared_memory_region.h" #include "content/common/histogram_fetcher.mojom.h" #include "ipc/message_filter.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" namespace base { class HistogramDeltaSerialization; @@ -26,11 +27,13 @@ ChildHistogramFetcherFactoryImpl(); ~ChildHistogramFetcherFactoryImpl() override; - static void Create(content::mojom::ChildHistogramFetcherFactoryRequest); + static void Create( + mojo::PendingReceiver<content::mojom::ChildHistogramFetcherFactory>); private: - void CreateFetcher(base::WritableSharedMemoryRegion, - content::mojom::ChildHistogramFetcherRequest) override; + void CreateFetcher( + base::WritableSharedMemoryRegion, + mojo::PendingReceiver<content::mojom::ChildHistogramFetcher>) override; }; class ChildHistogramFetcherImpl : public content::mojom::ChildHistogramFetcher {
diff --git a/content/common/frame.mojom b/content/common/frame.mojom index a99a8f3d..94b48f4 100644 --- a/content/common/frame.mojom +++ b/content/common/frame.mojom
@@ -424,7 +424,7 @@ CommonNavigationParams common_params, BeginNavigationParams begin_params, pending_remote<blink.mojom.BlobURLToken>? blob_url_token, - associated NavigationClient? navigation_client, + pending_associated_remote<NavigationClient>? navigation_client, pending_remote<blink.mojom.NavigationInitiator>? navigation_initiator); // Sent when a subresource response has started.
diff --git a/content/common/histogram_fetcher.mojom b/content/common/histogram_fetcher.mojom index 76c0d258..5ffecb4 100644 --- a/content/common/histogram_fetcher.mojom +++ b/content/common/histogram_fetcher.mojom
@@ -10,7 +10,7 @@ // Creates a ChildHistogram interface that uses shared memory buffer to // store histograms that are to be reported by the browser process to UMA. CreateFetcher(mojo_base.mojom.WritableSharedMemoryRegion? shared_memory, - ChildHistogramFetcher& child_histogram_fetcher); + pending_receiver<ChildHistogramFetcher> child_histogram_fetcher); }; interface ChildHistogramFetcher{
diff --git a/content/common/render_message_filter.mojom b/content/common/render_message_filter.mojom index bc461da3..96e2236 100644 --- a/content/common/render_message_filter.mojom +++ b/content/common/render_message_filter.mojom
@@ -17,11 +17,11 @@ // Similar to CreateWindow, except used for sub-widgets, like <select> // dropdowns. - [Sync] CreateNewWidget(int32 opener_id, Widget widget) + [Sync] CreateNewWidget(int32 opener_id, pending_remote<Widget> widget) => (int32 route_id); // Similar to CreateWidget except the widget is a full screen window. - [Sync] CreateFullscreenWidget(int32 opener_id, Widget widget) + [Sync] CreateFullscreenWidget(int32 opener_id, pending_remote<Widget> widget) => (int32 route_id); // A renderer sends this when it wants to know whether a gpu process exists.
diff --git a/content/public/renderer/content_renderer_client.h b/content/public/renderer/content_renderer_client.h index f4d048c..7ae6603 100644 --- a/content/public/renderer/content_renderer_client.h +++ b/content/public/renderer/content_renderer_client.h
@@ -141,18 +141,15 @@ // Note that |error_html| may be not written to in certain cases // (lack of information on the error code) so the caller should take care to // initialize it with a safe default before the call. - // TODO(dgozman): |ignoring_cache| is always false in these two methods. virtual void PrepareErrorPage(content::RenderFrame* render_frame, const blink::WebURLError& error, const std::string& http_method, - bool ignoring_cache, std::string* error_html) {} virtual void PrepareErrorPageForHttpStatusError( content::RenderFrame* render_frame, const GURL& unreachable_url, const std::string& http_method, - bool ignoring_cache, int http_status, std::string* error_html) {}
diff --git a/content/public/test/mock_render_thread.cc b/content/public/test/mock_render_thread.cc index 338f176..3937012 100644 --- a/content/public/test/mock_render_thread.cc +++ b/content/public/test/mock_render_thread.cc
@@ -50,14 +50,14 @@ } void CreateNewWidget(int32_t opener_id, - mojom::WidgetPtr widget, + mojo::PendingRemote<mojom::Widget> widget, CreateNewWidgetCallback callback) override { // See comment in CreateNewWindow(). NOTREACHED(); } bool CreateNewWidget(int32_t opener_id, - mojom::WidgetPtr widget, + mojo::PendingRemote<mojom::Widget> widget, int32_t* route_id) override { thread_->OnCreateWidget(opener_id, route_id); return true; @@ -65,7 +65,7 @@ void CreateFullscreenWidget( int opener_id, - mojom::WidgetPtr widget, + mojo::PendingRemote<mojom::Widget> widget, CreateFullscreenWidgetCallback callback) override { NOTREACHED(); }
diff --git a/content/renderer/browser_render_view_browsertest.cc b/content/renderer/browser_render_view_browsertest.cc index 6cda730..28e0505 100644 --- a/content/renderer/browser_render_view_browsertest.cc +++ b/content/renderer/browser_render_view_browsertest.cc
@@ -57,7 +57,6 @@ void PrepareErrorPage(content::RenderFrame* render_frame, const blink::WebURLError& error, const std::string& http_method, - bool ignoring_cache, std::string* error_html) override { if (error_html) *error_html = "A suffusion of yellow.";
diff --git a/content/renderer/navigation_client.cc b/content/renderer/navigation_client.cc index f8b7c83c..4f5cba3 100644 --- a/content/renderer/navigation_client.cc +++ b/content/renderer/navigation_client.cc
@@ -11,7 +11,7 @@ namespace content { NavigationClient::NavigationClient(RenderFrameImpl* render_frame) - : navigation_client_binding_(this), render_frame_(render_frame) {} + : render_frame_(render_frame) {} NavigationClient::~NavigationClient() {} @@ -59,10 +59,11 @@ std::move(subresource_loaders), std::move(callback)); } -void NavigationClient::Bind(mojom::NavigationClientAssociatedRequest request) { - navigation_client_binding_.Bind( - std::move(request), render_frame_->GetTaskRunner( - blink::TaskType::kInternalNavigationAssociated)); +void NavigationClient::Bind( + mojo::PendingAssociatedReceiver<mojom::NavigationClient> receiver) { + navigation_client_receiver_.Bind( + std::move(receiver), render_frame_->GetTaskRunner( + blink::TaskType::kInternalNavigationAssociated)); SetDisconnectionHandler(); } @@ -72,12 +73,12 @@ } void NavigationClient::SetDisconnectionHandler() { - navigation_client_binding_.set_connection_error_handler(base::BindOnce( + navigation_client_receiver_.set_disconnect_handler(base::BindOnce( &NavigationClient::OnDroppedNavigation, base::Unretained(this))); } void NavigationClient::ResetDisconnectionHandler() { - navigation_client_binding_.set_connection_error_handler(base::DoNothing()); + navigation_client_receiver_.set_disconnect_handler(base::DoNothing()); } void NavigationClient::OnDroppedNavigation() {
diff --git a/content/renderer/navigation_client.h b/content/renderer/navigation_client.h index 927e5f2f3..614a1c8 100644 --- a/content/renderer/navigation_client.h +++ b/content/renderer/navigation_client.h
@@ -6,7 +6,8 @@ #define CONTENT_RENDERER_NAVIGATION_CLIENT_H_ #include "content/common/navigation_client.mojom.h" -#include "mojo/public/cpp/bindings/associated_binding.h" +#include "mojo/public/cpp/bindings/associated_receiver.h" +#include "mojo/public/cpp/bindings/pending_associated_receiver.h" namespace content { @@ -43,7 +44,7 @@ std::unique_ptr<blink::URLLoaderFactoryBundleInfo> subresource_loaders, CommitFailedNavigationCallback callback) override; - void Bind(mojom::NavigationClientAssociatedRequest request); + void Bind(mojo::PendingAssociatedReceiver<mojom::NavigationClient> receiver); // See NavigationState::was_initiated_in_this_frame for details. void MarkWasInitiatedInThisFrame(); @@ -59,7 +60,8 @@ void SetDisconnectionHandler(); void ResetDisconnectionHandler(); - mojo::AssociatedBinding<mojom::NavigationClient> navigation_client_binding_; + mojo::AssociatedReceiver<mojom::NavigationClient> navigation_client_receiver_{ + this}; RenderFrameImpl* render_frame_; bool was_initiated_in_this_frame_ = false; };
diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.cc b/content/renderer/pepper/pepper_plugin_instance_impl.cc index c2e45ddb..f45103b 100644 --- a/content/renderer/pepper/pepper_plugin_instance_impl.cc +++ b/content/renderer/pepper/pepper_plugin_instance_impl.cc
@@ -2058,6 +2058,10 @@ return true; } +bool PepperPluginInstanceImpl::IsPdfPlugin() { + return LoadPdfInterface(); +} + bool PepperPluginInstanceImpl::CanRotateView() { if (!LoadPdfInterface() || module()->is_crashed()) return false;
diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.h b/content/renderer/pepper/pepper_plugin_instance_impl.h index 617e9cc..e15acbf5 100644 --- a/content/renderer/pepper/pepper_plugin_instance_impl.h +++ b/content/renderer/pepper/pepper_plugin_instance_impl.h
@@ -276,6 +276,7 @@ void PrintEnd(); bool GetPrintPresetOptionsFromDocument( blink::WebPrintPresetOptions* preset_options); + bool IsPdfPlugin(); bool CanRotateView(); void RotateView(blink::WebPlugin::RotationType type);
diff --git a/content/renderer/pepper/pepper_webplugin_impl.cc b/content/renderer/pepper/pepper_webplugin_impl.cc index db8dfbc..9b3bcfd 100644 --- a/content/renderer/pepper/pepper_webplugin_impl.cc +++ b/content/renderer/pepper/pepper_webplugin_impl.cc
@@ -457,6 +457,14 @@ return instance_->GetPrintPresetOptionsFromDocument(preset_options); } +bool PepperWebPluginImpl::IsPdfPlugin() { + // Re-entrancy may cause JS to try to execute script on the plugin before it + // is fully initialized. See: crbug.com/715747. + if (!instance_) + return false; + return instance_->IsPdfPlugin(); +} + bool PepperWebPluginImpl::CanRotateView() { // Re-entrancy may cause JS to try to execute script on the plugin before it // is fully initialized. See: crbug.com/715747.
diff --git a/content/renderer/pepper/pepper_webplugin_impl.h b/content/renderer/pepper/pepper_webplugin_impl.h index 0be81fc..7c1f1c6 100644 --- a/content/renderer/pepper/pepper_webplugin_impl.h +++ b/content/renderer/pepper/pepper_webplugin_impl.h
@@ -73,6 +73,7 @@ blink::WebURL LinkAtPosition(const blink::WebPoint& position) const override; bool GetPrintPresetOptionsFromDocument( blink::WebPrintPresetOptions* preset_options) override; + bool IsPdfPlugin() override; bool StartFind(const blink::WebString& search_text, bool case_sensitive, int identifier) override;
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 527b0e0c..45c0bf7 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -147,7 +147,6 @@ #include "content/renderer/worker/dedicated_worker_host_factory_client.h" #include "crypto/sha2.h" #include "mojo/public/cpp/bindings/pending_associated_remote.h" -#include "mojo/public/cpp/bindings/pending_remote.h" #include "net/base/data_url.h" #include "net/base/load_flags.h" #include "net/base/net_errors.h" @@ -2127,9 +2126,9 @@ if (main_frame->IsWebLocalFrame()) main_frame_url = main_frame->ToWebLocalFrame()->GetDocument().Url(); - mojom::WidgetPtr widget_channel; - mojom::WidgetRequest widget_channel_request = - mojo::MakeRequest(&widget_channel); + mojo::PendingRemote<mojom::Widget> widget_channel; + mojo::PendingReceiver<mojom::Widget> widget_channel_receiver = + widget_channel.InitWithNewPipeAndPassReceiver(); // Synchronous IPC to obtain a routing id for the fullscreen widget. int32_t fullscreen_widget_routing_id = MSG_ROUTING_NONE; @@ -2150,7 +2149,7 @@ GetLocalRootRenderWidget()->compositor_deps(), render_view()->page_properties(), plugin, std::move(main_frame_url), GetLocalRootRenderWidget()->GetWebScreenInfo(), - std::move(widget_channel_request)); + std::move(widget_channel_receiver)); // TODO(nick): The show() handshake seems like unnecessary complexity here, // since there's no real delay between CreateFullscreenWidget and // ShowCreatedFullscreenWidget. Would it be simpler to have the @@ -2394,9 +2393,9 @@ } void RenderFrameImpl::BindNavigationClient( - mojom::NavigationClientAssociatedRequest request) { + mojo::PendingAssociatedReceiver<mojom::NavigationClient> receiver) { navigation_client_impl_ = std::make_unique<NavigationClient>(this); - navigation_client_impl_->Bind(std::move(request)); + navigation_client_impl_->Bind(std::move(receiver)); } void RenderFrameImpl::OnBeforeUnload(bool is_reload) { @@ -3044,8 +3043,7 @@ error_html = error_page_content.value(); } else { GetContentClient()->renderer()->PrepareErrorPage( - this, error, document_loader->HttpMethod().Ascii(), - false /* ignoring_cache */, &error_html); + this, error, document_loader->HttpMethod().Ascii(), &error_html); } // Make sure we never show errors in view source mode. @@ -3879,18 +3877,13 @@ history_entry = PageStateToHistoryEntry(commit_params->page_state); std::string error_html; - if (error_page_content.has_value()) { + std::string* error_html_ptr = &error_html; + if (error_page_content) { error_html = error_page_content.value(); - // We don't need the actual error page content, but still call this - // for any possible side effects. - GetContentClient()->renderer()->PrepareErrorPage( - this, error, navigation_params->http_method.Ascii(), - false /* ignoring_cache */, nullptr); - } else { - GetContentClient()->renderer()->PrepareErrorPage( - this, error, navigation_params->http_method.Ascii(), - false /* ignoring_cache */, &error_html); + error_html_ptr = nullptr; } + GetContentClient()->renderer()->PrepareErrorPage( + this, error, navigation_params->http_method.Ascii(), error_html_ptr); // Make sure we never show errors in view source mode. frame_->EnableViewSourceMode(false); @@ -5083,7 +5076,7 @@ std::string error_html; GetContentClient()->renderer()->PrepareErrorPageForHttpStatusError( this, unreachable_url, document_loader->HttpMethod().Ascii(), - false /* ignoring_cache */, http_status_code, &error_html); + http_status_code, &error_html); // This call may run scripts, e.g. via the beforeunload event, and possibly // delete |this|. LoadNavigationErrorPage(document_loader, @@ -7277,9 +7270,11 @@ initiator ? base::make_optional<base::Value>(std::move(*initiator)) : base::nullopt); - mojom::NavigationClientAssociatedPtrInfo navigation_client_info; + mojo::PendingAssociatedRemote<mojom::NavigationClient> + navigation_client_remote; if (IsPerNavigationMojoInterfaceEnabled()) { - BindNavigationClient(mojo::MakeRequest(&navigation_client_info)); + BindNavigationClient( + navigation_client_remote.InitWithNewEndpointAndPassReceiver()); navigation_client_impl_->MarkWasInitiatedInThisFrame(); } @@ -7298,7 +7293,7 @@ load_flags, has_download_sandbox_flag, from_ad, is_history_navigation_in_new_child_frame), std::move(begin_navigation_params), std::move(blob_url_token), - std::move(navigation_client_info), std::move(navigation_initiator)); + std::move(navigation_client_remote), std::move(navigation_initiator)); } void RenderFrameImpl::DecodeDataURL(
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 7c64101..09752d4 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -65,6 +65,7 @@ #include "mojo/public/cpp/bindings/associated_receiver.h" #include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding_set.h" +#include "mojo/public/cpp/bindings/pending_associated_receiver.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h" @@ -909,7 +910,8 @@ void BindFrameNavigationControl( mojo::PendingAssociatedReceiver<mojom::FrameNavigationControl> receiver); // Only used when PerNavigationMojoInterface is enabled. - void BindNavigationClient(mojom::NavigationClientAssociatedRequest request); + void BindNavigationClient( + mojo::PendingAssociatedReceiver<mojom::NavigationClient> receiver); media::MediaPermission* GetMediaPermission();
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index 49f3e19..56bff368 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc
@@ -121,6 +121,8 @@ #include "media/base/media_switches.h" #include "media/media_buildflags.h" #include "media/video/gpu_video_accelerator_factories.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/self_owned_receiver.h" #include "mojo/public/cpp/bindings/strong_binding.h" #include "mojo/public/cpp/system/message_pipe.h" #include "net/base/net_errors.h" @@ -510,10 +512,11 @@ DISALLOW_COPY_AND_ASSIGN(ResourceUsageReporterImpl); }; -void CreateResourceUsageReporter(base::WeakPtr<RenderThread> thread, - mojom::ResourceUsageReporterRequest request) { - mojo::MakeStrongBinding(std::make_unique<ResourceUsageReporterImpl>(thread), - std::move(request)); +void CreateResourceUsageReporter( + base::WeakPtr<RenderThread> thread, + mojo::PendingReceiver<mojom::ResourceUsageReporter> receiver) { + mojo::MakeSelfOwnedReceiver( + std::make_unique<ResourceUsageReporterImpl>(thread), std::move(receiver)); } } // namespace
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc index ad387b2..e5c9bc9 100644 --- a/content/renderer/render_view_browsertest.cc +++ b/content/renderer/render_view_browsertest.cc
@@ -1999,7 +1999,6 @@ void PrepareErrorPage(content::RenderFrame* render_frame, const blink::WebURLError& error, const std::string& http_method, - bool ignoring_cache, std::string* error_html) override { if (error_html) *error_html = "A suffusion of yellow."; @@ -2008,7 +2007,6 @@ void PrepareErrorPageForHttpStatusError(content::RenderFrame* render_frame, const GURL& unreachable_url, const std::string& http_method, - bool ignoring_cache, int http_status, std::string* error_html) override { if (error_html)
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index 312ae58..f14d1f7 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -90,6 +90,7 @@ #include "media/media_buildflags.h" #include "media/renderers/audio_renderer_impl.h" #include "media/video/gpu_video_accelerator_factories.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" #include "net/base/data_url.h" #include "net/base/escape.h" #include "net/base/net_errors.h" @@ -1424,9 +1425,9 @@ blink::WebPagePopup* RenderViewImpl::CreatePopup( blink::WebLocalFrame* creator) { - mojom::WidgetPtr widget_channel; - mojom::WidgetRequest widget_channel_request = - mojo::MakeRequest(&widget_channel); + mojo::PendingRemote<mojom::Widget> widget_channel; + mojo::PendingReceiver<mojom::Widget> widget_channel_receiver = + widget_channel.InitWithNewPipeAndPassReceiver(); // Do a synchronous IPC to obtain a routing ID. int32_t widget_routing_id = MSG_ROUTING_NONE; @@ -1455,7 +1456,7 @@ page_properties(), view_render_widget->screen_info(), blink::kWebDisplayModeUndefined, /*hidden=*/false, - /*never_visible=*/false, std::move(widget_channel_request)); + /*never_visible=*/false, std::move(widget_channel_receiver)); // The returned WebPagePopup is self-referencing, so the pointer here is not // an owning pointer. It is de-referenced by calling Close().
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h index 518f67fd..fdf433b7 100644 --- a/content/renderer/render_view_impl.h +++ b/content/renderer/render_view_impl.h
@@ -36,6 +36,7 @@ #include "content/renderer/render_widget.h" #include "content/renderer/render_widget_delegate.h" #include "ipc/ipc_platform_file.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote_set.h" #include "third_party/blink/public/common/dom_storage/session_storage_namespace_id.h" #include "third_party/blink/public/common/feature_policy/feature_policy.h"
diff --git a/content/shell/renderer/shell_content_renderer_client.cc b/content/shell/renderer/shell_content_renderer_client.cc index d485682..c5f2ec4 100644 --- a/content/shell/renderer/shell_content_renderer_client.cc +++ b/content/shell/renderer/shell_content_renderer_client.cc
@@ -139,7 +139,6 @@ RenderFrame* render_frame, const blink::WebURLError& error, const std::string& http_method, - bool ignoring_cache, std::string* error_html) { if (error_html && error_html->empty()) { *error_html = @@ -156,7 +155,6 @@ content::RenderFrame* render_frame, const GURL& unreachable_url, const std::string& http_method, - bool ignoring_cache, int http_status, std::string* error_html) { if (error_html) {
diff --git a/content/shell/renderer/shell_content_renderer_client.h b/content/shell/renderer/shell_content_renderer_client.h index f0a2f39..b8addce9 100644 --- a/content/shell/renderer/shell_content_renderer_client.h +++ b/content/shell/renderer/shell_content_renderer_client.h
@@ -31,12 +31,10 @@ void PrepareErrorPage(RenderFrame* render_frame, const blink::WebURLError& error, const std::string& http_method, - bool ignoring_cache, std::string* error_html) override; void PrepareErrorPageForHttpStatusError(content::RenderFrame* render_frame, const GURL& unreachable_url, const std::string& http_method, - bool ignoring_cache, int http_status, std::string* error_html) override;
diff --git a/content/test/frame_host_interceptor.cc b/content/test/frame_host_interceptor.cc index f355e5c..155890ab7 100644 --- a/content/test/frame_host_interceptor.cc +++ b/content/test/frame_host_interceptor.cc
@@ -43,7 +43,7 @@ mojom::CommonNavigationParamsPtr common_params, mojom::BeginNavigationParamsPtr begin_params, mojo::PendingRemote<blink::mojom::BlobURLToken> blob_url_token, - mojom::NavigationClientAssociatedPtrInfo navigation_client, + mojo::PendingAssociatedRemote<mojom::NavigationClient> navigation_client, mojo::PendingRemote<blink::mojom::NavigationInitiator> navigation_initiator) override { if (interceptor_->WillDispatchBeginNavigation( @@ -80,7 +80,7 @@ mojom::CommonNavigationParamsPtr* common_params, mojom::BeginNavigationParamsPtr* begin_params, mojo::PendingRemote<blink::mojom::BlobURLToken>* blob_url_token, - mojom::NavigationClientAssociatedPtrInfo* navigation_client, + mojo::PendingAssociatedRemote<mojom::NavigationClient>* navigation_client, mojo::PendingRemote<blink::mojom::NavigationInitiator>* navigation_initiator) { return true;
diff --git a/content/test/frame_host_interceptor.h b/content/test/frame_host_interceptor.h index 3aec1e1..016b764 100644 --- a/content/test/frame_host_interceptor.h +++ b/content/test/frame_host_interceptor.h
@@ -11,6 +11,7 @@ #include "base/macros.h" #include "content/common/frame.mojom.h" #include "content/public/browser/web_contents_observer.h" +#include "mojo/public/cpp/bindings/pending_associated_remote.h" #include "mojo/public/cpp/bindings/pending_remote.h" namespace content { @@ -46,7 +47,7 @@ mojom::CommonNavigationParamsPtr* common_params, mojom::BeginNavigationParamsPtr* begin_params, mojo::PendingRemote<blink::mojom::BlobURLToken>* blob_url_token, - mojom::NavigationClientAssociatedPtrInfo* navigation_client, + mojo::PendingAssociatedRemote<mojom::NavigationClient>* navigation_client, mojo::PendingRemote<blink::mojom::NavigationInitiator>* navigation_initiator);
diff --git a/content/test/navigation_simulator_impl.cc b/content/test/navigation_simulator_impl.cc index 7fab994..4c07b19 100644 --- a/content/test/navigation_simulator_impl.cc +++ b/content/test/navigation_simulator_impl.cc
@@ -24,6 +24,7 @@ #include "content/test/test_navigation_url_loader.h" #include "content/test/test_render_frame_host.h" #include "content/test/test_web_contents.h" +#include "mojo/public/cpp/bindings/pending_associated_remote.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "net/base/load_flags.h" #include "net/url_request/redirect_info.h" @@ -1128,20 +1129,22 @@ std::vector<ContentSecurityPolicy>(), base::nullopt); if (IsPerNavigationMojoInterfaceEnabled()) { - mojom::NavigationClientAssociatedPtr navigation_client_ptr; - navigation_client_request_ = - mojo::MakeRequestAssociatedWithDedicatedPipe(&navigation_client_ptr); + mojo::PendingAssociatedRemote<mojom::NavigationClient> + navigation_client_remote; + navigation_client_receiver_ = + navigation_client_remote.InitWithNewEndpointAndPassReceiver(); render_frame_host_->frame_host_binding_for_testing() .impl() ->BeginNavigation(std::move(common_params), std::move(begin_params), mojo::NullRemote(), - navigation_client_ptr.PassInterface(), + std::move(navigation_client_remote), mojo::NullRemote()); } else { render_frame_host_->frame_host_binding_for_testing() .impl() ->BeginNavigation(std::move(common_params), std::move(begin_params), - mojo::NullRemote(), nullptr, mojo::NullRemote()); + mojo::NullRemote(), mojo::NullAssociatedRemote(), + mojo::NullRemote()); } NavigationRequest* request =
diff --git a/content/test/navigation_simulator_impl.h b/content/test/navigation_simulator_impl.h index d37b057..2bc10744 100644 --- a/content/test/navigation_simulator_impl.h +++ b/content/test/navigation_simulator_impl.h
@@ -16,7 +16,7 @@ #include "content/public/browser/navigation_throttle.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/test/navigation_simulator.h" -#include "mojo/public/cpp/bindings/associated_interface_request.h" +#include "mojo/public/cpp/bindings/pending_associated_receiver.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "net/base/host_port_pair.h" #include "net/base/ip_endpoint.h" @@ -344,8 +344,8 @@ // cancellation coming from the renderer process side. This member interface // will never be bound. // Only used when PerNavigationMojoInterface is enabled. - mojo::AssociatedInterfaceRequest<mojom::NavigationClient> - navigation_client_request_; + mojo::PendingAssociatedReceiver<mojom::NavigationClient> + navigation_client_receiver_; base::WeakPtrFactory<NavigationSimulatorImpl> weak_factory_{this}; };
diff --git a/content/test/test_render_frame.cc b/content/test/test_render_frame.cc index 3519af61..ba05a1a 100644 --- a/content/test/test_render_frame.cc +++ b/content/test/test_render_frame.cc
@@ -19,6 +19,7 @@ #include "content/public/test/mock_render_thread.h" #include "content/renderer/input/frame_input_handler_impl.h" #include "content/renderer/loader/web_url_loader_impl.h" +#include "mojo/public/cpp/bindings/pending_associated_remote.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "net/base/data_url.h" #include "services/network/public/cpp/resource_response.h" @@ -159,7 +160,7 @@ mojom::CommonNavigationParamsPtr common_params, mojom::BeginNavigationParamsPtr begin_params, mojo::PendingRemote<blink::mojom::BlobURLToken> blob_url_token, - mojom::NavigationClientAssociatedPtrInfo, + mojo::PendingAssociatedRemote<mojom::NavigationClient>, mojo::PendingRemote<blink::mojom::NavigationInitiator>) override {} void SubresourceResponseStarted(const GURL& url, @@ -281,8 +282,10 @@ mojo::NullRemote() /* prefetch_loader_factory */, base::UnguessableToken::Create(), base::DoNothing()); } else { + mock_navigation_client_.reset(); BindNavigationClient( - mojo::MakeRequestAssociatedWithDedicatedPipe(&mock_navigation_client_)); + mock_navigation_client_ + .BindNewEndpointAndPassDedicatedReceiverForTesting()); CommitPerNavigationMojoInterfaceNavigation( std::move(common_params), std::move(commit_params), head, mojo::ScopedDataPipeConsumerHandle(), @@ -313,8 +316,10 @@ false /* has_stale_copy_in_cache */, error_code, error_page_content, nullptr, base::DoNothing()); } else { + mock_navigation_client_.reset(); BindNavigationClient( - mojo::MakeRequestAssociatedWithDedicatedPipe(&mock_navigation_client_)); + mock_navigation_client_ + .BindNewEndpointAndPassDedicatedReceiverForTesting()); mock_navigation_client_->CommitFailedNavigation( std::move(common_params), std::move(commit_params), false /* has_stale_copy_in_cache */, error_code, error_page_content,
diff --git a/content/test/test_render_frame.h b/content/test/test_render_frame.h index 0880cc7c..40f54da 100644 --- a/content/test/test_render_frame.h +++ b/content/test/test_render_frame.h
@@ -13,6 +13,7 @@ #include "content/common/input/input_handler.mojom.h" #include "content/common/navigation_params.mojom.h" #include "content/renderer/render_frame_impl.h" +#include "mojo/public/cpp/bindings/associated_remote.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h" @@ -93,7 +94,7 @@ base::Optional<std::string> next_navigation_html_override_; mojom::FrameInputHandlerPtr frame_input_handler_; - mojom::NavigationClientAssociatedPtr mock_navigation_client_; + mojo::AssociatedRemote<mojom::NavigationClient> mock_navigation_client_; DISALLOW_COPY_AND_ASSIGN(TestRenderFrame); };
diff --git a/content/test/test_render_frame_host.cc b/content/test/test_render_frame_host.cc index 6251bd5..bd02bab 100644 --- a/content/test/test_render_frame_host.cc +++ b/content/test/test_render_frame_host.cc
@@ -29,6 +29,7 @@ #include "content/test/test_render_view_host.h" #include "content/test/test_render_widget_host.h" #include "mojo/public/cpp/bindings/interface_request.h" +#include "mojo/public/cpp/bindings/pending_associated_remote.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "net/base/ip_endpoint.h" #include "net/base/load_flags.h" @@ -360,15 +361,18 @@ common_params->navigation_type = mojom::NavigationType::DIFFERENT_DOCUMENT; common_params->has_user_gesture = has_user_gesture; - mojom::NavigationClientAssociatedPtr navigation_client_ptr; + mojo::PendingAssociatedRemote<mojom::NavigationClient> + navigation_client_remote; if (IsPerNavigationMojoInterfaceEnabled()) { - GetRemoteAssociatedInterfaces()->GetInterface(&navigation_client_ptr); + GetRemoteAssociatedInterfaces()->GetInterface( + navigation_client_remote.InitWithNewEndpointAndPassReceiver()); BeginNavigation(std::move(common_params), std::move(begin_params), - mojo::NullRemote(), navigation_client_ptr.PassInterface(), + mojo::NullRemote(), std::move(navigation_client_remote), mojo::NullRemote()); } else { BeginNavigation(std::move(common_params), std::move(begin_params), - mojo::NullRemote(), nullptr, mojo::NullRemote()); + mojo::NullRemote(), mojo::NullAssociatedRemote(), + mojo::NullRemote()); } }
diff --git a/content/test/test_render_widget_host.cc b/content/test/test_render_widget_host.cc index 9e469f2..b36b491 100644 --- a/content/test/test_render_widget_host.cc +++ b/content/test/test_render_widget_host.cc
@@ -14,9 +14,9 @@ RenderProcessHost* process, int32_t routing_id, bool hidden) { - mojom::WidgetPtr widget; + mojo::PendingRemote<mojom::Widget> widget; std::unique_ptr<MockWidgetImpl> widget_impl = - std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget)); + std::make_unique<MockWidgetImpl>(widget.InitWithNewPipeAndPassReceiver()); return base::WrapUnique(new TestRenderWidgetHost( delegate, process, routing_id, std::move(widget_impl), std::move(widget), hidden)); @@ -27,7 +27,7 @@ RenderProcessHost* process, int32_t routing_id, std::unique_ptr<MockWidgetImpl> widget_impl, - mojom::WidgetPtr widget, + mojo::PendingRemote<mojom::Widget> widget, bool hidden) : RenderWidgetHostImpl(delegate, process,
diff --git a/content/test/test_render_widget_host.h b/content/test/test_render_widget_host.h index 9e38af7..db5c3ad 100644 --- a/content/test/test_render_widget_host.h +++ b/content/test/test_render_widget_host.h
@@ -8,6 +8,7 @@ #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/test/mock_widget_impl.h" #include "content/test/mock_widget_input_handler.h" +#include "mojo/public/cpp/bindings/pending_remote.h" namespace content { // TestRenderWidgetHostView ---------------------------------------------------- @@ -33,7 +34,7 @@ RenderProcessHost* process, int32_t routing_id, std::unique_ptr<MockWidgetImpl> widget_impl, - mojom::WidgetPtr widget, + mojo::PendingRemote<mojom::Widget> widget, bool hidden); std::unique_ptr<MockWidgetImpl> widget_impl_;
diff --git a/content/test/test_render_widget_host_factory.cc b/content/test/test_render_widget_host_factory.cc index 3c63658..d8864fb 100644 --- a/content/test/test_render_widget_host_factory.cc +++ b/content/test/test_render_widget_host_factory.cc
@@ -21,7 +21,7 @@ RenderWidgetHostDelegate* delegate, RenderProcessHost* process, int32_t routing_id, - mojom::WidgetPtr widget_interface, + mojo::PendingRemote<mojom::Widget> widget_interface, bool hidden) { return TestRenderWidgetHost::Create(delegate, process, routing_id, hidden); }
diff --git a/content/test/test_render_widget_host_factory.h b/content/test/test_render_widget_host_factory.h index 88daf95..b4cae01 100644 --- a/content/test/test_render_widget_host_factory.h +++ b/content/test/test_render_widget_host_factory.h
@@ -10,6 +10,7 @@ #include "base/compiler_specific.h" #include "base/macros.h" #include "content/browser/renderer_host/render_widget_host_factory.h" +#include "mojo/public/cpp/bindings/pending_remote.h" namespace content { @@ -26,7 +27,7 @@ RenderWidgetHostDelegate* delegate, RenderProcessHost* process, int32_t routing_id, - mojom::WidgetPtr widget_interface, + mojo::PendingRemote<mojom::Widget> widget_interface, bool hidden) override; private:
diff --git a/content/test/test_web_contents.cc b/content/test/test_web_contents.cc index f93393a..1dc9589 100644 --- a/content/test/test_web_contents.cc +++ b/content/test/test_web_contents.cc
@@ -388,13 +388,15 @@ bool has_user_gesture, SessionStorageNamespace* session_storage_namespace) {} -void TestWebContents::CreateNewWidget(int32_t render_process_id, - int32_t route_id, - mojom::WidgetPtr widget) {} +void TestWebContents::CreateNewWidget( + int32_t render_process_id, + int32_t route_id, + mojo::PendingRemote<mojom::Widget> widget) {} -void TestWebContents::CreateNewFullscreenWidget(int32_t render_process_id, - int32_t route_id, - mojom::WidgetPtr widget) {} +void TestWebContents::CreateNewFullscreenWidget( + int32_t render_process_id, + int32_t route_id, + mojo::PendingRemote<mojom::Widget> widget) {} void TestWebContents::ShowCreatedWindow(int process_id, int route_id,
diff --git a/content/test/test_web_contents.h b/content/test/test_web_contents.h index d335576..77f4f16 100644 --- a/content/test/test_web_contents.h +++ b/content/test/test_web_contents.h
@@ -19,6 +19,7 @@ #include "content/public/test/web_contents_tester.h" #include "content/test/test_render_frame_host.h" #include "content/test/test_render_view_host.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/mojom/loader/pause_subresource_loading_handle.mojom.h" #include "ui/base/page_transition_types.h" @@ -187,10 +188,11 @@ SessionStorageNamespace* session_storage_namespace) override; void CreateNewWidget(int32_t render_process_id, int32_t route_id, - mojom::WidgetPtr widget) override; - void CreateNewFullscreenWidget(int32_t render_process_id, - int32_t route_id, - mojom::WidgetPtr widget) override; + mojo::PendingRemote<mojom::Widget> widget) override; + void CreateNewFullscreenWidget( + int32_t render_process_id, + int32_t route_id, + mojo::PendingRemote<mojom::Widget> widget) override; void ShowCreatedWindow(int process_id, int route_id, WindowOpenDisposition disposition,
diff --git a/content/utility/utility_thread_impl.cc b/content/utility/utility_thread_impl.cc index 22ca1b5..2a4bf65 100644 --- a/content/utility/utility_thread_impl.cc +++ b/content/utility/utility_thread_impl.cc
@@ -25,7 +25,6 @@ #include "ipc/ipc_sync_channel.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/self_owned_receiver.h" -#include "mojo/public/cpp/bindings/strong_binding.h" #include "mojo/public/cpp/system/simple_watcher.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/sandbox/switches.h" @@ -137,9 +136,10 @@ DISALLOW_COPY_AND_ASSIGN(ResourceUsageReporterImpl); }; -void CreateResourceUsageReporter(mojom::ResourceUsageReporterRequest request) { - mojo::MakeStrongBinding(std::make_unique<ResourceUsageReporterImpl>(), - std::move(request)); +void CreateResourceUsageReporter( + mojo::PendingReceiver<mojom::ResourceUsageReporter> receiver) { + mojo::MakeSelfOwnedReceiver(std::make_unique<ResourceUsageReporterImpl>(), + std::move(receiver)); } #endif // !defined(OS_ANDROID)
diff --git a/ios/chrome/browser/DEPS b/ios/chrome/browser/DEPS index 373fd94b..e9e62bba 100644 --- a/ios/chrome/browser/DEPS +++ b/ios/chrome/browser/DEPS
@@ -107,6 +107,7 @@ "+ios/public/provider/components", "+ios/shared/chrome/browser", "+libxml/xmlwriter.h", + "+mojo/public/cpp/bindings", "+net", "+rlz/buildflags", "+services/metrics/public",
diff --git a/ios/chrome/browser/browser_state/chrome_browser_state_io_data.h b/ios/chrome/browser/browser_state/chrome_browser_state_io_data.h index a4d7f557..ed3ec66 100644 --- a/ios/chrome/browser/browser_state/chrome_browser_state_io_data.h +++ b/ios/chrome/browser/browser_state/chrome_browser_state_io_data.h
@@ -96,10 +96,6 @@ content_settings::CookieSettings* GetCookieSettings() const; HostContentSettingsMap* GetHostContentSettingsMap() const; - StringPrefMember* google_services_account_id() const { - return &google_services_user_account_id_; - } - net::TransportSecurityState* transport_security_state() const { return transport_security_state_.get(); } @@ -259,8 +255,6 @@ // ChromeBrowserStateIOData. Deleted after lazy initialization. mutable std::unique_ptr<ProfileParams> profile_params_; - mutable StringPrefMember google_services_user_account_id_; - // Member variables which are pointed to by the various context objects. mutable BooleanPrefMember enable_referrers_; mutable BooleanPrefMember enable_do_not_track_;
diff --git a/ios/chrome/browser/browser_state/chrome_browser_state_io_data.mm b/ios/chrome/browser/browser_state/chrome_browser_state_io_data.mm index f1498f2..a205099 100644 --- a/ios/chrome/browser/browser_state/chrome_browser_state_io_data.mm +++ b/ios/chrome/browser/browser_state/chrome_browser_state_io_data.mm
@@ -113,14 +113,6 @@ chrome_http_user_agent_settings_.reset( new IOSChromeHttpUserAgentSettings(pref_service)); - - // These members are used only for sign in, which is not enabled - // in incognito mode. So no need to initialize them. - if (!IsOffTheRecord()) { - google_services_user_account_id_.Init(prefs::kGoogleServicesUserAccountId, - pref_service); - google_services_user_account_id_.MoveToSequence(io_task_runner); - } } ChromeBrowserStateIOData::AppRequestContext::AppRequestContext() {} @@ -412,7 +404,6 @@ std::unique_ptr<IOSChromeURLRequestContextGetterVector> context_getters) { DCHECK_CURRENTLY_ON(web::WebThread::UI); - google_services_user_account_id_.Destroy(); enable_referrers_.Destroy(); enable_do_not_track_.Destroy(); enable_metrics_.Destroy();
diff --git a/ios/chrome/browser/ios_chrome_io_thread.h b/ios/chrome/browser/ios_chrome_io_thread.h index c6e0a5bfe..5f3945b 100644 --- a/ios/chrome/browser/ios_chrome_io_thread.h +++ b/ios/chrome/browser/ios_chrome_io_thread.h
@@ -8,6 +8,7 @@ #include <memory> #include "ios/components/io_thread/ios_io_thread.h" +#include "mojo/public/cpp/bindings/remote.h" #include "services/network/public/mojom/network_service.mojom.h" class PrefService; @@ -48,7 +49,7 @@ scoped_refptr<network::WeakWrapperSharedURLLoaderFactory> shared_url_loader_factory_; - network::mojom::NetworkContextPtr network_context_; + mojo::Remote<network::mojom::NetworkContext> network_context_; std::unique_ptr<web::NetworkContextOwner> network_context_owner_; DISALLOW_COPY_AND_ASSIGN(IOSChromeIOThread);
diff --git a/ios/chrome/browser/prefs/browser_prefs.mm b/ios/chrome/browser/prefs/browser_prefs.mm index 2711cc4a..92efde18 100644 --- a/ios/chrome/browser/prefs/browser_prefs.mm +++ b/ios/chrome/browser/prefs/browser_prefs.mm
@@ -74,6 +74,7 @@ // Deprecated 9/2019 const char kGoogleServicesUsername[] = "google.services.username"; +const char kGoogleServicesUserAccountId[] = "google.services.user_account_id"; } void RegisterLocalStatePrefs(PrefRegistrySimple* registry) { @@ -184,6 +185,7 @@ registry->RegisterStringPref(kLastKnownGoogleURL, std::string()); registry->RegisterStringPref(kLastPromptedGoogleURL, std::string()); registry->RegisterStringPref(kGoogleServicesUsername, std::string()); + registry->RegisterStringPref(kGoogleServicesUserAccountId, std::string()); } // This method should be periodically pruned of year+ old migrations. @@ -215,4 +217,5 @@ // Added 09/2019 prefs->ClearPref(kGoogleServicesUsername); + prefs->ClearPref(kGoogleServicesUserAccountId); }
diff --git a/ios/web/navigation/navigation_manager_impl.mm b/ios/web/navigation/navigation_manager_impl.mm index a0f15ab..359b7e4 100644 --- a/ios/web/navigation/navigation_manager_impl.mm +++ b/ios/web/navigation/navigation_manager_impl.mm
@@ -427,6 +427,7 @@ wk_navigation_util::ExtractTargetURL(reload_url, &target_url)) { reload_url = target_url; } + DCHECK(!wk_navigation_util::IsRestoreSessionUrl(reload_url)); reload_url = wk_navigation_util::CreateRedirectUrl(reload_url); }
diff --git a/ios/web/navigation/navigation_manager_impl_unittest.mm b/ios/web/navigation/navigation_manager_impl_unittest.mm index b767337..d158af9 100644 --- a/ios/web/navigation/navigation_manager_impl_unittest.mm +++ b/ios/web/navigation/navigation_manager_impl_unittest.mm
@@ -2108,7 +2108,7 @@ EXPECT_EQ(1, navigation_manager()->GetLastCommittedItemIndex()); EXPECT_EQ(urls[1], navigation_manager()->GetLastCommittedItem()->GetURL()); - for (size_t i = 0; i < items.size(); ++i) { + for (size_t i = 0; i < base::size(urls); ++i) { EXPECT_EQ(urls[i], navigation_manager()->GetItemAtIndex(i)->GetURL()); }
diff --git a/ios/web/network_context_owner.cc b/ios/web/network_context_owner.cc index a1718fa2..d152200 100644 --- a/ios/web/network_context_owner.cc +++ b/ios/web/network_context_owner.cc
@@ -21,7 +21,7 @@ NetworkContextOwner::NetworkContextOwner( net::URLRequestContextGetter* request_context, const std::vector<std::string>& cors_exempt_header_list, - network::mojom::NetworkContextPtr* network_context_client) + mojo::Remote<network::mojom::NetworkContext>* network_context_client) : request_context_(request_context) { DCHECK_CURRENTLY_ON(WebThread::UI); base::PostTask( @@ -30,7 +30,7 @@ // This is safe, since |this| will be deleted on the IO // thread, which would have to happen afterwards. base::Unretained(this), cors_exempt_header_list, - mojo::MakeRequest(network_context_client))); + network_context_client->BindNewPipeAndPassReceiver())); } NetworkContextOwner::~NetworkContextOwner() {
diff --git a/ios/web/network_context_owner_unittest.cc b/ios/web/network_context_owner_unittest.cc index f07f19d..2cecd47 100644 --- a/ios/web/network_context_owner_unittest.cc +++ b/ios/web/network_context_owner_unittest.cc
@@ -12,6 +12,7 @@ #include "base/task/post_task.h" #include "ios/web/public/test/web_task_environment.h" #include "ios/web/public/thread/web_task_traits.h" +#include "mojo/public/cpp/bindings/remote.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.h" #include "net/url_request/url_request_test_util.h" @@ -34,7 +35,7 @@ void WatchForErrors() { ASSERT_TRUE(network_context_.is_bound()); - network_context_.set_connection_error_handler(base::BindOnce( + network_context_.set_disconnect_handler(base::BindOnce( &NetworkContextOwnerTest::SawError, base::Unretained(this))); } @@ -43,7 +44,7 @@ bool saw_connection_error_; WebTaskEnvironment task_environment_; scoped_refptr<net::TestURLRequestContextGetter> context_getter_; - network::mojom::NetworkContextPtr network_context_; + mojo::Remote<network::mojom::NetworkContext> network_context_; std::unique_ptr<NetworkContextOwner> network_context_owner_; };
diff --git a/ios/web/public/browser_state.h b/ios/web/public/browser_state.h index 5982c20..5a92fe94 100644 --- a/ios/web/public/browser_state.h +++ b/ios/web/public/browser_state.h
@@ -110,7 +110,7 @@ proto_database_provider_; scoped_refptr<network::WeakWrapperSharedURLLoaderFactory> shared_url_loader_factory_; - network::mojom::NetworkContextPtr network_context_; + mojo::Remote<network::mojom::NetworkContext> network_context_; // Owns the network::NetworkContext that backs |url_loader_factory_|. Created // on the UI thread, destroyed on the IO thread.
diff --git a/ios/web/public/init/network_context_owner.h b/ios/web/public/init/network_context_owner.h index 15bc9508..a500c641 100644 --- a/ios/web/public/init/network_context_owner.h +++ b/ios/web/public/init/network_context_owner.h
@@ -35,7 +35,7 @@ NetworkContextOwner( net::URLRequestContextGetter* request_context, const std::vector<std::string>& cors_exempt_header_list, - network::mojom::NetworkContextPtr* network_context_client); + mojo::Remote<network::mojom::NetworkContext>* network_context_client); ~NetworkContextOwner() override;
diff --git a/ios/web/web_state/ui/crw_web_request_controller.mm b/ios/web/web_state/ui/crw_web_request_controller.mm index 614b7ca..29d10fd 100644 --- a/ios/web/web_state/ui/crw_web_request_controller.mm +++ b/ios/web/web_state/ui/crw_web_request_controller.mm
@@ -34,6 +34,7 @@ #error "This file requires ARC support." #endif +using web::wk_navigation_util::ExtractTargetURL; using web::wk_navigation_util::ExtractUrlFromPlaceholderUrl; using web::wk_navigation_util::IsPlaceholderUrl; using web::wk_navigation_util::IsRestoreSessionUrl; @@ -305,15 +306,25 @@ ui::PageTransition transition = [self.navigationHandler pageTransitionFromNavigationType:navigationType]; - if (web::GetWebClient()->IsSlimNavigationManagerEnabled() && - navigationType == WKNavigationTypeBackForward && - self.webView.backForwardList.currentItem) { - web::NavigationItem* currentItem = [[CRWNavigationItemHolder - holderForBackForwardListItem:self.webView.backForwardList.currentItem] - navigationItem]; - if (currentItem) { - transition = ui::PageTransitionFromInt(transition | - currentItem->GetTransitionType()); + WKBackForwardListItem* currentItem = self.webView.backForwardList.currentItem; + if (web::GetWebClient()->IsSlimNavigationManagerEnabled() && currentItem) { + // SlimNav target redirect pages should default to a RELOAD transition, + // because transition state is not persisted on restore. + GURL targetURL; + if (navigationType == WKNavigationTypeOther && + IsRestoreSessionUrl(net::GURLWithNSURL(currentItem.URL)) && + ExtractTargetURL(net::GURLWithNSURL(currentItem.URL), &targetURL) && + targetURL == URL) { + DCHECK(ui::PageTransitionIsRedirect(transition)); + transition = ui::PAGE_TRANSITION_RELOAD; + } else if (navigationType == WKNavigationTypeBackForward) { + web::NavigationItem* currentItem = [[CRWNavigationItemHolder + holderForBackForwardListItem:self.webView.backForwardList.currentItem] + navigationItem]; + if (currentItem) { + transition = ui::PageTransitionFromInt( + transition | currentItem->GetTransitionType()); + } } }
diff --git a/ios/web/web_state/web_state_observer_inttest.mm b/ios/web/web_state/web_state_observer_inttest.mm index 0a42c55..bed13504 100644 --- a/ios/web/web_state/web_state_observer_inttest.mm +++ b/ios/web/web_state/web_state_observer_inttest.mm
@@ -697,16 +697,9 @@ EXPECT_TRUE((*context)->HasUserGesture()); } ui::PageTransition actual_transition = (*context)->GetPageTransition(); - if (GetWebClient()->IsSlimNavigationManagerEnabled()) { - // TODO(crbug.com/877671): restoration navigation should be reload. - EXPECT_TRUE(PageTransitionTypeIncludingQualifiersIs( - ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT, actual_transition)) - << "Got unexpected transition: " << actual_transition; - } else { - EXPECT_TRUE(PageTransitionCoreTypeIs( - ui::PageTransition::PAGE_TRANSITION_RELOAD, actual_transition)) - << "Got unexpected transition: " << actual_transition; - } + EXPECT_TRUE(PageTransitionCoreTypeIs( + ui::PageTransition::PAGE_TRANSITION_RELOAD, actual_transition)) + << "Got unexpected transition: " << actual_transition; EXPECT_FALSE((*context)->IsSameDocument()); EXPECT_FALSE((*context)->HasCommitted()); EXPECT_FALSE((*context)->IsDownload()); @@ -750,16 +743,9 @@ EXPECT_TRUE((*context)->HasUserGesture()); } ui::PageTransition actual_transition = (*context)->GetPageTransition(); - if (GetWebClient()->IsSlimNavigationManagerEnabled()) { - // TODO(crbug.com/877671): restoration navigation should be reload. - EXPECT_TRUE(PageTransitionTypeIncludingQualifiersIs( - ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT, actual_transition)) - << "Got unexpected transition: " << actual_transition; - } else { - EXPECT_TRUE(PageTransitionCoreTypeIs( - ui::PageTransition::PAGE_TRANSITION_RELOAD, actual_transition)) - << "Got unexpected transition: " << actual_transition; - } + EXPECT_TRUE(PageTransitionCoreTypeIs( + ui::PageTransition::PAGE_TRANSITION_RELOAD, actual_transition)) + << "Got unexpected transition: " << actual_transition; EXPECT_FALSE((*context)->IsSameDocument()); EXPECT_TRUE((*context)->HasCommitted()); EXPECT_FALSE((*context)->IsDownload());
diff --git a/ios/web/web_state/web_state_unittest.mm b/ios/web/web_state/web_state_unittest.mm index 71e5df1..767d9de 100644 --- a/ios/web/web_state/web_state_unittest.mm +++ b/ios/web/web_state/web_state_unittest.mm
@@ -381,6 +381,9 @@ EXPECT_EQ("http://www.0.com/", last_committed_item->GetURL()); EXPECT_EQ("http://www.0.com/", web_state_ptr->GetLastCommittedURL()); EXPECT_EQ(0, navigation_manager->GetLastCommittedItemIndex()); + EXPECT_TRUE(ui::PageTransitionCoreTypeIs( + navigation_manager->GetLastCommittedItem()->GetTransitionType(), + ui::PAGE_TRANSITION_RELOAD)); } else { EXPECT_EQ("", web_state_ptr->GetLastCommittedURL()); EXPECT_EQ(-1, navigation_manager->GetLastCommittedItemIndex()); @@ -423,6 +426,10 @@ !web_state_ptr->IsLoading() && web_state_ptr->GetLoadingProgress() == 1.0; })); + + EXPECT_TRUE(ui::PageTransitionCoreTypeIs( + navigation_manager->GetLastCommittedItem()->GetTransitionType(), + ui::PAGE_TRANSITION_RELOAD)); } // Verifies that calling WebState::Stop() does not stop the session restoration.
diff --git a/ios/web_view/DEPS b/ios/web_view/DEPS index d3dd360..179b6350 100644 --- a/ios/web_view/DEPS +++ b/ios/web_view/DEPS
@@ -8,4 +8,6 @@ "+ios/web/public", "-ios/web/public/test/fakes/test_browser_state.h", + + "+mojo/public/cpp/bindings", ]
diff --git a/ios/web_view/internal/app/application_context.h b/ios/web_view/internal/app/application_context.h index c46e0dd..234f6b4 100644 --- a/ios/web_view/internal/app/application_context.h +++ b/ios/web_view/internal/app/application_context.h
@@ -12,6 +12,7 @@ #include "base/no_destructor.h" #include "base/sequence_checker.h" #include "ios/web/public/init/network_context_owner.h" +#include "mojo/public/cpp/bindings/remote.h" #include "services/network/public/mojom/network_service.mojom.h" namespace net { @@ -88,7 +89,7 @@ std::unique_ptr<WebViewIOThread> web_view_io_thread_; std::string application_locale_; - network::mojom::NetworkContextPtr network_context_; + mojo::Remote<network::mojom::NetworkContext> network_context_; network::mojom::URLLoaderFactoryPtr url_loader_factory_; scoped_refptr<network::WeakWrapperSharedURLLoaderFactory> shared_url_loader_factory_;
diff --git a/ios/web_view/internal/signin/web_view_identity_manager_factory.mm b/ios/web_view/internal/signin/web_view_identity_manager_factory.mm index 8ff0dec..385cf1e0 100644 --- a/ios/web_view/internal/signin/web_view_identity_manager_factory.mm +++ b/ios/web_view/internal/signin/web_view_identity_manager_factory.mm
@@ -65,7 +65,6 @@ // ChromeWebView's signin state. PrefService* pref_service = browser_state->GetPrefs(); pref_service->ClearPref(prefs::kGoogleServicesAccountId); - pref_service->ClearPref(prefs::kGoogleServicesUserAccountId); IOSWebViewSigninClient* client = WebViewSigninClientFactory::GetForBrowserState(browser_state);
diff --git a/media/fuchsia/cdm/BUILD.gn b/media/fuchsia/cdm/BUILD.gn index a3baef0a..93f868a 100644 --- a/media/fuchsia/cdm/BUILD.gn +++ b/media/fuchsia/cdm/BUILD.gn
@@ -13,8 +13,8 @@ "fuchsia_cdm_provider.h", "fuchsia_decryptor.cc", "fuchsia_decryptor.h", - "stream_processor_decryptor.cc", - "stream_processor_decryptor.h", + "fuchsia_stream_decryptor.cc", + "fuchsia_stream_decryptor.h", ] public_deps = [
diff --git a/media/fuchsia/cdm/fuchsia_decryptor.cc b/media/fuchsia/cdm/fuchsia_decryptor.cc index a84ea4a..17b946b 100644 --- a/media/fuchsia/cdm/fuchsia_decryptor.cc +++ b/media/fuchsia/cdm/fuchsia_decryptor.cc
@@ -8,7 +8,7 @@ #include "base/logging.h" #include "media/base/decoder_buffer.h" #include "media/base/video_frame.h" -#include "media/fuchsia/cdm/stream_processor_decryptor.h" +#include "media/fuchsia/cdm/fuchsia_stream_decryptor.h" namespace media { @@ -35,7 +35,7 @@ } if (!audio_decryptor_) - audio_decryptor_ = StreamProcessorDecryptor::CreateAudioDecryptor(cdm_); + audio_decryptor_ = FuchsiaClearStreamDecryptor::Create(cdm_); audio_decryptor_->Decrypt(std::move(encrypted), decrypt_cb); } @@ -54,7 +54,6 @@ void FuchsiaDecryptor::InitializeVideoDecoder(const VideoDecoderConfig& config, const DecoderInitCB& init_cb) { - NOTIMPLEMENTED(); init_cb.Run(false); } @@ -69,18 +68,16 @@ void FuchsiaDecryptor::DecryptAndDecodeVideo( scoped_refptr<DecoderBuffer> encrypted, const VideoDecodeCB& video_decode_cb) { - NOTIMPLEMENTED(); + NOTREACHED(); video_decode_cb.Run(Status::kError, nullptr); } void FuchsiaDecryptor::ResetDecoder(StreamType stream_type) { - DCHECK_EQ(stream_type, StreamType::kVideo); - NOTIMPLEMENTED(); + NOTREACHED(); } void FuchsiaDecryptor::DeinitializeDecoder(StreamType stream_type) { - DCHECK_EQ(stream_type, StreamType::kVideo); - NOTIMPLEMENTED(); + NOTREACHED(); } bool FuchsiaDecryptor::CanAlwaysDecrypt() {
diff --git a/media/fuchsia/cdm/fuchsia_decryptor.h b/media/fuchsia/cdm/fuchsia_decryptor.h index 76ed365..cc15dd9 100644 --- a/media/fuchsia/cdm/fuchsia_decryptor.h +++ b/media/fuchsia/cdm/fuchsia_decryptor.h
@@ -18,7 +18,8 @@ } // namespace fuchsia namespace media { -class StreamProcessorDecryptor; + +class FuchsiaClearStreamDecryptor; class FuchsiaDecryptor : public Decryptor { public: @@ -48,7 +49,7 @@ private: fuchsia::media::drm::ContentDecryptionModule* const cdm_; - std::unique_ptr<StreamProcessorDecryptor> audio_decryptor_; + std::unique_ptr<FuchsiaClearStreamDecryptor> audio_decryptor_; DISALLOW_COPY_AND_ASSIGN(FuchsiaDecryptor); };
diff --git a/media/fuchsia/cdm/stream_processor_decryptor.cc b/media/fuchsia/cdm/fuchsia_stream_decryptor.cc similarity index 76% rename from media/fuchsia/cdm/stream_processor_decryptor.cc rename to media/fuchsia/cdm/fuchsia_stream_decryptor.cc index 9c1426a..88fdca3 100644 --- a/media/fuchsia/cdm/stream_processor_decryptor.cc +++ b/media/fuchsia/cdm/fuchsia_stream_decryptor.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "media/fuchsia/cdm/stream_processor_decryptor.h" +#include "media/fuchsia/cdm/fuchsia_stream_decryptor.h" #include <fuchsia/media/cpp/fidl.h> #include <fuchsia/media/drm/cpp/fidl.h> @@ -20,9 +20,9 @@ namespace media { namespace { -// Decryptor will copy decrypted data immediately once it's available. Client -// just needs one buffer. -const uint32_t kMaxUsedOutputFrames = 1; +// FuchsiaClearStreamDecryptor copies decrypted data immediately once it's +// available, so it doesn't need more than one output buffer. +const size_t kMinOutputAudioOutputFrames = 1; std::string GetEncryptionMode(EncryptionMode mode) { switch (mode) { @@ -87,32 +87,23 @@ } // namespace -StreamProcessorDecryptor::StreamProcessorDecryptor( +FuchsiaStreamDecryptorBase::FuchsiaStreamDecryptorBase( fuchsia::media::StreamProcessorPtr processor) : processor_(std::move(processor), this) {} -StreamProcessorDecryptor::~StreamProcessorDecryptor() = default; +FuchsiaStreamDecryptorBase::~FuchsiaStreamDecryptorBase() = default; -void StreamProcessorDecryptor::Decrypt(scoped_refptr<DecoderBuffer> encrypted, - Decryptor::DecryptCB decrypt_cb) { +void FuchsiaStreamDecryptorBase::DecryptInternal( + scoped_refptr<DecoderBuffer> encrypted) { DCHECK(!encrypted->end_of_stream()) << "EOS frame is always clear."; - DCHECK(!decrypt_cb_); DCHECK(!pending_encrypted_buffer_); - decrypt_cb_ = std::move(decrypt_cb); - // Input buffer writer is not available. Wait. if (!input_writer_) { pending_encrypted_buffer_ = std::move(encrypted); return; } - if (!input_pool_->is_live()) { - DLOG(ERROR) << "Input buffer pool is dead."; - std::move(decrypt_cb_).Run(Decryptor::kError, nullptr); - return; - } - // Decryptor can only process one buffer at a time, which means there // should be always enough unused buffers. base::Optional<size_t> buf_index = input_writer_->Acquire(); @@ -133,7 +124,7 @@ // TODO(yucliu): Handle large encrypted buffer correctly. For now, just // reject the decryption. DLOG(ERROR) << "Encrypted data size is too big."; - std::move(decrypt_cb_).Run(Decryptor::kError, nullptr); + OnError(); return; } @@ -143,25 +134,21 @@ auto input_packet = StreamProcessorHelper::IoPacket::CreateInput( index, encrypted->data_size(), encrypted->timestamp(), GetFormatDetails(decrypt_config), - base::BindOnce(&StreamProcessorDecryptor::OnInputPacketReleased, + base::BindOnce(&FuchsiaStreamDecryptorBase::OnInputPacketReleased, base::Unretained(this), index)); processor_.Process(std::move(input_packet)); } -void StreamProcessorDecryptor::CancelDecrypt() { +void FuchsiaStreamDecryptorBase::ResetStream() { // Close current stream and drop all the cached decoder buffers. - // Keep input/output_pool_ to avoid buffer re-allocation. + // Keep input and output buffers to avoid buffer re-allocation. processor_.Reset(); pending_encrypted_buffer_ = nullptr; - - // Fire |decrypt_cb_| immediately as required by Decryptor::CancelDecrypt. - if (decrypt_cb_) - std::move(decrypt_cb_).Run(Decryptor::kSuccess, nullptr); } // StreamProcessorHelper::Client implementation: -void StreamProcessorDecryptor::AllocateInputBuffers( +void FuchsiaStreamDecryptorBase::AllocateInputBuffers( const fuchsia::media::StreamBufferConstraints& stream_constraints) { base::Optional<fuchsia::sysmem::BufferCollectionConstraints> buffer_constraints = @@ -177,11 +164,95 @@ input_pool_creator_->Create( std::move(buffer_constraints).value(), - base::BindOnce(&StreamProcessorDecryptor::OnInputBufferPoolAvailable, + base::BindOnce(&FuchsiaStreamDecryptorBase::OnInputBufferPoolCreated, base::Unretained(this))); } -void StreamProcessorDecryptor::AllocateOutputBuffers( +void FuchsiaStreamDecryptorBase::OnInputPacketReleased(size_t index) { + input_writer_->Release(index); + + if (!pending_encrypted_buffer_) + return; + + // If there are pending decryption request, handle it now since we have + // available input buffers. + DecryptInternal(std::move(pending_encrypted_buffer_)); +} + +void FuchsiaStreamDecryptorBase::OnInputBufferPoolCreated( + std::unique_ptr<SysmemBufferPool> pool) { + if (!pool) { + DLOG(ERROR) << "Fail to allocate input buffer."; + OnError(); + return; + } + + input_pool_ = std::move(pool); + + // Provide token before enabling writer. Tokens must be provided to + // StreamProcessor before getting the allocated buffers. + processor_.CompleteInputBuffersAllocation(input_pool_->TakeToken()); + + input_pool_->CreateWriter(base::BindOnce( + &FuchsiaStreamDecryptorBase::OnInputBufferPoolWriterCreated, + base::Unretained(this))); +} + +void FuchsiaStreamDecryptorBase::OnInputBufferPoolWriterCreated( + std::unique_ptr<SysmemBufferWriter> writer) { + if (!writer) { + LOG(ERROR) << "Fail to enable input buffer writer"; + OnError(); + return; + } + + DCHECK(!input_writer_); + input_writer_ = std::move(writer); + + if (pending_encrypted_buffer_) { + DecryptInternal(std::move(pending_encrypted_buffer_)); + } +} + +std::unique_ptr<FuchsiaClearStreamDecryptor> +FuchsiaClearStreamDecryptor::Create( + fuchsia::media::drm::ContentDecryptionModule* cdm) { + DCHECK(cdm); + + fuchsia::media::drm::DecryptorParams params; + params.set_require_secure_mode(false); + params.mutable_input_details()->set_format_details_version_ordinal(0); + fuchsia::media::StreamProcessorPtr stream_processor; + cdm->CreateDecryptor(std::move(params), stream_processor.NewRequest()); + + return std::make_unique<FuchsiaClearStreamDecryptor>( + std::move(stream_processor)); +} + +FuchsiaClearStreamDecryptor::FuchsiaClearStreamDecryptor( + fuchsia::media::StreamProcessorPtr processor) + : FuchsiaStreamDecryptorBase(std::move(processor)) {} + +FuchsiaClearStreamDecryptor::~FuchsiaClearStreamDecryptor() = default; + +void FuchsiaClearStreamDecryptor::Decrypt( + scoped_refptr<DecoderBuffer> encrypted, + Decryptor::DecryptCB decrypt_cb) { + DCHECK(!decrypt_cb_); + decrypt_cb_ = std::move(decrypt_cb); + + DecryptInternal(std::move(encrypted)); +} + +void FuchsiaClearStreamDecryptor::CancelDecrypt() { + ResetStream(); + + // Fire |decrypt_cb_| immediately as required by Decryptor::CancelDecrypt. + if (decrypt_cb_) + std::move(decrypt_cb_).Run(Decryptor::kSuccess, nullptr); +} + +void FuchsiaClearStreamDecryptor::AllocateOutputBuffers( const fuchsia::media::StreamBufferConstraints& stream_constraints) { if (!stream_constraints.has_packet_count_for_client_max() || !stream_constraints.has_packet_count_for_client_min()) { @@ -190,10 +261,8 @@ return; } - size_t max_used_output_buffers = std::min( - kMaxUsedOutputFrames, stream_constraints.packet_count_for_client_max()); - max_used_output_buffers = std::max( - max_used_output_buffers, + size_t max_used_output_buffers = std::max( + kMinOutputAudioOutputFrames, static_cast<size_t>(stream_constraints.packet_count_for_client_min())); output_pool_creator_ = @@ -201,19 +270,19 @@ output_pool_creator_->Create( SysmemBufferReader::GetRecommendedConstraints(max_used_output_buffers), - base::BindOnce(&StreamProcessorDecryptor::OnOutputBufferPoolAvailable, + base::BindOnce(&FuchsiaClearStreamDecryptor::OnOutputBufferPoolCreated, base::Unretained(this), max_used_output_buffers)); } -void StreamProcessorDecryptor::OnProcessEos() { +void FuchsiaClearStreamDecryptor::OnProcessEos() { // Decryptor never pushes EOS frame. NOTREACHED(); } -void StreamProcessorDecryptor::OnOutputFormat( +void FuchsiaClearStreamDecryptor::OnOutputFormat( fuchsia::media::StreamOutputFormat format) {} -void StreamProcessorDecryptor::OnOutputPacket( +void FuchsiaClearStreamDecryptor::OnOutputPacket( std::unique_ptr<StreamProcessorHelper::IoPacket> packet) { DCHECK(output_reader_); if (!output_pool_->is_live()) { @@ -238,69 +307,18 @@ std::move(decrypt_cb_).Run(Decryptor::kSuccess, std::move(clear_buffer)); } -void StreamProcessorDecryptor::OnNoKey() { +void FuchsiaClearStreamDecryptor::OnNoKey() { if (decrypt_cb_) std::move(decrypt_cb_).Run(Decryptor::kNoKey, nullptr); } -void StreamProcessorDecryptor::OnError() { - pending_encrypted_buffer_ = nullptr; +void FuchsiaClearStreamDecryptor::OnError() { + ResetStream(); if (decrypt_cb_) std::move(decrypt_cb_).Run(Decryptor::kError, nullptr); - - processor_.Reset(); } -void StreamProcessorDecryptor::OnInputPacketReleased(size_t index) { - input_writer_->Release(index); - - if (!pending_encrypted_buffer_) - return; - - DCHECK(decrypt_cb_); - - // If there're pending decryption request, handle it now since we have - // available input buffers. - Decrypt(std::move(pending_encrypted_buffer_), std::move(decrypt_cb_)); -} - -void StreamProcessorDecryptor::OnInputBufferPoolAvailable( - std::unique_ptr<SysmemBufferPool> pool) { - if (!pool) { - DLOG(ERROR) << "Fail to allocate input buffer."; - OnError(); - return; - } - - input_pool_ = std::move(pool); - - // Provide token before enabling writer. Tokens must be provided to - // StreamProcessor before getting the allocated buffers. - processor_.CompleteInputBuffersAllocation(input_pool_->TakeToken()); - - input_pool_->CreateWriter( - base::BindOnce(&StreamProcessorDecryptor::OnInputBufferPoolWriter, - base::Unretained(this))); -} - -void StreamProcessorDecryptor::OnInputBufferPoolWriter( - std::unique_ptr<SysmemBufferWriter> writer) { - if (!writer) { - LOG(ERROR) << "Fail to enable input buffer writer"; - OnError(); - return; - } - - DCHECK(!input_writer_); - input_writer_ = std::move(writer); - - if (pending_encrypted_buffer_) { - DCHECK(decrypt_cb_); - Decrypt(std::move(pending_encrypted_buffer_), std::move(decrypt_cb_)); - } -} - -void StreamProcessorDecryptor::OnOutputBufferPoolAvailable( +void FuchsiaClearStreamDecryptor::OnOutputBufferPoolCreated( size_t max_used_output_buffers, std::unique_ptr<SysmemBufferPool> pool) { if (!pool) { @@ -316,12 +334,12 @@ processor_.CompleteOutputBuffersAllocation(max_used_output_buffers, output_pool_->TakeToken()); - output_pool_->CreateReader( - base::BindOnce(&StreamProcessorDecryptor::OnOutputBufferPoolReader, - base::Unretained(this))); + output_pool_->CreateReader(base::BindOnce( + &FuchsiaClearStreamDecryptor::OnOutputBufferPoolReaderCreated, + base::Unretained(this))); } -void StreamProcessorDecryptor::OnOutputBufferPoolReader( +void FuchsiaClearStreamDecryptor::OnOutputBufferPoolReaderCreated( std::unique_ptr<SysmemBufferReader> reader) { if (!reader) { LOG(ERROR) << "Fail to enable output buffer reader."; @@ -333,19 +351,4 @@ output_reader_ = std::move(reader); } -std::unique_ptr<StreamProcessorDecryptor> -StreamProcessorDecryptor::CreateAudioDecryptor( - fuchsia::media::drm::ContentDecryptionModule* cdm) { - DCHECK(cdm); - - fuchsia::media::drm::DecryptorParams params; - params.set_require_secure_mode(false); - params.mutable_input_details()->set_format_details_version_ordinal(0); - fuchsia::media::StreamProcessorPtr stream_processor; - cdm->CreateDecryptor(std::move(params), stream_processor.NewRequest()); - - return std::make_unique<StreamProcessorDecryptor>( - std::move(stream_processor)); -} - } // namespace media
diff --git a/media/fuchsia/cdm/fuchsia_stream_decryptor.h b/media/fuchsia/cdm/fuchsia_stream_decryptor.h new file mode 100644 index 0000000..323062c --- /dev/null +++ b/media/fuchsia/cdm/fuchsia_stream_decryptor.h
@@ -0,0 +1,98 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_FUCHSIA_CDM_FUCHSIA_STREAM_DECRYPTOR_H_ +#define MEDIA_FUCHSIA_CDM_FUCHSIA_STREAM_DECRYPTOR_H_ + +#include <fuchsia/media/drm/cpp/fidl.h> + +#include <memory> + +#include "media/base/decryptor.h" +#include "media/fuchsia/common/stream_processor_helper.h" +#include "media/fuchsia/common/sysmem_buffer_pool.h" + +namespace media { +class SysmemBufferReader; +class SysmemBufferWriter; + +// Base class for media stream decryptor implementations. +class FuchsiaStreamDecryptorBase : public StreamProcessorHelper::Client { + public: + explicit FuchsiaStreamDecryptorBase( + fuchsia::media::StreamProcessorPtr processor); + ~FuchsiaStreamDecryptorBase() override; + + protected: + // StreamProcessorHelper::Client overrides. + void AllocateInputBuffers( + const fuchsia::media::StreamBufferConstraints& stream_constraints) final; + + void DecryptInternal(scoped_refptr<DecoderBuffer> encrypted); + void ResetStream(); + + StreamProcessorHelper processor_; + + BufferAllocator allocator_; + + private: + void OnInputPacketReleased(size_t index); + void OnInputBufferPoolCreated(std::unique_ptr<SysmemBufferPool> pool); + void OnInputBufferPoolWriterCreated( + std::unique_ptr<SysmemBufferWriter> writer); + + // Pending buffers due to input buffer pool not available. + scoped_refptr<DecoderBuffer> pending_encrypted_buffer_; + + std::unique_ptr<SysmemBufferPool::Creator> input_pool_creator_; + std::unique_ptr<SysmemBufferPool> input_pool_; + std::unique_ptr<SysmemBufferWriter> input_writer_; + + DISALLOW_COPY_AND_ASSIGN(FuchsiaStreamDecryptorBase); +}; + +// Stream decryptor used by FuchsiaDecryptor for audio streams. +class FuchsiaClearStreamDecryptor : public FuchsiaStreamDecryptorBase { + public: + static std::unique_ptr<FuchsiaClearStreamDecryptor> Create( + fuchsia::media::drm::ContentDecryptionModule* cdm); + + FuchsiaClearStreamDecryptor(fuchsia::media::StreamProcessorPtr processor); + ~FuchsiaClearStreamDecryptor() override; + + // Decrypt() behavior should match media::Decryptor interface. + void Decrypt(scoped_refptr<DecoderBuffer> encrypted, + Decryptor::DecryptCB decrypt_cb); + void CancelDecrypt(); + + private: + // StreamProcessorHelper::Client overrides. + void AllocateOutputBuffers(const fuchsia::media::StreamBufferConstraints& + stream_constraints) override; + void OnProcessEos() override; + void OnOutputFormat(fuchsia::media::StreamOutputFormat format) override; + void OnOutputPacket( + std::unique_ptr<StreamProcessorHelper::IoPacket> packet) override; + void OnNoKey() override; + void OnError() override; + + void OnOutputBufferPoolCreated(size_t max_used_output_buffers, + std::unique_ptr<SysmemBufferPool> pool); + void OnOutputBufferPoolReaderCreated( + std::unique_ptr<SysmemBufferReader> reader); + + Decryptor::DecryptCB decrypt_cb_; + + std::unique_ptr<SysmemBufferPool::Creator> output_pool_creator_; + std::unique_ptr<SysmemBufferPool> output_pool_; + std::unique_ptr<SysmemBufferReader> output_reader_; + + scoped_refptr<DecoderBuffer> clear_buffer_; + + DISALLOW_COPY_AND_ASSIGN(FuchsiaClearStreamDecryptor); +}; + +} // namespace media + +#endif // MEDIA_FUCHSIA_CDM_FUCHSIA_STREAM_DECRYPTOR_H_
diff --git a/media/fuchsia/cdm/stream_processor_decryptor.h b/media/fuchsia/cdm/stream_processor_decryptor.h deleted file mode 100644 index c30e20f..0000000 --- a/media/fuchsia/cdm/stream_processor_decryptor.h +++ /dev/null
@@ -1,78 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MEDIA_FUCHSIA_CDM_STREAM_PROCESSOR_DECRYPTOR_H_ -#define MEDIA_FUCHSIA_CDM_STREAM_PROCESSOR_DECRYPTOR_H_ - -#include <fuchsia/media/drm/cpp/fidl.h> - -#include <memory> - -#include "media/base/decryptor.h" -#include "media/fuchsia/common/stream_processor_helper.h" -#include "media/fuchsia/common/sysmem_buffer_pool.h" - -namespace media { -class SysmemBufferReader; -class SysmemBufferWriter; - -// Class to handle decryption for one stream. All the APIs have the same -// requirement as Decryptor. -class StreamProcessorDecryptor : public StreamProcessorHelper::Client { - public: - static std::unique_ptr<StreamProcessorDecryptor> CreateAudioDecryptor( - fuchsia::media::drm::ContentDecryptionModule* cdm); - - explicit StreamProcessorDecryptor( - fuchsia::media::StreamProcessorPtr processor); - ~StreamProcessorDecryptor() override; - - void Decrypt(scoped_refptr<DecoderBuffer> encrypted, - Decryptor::DecryptCB decrypt_cb); - void CancelDecrypt(); - - // StreamProcessorHelper::Client implementation: - void AllocateInputBuffers(const fuchsia::media::StreamBufferConstraints& - stream_constraints) override; - void AllocateOutputBuffers(const fuchsia::media::StreamBufferConstraints& - stream_constraints) override; - void OnProcessEos() override; - void OnOutputFormat(fuchsia::media::StreamOutputFormat format) override; - void OnOutputPacket( - std::unique_ptr<StreamProcessorHelper::IoPacket> packet) override; - void OnNoKey() override; - void OnError() override; - - private: - void OnInputPacketReleased(size_t index); - void OnInputBufferPoolAvailable(std::unique_ptr<SysmemBufferPool> pool); - void OnInputBufferPoolWriter(std::unique_ptr<SysmemBufferWriter> writer); - void OnOutputBufferPoolAvailable(size_t max_used_output_buffers, - std::unique_ptr<SysmemBufferPool> pool); - void OnOutputBufferPoolReader(std::unique_ptr<SysmemBufferReader> reader); - - StreamProcessorHelper processor_; - BufferAllocator allocator_; - - // Pending buffers due to input buffer pool not available. - scoped_refptr<DecoderBuffer> pending_encrypted_buffer_; - - Decryptor::DecryptCB decrypt_cb_; - - std::unique_ptr<SysmemBufferPool::Creator> input_pool_creator_; - std::unique_ptr<SysmemBufferPool> input_pool_; - std::unique_ptr<SysmemBufferWriter> input_writer_; - - std::unique_ptr<SysmemBufferPool::Creator> output_pool_creator_; - std::unique_ptr<SysmemBufferPool> output_pool_; - std::unique_ptr<SysmemBufferReader> output_reader_; - - scoped_refptr<DecoderBuffer> clear_buffer_; - - DISALLOW_COPY_AND_ASSIGN(StreamProcessorDecryptor); -}; - -} // namespace media - -#endif // MEDIA_FUCHSIA_CDM_STREAM_PROCESSOR_DECRYPTOR_H_
diff --git a/media/gpu/windows/d3d11_video_decoder.cc b/media/gpu/windows/d3d11_video_decoder.cc index 7099ee9..23aab52d 100644 --- a/media/gpu/windows/d3d11_video_decoder.cc +++ b/media/gpu/windows/d3d11_video_decoder.cc
@@ -136,7 +136,8 @@ // Explicitly destroy the decoder, since it can reference picture buffers. accelerated_video_decoder_.reset(); - AddLifetimeProgressionStage(D3D11LifetimeProgression::kPlaybackSucceeded); + if (already_initialized_) + AddLifetimeProgressionStage(D3D11LifetimeProgression::kPlaybackSucceeded); } std::string D3D11VideoDecoder::GetDisplayName() const { @@ -188,7 +189,6 @@ const WaitingCB& waiting_cb) { if (already_initialized_) AddLifetimeProgressionStage(D3D11LifetimeProgression::kPlaybackSucceeded); - already_initialized_ = true; AddLifetimeProgressionStage(D3D11LifetimeProgression::kInitializeStarted); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -405,7 +405,8 @@ void D3D11VideoDecoder::AddLifetimeProgressionStage( D3D11LifetimeProgression stage) { - DCHECK(already_initialized_); + already_initialized_ = + (stage == D3D11LifetimeProgression::kInitializeSucceeded); const std::string uma_name("Media.D3D11.DecoderLifetimeProgression"); base::UmaHistogramEnumeration(uma_name, stage); }
diff --git a/media/mojo/services/mojo_video_encode_accelerator_provider.cc b/media/mojo/services/mojo_video_encode_accelerator_provider.cc index f11c787..f9f8f2e 100644 --- a/media/mojo/services/mojo_video_encode_accelerator_provider.cc +++ b/media/mojo/services/mojo_video_encode_accelerator_provider.cc
@@ -10,20 +10,21 @@ #include "base/logging.h" #include "media/base/bind_to_current_loop.h" #include "media/base/limits.h" -#include "mojo/public/cpp/bindings/strong_binding.h" +#include "mojo/public/cpp/bindings/self_owned_receiver.h" #include "mojo/public/cpp/system/platform_handle.h" namespace media { // static void MojoVideoEncodeAcceleratorProvider::Create( - mojom::VideoEncodeAcceleratorProviderRequest request, + mojo::PendingReceiver<mojom::VideoEncodeAcceleratorProvider> receiver, const CreateAndInitializeVideoEncodeAcceleratorCallback& create_vea_callback, const gpu::GpuPreferences& gpu_preferences) { - mojo::MakeStrongBinding(std::make_unique<MojoVideoEncodeAcceleratorProvider>( - create_vea_callback, gpu_preferences), - std::move(request)); + mojo::MakeSelfOwnedReceiver( + std::make_unique<MojoVideoEncodeAcceleratorProvider>(create_vea_callback, + gpu_preferences), + std::move(receiver)); } MojoVideoEncodeAcceleratorProvider::MojoVideoEncodeAcceleratorProvider(
diff --git a/media/mojo/services/mojo_video_encode_accelerator_provider.h b/media/mojo/services/mojo_video_encode_accelerator_provider.h index 86533c48..20c1cc83 100644 --- a/media/mojo/services/mojo_video_encode_accelerator_provider.h +++ b/media/mojo/services/mojo_video_encode_accelerator_provider.h
@@ -26,10 +26,11 @@ MojoVideoEncodeAcceleratorService:: CreateAndInitializeVideoEncodeAcceleratorCallback; - static void Create(mojom::VideoEncodeAcceleratorProviderRequest request, - const CreateAndInitializeVideoEncodeAcceleratorCallback& - create_vea_callback, - const gpu::GpuPreferences& gpu_preferences); + static void Create( + mojo::PendingReceiver<mojom::VideoEncodeAcceleratorProvider> receiver, + const CreateAndInitializeVideoEncodeAcceleratorCallback& + create_vea_callback, + const gpu::GpuPreferences& gpu_preferences); MojoVideoEncodeAcceleratorProvider( const CreateAndInitializeVideoEncodeAcceleratorCallback&
diff --git a/mojo/public/tools/bindings/mojom_bindings_generator.py b/mojo/public/tools/bindings/mojom_bindings_generator.py index d8a2118e..06e61ddf 100755 --- a/mojo/public/tools/bindings/mojom_bindings_generator.py +++ b/mojo/public/tools/bindings/mojom_bindings_generator.py
@@ -52,6 +52,10 @@ from mojom.parse.conditional_features import RemoveDisabledDefinitions from mojom.parse.parser import Parse +sys.path.append( + os.path.join(_GetDirAbove("mojo"), "tools", "diagnosis")) +import crbug_1001171 + _BUILTIN_GENERATORS = { "c++": "mojom_cpp_generator", @@ -547,4 +551,5 @@ if __name__ == "__main__": - sys.exit(main()) + with crbug_1001171.DumpStateOnLookupError(): + sys.exit(main())
diff --git a/mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py b/mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py index de7d3b2..948ba3d 100644 --- a/mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py +++ b/mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py
@@ -4,14 +4,9 @@ # Based on third_party/WebKit/Source/build/scripts/template_expander.py. -import codecs import os.path import sys -# Cache the ascii codec to ensure pickle can find it at jinja2 import time. -# See https://crbug.com/997598#c5 for context. -codecs.lookup('ascii') - _current_dir = os.path.dirname(os.path.realpath(__file__)) # jinja2 is in chromium's third_party directory # Insert at front to override system libraries, and after path[0] == script dir
diff --git a/net/BUILD.gn b/net/BUILD.gn index 951d506..0cf712e 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -1327,18 +1327,6 @@ "third_party/quiche/src/http2/platform/api/http2_string_utils.h", "third_party/quiche/src/quic/core/congestion_control/bandwidth_sampler.cc", "third_party/quiche/src/quic/core/congestion_control/bandwidth_sampler.h", - "third_party/quiche/src/quic/core/congestion_control/bbr2_drain.cc", - "third_party/quiche/src/quic/core/congestion_control/bbr2_drain.h", - "third_party/quiche/src/quic/core/congestion_control/bbr2_misc.cc", - "third_party/quiche/src/quic/core/congestion_control/bbr2_misc.h", - "third_party/quiche/src/quic/core/congestion_control/bbr2_probe_bw.cc", - "third_party/quiche/src/quic/core/congestion_control/bbr2_probe_bw.h", - "third_party/quiche/src/quic/core/congestion_control/bbr2_probe_rtt.cc", - "third_party/quiche/src/quic/core/congestion_control/bbr2_probe_rtt.h", - "third_party/quiche/src/quic/core/congestion_control/bbr2_sender.cc", - "third_party/quiche/src/quic/core/congestion_control/bbr2_sender.h", - "third_party/quiche/src/quic/core/congestion_control/bbr2_startup.cc", - "third_party/quiche/src/quic/core/congestion_control/bbr2_startup.h", "third_party/quiche/src/quic/core/congestion_control/bbr_sender.cc", "third_party/quiche/src/quic/core/congestion_control/bbr_sender.h", "third_party/quiche/src/quic/core/congestion_control/cubic_bytes.cc", @@ -5486,7 +5474,6 @@ "third_party/quiche/src/http2/tools/random_util.cc", "third_party/quiche/src/http2/tools/random_util.h", "third_party/quiche/src/quic/core/congestion_control/bandwidth_sampler_test.cc", - "third_party/quiche/src/quic/core/congestion_control/bbr2_simulator_test.cc", "third_party/quiche/src/quic/core/congestion_control/bbr_sender_test.cc", "third_party/quiche/src/quic/core/congestion_control/cubic_bytes_test.cc", "third_party/quiche/src/quic/core/congestion_control/general_loss_algorithm_test.cc",
diff --git a/net/quic/quic_flags_list.h b/net/quic/quic_flags_list.h index ac9797a..f34fb2a1 100644 --- a/net/quic/quic_flags_list.h +++ b/net/quic/quic_flags_list.h
@@ -49,22 +49,6 @@ // Congestion window gain for QUIC BBR during PROBE_BW phase. QUIC_FLAG(double, FLAGS_quic_bbr_cwnd_gain, 2.0f) -// The default minimum duration for BBRv2-native probes, in milliseconds. -QUIC_FLAG(int32_t, FLAGS_quic_bbr2_default_probe_bw_base_duration_ms, 2000) - -// The default upper bound of the random amount of BBRv2-native probes, in -// milliseconds. -QUIC_FLAG(int32_t, FLAGS_quic_bbr2_default_probe_bw_max_rand_duration_ms, 1000) - -// The default period for entering PROBE_RTT, in milliseconds. -QUIC_FLAG(int32_t, FLAGS_quic_bbr2_default_probe_rtt_period_ms, 10000) - -// The default loss threshold for QUIC BBRv2, should be a value between 0 and 1. -QUIC_FLAG(double, FLAGS_quic_bbr2_default_loss_threshold, 0.02) - -// The default minimum number of loss marking events to exit STARTUP. -QUIC_FLAG(int32_t, FLAGS_quic_bbr2_default_startup_full_loss_count, 8) - // If true, adjust congestion window when doing bandwidth resumption in BBR. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_fix_bbr_cwnd_in_bandwidth_resumption,
diff --git a/services/tracing/perfetto/perfetto_service.cc b/services/tracing/perfetto/perfetto_service.cc index b521b04c..995c0342 100644 --- a/services/tracing/perfetto/perfetto_service.cc +++ b/services/tracing/perfetto/perfetto_service.cc
@@ -71,16 +71,17 @@ return service_.get(); } -void PerfettoService::BindRequest(mojom::PerfettoServiceRequest request, - uint32_t pid) { - bindings_.AddBinding(this, std::move(request), pid); +void PerfettoService::BindReceiver( + mojo::PendingReceiver<mojom::PerfettoService> receiver, + uint32_t pid) { + receivers_.Add(this, std::move(receiver), pid); } void PerfettoService::ConnectToProducerHost( mojom::ProducerClientPtr producer_client, mojom::ProducerHostRequest producer_host_request) { auto new_producer = std::make_unique<ProducerHost>(); - uint32_t producer_pid = bindings_.dispatch_context(); + uint32_t producer_pid = receivers_.current_context(); new_producer->Initialize(std::move(producer_client), service_.get(), base::StrCat({mojom::kPerfettoProducerNamePrefix, base::NumberToString(producer_pid)}));
diff --git a/services/tracing/perfetto/perfetto_service.h b/services/tracing/perfetto/perfetto_service.h index aae5ede3..cd997d07 100644 --- a/services/tracing/perfetto/perfetto_service.h +++ b/services/tracing/perfetto/perfetto_service.h
@@ -9,7 +9,7 @@ #include <set> #include "base/macros.h" -#include "mojo/public/cpp/bindings/binding_set.h" +#include "mojo/public/cpp/bindings/receiver_set.h" #include "mojo/public/cpp/bindings/strong_binding_set.h" #include "services/service_manager/public/cpp/identity.h" #include "services/tracing/perfetto/consumer_host.h" @@ -36,7 +36,8 @@ static bool ParsePidFromProducerName(const std::string& producer_name, base::ProcessId* pid); - void BindRequest(mojom::PerfettoServiceRequest request, uint32_t pid); + void BindReceiver(mojo::PendingReceiver<mojom::PerfettoService> receiver, + uint32_t pid); // mojom::PerfettoService implementation. void ConnectToProducerHost(mojom::ProducerClientPtr producer_client, @@ -71,12 +72,12 @@ } private: - void BindOnSequence(mojom::PerfettoServiceRequest request); + void BindOnSequence(mojo::PendingReceiver<mojom::PerfettoService> receiver); void CreateServiceOnSequence(); PerfettoTaskRunner perfetto_task_runner_; std::unique_ptr<perfetto::TracingService> service_; - mojo::BindingSet<mojom::PerfettoService, uint32_t> bindings_; + mojo::ReceiverSet<mojom::PerfettoService, uint32_t> receivers_; mojo::StrongBindingSet<mojom::ProducerHost> producer_bindings_; std::set<ConsumerHost::TracingSession*> tracing_sessions_; // Not owned. std::set<base::ProcessId> active_service_pids_;
diff --git a/services/tracing/public/cpp/perfetto/producer_client.cc b/services/tracing/public/cpp/perfetto/producer_client.cc index c2f5fec7..a8230018 100644 --- a/services/tracing/public/cpp/perfetto/producer_client.cc +++ b/services/tracing/public/cpp/perfetto/producer_client.cc
@@ -10,6 +10,7 @@ #include "base/no_destructor.h" #include "base/process/process.h" #include "base/task/post_task.h" +#include "mojo/public/cpp/bindings/remote.h" #include "services/tracing/public/cpp/perfetto/shared_memory.h" #include "services/tracing/public/cpp/perfetto/trace_event_data_source.h" #include "services/tracing/public/mojom/constants.mojom.h" @@ -29,12 +30,13 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); } -void ProducerClient::Connect(mojom::PerfettoServicePtr perfetto_service) { +void ProducerClient::Connect( + mojo::PendingRemote<mojom::PerfettoService> perfetto_service) { mojom::ProducerClientPtr client; auto client_request = mojo::MakeRequest(&client); mojom::ProducerHostPtrInfo host_info; - perfetto_service->ConnectToProducerHost(std::move(client), - mojo::MakeRequest(&host_info)); + mojo::Remote<mojom::PerfettoService>(std::move(perfetto_service)) + ->ConnectToProducerHost(std::move(client), mojo::MakeRequest(&host_info)); task_runner()->GetOrCreateTaskRunner()->PostTask( FROM_HERE, base::BindOnce(&ProducerClient::BindClientAndHostPipesOnSequence,
diff --git a/services/tracing/public/cpp/perfetto/producer_client.h b/services/tracing/public/cpp/perfetto/producer_client.h index f578d29..fccb89c 100644 --- a/services/tracing/public/cpp/perfetto/producer_client.h +++ b/services/tracing/public/cpp/perfetto/producer_client.h
@@ -45,7 +45,7 @@ bool IsTracingActive() override; - void Connect(mojom::PerfettoServicePtr perfetto_service); + void Connect(mojo::PendingRemote<mojom::PerfettoService> perfetto_service); void set_in_process_shmem_arbiter(perfetto::SharedMemoryArbiter* arbiter) { DCHECK(!in_process_arbiter_);
diff --git a/services/tracing/public/cpp/traced_process_impl.cc b/services/tracing/public/cpp/traced_process_impl.cc index f9c9412c..707343e 100644 --- a/services/tracing/public/cpp/traced_process_impl.cc +++ b/services/tracing/public/cpp/traced_process_impl.cc
@@ -109,7 +109,8 @@ } PerfettoTracedProcess::Get()->producer_client()->Connect( - tracing::mojom::PerfettoServicePtr(std::move(request->perfetto_service))); + mojo::PendingRemote<tracing::mojom::PerfettoService>( + std::move(request->perfetto_service))); } void TracedProcessImpl::GetCategories(std::set<std::string>* category_set) {
diff --git a/services/tracing/tracing_service.cc b/services/tracing/tracing_service.cc index 7b24864..444890cc 100644 --- a/services/tracing/tracing_service.cc +++ b/services/tracing/tracing_service.cc
@@ -143,7 +143,7 @@ void OnProcessConnected( mojom::TracedProcessPtr traced_process, uint32_t pid, - mojom::PerfettoServiceRequest service_request, + mojo::PendingReceiver<mojom::PerfettoService> service_receiver, mojo::PendingReceiver<mojom::AgentRegistry> registry_receiver) { auto result = connected_pids_.insert(pid); if (!result.second) { @@ -152,8 +152,8 @@ } connected_pids_.insert(pid); - PerfettoService::GetInstance()->BindRequest(std::move(service_request), - pid); + PerfettoService::GetInstance()->BindReceiver(std::move(service_receiver), + pid); agent_registry_->BindAgentRegistryReceiver(std::move(registry_receiver)); }
diff --git a/services/viz/privileged/mojom/gl/gpu_service.mojom b/services/viz/privileged/mojom/gl/gpu_service.mojom index 4448c1e..f5b73dc 100644 --- a/services/viz/privileged/mojom/gl/gpu_service.mojom +++ b/services/viz/privileged/mojom/gl/gpu_service.mojom
@@ -40,33 +40,38 @@ // Create a new ARC VideoDecodeAccelerator and binds it to |vda|. [EnableIf=is_chromeos] - CreateArcVideoDecodeAccelerator(arc.mojom.VideoDecodeAccelerator& vda); + CreateArcVideoDecodeAccelerator( + pending_receiver<arc.mojom.VideoDecodeAccelerator> vda); // Create a new ARC VideoEncodeAccelerator and binds it to |vea|. [EnableIf=is_chromeos] - CreateArcVideoEncodeAccelerator(arc.mojom.VideoEncodeAccelerator& vea); + CreateArcVideoEncodeAccelerator( + pending_receiver<arc.mojom.VideoEncodeAccelerator> vea); // Create a new ARC VideoProtectedBufferAllocator and binds it to |pba|. [EnableIf=is_chromeos] CreateArcVideoProtectedBufferAllocator( - arc.mojom.VideoProtectedBufferAllocator& pba); + pending_receiver<arc.mojom.VideoProtectedBufferAllocator> pba); // Create a new ARC ProtectedBufferManager and binds it to |pbm|. [EnableIf=is_chromeos] - CreateArcProtectedBufferManager(arc.mojom.ProtectedBufferManager& pbm); + CreateArcProtectedBufferManager( + pending_receiver<arc.mojom.ProtectedBufferManager> pbm); // Creates a new MjpegDecodeAccelerator and binds it to |jda|. [EnableIf=is_chromeos] CreateJpegDecodeAccelerator( - chromeos_camera.mojom.MjpegDecodeAccelerator& jda); + pending_receiver<chromeos_camera.mojom.MjpegDecodeAccelerator> jda); // Creates a new JpegEncodeAccelerator and binds it to |jea|. [EnableIf=is_chromeos] - CreateJpegEncodeAccelerator(chromeos_camera.mojom.JpegEncodeAccelerator& jea); + CreateJpegEncodeAccelerator( + pending_receiver<chromeos_camera.mojom.JpegEncodeAccelerator> jea); // Creates a VideoEncodeAcceleratorProvider and binds it to |vea_provider|. CreateVideoEncodeAcceleratorProvider( - media.mojom.VideoEncodeAcceleratorProvider& vea_provider); + pending_receiver<media.mojom.VideoEncodeAcceleratorProvider> + vea_provider); CreateGpuMemoryBuffer(gfx.mojom.GpuMemoryBufferId id, gfx.mojom.Size size,
diff --git a/services/viz/public/cpp/gpu/gpu.cc b/services/viz/public/cpp/gpu/gpu.cc index 8c9bb11..eae7764 100644 --- a/services/viz/public/cpp/gpu/gpu.cc +++ b/services/viz/public/cpp/gpu/gpu.cc
@@ -64,9 +64,10 @@ #endif // defined(OS_CHROMEOS) void CreateVideoEncodeAcceleratorProvider( - media::mojom::VideoEncodeAcceleratorProviderRequest request) { + mojo::PendingReceiver<media::mojom::VideoEncodeAcceleratorProvider> + receiver) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - gpu_ptr_->CreateVideoEncodeAcceleratorProvider(std::move(request)); + gpu_ptr_->CreateVideoEncodeAcceleratorProvider(std::move(receiver)); } private: @@ -296,12 +297,13 @@ #endif // defined(OS_CHROMEOS) void Gpu::CreateVideoEncodeAcceleratorProvider( - media::mojom::VideoEncodeAcceleratorProviderRequest vea_provider_request) { + mojo::PendingReceiver<media::mojom::VideoEncodeAcceleratorProvider> + vea_provider_receiver) { DCHECK(main_task_runner_->BelongsToCurrentThread()); io_task_runner_->PostTask( FROM_HERE, base::BindOnce(&GpuPtrIO::CreateVideoEncodeAcceleratorProvider, base::Unretained(gpu_.get()), - std::move(vea_provider_request))); + std::move(vea_provider_receiver))); } void Gpu::EstablishGpuChannel(gpu::GpuChannelEstablishedCallback callback) {
diff --git a/services/viz/public/cpp/gpu/gpu.h b/services/viz/public/cpp/gpu/gpu.h index eaa7cbf..b343f666 100644 --- a/services/viz/public/cpp/gpu/gpu.h +++ b/services/viz/public/cpp/gpu/gpu.h
@@ -46,7 +46,8 @@ chromeos_camera::mojom::MjpegDecodeAcceleratorRequest jda_request); #endif // defined(OS_CHROMEOS) void CreateVideoEncodeAcceleratorProvider( - media::mojom::VideoEncodeAcceleratorProviderRequest vea_provider_request); + mojo::PendingReceiver<media::mojom::VideoEncodeAcceleratorProvider> + vea_provider_receiver); // gpu::GpuChannelEstablishFactory: void EstablishGpuChannel(
diff --git a/services/viz/public/cpp/gpu/gpu_unittest.cc b/services/viz/public/cpp/gpu/gpu_unittest.cc index 128ebb1..e7027ec 100644 --- a/services/viz/public/cpp/gpu/gpu_unittest.cc +++ b/services/viz/public/cpp/gpu/gpu_unittest.cc
@@ -65,7 +65,8 @@ #endif // defined(OS_CHROMEOS) void CreateVideoEncodeAcceleratorProvider( - media::mojom::VideoEncodeAcceleratorProviderRequest request) override {} + mojo::PendingReceiver<media::mojom::VideoEncodeAcceleratorProvider> + receiver) override {} private: bool request_will_succeed_ = true;
diff --git a/services/viz/public/mojom/gpu.mojom b/services/viz/public/mojom/gpu.mojom index 3004a0b1..76d40af5 100644 --- a/services/viz/public/mojom/gpu.mojom +++ b/services/viz/public/mojom/gpu.mojom
@@ -48,5 +48,6 @@ // Creates a VideoEncodeAcceleratorProvider and binds it to |vea_provider|. CreateVideoEncodeAcceleratorProvider( - media.mojom.VideoEncodeAcceleratorProvider& vea_provider); + pending_receiver<media.mojom.VideoEncodeAcceleratorProvider> + vea_provider); };
diff --git a/storage/browser/quota/OWNERS b/storage/browser/quota/OWNERS index f62a608e..148302e 100644 --- a/storage/browser/quota/OWNERS +++ b/storage/browser/quota/OWNERS
@@ -1,8 +1,11 @@ +# Primary +jarrydg@chromium.org + +# Secondary jsbell@chromium.org kinuko@chromium.org nhiroki@chromium.org pwnall@chromium.org -tzik@chromium.org # TEAM: storage-dev@chromium.org # COMPONENT: Blink>Storage>Quota
diff --git a/testing/buildbot/filters/bfcache.content_browsertests.filter b/testing/buildbot/filters/bfcache.content_browsertests.filter index a4252fd5..92eab99 100644 --- a/testing/buildbot/filters/bfcache.content_browsertests.filter +++ b/testing/buildbot/filters/bfcache.content_browsertests.filter
@@ -18,14 +18,6 @@ # Document expects javascript to run again from the beginning. -WebContentsImplBrowserTest.JavaScriptDialogsInMainAndSubframes -# render_view_impl.cc. Check failed: !frame_widget_. -# https://crbug.com/999846 --NavigationControllerBrowserTest.PageStateAfterForwardInCompetingFrames --NavigationControllerBrowserTest.PageStateWithIframeAfterForwardInCompetingFrames --NavigationControllerHistoryInterventionBrowserTest.NoUserActivationSetSkipOnBackForwardCrossSite --NavigationControllerHistoryInterventionBrowserTest.NoUserActivationSetSkipOnBackForwardCrossSite --RenderFrameHostManagerTest.BackForwardNotStale - # Javascript dialog is shown from a page in the BackForwardCache. # https://crbug.com/999847 -NavigationControllerBrowserTest.NoDialogsFromSwappedOutFrames
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 58663a3..92dfae1 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -468,6 +468,21 @@ ] } ], + "AndroidPasswordManagerOnboarding": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PasswordManagerOnboardingAndroid" + ] + } + ] + } + ], "AndroidSpellChecker": [ { "platforms": [ @@ -5264,6 +5279,8 @@ "ServiceWorkerOnUI": [ { "platforms": [ + "android", + "android_webview", "chromeos", "linux", "mac",
diff --git a/third_party/axe-core/README.chromium b/third_party/axe-core/README.chromium index 54f5507..7697284 100644 --- a/third_party/axe-core/README.chromium +++ b/third_party/axe-core/README.chromium
@@ -1,9 +1,9 @@ Name: AXE-CORE Accessibility Audit Short Name: axe-core URL: https://github.com/dequelabs/axe-core/ -Version: 3.3.2 -Date: Thur Aug 22 12:45:00 2019 -Revision: 281653df3794f429b71327fe3afa37ca0fadb1c7 +Version: 0 +Date: Mon Jul 24 12:17:05 2017 +Revision: d02dba3223fefe525438330e40b5da5de81eeeb5 License: MPL 2.0 License File: LICENSE Security Critical: no
diff --git a/third_party/axe-core/axe.d.ts b/third_party/axe-core/axe.d.ts index b68b2c6..258cf3dc 100644 --- a/third_party/axe-core/axe.d.ts +++ b/third_party/axe-core/axe.d.ts
@@ -1,224 +1,169 @@ -// Type definitions for axe-core +// Type definitions for axe-core 2.3.1 // Project: https://github.com/dequelabs/axe-core // Definitions by: Marcy Sutton <https://github.com/marcysutton> -declare namespace axe { - type ImpactValue = 'minor' | 'moderate' | 'serious' | 'critical'; +declare module axe { - type TagValue = 'wcag2a' | 'wcag2aa' | 'section508' | 'best-practice'; + type ImpactValue = "minor" | "moderate" | "serious" | "critical"; - type ReporterVersion = 'v1' | 'v2' | 'raw' | 'raw-env' | 'no-passes'; + type TagValue = "wcag2a" | "wcag2aa" | "section508" | "best-practice"; - type RunOnlyType = 'rule' | 'rules' | 'tag' | 'tags'; + type ReporterVersion = "v1" | "v2"; - type resultGroups = 'inapplicable' | 'passes' | 'incomplete' | 'violations'; + type RunOnlyType = "rule" | "rules" | "tag" | "tags"; - type RunOnlyObject = { - include?: string[] | string[][]; - exclude?: string[] | string[][]; - }; - - type RunCallback = (error: Error, results: AxeResults) => void; - - type ElementContext = Node | string | RunOnlyObject; - - interface TestEngine { - name: string; - version: string; - } - interface TestRunner { - name: string; - } - interface TestEnvironment { - userAgent: string; - windowWidth: number; - windowHeight: number; - orientationAngle?: number; - orientationType?: string; + interface ElementContext { + node?: Object, + selector?: string, + include?: any[], + exclude?: any[] } interface RunOnly { - type: RunOnlyType; - values?: TagValue[] | string[] | RunOnlyObject; - } - interface RunOptions { - runOnly?: RunOnly; - rules?: Object; - iframes?: boolean; - elementRef?: boolean; - selectors?: boolean; - resultTypes?: resultGroups[]; - reporter?: ReporterVersion; - xpath?: boolean; - absolutePaths?: boolean; - restoreScroll?: boolean; - frameWaitTime?: number; - preload?: boolean; - performanceTimer?: boolean; + type: RunOnlyType, + value?: { + include?: string[], + exclude?: string[] + } + values?: TagValue[] } interface AxeResults { - toolOptions: RunOptions; - testEngine: TestEngine; - testRunner: TestRunner; - testEnvironment: TestEnvironment; - url: string; - timestamp: string; - passes: Result[]; - violations: Result[]; - incomplete: Result[]; - inapplicable: Result[]; + url: string, + timestamp: string, + passes: Result[], + violations: Result[], + incomplete: Result[], + inapplicable: Result[] } interface Result { - description: string; - help: string; - helpUrl: string; - id: string; - impact?: ImpactValue; - tags: TagValue[]; - nodes: NodeResult[]; + description: string, + help: string, + helpUrl: string, + id: string, + impact: ImpactValue, + tags: TagValue[], + nodes: NodeResult[] } interface NodeResult { - html: string; - impact?: ImpactValue; - target: string[]; - xpath?: string[]; - any: CheckResult[]; - all: CheckResult[]; - none: CheckResult[]; - failureSummary?: string; + html: string, + impact: ImpactValue, + target: string[], + any: CheckResult[], + all: CheckResult[], + none: CheckResult[], + failureSummary?: string } interface CheckResult { - id: string; - impact: string; - message: string; - data: any; - relatedNodes?: RelatedNode[]; + id: string, + impact: string, + message: string, + data: any, + relatedNodes?: RelatedNode[] } interface RelatedNode { - target: string[]; - html: string; - } - interface RuleLocale { - [key: string]: { - description: string; - help: string; - }; - } - interface CheckLocale { - [key: string]: { - pass: string; - fail: string; - incomplete: string | { [key: string]: string }; - }; - } - interface Locale { - lang?: string; - rules?: RuleLocale; - checks?: CheckLocale; + target: string[], + html: string } interface Spec { branding?: { - brand?: string; - application?: string; - }; - reporter?: ReporterVersion; - checks?: Check[]; - rules?: Rule[]; - locale?: Locale; + brand: string, + application: string + }, + reporter?: ReporterVersion, + checks?: Check[], + rules?: Rule[] } interface Check { - id: string; - evaluate: Function | string; - after?: Function | string; - options?: any; - matches?: string; - enabled?: boolean; + id: string, + evaluate: Function, + after?: Function, + options?: any, + matches?: string, + enabled?: boolean } interface Rule { - id: string; - selector?: string; - excludeHidden?: boolean; - enabled?: boolean; - pageLevel?: boolean; - any?: string[]; - all?: string[]; - none?: string[]; - tags?: string[]; - matches?: string; + id: string, + selector?: string, + excludeHidden?: boolean, + enabled?: boolean, + pageLevel?: boolean, + any?: string[], + all?: string[], + none?: string[], + tags?: string[], + matches?: string } interface AxePlugin { - id: string; - run(...args: any[]): any; + id: string, + run(...args:any[]): any, commands: { - id: string; - callback(...args: any[]): void; - }[]; - cleanup?(callback: Function): void; + id: string, + callback(...args:any[]): void + }[], + cleanup?(callback:Function): void } - let plugins: any; + let plugins: any /** * Source string to use as an injected script in Selenium */ - let source: string; + let source: string /** - * Object for axe Results + * Object for aXe Results */ - var AxeResults: AxeResults; + var AxeResults: AxeResults /** * Runs a number of rules against the provided HTML page and returns the resulting issue list * - * @param {ElementContext} context Optional The `Context` specification object @see Context - * @param {RunOptions} options Optional Options passed into rules or checks, temporarily modifying them. - * @param {RunCallback} callback Optional The function to invoke when analysis is complete. - * @returns {Promise<AxeResults>|void} If the callback was not defined, axe will return a Promise. + * @param {Object} context Optional The `Context` specification object @see Context + * @param {Array} options Optional Options passed into rules or checks, temporarily modifying them. + * @param {Function} callback Optional The function to invoke when analysis is complete. + * @returns {any} results If the callback was not defined, aXe will return a Promise instead. */ - function run(context?: ElementContext): Promise<AxeResults>; - function run(options: RunOptions): Promise<AxeResults>; - function run(callback: (error: Error, results: AxeResults) => void): void; - function run(context: ElementContext, callback: RunCallback): void; - function run(options: RunOptions, callback: RunCallback): void; - function run( - context: ElementContext, - options: RunOptions - ): Promise<AxeResults>; - function run( - context: ElementContext, - options: RunOptions, - callback: RunCallback - ): void; + function run(context?: ElementContext, options?: {runOnly?: RunOnly, rules?: Object, iframes?: Boolean, elementRef?: Boolean, selectors?: Boolean}, callback?: (error: Error, results:AxeResults) => void): any /** - * Method for configuring the data format used by axe. Helpful for adding new + * Starts analysis on the current document and its subframes + * + * @param {Object} context The `Context` specification object @see Context + * @param {Array} options Options passed into rules or checks, temporarily modifyint them. + * @param {Function} callback The function to invoke when analysis is complete. + * @returns {Object} results The aXe results object + */ + function a11yCheck(context: ElementContext, options: {runOnly?: RunOnly, rules?: Object, iframes?: Boolean, elementRef?: Boolean, selectors?: Boolean}, callback: (results:AxeResults) => void): AxeResults + + /** + * Method for configuring the data format used by aXe. Helpful for adding new * rules, which must be registered with the library to execute. * @param {Spec} Spec Object with valid `branding`, `reporter`, `checks` and `rules` data */ - function configure(spec: Spec): void; + function configure(spec: Spec): void /** * Searches and returns rules that contain a tag in the list of tags. * @param {Array} tags Optional array of tags * @return {Array} Array of rules */ - function getRules(tags?: string[]): Object[]; + function getRules(tags?: string[]): Object[] /** * Restores the default axe configuration */ - function reset(): void; + function reset(): void /** * Function to register a plugin configuration in document and its subframes * @param {Object} plugin A plugin configuration object */ - function registerPlugin(plugin: AxePlugin): void; + function registerPlugin(plugin: AxePlugin): void /** * Function to clean up plugin configuration in document and its subframes */ - function cleanup(): void; + function cleanup(): void + } export = axe;
diff --git a/third_party/axe-core/axe.js b/third_party/axe-core/axe.js index 3b7cfe6..2e2c746b 100644 --- a/third_party/axe-core/axe.js +++ b/third_party/axe-core/axe.js
@@ -1,5 +1,5 @@ -/*! axe v3.3.2 - * Copyright (c) 2019 Deque Systems, Inc. +/*! aXe v3.0.0-alpha-1 + * Copyright (c) 2017 Deque Systems, Inc. * * Your use of this Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -13,22 +13,15 @@ var global = window; var document = window.document; 'use strict'; - function _typeof(obj) { - if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') { - _typeof = function _typeof(obj) { - return typeof obj; - }; - } else { - _typeof = function _typeof(obj) { - return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj; - }; - } - return _typeof(obj); - } + var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) { + return typeof obj; + } : function(obj) { + return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj; + }; var axe = axe || {}; - axe.version = '3.3.2'; + axe.version = '3.0.0-alpha-1'; if (typeof define === 'function' && define.amd) { - define('axe-core', [], function() { + define([], function() { 'use strict'; return axe; }); @@ -44,2496 +37,25 @@ function SupportError(error) { this.name = 'SupportError'; this.cause = error.cause; - this.message = '`'.concat(error.cause, '` - feature unsupported in your environment.'); + this.message = '`' + error.cause + '` - feature unsupported in your environment.'; if (error.ruleId) { this.ruleId = error.ruleId; - this.message += ' Skipping '.concat(this.ruleId, ' rule.'); + this.message += ' Skipping ' + this.ruleId + ' rule.'; } this.stack = new Error().stack; } SupportError.prototype = Object.create(Error.prototype); SupportError.prototype.constructor = SupportError; - (function() { - function r(e, n, t) { - function o(i, f) { - if (!n[i]) { - if (!e[i]) { - var c = 'function' == typeof require && require; - if (!f && c) { - return c(i, !0); - } - if (u) { - return u(i, !0); - } - var a = new Error('Cannot find module \'' + i + '\''); - throw a.code = 'MODULE_NOT_FOUND', a; - } - var p = n[i] = { - exports: {} - }; - e[i][0].call(p.exports, function(r) { - var n = e[i][1][r]; - return o(n || r); - }, p, p.exports, r, e, n, t); - } - return n[i].exports; - } - for (var u = 'function' == typeof require && require, i = 0; i < t.length; i++) { - o(t[i]); - } - return o; - } - return r; - })()({ - 1: [ function(_dereq_, module, exports) { - if (!('Promise' in window)) { - _dereq_('es6-promise').polyfill(); - } - _dereq_('weakmap-polyfill'); - axe.imports = { - axios: _dereq_('axios'), - CssSelectorParser: _dereq_('css-selector-parser').CssSelectorParser, - doT: _dereq_('@deque/dot'), - emojiRegexText: _dereq_('emoji-regex') - }; - }, { - '@deque/dot': 2, - axios: 3, - 'css-selector-parser': 29, - 'emoji-regex': 31, - 'es6-promise': 32, - 'weakmap-polyfill': 34 - } ], - 2: [ function(_dereq_, module, exports) { - (function() { - 'use strict'; - var doT = { - name: 'doT', - version: '1.1.1', - templateSettings: { - evaluate: /\{\{([\s\S]+?(\}?)+)\}\}/g, - interpolate: /\{\{=([\s\S]+?)\}\}/g, - encode: /\{\{!([\s\S]+?)\}\}/g, - use: /\{\{#([\s\S]+?)\}\}/g, - useParams: /(^|[^\w$])def(?:\.|\[[\'\"])([\w$\.]+)(?:[\'\"]\])?\s*\:\s*([\w$\.]+|\"[^\"]+\"|\'[^\']+\'|\{[^\}]+\})/g, - define: /\{\{##\s*([\w\.$]+)\s*(\:|=)([\s\S]+?)#\}\}/g, - defineParams: /^\s*([\w$]+):([\s\S]+)/, - conditional: /\{\{\?(\?)?\s*([\s\S]*?)\s*\}\}/g, - iterate: /\{\{~\s*(?:\}\}|([\s\S]+?)\s*\:\s*([\w$]+)\s*(?:\:\s*([\w$]+))?\s*\}\})/g, - varname: 'it', - strip: true, - append: true, - selfcontained: false, - doNotSkipEncoded: false - }, - template: undefined, - compile: undefined, - log: true - }; - (function() { - if (typeof globalThis === 'object') { - return; - } - Object.defineProperty(Object.prototype, '__magic__', { - get: function() { - return this; - }, - configurable: true - }); - __magic__.globalThis = __magic__; - delete Object.prototype.__magic__; - })(); - doT.encodeHTMLSource = function(doNotSkipEncoded) { - var encodeHTMLRules = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - '\'': ''', - '/': '/' - }, matchHTML = doNotSkipEncoded ? /[&<>"'\/]/g : /&(?!#?\w+;)|<|>|"|'|\//g; - return function(code) { - return code ? code.toString().replace(matchHTML, function(m) { - return encodeHTMLRules[m] || m; - }) : ''; - }; - }; - if (typeof module !== 'undefined' && module.exports) { - module.exports = doT; - } else if (typeof define === 'function' && define.amd) { - define(function() { - return doT; - }); - } else { - globalThis.doT = doT; - } - var startend = { - append: { - start: '\'+(', - end: ')+\'', - startencode: '\'+encodeHTML(' - }, - split: { - start: '\';out+=(', - end: ');out+=\'', - startencode: '\';out+=encodeHTML(' - } - }, skip = /$^/; - function resolveDefs(c, block, def) { - return (typeof block === 'string' ? block : block.toString()).replace(c.define || skip, function(m, code, assign, value) { - if (code.indexOf('def.') === 0) { - code = code.substring(4); - } - if (!(code in def)) { - if (assign === ':') { - if (c.defineParams) { - value.replace(c.defineParams, function(m, param, v) { - def[code] = { - arg: param, - text: v - }; - }); - } - if (!(code in def)) { - def[code] = value; - } - } else { - new Function('def', 'def[\'' + code + '\']=' + value)(def); - } - } - return ''; - }).replace(c.use || skip, function(m, code) { - if (c.useParams) { - code = code.replace(c.useParams, function(m, s, d, param) { - if (def[d] && def[d].arg && param) { - var rw = (d + ':' + param).replace(/'|\\/g, '_'); - def.__exp = def.__exp || {}; - def.__exp[rw] = def[d].text.replace(new RegExp('(^|[^\\w$])' + def[d].arg + '([^\\w$])', 'g'), '$1' + param + '$2'); - return s + 'def.__exp[\'' + rw + '\']'; - } - }); - } - var v = new Function('def', 'return ' + code)(def); - return v ? resolveDefs(c, v, def) : v; - }); - } - function unescape(code) { - return code.replace(/\\('|\\)/g, '$1').replace(/[\r\t\n]/g, ' '); - } - doT.template = function(tmpl, c, def) { - c = c || doT.templateSettings; - var cse = c.append ? startend.append : startend.split, needhtmlencode, sid = 0, indv, str = c.use || c.define ? resolveDefs(c, tmpl, def || {}) : tmpl; - str = ('var out=\'' + (c.strip ? str.replace(/(^|\r|\n)\t* +| +\t*(\r|\n|$)/g, ' ').replace(/\r|\n|\t|\/\*[\s\S]*?\*\//g, '') : str).replace(/'|\\/g, '\\$&').replace(c.interpolate || skip, function(m, code) { - return cse.start + unescape(code) + cse.end; - }).replace(c.encode || skip, function(m, code) { - needhtmlencode = true; - return cse.startencode + unescape(code) + cse.end; - }).replace(c.conditional || skip, function(m, elsecase, code) { - return elsecase ? code ? '\';}else if(' + unescape(code) + '){out+=\'' : '\';}else{out+=\'' : code ? '\';if(' + unescape(code) + '){out+=\'' : '\';}out+=\''; - }).replace(c.iterate || skip, function(m, iterate, vname, iname) { - if (!iterate) { - return '\';} } out+=\''; - } - sid += 1; - indv = iname || 'i' + sid; - iterate = unescape(iterate); - return '\';var arr' + sid + '=' + iterate + ';if(arr' + sid + '){var ' + vname + ',' + indv + '=-1,l' + sid + '=arr' + sid + '.length-1;while(' + indv + '<l' + sid + '){' + vname + '=arr' + sid + '[' + indv + '+=1];out+=\''; - }).replace(c.evaluate || skip, function(m, code) { - return '\';' + unescape(code) + 'out+=\''; - }) + '\';return out;').replace(/\n/g, '\\n').replace(/\t/g, '\\t').replace(/\r/g, '\\r').replace(/(\s|;|\}|^|\{)out\+='';/g, '$1').replace(/\+''/g, ''); - if (needhtmlencode) { - if (!c.selfcontained && globalThis && !globalThis._encodeHTML) { - globalThis._encodeHTML = doT.encodeHTMLSource(c.doNotSkipEncoded); - } - str = 'var encodeHTML = typeof _encodeHTML !== \'undefined\' ? _encodeHTML : (' + doT.encodeHTMLSource.toString() + '(' + (c.doNotSkipEncoded || '') + '));' + str; - } - try { - return new Function(c.varname, str); - } catch (e) { - if (typeof console !== 'undefined') { - console.log('Could not create a template function: ' + str); - } - throw e; - } - }; - doT.compile = function(tmpl, def) { - return doT.template(tmpl, null, def); - }; - })(); - }, {} ], - 3: [ function(_dereq_, module, exports) { - module.exports = _dereq_('./lib/axios'); - }, { - './lib/axios': 5 - } ], - 4: [ function(_dereq_, module, exports) { - 'use strict'; - var utils = _dereq_('./../utils'); - var settle = _dereq_('./../core/settle'); - var buildURL = _dereq_('./../helpers/buildURL'); - var parseHeaders = _dereq_('./../helpers/parseHeaders'); - var isURLSameOrigin = _dereq_('./../helpers/isURLSameOrigin'); - var createError = _dereq_('../core/createError'); - module.exports = function xhrAdapter(config) { - return new Promise(function dispatchXhrRequest(resolve, reject) { - var requestData = config.data; - var requestHeaders = config.headers; - if (utils.isFormData(requestData)) { - delete requestHeaders['Content-Type']; - } - var request = new XMLHttpRequest(); - if (config.auth) { - var username = config.auth.username || ''; - var password = config.auth.password || ''; - requestHeaders.Authorization = 'Basic ' + btoa(username + ':' + password); - } - request.open(config.method.toUpperCase(), buildURL(config.url, config.params, config.paramsSerializer), true); - request.timeout = config.timeout; - request.onreadystatechange = function handleLoad() { - if (!request || request.readyState !== 4) { - return; - } - if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) { - return; - } - var responseHeaders = 'getAllResponseHeaders' in request ? parseHeaders(request.getAllResponseHeaders()) : null; - var responseData = !config.responseType || config.responseType === 'text' ? request.responseText : request.response; - var response = { - data: responseData, - status: request.status, - statusText: request.statusText, - headers: responseHeaders, - config: config, - request: request - }; - settle(resolve, reject, response); - request = null; - }; - request.onabort = function handleAbort() { - if (!request) { - return; - } - reject(createError('Request aborted', config, 'ECONNABORTED', request)); - request = null; - }; - request.onerror = function handleError() { - reject(createError('Network Error', config, null, request)); - request = null; - }; - request.ontimeout = function handleTimeout() { - reject(createError('timeout of ' + config.timeout + 'ms exceeded', config, 'ECONNABORTED', request)); - request = null; - }; - if (utils.isStandardBrowserEnv()) { - var cookies = _dereq_('./../helpers/cookies'); - var xsrfValue = (config.withCredentials || isURLSameOrigin(config.url)) && config.xsrfCookieName ? cookies.read(config.xsrfCookieName) : undefined; - if (xsrfValue) { - requestHeaders[config.xsrfHeaderName] = xsrfValue; - } - } - if ('setRequestHeader' in request) { - utils.forEach(requestHeaders, function setRequestHeader(val, key) { - if (typeof requestData === 'undefined' && key.toLowerCase() === 'content-type') { - delete requestHeaders[key]; - } else { - request.setRequestHeader(key, val); - } - }); - } - if (config.withCredentials) { - request.withCredentials = true; - } - if (config.responseType) { - try { - request.responseType = config.responseType; - } catch (e) { - if (config.responseType !== 'json') { - throw e; - } - } - } - if (typeof config.onDownloadProgress === 'function') { - request.addEventListener('progress', config.onDownloadProgress); - } - if (typeof config.onUploadProgress === 'function' && request.upload) { - request.upload.addEventListener('progress', config.onUploadProgress); - } - if (config.cancelToken) { - config.cancelToken.promise.then(function onCanceled(cancel) { - if (!request) { - return; - } - request.abort(); - reject(cancel); - request = null; - }); - } - if (requestData === undefined) { - requestData = null; - } - request.send(requestData); - }); - }; - }, { - '../core/createError': 11, - './../core/settle': 15, - './../helpers/buildURL': 19, - './../helpers/cookies': 21, - './../helpers/isURLSameOrigin': 23, - './../helpers/parseHeaders': 25, - './../utils': 27 - } ], - 5: [ function(_dereq_, module, exports) { - 'use strict'; - var utils = _dereq_('./utils'); - var bind = _dereq_('./helpers/bind'); - var Axios = _dereq_('./core/Axios'); - var mergeConfig = _dereq_('./core/mergeConfig'); - var defaults = _dereq_('./defaults'); - function createInstance(defaultConfig) { - var context = new Axios(defaultConfig); - var instance = bind(Axios.prototype.request, context); - utils.extend(instance, Axios.prototype, context); - utils.extend(instance, context); - return instance; - } - var axios = createInstance(defaults); - axios.Axios = Axios; - axios.create = function create(instanceConfig) { - return createInstance(mergeConfig(axios.defaults, instanceConfig)); - }; - axios.Cancel = _dereq_('./cancel/Cancel'); - axios.CancelToken = _dereq_('./cancel/CancelToken'); - axios.isCancel = _dereq_('./cancel/isCancel'); - axios.all = function all(promises) { - return Promise.all(promises); - }; - axios.spread = _dereq_('./helpers/spread'); - module.exports = axios; - module.exports.default = axios; - }, { - './cancel/Cancel': 6, - './cancel/CancelToken': 7, - './cancel/isCancel': 8, - './core/Axios': 9, - './core/mergeConfig': 14, - './defaults': 17, - './helpers/bind': 18, - './helpers/spread': 26, - './utils': 27 - } ], - 6: [ function(_dereq_, module, exports) { - 'use strict'; - function Cancel(message) { - this.message = message; - } - Cancel.prototype.toString = function toString() { - return 'Cancel' + (this.message ? ': ' + this.message : ''); - }; - Cancel.prototype.__CANCEL__ = true; - module.exports = Cancel; - }, {} ], - 7: [ function(_dereq_, module, exports) { - 'use strict'; - var Cancel = _dereq_('./Cancel'); - function CancelToken(executor) { - if (typeof executor !== 'function') { - throw new TypeError('executor must be a function.'); - } - var resolvePromise; - this.promise = new Promise(function promiseExecutor(resolve) { - resolvePromise = resolve; - }); - var token = this; - executor(function cancel(message) { - if (token.reason) { - return; - } - token.reason = new Cancel(message); - resolvePromise(token.reason); - }); - } - CancelToken.prototype.throwIfRequested = function throwIfRequested() { - if (this.reason) { - throw this.reason; - } - }; - CancelToken.source = function source() { - var cancel; - var token = new CancelToken(function executor(c) { - cancel = c; - }); - return { - token: token, - cancel: cancel - }; - }; - module.exports = CancelToken; - }, { - './Cancel': 6 - } ], - 8: [ function(_dereq_, module, exports) { - 'use strict'; - module.exports = function isCancel(value) { - return !!(value && value.__CANCEL__); - }; - }, {} ], - 9: [ function(_dereq_, module, exports) { - 'use strict'; - var utils = _dereq_('./../utils'); - var buildURL = _dereq_('../helpers/buildURL'); - var InterceptorManager = _dereq_('./InterceptorManager'); - var dispatchRequest = _dereq_('./dispatchRequest'); - var mergeConfig = _dereq_('./mergeConfig'); - function Axios(instanceConfig) { - this.defaults = instanceConfig; - this.interceptors = { - request: new InterceptorManager(), - response: new InterceptorManager() - }; - } - Axios.prototype.request = function request(config) { - if (typeof config === 'string') { - config = arguments[1] || {}; - config.url = arguments[0]; - } else { - config = config || {}; - } - config = mergeConfig(this.defaults, config); - config.method = config.method ? config.method.toLowerCase() : 'get'; - var chain = [ dispatchRequest, undefined ]; - var promise = Promise.resolve(config); - this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) { - chain.unshift(interceptor.fulfilled, interceptor.rejected); - }); - this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) { - chain.push(interceptor.fulfilled, interceptor.rejected); - }); - while (chain.length) { - promise = promise.then(chain.shift(), chain.shift()); - } - return promise; - }; - Axios.prototype.getUri = function getUri(config) { - config = mergeConfig(this.defaults, config); - return buildURL(config.url, config.params, config.paramsSerializer).replace(/^\?/, ''); - }; - utils.forEach([ 'delete', 'get', 'head', 'options' ], function forEachMethodNoData(method) { - Axios.prototype[method] = function(url, config) { - return this.request(utils.merge(config || {}, { - method: method, - url: url - })); - }; - }); - utils.forEach([ 'post', 'put', 'patch' ], function forEachMethodWithData(method) { - Axios.prototype[method] = function(url, data, config) { - return this.request(utils.merge(config || {}, { - method: method, - url: url, - data: data - })); - }; - }); - module.exports = Axios; - }, { - '../helpers/buildURL': 19, - './../utils': 27, - './InterceptorManager': 10, - './dispatchRequest': 12, - './mergeConfig': 14 - } ], - 10: [ function(_dereq_, module, exports) { - 'use strict'; - var utils = _dereq_('./../utils'); - function InterceptorManager() { - this.handlers = []; - } - InterceptorManager.prototype.use = function use(fulfilled, rejected) { - this.handlers.push({ - fulfilled: fulfilled, - rejected: rejected - }); - return this.handlers.length - 1; - }; - InterceptorManager.prototype.eject = function eject(id) { - if (this.handlers[id]) { - this.handlers[id] = null; - } - }; - InterceptorManager.prototype.forEach = function forEach(fn) { - utils.forEach(this.handlers, function forEachHandler(h) { - if (h !== null) { - fn(h); - } - }); - }; - module.exports = InterceptorManager; - }, { - './../utils': 27 - } ], - 11: [ function(_dereq_, module, exports) { - 'use strict'; - var enhanceError = _dereq_('./enhanceError'); - module.exports = function createError(message, config, code, request, response) { - var error = new Error(message); - return enhanceError(error, config, code, request, response); - }; - }, { - './enhanceError': 13 - } ], - 12: [ function(_dereq_, module, exports) { - 'use strict'; - var utils = _dereq_('./../utils'); - var transformData = _dereq_('./transformData'); - var isCancel = _dereq_('../cancel/isCancel'); - var defaults = _dereq_('../defaults'); - var isAbsoluteURL = _dereq_('./../helpers/isAbsoluteURL'); - var combineURLs = _dereq_('./../helpers/combineURLs'); - function throwIfCancellationRequested(config) { - if (config.cancelToken) { - config.cancelToken.throwIfRequested(); - } - } - module.exports = function dispatchRequest(config) { - throwIfCancellationRequested(config); - if (config.baseURL && !isAbsoluteURL(config.url)) { - config.url = combineURLs(config.baseURL, config.url); - } - config.headers = config.headers || {}; - config.data = transformData(config.data, config.headers, config.transformRequest); - config.headers = utils.merge(config.headers.common || {}, config.headers[config.method] || {}, config.headers || {}); - utils.forEach([ 'delete', 'get', 'head', 'post', 'put', 'patch', 'common' ], function cleanHeaderConfig(method) { - delete config.headers[method]; - }); - var adapter = config.adapter || defaults.adapter; - return adapter(config).then(function onAdapterResolution(response) { - throwIfCancellationRequested(config); - response.data = transformData(response.data, response.headers, config.transformResponse); - return response; - }, function onAdapterRejection(reason) { - if (!isCancel(reason)) { - throwIfCancellationRequested(config); - if (reason && reason.response) { - reason.response.data = transformData(reason.response.data, reason.response.headers, config.transformResponse); - } - } - return Promise.reject(reason); - }); - }; - }, { - '../cancel/isCancel': 8, - '../defaults': 17, - './../helpers/combineURLs': 20, - './../helpers/isAbsoluteURL': 22, - './../utils': 27, - './transformData': 16 - } ], - 13: [ function(_dereq_, module, exports) { - 'use strict'; - module.exports = function enhanceError(error, config, code, request, response) { - error.config = config; - if (code) { - error.code = code; - } - error.request = request; - error.response = response; - error.isAxiosError = true; - error.toJSON = function() { - return { - message: this.message, - name: this.name, - description: this.description, - number: this.number, - fileName: this.fileName, - lineNumber: this.lineNumber, - columnNumber: this.columnNumber, - stack: this.stack, - config: this.config, - code: this.code - }; - }; - return error; - }; - }, {} ], - 14: [ function(_dereq_, module, exports) { - 'use strict'; - var utils = _dereq_('../utils'); - module.exports = function mergeConfig(config1, config2) { - config2 = config2 || {}; - var config = {}; - utils.forEach([ 'url', 'method', 'params', 'data' ], function valueFromConfig2(prop) { - if (typeof config2[prop] !== 'undefined') { - config[prop] = config2[prop]; - } - }); - utils.forEach([ 'headers', 'auth', 'proxy' ], function mergeDeepProperties(prop) { - if (utils.isObject(config2[prop])) { - config[prop] = utils.deepMerge(config1[prop], config2[prop]); - } else if (typeof config2[prop] !== 'undefined') { - config[prop] = config2[prop]; - } else if (utils.isObject(config1[prop])) { - config[prop] = utils.deepMerge(config1[prop]); - } else if (typeof config1[prop] !== 'undefined') { - config[prop] = config1[prop]; - } - }); - utils.forEach([ 'baseURL', 'transformRequest', 'transformResponse', 'paramsSerializer', 'timeout', 'withCredentials', 'adapter', 'responseType', 'xsrfCookieName', 'xsrfHeaderName', 'onUploadProgress', 'onDownloadProgress', 'maxContentLength', 'validateStatus', 'maxRedirects', 'httpAgent', 'httpsAgent', 'cancelToken', 'socketPath' ], function defaultToConfig2(prop) { - if (typeof config2[prop] !== 'undefined') { - config[prop] = config2[prop]; - } else if (typeof config1[prop] !== 'undefined') { - config[prop] = config1[prop]; - } - }); - return config; - }; - }, { - '../utils': 27 - } ], - 15: [ function(_dereq_, module, exports) { - 'use strict'; - var createError = _dereq_('./createError'); - module.exports = function settle(resolve, reject, response) { - var validateStatus = response.config.validateStatus; - if (!validateStatus || validateStatus(response.status)) { - resolve(response); - } else { - reject(createError('Request failed with status code ' + response.status, response.config, null, response.request, response)); - } - }; - }, { - './createError': 11 - } ], - 16: [ function(_dereq_, module, exports) { - 'use strict'; - var utils = _dereq_('./../utils'); - module.exports = function transformData(data, headers, fns) { - utils.forEach(fns, function transform(fn) { - data = fn(data, headers); - }); - return data; - }; - }, { - './../utils': 27 - } ], - 17: [ function(_dereq_, module, exports) { - (function(process) { - 'use strict'; - var utils = _dereq_('./utils'); - var normalizeHeaderName = _dereq_('./helpers/normalizeHeaderName'); - var DEFAULT_CONTENT_TYPE = { - 'Content-Type': 'application/x-www-form-urlencoded' - }; - function setContentTypeIfUnset(headers, value) { - if (!utils.isUndefined(headers) && utils.isUndefined(headers['Content-Type'])) { - headers['Content-Type'] = value; - } - } - function getDefaultAdapter() { - var adapter; - if (typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]') { - adapter = _dereq_('./adapters/http'); - } else if (typeof XMLHttpRequest !== 'undefined') { - adapter = _dereq_('./adapters/xhr'); - } - return adapter; - } - var defaults = { - adapter: getDefaultAdapter(), - transformRequest: [ function transformRequest(data, headers) { - normalizeHeaderName(headers, 'Accept'); - normalizeHeaderName(headers, 'Content-Type'); - if (utils.isFormData(data) || utils.isArrayBuffer(data) || utils.isBuffer(data) || utils.isStream(data) || utils.isFile(data) || utils.isBlob(data)) { - return data; - } - if (utils.isArrayBufferView(data)) { - return data.buffer; - } - if (utils.isURLSearchParams(data)) { - setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8'); - return data.toString(); - } - if (utils.isObject(data)) { - setContentTypeIfUnset(headers, 'application/json;charset=utf-8'); - return JSON.stringify(data); - } - return data; - } ], - transformResponse: [ function transformResponse(data) { - if (typeof data === 'string') { - try { - data = JSON.parse(data); - } catch (e) {} - } - return data; - } ], - timeout: 0, - xsrfCookieName: 'XSRF-TOKEN', - xsrfHeaderName: 'X-XSRF-TOKEN', - maxContentLength: -1, - validateStatus: function validateStatus(status) { - return status >= 200 && status < 300; - } - }; - defaults.headers = { - common: { - Accept: 'application/json, text/plain, */*' - } - }; - utils.forEach([ 'delete', 'get', 'head' ], function forEachMethodNoData(method) { - defaults.headers[method] = {}; - }); - utils.forEach([ 'post', 'put', 'patch' ], function forEachMethodWithData(method) { - defaults.headers[method] = utils.merge(DEFAULT_CONTENT_TYPE); - }); - module.exports = defaults; - }).call(this, _dereq_('_process')); - }, { - './adapters/http': 4, - './adapters/xhr': 4, - './helpers/normalizeHeaderName': 24, - './utils': 27, - _process: 33 - } ], - 18: [ function(_dereq_, module, exports) { - 'use strict'; - module.exports = function bind(fn, thisArg) { - return function wrap() { - var args = new Array(arguments.length); - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i]; - } - return fn.apply(thisArg, args); - }; - }; - }, {} ], - 19: [ function(_dereq_, module, exports) { - 'use strict'; - var utils = _dereq_('./../utils'); - function encode(val) { - return encodeURIComponent(val).replace(/%40/gi, '@').replace(/%3A/gi, ':').replace(/%24/g, '$').replace(/%2C/gi, ',').replace(/%20/g, '+').replace(/%5B/gi, '[').replace(/%5D/gi, ']'); - } - module.exports = function buildURL(url, params, paramsSerializer) { - if (!params) { - return url; - } - var serializedParams; - if (paramsSerializer) { - serializedParams = paramsSerializer(params); - } else if (utils.isURLSearchParams(params)) { - serializedParams = params.toString(); - } else { - var parts = []; - utils.forEach(params, function serialize(val, key) { - if (val === null || typeof val === 'undefined') { - return; - } - if (utils.isArray(val)) { - key = key + '[]'; - } else { - val = [ val ]; - } - utils.forEach(val, function parseValue(v) { - if (utils.isDate(v)) { - v = v.toISOString(); - } else if (utils.isObject(v)) { - v = JSON.stringify(v); - } - parts.push(encode(key) + '=' + encode(v)); - }); - }); - serializedParams = parts.join('&'); - } - if (serializedParams) { - var hashmarkIndex = url.indexOf('#'); - if (hashmarkIndex !== -1) { - url = url.slice(0, hashmarkIndex); - } - url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams; - } - return url; - }; - }, { - './../utils': 27 - } ], - 20: [ function(_dereq_, module, exports) { - 'use strict'; - module.exports = function combineURLs(baseURL, relativeURL) { - return relativeURL ? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '') : baseURL; - }; - }, {} ], - 21: [ function(_dereq_, module, exports) { - 'use strict'; - var utils = _dereq_('./../utils'); - module.exports = utils.isStandardBrowserEnv() ? function standardBrowserEnv() { - return { - write: function write(name, value, expires, path, domain, secure) { - var cookie = []; - cookie.push(name + '=' + encodeURIComponent(value)); - if (utils.isNumber(expires)) { - cookie.push('expires=' + new Date(expires).toGMTString()); - } - if (utils.isString(path)) { - cookie.push('path=' + path); - } - if (utils.isString(domain)) { - cookie.push('domain=' + domain); - } - if (secure === true) { - cookie.push('secure'); - } - document.cookie = cookie.join('; '); - }, - read: function read(name) { - var match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)')); - return match ? decodeURIComponent(match[3]) : null; - }, - remove: function remove(name) { - this.write(name, '', Date.now() - 864e5); - } - }; - }() : function nonStandardBrowserEnv() { - return { - write: function write() {}, - read: function read() { - return null; - }, - remove: function remove() {} - }; - }(); - }, { - './../utils': 27 - } ], - 22: [ function(_dereq_, module, exports) { - 'use strict'; - module.exports = function isAbsoluteURL(url) { - return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url); - }; - }, {} ], - 23: [ function(_dereq_, module, exports) { - 'use strict'; - var utils = _dereq_('./../utils'); - module.exports = utils.isStandardBrowserEnv() ? function standardBrowserEnv() { - var msie = /(msie|trident)/i.test(navigator.userAgent); - var urlParsingNode = document.createElement('a'); - var originURL; - function resolveURL(url) { - var href = url; - if (msie) { - urlParsingNode.setAttribute('href', href); - href = urlParsingNode.href; - } - urlParsingNode.setAttribute('href', href); - return { - href: urlParsingNode.href, - protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '', - host: urlParsingNode.host, - search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '', - hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '', - hostname: urlParsingNode.hostname, - port: urlParsingNode.port, - pathname: urlParsingNode.pathname.charAt(0) === '/' ? urlParsingNode.pathname : '/' + urlParsingNode.pathname - }; - } - originURL = resolveURL(window.location.href); - return function isURLSameOrigin(requestURL) { - var parsed = utils.isString(requestURL) ? resolveURL(requestURL) : requestURL; - return parsed.protocol === originURL.protocol && parsed.host === originURL.host; - }; - }() : function nonStandardBrowserEnv() { - return function isURLSameOrigin() { - return true; - }; - }(); - }, { - './../utils': 27 - } ], - 24: [ function(_dereq_, module, exports) { - 'use strict'; - var utils = _dereq_('../utils'); - module.exports = function normalizeHeaderName(headers, normalizedName) { - utils.forEach(headers, function processHeader(value, name) { - if (name !== normalizedName && name.toUpperCase() === normalizedName.toUpperCase()) { - headers[normalizedName] = value; - delete headers[name]; - } - }); - }; - }, { - '../utils': 27 - } ], - 25: [ function(_dereq_, module, exports) { - 'use strict'; - var utils = _dereq_('./../utils'); - var ignoreDuplicateOf = [ 'age', 'authorization', 'content-length', 'content-type', 'etag', 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since', 'last-modified', 'location', 'max-forwards', 'proxy-authorization', 'referer', 'retry-after', 'user-agent' ]; - module.exports = function parseHeaders(headers) { - var parsed = {}; - var key; - var val; - var i; - if (!headers) { - return parsed; - } - utils.forEach(headers.split('\n'), function parser(line) { - i = line.indexOf(':'); - key = utils.trim(line.substr(0, i)).toLowerCase(); - val = utils.trim(line.substr(i + 1)); - if (key) { - if (parsed[key] && ignoreDuplicateOf.indexOf(key) >= 0) { - return; - } - if (key === 'set-cookie') { - parsed[key] = (parsed[key] ? parsed[key] : []).concat([ val ]); - } else { - parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val; - } - } - }); - return parsed; - }; - }, { - './../utils': 27 - } ], - 26: [ function(_dereq_, module, exports) { - 'use strict'; - module.exports = function spread(callback) { - return function wrap(arr) { - return callback.apply(null, arr); - }; - }; - }, {} ], - 27: [ function(_dereq_, module, exports) { - 'use strict'; - var bind = _dereq_('./helpers/bind'); - var isBuffer = _dereq_('is-buffer'); - var toString = Object.prototype.toString; - function isArray(val) { - return toString.call(val) === '[object Array]'; - } - function isArrayBuffer(val) { - return toString.call(val) === '[object ArrayBuffer]'; - } - function isFormData(val) { - return typeof FormData !== 'undefined' && val instanceof FormData; - } - function isArrayBufferView(val) { - var result; - if (typeof ArrayBuffer !== 'undefined' && ArrayBuffer.isView) { - result = ArrayBuffer.isView(val); - } else { - result = val && val.buffer && val.buffer instanceof ArrayBuffer; - } - return result; - } - function isString(val) { - return typeof val === 'string'; - } - function isNumber(val) { - return typeof val === 'number'; - } - function isUndefined(val) { - return typeof val === 'undefined'; - } - function isObject(val) { - return val !== null && typeof val === 'object'; - } - function isDate(val) { - return toString.call(val) === '[object Date]'; - } - function isFile(val) { - return toString.call(val) === '[object File]'; - } - function isBlob(val) { - return toString.call(val) === '[object Blob]'; - } - function isFunction(val) { - return toString.call(val) === '[object Function]'; - } - function isStream(val) { - return isObject(val) && isFunction(val.pipe); - } - function isURLSearchParams(val) { - return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams; - } - function trim(str) { - return str.replace(/^\s*/, '').replace(/\s*$/, ''); - } - function isStandardBrowserEnv() { - if (typeof navigator !== 'undefined' && (navigator.product === 'ReactNative' || navigator.product === 'NativeScript' || navigator.product === 'NS')) { - return false; - } - return typeof window !== 'undefined' && typeof document !== 'undefined'; - } - function forEach(obj, fn) { - if (obj === null || typeof obj === 'undefined') { - return; - } - if (typeof obj !== 'object') { - obj = [ obj ]; - } - if (isArray(obj)) { - for (var i = 0, l = obj.length; i < l; i++) { - fn.call(null, obj[i], i, obj); - } - } else { - for (var key in obj) { - if (Object.prototype.hasOwnProperty.call(obj, key)) { - fn.call(null, obj[key], key, obj); - } - } - } - } - function merge() { - var result = {}; - function assignValue(val, key) { - if (typeof result[key] === 'object' && typeof val === 'object') { - result[key] = merge(result[key], val); - } else { - result[key] = val; - } - } - for (var i = 0, l = arguments.length; i < l; i++) { - forEach(arguments[i], assignValue); - } - return result; - } - function deepMerge() { - var result = {}; - function assignValue(val, key) { - if (typeof result[key] === 'object' && typeof val === 'object') { - result[key] = deepMerge(result[key], val); - } else if (typeof val === 'object') { - result[key] = deepMerge({}, val); - } else { - result[key] = val; - } - } - for (var i = 0, l = arguments.length; i < l; i++) { - forEach(arguments[i], assignValue); - } - return result; - } - function extend(a, b, thisArg) { - forEach(b, function assignValue(val, key) { - if (thisArg && typeof val === 'function') { - a[key] = bind(val, thisArg); - } else { - a[key] = val; - } - }); - return a; - } - module.exports = { - isArray: isArray, - isArrayBuffer: isArrayBuffer, - isBuffer: isBuffer, - isFormData: isFormData, - isArrayBufferView: isArrayBufferView, - isString: isString, - isNumber: isNumber, - isObject: isObject, - isUndefined: isUndefined, - isDate: isDate, - isFile: isFile, - isBlob: isBlob, - isFunction: isFunction, - isStream: isStream, - isURLSearchParams: isURLSearchParams, - isStandardBrowserEnv: isStandardBrowserEnv, - forEach: forEach, - merge: merge, - deepMerge: deepMerge, - extend: extend, - trim: trim - }; - }, { - './helpers/bind': 18, - 'is-buffer': 28 - } ], - 28: [ function(_dereq_, module, exports) { - module.exports = function isBuffer(obj) { - return obj != null && obj.constructor != null && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj); - }; - }, {} ], - 29: [ function(_dereq_, module, exports) { - module.exports = { - CssSelectorParser: _dereq_('./lib/css-selector-parser.js').CssSelectorParser - }; - }, { - './lib/css-selector-parser.js': 30 - } ], - 30: [ function(_dereq_, module, exports) { - function CssSelectorParser() { - this.pseudos = {}; - this.attrEqualityMods = {}; - this.ruleNestingOperators = {}; - this.substitutesEnabled = false; - } - CssSelectorParser.prototype.registerSelectorPseudos = function(name) { - for (var j = 0, len = arguments.length; j < len; j++) { - name = arguments[j]; - this.pseudos[name] = 'selector'; - } - return this; - }; - CssSelectorParser.prototype.unregisterSelectorPseudos = function(name) { - for (var j = 0, len = arguments.length; j < len; j++) { - name = arguments[j]; - delete this.pseudos[name]; - } - return this; - }; - CssSelectorParser.prototype.registerNumericPseudos = function(name) { - for (var j = 0, len = arguments.length; j < len; j++) { - name = arguments[j]; - this.pseudos[name] = 'numeric'; - } - return this; - }; - CssSelectorParser.prototype.unregisterNumericPseudos = function(name) { - for (var j = 0, len = arguments.length; j < len; j++) { - name = arguments[j]; - delete this.pseudos[name]; - } - return this; - }; - CssSelectorParser.prototype.registerNestingOperators = function(operator) { - for (var j = 0, len = arguments.length; j < len; j++) { - operator = arguments[j]; - this.ruleNestingOperators[operator] = true; - } - return this; - }; - CssSelectorParser.prototype.unregisterNestingOperators = function(operator) { - for (var j = 0, len = arguments.length; j < len; j++) { - operator = arguments[j]; - delete this.ruleNestingOperators[operator]; - } - return this; - }; - CssSelectorParser.prototype.registerAttrEqualityMods = function(mod) { - for (var j = 0, len = arguments.length; j < len; j++) { - mod = arguments[j]; - this.attrEqualityMods[mod] = true; - } - return this; - }; - CssSelectorParser.prototype.unregisterAttrEqualityMods = function(mod) { - for (var j = 0, len = arguments.length; j < len; j++) { - mod = arguments[j]; - delete this.attrEqualityMods[mod]; - } - return this; - }; - CssSelectorParser.prototype.enableSubstitutes = function() { - this.substitutesEnabled = true; - return this; - }; - CssSelectorParser.prototype.disableSubstitutes = function() { - this.substitutesEnabled = false; - return this; - }; - function isIdentStart(c) { - return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c === '-' || c === '_'; - } - function isIdent(c) { - return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' || c === '-' || c === '_'; - } - function isHex(c) { - return c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F' || c >= '0' && c <= '9'; - } - function isDecimal(c) { - return c >= '0' && c <= '9'; - } - function isAttrMatchOperator(chr) { - return chr === '=' || chr === '^' || chr === '$' || chr === '*' || chr === '~'; - } - var identSpecialChars = { - '!': true, - '"': true, - '#': true, - $: true, - '%': true, - '&': true, - '\'': true, - '(': true, - ')': true, - '*': true, - '+': true, - ',': true, - '.': true, - '/': true, - ';': true, - '<': true, - '=': true, - '>': true, - '?': true, - '@': true, - '[': true, - '\\': true, - ']': true, - '^': true, - '`': true, - '{': true, - '|': true, - '}': true, - '~': true - }; - var strReplacementsRev = { - '\n': '\\n', - '\r': '\\r', - '\t': '\\t', - '\f': '\\f', - '\v': '\\v' - }; - var singleQuoteEscapeChars = { - n: '\n', - r: '\r', - t: '\t', - f: '\f', - '\\': '\\', - '\'': '\'' - }; - var doubleQuotesEscapeChars = { - n: '\n', - r: '\r', - t: '\t', - f: '\f', - '\\': '\\', - '"': '"' - }; - function ParseContext(str, pos, pseudos, attrEqualityMods, ruleNestingOperators, substitutesEnabled) { - var chr, getIdent, getStr, l, skipWhitespace; - l = str.length; - chr = null; - getStr = function(quote, escapeTable) { - var esc, hex, result; - result = ''; - pos++; - chr = str.charAt(pos); - while (pos < l) { - if (chr === quote) { - pos++; - return result; - } else if (chr === '\\') { - pos++; - chr = str.charAt(pos); - if (chr === quote) { - result += quote; - } else if (esc = escapeTable[chr]) { - result += esc; - } else if (isHex(chr)) { - hex = chr; - pos++; - chr = str.charAt(pos); - while (isHex(chr)) { - hex += chr; - pos++; - chr = str.charAt(pos); - } - if (chr === ' ') { - pos++; - chr = str.charAt(pos); - } - result += String.fromCharCode(parseInt(hex, 16)); - continue; - } else { - result += chr; - } - } else { - result += chr; - } - pos++; - chr = str.charAt(pos); - } - return result; - }; - getIdent = function() { - var result = ''; - chr = str.charAt(pos); - while (pos < l) { - if (isIdent(chr)) { - result += chr; - } else if (chr === '\\') { - pos++; - if (pos >= l) { - throw Error('Expected symbol but end of file reached.'); - } - chr = str.charAt(pos); - if (identSpecialChars[chr]) { - result += chr; - } else if (isHex(chr)) { - var hex = chr; - pos++; - chr = str.charAt(pos); - while (isHex(chr)) { - hex += chr; - pos++; - chr = str.charAt(pos); - } - if (chr === ' ') { - pos++; - chr = str.charAt(pos); - } - result += String.fromCharCode(parseInt(hex, 16)); - continue; - } else { - result += chr; - } - } else { - return result; - } - pos++; - chr = str.charAt(pos); - } - return result; - }; - skipWhitespace = function() { - chr = str.charAt(pos); - var result = false; - while (chr === ' ' || chr === '\t' || chr === '\n' || chr === '\r' || chr === '\f') { - result = true; - pos++; - chr = str.charAt(pos); - } - return result; - }; - this.parse = function() { - var res = this.parseSelector(); - if (pos < l) { - throw Error('Rule expected but "' + str.charAt(pos) + '" found.'); - } - return res; - }; - this.parseSelector = function() { - var res; - var selector = res = this.parseSingleSelector(); - chr = str.charAt(pos); - while (chr === ',') { - pos++; - skipWhitespace(); - if (res.type !== 'selectors') { - res = { - type: 'selectors', - selectors: [ selector ] - }; - } - selector = this.parseSingleSelector(); - if (!selector) { - throw Error('Rule expected after ",".'); - } - res.selectors.push(selector); - } - return res; - }; - this.parseSingleSelector = function() { - skipWhitespace(); - var selector = { - type: 'ruleSet' - }; - var rule = this.parseRule(); - if (!rule) { - return null; - } - var currentRule = selector; - while (rule) { - rule.type = 'rule'; - currentRule.rule = rule; - currentRule = rule; - skipWhitespace(); - chr = str.charAt(pos); - if (pos >= l || chr === ',' || chr === ')') { - break; - } - if (ruleNestingOperators[chr]) { - var op = chr; - pos++; - skipWhitespace(); - rule = this.parseRule(); - if (!rule) { - throw Error('Rule expected after "' + op + '".'); - } - rule.nestingOperator = op; - } else { - rule = this.parseRule(); - if (rule) { - rule.nestingOperator = null; - } - } - } - return selector; - }; - this.parseRule = function() { - var rule = null; - while (pos < l) { - chr = str.charAt(pos); - if (chr === '*') { - pos++; - (rule = rule || {}).tagName = '*'; - } else if (isIdentStart(chr) || chr === '\\') { - (rule = rule || {}).tagName = getIdent(); - } else if (chr === '.') { - pos++; - rule = rule || {}; - (rule.classNames = rule.classNames || []).push(getIdent()); - } else if (chr === '#') { - pos++; - (rule = rule || {}).id = getIdent(); - } else if (chr === '[') { - pos++; - skipWhitespace(); - var attr = { - name: getIdent() - }; - skipWhitespace(); - if (chr === ']') { - pos++; - } else { - var operator = ''; - if (attrEqualityMods[chr]) { - operator = chr; - pos++; - chr = str.charAt(pos); - } - if (pos >= l) { - throw Error('Expected "=" but end of file reached.'); - } - if (chr !== '=') { - throw Error('Expected "=" but "' + chr + '" found.'); - } - attr.operator = operator + '='; - pos++; - skipWhitespace(); - var attrValue = ''; - attr.valueType = 'string'; - if (chr === '"') { - attrValue = getStr('"', doubleQuotesEscapeChars); - } else if (chr === '\'') { - attrValue = getStr('\'', singleQuoteEscapeChars); - } else if (substitutesEnabled && chr === '$') { - pos++; - attrValue = getIdent(); - attr.valueType = 'substitute'; - } else { - while (pos < l) { - if (chr === ']') { - break; - } - attrValue += chr; - pos++; - chr = str.charAt(pos); - } - attrValue = attrValue.trim(); - } - skipWhitespace(); - if (pos >= l) { - throw Error('Expected "]" but end of file reached.'); - } - if (chr !== ']') { - throw Error('Expected "]" but "' + chr + '" found.'); - } - pos++; - attr.value = attrValue; - } - rule = rule || {}; - (rule.attrs = rule.attrs || []).push(attr); - } else if (chr === ':') { - pos++; - var pseudoName = getIdent(); - var pseudo = { - name: pseudoName - }; - if (chr === '(') { - pos++; - var value = ''; - skipWhitespace(); - if (pseudos[pseudoName] === 'selector') { - pseudo.valueType = 'selector'; - value = this.parseSelector(); - } else { - pseudo.valueType = pseudos[pseudoName] || 'string'; - if (chr === '"') { - value = getStr('"', doubleQuotesEscapeChars); - } else if (chr === '\'') { - value = getStr('\'', singleQuoteEscapeChars); - } else if (substitutesEnabled && chr === '$') { - pos++; - value = getIdent(); - pseudo.valueType = 'substitute'; - } else { - while (pos < l) { - if (chr === ')') { - break; - } - value += chr; - pos++; - chr = str.charAt(pos); - } - value = value.trim(); - } - skipWhitespace(); - } - if (pos >= l) { - throw Error('Expected ")" but end of file reached.'); - } - if (chr !== ')') { - throw Error('Expected ")" but "' + chr + '" found.'); - } - pos++; - pseudo.value = value; - } - rule = rule || {}; - (rule.pseudos = rule.pseudos || []).push(pseudo); - } else { - break; - } - } - return rule; - }; - return this; - } - CssSelectorParser.prototype.parse = function(str) { - var context = new ParseContext(str, 0, this.pseudos, this.attrEqualityMods, this.ruleNestingOperators, this.substitutesEnabled); - return context.parse(); - }; - CssSelectorParser.prototype.escapeIdentifier = function(s) { - var result = ''; - var i = 0; - var len = s.length; - while (i < len) { - var chr = s.charAt(i); - if (identSpecialChars[chr]) { - result += '\\' + chr; - } else { - if (!(chr === '_' || chr === '-' || chr >= 'A' && chr <= 'Z' || chr >= 'a' && chr <= 'z' || i !== 0 && chr >= '0' && chr <= '9')) { - var charCode = chr.charCodeAt(0); - if ((charCode & 63488) === 55296) { - var extraCharCode = s.charCodeAt(i++); - if ((charCode & 64512) !== 55296 || (extraCharCode & 64512) !== 56320) { - throw Error('UCS-2(decode): illegal sequence'); - } - charCode = ((charCode & 1023) << 10) + (extraCharCode & 1023) + 65536; - } - result += '\\' + charCode.toString(16) + ' '; - } else { - result += chr; - } - } - i++; - } - return result; - }; - CssSelectorParser.prototype.escapeStr = function(s) { - var result = ''; - var i = 0; - var len = s.length; - var chr, replacement; - while (i < len) { - chr = s.charAt(i); - if (chr === '"') { - chr = '\\"'; - } else if (chr === '\\') { - chr = '\\\\'; - } else if (replacement = strReplacementsRev[chr]) { - chr = replacement; - } - result += chr; - i++; - } - return '"' + result + '"'; - }; - CssSelectorParser.prototype.render = function(path) { - return this._renderEntity(path).trim(); - }; - CssSelectorParser.prototype._renderEntity = function(entity) { - var currentEntity, parts, res; - res = ''; - switch (entity.type) { - case 'ruleSet': - currentEntity = entity.rule; - parts = []; - while (currentEntity) { - if (currentEntity.nestingOperator) { - parts.push(currentEntity.nestingOperator); - } - parts.push(this._renderEntity(currentEntity)); - currentEntity = currentEntity.rule; - } - res = parts.join(' '); - break; - - case 'selectors': - res = entity.selectors.map(this._renderEntity, this).join(', '); - break; - - case 'rule': - if (entity.tagName) { - if (entity.tagName === '*') { - res = '*'; - } else { - res = this.escapeIdentifier(entity.tagName); - } - } - if (entity.id) { - res += '#' + this.escapeIdentifier(entity.id); - } - if (entity.classNames) { - res += entity.classNames.map(function(cn) { - return '.' + this.escapeIdentifier(cn); - }, this).join(''); - } - if (entity.attrs) { - res += entity.attrs.map(function(attr) { - if (attr.operator) { - if (attr.valueType === 'substitute') { - return '[' + this.escapeIdentifier(attr.name) + attr.operator + '$' + attr.value + ']'; - } else { - return '[' + this.escapeIdentifier(attr.name) + attr.operator + this.escapeStr(attr.value) + ']'; - } - } else { - return '[' + this.escapeIdentifier(attr.name) + ']'; - } - }, this).join(''); - } - if (entity.pseudos) { - res += entity.pseudos.map(function(pseudo) { - if (pseudo.valueType) { - if (pseudo.valueType === 'selector') { - return ':' + this.escapeIdentifier(pseudo.name) + '(' + this._renderEntity(pseudo.value) + ')'; - } else if (pseudo.valueType === 'substitute') { - return ':' + this.escapeIdentifier(pseudo.name) + '($' + pseudo.value + ')'; - } else if (pseudo.valueType === 'numeric') { - return ':' + this.escapeIdentifier(pseudo.name) + '(' + pseudo.value + ')'; - } else { - return ':' + this.escapeIdentifier(pseudo.name) + '(' + this.escapeIdentifier(pseudo.value) + ')'; - } - } else { - return ':' + this.escapeIdentifier(pseudo.name); - } - }, this).join(''); - } - break; - - default: - throw Error('Unknown entity type: "' + entity.type(+'".')); - } - return res; - }; - exports.CssSelectorParser = CssSelectorParser; - }, {} ], - 31: [ function(_dereq_, module, exports) { - 'use strict'; - module.exports = function() { - return /\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F|\uD83D\uDC68(?:\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68\uD83C\uDFFB|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|[\u2695\u2696\u2708]\uFE0F|\uD83D[\uDC66\uDC67]|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708])\uFE0F|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C[\uDFFB-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)\uD83C\uDFFB|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB\uDFFC])|\uD83D\uDC69(?:\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB-\uDFFD])|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|(?:(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)\uFE0F|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\u200D[\u2640\u2642])|\uD83C\uDFF4\u200D\u2620)\uFE0F|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF4\uD83C\uDDF2|\uD83C\uDDF6\uD83C\uDDE6|[#\*0-9]\uFE0F\u20E3|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83D\uDC69(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270A-\u270D]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC70\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDCAA\uDD74\uDD7A\uDD90\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD36\uDDB5\uDDB6\uDDBB\uDDD2-\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5\uDEEB\uDEEC\uDEF4-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g; - }; - }, {} ], - 32: [ function(_dereq_, module, exports) { - (function(process, global) { - (function(global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : global.ES6Promise = factory(); - })(this, function() { - 'use strict'; - function objectOrFunction(x) { - var type = typeof x; - return x !== null && (type === 'object' || type === 'function'); - } - function isFunction(x) { - return typeof x === 'function'; - } - var _isArray = void 0; - if (Array.isArray) { - _isArray = Array.isArray; - } else { - _isArray = function(x) { - return Object.prototype.toString.call(x) === '[object Array]'; - }; - } - var isArray = _isArray; - var len = 0; - var vertxNext = void 0; - var customSchedulerFn = void 0; - var asap = function asap(callback, arg) { - queue[len] = callback; - queue[len + 1] = arg; - len += 2; - if (len === 2) { - if (customSchedulerFn) { - customSchedulerFn(flush); - } else { - scheduleFlush(); - } - } - }; - function setScheduler(scheduleFn) { - customSchedulerFn = scheduleFn; - } - function setAsap(asapFn) { - asap = asapFn; - } - var browserWindow = typeof window !== 'undefined' ? window : undefined; - var browserGlobal = browserWindow || {}; - var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver; - var isNode = typeof self === 'undefined' && typeof process !== 'undefined' && {}.toString.call(process) === '[object process]'; - var isWorker = typeof Uint8ClampedArray !== 'undefined' && typeof importScripts !== 'undefined' && typeof MessageChannel !== 'undefined'; - function useNextTick() { - return function() { - return process.nextTick(flush); - }; - } - function useVertxTimer() { - if (typeof vertxNext !== 'undefined') { - return function() { - vertxNext(flush); - }; - } - return useSetTimeout(); - } - function useMutationObserver() { - var iterations = 0; - var observer = new BrowserMutationObserver(flush); - var node = document.createTextNode(''); - observer.observe(node, { - characterData: true - }); - return function() { - node.data = iterations = ++iterations % 2; - }; - } - function useMessageChannel() { - var channel = new MessageChannel(); - channel.port1.onmessage = flush; - return function() { - return channel.port2.postMessage(0); - }; - } - function useSetTimeout() { - var globalSetTimeout = setTimeout; - return function() { - return globalSetTimeout(flush, 1); - }; - } - var queue = new Array(1e3); - function flush() { - for (var i = 0; i < len; i += 2) { - var callback = queue[i]; - var arg = queue[i + 1]; - callback(arg); - queue[i] = undefined; - queue[i + 1] = undefined; - } - len = 0; - } - function attemptVertx() { - try { - var vertx = Function('return this')().require('vertx'); - vertxNext = vertx.runOnLoop || vertx.runOnContext; - return useVertxTimer(); - } catch (e) { - return useSetTimeout(); - } - } - var scheduleFlush = void 0; - if (isNode) { - scheduleFlush = useNextTick(); - } else if (BrowserMutationObserver) { - scheduleFlush = useMutationObserver(); - } else if (isWorker) { - scheduleFlush = useMessageChannel(); - } else if (browserWindow === undefined && typeof _dereq_ === 'function') { - scheduleFlush = attemptVertx(); - } else { - scheduleFlush = useSetTimeout(); - } - function then(onFulfillment, onRejection) { - var parent = this; - var child = new this.constructor(noop); - if (child[PROMISE_ID] === undefined) { - makePromise(child); - } - var _state = parent._state; - if (_state) { - var callback = arguments[_state - 1]; - asap(function() { - return invokeCallback(_state, child, callback, parent._result); - }); - } else { - subscribe(parent, child, onFulfillment, onRejection); - } - return child; - } - function resolve$1(object) { - var Constructor = this; - if (object && typeof object === 'object' && object.constructor === Constructor) { - return object; - } - var promise = new Constructor(noop); - resolve(promise, object); - return promise; - } - var PROMISE_ID = Math.random().toString(36).substring(2); - function noop() {} - var PENDING = void 0; - var FULFILLED = 1; - var REJECTED = 2; - function selfFulfillment() { - return new TypeError('You cannot resolve a promise with itself'); - } - function cannotReturnOwn() { - return new TypeError('A promises callback cannot return that same promise.'); - } - function tryThen(then$$1, value, fulfillmentHandler, rejectionHandler) { - try { - then$$1.call(value, fulfillmentHandler, rejectionHandler); - } catch (e) { - return e; - } - } - function handleForeignThenable(promise, thenable, then$$1) { - asap(function(promise) { - var sealed = false; - var error = tryThen(then$$1, thenable, function(value) { - if (sealed) { - return; - } - sealed = true; - if (thenable !== value) { - resolve(promise, value); - } else { - fulfill(promise, value); - } - }, function(reason) { - if (sealed) { - return; - } - sealed = true; - reject(promise, reason); - }, 'Settle: ' + (promise._label || ' unknown promise')); - if (!sealed && error) { - sealed = true; - reject(promise, error); - } - }, promise); - } - function handleOwnThenable(promise, thenable) { - if (thenable._state === FULFILLED) { - fulfill(promise, thenable._result); - } else if (thenable._state === REJECTED) { - reject(promise, thenable._result); - } else { - subscribe(thenable, undefined, function(value) { - return resolve(promise, value); - }, function(reason) { - return reject(promise, reason); - }); - } - } - function handleMaybeThenable(promise, maybeThenable, then$$1) { - if (maybeThenable.constructor === promise.constructor && then$$1 === then && maybeThenable.constructor.resolve === resolve$1) { - handleOwnThenable(promise, maybeThenable); - } else { - if (then$$1 === undefined) { - fulfill(promise, maybeThenable); - } else if (isFunction(then$$1)) { - handleForeignThenable(promise, maybeThenable, then$$1); - } else { - fulfill(promise, maybeThenable); - } - } - } - function resolve(promise, value) { - if (promise === value) { - reject(promise, selfFulfillment()); - } else if (objectOrFunction(value)) { - var then$$1 = void 0; - try { - then$$1 = value.then; - } catch (error) { - reject(promise, error); - return; - } - handleMaybeThenable(promise, value, then$$1); - } else { - fulfill(promise, value); - } - } - function publishRejection(promise) { - if (promise._onerror) { - promise._onerror(promise._result); - } - publish(promise); - } - function fulfill(promise, value) { - if (promise._state !== PENDING) { - return; - } - promise._result = value; - promise._state = FULFILLED; - if (promise._subscribers.length !== 0) { - asap(publish, promise); - } - } - function reject(promise, reason) { - if (promise._state !== PENDING) { - return; - } - promise._state = REJECTED; - promise._result = reason; - asap(publishRejection, promise); - } - function subscribe(parent, child, onFulfillment, onRejection) { - var _subscribers = parent._subscribers; - var length = _subscribers.length; - parent._onerror = null; - _subscribers[length] = child; - _subscribers[length + FULFILLED] = onFulfillment; - _subscribers[length + REJECTED] = onRejection; - if (length === 0 && parent._state) { - asap(publish, parent); - } - } - function publish(promise) { - var subscribers = promise._subscribers; - var settled = promise._state; - if (subscribers.length === 0) { - return; - } - var child = void 0, callback = void 0, detail = promise._result; - for (var i = 0; i < subscribers.length; i += 3) { - child = subscribers[i]; - callback = subscribers[i + settled]; - if (child) { - invokeCallback(settled, child, callback, detail); - } else { - callback(detail); - } - } - promise._subscribers.length = 0; - } - function invokeCallback(settled, promise, callback, detail) { - var hasCallback = isFunction(callback), value = void 0, error = void 0, succeeded = true; - if (hasCallback) { - try { - value = callback(detail); - } catch (e) { - succeeded = false; - error = e; - } - if (promise === value) { - reject(promise, cannotReturnOwn()); - return; - } - } else { - value = detail; - } - if (promise._state !== PENDING) {} else if (hasCallback && succeeded) { - resolve(promise, value); - } else if (succeeded === false) { - reject(promise, error); - } else if (settled === FULFILLED) { - fulfill(promise, value); - } else if (settled === REJECTED) { - reject(promise, value); - } - } - function initializePromise(promise, resolver) { - try { - resolver(function resolvePromise(value) { - resolve(promise, value); - }, function rejectPromise(reason) { - reject(promise, reason); - }); - } catch (e) { - reject(promise, e); - } - } - var id = 0; - function nextId() { - return id++; - } - function makePromise(promise) { - promise[PROMISE_ID] = id++; - promise._state = undefined; - promise._result = undefined; - promise._subscribers = []; - } - function validationError() { - return new Error('Array Methods must be provided an Array'); - } - var Enumerator = function() { - function Enumerator(Constructor, input) { - this._instanceConstructor = Constructor; - this.promise = new Constructor(noop); - if (!this.promise[PROMISE_ID]) { - makePromise(this.promise); - } - if (isArray(input)) { - this.length = input.length; - this._remaining = input.length; - this._result = new Array(this.length); - if (this.length === 0) { - fulfill(this.promise, this._result); - } else { - this.length = this.length || 0; - this._enumerate(input); - if (this._remaining === 0) { - fulfill(this.promise, this._result); - } - } - } else { - reject(this.promise, validationError()); - } - } - Enumerator.prototype._enumerate = function _enumerate(input) { - for (var i = 0; this._state === PENDING && i < input.length; i++) { - this._eachEntry(input[i], i); - } - }; - Enumerator.prototype._eachEntry = function _eachEntry(entry, i) { - var c = this._instanceConstructor; - var resolve$$1 = c.resolve; - if (resolve$$1 === resolve$1) { - var _then = void 0; - var error = void 0; - var didError = false; - try { - _then = entry.then; - } catch (e) { - didError = true; - error = e; - } - if (_then === then && entry._state !== PENDING) { - this._settledAt(entry._state, i, entry._result); - } else if (typeof _then !== 'function') { - this._remaining--; - this._result[i] = entry; - } else if (c === Promise$1) { - var promise = new c(noop); - if (didError) { - reject(promise, error); - } else { - handleMaybeThenable(promise, entry, _then); - } - this._willSettleAt(promise, i); - } else { - this._willSettleAt(new c(function(resolve$$1) { - return resolve$$1(entry); - }), i); - } - } else { - this._willSettleAt(resolve$$1(entry), i); - } - }; - Enumerator.prototype._settledAt = function _settledAt(state, i, value) { - var promise = this.promise; - if (promise._state === PENDING) { - this._remaining--; - if (state === REJECTED) { - reject(promise, value); - } else { - this._result[i] = value; - } - } - if (this._remaining === 0) { - fulfill(promise, this._result); - } - }; - Enumerator.prototype._willSettleAt = function _willSettleAt(promise, i) { - var enumerator = this; - subscribe(promise, undefined, function(value) { - return enumerator._settledAt(FULFILLED, i, value); - }, function(reason) { - return enumerator._settledAt(REJECTED, i, reason); - }); - }; - return Enumerator; - }(); - function all(entries) { - return new Enumerator(this, entries).promise; - } - function race(entries) { - var Constructor = this; - if (!isArray(entries)) { - return new Constructor(function(_, reject) { - return reject(new TypeError('You must pass an array to race.')); - }); - } else { - return new Constructor(function(resolve, reject) { - var length = entries.length; - for (var i = 0; i < length; i++) { - Constructor.resolve(entries[i]).then(resolve, reject); - } - }); - } - } - function reject$1(reason) { - var Constructor = this; - var promise = new Constructor(noop); - reject(promise, reason); - return promise; - } - function needsResolver() { - throw new TypeError('You must pass a resolver function as the first argument to the promise constructor'); - } - function needsNew() { - throw new TypeError('Failed to construct \'Promise\': Please use the \'new\' operator, this object constructor cannot be called as a function.'); - } - var Promise$1 = function() { - function Promise(resolver) { - this[PROMISE_ID] = nextId(); - this._result = this._state = undefined; - this._subscribers = []; - if (noop !== resolver) { - typeof resolver !== 'function' && needsResolver(); - this instanceof Promise ? initializePromise(this, resolver) : needsNew(); - } - } - Promise.prototype.catch = function _catch(onRejection) { - return this.then(null, onRejection); - }; - Promise.prototype.finally = function _finally(callback) { - var promise = this; - var constructor = promise.constructor; - if (isFunction(callback)) { - return promise.then(function(value) { - return constructor.resolve(callback()).then(function() { - return value; - }); - }, function(reason) { - return constructor.resolve(callback()).then(function() { - throw reason; - }); - }); - } - return promise.then(callback, callback); - }; - return Promise; - }(); - Promise$1.prototype.then = then; - Promise$1.all = all; - Promise$1.race = race; - Promise$1.resolve = resolve$1; - Promise$1.reject = reject$1; - Promise$1._setScheduler = setScheduler; - Promise$1._setAsap = setAsap; - Promise$1._asap = asap; - function polyfill() { - var local = void 0; - if (typeof global !== 'undefined') { - local = global; - } else if (typeof self !== 'undefined') { - local = self; - } else { - try { - local = Function('return this')(); - } catch (e) { - throw new Error('polyfill failed because global object is unavailable in this environment'); - } - } - var P = local.Promise; - if (P) { - var promiseToString = null; - try { - promiseToString = Object.prototype.toString.call(P.resolve()); - } catch (e) {} - if (promiseToString === '[object Promise]' && !P.cast) { - return; - } - } - local.Promise = Promise$1; - } - Promise$1.polyfill = polyfill; - Promise$1.Promise = Promise$1; - return Promise$1; - }); - }).call(this, _dereq_('_process'), typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : typeof window !== 'undefined' ? window : {}); - }, { - _process: 33 - } ], - 33: [ function(_dereq_, module, exports) { - var process = module.exports = {}; - var cachedSetTimeout; - var cachedClearTimeout; - function defaultSetTimout() { - throw new Error('setTimeout has not been defined'); - } - function defaultClearTimeout() { - throw new Error('clearTimeout has not been defined'); - } - (function() { - try { - if (typeof setTimeout === 'function') { - cachedSetTimeout = setTimeout; - } else { - cachedSetTimeout = defaultSetTimout; - } - } catch (e) { - cachedSetTimeout = defaultSetTimout; - } - try { - if (typeof clearTimeout === 'function') { - cachedClearTimeout = clearTimeout; - } else { - cachedClearTimeout = defaultClearTimeout; - } - } catch (e) { - cachedClearTimeout = defaultClearTimeout; - } - })(); - function runTimeout(fun) { - if (cachedSetTimeout === setTimeout) { - return setTimeout(fun, 0); - } - if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { - cachedSetTimeout = setTimeout; - return setTimeout(fun, 0); - } - try { - return cachedSetTimeout(fun, 0); - } catch (e) { - try { - return cachedSetTimeout.call(null, fun, 0); - } catch (e) { - return cachedSetTimeout.call(this, fun, 0); - } - } - } - function runClearTimeout(marker) { - if (cachedClearTimeout === clearTimeout) { - return clearTimeout(marker); - } - if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { - cachedClearTimeout = clearTimeout; - return clearTimeout(marker); - } - try { - return cachedClearTimeout(marker); - } catch (e) { - try { - return cachedClearTimeout.call(null, marker); - } catch (e) { - return cachedClearTimeout.call(this, marker); - } - } - } - var queue = []; - var draining = false; - var currentQueue; - var queueIndex = -1; - function cleanUpNextTick() { - if (!draining || !currentQueue) { - return; - } - draining = false; - if (currentQueue.length) { - queue = currentQueue.concat(queue); - } else { - queueIndex = -1; - } - if (queue.length) { - drainQueue(); - } - } - function drainQueue() { - if (draining) { - return; - } - var timeout = runTimeout(cleanUpNextTick); - draining = true; - var len = queue.length; - while (len) { - currentQueue = queue; - queue = []; - while (++queueIndex < len) { - if (currentQueue) { - currentQueue[queueIndex].run(); - } - } - queueIndex = -1; - len = queue.length; - } - currentQueue = null; - draining = false; - runClearTimeout(timeout); - } - process.nextTick = function(fun) { - var args = new Array(arguments.length - 1); - if (arguments.length > 1) { - for (var i = 1; i < arguments.length; i++) { - args[i - 1] = arguments[i]; - } - } - queue.push(new Item(fun, args)); - if (queue.length === 1 && !draining) { - runTimeout(drainQueue); - } - }; - function Item(fun, array) { - this.fun = fun; - this.array = array; - } - Item.prototype.run = function() { - this.fun.apply(null, this.array); - }; - process.title = 'browser'; - process.browser = true; - process.env = {}; - process.argv = []; - process.version = ''; - process.versions = {}; - function noop() {} - process.on = noop; - process.addListener = noop; - process.once = noop; - process.off = noop; - process.removeListener = noop; - process.removeAllListeners = noop; - process.emit = noop; - process.prependListener = noop; - process.prependOnceListener = noop; - process.listeners = function(name) { - return []; - }; - process.binding = function(name) { - throw new Error('process.binding is not supported'); - }; - process.cwd = function() { - return '/'; - }; - process.chdir = function(dir) { - throw new Error('process.chdir is not supported'); - }; - process.umask = function() { - return 0; - }; - }, {} ], - 34: [ function(_dereq_, module, exports) { - (function(global) { - (function(self) { - 'use strict'; - if (self.WeakMap) { - return; - } - var hasOwnProperty = Object.prototype.hasOwnProperty; - var defineProperty = function(object, name, value) { - if (Object.defineProperty) { - Object.defineProperty(object, name, { - configurable: true, - writable: true, - value: value - }); - } else { - object[name] = value; - } - }; - self.WeakMap = function() { - function WeakMap() { - if (this === void 0) { - throw new TypeError('Constructor WeakMap requires \'new\''); - } - defineProperty(this, '_id', genId('_WeakMap')); - if (arguments.length > 0) { - throw new TypeError('WeakMap iterable is not supported'); - } - } - defineProperty(WeakMap.prototype, 'delete', function(key) { - checkInstance(this, 'delete'); - if (!isObject(key)) { - return false; - } - var entry = key[this._id]; - if (entry && entry[0] === key) { - delete key[this._id]; - return true; - } - return false; - }); - defineProperty(WeakMap.prototype, 'get', function(key) { - checkInstance(this, 'get'); - if (!isObject(key)) { - return void 0; - } - var entry = key[this._id]; - if (entry && entry[0] === key) { - return entry[1]; - } - return void 0; - }); - defineProperty(WeakMap.prototype, 'has', function(key) { - checkInstance(this, 'has'); - if (!isObject(key)) { - return false; - } - var entry = key[this._id]; - if (entry && entry[0] === key) { - return true; - } - return false; - }); - defineProperty(WeakMap.prototype, 'set', function(key, value) { - checkInstance(this, 'set'); - if (!isObject(key)) { - throw new TypeError('Invalid value used as weak map key'); - } - var entry = key[this._id]; - if (entry && entry[0] === key) { - entry[1] = value; - return this; - } - defineProperty(key, this._id, [ key, value ]); - return this; - }); - function checkInstance(x, methodName) { - if (!isObject(x) || !hasOwnProperty.call(x, '_id')) { - throw new TypeError(methodName + ' method called on incompatible receiver ' + typeof x); - } - } - function genId(prefix) { - return prefix + '_' + rand() + '.' + rand(); - } - function rand() { - return Math.random().toString().substring(2); - } - defineProperty(WeakMap, '_polyfill', true); - return WeakMap; - }(); - function isObject(x) { - return Object(x) === x; - } - })(typeof self !== 'undefined' ? self : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : this); - }).call(this, typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : typeof window !== 'undefined' ? window : {}); - }, {} ] - }, {}, [ 1 ]); 'use strict'; var utils = axe.utils = {}; 'use strict'; var helpers = {}; 'use strict'; - function _typeof(obj) { - if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') { - _typeof = function _typeof(obj) { - return typeof obj; - }; - } else { - _typeof = function _typeof(obj) { - return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj; - }; - } - return _typeof(obj); - } - function _extends() { - _extends = Object.assign || function(target) { - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i]; - for (var key in source) { - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - return target; - }; - return _extends.apply(this, arguments); - } + var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) { + return typeof obj; + } : function(obj) { + return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj; + }; function getDefaultConfiguration(audit) { 'use strict'; var config; @@ -2546,7 +68,7 @@ config.reporter = config.reporter || null; config.rules = config.rules || []; config.checks = config.checks || []; - config.data = _extends({ + config.data = Object.assign({ checks: {}, rules: {} }, config.data); @@ -2565,104 +87,7 @@ this.tagExclude = [ 'experimental' ]; this.defaultConfig = audit; this._init(); - this._defaultLocale = null; } - Audit.prototype._setDefaultLocale = function() { - if (this._defaultLocale) { - return; - } - var locale = { - checks: {}, - rules: {} - }; - var checkIDs = Object.keys(this.data.checks); - for (var i = 0; i < checkIDs.length; i++) { - var id = checkIDs[i]; - var check = this.data.checks[id]; - var _check$messages = check.messages, pass = _check$messages.pass, fail = _check$messages.fail, incomplete = _check$messages.incomplete; - locale.checks[id] = { - pass: pass, - fail: fail, - incomplete: incomplete - }; - } - var ruleIDs = Object.keys(this.data.rules); - for (var _i = 0; _i < ruleIDs.length; _i++) { - var _id = ruleIDs[_i]; - var rule = this.data.rules[_id]; - var description = rule.description, help = rule.help; - locale.rules[_id] = { - description: description, - help: help - }; - } - this._defaultLocale = locale; - }; - Audit.prototype._resetLocale = function() { - var defaultLocale = this._defaultLocale; - if (!defaultLocale) { - return; - } - this.applyLocale(defaultLocale); - }; - var mergeCheckLocale = function mergeCheckLocale(a, b) { - var pass = b.pass, fail = b.fail; - if (typeof pass === 'string') { - pass = axe.imports.doT.compile(pass); - } - if (typeof fail === 'string') { - fail = axe.imports.doT.compile(fail); - } - return _extends({}, a, { - messages: { - pass: pass || a.messages.pass, - fail: fail || a.messages.fail, - incomplete: _typeof(a.messages.incomplete) === 'object' ? _extends({}, a.messages.incomplete, {}, b.incomplete) : b.incomplete - } - }); - }; - var mergeRuleLocale = function mergeRuleLocale(a, b) { - var help = b.help, description = b.description; - if (typeof help === 'string') { - help = axe.imports.doT.compile(help); - } - if (typeof description === 'string') { - description = axe.imports.doT.compile(description); - } - return _extends({}, a, { - help: help || a.help, - description: description || a.description - }); - }; - Audit.prototype._applyCheckLocale = function(checks) { - var keys = Object.keys(checks); - for (var i = 0; i < keys.length; i++) { - var id = keys[i]; - if (!this.data.checks[id]) { - throw new Error('Locale provided for unknown check: "'.concat(id, '"')); - } - this.data.checks[id] = mergeCheckLocale(this.data.checks[id], checks[id]); - } - }; - Audit.prototype._applyRuleLocale = function(rules) { - var keys = Object.keys(rules); - for (var i = 0; i < keys.length; i++) { - var id = keys[i]; - if (!this.data.rules[id]) { - throw new Error('Locale provided for unknown rule: "'.concat(id, '"')); - } - this.data.rules[id] = mergeRuleLocale(this.data.rules[id], rules[id]); - } - }; - Audit.prototype.applyLocale = function(locale) { - this._setDefaultLocale(); - if (locale.checks) { - this._applyCheckLocale(locale.checks); - } - if (locale.rules) { - this._applyRuleLocale(locale.rules); - } - }; Audit.prototype._init = function() { var audit = getDefaultConfiguration(this.defaultConfig); axe.commons = commons = audit.commons; @@ -2698,7 +123,7 @@ Audit.prototype.addCheck = function(spec) { 'use strict'; var metadata = spec.metadata; - if (_typeof(metadata) === 'object') { + if ((typeof metadata === 'undefined' ? 'undefined' : _typeof(metadata)) === 'object') { this.data.checks[spec.id] = metadata; if (_typeof(metadata.messages) === 'object') { Object.keys(metadata.messages).filter(function(prop) { @@ -2716,110 +141,54 @@ this.checks[spec.id] = new Check(spec); } }; - function getRulesToRun(rules, context, options) { - var base = { - now: [], - later: [] - }; - var splitRules = rules.reduce(function(out, rule) { - if (!axe.utils.ruleShouldRun(rule, context, options)) { - return out; - } - if (rule.preload) { - out.later.push(rule); - return out; - } - out.now.push(rule); - return out; - }, base); - return splitRules; - } - function getDefferedRule(rule, context, options) { - if (options.performanceTimer) { - axe.utils.performanceTimer.mark('mark_rule_start_' + rule.id); - } - return function(resolve, reject) { - rule.run(context, options, function(ruleResult) { - resolve(ruleResult); - }, function(err) { - if (!options.debug) { - var errResult = Object.assign(new RuleResult(rule), { - result: axe.constants.CANTTELL, - description: 'An error occured while running this rule', - message: err.message, - stack: err.stack, - error: err, - errorNode: err.errorNode - }); - resolve(errResult); - } else { - reject(err); - } - }); - }; - } Audit.prototype.run = function(context, options, resolve, reject) { 'use strict'; - this.normalizeOptions(options); - axe._selectCache = []; - var allRulesToRun = getRulesToRun(this.rules, context, options); - var runNowRules = allRulesToRun.now; - var runLaterRules = allRulesToRun.later; - var nowRulesQueue = axe.utils.queue(); - runNowRules.forEach(function(rule) { - nowRulesQueue.defer(getDefferedRule(rule, context, options)); - }); - var preloaderQueue = axe.utils.queue(); - if (runLaterRules.length) { - preloaderQueue.defer(function(resolve) { - axe.utils.preload(options).then(function(assets) { - return resolve(assets); - })['catch'](function(err) { - console.warn('Couldn\'t load preload assets: ', err); - resolve(undefined); - }); - }); - } - var queueForNowRulesAndPreloader = axe.utils.queue(); - queueForNowRulesAndPreloader.defer(nowRulesQueue); - queueForNowRulesAndPreloader.defer(preloaderQueue); - queueForNowRulesAndPreloader.then(function(nowRulesAndPreloaderResults) { - var assetsFromQueue = nowRulesAndPreloaderResults.pop(); - if (assetsFromQueue && assetsFromQueue.length) { - var assets = assetsFromQueue[0]; - if (assets) { - context = _extends({}, context, {}, assets); + this.validateOptions(options); + axe._tree = axe.utils.getFlattenedTree(document.documentElement); + var q = axe.utils.queue(); + this.rules.forEach(function(rule) { + if (axe.utils.ruleShouldRun(rule, context, options)) { + if (options.performanceTimer) { + var markEnd = 'mark_rule_end_' + rule.id; + var markStart = 'mark_rule_start_' + rule.id; + axe.utils.performanceTimer.mark(markStart); } + q.defer(function(res, rej) { + rule.run(context, options, function(out) { + if (options.performanceTimer) { + axe.utils.performanceTimer.mark(markEnd); + axe.utils.performanceTimer.measure('rule_' + rule.id, markStart, markEnd); + } + res(out); + }, function(err) { + if (!options.debug) { + var errResult = Object.assign(new RuleResult(rule), { + result: axe.constants.CANTTELL, + description: 'An error occured while running this rule', + message: err.message, + stack: err.stack, + error: err + }); + res(errResult); + } else { + rej(err); + } + }); + }); } - var nowRulesResults = nowRulesAndPreloaderResults[0]; - if (!runLaterRules.length) { - axe._selectCache = undefined; - resolve(nowRulesResults.filter(function(result) { - return !!result; - })); - return; - } - var laterRulesQueue = axe.utils.queue(); - runLaterRules.forEach(function(rule) { - var deferredRule = getDefferedRule(rule, context, options); - laterRulesQueue.defer(deferredRule); - }); - laterRulesQueue.then(function(laterRuleResults) { - axe._selectCache = undefined; - resolve(nowRulesResults.concat(laterRuleResults).filter(function(result) { - return !!result; - })); - })['catch'](reject); - })['catch'](reject); + }); + q.then(function(results) { + axe._tree = undefined; + resolve(results.filter(function(result) { + return !!result; + })); + }).catch(reject); }; Audit.prototype.after = function(results, options) { 'use strict'; var rules = this.rules; return results.map(function(ruleResult) { var rule = axe.utils.findBy(rules, 'id', ruleResult.id); - if (!rule) { - throw new Error('Result for unknown rule. You may be running mismatch axe-core versions'); - } return rule.after(ruleResult, options); }); }; @@ -2828,43 +197,34 @@ return rule.id === ruleId; }); }; - Audit.prototype.normalizeOptions = function(options) { + Audit.prototype.validateOptions = function(options) { 'use strict'; var audit = this; if (_typeof(options.runOnly) === 'object') { - if (Array.isArray(options.runOnly)) { - options.runOnly = { - type: 'tag', - values: options.runOnly - }; - } var only = options.runOnly; - if (only.value && !only.values) { - only.values = only.value; - delete only.value; - } - if (!Array.isArray(only.values) || only.values.length === 0) { - throw new Error('runOnly.values must be a non-empty array'); - } - if ([ 'rule', 'rules' ].includes(only.type)) { - only.type = 'rule'; - only.values.forEach(function(ruleId) { + if (only.type === 'rule' && Array.isArray(only.value)) { + only.value.forEach(function(ruleId) { if (!audit.getRule(ruleId)) { throw new Error('unknown rule `' + ruleId + '` in options.runOnly'); } }); - } else if ([ 'tag', 'tags', undefined ].includes(only.type)) { - only.type = 'tag'; - var unmatchedTags = audit.rules.reduce(function(unmatchedTags, rule) { - return unmatchedTags.length ? unmatchedTags.filter(function(tag) { - return !rule.tags.includes(tag); - }) : unmatchedTags; - }, only.values); - if (unmatchedTags.length !== 0) { - axe.log('Could not find tags `' + unmatchedTags.join('`, `') + '`'); + } else if (Array.isArray(only.value) && only.value.length > 0) { + var tags = [].concat(only.value); + audit.rules.forEach(function(rule) { + var tagPos, i, l; + if (!tags) { + return; + } + for (i = 0, l = rule.tags.length; i < l; i++) { + tagPos = tags.indexOf(rule.tags[i]); + if (tagPos !== -1) { + tags.splice(tagPos, 1); + } + } + }); + if (tags.length !== 0) { + throw new Error('could not find tags `' + tags.join('`, `') + '`'); } - } else { - throw new Error('Unknown runOnly type \''.concat(only.type, '\'')); } } if (_typeof(options.rules) === 'object') { @@ -2897,7 +257,7 @@ Audit.prototype._constructHelpUrls = function() { var _this = this; var previous = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; - var version = (axe.version.match(/^[1-9][0-9]*\.[0-9]+/) || [ 'x.y' ])[0]; + var version = axe.version.substring(0, axe.version.lastIndexOf('.')); this.rules.forEach(function(rule) { if (!_this.data.rules[rule.id]) { _this.data.rules[rule.id] = {}; @@ -2911,26 +271,8 @@ Audit.prototype.resetRulesAndChecks = function() { 'use strict'; this._init(); - this._resetLocale(); }; 'use strict'; - (function() { - 'use strict'; - var _cache = {}; - var cache = { - set: function set(key, value) { - _cache[key] = value; - }, - get: function get(key) { - return _cache[key]; - }, - clear: function clear() { - _cache = {}; - } - }; - axe._cache = cache; - })(); - 'use strict'; function CheckResult(check) { 'use strict'; this.id = check.id; @@ -2953,7 +295,7 @@ } } Check.prototype.enabled = true; - Check.prototype.run = function(node, options, context, resolve, reject) { + Check.prototype.run = function(node, options, resolve, reject) { 'use strict'; options = options || {}; var enabled = options.hasOwnProperty('enabled') ? options.enabled : this.enabled, checkOptions = options.options || this.options; @@ -2962,46 +304,21 @@ var checkHelper = axe.utils.checkHelper(checkResult, options, resolve, reject); var result; try { - result = this.evaluate.call(checkHelper, node.actualNode, checkOptions, node, context); + result = this.evaluate.call(checkHelper, node.actualNode, checkOptions, node); } catch (e) { - if (node && node.actualNode) { - e.errorNode = new DqElement(node.actualNode).toJSON(); - } reject(e); return; } if (!checkHelper.isAsync) { checkResult.result = result; - resolve(checkResult); + setTimeout(function() { + resolve(checkResult); + }, 0); } } else { resolve(null); } }; - Check.prototype.runSync = function(node, options, context) { - options = options || {}; - var _options = options, _options$enabled = _options.enabled, enabled = _options$enabled === void 0 ? this.enabled : _options$enabled; - if (!enabled) { - return null; - } - var checkOptions = options.options || this.options; - var checkResult = new CheckResult(this); - var checkHelper = axe.utils.checkHelper(checkResult, options); - checkHelper.async = function() { - throw new Error('Cannot run async check while in a synchronous run'); - }; - var result; - try { - result = this.evaluate.call(checkHelper, node.actualNode, checkOptions, node, context); - } catch (e) { - if (node && node.actualNode) { - e.errorNode = new DqElement(node.actualNode).toJSON(); - } - throw e; - } - checkResult.result = result; - return checkResult; - }; Check.prototype.configure = function(spec) { var _this = this; [ 'options', 'enabled' ].filter(function(prop) { @@ -3016,18 +333,11 @@ }); }; 'use strict'; - function _typeof(obj) { - if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') { - _typeof = function _typeof(obj) { - return typeof obj; - }; - } else { - _typeof = function _typeof(obj) { - return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj; - }; - } - return _typeof(obj); - } + var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) { + return typeof obj; + } : function(obj) { + return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj; + }; function pushUniqueFrame(collection, frame) { 'use strict'; if (axe.utils.isHidden(frame)) { @@ -3068,7 +378,7 @@ } function normalizeContext(context) { 'use strict'; - if (context && _typeof(context) === 'object' || context instanceof NodeList) { + if (context && (typeof context === 'undefined' ? 'undefined' : _typeof(context)) === 'object' || context instanceof NodeList) { if (context instanceof Node) { return { include: [ context ], @@ -3107,7 +417,7 @@ if (typeof item === 'string') { nodeList = Array.from(document.querySelectorAll(item)); result = result.concat(nodeList.map(function(node) { - return axe.utils.getNodeFromTree(node); + return axe.utils.getFlattenedTree(node)[0]; })); break; } else if (item && item.length && !(item instanceof Node)) { @@ -3116,15 +426,11 @@ } else { nodeList = Array.from(document.querySelectorAll(item[0])); result = result.concat(nodeList.map(function(node) { - return axe.utils.getNodeFromTree(node); + return axe.utils.getFlattenedTree(node)[0]; })); } } else if (item instanceof Node) { - if (item.documentElement instanceof Node) { - result.push(context.flatTree[0]); - } else { - result.push(axe.utils.getNodeFromTree(item)); - } + result.push(axe.utils.getFlattenedTree(item)[0]); } } return result.filter(function(r) { @@ -3145,35 +451,20 @@ }); } } - function getRootNode(_ref) { - var include = _ref.include, exclude = _ref.exclude; - var selectors = Array.from(include).concat(Array.from(exclude)); - var localDocument = selectors.reduce(function(result, item) { - if (result) { - return result; - } else if (item instanceof Element) { - return item.ownerDocument; - } else if (item instanceof Document) { - return item; - } - }, null); - return (localDocument || document).documentElement; - } function Context(spec) { 'use strict'; - var _this = this; + var self = this; this.frames = []; this.initiator = spec && typeof spec.initiator === 'boolean' ? spec.initiator : true; this.page = false; spec = normalizeContext(spec); - this.flatTree = axe.utils.getFlattenedTree(getRootNode(spec)); this.exclude = spec.exclude; this.include = spec.include; this.include = parseSelectorArray(this, 'include'); this.exclude = parseSelectorArray(this, 'exclude'); axe.utils.select('frame, iframe', this).forEach(function(frame) { - if (isNodeInContext(frame, _this)) { - pushUniqueFrame(_this.frames, frame.actualNode); + if (isNodeInContext(frame, self)) { + pushUniqueFrame(self.frames, frame.actualNode); } }); if (this.include.length === 1 && this.include[0].actualNode === document.documentElement) { @@ -3183,10 +474,6 @@ if (err instanceof Error) { throw err; } - if (!Array.isArray(this.include)) { - this.include = Array.from(this.include); - } - this.include.sort(axe.utils.nodeSorter); } 'use strict'; function RuleResult(rule) { @@ -3210,7 +497,6 @@ this.all = spec.all || []; this.none = spec.none || []; this.tags = spec.tags || []; - this.preload = spec.preload ? true : false; if (spec.matches) { this.matches = createExecutionContext(spec.matches); } @@ -3220,34 +506,16 @@ return true; }; Rule.prototype.gather = function(context) { - var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var markStart = 'mark_gather_start_' + this.id; - var markEnd = 'mark_gather_end_' + this.id; - var markHiddenStart = 'mark_isHidden_start_' + this.id; - var markHiddenEnd = 'mark_isHidden_end_' + this.id; - if (options.performanceTimer) { - axe.utils.performanceTimer.mark(markStart); - } + 'use strict'; var elements = axe.utils.select(this.selector, context); if (this.excludeHidden) { - if (options.performanceTimer) { - axe.utils.performanceTimer.mark(markHiddenStart); - } - elements = elements.filter(function(element) { + return elements.filter(function(element) { return !axe.utils.isHidden(element.actualNode); }); - if (options.performanceTimer) { - axe.utils.performanceTimer.mark(markHiddenEnd); - axe.utils.performanceTimer.measure('rule_' + this.id + '#gather_axe.utils.isHidden', markHiddenStart, markHiddenEnd); - } - } - if (options.performanceTimer) { - axe.utils.performanceTimer.mark(markEnd); - axe.utils.performanceTimer.measure('rule_' + this.id + '#gather', markStart, markEnd); } return elements; }; - Rule.prototype.runChecks = function(type, node, options, context, resolve, reject) { + Rule.prototype.runChecks = function(type, node, options, resolve, reject) { 'use strict'; var self = this; var checkQueue = axe.utils.queue(); @@ -3255,7 +523,7 @@ var check = self._audit.checks[c.id || c]; var option = axe.utils.getCheckOption(check, self.id, options); checkQueue.defer(function(res, rej) { - check.run(node, option, context, res, rej); + check.run(node, option, res, rej); }); }); checkQueue.then(function(results) { @@ -3266,38 +534,17 @@ type: type, results: results }); - })['catch'](reject); + }).catch(reject); }; - Rule.prototype.runChecksSync = function(type, node, options, context) { - 'use strict'; - var self = this; - var results = []; - this[type].forEach(function(c) { - var check = self._audit.checks[c.id || c]; - var option = axe.utils.getCheckOption(check, self.id, options); - results.push(check.runSync(node, option, context)); - }); - results = results.filter(function(check) { - return check; - }); - return { - type: type, - results: results - }; - }; - Rule.prototype.run = function(context) { + Rule.prototype.run = function(context, options, resolve, reject) { var _this = this; - var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var resolve = arguments.length > 2 ? arguments[2] : undefined; - var reject = arguments.length > 3 ? arguments[3] : undefined; - if (options.performanceTimer) { - this._trackPerformance(); - } var q = axe.utils.queue(); var ruleResult = new RuleResult(this); - var nodes; + var nodes = void 0; try { - nodes = this.gatherAndMatchNodes(context, options); + nodes = this.gather(context).filter(function(node) { + return _this.matches(node.actualNode, node); + }); } catch (error) { reject(new SupportError({ cause: error, @@ -3306,126 +553,49 @@ return; } if (options.performanceTimer) { - this._logGatherPerformance(nodes); + axe.log('gather (', nodes.length, '):', axe.utils.performanceTimer.timeElapsed() + 'ms'); } nodes.forEach(function(node) { q.defer(function(resolveNode, rejectNode) { var checkQueue = axe.utils.queue(); - [ 'any', 'all', 'none' ].forEach(function(type) { - checkQueue.defer(function(res, rej) { - _this.runChecks(type, node, options, context, res, rej); - }); + checkQueue.defer(function(res, rej) { + _this.runChecks('any', node, options, res, rej); + }); + checkQueue.defer(function(res, rej) { + _this.runChecks('all', node, options, res, rej); + }); + checkQueue.defer(function(res, rej) { + _this.runChecks('none', node, options, res, rej); }); checkQueue.then(function(results) { - var result = getResult(results); - if (result) { - result.node = new axe.utils.DqElement(node.actualNode, options); - ruleResult.nodes.push(result); + if (results.length) { + var hasResults = false, result = {}; + results.forEach(function(r) { + var res = r.results.filter(function(result) { + return result; + }); + result[r.type] = res; + if (res.length) { + hasResults = true; + } + }); + if (hasResults) { + result.node = new axe.utils.DqElement(node.actualNode, options); + ruleResult.nodes.push(result); + } } resolveNode(); - })['catch'](function(err) { + }).catch(function(err) { return rejectNode(err); }); }); }); - q.defer(function(resolve) { - return setTimeout(resolve, 0); - }); - if (options.performanceTimer) { - this._logRulePerformance(); - } q.then(function() { return resolve(ruleResult); - })['catch'](function(error) { + }).catch(function(error) { return reject(error); }); }; - Rule.prototype.runSync = function(context) { - var _this2 = this; - var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - if (options.performanceTimer) { - this._trackPerformance(); - } - var ruleResult = new RuleResult(this); - var nodes; - try { - nodes = this.gatherAndMatchNodes(context, options); - } catch (error) { - throw new SupportError({ - cause: error, - ruleId: this.id - }); - } - if (options.performanceTimer) { - this._logGatherPerformance(nodes); - } - nodes.forEach(function(node) { - var results = []; - [ 'any', 'all', 'none' ].forEach(function(type) { - results.push(_this2.runChecksSync(type, node, options, context)); - }); - var result = getResult(results); - if (result) { - result.node = node.actualNode ? new axe.utils.DqElement(node.actualNode, options) : null; - ruleResult.nodes.push(result); - } - }); - if (options.performanceTimer) { - this._logRulePerformance(); - } - return ruleResult; - }; - Rule.prototype._trackPerformance = function() { - this._markStart = 'mark_rule_start_' + this.id; - this._markEnd = 'mark_rule_end_' + this.id; - this._markChecksStart = 'mark_runchecks_start_' + this.id; - this._markChecksEnd = 'mark_runchecks_end_' + this.id; - }; - Rule.prototype._logGatherPerformance = function(nodes) { - axe.log('gather (', nodes.length, '):', axe.utils.performanceTimer.timeElapsed() + 'ms'); - axe.utils.performanceTimer.mark(this._markChecksStart); - }; - Rule.prototype._logRulePerformance = function() { - axe.utils.performanceTimer.mark(this._markChecksEnd); - axe.utils.performanceTimer.mark(this._markEnd); - axe.utils.performanceTimer.measure('runchecks_' + this.id, this._markChecksStart, this._markChecksEnd); - axe.utils.performanceTimer.measure('rule_' + this.id, this._markStart, this._markEnd); - }; - function getResult(results) { - if (results.length) { - var hasResults = false, result = {}; - results.forEach(function(r) { - var res = r.results.filter(function(result) { - return result; - }); - result[r.type] = res; - if (res.length) { - hasResults = true; - } - }); - if (hasResults) { - return result; - } - return null; - } - } - Rule.prototype.gatherAndMatchNodes = function(context, options) { - var _this3 = this; - var markMatchesStart = 'mark_matches_start_' + this.id; - var markMatchesEnd = 'mark_matches_end_' + this.id; - var nodes = this.gather(context, options); - if (options.performanceTimer) { - axe.utils.performanceTimer.mark(markMatchesStart); - } - nodes = nodes.filter(function(node) { - return _this3.matches(node.actualNode, node, context); - }); - if (options.performanceTimer) { - axe.utils.performanceTimer.mark(markMatchesEnd); - axe.utils.performanceTimer.measure('rule_' + this.id + '#matches', markMatchesStart, markMatchesEnd); - } - return nodes; - }; function findAfterChecks(rule) { 'use strict'; return axe.utils.getAllChecks(rule).map(function(c) { @@ -3527,188 +697,6 @@ } }; 'use strict'; - function _typeof(obj) { - if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') { - _typeof = function _typeof(obj) { - return typeof obj; - }; - } else { - _typeof = function _typeof(obj) { - return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj; - }; - } - return _typeof(obj); - } - function _possibleConstructorReturn(self, call) { - if (call && (_typeof(call) === 'object' || typeof call === 'function')) { - return call; - } - return _assertThisInitialized(self); - } - function _getPrototypeOf(o) { - _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { - return o.__proto__ || Object.getPrototypeOf(o); - }; - return _getPrototypeOf(o); - } - function _assertThisInitialized(self) { - if (self === void 0) { - throw new ReferenceError('this hasn\'t been initialised - super() hasn\'t been called'); - } - return self; - } - function _inherits(subClass, superClass) { - if (typeof superClass !== 'function' && superClass !== null) { - throw new TypeError('Super expression must either be null or a function'); - } - subClass.prototype = Object.create(superClass && superClass.prototype, { - constructor: { - value: subClass, - writable: true, - configurable: true - } - }); - if (superClass) { - _setPrototypeOf(subClass, superClass); - } - } - function _setPrototypeOf(o, p) { - _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { - o.__proto__ = p; - return o; - }; - return _setPrototypeOf(o, p); - } - function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError('Cannot call a class as a function'); - } - } - function _defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ('value' in descriptor) { - descriptor.writable = true; - } - Object.defineProperty(target, descriptor.key, descriptor); - } - } - function _createClass(Constructor, protoProps, staticProps) { - if (protoProps) { - _defineProperties(Constructor.prototype, protoProps); - } - if (staticProps) { - _defineProperties(Constructor, staticProps); - } - return Constructor; - } - var whitespaceRegex = /[\t\r\n\f]/g; - var AbstractVirtualNode = function() { - function AbstractVirtualNode() { - _classCallCheck(this, AbstractVirtualNode); - this.children = []; - this.parent = null; - } - _createClass(AbstractVirtualNode, [ { - key: 'hasClass', - value: function hasClass() { - throw new Error('VirtualNode class must have a "hasClass" function'); - } - }, { - key: 'attr', - value: function attr() { - throw new Error('VirtualNode class must have a "attr" function'); - } - }, { - key: 'hasAttr', - value: function hasAttr() { - throw new Error('VirtualNode class must have a "hasAttr" function'); - } - }, { - key: 'props', - get: function get() { - throw new Error('VirtualNode class must have a "props" object consisting ' + 'of "nodeType" and "nodeName" properties'); - } - } ]); - return AbstractVirtualNode; - }(); - var VirtualNode = function(_AbstractVirtualNode) { - _inherits(VirtualNode, _AbstractVirtualNode); - function VirtualNode(node, parent, shadowId) { - var _this; - _classCallCheck(this, VirtualNode); - _this = _possibleConstructorReturn(this, _getPrototypeOf(VirtualNode).call(this)); - _this.shadowId = shadowId; - _this.children = []; - _this.actualNode = node; - _this.parent = parent; - _this._isHidden = null; - _this._cache = {}; - if (axe._cache.get('nodeMap')) { - axe._cache.get('nodeMap').set(node, _assertThisInitialized(_this)); - } - return _this; - } - _createClass(VirtualNode, [ { - key: 'hasClass', - value: function hasClass(className) { - var classAttr = this.attr('class'); - if (!classAttr) { - return false; - } - var selector = ' ' + className + ' '; - return (' ' + classAttr + ' ').replace(whitespaceRegex, ' ').indexOf(selector) >= 0; - } - }, { - key: 'attr', - value: function attr(attrName) { - if (typeof this.actualNode.getAttribute !== 'function') { - return null; - } - return this.actualNode.getAttribute(attrName); - } - }, { - key: 'hasAttr', - value: function hasAttr(attrName) { - if (typeof this.actualNode.hasAttribute !== 'function') { - return false; - } - return this.actualNode.hasAttribute(attrName); - } - }, { - key: 'props', - get: function get() { - var _this$actualNode = this.actualNode, nodeType = _this$actualNode.nodeType, nodeName = _this$actualNode.nodeName, id = _this$actualNode.id, type = _this$actualNode.type; - return { - nodeType: nodeType, - nodeName: nodeName.toLowerCase(), - id: id, - type: type - }; - } - }, { - key: 'isFocusable', - get: function get() { - if (!this._cache.hasOwnProperty('isFocusable')) { - this._cache.isFocusable = axe.commons.dom.isFocusable(this.actualNode); - } - return this._cache.isFocusable; - } - }, { - key: 'tabbableElements', - get: function get() { - if (!this._cache.hasOwnProperty('tabbableElements')) { - this._cache.tabbableElements = axe.commons.dom.getTabbableElements(this); - } - return this._cache.tabbableElements; - } - } ]); - return VirtualNode; - }(AbstractVirtualNode); - axe.AbstractVirtualNode = AbstractVirtualNode; - 'use strict'; (function(axe) { var definitions = [ { name: 'NA', @@ -3736,11 +724,7 @@ results: [], resultGroups: [], resultGroupMap: {}, - impact: Object.freeze([ 'minor', 'moderate', 'serious', 'critical' ]), - preload: Object.freeze({ - assets: [ 'cssom' ], - timeout: 1e4 - }) + impact: Object.freeze([ 'minor', 'moderate', 'serious', 'critical' ]) }; definitions.forEach(function(definition) { var name = definition.name; @@ -3766,18 +750,11 @@ }); })(axe); 'use strict'; - function _typeof(obj) { - if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') { - _typeof = function _typeof(obj) { - return typeof obj; - }; - } else { - _typeof = function _typeof(obj) { - return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj; - }; - } - return _typeof(obj); - } + var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) { + return typeof obj; + } : function(obj) { + return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj; + }; axe.log = function() { 'use strict'; if ((typeof console === 'undefined' ? 'undefined' : _typeof(console)) === 'object' && console.log) { @@ -3785,10 +762,42 @@ } }; 'use strict'; + var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) { + return typeof obj; + } : function(obj) { + return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj; + }; + axe.a11yCheck = function(context, options, callback) { + 'use strict'; + if (typeof options === 'function') { + callback = options; + options = {}; + } + if (!options || (typeof options === 'undefined' ? 'undefined' : _typeof(options)) !== 'object') { + options = {}; + } + var audit = axe._audit; + if (!audit) { + throw new Error('No audit configured'); + } + options.reporter = options.reporter || audit.reporter || 'v2'; + if (options.performanceTimer) { + axe.utils.performanceTimer.start(); + } + var reporter = axe.getReporter(options.reporter); + axe._runRules(context, options, function(results) { + var res = reporter(results, options, callback); + if (res !== undefined) { + if (options.performanceTimer) { + axe.utils.performanceTimer.end(); + } + callback(res); + } + }, axe.log); + }; + 'use strict'; function cleanupPlugins(resolve, reject) { 'use strict'; - resolve = resolve || function() {}; - reject = reject || axe.log; if (!axe._audit) { throw new Error('No audit configured'); } @@ -3807,10 +816,9 @@ } }); }); - var flattenedTree = axe.utils.getFlattenedTree(document.body); - axe.utils.querySelectorAll(flattenedTree, 'iframe, frame').forEach(function(node) { + axe.utils.toArray(document.querySelectorAll('frame, iframe')).forEach(function(frame) { q.defer(function(res, rej) { - return axe.utils.sendCommandToFrame(node.actualNode, { + return axe.utils.sendCommandToFrame(frame, { command: 'cleanup-plugin' }, res, rej); }); @@ -3821,7 +829,7 @@ } else { reject(cleanupErrors); } - })['catch'](reject); + }).catch(reject); } axe.cleanup = cleanupPlugins; 'use strict'; @@ -3840,20 +848,11 @@ audit.addCheck(check); }); } - var modifiedRules = []; if (spec.rules) { spec.rules.forEach(function(rule) { - modifiedRules.push(rule.id); audit.addRule(rule); }); } - if (spec.disableOtherRules) { - audit.rules.forEach(function(rule) { - if (modifiedRules.includes(rule.id) === false) { - rule.enabled = false; - } - }); - } if (typeof spec.branding !== 'undefined') { audit.setBranding(spec.branding); } else { @@ -3862,9 +861,6 @@ if (spec.tagExclude) { audit.tagExclude = spec.tagExclude; } - if (spec.locale) { - audit.applyLocale(spec.locale); - } } axe.configure = configureChecksRulesAndBranding; 'use strict'; @@ -3899,16 +895,13 @@ callback(err); }; var context = data && data.context || {}; - if (context.hasOwnProperty('include') && !context.include.length) { + if (context.include && !context.include.length) { context.include = [ document ]; } var options = data && data.options || {}; switch (data.command) { case 'rules': - return runRules(context, options, function(results, cleanup) { - resolve(results); - cleanup(); - }, reject); + return runRules(context, options, resolve, reject); case 'cleanup-plugin': return cleanupPlugins(resolve, reject); @@ -4001,19 +994,11 @@ } axe.reset = resetConfiguration; 'use strict'; - function cleanup() { - axe._cache.clear(); - axe._tree = undefined; - axe._selectorData = undefined; - } function runRules(context, options, resolve, reject) { 'use strict'; try { context = new Context(context); - axe._tree = context.flatTree; - axe._selectorData = axe.utils.getSelectorData(context.flatTree); } catch (e) { - cleanup(); return reject(e); } var q = axe.utils.queue(); @@ -4026,24 +1011,23 @@ axe.utils.collectResultsFromFrames(context, options, 'rules', null, res, rej); }); } - var scrollState; q.defer(function(res, rej) { if (options.restoreScroll) { - scrollState = axe.utils.getScrollState(); + var scrollState = axe.utils.getScrollState(); + audit.run(context, options, res, rej); + axe.utils.setScrollState(scrollState); + } else { + audit.run(context, options, res, rej); } - audit.run(context, options, res, rej); }); q.then(function(data) { try { - if (scrollState) { - axe.utils.setScrollState(scrollState); - } if (options.performanceTimer) { axe.utils.performanceTimer.auditEnd(); } - var results = axe.utils.mergeResults(data.map(function(results) { + var results = axe.utils.mergeResults(data.map(function(d) { return { - results: results + results: d }; })); if (context.initiator) { @@ -4052,80 +1036,22 @@ results = results.map(axe.utils.finalizeRuleResult); } try { - resolve(results, cleanup); + resolve(results); } catch (e) { - cleanup(); axe.log(e); } } catch (e) { - cleanup(); reject(e); } - })['catch'](function(e) { - cleanup(); - reject(e); - }); + }).catch(reject); } axe._runRules = runRules; 'use strict'; - function _extends() { - _extends = Object.assign || function(target) { - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i]; - for (var key in source) { - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - return target; - }; - return _extends.apply(this, arguments); - } - axe.runVirtualRule = function(ruleId, vNode) { - var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - options.reporter = options.reporter || axe._audit.reporter || 'v1'; - axe._selectorData = {}; - var rule = axe._audit.rules.find(function(rule) { - return rule.id === ruleId; - }); - if (!rule) { - throw new Error('unknown rule `' + ruleId + '`'); - } - rule = Object.create(rule, { - excludeHidden: { - value: false - } - }); - var context = { - include: [ vNode ] - }; - var rawResults = rule.runSync(context, options); - axe.utils.publishMetaData(rawResults); - axe.utils.finalizeRuleResult(rawResults); - var results = axe.utils.aggregateResult([ rawResults ]); - results.violations.forEach(function(result) { - return result.nodes.forEach(function(nodeResult) { - nodeResult.failureSummary = helpers.failureSummary(nodeResult); - }); - }); - return _extends({}, helpers.getEnvironmentData(), {}, results, { - toolOptions: options - }); + var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) { + return typeof obj; + } : function(obj) { + return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj; }; - 'use strict'; - function _typeof(obj) { - if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') { - _typeof = function _typeof(obj) { - return typeof obj; - }; - } else { - _typeof = function _typeof(obj) { - return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj; - }; - } - return _typeof(obj); - } function isContext(potential) { 'use strict'; switch (true) { @@ -4135,7 +1061,7 @@ case NodeList && potential instanceof NodeList: return true; - case _typeof(potential) !== 'object': + case (typeof potential === 'undefined' ? 'undefined' : _typeof(potential)) !== 'object': return false; case potential.include !== undefined: @@ -4159,7 +1085,7 @@ options = context; context = document; } - if (_typeof(options) !== 'object') { + if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) !== 'object') { if (callback !== undefined) { throw typeErr; } @@ -4188,18 +1114,17 @@ if (options.performanceTimer) { axe.utils.performanceTimer.start(); } - var p; + var p = void 0; var reject = noop; var resolve = noop; - if (typeof Promise === 'function' && callback === noop) { + if (window.Promise && callback === noop) { p = new Promise(function(_resolve, _reject) { reject = _reject; resolve = _resolve; }); } - axe._runRules(context, options, function(rawResults, cleanup) { + axe._runRules(context, options, function(rawResults) { var respond = function respond(results) { - cleanup(); try { callback(null, results); } catch (e) { @@ -4217,7 +1142,6 @@ respond(results); } } catch (err) { - cleanup(); callback(err); reject(err); } @@ -4248,47 +1172,16 @@ }).join('\n\n'); }; 'use strict'; - helpers.getEnvironmentData = function getEnvironmentData() { - var win = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window; - var _win$screen = win.screen, screen = _win$screen === void 0 ? {} : _win$screen, _win$navigator = win.navigator, navigator = _win$navigator === void 0 ? {} : _win$navigator, _win$location = win.location, location = _win$location === void 0 ? {} : _win$location, innerHeight = win.innerHeight, innerWidth = win.innerWidth; - var orientation = screen.msOrientation || screen.orientation || screen.mozOrientation || {}; - return { - testEngine: { - name: 'axe-core', - version: axe.version - }, - testRunner: { - name: axe._audit.brand - }, - testEnvironment: { - userAgent: navigator.userAgent, - windowWidth: innerWidth, - windowHeight: innerHeight, - orientationAngle: orientation.angle, - orientationType: orientation.type - }, - timestamp: new Date().toISOString(), - url: location.href - }; - }; - 'use strict'; helpers.incompleteFallbackMessage = function incompleteFallbackMessage() { 'use strict'; return axe._audit.data.incompleteFallbackMessage(); }; 'use strict'; - function _typeof(obj) { - if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') { - _typeof = function _typeof(obj) { - return typeof obj; - }; - } else { - _typeof = function _typeof(obj) { - return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj; - }; - } - return _typeof(obj); - } + var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) { + return typeof obj; + } : function(obj) { + return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj; + }; function normalizeRelatedNodes(node, options) { 'use strict'; [ 'any', 'all', 'none' ].forEach(function(type) { @@ -4319,14 +1212,9 @@ var resultKeys = axe.constants.resultGroups; helpers.processAggregate = function(results, options) { var resultObject = axe.utils.aggregateResult(results); + resultObject.timestamp = new Date().toISOString(); + resultObject.url = window.location.href; resultKeys.forEach(function(key) { - if (options.resultTypes && !options.resultTypes.includes(key)) { - (resultObject[key] || []).forEach(function(ruleResult) { - if (Array.isArray(ruleResult.nodes) && ruleResult.nodes.length > 0) { - ruleResult.nodes = [ ruleResult.nodes[0] ]; - } - }); - } resultObject[key] = (resultObject[key] || []).map(function(ruleResult) { ruleResult = Object.assign({}, ruleResult); if (Array.isArray(ruleResult.nodes) && ruleResult.nodes.length > 0) { @@ -4360,135 +1248,46 @@ return resultObject; }; 'use strict'; - function _extends() { - _extends = Object.assign || function(target) { - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i]; - for (var key in source) { - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - return target; - }; - return _extends.apply(this, arguments); - } axe.addReporter('na', function(results, options, callback) { 'use strict'; - console.warn('"na" reporter will be deprecated in axe v4.0. Use the "v2" reporter instead.'); if (typeof options === 'function') { callback = options; options = {}; } var out = helpers.processAggregate(results, options); - callback(_extends({}, helpers.getEnvironmentData(), { - toolOptions: options, + callback({ violations: out.violations, passes: out.passes, incomplete: out.incomplete, - inapplicable: out.inapplicable - })); + inapplicable: out.inapplicable, + timestamp: out.timestamp, + url: out.url + }); }); 'use strict'; - function _extends() { - _extends = Object.assign || function(target) { - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i]; - for (var key in source) { - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - return target; - }; - return _extends.apply(this, arguments); - } axe.addReporter('no-passes', function(results, options, callback) { 'use strict'; if (typeof options === 'function') { callback = options; options = {}; } - options.resultTypes = [ 'violations' ]; var out = helpers.processAggregate(results, options); - callback(_extends({}, helpers.getEnvironmentData(), { - toolOptions: options, - violations: out.violations - })); + callback({ + violations: out.violations, + timestamp: out.timestamp, + url: out.url + }); }); 'use strict'; - axe.addReporter('rawEnv', function(results, options, callback) { - if (typeof options === 'function') { - callback = options; - options = {}; - } - function rawCallback(raw) { - var env = helpers.getEnvironmentData(); - callback({ - raw: raw, - env: env - }); - } - axe.getReporter('raw')(results, options, rawCallback); - }); - 'use strict'; - function _extends() { - _extends = Object.assign || function(target) { - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i]; - for (var key in source) { - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - return target; - }; - return _extends.apply(this, arguments); - } axe.addReporter('raw', function(results, options, callback) { 'use strict'; if (typeof options === 'function') { callback = options; options = {}; } - if (!results || !Array.isArray(results)) { - return callback(results); - } - var transformedResults = results.map(function(result) { - var transformedResult = _extends({}, result); - var types = [ 'passes', 'violations', 'incomplete', 'inapplicable' ]; - for (var _i = 0, _types = types; _i < _types.length; _i++) { - var type = _types[_i]; - if (transformedResult[type] && Array.isArray(transformedResult[type])) { - transformedResult[type] = transformedResult[type].map(function(typeResult) { - return _extends({}, typeResult, { - node: typeResult.node.toJSON() - }); - }); - } - } - return transformedResult; - }); - callback(transformedResults); + callback(results); }); 'use strict'; - function _extends() { - _extends = Object.assign || function(target) { - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i]; - for (var key in source) { - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - return target; - }; - return _extends.apply(this, arguments); - } axe.addReporter('v1', function(results, options, callback) { 'use strict'; if (typeof options === 'function') { @@ -4501,29 +1300,16 @@ nodeResult.failureSummary = helpers.failureSummary(nodeResult); }); }); - callback(_extends({}, helpers.getEnvironmentData(), { - toolOptions: options, + callback({ violations: out.violations, passes: out.passes, incomplete: out.incomplete, - inapplicable: out.inapplicable - })); + inapplicable: out.inapplicable, + timestamp: out.timestamp, + url: out.url + }); }); 'use strict'; - function _extends() { - _extends = Object.assign || function(target) { - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i]; - for (var key in source) { - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - return target; - }; - return _extends.apply(this, arguments); - } axe.addReporter('v2', function(results, options, callback) { 'use strict'; if (typeof options === 'function') { @@ -4531,13 +1317,14 @@ options = {}; } var out = helpers.processAggregate(results, options); - callback(_extends({}, helpers.getEnvironmentData(), { - toolOptions: options, + callback({ violations: out.violations, passes: out.passes, incomplete: out.incomplete, - inapplicable: out.inapplicable - })); + inapplicable: out.inapplicable, + timestamp: out.timestamp, + url: out.url + }); }, true); 'use strict'; axe.utils.aggregate = function(map, values, initial) { @@ -4551,7 +1338,6 @@ return map[sorting.pop()]; }; 'use strict'; - var _axe$constants = axe.constants, CANTTELL_PRIO = _axe$constants.CANTTELL_PRIO, FAIL_PRIO = _axe$constants.FAIL_PRIO; var checkMap = []; checkMap[axe.constants.PASS_PRIO] = true; checkMap[axe.constants.CANTTELL_PRIO] = null; @@ -4568,38 +1354,32 @@ axe.utils.aggregateChecks = function(nodeResOriginal) { var nodeResult = Object.assign({}, nodeResOriginal); anyAllNone(nodeResult, function(check, type) { - var i = typeof check.result === 'undefined' ? -1 : checkMap.indexOf(check.result); + var i = checkMap.indexOf(check.result); check.priority = i !== -1 ? i : axe.constants.CANTTELL_PRIO; if (type === 'none') { - if (check.priority === axe.constants.PASS_PRIO) { - check.priority = axe.constants.FAIL_PRIO; - } else if (check.priority === axe.constants.FAIL_PRIO) { - check.priority = axe.constants.PASS_PRIO; - } + check.priority = 4 - check.priority; } }); - var priorities = { - all: nodeResult.all.reduce(function(a, b) { - return Math.max(a, b.priority); - }, 0), - none: nodeResult.none.reduce(function(a, b) { - return Math.max(a, b.priority); - }, 0), - any: nodeResult.any.reduce(function(a, b) { - return Math.min(a, b.priority); - }, 4) % 4 - }; - nodeResult.priority = Math.max(priorities.all, priorities.none, priorities.any); + var priorities = anyAllNone(nodeResult, function(c) { + return c.priority; + }); + nodeResult.priority = Math.max(priorities.all.reduce(function(a, b) { + return Math.max(a, b); + }, 0), priorities.none.reduce(function(a, b) { + return Math.max(a, b); + }, 0), priorities.any.reduce(function(a, b) { + return Math.min(a, b); + }, 4) % 4); var impacts = []; checkTypes.forEach(function(type) { nodeResult[type] = nodeResult[type].filter(function(check) { - return check.priority === nodeResult.priority && check.priority === priorities[type]; + return check.priority === nodeResult.priority; }); nodeResult[type].forEach(function(check) { return impacts.push(check.impact); }); }); - if ([ CANTTELL_PRIO, FAIL_PRIO ].includes(nodeResult.priority)) { + if (nodeResult.priority === axe.constants.FAIL_PRIO) { nodeResult.impact = axe.utils.aggregate(axe.constants.impact, impacts); } else { nodeResult.impact = null; @@ -4613,49 +1393,6 @@ return nodeResult; }; 'use strict'; - (function() { - axe.utils.aggregateNodeResults = function(nodeResults) { - var ruleResult = {}; - nodeResults = nodeResults.map(function(nodeResult) { - if (nodeResult.any && nodeResult.all && nodeResult.none) { - return axe.utils.aggregateChecks(nodeResult); - } else if (Array.isArray(nodeResult.node)) { - return axe.utils.finalizeRuleResult(nodeResult); - } else { - throw new TypeError('Invalid Result type'); - } - }); - if (nodeResults && nodeResults.length) { - var resultList = nodeResults.map(function(node) { - return node.result; - }); - ruleResult.result = axe.utils.aggregate(axe.constants.results, resultList, ruleResult.result); - } else { - ruleResult.result = 'inapplicable'; - } - axe.constants.resultGroups.forEach(function(group) { - return ruleResult[group] = []; - }); - nodeResults.forEach(function(nodeResult) { - var groupName = axe.constants.resultGroupMap[nodeResult.result]; - ruleResult[groupName].push(nodeResult); - }); - var impactGroup = axe.constants.FAIL_GROUP; - if (ruleResult[impactGroup].length === 0) { - impactGroup = axe.constants.CANTTELL_GROUP; - } - if (ruleResult[impactGroup].length > 0) { - var impactList = ruleResult[impactGroup].map(function(failure) { - return failure.impact; - }); - ruleResult.impact = axe.utils.aggregate(axe.constants.impact, impactList) || null; - } else { - ruleResult.impact = null; - } - return ruleResult; - }; - })(); - 'use strict'; function copyToGroup(resultObject, subResult, group) { var resultCopy = Object.assign({}, subResult); resultCopy.nodes = (resultCopy[group] || []).concat(); @@ -4685,6 +1422,42 @@ return resultObject; }; 'use strict'; + (function() { + axe.utils.aggregateRule = function(subResults) { + var ruleResult = {}; + subResults = subResults.map(function(subResult) { + if (subResult.any && subResult.all && subResult.none) { + return axe.utils.aggregateChecks(subResult); + } else if (Array.isArray(subResult.node)) { + return axe.utils.finalizeRuleResult(subResult); + } else { + throw new TypeError('Invalid Result type'); + } + }); + var resultList = subResults.map(function(node) { + return node.result; + }); + ruleResult.result = axe.utils.aggregate(axe.constants.results, resultList, ruleResult.result); + axe.constants.resultGroups.forEach(function(group) { + return ruleResult[group] = []; + }); + subResults.forEach(function(subResult) { + var groupName = axe.constants.resultGroupMap[subResult.result]; + ruleResult[groupName].push(subResult); + }); + var failGroup = axe.constants.FAIL_GROUP; + if (ruleResult[failGroup].length > 0) { + var impactList = ruleResult[failGroup].map(function(failure) { + return failure.impact; + }); + ruleResult.impact = axe.utils.aggregate(axe.constants.impact, impactList) || null; + } else { + ruleResult.impact = null; + } + return ruleResult; + }; + })(); + 'use strict'; function areStylesSet(el, styles, stopAt) { 'use strict'; var styl = window.getComputedStyle(el, null); @@ -4715,7 +1488,7 @@ this.isAsync = true; return function(result) { if (result instanceof Error === false) { - checkResult.result = result; + checkResult.value = result; resolve(checkResult); } else { reject(result); @@ -4734,22 +1507,15 @@ }; }; 'use strict'; - function _typeof(obj) { - if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') { - _typeof = function _typeof(obj) { - return typeof obj; - }; - } else { - _typeof = function _typeof(obj) { - return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj; - }; - } - return _typeof(obj); - } + var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) { + return typeof obj; + } : function(obj) { + return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj; + }; axe.utils.clone = function(obj) { 'use strict'; var index, length, out = obj; - if (obj !== null && _typeof(obj) === 'object') { + if (obj !== null && (typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object') { if (Array.isArray(obj)) { out = []; for (index = 0, length = obj.length; index < length; index++) { @@ -4767,11 +1533,7 @@ 'use strict'; function err(message, node) { 'use strict'; - var selector; - if (axe._tree) { - selector = axe.utils.getSelector(node); - } - return new Error(message + ': ' + (selector || node)); + return new Error(message + ': ' + axe.utils.getSelector(node)); } axe.utils.sendCommandToFrame = function(node, parameters, resolve, reject) { 'use strict'; @@ -4783,19 +1545,20 @@ } var timeout = setTimeout(function() { timeout = setTimeout(function() { + var errMsg = err('No response from frame', node); if (!parameters.debug) { + axe.log(errMsg); resolve(null); } else { - reject(err('No response from frame', node)); + reject(errMsg); } }, 0); }, 500); axe.utils.respondable(win, 'axe.ping', null, undefined, function() { clearTimeout(timeout); - var frameWaitTime = parameters.options && parameters.options.frameWaitTime || 6e4; timeout = setTimeout(function() { reject(err('Axe in frame timed out', node)); - }, frameWaitTime); + }, 3e4); axe.utils.respondable(win, 'axe.start', parameters, undefined, function(data) { clearTimeout(timeout); if (data instanceof Error === false) { @@ -4838,43 +1601,611 @@ }); q.then(function(data) { resolve(axe.utils.mergeResults(data, options)); - })['catch'](reject); + }).catch(reject); } axe.utils.collectResultsFromFrames = collectResultsFromFrames; 'use strict'; - axe.utils.contains = function(vNode, otherVNode) { + axe.utils.contains = function(node, otherNode) { 'use strict'; - function containsShadowChild(vNode, otherVNode) { - if (vNode.shadowId === otherVNode.shadowId) { + function containsShadowChild(node, otherNode) { + if (node.shadowId === otherNode.shadowId) { return true; } - return !!vNode.children.find(function(child) { - return containsShadowChild(child, otherVNode); + return !!node.children.find(function(child) { + return containsShadowChild(child, otherNode); }); } - if (vNode.shadowId || otherVNode.shadowId) { - return containsShadowChild(vNode, otherVNode); + if (node.shadowId || otherNode.shadowId) { + return containsShadowChild(node, otherNode); } - if (vNode.actualNode) { - if (typeof vNode.actualNode.contains === 'function') { - return vNode.actualNode.contains(otherVNode.actualNode); - } - return !!(vNode.actualNode.compareDocumentPosition(otherVNode.actualNode) & 16); - } else { - do { - if (otherVNode === vNode) { - return true; - } - } while (otherVNode = otherVNode && otherVNode.parent); + if (typeof node.actualNode.contains === 'function') { + return node.actualNode.contains(otherNode.actualNode); } - return false; + return !!(node.actualNode.compareDocumentPosition(otherNode.actualNode) & 16); }; 'use strict'; (function(axe) { - var parser = new axe.imports.CssSelectorParser(); - parser.registerSelectorPseudos('not'); + /*! + * The copyright below covers the code within this function block only + * + * Copyright (c) 2013 Dulin Marat + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + function CssSelectorParser() { + this.pseudos = {}; + this.attrEqualityMods = {}; + this.ruleNestingOperators = {}; + this.substitutesEnabled = false; + } + CssSelectorParser.prototype.registerSelectorPseudos = function(name) { + for (var j = 0, len = arguments.length; j < len; j++) { + name = arguments[j]; + this.pseudos[name] = 'selector'; + } + return this; + }; + CssSelectorParser.prototype.unregisterSelectorPseudos = function(name) { + for (var j = 0, len = arguments.length; j < len; j++) { + name = arguments[j]; + delete this.pseudos[name]; + } + return this; + }; + CssSelectorParser.prototype.registerNumericPseudos = function(name) { + for (var j = 0, len = arguments.length; j < len; j++) { + name = arguments[j]; + this.pseudos[name] = 'numeric'; + } + return this; + }; + CssSelectorParser.prototype.unregisterNumericPseudos = function(name) { + for (var j = 0, len = arguments.length; j < len; j++) { + name = arguments[j]; + delete this.pseudos[name]; + } + return this; + }; + CssSelectorParser.prototype.registerNestingOperators = function(operator) { + for (var j = 0, len = arguments.length; j < len; j++) { + operator = arguments[j]; + this.ruleNestingOperators[operator] = true; + } + return this; + }; + CssSelectorParser.prototype.unregisterNestingOperators = function(operator) { + for (var j = 0, len = arguments.length; j < len; j++) { + operator = arguments[j]; + delete this.ruleNestingOperators[operator]; + } + return this; + }; + CssSelectorParser.prototype.registerAttrEqualityMods = function(mod) { + for (var j = 0, len = arguments.length; j < len; j++) { + mod = arguments[j]; + this.attrEqualityMods[mod] = true; + } + return this; + }; + CssSelectorParser.prototype.unregisterAttrEqualityMods = function(mod) { + for (var j = 0, len = arguments.length; j < len; j++) { + mod = arguments[j]; + delete this.attrEqualityMods[mod]; + } + return this; + }; + CssSelectorParser.prototype.enableSubstitutes = function() { + this.substitutesEnabled = true; + return this; + }; + CssSelectorParser.prototype.disableSubstitutes = function() { + this.substitutesEnabled = false; + return this; + }; + function isIdentStart(c) { + return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c === '-' || c === '_'; + } + function isIdent(c) { + return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' || c === '-' || c === '_'; + } + function isHex(c) { + return c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F' || c >= '0' && c <= '9'; + } + function isDecimal(c) { + return c >= '0' && c <= '9'; + } + function isAttrMatchOperator(chr) { + return chr === '=' || chr === '^' || chr === '$' || chr === '*' || chr === '~'; + } + var identSpecialChars = { + '!': true, + '"': true, + '#': true, + $: true, + '%': true, + '&': true, + '\'': true, + '(': true, + ')': true, + '*': true, + '+': true, + ',': true, + '.': true, + '/': true, + ';': true, + '<': true, + '=': true, + '>': true, + '?': true, + '@': true, + '[': true, + '\\': true, + ']': true, + '^': true, + '`': true, + '{': true, + '|': true, + '}': true, + '~': true + }; + var strReplacementsRev = { + '\n': '\\n', + '\r': '\\r', + '\t': '\\t', + '\f': '\\f', + '\v': '\\v' + }; + var singleQuoteEscapeChars = { + n: '\n', + r: '\r', + t: '\t', + f: '\f', + '\\': '\\', + '\'': '\'' + }; + var doubleQuotesEscapeChars = { + n: '\n', + r: '\r', + t: '\t', + f: '\f', + '\\': '\\', + '"': '"' + }; + function ParseContext(str, pos, pseudos, attrEqualityMods, ruleNestingOperators, substitutesEnabled) { + var chr, getIdent, getStr, l, skipWhitespace; + l = str.length; + chr = null; + getStr = function getStr(quote, escapeTable) { + var esc, hex, result; + result = ''; + pos++; + chr = str.charAt(pos); + while (pos < l) { + if (chr === quote) { + pos++; + return result; + } else if (chr === '\\') { + pos++; + chr = str.charAt(pos); + if (chr === quote) { + result += quote; + } else if (esc = escapeTable[chr]) { + result += esc; + } else if (isHex(chr)) { + hex = chr; + pos++; + chr = str.charAt(pos); + while (isHex(chr)) { + hex += chr; + pos++; + chr = str.charAt(pos); + } + if (chr === ' ') { + pos++; + chr = str.charAt(pos); + } + result += String.fromCharCode(parseInt(hex, 16)); + continue; + } else { + result += chr; + } + } else { + result += chr; + } + pos++; + chr = str.charAt(pos); + } + return result; + }; + getIdent = function getIdent() { + var result = ''; + chr = str.charAt(pos); + while (pos < l) { + if (isIdent(chr)) { + result += chr; + } else if (chr === '\\') { + pos++; + if (pos >= l) { + throw Error('Expected symbol but end of file reached.'); + } + chr = str.charAt(pos); + if (identSpecialChars[chr]) { + result += chr; + } else if (isHex(chr)) { + var hex = chr; + pos++; + chr = str.charAt(pos); + while (isHex(chr)) { + hex += chr; + pos++; + chr = str.charAt(pos); + } + if (chr === ' ') { + pos++; + chr = str.charAt(pos); + } + result += String.fromCharCode(parseInt(hex, 16)); + continue; + } else { + result += chr; + } + } else { + return result; + } + pos++; + chr = str.charAt(pos); + } + return result; + }; + skipWhitespace = function skipWhitespace() { + chr = str.charAt(pos); + var result = false; + while (chr === ' ' || chr === '\t' || chr === '\n' || chr === '\r' || chr === '\f') { + result = true; + pos++; + chr = str.charAt(pos); + } + return result; + }; + this.parse = function() { + var res = this.parseSelector(); + if (pos < l) { + throw Error('Rule expected but "' + str.charAt(pos) + '" found.'); + } + return res; + }; + this.parseSelector = function() { + var res; + var selector = res = this.parseSingleSelector(); + chr = str.charAt(pos); + while (chr === ',') { + pos++; + skipWhitespace(); + if (res.type !== 'selectors') { + res = { + type: 'selectors', + selectors: [ selector ] + }; + } + selector = this.parseSingleSelector(); + if (!selector) { + throw Error('Rule expected after ",".'); + } + res.selectors.push(selector); + } + return res; + }; + this.parseSingleSelector = function() { + skipWhitespace(); + var selector = { + type: 'ruleSet' + }; + var rule = this.parseRule(); + if (!rule) { + return null; + } + var currentRule = selector; + while (rule) { + rule.type = 'rule'; + currentRule.rule = rule; + currentRule = rule; + skipWhitespace(); + chr = str.charAt(pos); + if (pos >= l || chr === ',' || chr === ')') { + break; + } + if (ruleNestingOperators[chr]) { + var op = chr; + pos++; + skipWhitespace(); + rule = this.parseRule(); + if (!rule) { + throw Error('Rule expected after "' + op + '".'); + } + rule.nestingOperator = op; + } else { + rule = this.parseRule(); + if (rule) { + rule.nestingOperator = null; + } + } + } + return selector; + }; + this.parseRule = function() { + var rule = null; + while (pos < l) { + chr = str.charAt(pos); + if (chr === '*') { + pos++; + (rule = rule || {}).tagName = '*'; + } else if (isIdentStart(chr) || chr === '\\') { + (rule = rule || {}).tagName = getIdent(); + } else if (chr === '.') { + pos++; + rule = rule || {}; + (rule.classNames = rule.classNames || []).push(getIdent()); + } else if (chr === '#') { + pos++; + (rule = rule || {}).id = getIdent(); + } else if (chr === '[') { + pos++; + skipWhitespace(); + var attr = { + name: getIdent() + }; + skipWhitespace(); + if (chr === ']') { + pos++; + } else { + var operator = ''; + if (attrEqualityMods[chr]) { + operator = chr; + pos++; + chr = str.charAt(pos); + } + if (pos >= l) { + throw Error('Expected "=" but end of file reached.'); + } + if (chr !== '=') { + throw Error('Expected "=" but "' + chr + '" found.'); + } + attr.operator = operator + '='; + pos++; + skipWhitespace(); + var attrValue = ''; + attr.valueType = 'string'; + if (chr === '"') { + attrValue = getStr('"', doubleQuotesEscapeChars); + } else if (chr === '\'') { + attrValue = getStr('\'', singleQuoteEscapeChars); + } else if (substitutesEnabled && chr === '$') { + pos++; + attrValue = getIdent(); + attr.valueType = 'substitute'; + } else { + while (pos < l) { + if (chr === ']') { + break; + } + attrValue += chr; + pos++; + chr = str.charAt(pos); + } + attrValue = attrValue.trim(); + } + skipWhitespace(); + if (pos >= l) { + throw Error('Expected "]" but end of file reached.'); + } + if (chr !== ']') { + throw Error('Expected "]" but "' + chr + '" found.'); + } + pos++; + attr.value = attrValue; + } + rule = rule || {}; + (rule.attrs = rule.attrs || []).push(attr); + } else if (chr === ':') { + pos++; + var pseudoName = getIdent(); + var pseudo = { + name: pseudoName + }; + if (chr === '(') { + pos++; + var value = ''; + skipWhitespace(); + if (pseudos[pseudoName] === 'selector') { + pseudo.valueType = 'selector'; + value = this.parseSelector(); + } else { + pseudo.valueType = pseudos[pseudoName] || 'string'; + if (chr === '"') { + value = getStr('"', doubleQuotesEscapeChars); + } else if (chr === '\'') { + value = getStr('\'', singleQuoteEscapeChars); + } else if (substitutesEnabled && chr === '$') { + pos++; + value = getIdent(); + pseudo.valueType = 'substitute'; + } else { + while (pos < l) { + if (chr === ')') { + break; + } + value += chr; + pos++; + chr = str.charAt(pos); + } + value = value.trim(); + } + skipWhitespace(); + } + if (pos >= l) { + throw Error('Expected ")" but end of file reached.'); + } + if (chr !== ')') { + throw Error('Expected ")" but "' + chr + '" found.'); + } + pos++; + pseudo.value = value; + } + rule = rule || {}; + (rule.pseudos = rule.pseudos || []).push(pseudo); + } else { + break; + } + } + return rule; + }; + return this; + } + CssSelectorParser.prototype.parse = function(str) { + var context = new ParseContext(str, 0, this.pseudos, this.attrEqualityMods, this.ruleNestingOperators, this.substitutesEnabled); + return context.parse(); + }; + CssSelectorParser.prototype.escapeIdentifier = function(s) { + var result = ''; + var i = 0; + var len = s.length; + while (i < len) { + var chr = s.charAt(i); + if (identSpecialChars[chr]) { + result += '\\' + chr; + } else { + if (!(chr === '_' || chr === '-' || chr >= 'A' && chr <= 'Z' || chr >= 'a' && chr <= 'z' || i !== 0 && chr >= '0' && chr <= '9')) { + var charCode = chr.charCodeAt(0); + if ((charCode & 63488) === 55296) { + var extraCharCode = s.charCodeAt(i++); + if ((charCode & 64512) !== 55296 || (extraCharCode & 64512) !== 56320) { + throw Error('UCS-2(decode): illegal sequence'); + } + charCode = ((charCode & 1023) << 10) + (extraCharCode & 1023) + 65536; + } + result += '\\' + charCode.toString(16) + ' '; + } else { + result += chr; + } + } + i++; + } + return result; + }; + CssSelectorParser.prototype.escapeStr = function(s) { + var result = ''; + var i = 0; + var len = s.length; + var chr, replacement; + while (i < len) { + chr = s.charAt(i); + if (chr === '"') { + chr = '\\"'; + } else if (chr === '\\') { + chr = '\\\\'; + } else if (replacement = strReplacementsRev[chr]) { + chr = replacement; + } + result += chr; + i++; + } + return '"' + result + '"'; + }; + CssSelectorParser.prototype.render = function(path) { + return this._renderEntity(path).trim(); + }; + CssSelectorParser.prototype._renderEntity = function(entity) { + var currentEntity, parts, res; + res = ''; + switch (entity.type) { + case 'ruleSet': + currentEntity = entity.rule; + parts = []; + while (currentEntity) { + if (currentEntity.nestingOperator) { + parts.push(currentEntity.nestingOperator); + } + parts.push(this._renderEntity(currentEntity)); + currentEntity = currentEntity.rule; + } + res = parts.join(' '); + break; + + case 'selectors': + res = entity.selectors.map(this._renderEntity, this).join(', '); + break; + + case 'rule': + if (entity.tagName) { + if (entity.tagName === '*') { + res = '*'; + } else { + res = this.escapeIdentifier(entity.tagName); + } + } + if (entity.id) { + res += '#' + this.escapeIdentifier(entity.id); + } + if (entity.classNames) { + res += entity.classNames.map(function(cn) { + return '.' + this.escapeIdentifier(cn); + }, this).join(''); + } + if (entity.attrs) { + res += entity.attrs.map(function(attr) { + if (attr.operator) { + if (attr.valueType === 'substitute') { + return '[' + this.escapeIdentifier(attr.name) + attr.operator + '$' + attr.value + ']'; + } else { + return '[' + this.escapeIdentifier(attr.name) + attr.operator + this.escapeStr(attr.value) + ']'; + } + } else { + return '[' + this.escapeIdentifier(attr.name) + ']'; + } + }, this).join(''); + } + if (entity.pseudos) { + res += entity.pseudos.map(function(pseudo) { + if (pseudo.valueType) { + if (pseudo.valueType === 'selector') { + return ':' + this.escapeIdentifier(pseudo.name) + '(' + this._renderEntity(pseudo.value) + ')'; + } else if (pseudo.valueType === 'substitute') { + return ':' + this.escapeIdentifier(pseudo.name) + '($' + pseudo.value + ')'; + } else if (pseudo.valueType === 'numeric') { + return ':' + this.escapeIdentifier(pseudo.name) + '(' + pseudo.value + ')'; + } else { + return ':' + this.escapeIdentifier(pseudo.name) + '(' + this.escapeIdentifier(pseudo.value) + ')'; + } + } else { + return ':' + this.escapeIdentifier(pseudo.name); + } + }, this).join(''); + } + break; + + default: + throw Error('Unknown entity type: "' + entity.type(+'".')); + } + return res; + }; + var parser = new CssSelectorParser(); parser.registerNestingOperators('>'); - parser.registerAttrEqualityMods('^', '$', '*'); axe.utils.cssParser = parser; })(axe); 'use strict'; @@ -4936,23 +2267,20 @@ axe.utils.matchesSelector = function() { 'use strict'; var method; - function getMethod(node) { - var index, candidate, candidates = [ 'matches', 'matchesSelector', 'mozMatchesSelector', 'webkitMatchesSelector', 'msMatchesSelector' ], length = candidates.length; + function getMethod(win) { + var index, candidate, elProto = win.Element.prototype, candidates = [ 'matches', 'matchesSelector', 'mozMatchesSelector', 'webkitMatchesSelector', 'msMatchesSelector' ], length = candidates.length; for (index = 0; index < length; index++) { candidate = candidates[index]; - if (node[candidate]) { + if (elProto[candidate]) { return candidate; } } } return function(node, selector) { if (!method || !node[method]) { - method = getMethod(node); + method = getMethod(node.ownerDocument.defaultView); } - if (node[method]) { - return node[method](selector); - } - return false; + return node[method](selector); }; }(); 'use strict'; @@ -4967,14 +2295,13 @@ while (++index < length) { codeUnit = string.charCodeAt(index); if (codeUnit == 0) { - result += '�'; - continue; + throw new Error('INVALID_CHARACTER_ERR'); } - if (codeUnit >= 1 && codeUnit <= 31 || codeUnit == 127 || index == 0 && codeUnit >= 48 && codeUnit <= 57 || index == 1 && codeUnit >= 48 && codeUnit <= 57 && firstCodeUnit == 45) { + if (codeUnit >= 1 && codeUnit <= 31 || codeUnit >= 127 && codeUnit <= 159 || index == 0 && codeUnit >= 48 && codeUnit <= 57 || index == 1 && codeUnit >= 48 && codeUnit <= 57 && firstCodeUnit == 45) { result += '\\' + codeUnit.toString(16) + ' '; continue; } - if (index == 0 && length == 1 && codeUnit == 45) { + if (index == 1 && codeUnit == 45 && firstCodeUnit == 45) { result += '\\' + string.charAt(index); continue; } @@ -5000,27 +2327,20 @@ }; 'use strict'; axe.utils.finalizeRuleResult = function(ruleResult) { - Object.assign(ruleResult, axe.utils.aggregateNodeResults(ruleResult.nodes)); + Object.assign(ruleResult, axe.utils.aggregateRule(ruleResult.nodes)); delete ruleResult.nodes; return ruleResult; }; 'use strict'; - function _typeof(obj) { - if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') { - _typeof = function _typeof(obj) { - return typeof obj; - }; - } else { - _typeof = function _typeof(obj) { - return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj; - }; - } - return _typeof(obj); - } + var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) { + return typeof obj; + } : function(obj) { + return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj; + }; axe.utils.findBy = function(array, key, value) { if (Array.isArray(array)) { return array.find(function(obj) { - return _typeof(obj) === 'object' && obj[key] === value; + return (typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object' && obj[key] === value; }); } }; @@ -5028,6 +2348,13 @@ var axe = axe || { utils: {} }; + function virtualDOMfromNode(node, shadowId) { + return { + shadowId: shadowId, + children: [], + actualNode: node + }; + } function getSlotChildren(node) { var retVal = []; node = node.firstChild; @@ -5037,10 +2364,10 @@ } return retVal; } - function flattenTree(node, shadowId, parent) { + axe.utils.getFlattenedTree = function(node, shadowId) { var retVal, realArray, nodeName; - function reduceShadowDOM(res, child, parent) { - var replacements = flattenTree(child, shadowId, parent); + function reduceShadowDOM(res, child) { + var replacements = axe.utils.getFlattenedTree(child, shadowId); if (replacements) { res = res.concat(replacements); } @@ -5050,59 +2377,59 @@ node = node.documentElement; } nodeName = node.nodeName.toLowerCase(); - if (axe.utils.isShadowRoot(node)) { - retVal = new VirtualNode(node, parent, shadowId); + if (node.shadowRoot && nodeName !== 'marquee') { + retVal = virtualDOMfromNode(node, shadowId); shadowId = 'a' + Math.random().toString().substring(2); realArray = Array.from(node.shadowRoot.childNodes); - retVal.children = realArray.reduce(function(res, child) { - return reduceShadowDOM(res, child, retVal); - }, []); + retVal.children = realArray.reduce(reduceShadowDOM, []); return [ retVal ]; } else { - if (nodeName === 'content' && typeof node.getDistributedNodes === 'function') { + if (nodeName === 'content') { realArray = Array.from(node.getDistributedNodes()); - return realArray.reduce(function(res, child) { - return reduceShadowDOM(res, child, parent); - }, []); - } else if (nodeName === 'slot' && typeof node.assignedNodes === 'function') { + return realArray.reduce(reduceShadowDOM, []); + } else if (nodeName === 'slot') { realArray = Array.from(node.assignedNodes()); if (!realArray.length) { realArray = getSlotChildren(node); } var styl = window.getComputedStyle(node); if (false && styl.display !== 'contents') { - retVal = new VirtualNode(node, parent, shadowId); - retVal.children = realArray.reduce(function(res, child) { - return reduceShadowDOM(res, child, retVal); - }, []); + retVal = virtualDOMfromNode(node, shadowId); + retVal.children = realArray.reduce(reduceShadowDOM, []); return [ retVal ]; } else { - return realArray.reduce(function(res, child) { - return reduceShadowDOM(res, child, parent); - }, []); + return realArray.reduce(reduceShadowDOM, []); } } else { if (node.nodeType === 1) { - retVal = new VirtualNode(node, parent, shadowId); + retVal = virtualDOMfromNode(node, shadowId); realArray = Array.from(node.childNodes); - retVal.children = realArray.reduce(function(res, child) { - return reduceShadowDOM(res, child, retVal); - }, []); + retVal.children = realArray.reduce(reduceShadowDOM, []); return [ retVal ]; } else if (node.nodeType === 3) { - return [ new VirtualNode(node, parent) ]; + return [ virtualDOMfromNode(node) ]; } return undefined; } } - } - axe.utils.getFlattenedTree = function(node, shadowId) { - axe._cache.set('nodeMap', new WeakMap()); - return flattenTree(node, shadowId); }; axe.utils.getNodeFromTree = function(vNode, node) { - var el = node || vNode; - return axe._cache.get('nodeMap') ? axe._cache.get('nodeMap').get(el) : null; + var found; + if (vNode.actualNode === node) { + return vNode; + } + vNode.children.forEach(function(candidate) { + var retVal; + if (candidate.actualNode === node) { + found = candidate; + } else { + retVal = axe.utils.getNodeFromTree(candidate, node); + if (retVal) { + found = retVal; + } + } + }); + return found; }; 'use strict'; axe.utils.getAllChecks = function getAllChecks(object) { @@ -5111,13 +2438,6 @@ return result.concat(object.any || []).concat(object.all || []).concat(object.none || []); }; 'use strict'; - axe.utils.getBaseLang = function getBaseLang(lang) { - if (!lang) { - return ''; - } - return lang.trim().split('-')[0].toLowerCase(); - }; - 'use strict'; axe.utils.getCheckOption = function(check, ruleID, options) { var ruleCheckOption = ((options.rules && options.rules[ruleID] || {}).checks || {})[check.id]; var checkOption = (options.checks || {})[check.id]; @@ -5146,45 +2466,45 @@ }; }; 'use strict'; - function _slicedToArray(arr, i) { - return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); - } - function _nonIterableRest() { - throw new TypeError('Invalid attempt to destructure non-iterable instance'); - } - function _iterableToArrayLimit(arr, i) { - var _arr = []; - var _n = true; - var _d = false; - var _e = undefined; - try { - for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { - _arr.push(_s.value); - if (i && _arr.length === i) { - break; - } - } - } catch (err) { - _d = true; - _e = err; - } finally { + var _slicedToArray = function() { + function sliceIterator(arr, i) { + var _arr = []; + var _n = true; + var _d = false; + var _e = undefined; try { - if (!_n && _i['return'] != null) { - _i['return'](); + for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { + _arr.push(_s.value); + if (i && _arr.length === i) { + break; + } } + } catch (err) { + _d = true; + _e = err; } finally { - if (_d) { - throw _e; + try { + if (!_n && _i['return']) { + _i['return'](); + } + } finally { + if (_d) { + throw _e; + } } } + return _arr; } - return _arr; - } - function _arrayWithHoles(arr) { - if (Array.isArray(arr)) { - return arr; - } - } + return function(arr, i) { + if (Array.isArray(arr)) { + return arr; + } else if (Symbol.iterator in Object(arr)) { + return sliceIterator(arr, i); + } else { + throw new TypeError('Invalid attempt to destructure non-iterable instance'); + } + }; + }(); function isMostlyNumbers() { var str = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; return str.length !== 0 && (str.match(/[0-9]/g) || '').length >= str.length / 2; @@ -5192,9 +2512,6 @@ function splitString(str, splitIndex) { return [ str.substring(0, splitIndex), str.substring(splitIndex) ]; } - function trimRight(str) { - return str.replace(/\s+$/, ''); - } function uriParser(url) { var original = url; var protocol = '', domain = '', port = '', path = '', query = '', hash = ''; @@ -5252,168 +2569,61 @@ if (uri.length <= 1 || uri.substr(0, 5) === 'data:' || uri.substr(0, 11) === 'javascript:' || uri.includes('?')) { return; } - var currentDomain = options.currentDomain, _options$maxLength = options.maxLength, maxLength = _options$maxLength === void 0 ? 25 : _options$maxLength; + var currentDomain = options.currentDomain, _options$maxLength = options.maxLength, maxLength = _options$maxLength === undefined ? 25 : _options$maxLength; var _uriParser = uriParser(uri), path = _uriParser.path, domain = _uriParser.domain, hash = _uriParser.hash; var pathEnd = path.substr(path.substr(0, path.length - 2).lastIndexOf('/') + 1); if (hash) { if (pathEnd && (pathEnd + hash).length <= maxLength) { - return trimRight(pathEnd + hash); + return pathEnd + hash; } else if (pathEnd.length < 2 && hash.length > 2 && hash.length <= maxLength) { - return trimRight(hash); + return hash; } else { return; } } else if (domain && domain.length < maxLength && path.length <= 1) { - return trimRight(domain + path); + return domain + path; } if (path === '/' + pathEnd && domain && currentDomain && domain !== currentDomain && (domain + path).length <= maxLength) { - return trimRight(domain + path); + return domain + path; } var lastDotIndex = pathEnd.lastIndexOf('.'); if ((lastDotIndex === -1 || lastDotIndex > 1) && (lastDotIndex !== -1 || pathEnd.length > 2) && pathEnd.length <= maxLength && !pathEnd.match(/index(\.[a-zA-Z]{2-4})?/) && !isMostlyNumbers(pathEnd)) { - return trimRight(pathEnd); + return pathEnd; } }; 'use strict'; - axe.utils.getNodeAttributes = function getNodeAttributes(node) { - if (node.attributes instanceof window.NamedNodeMap) { - return node.attributes; - } - return node.cloneNode(false).attributes; - }; - 'use strict'; - axe.utils.getRootNode = function getRootNode(node) { - var doc = node.getRootNode && node.getRootNode() || document; - if (doc === node) { - doc = document; - } - return doc; - }; - 'use strict'; - axe.utils.getScroll = function getScroll(elm) { - var buffer = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; - var overflowX = elm.scrollWidth > elm.clientWidth + buffer; - var overflowY = elm.scrollHeight > elm.clientHeight + buffer; - if (!(overflowX || overflowY)) { - return; - } - var style = window.getComputedStyle(elm); - var overflowXStyle = style.getPropertyValue('overflow-x'); - var overflowYStyle = style.getPropertyValue('overflow-y'); - var scrollableX = overflowXStyle !== 'visible' && overflowXStyle !== 'hidden'; - var scrollableY = overflowYStyle !== 'visible' && overflowYStyle !== 'hidden'; - if (overflowX && scrollableX || overflowY && scrollableY) { - return { - elm: elm, - top: elm.scrollTop, - left: elm.scrollLeft - }; - } - }; - 'use strict'; - var escapeSelector = axe.utils.escapeSelector; - var isXHTML; - var ignoredAttributes = [ 'class', 'style', 'id', 'selected', 'checked', 'disabled', 'tabindex', 'aria-checked', 'aria-selected', 'aria-invalid', 'aria-activedescendant', 'aria-busy', 'aria-disabled', 'aria-expanded', 'aria-grabbed', 'aria-pressed', 'aria-valuenow' ]; - var MAXATTRIBUTELENGTH = 31; - function getAttributeNameValue(node, at) { - var name = at.name; - var atnv; - if (name.indexOf('href') !== -1 || name.indexOf('src') !== -1) { - var friendly = axe.utils.getFriendlyUriEnd(node.getAttribute(name)); - if (friendly) { - var value = encodeURI(friendly); - if (value) { - atnv = escapeSelector(at.name) + '$="' + escapeSelector(value) + '"'; - } else { - return; - } - } else { - atnv = escapeSelector(at.name) + '="' + escapeSelector(node.getAttribute(name)) + '"'; + function _toConsumableArray(arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { + arr2[i] = arr[i]; } + return arr2; } else { - atnv = escapeSelector(name) + '="' + escapeSelector(at.value) + '"'; + return Array.from(arr); } - return atnv; } - function countSort(a, b) { - return a.count < b.count ? -1 : a.count === b.count ? 0 : 1; + var escapeSelector = axe.utils.escapeSelector; + function isUncommonClassName(className) { + return ![ 'focus', 'hover', 'hidden', 'visible', 'dirty', 'touched', 'valid', 'disable', 'enable', 'active', 'col-' ].find(function(str) { + return className.includes(str); + }); } - function filterAttributes(at) { - return !ignoredAttributes.includes(at.name) && at.name.indexOf(':') === -1 && (!at.value || at.value.length < MAXATTRIBUTELENGTH); - } - axe.utils.getSelectorData = function(domTree) { - var data = { - classes: {}, - tags: {}, - attributes: {} - }; - domTree = Array.isArray(domTree) ? domTree : [ domTree ]; - var currentLevel = domTree.slice(); - var stack = []; - var _loop = function _loop() { - var current = currentLevel.pop(); - var node = current.actualNode; - if (!!node.querySelectorAll) { - var tag = node.nodeName; - if (data.tags[tag]) { - data.tags[tag]++; - } else { - data.tags[tag] = 1; - } - if (node.classList) { - Array.from(node.classList).forEach(function(cl) { - var ind = escapeSelector(cl); - if (data.classes[ind]) { - data.classes[ind]++; - } else { - data.classes[ind] = 1; - } - }); - } - if (node.hasAttributes()) { - Array.from(axe.utils.getNodeAttributes(node)).filter(filterAttributes).forEach(function(at) { - var atnv = getAttributeNameValue(node, at); - if (atnv) { - if (data.attributes[atnv]) { - data.attributes[atnv]++; - } else { - data.attributes[atnv] = 1; - } - } - }); - } - } - if (current.children.length) { - stack.push(currentLevel); - currentLevel = current.children.slice(); - } - while (!currentLevel.length && stack.length) { - currentLevel = stack.pop(); - } - }; - while (currentLevel.length) { - _loop(); + function getDistinctClassList(elm) { + if (!elm.classList || elm.classList.length === 0) { + return []; } - return data; - }; - function uncommonClasses(node, selectorData) { - var retVal = []; - var classData = selectorData.classes; - var tagData = selectorData.tags; - if (node.classList) { - Array.from(node.classList).forEach(function(cl) { - var ind = escapeSelector(cl); - if (classData[ind] < tagData[node.nodeName]) { - retVal.push({ - name: ind, - count: classData[ind], - species: 'class' - }); - } - }); - } - return retVal.sort(countSort); + var siblings = elm.parentNode && Array.from(elm.parentNode.children || '') || []; + return siblings.reduce(function(classList, childElm) { + if (elm === childElm) { + return classList; + } else { + return classList.filter(function(classItem) { + return !childElm.classList.contains(classItem); + }); + } + }, Array.from(elm.classList).filter(isUncommonClassName)); } + var commonNodes = [ 'div', 'span', 'p', 'b', 'i', 'u', 'strong', 'em', 'h2', 'h3' ]; function getNthChildString(elm, selector) { var siblings = elm.parentNode && Array.from(elm.parentNode.children || '') || []; var hasMatchingSiblings = siblings.find(function(sibling) { @@ -5426,108 +2636,124 @@ return ''; } } - function getElmId(elm) { - if (!elm.getAttribute('id')) { - return; - } - var doc = elm.getRootNode && elm.getRootNode() || document; - var id = '#' + escapeSelector(elm.getAttribute('id') || ''); - if (!id.match(/player_uid_/) && doc.querySelectorAll(id).length === 1) { - return id; - } - } - function getBaseSelector(elm) { - if (typeof isXHTML === 'undefined') { - isXHTML = axe.utils.isXHTML(document); - } - return escapeSelector(isXHTML ? elm.localName : elm.nodeName.toLowerCase()); - } - function uncommonAttributes(node, selectorData) { - var retVal = []; - var attData = selectorData.attributes; - var tagData = selectorData.tags; - if (node.hasAttributes()) { - Array.from(axe.utils.getNodeAttributes(node)).filter(filterAttributes).forEach(function(at) { - var atnv = getAttributeNameValue(node, at); - if (atnv && attData[atnv] < tagData[node.nodeName]) { - retVal.push({ - name: atnv, - count: attData[atnv], - species: 'attribute' - }); + var createSelector = { + getElmId: function getElmId(elm) { + if (!elm.getAttribute('id')) { + return; + } + var doc = elm.getRootNode && elm.getRootNode() || document; + var id = '#' + escapeSelector(elm.getAttribute('id') || ''); + if (!id.match(/player_uid_/) && doc.querySelectorAll(id).length === 1) { + return id; + } + }, + getCustomElm: function getCustomElm(elm, _ref) { + var isCustomElm = _ref.isCustomElm, nodeName = _ref.nodeName; + if (isCustomElm) { + return nodeName; + } + }, + getElmRoleProp: function getElmRoleProp(elm) { + if (elm.hasAttribute('role')) { + return '[role="' + escapeSelector(elm.getAttribute('role')) + '"]'; + } + }, + getUncommonElm: function getUncommonElm(elm, _ref2) { + var isCommonElm = _ref2.isCommonElm, isCustomElm = _ref2.isCustomElm, nodeName = _ref2.nodeName; + if (!isCommonElm && !isCustomElm) { + nodeName = escapeSelector(nodeName); + if (nodeName === 'input' && elm.hasAttribute('type')) { + nodeName += '[type="' + elm.type + '"]'; } - }); - } - return retVal.sort(countSort); - } - function getThreeLeastCommonFeatures(elm, selectorData) { - var selector = ''; - var features; - var clss = uncommonClasses(elm, selectorData); - var atts = uncommonAttributes(elm, selectorData); - if (clss.length && clss[0].count === 1) { - features = [ clss[0] ]; - } else if (atts.length && atts[0].count === 1) { - features = [ atts[0] ]; - selector = getBaseSelector(elm); - } else { - features = clss.concat(atts); - features.sort(countSort); - features = features.slice(0, 3); - if (!features.some(function(feat) { - return feat.species === 'class'; - })) { - selector = getBaseSelector(elm); + return nodeName; + } + }, + getElmNameProp: function getElmNameProp(elm) { + if (!elm.hasAttribute('id') && elm.name) { + return '[name="' + escapeSelector(elm.name) + '"]'; + } + }, + getDistinctClass: function getDistinctClass(elm, _ref3) { + var distinctClassList = _ref3.distinctClassList; + if (distinctClassList.length > 0 && distinctClassList.length < 3) { + return '.' + distinctClassList.map(escapeSelector).join('.'); + } + }, + getFileRefProp: function getFileRefProp(elm) { + var attr = void 0; + if (elm.hasAttribute('href')) { + attr = 'href'; + } else if (elm.hasAttribute('src')) { + attr = 'src'; } else { - features.sort(function(a, b) { - return a.species !== b.species && a.species === 'class' ? -1 : a.species === b.species ? 0 : 1; - }); + return; + } + var friendlyUriEnd = axe.utils.getFriendlyUriEnd(elm.getAttribute(attr)); + if (friendlyUriEnd) { + return '[' + attr + '$="' + encodeURI(friendlyUriEnd) + '"]'; + } + }, + getCommonName: function getCommonName(elm, _ref4) { + var nodeName = _ref4.nodeName, isCommonElm = _ref4.isCommonElm; + if (isCommonElm) { + return nodeName; } } - return selector += features.reduce(function(val, feat) { - switch (feat.species) { - case 'class': - return val + '.' + feat.name; - - case 'attribute': - return val + '[' + feat.name + ']'; + }; + function getElmFeatures(elm, featureCount) { + var nodeName = elm.nodeName.toLowerCase(); + var classList = Array.from(elm.classList) || []; + var props = { + nodeName: nodeName, + classList: classList, + isCustomElm: nodeName.includes('-'), + isCommonElm: commonNodes.includes(nodeName), + distinctClassList: getDistinctClassList(elm) + }; + return [ createSelector.getCustomElm, createSelector.getElmRoleProp, createSelector.getUncommonElm, createSelector.getElmNameProp, createSelector.getDistinctClass, createSelector.getFileRefProp, createSelector.getCommonName ].reduce(function(features, func) { + if (features.length === featureCount) { + return features; } - return val; - }, ''); + var feature = func(elm, props); + if (feature) { + if (!feature[0].match(/[a-z]/)) { + features.push(feature); + } else { + features.unshift(feature); + } + } + return features; + }, []); } function generateSelector(elm, options, doc) { - if (!axe._selectorData) { - throw new Error('Expect axe._selectorData to be set up'); + var selector = void 0, addParent = void 0; + var _options$isUnique = options.isUnique, isUnique = _options$isUnique === undefined ? false : _options$isUnique; + var idSelector = createSelector.getElmId(elm); + var _options$featureCount = options.featureCount, featureCount = _options$featureCount === undefined ? 2 : _options$featureCount, _options$minDepth = options.minDepth, minDepth = _options$minDepth === undefined ? 1 : _options$minDepth, _options$toRoot = options.toRoot, toRoot = _options$toRoot === undefined ? false : _options$toRoot, _options$childSelecto = options.childSelectors, childSelectors = _options$childSelecto === undefined ? [] : _options$childSelecto; + if (idSelector) { + selector = idSelector; + isUnique = true; + } else { + selector = getElmFeatures(elm, featureCount).join(''); + selector += getNthChildString(elm, selector); + isUnique = options.isUnique || doc.querySelectorAll(selector).length === 1; + if (!isUnique && elm === document.documentElement) { + selector += ':root'; + } + addParent = minDepth !== 0 || !isUnique; } - var _options$toRoot = options.toRoot, toRoot = _options$toRoot === void 0 ? false : _options$toRoot; - var selector; - var similar; - do { - var features = getElmId(elm); - if (!features) { - features = getThreeLeastCommonFeatures(elm, axe._selectorData); - features += getNthChildString(elm, features); - } - if (selector) { - selector = features + ' > ' + selector; - } else { - selector = features; - } - if (!similar) { - similar = Array.from(doc.querySelectorAll(selector)); - } else { - similar = similar.filter(function(item) { - return axe.utils.matchesSelector(item, selector); - }); - } - elm = elm.parentElement; - } while ((similar.length > 1 || toRoot) && elm && elm.nodeType !== 11); - if (similar.length === 1) { - return selector; - } else if (selector.indexOf(' > ') !== -1) { - return ':root' + selector.substring(selector.indexOf(' > ')); + var selectorParts = [ selector ].concat(_toConsumableArray(childSelectors)); + if (elm.parentElement && elm.parentElement.nodeType !== 11 && (toRoot || addParent)) { + return generateSelector(elm.parentNode, { + toRoot: toRoot, + isUnique: isUnique, + childSelectors: selectorParts, + featureCount: 1, + minDepth: minDepth - 1 + }, doc); + } else { + return selectorParts.join(' > '); } - return ':root'; } axe.utils.getSelector = function createUniqueSelector(elm) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; @@ -5557,30 +2783,6 @@ } }; 'use strict'; - axe.utils.getStyleSheetFactory = function getStyleSheetFactory(dynamicDoc) { - if (!dynamicDoc) { - throw new Error('axe.utils.getStyleSheetFactory should be invoked with an argument'); - } - return function(options) { - var data = options.data, _options$isCrossOrigi = options.isCrossOrigin, isCrossOrigin = _options$isCrossOrigi === void 0 ? false : _options$isCrossOrigi, shadowId = options.shadowId, root = options.root, priority = options.priority, _options$isLink = options.isLink, isLink = _options$isLink === void 0 ? false : _options$isLink; - var style = dynamicDoc.createElement('style'); - if (isLink) { - var text = dynamicDoc.createTextNode('@import "'.concat(data.href, '"')); - style.appendChild(text); - } else { - style.appendChild(dynamicDoc.createTextNode(data)); - } - dynamicDoc.head.appendChild(style); - return { - sheet: style.sheet, - isCrossOrigin: isCrossOrigin, - shadowId: shadowId, - root: root, - priority: priority - }; - }; - }; - 'use strict'; function getXPathArray(node, path) { var sibling, count; if (!node) { @@ -5637,9 +2839,9 @@ function xpathToString(xpathArray) { return xpathArray.reduce(function(str, elm) { if (elm.id) { - return '/'.concat(elm.str, '[@id=\'').concat(elm.id, '\']'); + return '/' + elm.str + '[@id=\'' + elm.id + '\']'; } else { - return str + '/'.concat(elm.str) + (elm.count > 0 ? '['.concat(elm.count, ']') : ''); + return str + ('/' + elm.str) + (elm.count > 0 ? '[' + elm.count + ']' : ''); } }, ''); } @@ -5677,51 +2879,19 @@ 'use strict'; axe.utils.isHidden = function isHidden(el, recursed) { 'use strict'; - var node = axe.utils.getNodeFromTree(el); + var parent; if (el.nodeType === 9) { return false; } if (el.nodeType === 11) { el = el.host; } - if (node && node._isHidden !== null) { - return node._isHidden; - } var style = window.getComputedStyle(el, null); if (!style || !el.parentNode || style.getPropertyValue('display') === 'none' || !recursed && style.getPropertyValue('visibility') === 'hidden' || el.getAttribute('aria-hidden') === 'true') { return true; } - var parent = el.assignedSlot ? el.assignedSlot : el.parentNode; - var isHidden = axe.utils.isHidden(parent, true); - if (node) { - node._isHidden = isHidden; - } - return isHidden; - }; - 'use strict'; - var htmlTags = [ 'a', 'abbr', 'address', 'area', 'article', 'aside', 'audio', 'b', 'base', 'bdi', 'bdo', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'cite', 'code', 'col', 'colgroup', 'data', 'datalist', 'dd', 'del', 'details', 'dfn', 'dialog', 'div', 'dl', 'dt', 'em', 'embed', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'iframe', 'img', 'input', 'ins', 'kbd', 'keygen', 'label', 'legend', 'li', 'link', 'main', 'map', 'mark', 'math', 'menu', 'menuitem', 'meta', 'meter', 'nav', 'noscript', 'object', 'ol', 'optgroup', 'option', 'output', 'p', 'param', 'picture', 'pre', 'progress', 'q', 'rb', 'rp', 'rt', 'rtc', 'ruby', 's', 'samp', 'script', 'section', 'select', 'slot', 'small', 'source', 'span', 'strong', 'style', 'sub', 'summary', 'sup', 'svg', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'title', 'tr', 'track', 'u', 'ul', 'var', 'video', 'wbr' ]; - axe.utils.isHtmlElement = function isHtmlElement(node) { - var tagName = node.nodeName.toLowerCase(); - return htmlTags.includes(tagName) && node.namespaceURI !== 'http://www.w3.org/2000/svg'; - }; - 'use strict'; - var possibleShadowRoots = [ 'article', 'aside', 'blockquote', 'body', 'div', 'footer', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'main', 'nav', 'p', 'section', 'span' ]; - axe.utils.isShadowRoot = function isShadowRoot(node) { - var nodeName = node.nodeName.toLowerCase(); - if (node.shadowRoot) { - if (/^[a-z][a-z0-9_.-]*-[a-z0-9_.-]*$/.test(nodeName) || possibleShadowRoots.includes(nodeName)) { - return true; - } - } - return false; - }; - 'use strict'; - axe.utils.isXHTML = function(doc) { - 'use strict'; - if (!doc.createElement) { - return false; - } - return doc.createElement('A').localName === 'A'; + parent = el.assignedSlot ? el.assignedSlot : el.parentNode; + return axe.utils.isHidden(parent, true); }; 'use strict'; function pushFrame(resultSet, options, frameElement, frameSelector) { @@ -5799,125 +2969,17 @@ return result; }; 'use strict'; - axe.utils.nodeSorter = function nodeSorter(nodeA, nodeB) { - nodeA = nodeA.actualNode || nodeA; - nodeB = nodeB.actualNode || nodeB; - if (nodeA === nodeB) { + axe.utils.nodeSorter = function nodeSorter(a, b) { + 'use strict'; + if (a.actualNode === b.actualNode) { return 0; } - if (nodeA.compareDocumentPosition(nodeB) & 4) { + if (a.actualNode.compareDocumentPosition(b.actualNode) & 4) { return -1; - } else { - return 1; } + return 1; }; 'use strict'; - axe.utils.parseCrossOriginStylesheet = function parseCrossOriginStylesheet(url, options, priority, importedUrls, isCrossOrigin) { - var axiosOptions = { - method: 'get', - url: url - }; - importedUrls.push(url); - return axe.imports.axios(axiosOptions).then(function(_ref) { - var data = _ref.data; - var result = options.convertDataToStylesheet({ - data: data, - isCrossOrigin: isCrossOrigin, - priority: priority, - root: options.rootNode, - shadowId: options.shadowId - }); - return axe.utils.parseStylesheet(result.sheet, options, priority, importedUrls, result.isCrossOrigin); - }); - }; - 'use strict'; - function _toConsumableArray(arr) { - return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); - } - function _nonIterableSpread() { - throw new TypeError('Invalid attempt to spread non-iterable instance'); - } - function _iterableToArray(iter) { - if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === '[object Arguments]') { - return Array.from(iter); - } - } - function _arrayWithoutHoles(arr) { - if (Array.isArray(arr)) { - for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { - arr2[i] = arr[i]; - } - return arr2; - } - } - axe.utils.parseSameOriginStylesheet = function parseSameOriginStylesheet(sheet, options, priority, importedUrls) { - var isCrossOrigin = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; - var rules = Array.from(sheet.cssRules); - if (!rules) { - return Promise.resolve(); - } - var cssImportRules = rules.filter(function(r) { - return r.type === 3; - }); - if (!cssImportRules.length) { - return Promise.resolve({ - isCrossOrigin: isCrossOrigin, - priority: priority, - root: options.rootNode, - shadowId: options.shadowId, - sheet: sheet - }); - } - var cssImportUrlsNotAlreadyImported = cssImportRules.filter(function(rule) { - return rule.href; - }).map(function(rule) { - return rule.href; - }).filter(function(url) { - return !importedUrls.includes(url); - }); - var promises = cssImportUrlsNotAlreadyImported.map(function(importUrl, cssRuleIndex) { - var newPriority = [].concat(_toConsumableArray(priority), [ cssRuleIndex ]); - var isCrossOriginRequest = /^https?:\/\/|^\/\//i.test(importUrl); - return axe.utils.parseCrossOriginStylesheet(importUrl, options, newPriority, importedUrls, isCrossOriginRequest); - }); - var nonImportCSSRules = rules.filter(function(r) { - return r.type !== 3; - }); - if (!nonImportCSSRules.length) { - return Promise.all(promises); - } - promises.push(Promise.resolve(options.convertDataToStylesheet({ - data: nonImportCSSRules.map(function(rule) { - return rule.cssText; - }).join(), - isCrossOrigin: isCrossOrigin, - priority: priority, - root: options.rootNode, - shadowId: options.shadowId - }))); - return Promise.all(promises); - }; - 'use strict'; - axe.utils.parseStylesheet = function parseStylesheet(sheet, options, priority, importedUrls) { - var isCrossOrigin = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; - var isSameOrigin = isSameOriginStylesheet(sheet); - if (isSameOrigin) { - return axe.utils.parseSameOriginStylesheet(sheet, options, priority, importedUrls, isCrossOrigin); - } - return axe.utils.parseCrossOriginStylesheet(sheet.href, options, priority, importedUrls, true); - }; - function isSameOriginStylesheet(sheet) { - try { - var rules = sheet.cssRules; - if (!rules && sheet.href) { - return false; - } - return true; - } catch (e) { - return false; - } - } - 'use strict'; utils.performanceTimer = function() { 'use strict'; function now() { @@ -5959,10 +3021,7 @@ axe.log('Measure ' + req.name + ' took ' + req.duration + 'ms'); } if (window.performance && window.performance.getEntriesByType !== undefined) { - var axeStart = window.performance.getEntriesByName('mark_axe_start')[0]; - var measures = window.performance.getEntriesByType('measure').filter(function(measure) { - return measure.startTime >= axeStart.startTime; - }); + var measures = window.performance.getEntriesByType('measure'); for (var i = 0; i < measures.length; ++i) { var req = measures[i]; if (req.name === measureName) { @@ -6008,27 +3067,25 @@ })(); } if (!Array.prototype.find) { - Object.defineProperty(Array.prototype, 'find', { - value: function value(predicate) { - if (this === null) { - throw new TypeError('Array.prototype.find called on null or undefined'); - } - if (typeof predicate !== 'function') { - throw new TypeError('predicate must be a function'); - } - var list = Object(this); - var length = list.length >>> 0; - var thisArg = arguments[1]; - var value; - for (var i = 0; i < length; i++) { - value = list[i]; - if (predicate.call(thisArg, value, i, list)) { - return value; - } - } - return undefined; + Array.prototype.find = function(predicate) { + if (this === null) { + throw new TypeError('Array.prototype.find called on null or undefined'); } - }); + if (typeof predicate !== 'function') { + throw new TypeError('predicate must be a function'); + } + var list = Object(this); + var length = list.length >>> 0; + var thisArg = arguments[1]; + var value; + for (var i = 0; i < length; i++) { + value = list[i]; + if (predicate.call(thisArg, value, i, list)) { + return value; + } + } + return undefined; + }; } axe.utils.pollyfillElementsFromPoint = function() { if (document.elementsFromPoint) { @@ -6059,10 +3116,6 @@ }); current.style.setProperty(cssProp, cssDisableVal, 'important'); } - if (elements.indexOf(document.documentElement) < elements.length - 1) { - elements.splice(elements.indexOf(document.documentElement), 1); - elements.push(document.documentElement); - } for (i = previousPointerEvents.length; !!(d = previousPointerEvents[--i]); ) { elements[i].style.setProperty(cssProp, d.value ? d.value : '', d.priority); } @@ -6074,114 +3127,108 @@ document.elementsFromPoint = axe.utils.pollyfillElementsFromPoint(); } if (!Array.prototype.includes) { - Object.defineProperty(Array.prototype, 'includes', { - value: function value(searchElement) { - 'use strict'; - var O = Object(this); - var len = parseInt(O.length, 10) || 0; - if (len === 0) { - return false; - } - var n = parseInt(arguments[1], 10) || 0; - var k; - if (n >= 0) { - k = n; - } else { - k = len + n; - if (k < 0) { - k = 0; - } - } - var currentElement; - while (k < len) { - currentElement = O[k]; - if (searchElement === currentElement || searchElement !== searchElement && currentElement !== currentElement) { - return true; - } - k++; - } + Array.prototype.includes = function(searchElement) { + 'use strict'; + var O = Object(this); + var len = parseInt(O.length, 10) || 0; + if (len === 0) { return false; } - }); + var n = parseInt(arguments[1], 10) || 0; + var k; + if (n >= 0) { + k = n; + } else { + k = len + n; + if (k < 0) { + k = 0; + } + } + var currentElement; + while (k < len) { + currentElement = O[k]; + if (searchElement === currentElement || searchElement !== searchElement && currentElement !== currentElement) { + return true; + } + k++; + } + return false; + }; } if (!Array.prototype.some) { - Object.defineProperty(Array.prototype, 'some', { - value: function value(fun) { - 'use strict'; - if (this == null) { - throw new TypeError('Array.prototype.some called on null or undefined'); - } - if (typeof fun !== 'function') { - throw new TypeError(); - } - var t = Object(this); - var len = t.length >>> 0; - var thisArg = arguments.length >= 2 ? arguments[1] : void 0; - for (var i = 0; i < len; i++) { - if (i in t && fun.call(thisArg, t[i], i, t)) { - return true; - } - } - return false; + Array.prototype.some = function(fun) { + 'use strict'; + if (this == null) { + throw new TypeError('Array.prototype.some called on null or undefined'); } - }); + if (typeof fun !== 'function') { + throw new TypeError(); + } + var t = Object(this); + var len = t.length >>> 0; + var thisArg = arguments.length >= 2 ? arguments[1] : void 0; + for (var i = 0; i < len; i++) { + if (i in t && fun.call(thisArg, t[i], i, t)) { + return true; + } + } + return false; + }; } if (!Array.from) { - Object.defineProperty(Array, 'from', { - value: function() { - var toStr = Object.prototype.toString; - var isCallable = function isCallable(fn) { - return typeof fn === 'function' || toStr.call(fn) === '[object Function]'; - }; - var toInteger = function toInteger(value) { - var number = Number(value); - if (isNaN(number)) { - return 0; + Array.from = function() { + var toStr = Object.prototype.toString; + var isCallable = function isCallable(fn) { + return typeof fn === 'function' || toStr.call(fn) === '[object Function]'; + }; + var toInteger = function toInteger(value) { + var number = Number(value); + if (isNaN(number)) { + return 0; + } + if (number === 0 || !isFinite(number)) { + return number; + } + return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number)); + }; + var maxSafeInteger = Math.pow(2, 53) - 1; + var toLength = function toLength(value) { + var len = toInteger(value); + return Math.min(Math.max(len, 0), maxSafeInteger); + }; + return function from(arrayLike) { + var C = this; + var items = Object(arrayLike); + if (arrayLike == null) { + throw new TypeError('Array.from requires an array-like object - not null or undefined'); + } + var mapFn = arguments.length > 1 ? arguments[1] : void undefined; + var T; + if (typeof mapFn !== 'undefined') { + if (!isCallable(mapFn)) { + throw new TypeError('Array.from: when provided, the second argument must be a function'); } - if (number === 0 || !isFinite(number)) { - return number; + if (arguments.length > 2) { + T = arguments[2]; } - return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number)); - }; - var maxSafeInteger = Math.pow(2, 53) - 1; - var toLength = function toLength(value) { - var len = toInteger(value); - return Math.min(Math.max(len, 0), maxSafeInteger); - }; - return function from(arrayLike) { - var C = this; - var items = Object(arrayLike); - if (arrayLike == null) { - throw new TypeError('Array.from requires an array-like object - not null or undefined'); + } + var len = toLength(items.length); + var A = isCallable(C) ? Object(new C(len)) : new Array(len); + var k = 0; + var kValue; + while (k < len) { + kValue = items[k]; + if (mapFn) { + A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k); + } else { + A[k] = kValue; } - var mapFn = arguments.length > 1 ? arguments[1] : void undefined; - var T; - if (typeof mapFn !== 'undefined') { - if (!isCallable(mapFn)) { - throw new TypeError('Array.from: when provided, the second argument must be a function'); - } - if (arguments.length > 2) { - T = arguments[2]; - } - } - var len = toLength(items.length); - var A = isCallable(C) ? Object(new C(len)) : new Array(len); - var k = 0; - var kValue; - while (k < len) { - kValue = items[k]; - if (mapFn) { - A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k); - } else { - A[k] = kValue; - } - k += 1; - } - A.length = len; - return A; - }; - }() - }); + k += 1; + } + A.length = len; + return A; + }; + }(); } if (!String.prototype.includes) { String.prototype.includes = function(search, start) { @@ -6196,238 +3243,15 @@ }; } 'use strict'; - axe.utils.preloadCssom = function preloadCssom(_ref) { - var _ref$treeRoot = _ref.treeRoot, treeRoot = _ref$treeRoot === void 0 ? axe._tree[0] : _ref$treeRoot; - var rootNodes = getAllRootNodesInTree(treeRoot); - if (!rootNodes.length) { - return Promise.resolve(); - } - var dynamicDoc = document.implementation.createHTMLDocument('Dynamic document for loading cssom'); - var convertDataToStylesheet = axe.utils.getStyleSheetFactory(dynamicDoc); - return getCssomForAllRootNodes(rootNodes, convertDataToStylesheet).then(function(assets) { - return flattenAssets(assets); - }); + var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) { + return typeof obj; + } : function(obj) { + return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj; }; - function getAllRootNodesInTree(tree) { - var ids = []; - var rootNodes = axe.utils.querySelectorAllFilter(tree, '*', function(node) { - if (ids.includes(node.shadowId)) { - return false; - } - ids.push(node.shadowId); - return true; - }).map(function(node) { - return { - shadowId: node.shadowId, - rootNode: axe.utils.getRootNode(node.actualNode) - }; - }); - return axe.utils.uniqueArray(rootNodes, []); - } - function getCssomForAllRootNodes(rootNodes, convertDataToStylesheet) { - var promises = []; - rootNodes.forEach(function(_ref2, index) { - var rootNode = _ref2.rootNode, shadowId = _ref2.shadowId; - var sheets = getStylesheetsOfRootNode(rootNode, shadowId, convertDataToStylesheet); - if (!sheets) { - return Promise.all(promises); - } - var rootIndex = index + 1; - var parseOptions = { - rootNode: rootNode, - shadowId: shadowId, - convertDataToStylesheet: convertDataToStylesheet, - rootIndex: rootIndex - }; - var importedUrls = []; - var p = Promise.all(sheets.map(function(sheet, sheetIndex) { - var priority = [ rootIndex, sheetIndex ]; - return axe.utils.parseStylesheet(sheet, parseOptions, priority, importedUrls); - })); - promises.push(p); - }); - return Promise.all(promises); - } - function flattenAssets(assets) { - return assets.reduce(function(acc, val) { - return Array.isArray(val) ? acc.concat(flattenAssets(val)) : acc.concat(val); - }, []); - } - function getStylesheetsOfRootNode(rootNode, shadowId, convertDataToStylesheet) { - var sheets; - if (rootNode.nodeType === 11 && shadowId) { - sheets = getStylesheetsFromDocumentFragment(rootNode, convertDataToStylesheet); - } else { - sheets = getStylesheetsFromDocument(rootNode); - } - return filterStylesheetsWithSameHref(sheets); - } - function getStylesheetsFromDocumentFragment(rootNode, convertDataToStylesheet) { - return Array.from(rootNode.children).filter(filerStyleAndLinkAttributesInDocumentFragment).reduce(function(out, node) { - var nodeName = node.nodeName.toUpperCase(); - var data = nodeName === 'STYLE' ? node.textContent : node; - var isLink = nodeName === 'LINK'; - var stylesheet = convertDataToStylesheet({ - data: data, - isLink: isLink, - root: rootNode - }); - out.push(stylesheet.sheet); - return out; - }, []); - } - function getStylesheetsFromDocument(rootNode) { - return Array.from(rootNode.styleSheets).filter(function(sheet) { - return filterMediaIsPrint(sheet.media.mediaText); - }); - } - function filerStyleAndLinkAttributesInDocumentFragment(node) { - var nodeName = node.nodeName.toUpperCase(); - var linkHref = node.getAttribute('href'); - var linkRel = node.getAttribute('rel'); - var isLink = nodeName === 'LINK' && linkHref && linkRel && node.rel.toUpperCase().includes('STYLESHEET'); - var isStyle = nodeName === 'STYLE'; - return isStyle || isLink && filterMediaIsPrint(node.media); - } - function filterMediaIsPrint(media) { - if (!media) { - return true; - } - return !media.toUpperCase().includes('PRINT'); - } - function filterStylesheetsWithSameHref(sheets) { - var hrefs = []; - return sheets.filter(function(sheet) { - if (!sheet.href) { - return true; - } - if (hrefs.includes(sheet.href)) { - return false; - } - hrefs.push(sheet.href); - return true; - }); - } - 'use strict'; - function _extends() { - _extends = Object.assign || function(target) { - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i]; - for (var key in source) { - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - return target; - }; - return _extends.apply(this, arguments); - } - function _defineProperty(obj, key, value) { - if (key in obj) { - Object.defineProperty(obj, key, { - value: value, - enumerable: true, - configurable: true, - writable: true - }); - } else { - obj[key] = value; - } - return obj; - } - function _typeof(obj) { - if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') { - _typeof = function _typeof(obj) { - return typeof obj; - }; - } else { - _typeof = function _typeof(obj) { - return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj; - }; - } - return _typeof(obj); - } - function isValidPreloadObject(preload) { - return _typeof(preload) === 'object' && Array.isArray(preload.assets); - } - axe.utils.shouldPreload = function shouldPreload(options) { - if (!options || options.preload === undefined || options.preload === null) { - return true; - } - if (typeof options.preload === 'boolean') { - return options.preload; - } - return isValidPreloadObject(options.preload); - }; - axe.utils.getPreloadConfig = function getPreloadConfig(options) { - var _axe$constants$preloa = axe.constants.preload, assets = _axe$constants$preloa.assets, timeout = _axe$constants$preloa.timeout; - var config = { - assets: assets, - timeout: timeout - }; - if (!options.preload) { - return config; - } - if (typeof options.preload === 'boolean') { - return config; - } - var areRequestedAssetsValid = options.preload.assets.every(function(a) { - return assets.includes(a.toLowerCase()); - }); - if (!areRequestedAssetsValid) { - throw new Error('Requested assets, not supported. ' + 'Supported assets are: '.concat(assets.join(', '), '.')); - } - config.assets = axe.utils.uniqueArray(options.preload.assets.map(function(a) { - return a.toLowerCase(); - }), []); - if (options.preload.timeout && typeof options.preload.timeout === 'number' && !Number.isNaN(options.preload.timeout)) { - config.timeout = options.preload.timeout; - } - return config; - }; - axe.utils.preload = function preload(options) { - var preloadFunctionsMap = { - cssom: axe.utils.preloadCssom - }; - var shouldPreload = axe.utils.shouldPreload(options); - if (!shouldPreload) { - return Promise.resolve(); - } - return new Promise(function(resolve, reject) { - var _axe$utils$getPreload = axe.utils.getPreloadConfig(options), assets = _axe$utils$getPreload.assets, timeout = _axe$utils$getPreload.timeout; - setTimeout(function() { - return reject('Preload assets timed out.'); - }, timeout); - Promise.all(assets.map(function(asset) { - return preloadFunctionsMap[asset](options).then(function(results) { - return _defineProperty({}, asset, results); - }); - })).then(function(results) { - var preloadAssets = results.reduce(function(out, result) { - return _extends({}, out, {}, result); - }, {}); - resolve(preloadAssets); - }); - }); - }; - 'use strict'; - function _typeof(obj) { - if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') { - _typeof = function _typeof(obj) { - return typeof obj; - }; - } else { - _typeof = function _typeof(obj) { - return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj; - }; - } - return _typeof(obj); - } function getIncompleteReason(checkData, messages) { function getDefaultMsg(messages) { - if (messages.incomplete && messages.incomplete['default']) { - return messages.incomplete['default']; + if (messages.incomplete && messages.incomplete.default) { + return messages.incomplete.default; } else { return helpers.incompleteFallbackMessage(); } @@ -6489,22 +3313,22 @@ 'use strict'; var convertExpressions = function convertExpressions() {}; var matchExpressions = function matchExpressions() {}; - function matchesTag(vNode, exp) { - return vNode.props.nodeType === 1 && (exp.tag === '*' || vNode.props.nodeName === exp.tag); + function matchesTag(node, exp) { + return node.nodeType === 1 && (exp.tag === '*' || node.nodeName.toLowerCase() === exp.tag); } - function matchesClasses(vNode, exp) { - return !exp.classes || exp.classes.every(function(cl) { - return vNode.hasClass(cl.value); - }); + function matchesClasses(node, exp) { + return !exp.classes || exp.classes.reduce(function(result, cl) { + return result && node.className && node.className.match(cl.regexp); + }, true); } - function matchesAttributes(vNode, exp) { + function matchesAttributes(node, exp) { return !exp.attributes || exp.attributes.reduce(function(result, att) { - var nodeAtt = vNode.attr(att.key); + var nodeAtt = node.getAttribute(att.key); return result && nodeAtt !== null && (!att.value || att.test(nodeAtt)); }, true); } - function matchesId(vNode, exp) { - return !exp.id || vNode.props.id === exp.id; + function matchesId(node, exp) { + return !exp.id || node.id === exp.id; } function matchesPseudos(target, exp) { if (!exp.pseudos || exp.pseudos.reduce(function(result, pseudo) { @@ -6517,7 +3341,23 @@ } return false; } + function matchSelector(targets, exp, recurse) { + var result = []; + targets = Array.isArray(targets) ? targets : [ targets ]; + targets.forEach(function(target) { + if (matchesTag(target.actualNode, exp) && matchesClasses(target.actualNode, exp) && matchesAttributes(target.actualNode, exp) && matchesId(target.actualNode, exp) && matchesPseudos(target, exp)) { + result.push(target); + } + if (recurse) { + result = result.concat(matchSelector(target.children.filter(function(child) { + return !exp.id || child.shadowId === target.shadowId; + }), exp, recurse)); + } + }); + return result; + } var escapeRegExp = function() { + /*! Credit: XRegExp 0.6.1 (c) 2007-2008 Steven Levithan <http://stevenlevithan.com/regex/xregexp/> MIT License */ var from = /(?=[\-\[\]{}()*+?.\\\^$|,#\s])/g; var to = '\\'; return function(string) { @@ -6526,6 +3366,7 @@ }(); var reUnescape = /\\/g; function convertAttributes(atts) { + /*! Credit Mootools Copyright Mootools, MIT License */ if (!atts) { return; } @@ -6558,7 +3399,7 @@ case '*=': test = function test(value) { - return value && value.includes(attributeValue); + return value && value.indexOf(attributeValue) > -1; }; break; @@ -6609,7 +3450,7 @@ return pseudos.map(function(p) { var expressions; if (p.name === 'not') { - expressions = p.value; + expressions = axe.utils.cssParser.parse(p.value); expressions = expressions.selectors ? expressions.selectors : [ expressions ]; expressions = convertExpressions(expressions); } @@ -6638,87 +3479,34 @@ return newExp; }); }; - function createLocalVariables(vNodes, anyLevel, thisLevel, parentShadowId) { - var retVal = { - vNodes: vNodes.slice(), - anyLevel: anyLevel, - thisLevel: thisLevel, - parentShadowId: parentShadowId - }; - retVal.vNodes.reverse(); - return retVal; - } - function matchesSelector(vNode, exp) { - return matchesTag(vNode, exp[0]) && matchesClasses(vNode, exp[0]) && matchesAttributes(vNode, exp[0]) && matchesId(vNode, exp[0]) && matchesPseudos(vNode, exp[0]); - } - matchExpressions = function matchExpressions(domTree, expressions, recurse, filter) { - var stack = []; - var vNodes = Array.isArray(domTree) ? domTree : [ domTree ]; - var currentLevel = createLocalVariables(vNodes, expressions, [], domTree[0].shadowId); - var result = []; - while (currentLevel.vNodes.length) { - var vNode = currentLevel.vNodes.pop(); - var childOnly = []; - var childAny = []; - var combined = currentLevel.anyLevel.slice().concat(currentLevel.thisLevel); - var added = false; - for (var i = 0; i < combined.length; i++) { - var exp = combined[i]; - if (matchesSelector(vNode, exp) && (!exp[0].id || vNode.shadowId === currentLevel.parentShadowId)) { - if (exp.length === 1) { - if (!added && (!filter || filter(vNode))) { - result.push(vNode); - added = true; - } - } else { - var rest = exp.slice(1); - if ([ ' ', '>' ].includes(rest[0].combinator) === false) { - throw new Error('axe.utils.querySelectorAll does not support the combinator: ' + exp[1].combinator); - } - if (rest[0].combinator === '>') { - childOnly.push(rest); - } else { - childAny.push(rest); - } - } + matchExpressions = function matchExpressions(domTree, expressions, recurse) { + return expressions.reduce(function(collected, exprArr) { + var candidates = domTree; + exprArr.forEach(function(exp, index) { + recurse = exp.combinator === '>' ? false : recurse; + if ([ ' ', '>' ].indexOf(exp.combinator) === -1) { + throw new Error('axe.utils.querySelectorAll does not support the combinator: ' + exp.combinator); } - if (currentLevel.anyLevel.includes(exp) && (!exp[0].id || vNode.shadowId === currentLevel.parentShadowId)) { - childAny.push(exp); - } - } - if (vNode.children && vNode.children.length && recurse) { - stack.push(currentLevel); - currentLevel = createLocalVariables(vNode.children, childAny, childOnly, vNode.shadowId); - } - while (!currentLevel.vNodes.length && stack.length) { - currentLevel = stack.pop(); - } - } - return result; + candidates = candidates.reduce(function(result, node) { + return result.concat(matchSelector(index ? node.children : node, exp, recurse)); + }, []); + }); + return collected.concat(candidates); + }, []); }; axe.utils.querySelectorAll = function(domTree, selector) { - return axe.utils.querySelectorAllFilter(domTree, selector); - }; - axe.utils.querySelectorAllFilter = function(domTree, selector, filter) { domTree = Array.isArray(domTree) ? domTree : [ domTree ]; var expressions = axe.utils.cssParser.parse(selector); expressions = expressions.selectors ? expressions.selectors : [ expressions ]; expressions = convertExpressions(expressions); - return matchExpressions(domTree, expressions, true, filter); + return matchExpressions(domTree, expressions, true); }; 'use strict'; - function _typeof(obj) { - if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') { - _typeof = function _typeof(obj) { - return typeof obj; - }; - } else { - _typeof = function _typeof(obj) { - return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj; - }; - } - return _typeof(obj); - } + var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) { + return typeof obj; + } : function(obj) { + return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj; + }; (function() { 'use strict'; function noop() {} @@ -6771,10 +3559,10 @@ } var q = { defer: function defer(fn) { - if (_typeof(fn) === 'object' && fn.then && fn['catch']) { + if ((typeof fn === 'undefined' ? 'undefined' : _typeof(fn)) === 'object' && fn.then && fn.catch) { var defer = fn; fn = function fn(resolve, reject) { - defer.then(resolve)['catch'](reject); + defer.then(resolve).catch(reject); }; } funcGuard(fn); @@ -6822,24 +3610,17 @@ axe.utils.queue = queue; })(); 'use strict'; - function _typeof(obj) { - if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') { - _typeof = function _typeof(obj) { - return typeof obj; - }; - } else { - _typeof = function _typeof(obj) { - return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj; - }; - } - return _typeof(obj); - } + var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) { + return typeof obj; + } : function(obj) { + return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj; + }; (function(exports) { 'use strict'; - var messages = {}, subscribers = {}, errorTypes = Object.freeze([ 'EvalError', 'RangeError', 'ReferenceError', 'SyntaxError', 'TypeError', 'URIError' ]); + var messages = {}, subscribers = {}; function _getSource() { - var application = 'axeAPI', version = '', src; - if (typeof axe !== 'undefined' && axe._audit && axe._audit.application) { + var application = 'axe', version = '', src; + if (typeof axe !== 'undefined' && axe._audit && !axe._audit.application) { application = axe._audit.application; } if (typeof axe !== 'undefined') { @@ -6849,9 +3630,9 @@ return src; } function verify(postedMessage) { - if (_typeof(postedMessage) === 'object' && typeof postedMessage.uuid === 'string' && postedMessage._respondable === true) { + if ((typeof postedMessage === 'undefined' ? 'undefined' : _typeof(postedMessage)) === 'object' && typeof postedMessage.uuid === 'string' && postedMessage._respondable === true) { var messageSource = _getSource(); - return postedMessage._source === messageSource || postedMessage._source === 'axeAPI.x.y.z' || messageSource === 'axeAPI.x.y.z'; + return postedMessage._source === messageSource || postedMessage._source === 'axe.x.y.z' || messageSource === 'axe.x.y.z'; } return false; } @@ -6895,18 +3676,17 @@ post(source, topic, message, uuid, keepalive, callback); }; } - function publish(source, data, keepalive) { + function publish(target, data, keepalive) { var topic = data.topic; var subscriber = subscribers[topic]; if (subscriber) { - var responder = createResponder(source, null, data.uuid); + var responder = createResponder(target, null, data.uuid); subscriber(data.message, keepalive, responder); } } function buildErrorObject(error) { var msg = error.message || 'Unknown error occurred'; - var errorName = errorTypes.includes(error.name) ? error.name : 'Error'; - var ErrConstructor = window[errorName] || Error; + var ErrConstructor = window[error.name] || Error; if (error.stack) { msg += '\n' + error.stack.replace(error.message, ''); } @@ -6963,7 +3743,7 @@ 'use strict'; var include, exclude, matching; var defaultExclude = axe._audit && axe._audit.tagExclude ? axe._audit.tagExclude : []; - if (runOnly.hasOwnProperty('include') || runOnly.hasOwnProperty('exclude')) { + if (runOnly.include || runOnly.exclude) { include = runOnly.include || []; include = Array.isArray(include) ? include : [ include ]; exclude = runOnly.exclude || []; @@ -7005,9 +3785,21 @@ } }; 'use strict'; + function getScroll(elm) { + var style = window.getComputedStyle(elm); + var visibleOverflowY = style.getPropertyValue('overflow-y') === 'visible'; + var visibleOverflowX = style.getPropertyValue('overflow-x') === 'visible'; + if (!visibleOverflowY && elm.scrollHeight > elm.clientHeight || !visibleOverflowX && elm.scrollWidth > elm.clientWidth) { + return { + elm: elm, + top: elm.scrollTop, + left: elm.scrollLeft + }; + } + } function setScroll(elm, top, left) { if (elm === window) { - return elm.scroll(left, top); + return elm.scroll(top, left); } else { elm.scrollTop = top; elm.scrollLeft = left; @@ -7015,7 +3807,7 @@ } function getElmScrollRecursive(root) { return Array.from(root.children).reduce(function(scrolls, elm) { - var scroll = axe.utils.getScroll(elm); + var scroll = getScroll(elm); if (scroll) { scrolls.push(scroll); } @@ -7065,77 +3857,33 @@ } return false; } - function pushNode(result, nodes) { + function pushNode(result, nodes, context) { 'use strict'; - var temp; - if (result.length === 0) { - return nodes; - } - if (result.length < nodes.length) { - temp = result; - result = nodes; - nodes = temp; - } for (var i = 0, l = nodes.length; i < l; i++) { - if (!result.includes(nodes[i])) { + if (!result.find(function(item) { + return item.actualNode === nodes[i].actualNode; + }) && isNodeInContext(nodes[i], context)) { result.push(nodes[i]); } } - return result; - } - function reduceIncludes(includes) { - return includes.reduce(function(res, el) { - if (!res.length || !axe.utils.contains(res[res.length - 1], el)) { - res.push(el); - } - return res; - }, []); } axe.utils.select = function select(selector, context) { 'use strict'; - var result = []; - var candidate; - if (axe._selectCache) { - for (var j = 0, l = axe._selectCache.length; j < l; j++) { - var item = axe._selectCache[j]; - if (item.selector === selector) { - return item.result; - } + var result = [], candidate; + for (var i = 0, l = context.include.length; i < l; i++) { + candidate = context.include[i]; + if (candidate.actualNode.nodeType === candidate.actualNode.ELEMENT_NODE && axe.utils.matchesSelector(candidate.actualNode, selector)) { + pushNode(result, [ candidate ], context); } + pushNode(result, axe.utils.querySelectorAll(candidate, selector), context); } - var curried = function(context) { - return function(node) { - return isNodeInContext(node, context); - }; - }(context); - var reducedIncludes = reduceIncludes(context.include); - for (var i = 0; i < reducedIncludes.length; i++) { - candidate = reducedIncludes[i]; - result = pushNode(result, axe.utils.querySelectorAllFilter(candidate, selector, curried)); - } - if (axe._selectCache) { - axe._selectCache.push({ - selector: selector, - result: result - }); - } - return result; + return result.sort(axe.utils.nodeSorter); }; 'use strict'; axe.utils.toArray = function(thing) { 'use strict'; return Array.prototype.slice.call(thing); }; - axe.utils.uniqueArray = function(arr1, arr2) { - return arr1.concat(arr2).filter(function(elem, pos, arr) { - return arr.indexOf(elem) === pos; - }); - }; - 'use strict'; - axe.utils.tokenList = function(str) { - 'use strict'; - return str.trim().replace(/\s{2,}/g, ' ').split(' '); - }; 'use strict'; var uuid; (function(_global) { @@ -7252,62 +4000,6 @@ uuid.BufferClass = BufferClass; })(window); 'use strict'; - axe.utils.validInputTypes = function validInputTypes() { - 'use strict'; - return [ 'hidden', 'text', 'search', 'tel', 'url', 'email', 'password', 'date', 'month', 'week', 'time', 'datetime-local', 'number', 'range', 'color', 'checkbox', 'radio', 'file', 'submit', 'image', 'reset', 'button' ]; - }; - 'use strict'; - var langs = [ 'aa', 'ab', 'ae', 'af', 'ak', 'am', 'an', 'ar', 'as', 'av', 'ay', 'az', 'ba', 'be', 'bg', 'bh', 'bi', 'bm', 'bn', 'bo', 'br', 'bs', 'ca', 'ce', 'ch', 'co', 'cr', 'cs', 'cu', 'cv', 'cy', 'da', 'de', 'dv', 'dz', 'ee', 'el', 'en', 'eo', 'es', 'et', 'eu', 'fa', 'ff', 'fi', 'fj', 'fo', 'fr', 'fy', 'ga', 'gd', 'gl', 'gn', 'gu', 'gv', 'ha', 'he', 'hi', 'ho', 'hr', 'ht', 'hu', 'hy', 'hz', 'ia', 'id', 'ie', 'ig', 'ii', 'ik', 'in', 'io', 'is', 'it', 'iu', 'iw', 'ja', 'ji', 'jv', 'jw', 'ka', 'kg', 'ki', 'kj', 'kk', 'kl', 'km', 'kn', 'ko', 'kr', 'ks', 'ku', 'kv', 'kw', 'ky', 'la', 'lb', 'lg', 'li', 'ln', 'lo', 'lt', 'lu', 'lv', 'mg', 'mh', 'mi', 'mk', 'ml', 'mn', 'mo', 'mr', 'ms', 'mt', 'my', 'na', 'nb', 'nd', 'ne', 'ng', 'nl', 'nn', 'no', 'nr', 'nv', 'ny', 'oc', 'oj', 'om', 'or', 'os', 'pa', 'pi', 'pl', 'ps', 'pt', 'qu', 'rm', 'rn', 'ro', 'ru', 'rw', 'sa', 'sc', 'sd', 'se', 'sg', 'sh', 'si', 'sk', 'sl', 'sm', 'sn', 'so', 'sq', 'sr', 'ss', 'st', 'su', 'sv', 'sw', 'ta', 'te', 'tg', 'th', 'ti', 'tk', 'tl', 'tn', 'to', 'tr', 'ts', 'tt', 'tw', 'ty', 'ug', 'uk', 'ur', 'uz', 've', 'vi', 'vo', 'wa', 'wo', 'xh', 'yi', 'yo', 'za', 'zh', 'zu', 'aaa', 'aab', 'aac', 'aad', 'aae', 'aaf', 'aag', 'aah', 'aai', 'aak', 'aal', 'aam', 'aan', 'aao', 'aap', 'aaq', 'aas', 'aat', 'aau', 'aav', 'aaw', 'aax', 'aaz', 'aba', 'abb', 'abc', 'abd', 'abe', 'abf', 'abg', 'abh', 'abi', 'abj', 'abl', 'abm', 'abn', 'abo', 'abp', 'abq', 'abr', 'abs', 'abt', 'abu', 'abv', 'abw', 'abx', 'aby', 'abz', 'aca', 'acb', 'acd', 'ace', 'acf', 'ach', 'aci', 'ack', 'acl', 'acm', 'acn', 'acp', 'acq', 'acr', 'acs', 'act', 'acu', 'acv', 'acw', 'acx', 'acy', 'acz', 'ada', 'adb', 'add', 'ade', 'adf', 'adg', 'adh', 'adi', 'adj', 'adl', 'adn', 'ado', 'adp', 'adq', 'adr', 'ads', 'adt', 'adu', 'adw', 'adx', 'ady', 'adz', 'aea', 'aeb', 'aec', 'aed', 'aee', 'aek', 'ael', 'aem', 'aen', 'aeq', 'aer', 'aes', 'aeu', 'aew', 'aey', 'aez', 'afa', 'afb', 'afd', 'afe', 'afg', 'afh', 'afi', 'afk', 'afn', 'afo', 'afp', 'afs', 'aft', 'afu', 'afz', 'aga', 'agb', 'agc', 'agd', 'age', 'agf', 'agg', 'agh', 'agi', 'agj', 'agk', 'agl', 'agm', 'agn', 'ago', 'agp', 'agq', 'agr', 'ags', 'agt', 'agu', 'agv', 'agw', 'agx', 'agy', 'agz', 'aha', 'ahb', 'ahg', 'ahh', 'ahi', 'ahk', 'ahl', 'ahm', 'ahn', 'aho', 'ahp', 'ahr', 'ahs', 'aht', 'aia', 'aib', 'aic', 'aid', 'aie', 'aif', 'aig', 'aih', 'aii', 'aij', 'aik', 'ail', 'aim', 'ain', 'aio', 'aip', 'aiq', 'air', 'ais', 'ait', 'aiw', 'aix', 'aiy', 'aja', 'ajg', 'aji', 'ajn', 'ajp', 'ajt', 'aju', 'ajw', 'ajz', 'akb', 'akc', 'akd', 'ake', 'akf', 'akg', 'akh', 'aki', 'akj', 'akk', 'akl', 'akm', 'ako', 'akp', 'akq', 'akr', 'aks', 'akt', 'aku', 'akv', 'akw', 'akx', 'aky', 'akz', 'ala', 'alc', 'ald', 'ale', 'alf', 'alg', 'alh', 'ali', 'alj', 'alk', 'all', 'alm', 'aln', 'alo', 'alp', 'alq', 'alr', 'als', 'alt', 'alu', 'alv', 'alw', 'alx', 'aly', 'alz', 'ama', 'amb', 'amc', 'ame', 'amf', 'amg', 'ami', 'amj', 'amk', 'aml', 'amm', 'amn', 'amo', 'amp', 'amq', 'amr', 'ams', 'amt', 'amu', 'amv', 'amw', 'amx', 'amy', 'amz', 'ana', 'anb', 'anc', 'and', 'ane', 'anf', 'ang', 'anh', 'ani', 'anj', 'ank', 'anl', 'anm', 'ann', 'ano', 'anp', 'anq', 'anr', 'ans', 'ant', 'anu', 'anv', 'anw', 'anx', 'any', 'anz', 'aoa', 'aob', 'aoc', 'aod', 'aoe', 'aof', 'aog', 'aoh', 'aoi', 'aoj', 'aok', 'aol', 'aom', 'aon', 'aor', 'aos', 'aot', 'aou', 'aox', 'aoz', 'apa', 'apb', 'apc', 'apd', 'ape', 'apf', 'apg', 'aph', 'api', 'apj', 'apk', 'apl', 'apm', 'apn', 'apo', 'app', 'apq', 'apr', 'aps', 'apt', 'apu', 'apv', 'apw', 'apx', 'apy', 'apz', 'aqa', 'aqc', 'aqd', 'aqg', 'aql', 'aqm', 'aqn', 'aqp', 'aqr', 'aqt', 'aqz', 'arb', 'arc', 'ard', 'are', 'arh', 'ari', 'arj', 'ark', 'arl', 'arn', 'aro', 'arp', 'arq', 'arr', 'ars', 'art', 'aru', 'arv', 'arw', 'arx', 'ary', 'arz', 'asa', 'asb', 'asc', 'asd', 'ase', 'asf', 'asg', 'ash', 'asi', 'asj', 'ask', 'asl', 'asn', 'aso', 'asp', 'asq', 'asr', 'ass', 'ast', 'asu', 'asv', 'asw', 'asx', 'asy', 'asz', 'ata', 'atb', 'atc', 'atd', 'ate', 'atg', 'ath', 'ati', 'atj', 'atk', 'atl', 'atm', 'atn', 'ato', 'atp', 'atq', 'atr', 'ats', 'att', 'atu', 'atv', 'atw', 'atx', 'aty', 'atz', 'aua', 'aub', 'auc', 'aud', 'aue', 'auf', 'aug', 'auh', 'aui', 'auj', 'auk', 'aul', 'aum', 'aun', 'auo', 'aup', 'auq', 'aur', 'aus', 'aut', 'auu', 'auw', 'aux', 'auy', 'auz', 'avb', 'avd', 'avi', 'avk', 'avl', 'avm', 'avn', 'avo', 'avs', 'avt', 'avu', 'avv', 'awa', 'awb', 'awc', 'awd', 'awe', 'awg', 'awh', 'awi', 'awk', 'awm', 'awn', 'awo', 'awr', 'aws', 'awt', 'awu', 'awv', 'aww', 'awx', 'awy', 'axb', 'axe', 'axg', 'axk', 'axl', 'axm', 'axx', 'aya', 'ayb', 'ayc', 'ayd', 'aye', 'ayg', 'ayh', 'ayi', 'ayk', 'ayl', 'ayn', 'ayo', 'ayp', 'ayq', 'ayr', 'ays', 'ayt', 'ayu', 'ayx', 'ayy', 'ayz', 'aza', 'azb', 'azc', 'azd', 'azg', 'azj', 'azm', 'azn', 'azo', 'azt', 'azz', 'baa', 'bab', 'bac', 'bad', 'bae', 'baf', 'bag', 'bah', 'bai', 'baj', 'bal', 'ban', 'bao', 'bap', 'bar', 'bas', 'bat', 'bau', 'bav', 'baw', 'bax', 'bay', 'baz', 'bba', 'bbb', 'bbc', 'bbd', 'bbe', 'bbf', 'bbg', 'bbh', 'bbi', 'bbj', 'bbk', 'bbl', 'bbm', 'bbn', 'bbo', 'bbp', 'bbq', 'bbr', 'bbs', 'bbt', 'bbu', 'bbv', 'bbw', 'bbx', 'bby', 'bbz', 'bca', 'bcb', 'bcc', 'bcd', 'bce', 'bcf', 'bcg', 'bch', 'bci', 'bcj', 'bck', 'bcl', 'bcm', 'bcn', 'bco', 'bcp', 'bcq', 'bcr', 'bcs', 'bct', 'bcu', 'bcv', 'bcw', 'bcy', 'bcz', 'bda', 'bdb', 'bdc', 'bdd', 'bde', 'bdf', 'bdg', 'bdh', 'bdi', 'bdj', 'bdk', 'bdl', 'bdm', 'bdn', 'bdo', 'bdp', 'bdq', 'bdr', 'bds', 'bdt', 'bdu', 'bdv', 'bdw', 'bdx', 'bdy', 'bdz', 'bea', 'beb', 'bec', 'bed', 'bee', 'bef', 'beg', 'beh', 'bei', 'bej', 'bek', 'bem', 'beo', 'bep', 'beq', 'ber', 'bes', 'bet', 'beu', 'bev', 'bew', 'bex', 'bey', 'bez', 'bfa', 'bfb', 'bfc', 'bfd', 'bfe', 'bff', 'bfg', 'bfh', 'bfi', 'bfj', 'bfk', 'bfl', 'bfm', 'bfn', 'bfo', 'bfp', 'bfq', 'bfr', 'bfs', 'bft', 'bfu', 'bfw', 'bfx', 'bfy', 'bfz', 'bga', 'bgb', 'bgc', 'bgd', 'bge', 'bgf', 'bgg', 'bgi', 'bgj', 'bgk', 'bgl', 'bgm', 'bgn', 'bgo', 'bgp', 'bgq', 'bgr', 'bgs', 'bgt', 'bgu', 'bgv', 'bgw', 'bgx', 'bgy', 'bgz', 'bha', 'bhb', 'bhc', 'bhd', 'bhe', 'bhf', 'bhg', 'bhh', 'bhi', 'bhj', 'bhk', 'bhl', 'bhm', 'bhn', 'bho', 'bhp', 'bhq', 'bhr', 'bhs', 'bht', 'bhu', 'bhv', 'bhw', 'bhx', 'bhy', 'bhz', 'bia', 'bib', 'bic', 'bid', 'bie', 'bif', 'big', 'bij', 'bik', 'bil', 'bim', 'bin', 'bio', 'bip', 'biq', 'bir', 'bit', 'biu', 'biv', 'biw', 'bix', 'biy', 'biz', 'bja', 'bjb', 'bjc', 'bjd', 'bje', 'bjf', 'bjg', 'bjh', 'bji', 'bjj', 'bjk', 'bjl', 'bjm', 'bjn', 'bjo', 'bjp', 'bjq', 'bjr', 'bjs', 'bjt', 'bju', 'bjv', 'bjw', 'bjx', 'bjy', 'bjz', 'bka', 'bkb', 'bkc', 'bkd', 'bkf', 'bkg', 'bkh', 'bki', 'bkj', 'bkk', 'bkl', 'bkm', 'bkn', 'bko', 'bkp', 'bkq', 'bkr', 'bks', 'bkt', 'bku', 'bkv', 'bkw', 'bkx', 'bky', 'bkz', 'bla', 'blb', 'blc', 'bld', 'ble', 'blf', 'blg', 'blh', 'bli', 'blj', 'blk', 'bll', 'blm', 'bln', 'blo', 'blp', 'blq', 'blr', 'bls', 'blt', 'blv', 'blw', 'blx', 'bly', 'blz', 'bma', 'bmb', 'bmc', 'bmd', 'bme', 'bmf', 'bmg', 'bmh', 'bmi', 'bmj', 'bmk', 'bml', 'bmm', 'bmn', 'bmo', 'bmp', 'bmq', 'bmr', 'bms', 'bmt', 'bmu', 'bmv', 'bmw', 'bmx', 'bmy', 'bmz', 'bna', 'bnb', 'bnc', 'bnd', 'bne', 'bnf', 'bng', 'bni', 'bnj', 'bnk', 'bnl', 'bnm', 'bnn', 'bno', 'bnp', 'bnq', 'bnr', 'bns', 'bnt', 'bnu', 'bnv', 'bnw', 'bnx', 'bny', 'bnz', 'boa', 'bob', 'boe', 'bof', 'bog', 'boh', 'boi', 'boj', 'bok', 'bol', 'bom', 'bon', 'boo', 'bop', 'boq', 'bor', 'bot', 'bou', 'bov', 'bow', 'box', 'boy', 'boz', 'bpa', 'bpb', 'bpd', 'bpg', 'bph', 'bpi', 'bpj', 'bpk', 'bpl', 'bpm', 'bpn', 'bpo', 'bpp', 'bpq', 'bpr', 'bps', 'bpt', 'bpu', 'bpv', 'bpw', 'bpx', 'bpy', 'bpz', 'bqa', 'bqb', 'bqc', 'bqd', 'bqf', 'bqg', 'bqh', 'bqi', 'bqj', 'bqk', 'bql', 'bqm', 'bqn', 'bqo', 'bqp', 'bqq', 'bqr', 'bqs', 'bqt', 'bqu', 'bqv', 'bqw', 'bqx', 'bqy', 'bqz', 'bra', 'brb', 'brc', 'brd', 'brf', 'brg', 'brh', 'bri', 'brj', 'brk', 'brl', 'brm', 'brn', 'bro', 'brp', 'brq', 'brr', 'brs', 'brt', 'bru', 'brv', 'brw', 'brx', 'bry', 'brz', 'bsa', 'bsb', 'bsc', 'bse', 'bsf', 'bsg', 'bsh', 'bsi', 'bsj', 'bsk', 'bsl', 'bsm', 'bsn', 'bso', 'bsp', 'bsq', 'bsr', 'bss', 'bst', 'bsu', 'bsv', 'bsw', 'bsx', 'bsy', 'bta', 'btb', 'btc', 'btd', 'bte', 'btf', 'btg', 'bth', 'bti', 'btj', 'btk', 'btl', 'btm', 'btn', 'bto', 'btp', 'btq', 'btr', 'bts', 'btt', 'btu', 'btv', 'btw', 'btx', 'bty', 'btz', 'bua', 'bub', 'buc', 'bud', 'bue', 'buf', 'bug', 'buh', 'bui', 'buj', 'buk', 'bum', 'bun', 'buo', 'bup', 'buq', 'bus', 'but', 'buu', 'buv', 'buw', 'bux', 'buy', 'buz', 'bva', 'bvb', 'bvc', 'bvd', 'bve', 'bvf', 'bvg', 'bvh', 'bvi', 'bvj', 'bvk', 'bvl', 'bvm', 'bvn', 'bvo', 'bvp', 'bvq', 'bvr', 'bvt', 'bvu', 'bvv', 'bvw', 'bvx', 'bvy', 'bvz', 'bwa', 'bwb', 'bwc', 'bwd', 'bwe', 'bwf', 'bwg', 'bwh', 'bwi', 'bwj', 'bwk', 'bwl', 'bwm', 'bwn', 'bwo', 'bwp', 'bwq', 'bwr', 'bws', 'bwt', 'bwu', 'bww', 'bwx', 'bwy', 'bwz', 'bxa', 'bxb', 'bxc', 'bxd', 'bxe', 'bxf', 'bxg', 'bxh', 'bxi', 'bxj', 'bxk', 'bxl', 'bxm', 'bxn', 'bxo', 'bxp', 'bxq', 'bxr', 'bxs', 'bxu', 'bxv', 'bxw', 'bxx', 'bxz', 'bya', 'byb', 'byc', 'byd', 'bye', 'byf', 'byg', 'byh', 'byi', 'byj', 'byk', 'byl', 'bym', 'byn', 'byo', 'byp', 'byq', 'byr', 'bys', 'byt', 'byv', 'byw', 'byx', 'byy', 'byz', 'bza', 'bzb', 'bzc', 'bzd', 'bze', 'bzf', 'bzg', 'bzh', 'bzi', 'bzj', 'bzk', 'bzl', 'bzm', 'bzn', 'bzo', 'bzp', 'bzq', 'bzr', 'bzs', 'bzt', 'bzu', 'bzv', 'bzw', 'bzx', 'bzy', 'bzz', 'caa', 'cab', 'cac', 'cad', 'cae', 'caf', 'cag', 'cah', 'cai', 'caj', 'cak', 'cal', 'cam', 'can', 'cao', 'cap', 'caq', 'car', 'cas', 'cau', 'cav', 'caw', 'cax', 'cay', 'caz', 'cba', 'cbb', 'cbc', 'cbd', 'cbe', 'cbg', 'cbh', 'cbi', 'cbj', 'cbk', 'cbl', 'cbn', 'cbo', 'cbq', 'cbr', 'cbs', 'cbt', 'cbu', 'cbv', 'cbw', 'cby', 'cca', 'ccc', 'ccd', 'cce', 'ccg', 'cch', 'ccj', 'ccl', 'ccm', 'ccn', 'cco', 'ccp', 'ccq', 'ccr', 'ccs', 'cda', 'cdc', 'cdd', 'cde', 'cdf', 'cdg', 'cdh', 'cdi', 'cdj', 'cdm', 'cdn', 'cdo', 'cdr', 'cds', 'cdy', 'cdz', 'cea', 'ceb', 'ceg', 'cek', 'cel', 'cen', 'cet', 'cfa', 'cfd', 'cfg', 'cfm', 'cga', 'cgc', 'cgg', 'cgk', 'chb', 'chc', 'chd', 'chf', 'chg', 'chh', 'chj', 'chk', 'chl', 'chm', 'chn', 'cho', 'chp', 'chq', 'chr', 'cht', 'chw', 'chx', 'chy', 'chz', 'cia', 'cib', 'cic', 'cid', 'cie', 'cih', 'cik', 'cim', 'cin', 'cip', 'cir', 'ciw', 'ciy', 'cja', 'cje', 'cjh', 'cji', 'cjk', 'cjm', 'cjn', 'cjo', 'cjp', 'cjr', 'cjs', 'cjv', 'cjy', 'cka', 'ckb', 'ckh', 'ckl', 'ckn', 'cko', 'ckq', 'ckr', 'cks', 'ckt', 'cku', 'ckv', 'ckx', 'cky', 'ckz', 'cla', 'clc', 'cld', 'cle', 'clh', 'cli', 'clj', 'clk', 'cll', 'clm', 'clo', 'clt', 'clu', 'clw', 'cly', 'cma', 'cmc', 'cme', 'cmg', 'cmi', 'cmk', 'cml', 'cmm', 'cmn', 'cmo', 'cmr', 'cms', 'cmt', 'cna', 'cnb', 'cnc', 'cng', 'cnh', 'cni', 'cnk', 'cnl', 'cno', 'cnr', 'cns', 'cnt', 'cnu', 'cnw', 'cnx', 'coa', 'cob', 'coc', 'cod', 'coe', 'cof', 'cog', 'coh', 'coj', 'cok', 'col', 'com', 'con', 'coo', 'cop', 'coq', 'cot', 'cou', 'cov', 'cow', 'cox', 'coy', 'coz', 'cpa', 'cpb', 'cpc', 'cpe', 'cpf', 'cpg', 'cpi', 'cpn', 'cpo', 'cpp', 'cps', 'cpu', 'cpx', 'cpy', 'cqd', 'cqu', 'cra', 'crb', 'crc', 'crd', 'crf', 'crg', 'crh', 'cri', 'crj', 'crk', 'crl', 'crm', 'crn', 'cro', 'crp', 'crq', 'crr', 'crs', 'crt', 'crv', 'crw', 'crx', 'cry', 'crz', 'csa', 'csb', 'csc', 'csd', 'cse', 'csf', 'csg', 'csh', 'csi', 'csj', 'csk', 'csl', 'csm', 'csn', 'cso', 'csq', 'csr', 'css', 'cst', 'csu', 'csv', 'csw', 'csy', 'csz', 'cta', 'ctc', 'ctd', 'cte', 'ctg', 'cth', 'ctl', 'ctm', 'ctn', 'cto', 'ctp', 'cts', 'ctt', 'ctu', 'ctz', 'cua', 'cub', 'cuc', 'cug', 'cuh', 'cui', 'cuj', 'cuk', 'cul', 'cum', 'cuo', 'cup', 'cuq', 'cur', 'cus', 'cut', 'cuu', 'cuv', 'cuw', 'cux', 'cuy', 'cvg', 'cvn', 'cwa', 'cwb', 'cwd', 'cwe', 'cwg', 'cwt', 'cya', 'cyb', 'cyo', 'czh', 'czk', 'czn', 'czo', 'czt', 'daa', 'dac', 'dad', 'dae', 'daf', 'dag', 'dah', 'dai', 'daj', 'dak', 'dal', 'dam', 'dao', 'dap', 'daq', 'dar', 'das', 'dau', 'dav', 'daw', 'dax', 'day', 'daz', 'dba', 'dbb', 'dbd', 'dbe', 'dbf', 'dbg', 'dbi', 'dbj', 'dbl', 'dbm', 'dbn', 'dbo', 'dbp', 'dbq', 'dbr', 'dbt', 'dbu', 'dbv', 'dbw', 'dby', 'dcc', 'dcr', 'dda', 'ddd', 'dde', 'ddg', 'ddi', 'ddj', 'ddn', 'ddo', 'ddr', 'dds', 'ddw', 'dec', 'ded', 'dee', 'def', 'deg', 'deh', 'dei', 'dek', 'del', 'dem', 'den', 'dep', 'deq', 'der', 'des', 'dev', 'dez', 'dga', 'dgb', 'dgc', 'dgd', 'dge', 'dgg', 'dgh', 'dgi', 'dgk', 'dgl', 'dgn', 'dgo', 'dgr', 'dgs', 'dgt', 'dgu', 'dgw', 'dgx', 'dgz', 'dha', 'dhd', 'dhg', 'dhi', 'dhl', 'dhm', 'dhn', 'dho', 'dhr', 'dhs', 'dhu', 'dhv', 'dhw', 'dhx', 'dia', 'dib', 'dic', 'did', 'dif', 'dig', 'dih', 'dii', 'dij', 'dik', 'dil', 'dim', 'din', 'dio', 'dip', 'diq', 'dir', 'dis', 'dit', 'diu', 'diw', 'dix', 'diy', 'diz', 'dja', 'djb', 'djc', 'djd', 'dje', 'djf', 'dji', 'djj', 'djk', 'djl', 'djm', 'djn', 'djo', 'djr', 'dju', 'djw', 'dka', 'dkk', 'dkl', 'dkr', 'dks', 'dkx', 'dlg', 'dlk', 'dlm', 'dln', 'dma', 'dmb', 'dmc', 'dmd', 'dme', 'dmg', 'dmk', 'dml', 'dmm', 'dmn', 'dmo', 'dmr', 'dms', 'dmu', 'dmv', 'dmw', 'dmx', 'dmy', 'dna', 'dnd', 'dne', 'dng', 'dni', 'dnj', 'dnk', 'dnn', 'dnr', 'dnt', 'dnu', 'dnv', 'dnw', 'dny', 'doa', 'dob', 'doc', 'doe', 'dof', 'doh', 'doi', 'dok', 'dol', 'don', 'doo', 'dop', 'doq', 'dor', 'dos', 'dot', 'dov', 'dow', 'dox', 'doy', 'doz', 'dpp', 'dra', 'drb', 'drc', 'drd', 'dre', 'drg', 'drh', 'dri', 'drl', 'drn', 'dro', 'drq', 'drr', 'drs', 'drt', 'dru', 'drw', 'dry', 'dsb', 'dse', 'dsh', 'dsi', 'dsl', 'dsn', 'dso', 'dsq', 'dta', 'dtb', 'dtd', 'dth', 'dti', 'dtk', 'dtm', 'dtn', 'dto', 'dtp', 'dtr', 'dts', 'dtt', 'dtu', 'dty', 'dua', 'dub', 'duc', 'dud', 'due', 'duf', 'dug', 'duh', 'dui', 'duj', 'duk', 'dul', 'dum', 'dun', 'duo', 'dup', 'duq', 'dur', 'dus', 'duu', 'duv', 'duw', 'dux', 'duy', 'duz', 'dva', 'dwa', 'dwl', 'dwr', 'dws', 'dwu', 'dww', 'dwy', 'dya', 'dyb', 'dyd', 'dyg', 'dyi', 'dym', 'dyn', 'dyo', 'dyu', 'dyy', 'dza', 'dzd', 'dze', 'dzg', 'dzl', 'dzn', 'eaa', 'ebg', 'ebk', 'ebo', 'ebr', 'ebu', 'ecr', 'ecs', 'ecy', 'eee', 'efa', 'efe', 'efi', 'ega', 'egl', 'ego', 'egx', 'egy', 'ehu', 'eip', 'eit', 'eiv', 'eja', 'eka', 'ekc', 'eke', 'ekg', 'eki', 'ekk', 'ekl', 'ekm', 'eko', 'ekp', 'ekr', 'eky', 'ele', 'elh', 'eli', 'elk', 'elm', 'elo', 'elp', 'elu', 'elx', 'ema', 'emb', 'eme', 'emg', 'emi', 'emk', 'emm', 'emn', 'emo', 'emp', 'ems', 'emu', 'emw', 'emx', 'emy', 'ena', 'enb', 'enc', 'end', 'enf', 'enh', 'enl', 'enm', 'enn', 'eno', 'enq', 'enr', 'enu', 'env', 'enw', 'enx', 'eot', 'epi', 'era', 'erg', 'erh', 'eri', 'erk', 'ero', 'err', 'ers', 'ert', 'erw', 'ese', 'esg', 'esh', 'esi', 'esk', 'esl', 'esm', 'esn', 'eso', 'esq', 'ess', 'esu', 'esx', 'esy', 'etb', 'etc', 'eth', 'etn', 'eto', 'etr', 'ets', 'ett', 'etu', 'etx', 'etz', 'euq', 'eve', 'evh', 'evn', 'ewo', 'ext', 'eya', 'eyo', 'eza', 'eze', 'faa', 'fab', 'fad', 'faf', 'fag', 'fah', 'fai', 'faj', 'fak', 'fal', 'fam', 'fan', 'fap', 'far', 'fat', 'fau', 'fax', 'fay', 'faz', 'fbl', 'fcs', 'fer', 'ffi', 'ffm', 'fgr', 'fia', 'fie', 'fil', 'fip', 'fir', 'fit', 'fiu', 'fiw', 'fkk', 'fkv', 'fla', 'flh', 'fli', 'fll', 'fln', 'flr', 'fly', 'fmp', 'fmu', 'fnb', 'fng', 'fni', 'fod', 'foi', 'fom', 'fon', 'for', 'fos', 'fox', 'fpe', 'fqs', 'frc', 'frd', 'frk', 'frm', 'fro', 'frp', 'frq', 'frr', 'frs', 'frt', 'fse', 'fsl', 'fss', 'fub', 'fuc', 'fud', 'fue', 'fuf', 'fuh', 'fui', 'fuj', 'fum', 'fun', 'fuq', 'fur', 'fut', 'fuu', 'fuv', 'fuy', 'fvr', 'fwa', 'fwe', 'gaa', 'gab', 'gac', 'gad', 'gae', 'gaf', 'gag', 'gah', 'gai', 'gaj', 'gak', 'gal', 'gam', 'gan', 'gao', 'gap', 'gaq', 'gar', 'gas', 'gat', 'gau', 'gav', 'gaw', 'gax', 'gay', 'gaz', 'gba', 'gbb', 'gbc', 'gbd', 'gbe', 'gbf', 'gbg', 'gbh', 'gbi', 'gbj', 'gbk', 'gbl', 'gbm', 'gbn', 'gbo', 'gbp', 'gbq', 'gbr', 'gbs', 'gbu', 'gbv', 'gbw', 'gbx', 'gby', 'gbz', 'gcc', 'gcd', 'gce', 'gcf', 'gcl', 'gcn', 'gcr', 'gct', 'gda', 'gdb', 'gdc', 'gdd', 'gde', 'gdf', 'gdg', 'gdh', 'gdi', 'gdj', 'gdk', 'gdl', 'gdm', 'gdn', 'gdo', 'gdq', 'gdr', 'gds', 'gdt', 'gdu', 'gdx', 'gea', 'geb', 'gec', 'ged', 'geg', 'geh', 'gei', 'gej', 'gek', 'gel', 'gem', 'geq', 'ges', 'gev', 'gew', 'gex', 'gey', 'gez', 'gfk', 'gft', 'gfx', 'gga', 'ggb', 'ggd', 'gge', 'ggg', 'ggk', 'ggl', 'ggn', 'ggo', 'ggr', 'ggt', 'ggu', 'ggw', 'gha', 'ghc', 'ghe', 'ghh', 'ghk', 'ghl', 'ghn', 'gho', 'ghr', 'ghs', 'ght', 'gia', 'gib', 'gic', 'gid', 'gie', 'gig', 'gih', 'gil', 'gim', 'gin', 'gio', 'gip', 'giq', 'gir', 'gis', 'git', 'giu', 'giw', 'gix', 'giy', 'giz', 'gji', 'gjk', 'gjm', 'gjn', 'gjr', 'gju', 'gka', 'gkd', 'gke', 'gkn', 'gko', 'gkp', 'gku', 'glc', 'gld', 'glh', 'gli', 'glj', 'glk', 'gll', 'glo', 'glr', 'glu', 'glw', 'gly', 'gma', 'gmb', 'gmd', 'gme', 'gmg', 'gmh', 'gml', 'gmm', 'gmn', 'gmq', 'gmu', 'gmv', 'gmw', 'gmx', 'gmy', 'gmz', 'gna', 'gnb', 'gnc', 'gnd', 'gne', 'gng', 'gnh', 'gni', 'gnj', 'gnk', 'gnl', 'gnm', 'gnn', 'gno', 'gnq', 'gnr', 'gnt', 'gnu', 'gnw', 'gnz', 'goa', 'gob', 'goc', 'god', 'goe', 'gof', 'gog', 'goh', 'goi', 'goj', 'gok', 'gol', 'gom', 'gon', 'goo', 'gop', 'goq', 'gor', 'gos', 'got', 'gou', 'gow', 'gox', 'goy', 'goz', 'gpa', 'gpe', 'gpn', 'gqa', 'gqi', 'gqn', 'gqr', 'gqu', 'gra', 'grb', 'grc', 'grd', 'grg', 'grh', 'gri', 'grj', 'grk', 'grm', 'gro', 'grq', 'grr', 'grs', 'grt', 'gru', 'grv', 'grw', 'grx', 'gry', 'grz', 'gse', 'gsg', 'gsl', 'gsm', 'gsn', 'gso', 'gsp', 'gss', 'gsw', 'gta', 'gti', 'gtu', 'gua', 'gub', 'guc', 'gud', 'gue', 'guf', 'gug', 'guh', 'gui', 'guk', 'gul', 'gum', 'gun', 'guo', 'gup', 'guq', 'gur', 'gus', 'gut', 'guu', 'guv', 'guw', 'gux', 'guz', 'gva', 'gvc', 'gve', 'gvf', 'gvj', 'gvl', 'gvm', 'gvn', 'gvo', 'gvp', 'gvr', 'gvs', 'gvy', 'gwa', 'gwb', 'gwc', 'gwd', 'gwe', 'gwf', 'gwg', 'gwi', 'gwj', 'gwm', 'gwn', 'gwr', 'gwt', 'gwu', 'gww', 'gwx', 'gxx', 'gya', 'gyb', 'gyd', 'gye', 'gyf', 'gyg', 'gyi', 'gyl', 'gym', 'gyn', 'gyo', 'gyr', 'gyy', 'gza', 'gzi', 'gzn', 'haa', 'hab', 'hac', 'had', 'hae', 'haf', 'hag', 'hah', 'hai', 'haj', 'hak', 'hal', 'ham', 'han', 'hao', 'hap', 'haq', 'har', 'has', 'hav', 'haw', 'hax', 'hay', 'haz', 'hba', 'hbb', 'hbn', 'hbo', 'hbu', 'hca', 'hch', 'hdn', 'hds', 'hdy', 'hea', 'hed', 'heg', 'heh', 'hei', 'hem', 'hgm', 'hgw', 'hhi', 'hhr', 'hhy', 'hia', 'hib', 'hid', 'hif', 'hig', 'hih', 'hii', 'hij', 'hik', 'hil', 'him', 'hio', 'hir', 'hit', 'hiw', 'hix', 'hji', 'hka', 'hke', 'hkk', 'hkn', 'hks', 'hla', 'hlb', 'hld', 'hle', 'hlt', 'hlu', 'hma', 'hmb', 'hmc', 'hmd', 'hme', 'hmf', 'hmg', 'hmh', 'hmi', 'hmj', 'hmk', 'hml', 'hmm', 'hmn', 'hmp', 'hmq', 'hmr', 'hms', 'hmt', 'hmu', 'hmv', 'hmw', 'hmx', 'hmy', 'hmz', 'hna', 'hnd', 'hne', 'hnh', 'hni', 'hnj', 'hnn', 'hno', 'hns', 'hnu', 'hoa', 'hob', 'hoc', 'hod', 'hoe', 'hoh', 'hoi', 'hoj', 'hok', 'hol', 'hom', 'hoo', 'hop', 'hor', 'hos', 'hot', 'hov', 'how', 'hoy', 'hoz', 'hpo', 'hps', 'hra', 'hrc', 'hre', 'hrk', 'hrm', 'hro', 'hrp', 'hrr', 'hrt', 'hru', 'hrw', 'hrx', 'hrz', 'hsb', 'hsh', 'hsl', 'hsn', 'hss', 'hti', 'hto', 'hts', 'htu', 'htx', 'hub', 'huc', 'hud', 'hue', 'huf', 'hug', 'huh', 'hui', 'huj', 'huk', 'hul', 'hum', 'huo', 'hup', 'huq', 'hur', 'hus', 'hut', 'huu', 'huv', 'huw', 'hux', 'huy', 'huz', 'hvc', 'hve', 'hvk', 'hvn', 'hvv', 'hwa', 'hwc', 'hwo', 'hya', 'hyw', 'hyx', 'iai', 'ian', 'iap', 'iar', 'iba', 'ibb', 'ibd', 'ibe', 'ibg', 'ibh', 'ibi', 'ibl', 'ibm', 'ibn', 'ibr', 'ibu', 'iby', 'ica', 'ich', 'icl', 'icr', 'ida', 'idb', 'idc', 'idd', 'ide', 'idi', 'idr', 'ids', 'idt', 'idu', 'ifa', 'ifb', 'ife', 'iff', 'ifk', 'ifm', 'ifu', 'ify', 'igb', 'ige', 'igg', 'igl', 'igm', 'ign', 'igo', 'igs', 'igw', 'ihb', 'ihi', 'ihp', 'ihw', 'iin', 'iir', 'ijc', 'ije', 'ijj', 'ijn', 'ijo', 'ijs', 'ike', 'iki', 'ikk', 'ikl', 'iko', 'ikp', 'ikr', 'iks', 'ikt', 'ikv', 'ikw', 'ikx', 'ikz', 'ila', 'ilb', 'ilg', 'ili', 'ilk', 'ill', 'ilm', 'ilo', 'ilp', 'ils', 'ilu', 'ilv', 'ilw', 'ima', 'ime', 'imi', 'iml', 'imn', 'imo', 'imr', 'ims', 'imy', 'inb', 'inc', 'ine', 'ing', 'inh', 'inj', 'inl', 'inm', 'inn', 'ino', 'inp', 'ins', 'int', 'inz', 'ior', 'iou', 'iow', 'ipi', 'ipo', 'iqu', 'iqw', 'ira', 'ire', 'irh', 'iri', 'irk', 'irn', 'iro', 'irr', 'iru', 'irx', 'iry', 'isa', 'isc', 'isd', 'ise', 'isg', 'ish', 'isi', 'isk', 'ism', 'isn', 'iso', 'isr', 'ist', 'isu', 'itb', 'itc', 'itd', 'ite', 'iti', 'itk', 'itl', 'itm', 'ito', 'itr', 'its', 'itt', 'itv', 'itw', 'itx', 'ity', 'itz', 'ium', 'ivb', 'ivv', 'iwk', 'iwm', 'iwo', 'iws', 'ixc', 'ixl', 'iya', 'iyo', 'iyx', 'izh', 'izi', 'izr', 'izz', 'jaa', 'jab', 'jac', 'jad', 'jae', 'jaf', 'jah', 'jaj', 'jak', 'jal', 'jam', 'jan', 'jao', 'jaq', 'jar', 'jas', 'jat', 'jau', 'jax', 'jay', 'jaz', 'jbe', 'jbi', 'jbj', 'jbk', 'jbn', 'jbo', 'jbr', 'jbt', 'jbu', 'jbw', 'jcs', 'jct', 'jda', 'jdg', 'jdt', 'jeb', 'jee', 'jeg', 'jeh', 'jei', 'jek', 'jel', 'jen', 'jer', 'jet', 'jeu', 'jgb', 'jge', 'jgk', 'jgo', 'jhi', 'jhs', 'jia', 'jib', 'jic', 'jid', 'jie', 'jig', 'jih', 'jii', 'jil', 'jim', 'jio', 'jiq', 'jit', 'jiu', 'jiv', 'jiy', 'jje', 'jjr', 'jka', 'jkm', 'jko', 'jkp', 'jkr', 'jku', 'jle', 'jls', 'jma', 'jmb', 'jmc', 'jmd', 'jmi', 'jml', 'jmn', 'jmr', 'jms', 'jmw', 'jmx', 'jna', 'jnd', 'jng', 'jni', 'jnj', 'jnl', 'jns', 'job', 'jod', 'jog', 'jor', 'jos', 'jow', 'jpa', 'jpr', 'jpx', 'jqr', 'jra', 'jrb', 'jrr', 'jrt', 'jru', 'jsl', 'jua', 'jub', 'juc', 'jud', 'juh', 'jui', 'juk', 'jul', 'jum', 'jun', 'juo', 'jup', 'jur', 'jus', 'jut', 'juu', 'juw', 'juy', 'jvd', 'jvn', 'jwi', 'jya', 'jye', 'jyy', 'kaa', 'kab', 'kac', 'kad', 'kae', 'kaf', 'kag', 'kah', 'kai', 'kaj', 'kak', 'kam', 'kao', 'kap', 'kaq', 'kar', 'kav', 'kaw', 'kax', 'kay', 'kba', 'kbb', 'kbc', 'kbd', 'kbe', 'kbf', 'kbg', 'kbh', 'kbi', 'kbj', 'kbk', 'kbl', 'kbm', 'kbn', 'kbo', 'kbp', 'kbq', 'kbr', 'kbs', 'kbt', 'kbu', 'kbv', 'kbw', 'kbx', 'kby', 'kbz', 'kca', 'kcb', 'kcc', 'kcd', 'kce', 'kcf', 'kcg', 'kch', 'kci', 'kcj', 'kck', 'kcl', 'kcm', 'kcn', 'kco', 'kcp', 'kcq', 'kcr', 'kcs', 'kct', 'kcu', 'kcv', 'kcw', 'kcx', 'kcy', 'kcz', 'kda', 'kdc', 'kdd', 'kde', 'kdf', 'kdg', 'kdh', 'kdi', 'kdj', 'kdk', 'kdl', 'kdm', 'kdn', 'kdo', 'kdp', 'kdq', 'kdr', 'kdt', 'kdu', 'kdv', 'kdw', 'kdx', 'kdy', 'kdz', 'kea', 'keb', 'kec', 'ked', 'kee', 'kef', 'keg', 'keh', 'kei', 'kej', 'kek', 'kel', 'kem', 'ken', 'keo', 'kep', 'keq', 'ker', 'kes', 'ket', 'keu', 'kev', 'kew', 'kex', 'key', 'kez', 'kfa', 'kfb', 'kfc', 'kfd', 'kfe', 'kff', 'kfg', 'kfh', 'kfi', 'kfj', 'kfk', 'kfl', 'kfm', 'kfn', 'kfo', 'kfp', 'kfq', 'kfr', 'kfs', 'kft', 'kfu', 'kfv', 'kfw', 'kfx', 'kfy', 'kfz', 'kga', 'kgb', 'kgc', 'kgd', 'kge', 'kgf', 'kgg', 'kgh', 'kgi', 'kgj', 'kgk', 'kgl', 'kgm', 'kgn', 'kgo', 'kgp', 'kgq', 'kgr', 'kgs', 'kgt', 'kgu', 'kgv', 'kgw', 'kgx', 'kgy', 'kha', 'khb', 'khc', 'khd', 'khe', 'khf', 'khg', 'khh', 'khi', 'khj', 'khk', 'khl', 'khn', 'kho', 'khp', 'khq', 'khr', 'khs', 'kht', 'khu', 'khv', 'khw', 'khx', 'khy', 'khz', 'kia', 'kib', 'kic', 'kid', 'kie', 'kif', 'kig', 'kih', 'kii', 'kij', 'kil', 'kim', 'kio', 'kip', 'kiq', 'kis', 'kit', 'kiu', 'kiv', 'kiw', 'kix', 'kiy', 'kiz', 'kja', 'kjb', 'kjc', 'kjd', 'kje', 'kjf', 'kjg', 'kjh', 'kji', 'kjj', 'kjk', 'kjl', 'kjm', 'kjn', 'kjo', 'kjp', 'kjq', 'kjr', 'kjs', 'kjt', 'kju', 'kjv', 'kjx', 'kjy', 'kjz', 'kka', 'kkb', 'kkc', 'kkd', 'kke', 'kkf', 'kkg', 'kkh', 'kki', 'kkj', 'kkk', 'kkl', 'kkm', 'kkn', 'kko', 'kkp', 'kkq', 'kkr', 'kks', 'kkt', 'kku', 'kkv', 'kkw', 'kkx', 'kky', 'kkz', 'kla', 'klb', 'klc', 'kld', 'kle', 'klf', 'klg', 'klh', 'kli', 'klj', 'klk', 'kll', 'klm', 'kln', 'klo', 'klp', 'klq', 'klr', 'kls', 'klt', 'klu', 'klv', 'klw', 'klx', 'kly', 'klz', 'kma', 'kmb', 'kmc', 'kmd', 'kme', 'kmf', 'kmg', 'kmh', 'kmi', 'kmj', 'kmk', 'kml', 'kmm', 'kmn', 'kmo', 'kmp', 'kmq', 'kmr', 'kms', 'kmt', 'kmu', 'kmv', 'kmw', 'kmx', 'kmy', 'kmz', 'kna', 'knb', 'knc', 'knd', 'kne', 'knf', 'kng', 'kni', 'knj', 'knk', 'knl', 'knm', 'knn', 'kno', 'knp', 'knq', 'knr', 'kns', 'knt', 'knu', 'knv', 'knw', 'knx', 'kny', 'knz', 'koa', 'koc', 'kod', 'koe', 'kof', 'kog', 'koh', 'koi', 'koj', 'kok', 'kol', 'koo', 'kop', 'koq', 'kos', 'kot', 'kou', 'kov', 'kow', 'kox', 'koy', 'koz', 'kpa', 'kpb', 'kpc', 'kpd', 'kpe', 'kpf', 'kpg', 'kph', 'kpi', 'kpj', 'kpk', 'kpl', 'kpm', 'kpn', 'kpo', 'kpp', 'kpq', 'kpr', 'kps', 'kpt', 'kpu', 'kpv', 'kpw', 'kpx', 'kpy', 'kpz', 'kqa', 'kqb', 'kqc', 'kqd', 'kqe', 'kqf', 'kqg', 'kqh', 'kqi', 'kqj', 'kqk', 'kql', 'kqm', 'kqn', 'kqo', 'kqp', 'kqq', 'kqr', 'kqs', 'kqt', 'kqu', 'kqv', 'kqw', 'kqx', 'kqy', 'kqz', 'kra', 'krb', 'krc', 'krd', 'kre', 'krf', 'krh', 'kri', 'krj', 'krk', 'krl', 'krm', 'krn', 'kro', 'krp', 'krr', 'krs', 'krt', 'kru', 'krv', 'krw', 'krx', 'kry', 'krz', 'ksa', 'ksb', 'ksc', 'ksd', 'kse', 'ksf', 'ksg', 'ksh', 'ksi', 'ksj', 'ksk', 'ksl', 'ksm', 'ksn', 'kso', 'ksp', 'ksq', 'ksr', 'kss', 'kst', 'ksu', 'ksv', 'ksw', 'ksx', 'ksy', 'ksz', 'kta', 'ktb', 'ktc', 'ktd', 'kte', 'ktf', 'ktg', 'kth', 'kti', 'ktj', 'ktk', 'ktl', 'ktm', 'ktn', 'kto', 'ktp', 'ktq', 'ktr', 'kts', 'ktt', 'ktu', 'ktv', 'ktw', 'ktx', 'kty', 'ktz', 'kub', 'kuc', 'kud', 'kue', 'kuf', 'kug', 'kuh', 'kui', 'kuj', 'kuk', 'kul', 'kum', 'kun', 'kuo', 'kup', 'kuq', 'kus', 'kut', 'kuu', 'kuv', 'kuw', 'kux', 'kuy', 'kuz', 'kva', 'kvb', 'kvc', 'kvd', 'kve', 'kvf', 'kvg', 'kvh', 'kvi', 'kvj', 'kvk', 'kvl', 'kvm', 'kvn', 'kvo', 'kvp', 'kvq', 'kvr', 'kvs', 'kvt', 'kvu', 'kvv', 'kvw', 'kvx', 'kvy', 'kvz', 'kwa', 'kwb', 'kwc', 'kwd', 'kwe', 'kwf', 'kwg', 'kwh', 'kwi', 'kwj', 'kwk', 'kwl', 'kwm', 'kwn', 'kwo', 'kwp', 'kwq', 'kwr', 'kws', 'kwt', 'kwu', 'kwv', 'kww', 'kwx', 'kwy', 'kwz', 'kxa', 'kxb', 'kxc', 'kxd', 'kxe', 'kxf', 'kxh', 'kxi', 'kxj', 'kxk', 'kxl', 'kxm', 'kxn', 'kxo', 'kxp', 'kxq', 'kxr', 'kxs', 'kxt', 'kxu', 'kxv', 'kxw', 'kxx', 'kxy', 'kxz', 'kya', 'kyb', 'kyc', 'kyd', 'kye', 'kyf', 'kyg', 'kyh', 'kyi', 'kyj', 'kyk', 'kyl', 'kym', 'kyn', 'kyo', 'kyp', 'kyq', 'kyr', 'kys', 'kyt', 'kyu', 'kyv', 'kyw', 'kyx', 'kyy', 'kyz', 'kza', 'kzb', 'kzc', 'kzd', 'kze', 'kzf', 'kzg', 'kzh', 'kzi', 'kzj', 'kzk', 'kzl', 'kzm', 'kzn', 'kzo', 'kzp', 'kzq', 'kzr', 'kzs', 'kzt', 'kzu', 'kzv', 'kzw', 'kzx', 'kzy', 'kzz', 'laa', 'lab', 'lac', 'lad', 'lae', 'laf', 'lag', 'lah', 'lai', 'laj', 'lak', 'lal', 'lam', 'lan', 'lap', 'laq', 'lar', 'las', 'lau', 'law', 'lax', 'lay', 'laz', 'lba', 'lbb', 'lbc', 'lbe', 'lbf', 'lbg', 'lbi', 'lbj', 'lbk', 'lbl', 'lbm', 'lbn', 'lbo', 'lbq', 'lbr', 'lbs', 'lbt', 'lbu', 'lbv', 'lbw', 'lbx', 'lby', 'lbz', 'lcc', 'lcd', 'lce', 'lcf', 'lch', 'lcl', 'lcm', 'lcp', 'lcq', 'lcs', 'lda', 'ldb', 'ldd', 'ldg', 'ldh', 'ldi', 'ldj', 'ldk', 'ldl', 'ldm', 'ldn', 'ldo', 'ldp', 'ldq', 'lea', 'leb', 'lec', 'led', 'lee', 'lef', 'leg', 'leh', 'lei', 'lej', 'lek', 'lel', 'lem', 'len', 'leo', 'lep', 'leq', 'ler', 'les', 'let', 'leu', 'lev', 'lew', 'lex', 'ley', 'lez', 'lfa', 'lfn', 'lga', 'lgb', 'lgg', 'lgh', 'lgi', 'lgk', 'lgl', 'lgm', 'lgn', 'lgq', 'lgr', 'lgt', 'lgu', 'lgz', 'lha', 'lhh', 'lhi', 'lhl', 'lhm', 'lhn', 'lhp', 'lhs', 'lht', 'lhu', 'lia', 'lib', 'lic', 'lid', 'lie', 'lif', 'lig', 'lih', 'lii', 'lij', 'lik', 'lil', 'lio', 'lip', 'liq', 'lir', 'lis', 'liu', 'liv', 'liw', 'lix', 'liy', 'liz', 'lja', 'lje', 'lji', 'ljl', 'ljp', 'ljw', 'ljx', 'lka', 'lkb', 'lkc', 'lkd', 'lke', 'lkh', 'lki', 'lkj', 'lkl', 'lkm', 'lkn', 'lko', 'lkr', 'lks', 'lkt', 'lku', 'lky', 'lla', 'llb', 'llc', 'lld', 'lle', 'llf', 'llg', 'llh', 'lli', 'llj', 'llk', 'lll', 'llm', 'lln', 'llo', 'llp', 'llq', 'lls', 'llu', 'llx', 'lma', 'lmb', 'lmc', 'lmd', 'lme', 'lmf', 'lmg', 'lmh', 'lmi', 'lmj', 'lmk', 'lml', 'lmm', 'lmn', 'lmo', 'lmp', 'lmq', 'lmr', 'lmu', 'lmv', 'lmw', 'lmx', 'lmy', 'lmz', 'lna', 'lnb', 'lnd', 'lng', 'lnh', 'lni', 'lnj', 'lnl', 'lnm', 'lnn', 'lno', 'lns', 'lnu', 'lnw', 'lnz', 'loa', 'lob', 'loc', 'loe', 'lof', 'log', 'loh', 'loi', 'loj', 'lok', 'lol', 'lom', 'lon', 'loo', 'lop', 'loq', 'lor', 'los', 'lot', 'lou', 'lov', 'low', 'lox', 'loy', 'loz', 'lpa', 'lpe', 'lpn', 'lpo', 'lpx', 'lra', 'lrc', 'lre', 'lrg', 'lri', 'lrk', 'lrl', 'lrm', 'lrn', 'lro', 'lrr', 'lrt', 'lrv', 'lrz', 'lsa', 'lsd', 'lse', 'lsg', 'lsh', 'lsi', 'lsl', 'lsm', 'lso', 'lsp', 'lsr', 'lss', 'lst', 'lsy', 'ltc', 'ltg', 'lth', 'lti', 'ltn', 'lto', 'lts', 'ltu', 'lua', 'luc', 'lud', 'lue', 'luf', 'lui', 'luj', 'luk', 'lul', 'lum', 'lun', 'luo', 'lup', 'luq', 'lur', 'lus', 'lut', 'luu', 'luv', 'luw', 'luy', 'luz', 'lva', 'lvk', 'lvs', 'lvu', 'lwa', 'lwe', 'lwg', 'lwh', 'lwl', 'lwm', 'lwo', 'lws', 'lwt', 'lwu', 'lww', 'lya', 'lyg', 'lyn', 'lzh', 'lzl', 'lzn', 'lzz', 'maa', 'mab', 'mad', 'mae', 'maf', 'mag', 'mai', 'maj', 'mak', 'mam', 'man', 'map', 'maq', 'mas', 'mat', 'mau', 'mav', 'maw', 'max', 'maz', 'mba', 'mbb', 'mbc', 'mbd', 'mbe', 'mbf', 'mbh', 'mbi', 'mbj', 'mbk', 'mbl', 'mbm', 'mbn', 'mbo', 'mbp', 'mbq', 'mbr', 'mbs', 'mbt', 'mbu', 'mbv', 'mbw', 'mbx', 'mby', 'mbz', 'mca', 'mcb', 'mcc', 'mcd', 'mce', 'mcf', 'mcg', 'mch', 'mci', 'mcj', 'mck', 'mcl', 'mcm', 'mcn', 'mco', 'mcp', 'mcq', 'mcr', 'mcs', 'mct', 'mcu', 'mcv', 'mcw', 'mcx', 'mcy', 'mcz', 'mda', 'mdb', 'mdc', 'mdd', 'mde', 'mdf', 'mdg', 'mdh', 'mdi', 'mdj', 'mdk', 'mdl', 'mdm', 'mdn', 'mdp', 'mdq', 'mdr', 'mds', 'mdt', 'mdu', 'mdv', 'mdw', 'mdx', 'mdy', 'mdz', 'mea', 'meb', 'mec', 'med', 'mee', 'mef', 'meg', 'meh', 'mei', 'mej', 'mek', 'mel', 'mem', 'men', 'meo', 'mep', 'meq', 'mer', 'mes', 'met', 'meu', 'mev', 'mew', 'mey', 'mez', 'mfa', 'mfb', 'mfc', 'mfd', 'mfe', 'mff', 'mfg', 'mfh', 'mfi', 'mfj', 'mfk', 'mfl', 'mfm', 'mfn', 'mfo', 'mfp', 'mfq', 'mfr', 'mfs', 'mft', 'mfu', 'mfv', 'mfw', 'mfx', 'mfy', 'mfz', 'mga', 'mgb', 'mgc', 'mgd', 'mge', 'mgf', 'mgg', 'mgh', 'mgi', 'mgj', 'mgk', 'mgl', 'mgm', 'mgn', 'mgo', 'mgp', 'mgq', 'mgr', 'mgs', 'mgt', 'mgu', 'mgv', 'mgw', 'mgx', 'mgy', 'mgz', 'mha', 'mhb', 'mhc', 'mhd', 'mhe', 'mhf', 'mhg', 'mhh', 'mhi', 'mhj', 'mhk', 'mhl', 'mhm', 'mhn', 'mho', 'mhp', 'mhq', 'mhr', 'mhs', 'mht', 'mhu', 'mhw', 'mhx', 'mhy', 'mhz', 'mia', 'mib', 'mic', 'mid', 'mie', 'mif', 'mig', 'mih', 'mii', 'mij', 'mik', 'mil', 'mim', 'min', 'mio', 'mip', 'miq', 'mir', 'mis', 'mit', 'miu', 'miw', 'mix', 'miy', 'miz', 'mja', 'mjb', 'mjc', 'mjd', 'mje', 'mjg', 'mjh', 'mji', 'mjj', 'mjk', 'mjl', 'mjm', 'mjn', 'mjo', 'mjp', 'mjq', 'mjr', 'mjs', 'mjt', 'mju', 'mjv', 'mjw', 'mjx', 'mjy', 'mjz', 'mka', 'mkb', 'mkc', 'mke', 'mkf', 'mkg', 'mkh', 'mki', 'mkj', 'mkk', 'mkl', 'mkm', 'mkn', 'mko', 'mkp', 'mkq', 'mkr', 'mks', 'mkt', 'mku', 'mkv', 'mkw', 'mkx', 'mky', 'mkz', 'mla', 'mlb', 'mlc', 'mld', 'mle', 'mlf', 'mlh', 'mli', 'mlj', 'mlk', 'mll', 'mlm', 'mln', 'mlo', 'mlp', 'mlq', 'mlr', 'mls', 'mlu', 'mlv', 'mlw', 'mlx', 'mlz', 'mma', 'mmb', 'mmc', 'mmd', 'mme', 'mmf', 'mmg', 'mmh', 'mmi', 'mmj', 'mmk', 'mml', 'mmm', 'mmn', 'mmo', 'mmp', 'mmq', 'mmr', 'mmt', 'mmu', 'mmv', 'mmw', 'mmx', 'mmy', 'mmz', 'mna', 'mnb', 'mnc', 'mnd', 'mne', 'mnf', 'mng', 'mnh', 'mni', 'mnj', 'mnk', 'mnl', 'mnm', 'mnn', 'mno', 'mnp', 'mnq', 'mnr', 'mns', 'mnt', 'mnu', 'mnv', 'mnw', 'mnx', 'mny', 'mnz', 'moa', 'moc', 'mod', 'moe', 'mof', 'mog', 'moh', 'moi', 'moj', 'mok', 'mom', 'moo', 'mop', 'moq', 'mor', 'mos', 'mot', 'mou', 'mov', 'mow', 'mox', 'moy', 'moz', 'mpa', 'mpb', 'mpc', 'mpd', 'mpe', 'mpg', 'mph', 'mpi', 'mpj', 'mpk', 'mpl', 'mpm', 'mpn', 'mpo', 'mpp', 'mpq', 'mpr', 'mps', 'mpt', 'mpu', 'mpv', 'mpw', 'mpx', 'mpy', 'mpz', 'mqa', 'mqb', 'mqc', 'mqe', 'mqf', 'mqg', 'mqh', 'mqi', 'mqj', 'mqk', 'mql', 'mqm', 'mqn', 'mqo', 'mqp', 'mqq', 'mqr', 'mqs', 'mqt', 'mqu', 'mqv', 'mqw', 'mqx', 'mqy', 'mqz', 'mra', 'mrb', 'mrc', 'mrd', 'mre', 'mrf', 'mrg', 'mrh', 'mrj', 'mrk', 'mrl', 'mrm', 'mrn', 'mro', 'mrp', 'mrq', 'mrr', 'mrs', 'mrt', 'mru', 'mrv', 'mrw', 'mrx', 'mry', 'mrz', 'msb', 'msc', 'msd', 'mse', 'msf', 'msg', 'msh', 'msi', 'msj', 'msk', 'msl', 'msm', 'msn', 'mso', 'msp', 'msq', 'msr', 'mss', 'mst', 'msu', 'msv', 'msw', 'msx', 'msy', 'msz', 'mta', 'mtb', 'mtc', 'mtd', 'mte', 'mtf', 'mtg', 'mth', 'mti', 'mtj', 'mtk', 'mtl', 'mtm', 'mtn', 'mto', 'mtp', 'mtq', 'mtr', 'mts', 'mtt', 'mtu', 'mtv', 'mtw', 'mtx', 'mty', 'mua', 'mub', 'muc', 'mud', 'mue', 'mug', 'muh', 'mui', 'muj', 'muk', 'mul', 'mum', 'mun', 'muo', 'mup', 'muq', 'mur', 'mus', 'mut', 'muu', 'muv', 'mux', 'muy', 'muz', 'mva', 'mvb', 'mvd', 'mve', 'mvf', 'mvg', 'mvh', 'mvi', 'mvk', 'mvl', 'mvm', 'mvn', 'mvo', 'mvp', 'mvq', 'mvr', 'mvs', 'mvt', 'mvu', 'mvv', 'mvw', 'mvx', 'mvy', 'mvz', 'mwa', 'mwb', 'mwc', 'mwd', 'mwe', 'mwf', 'mwg', 'mwh', 'mwi', 'mwj', 'mwk', 'mwl', 'mwm', 'mwn', 'mwo', 'mwp', 'mwq', 'mwr', 'mws', 'mwt', 'mwu', 'mwv', 'mww', 'mwx', 'mwy', 'mwz', 'mxa', 'mxb', 'mxc', 'mxd', 'mxe', 'mxf', 'mxg', 'mxh', 'mxi', 'mxj', 'mxk', 'mxl', 'mxm', 'mxn', 'mxo', 'mxp', 'mxq', 'mxr', 'mxs', 'mxt', 'mxu', 'mxv', 'mxw', 'mxx', 'mxy', 'mxz', 'myb', 'myc', 'myd', 'mye', 'myf', 'myg', 'myh', 'myi', 'myj', 'myk', 'myl', 'mym', 'myn', 'myo', 'myp', 'myq', 'myr', 'mys', 'myt', 'myu', 'myv', 'myw', 'myx', 'myy', 'myz', 'mza', 'mzb', 'mzc', 'mzd', 'mze', 'mzg', 'mzh', 'mzi', 'mzj', 'mzk', 'mzl', 'mzm', 'mzn', 'mzo', 'mzp', 'mzq', 'mzr', 'mzs', 'mzt', 'mzu', 'mzv', 'mzw', 'mzx', 'mzy', 'mzz', 'naa', 'nab', 'nac', 'nad', 'nae', 'naf', 'nag', 'nah', 'nai', 'naj', 'nak', 'nal', 'nam', 'nan', 'nao', 'nap', 'naq', 'nar', 'nas', 'nat', 'naw', 'nax', 'nay', 'naz', 'nba', 'nbb', 'nbc', 'nbd', 'nbe', 'nbf', 'nbg', 'nbh', 'nbi', 'nbj', 'nbk', 'nbm', 'nbn', 'nbo', 'nbp', 'nbq', 'nbr', 'nbs', 'nbt', 'nbu', 'nbv', 'nbw', 'nbx', 'nby', 'nca', 'ncb', 'ncc', 'ncd', 'nce', 'ncf', 'ncg', 'nch', 'nci', 'ncj', 'nck', 'ncl', 'ncm', 'ncn', 'nco', 'ncp', 'ncq', 'ncr', 'ncs', 'nct', 'ncu', 'ncx', 'ncz', 'nda', 'ndb', 'ndc', 'ndd', 'ndf', 'ndg', 'ndh', 'ndi', 'ndj', 'ndk', 'ndl', 'ndm', 'ndn', 'ndp', 'ndq', 'ndr', 'nds', 'ndt', 'ndu', 'ndv', 'ndw', 'ndx', 'ndy', 'ndz', 'nea', 'neb', 'nec', 'ned', 'nee', 'nef', 'neg', 'neh', 'nei', 'nej', 'nek', 'nem', 'nen', 'neo', 'neq', 'ner', 'nes', 'net', 'neu', 'nev', 'new', 'nex', 'ney', 'nez', 'nfa', 'nfd', 'nfl', 'nfr', 'nfu', 'nga', 'ngb', 'ngc', 'ngd', 'nge', 'ngf', 'ngg', 'ngh', 'ngi', 'ngj', 'ngk', 'ngl', 'ngm', 'ngn', 'ngo', 'ngp', 'ngq', 'ngr', 'ngs', 'ngt', 'ngu', 'ngv', 'ngw', 'ngx', 'ngy', 'ngz', 'nha', 'nhb', 'nhc', 'nhd', 'nhe', 'nhf', 'nhg', 'nhh', 'nhi', 'nhk', 'nhm', 'nhn', 'nho', 'nhp', 'nhq', 'nhr', 'nht', 'nhu', 'nhv', 'nhw', 'nhx', 'nhy', 'nhz', 'nia', 'nib', 'nic', 'nid', 'nie', 'nif', 'nig', 'nih', 'nii', 'nij', 'nik', 'nil', 'nim', 'nin', 'nio', 'niq', 'nir', 'nis', 'nit', 'niu', 'niv', 'niw', 'nix', 'niy', 'niz', 'nja', 'njb', 'njd', 'njh', 'nji', 'njj', 'njl', 'njm', 'njn', 'njo', 'njr', 'njs', 'njt', 'nju', 'njx', 'njy', 'njz', 'nka', 'nkb', 'nkc', 'nkd', 'nke', 'nkf', 'nkg', 'nkh', 'nki', 'nkj', 'nkk', 'nkm', 'nkn', 'nko', 'nkp', 'nkq', 'nkr', 'nks', 'nkt', 'nku', 'nkv', 'nkw', 'nkx', 'nkz', 'nla', 'nlc', 'nle', 'nlg', 'nli', 'nlj', 'nlk', 'nll', 'nlm', 'nln', 'nlo', 'nlq', 'nlr', 'nlu', 'nlv', 'nlw', 'nlx', 'nly', 'nlz', 'nma', 'nmb', 'nmc', 'nmd', 'nme', 'nmf', 'nmg', 'nmh', 'nmi', 'nmj', 'nmk', 'nml', 'nmm', 'nmn', 'nmo', 'nmp', 'nmq', 'nmr', 'nms', 'nmt', 'nmu', 'nmv', 'nmw', 'nmx', 'nmy', 'nmz', 'nna', 'nnb', 'nnc', 'nnd', 'nne', 'nnf', 'nng', 'nnh', 'nni', 'nnj', 'nnk', 'nnl', 'nnm', 'nnn', 'nnp', 'nnq', 'nnr', 'nns', 'nnt', 'nnu', 'nnv', 'nnw', 'nnx', 'nny', 'nnz', 'noa', 'noc', 'nod', 'noe', 'nof', 'nog', 'noh', 'noi', 'noj', 'nok', 'nol', 'nom', 'non', 'noo', 'nop', 'noq', 'nos', 'not', 'nou', 'nov', 'now', 'noy', 'noz', 'npa', 'npb', 'npg', 'nph', 'npi', 'npl', 'npn', 'npo', 'nps', 'npu', 'npx', 'npy', 'nqg', 'nqk', 'nql', 'nqm', 'nqn', 'nqo', 'nqq', 'nqy', 'nra', 'nrb', 'nrc', 'nre', 'nrf', 'nrg', 'nri', 'nrk', 'nrl', 'nrm', 'nrn', 'nrp', 'nrr', 'nrt', 'nru', 'nrx', 'nrz', 'nsa', 'nsc', 'nsd', 'nse', 'nsf', 'nsg', 'nsh', 'nsi', 'nsk', 'nsl', 'nsm', 'nsn', 'nso', 'nsp', 'nsq', 'nsr', 'nss', 'nst', 'nsu', 'nsv', 'nsw', 'nsx', 'nsy', 'nsz', 'ntd', 'nte', 'ntg', 'nti', 'ntj', 'ntk', 'ntm', 'nto', 'ntp', 'ntr', 'nts', 'ntu', 'ntw', 'ntx', 'nty', 'ntz', 'nua', 'nub', 'nuc', 'nud', 'nue', 'nuf', 'nug', 'nuh', 'nui', 'nuj', 'nuk', 'nul', 'num', 'nun', 'nuo', 'nup', 'nuq', 'nur', 'nus', 'nut', 'nuu', 'nuv', 'nuw', 'nux', 'nuy', 'nuz', 'nvh', 'nvm', 'nvo', 'nwa', 'nwb', 'nwc', 'nwe', 'nwg', 'nwi', 'nwm', 'nwo', 'nwr', 'nwx', 'nwy', 'nxa', 'nxd', 'nxe', 'nxg', 'nxi', 'nxk', 'nxl', 'nxm', 'nxn', 'nxo', 'nxq', 'nxr', 'nxu', 'nxx', 'nyb', 'nyc', 'nyd', 'nye', 'nyf', 'nyg', 'nyh', 'nyi', 'nyj', 'nyk', 'nyl', 'nym', 'nyn', 'nyo', 'nyp', 'nyq', 'nyr', 'nys', 'nyt', 'nyu', 'nyv', 'nyw', 'nyx', 'nyy', 'nza', 'nzb', 'nzd', 'nzi', 'nzk', 'nzm', 'nzs', 'nzu', 'nzy', 'nzz', 'oaa', 'oac', 'oar', 'oav', 'obi', 'obk', 'obl', 'obm', 'obo', 'obr', 'obt', 'obu', 'oca', 'och', 'oco', 'ocu', 'oda', 'odk', 'odt', 'odu', 'ofo', 'ofs', 'ofu', 'ogb', 'ogc', 'oge', 'ogg', 'ogo', 'ogu', 'oht', 'ohu', 'oia', 'oin', 'ojb', 'ojc', 'ojg', 'ojp', 'ojs', 'ojv', 'ojw', 'oka', 'okb', 'okd', 'oke', 'okg', 'okh', 'oki', 'okj', 'okk', 'okl', 'okm', 'okn', 'oko', 'okr', 'oks', 'oku', 'okv', 'okx', 'ola', 'old', 'ole', 'olk', 'olm', 'olo', 'olr', 'olt', 'olu', 'oma', 'omb', 'omc', 'ome', 'omg', 'omi', 'omk', 'oml', 'omn', 'omo', 'omp', 'omq', 'omr', 'omt', 'omu', 'omv', 'omw', 'omx', 'ona', 'onb', 'one', 'ong', 'oni', 'onj', 'onk', 'onn', 'ono', 'onp', 'onr', 'ons', 'ont', 'onu', 'onw', 'onx', 'ood', 'oog', 'oon', 'oor', 'oos', 'opa', 'opk', 'opm', 'opo', 'opt', 'opy', 'ora', 'orc', 'ore', 'org', 'orh', 'orn', 'oro', 'orr', 'ors', 'ort', 'oru', 'orv', 'orw', 'orx', 'ory', 'orz', 'osa', 'osc', 'osi', 'oso', 'osp', 'ost', 'osu', 'osx', 'ota', 'otb', 'otd', 'ote', 'oti', 'otk', 'otl', 'otm', 'otn', 'oto', 'otq', 'otr', 'ots', 'ott', 'otu', 'otw', 'otx', 'oty', 'otz', 'oua', 'oub', 'oue', 'oui', 'oum', 'oun', 'ovd', 'owi', 'owl', 'oyb', 'oyd', 'oym', 'oyy', 'ozm', 'paa', 'pab', 'pac', 'pad', 'pae', 'paf', 'pag', 'pah', 'pai', 'pak', 'pal', 'pam', 'pao', 'pap', 'paq', 'par', 'pas', 'pat', 'pau', 'pav', 'paw', 'pax', 'pay', 'paz', 'pbb', 'pbc', 'pbe', 'pbf', 'pbg', 'pbh', 'pbi', 'pbl', 'pbm', 'pbn', 'pbo', 'pbp', 'pbr', 'pbs', 'pbt', 'pbu', 'pbv', 'pby', 'pbz', 'pca', 'pcb', 'pcc', 'pcd', 'pce', 'pcf', 'pcg', 'pch', 'pci', 'pcj', 'pck', 'pcl', 'pcm', 'pcn', 'pcp', 'pcr', 'pcw', 'pda', 'pdc', 'pdi', 'pdn', 'pdo', 'pdt', 'pdu', 'pea', 'peb', 'ped', 'pee', 'pef', 'peg', 'peh', 'pei', 'pej', 'pek', 'pel', 'pem', 'peo', 'pep', 'peq', 'pes', 'pev', 'pex', 'pey', 'pez', 'pfa', 'pfe', 'pfl', 'pga', 'pgd', 'pgg', 'pgi', 'pgk', 'pgl', 'pgn', 'pgs', 'pgu', 'pgy', 'pgz', 'pha', 'phd', 'phg', 'phh', 'phi', 'phk', 'phl', 'phm', 'phn', 'pho', 'phq', 'phr', 'pht', 'phu', 'phv', 'phw', 'pia', 'pib', 'pic', 'pid', 'pie', 'pif', 'pig', 'pih', 'pii', 'pij', 'pil', 'pim', 'pin', 'pio', 'pip', 'pir', 'pis', 'pit', 'piu', 'piv', 'piw', 'pix', 'piy', 'piz', 'pjt', 'pka', 'pkb', 'pkc', 'pkg', 'pkh', 'pkn', 'pko', 'pkp', 'pkr', 'pks', 'pkt', 'pku', 'pla', 'plb', 'plc', 'pld', 'ple', 'plf', 'plg', 'plh', 'plj', 'plk', 'pll', 'pln', 'plo', 'plp', 'plq', 'plr', 'pls', 'plt', 'plu', 'plv', 'plw', 'ply', 'plz', 'pma', 'pmb', 'pmc', 'pmd', 'pme', 'pmf', 'pmh', 'pmi', 'pmj', 'pmk', 'pml', 'pmm', 'pmn', 'pmo', 'pmq', 'pmr', 'pms', 'pmt', 'pmu', 'pmw', 'pmx', 'pmy', 'pmz', 'pna', 'pnb', 'pnc', 'pne', 'png', 'pnh', 'pni', 'pnj', 'pnk', 'pnl', 'pnm', 'pnn', 'pno', 'pnp', 'pnq', 'pnr', 'pns', 'pnt', 'pnu', 'pnv', 'pnw', 'pnx', 'pny', 'pnz', 'poc', 'pod', 'poe', 'pof', 'pog', 'poh', 'poi', 'pok', 'pom', 'pon', 'poo', 'pop', 'poq', 'pos', 'pot', 'pov', 'pow', 'pox', 'poy', 'poz', 'ppa', 'ppe', 'ppi', 'ppk', 'ppl', 'ppm', 'ppn', 'ppo', 'ppp', 'ppq', 'ppr', 'pps', 'ppt', 'ppu', 'pqa', 'pqe', 'pqm', 'pqw', 'pra', 'prb', 'prc', 'prd', 'pre', 'prf', 'prg', 'prh', 'pri', 'prk', 'prl', 'prm', 'prn', 'pro', 'prp', 'prq', 'prr', 'prs', 'prt', 'pru', 'prw', 'prx', 'pry', 'prz', 'psa', 'psc', 'psd', 'pse', 'psg', 'psh', 'psi', 'psl', 'psm', 'psn', 'pso', 'psp', 'psq', 'psr', 'pss', 'pst', 'psu', 'psw', 'psy', 'pta', 'pth', 'pti', 'ptn', 'pto', 'ptp', 'ptq', 'ptr', 'ptt', 'ptu', 'ptv', 'ptw', 'pty', 'pua', 'pub', 'puc', 'pud', 'pue', 'puf', 'pug', 'pui', 'puj', 'puk', 'pum', 'puo', 'pup', 'puq', 'pur', 'put', 'puu', 'puw', 'pux', 'puy', 'puz', 'pwa', 'pwb', 'pwg', 'pwi', 'pwm', 'pwn', 'pwo', 'pwr', 'pww', 'pxm', 'pye', 'pym', 'pyn', 'pys', 'pyu', 'pyx', 'pyy', 'pzn', 'qaa..qtz', 'qua', 'qub', 'quc', 'qud', 'quf', 'qug', 'quh', 'qui', 'quk', 'qul', 'qum', 'qun', 'qup', 'quq', 'qur', 'qus', 'quv', 'quw', 'qux', 'quy', 'quz', 'qva', 'qvc', 'qve', 'qvh', 'qvi', 'qvj', 'qvl', 'qvm', 'qvn', 'qvo', 'qvp', 'qvs', 'qvw', 'qvy', 'qvz', 'qwa', 'qwc', 'qwe', 'qwh', 'qwm', 'qws', 'qwt', 'qxa', 'qxc', 'qxh', 'qxl', 'qxn', 'qxo', 'qxp', 'qxq', 'qxr', 'qxs', 'qxt', 'qxu', 'qxw', 'qya', 'qyp', 'raa', 'rab', 'rac', 'rad', 'raf', 'rag', 'rah', 'rai', 'raj', 'rak', 'ral', 'ram', 'ran', 'rao', 'rap', 'raq', 'rar', 'ras', 'rat', 'rau', 'rav', 'raw', 'rax', 'ray', 'raz', 'rbb', 'rbk', 'rbl', 'rbp', 'rcf', 'rdb', 'rea', 'reb', 'ree', 'reg', 'rei', 'rej', 'rel', 'rem', 'ren', 'rer', 'res', 'ret', 'rey', 'rga', 'rge', 'rgk', 'rgn', 'rgr', 'rgs', 'rgu', 'rhg', 'rhp', 'ria', 'rie', 'rif', 'ril', 'rim', 'rin', 'rir', 'rit', 'riu', 'rjg', 'rji', 'rjs', 'rka', 'rkb', 'rkh', 'rki', 'rkm', 'rkt', 'rkw', 'rma', 'rmb', 'rmc', 'rmd', 'rme', 'rmf', 'rmg', 'rmh', 'rmi', 'rmk', 'rml', 'rmm', 'rmn', 'rmo', 'rmp', 'rmq', 'rmr', 'rms', 'rmt', 'rmu', 'rmv', 'rmw', 'rmx', 'rmy', 'rmz', 'rna', 'rnd', 'rng', 'rnl', 'rnn', 'rnp', 'rnr', 'rnw', 'roa', 'rob', 'roc', 'rod', 'roe', 'rof', 'rog', 'rol', 'rom', 'roo', 'rop', 'ror', 'rou', 'row', 'rpn', 'rpt', 'rri', 'rro', 'rrt', 'rsb', 'rsi', 'rsl', 'rsm', 'rtc', 'rth', 'rtm', 'rts', 'rtw', 'rub', 'ruc', 'rue', 'ruf', 'rug', 'ruh', 'rui', 'ruk', 'ruo', 'rup', 'ruq', 'rut', 'ruu', 'ruy', 'ruz', 'rwa', 'rwk', 'rwm', 'rwo', 'rwr', 'rxd', 'rxw', 'ryn', 'rys', 'ryu', 'rzh', 'saa', 'sab', 'sac', 'sad', 'sae', 'saf', 'sah', 'sai', 'saj', 'sak', 'sal', 'sam', 'sao', 'sap', 'saq', 'sar', 'sas', 'sat', 'sau', 'sav', 'saw', 'sax', 'say', 'saz', 'sba', 'sbb', 'sbc', 'sbd', 'sbe', 'sbf', 'sbg', 'sbh', 'sbi', 'sbj', 'sbk', 'sbl', 'sbm', 'sbn', 'sbo', 'sbp', 'sbq', 'sbr', 'sbs', 'sbt', 'sbu', 'sbv', 'sbw', 'sbx', 'sby', 'sbz', 'sca', 'scb', 'sce', 'scf', 'scg', 'sch', 'sci', 'sck', 'scl', 'scn', 'sco', 'scp', 'scq', 'scs', 'sct', 'scu', 'scv', 'scw', 'scx', 'sda', 'sdb', 'sdc', 'sde', 'sdf', 'sdg', 'sdh', 'sdj', 'sdk', 'sdl', 'sdm', 'sdn', 'sdo', 'sdp', 'sdr', 'sds', 'sdt', 'sdu', 'sdv', 'sdx', 'sdz', 'sea', 'seb', 'sec', 'sed', 'see', 'sef', 'seg', 'seh', 'sei', 'sej', 'sek', 'sel', 'sem', 'sen', 'seo', 'sep', 'seq', 'ser', 'ses', 'set', 'seu', 'sev', 'sew', 'sey', 'sez', 'sfb', 'sfe', 'sfm', 'sfs', 'sfw', 'sga', 'sgb', 'sgc', 'sgd', 'sge', 'sgg', 'sgh', 'sgi', 'sgj', 'sgk', 'sgl', 'sgm', 'sgn', 'sgo', 'sgp', 'sgr', 'sgs', 'sgt', 'sgu', 'sgw', 'sgx', 'sgy', 'sgz', 'sha', 'shb', 'shc', 'shd', 'she', 'shg', 'shh', 'shi', 'shj', 'shk', 'shl', 'shm', 'shn', 'sho', 'shp', 'shq', 'shr', 'shs', 'sht', 'shu', 'shv', 'shw', 'shx', 'shy', 'shz', 'sia', 'sib', 'sid', 'sie', 'sif', 'sig', 'sih', 'sii', 'sij', 'sik', 'sil', 'sim', 'sio', 'sip', 'siq', 'sir', 'sis', 'sit', 'siu', 'siv', 'siw', 'six', 'siy', 'siz', 'sja', 'sjb', 'sjd', 'sje', 'sjg', 'sjk', 'sjl', 'sjm', 'sjn', 'sjo', 'sjp', 'sjr', 'sjs', 'sjt', 'sju', 'sjw', 'ska', 'skb', 'skc', 'skd', 'ske', 'skf', 'skg', 'skh', 'ski', 'skj', 'skk', 'skm', 'skn', 'sko', 'skp', 'skq', 'skr', 'sks', 'skt', 'sku', 'skv', 'skw', 'skx', 'sky', 'skz', 'sla', 'slc', 'sld', 'sle', 'slf', 'slg', 'slh', 'sli', 'slj', 'sll', 'slm', 'sln', 'slp', 'slq', 'slr', 'sls', 'slt', 'slu', 'slw', 'slx', 'sly', 'slz', 'sma', 'smb', 'smc', 'smd', 'smf', 'smg', 'smh', 'smi', 'smj', 'smk', 'sml', 'smm', 'smn', 'smp', 'smq', 'smr', 'sms', 'smt', 'smu', 'smv', 'smw', 'smx', 'smy', 'smz', 'snb', 'snc', 'sne', 'snf', 'sng', 'snh', 'sni', 'snj', 'snk', 'snl', 'snm', 'snn', 'sno', 'snp', 'snq', 'snr', 'sns', 'snu', 'snv', 'snw', 'snx', 'sny', 'snz', 'soa', 'sob', 'soc', 'sod', 'soe', 'sog', 'soh', 'soi', 'soj', 'sok', 'sol', 'son', 'soo', 'sop', 'soq', 'sor', 'sos', 'sou', 'sov', 'sow', 'sox', 'soy', 'soz', 'spb', 'spc', 'spd', 'spe', 'spg', 'spi', 'spk', 'spl', 'spm', 'spn', 'spo', 'spp', 'spq', 'spr', 'sps', 'spt', 'spu', 'spv', 'spx', 'spy', 'sqa', 'sqh', 'sqj', 'sqk', 'sqm', 'sqn', 'sqo', 'sqq', 'sqr', 'sqs', 'sqt', 'squ', 'sra', 'srb', 'src', 'sre', 'srf', 'srg', 'srh', 'sri', 'srk', 'srl', 'srm', 'srn', 'sro', 'srq', 'srr', 'srs', 'srt', 'sru', 'srv', 'srw', 'srx', 'sry', 'srz', 'ssa', 'ssb', 'ssc', 'ssd', 'sse', 'ssf', 'ssg', 'ssh', 'ssi', 'ssj', 'ssk', 'ssl', 'ssm', 'ssn', 'sso', 'ssp', 'ssq', 'ssr', 'sss', 'sst', 'ssu', 'ssv', 'ssx', 'ssy', 'ssz', 'sta', 'stb', 'std', 'ste', 'stf', 'stg', 'sth', 'sti', 'stj', 'stk', 'stl', 'stm', 'stn', 'sto', 'stp', 'stq', 'str', 'sts', 'stt', 'stu', 'stv', 'stw', 'sty', 'sua', 'sub', 'suc', 'sue', 'sug', 'sui', 'suj', 'suk', 'sul', 'sum', 'suq', 'sur', 'sus', 'sut', 'suv', 'suw', 'sux', 'suy', 'suz', 'sva', 'svb', 'svc', 'sve', 'svk', 'svm', 'svr', 'svs', 'svx', 'swb', 'swc', 'swf', 'swg', 'swh', 'swi', 'swj', 'swk', 'swl', 'swm', 'swn', 'swo', 'swp', 'swq', 'swr', 'sws', 'swt', 'swu', 'swv', 'sww', 'swx', 'swy', 'sxb', 'sxc', 'sxe', 'sxg', 'sxk', 'sxl', 'sxm', 'sxn', 'sxo', 'sxr', 'sxs', 'sxu', 'sxw', 'sya', 'syb', 'syc', 'syd', 'syi', 'syk', 'syl', 'sym', 'syn', 'syo', 'syr', 'sys', 'syw', 'syx', 'syy', 'sza', 'szb', 'szc', 'szd', 'sze', 'szg', 'szl', 'szn', 'szp', 'szs', 'szv', 'szw', 'taa', 'tab', 'tac', 'tad', 'tae', 'taf', 'tag', 'tai', 'taj', 'tak', 'tal', 'tan', 'tao', 'tap', 'taq', 'tar', 'tas', 'tau', 'tav', 'taw', 'tax', 'tay', 'taz', 'tba', 'tbb', 'tbc', 'tbd', 'tbe', 'tbf', 'tbg', 'tbh', 'tbi', 'tbj', 'tbk', 'tbl', 'tbm', 'tbn', 'tbo', 'tbp', 'tbq', 'tbr', 'tbs', 'tbt', 'tbu', 'tbv', 'tbw', 'tbx', 'tby', 'tbz', 'tca', 'tcb', 'tcc', 'tcd', 'tce', 'tcf', 'tcg', 'tch', 'tci', 'tck', 'tcl', 'tcm', 'tcn', 'tco', 'tcp', 'tcq', 'tcs', 'tct', 'tcu', 'tcw', 'tcx', 'tcy', 'tcz', 'tda', 'tdb', 'tdc', 'tdd', 'tde', 'tdf', 'tdg', 'tdh', 'tdi', 'tdj', 'tdk', 'tdl', 'tdm', 'tdn', 'tdo', 'tdq', 'tdr', 'tds', 'tdt', 'tdu', 'tdv', 'tdx', 'tdy', 'tea', 'teb', 'tec', 'ted', 'tee', 'tef', 'teg', 'teh', 'tei', 'tek', 'tem', 'ten', 'teo', 'tep', 'teq', 'ter', 'tes', 'tet', 'teu', 'tev', 'tew', 'tex', 'tey', 'tez', 'tfi', 'tfn', 'tfo', 'tfr', 'tft', 'tga', 'tgb', 'tgc', 'tgd', 'tge', 'tgf', 'tgg', 'tgh', 'tgi', 'tgj', 'tgn', 'tgo', 'tgp', 'tgq', 'tgr', 'tgs', 'tgt', 'tgu', 'tgv', 'tgw', 'tgx', 'tgy', 'tgz', 'thc', 'thd', 'the', 'thf', 'thh', 'thi', 'thk', 'thl', 'thm', 'thn', 'thp', 'thq', 'thr', 'ths', 'tht', 'thu', 'thv', 'thw', 'thx', 'thy', 'thz', 'tia', 'tic', 'tid', 'tie', 'tif', 'tig', 'tih', 'tii', 'tij', 'tik', 'til', 'tim', 'tin', 'tio', 'tip', 'tiq', 'tis', 'tit', 'tiu', 'tiv', 'tiw', 'tix', 'tiy', 'tiz', 'tja', 'tjg', 'tji', 'tjl', 'tjm', 'tjn', 'tjo', 'tjs', 'tju', 'tjw', 'tka', 'tkb', 'tkd', 'tke', 'tkf', 'tkg', 'tkk', 'tkl', 'tkm', 'tkn', 'tkp', 'tkq', 'tkr', 'tks', 'tkt', 'tku', 'tkv', 'tkw', 'tkx', 'tkz', 'tla', 'tlb', 'tlc', 'tld', 'tlf', 'tlg', 'tlh', 'tli', 'tlj', 'tlk', 'tll', 'tlm', 'tln', 'tlo', 'tlp', 'tlq', 'tlr', 'tls', 'tlt', 'tlu', 'tlv', 'tlw', 'tlx', 'tly', 'tma', 'tmb', 'tmc', 'tmd', 'tme', 'tmf', 'tmg', 'tmh', 'tmi', 'tmj', 'tmk', 'tml', 'tmm', 'tmn', 'tmo', 'tmp', 'tmq', 'tmr', 'tms', 'tmt', 'tmu', 'tmv', 'tmw', 'tmy', 'tmz', 'tna', 'tnb', 'tnc', 'tnd', 'tne', 'tnf', 'tng', 'tnh', 'tni', 'tnk', 'tnl', 'tnm', 'tnn', 'tno', 'tnp', 'tnq', 'tnr', 'tns', 'tnt', 'tnu', 'tnv', 'tnw', 'tnx', 'tny', 'tnz', 'tob', 'toc', 'tod', 'toe', 'tof', 'tog', 'toh', 'toi', 'toj', 'tol', 'tom', 'too', 'top', 'toq', 'tor', 'tos', 'tou', 'tov', 'tow', 'tox', 'toy', 'toz', 'tpa', 'tpc', 'tpe', 'tpf', 'tpg', 'tpi', 'tpj', 'tpk', 'tpl', 'tpm', 'tpn', 'tpo', 'tpp', 'tpq', 'tpr', 'tpt', 'tpu', 'tpv', 'tpw', 'tpx', 'tpy', 'tpz', 'tqb', 'tql', 'tqm', 'tqn', 'tqo', 'tqp', 'tqq', 'tqr', 'tqt', 'tqu', 'tqw', 'tra', 'trb', 'trc', 'trd', 'tre', 'trf', 'trg', 'trh', 'tri', 'trj', 'trk', 'trl', 'trm', 'trn', 'tro', 'trp', 'trq', 'trr', 'trs', 'trt', 'tru', 'trv', 'trw', 'trx', 'try', 'trz', 'tsa', 'tsb', 'tsc', 'tsd', 'tse', 'tsf', 'tsg', 'tsh', 'tsi', 'tsj', 'tsk', 'tsl', 'tsm', 'tsp', 'tsq', 'tsr', 'tss', 'tst', 'tsu', 'tsv', 'tsw', 'tsx', 'tsy', 'tsz', 'tta', 'ttb', 'ttc', 'ttd', 'tte', 'ttf', 'ttg', 'tth', 'tti', 'ttj', 'ttk', 'ttl', 'ttm', 'ttn', 'tto', 'ttp', 'ttq', 'ttr', 'tts', 'ttt', 'ttu', 'ttv', 'ttw', 'tty', 'ttz', 'tua', 'tub', 'tuc', 'tud', 'tue', 'tuf', 'tug', 'tuh', 'tui', 'tuj', 'tul', 'tum', 'tun', 'tuo', 'tup', 'tuq', 'tus', 'tut', 'tuu', 'tuv', 'tuw', 'tux', 'tuy', 'tuz', 'tva', 'tvd', 'tve', 'tvk', 'tvl', 'tvm', 'tvn', 'tvo', 'tvs', 'tvt', 'tvu', 'tvw', 'tvy', 'twa', 'twb', 'twc', 'twd', 'twe', 'twf', 'twg', 'twh', 'twl', 'twm', 'twn', 'two', 'twp', 'twq', 'twr', 'twt', 'twu', 'tww', 'twx', 'twy', 'txa', 'txb', 'txc', 'txe', 'txg', 'txh', 'txi', 'txj', 'txm', 'txn', 'txo', 'txq', 'txr', 'txs', 'txt', 'txu', 'txx', 'txy', 'tya', 'tye', 'tyh', 'tyi', 'tyj', 'tyl', 'tyn', 'typ', 'tyr', 'tys', 'tyt', 'tyu', 'tyv', 'tyx', 'tyz', 'tza', 'tzh', 'tzj', 'tzl', 'tzm', 'tzn', 'tzo', 'tzx', 'uam', 'uan', 'uar', 'uba', 'ubi', 'ubl', 'ubr', 'ubu', 'uby', 'uda', 'ude', 'udg', 'udi', 'udj', 'udl', 'udm', 'udu', 'ues', 'ufi', 'uga', 'ugb', 'uge', 'ugn', 'ugo', 'ugy', 'uha', 'uhn', 'uis', 'uiv', 'uji', 'uka', 'ukg', 'ukh', 'ukk', 'ukl', 'ukp', 'ukq', 'uks', 'uku', 'ukw', 'uky', 'ula', 'ulb', 'ulc', 'ule', 'ulf', 'uli', 'ulk', 'ull', 'ulm', 'uln', 'ulu', 'ulw', 'uma', 'umb', 'umc', 'umd', 'umg', 'umi', 'umm', 'umn', 'umo', 'ump', 'umr', 'ums', 'umu', 'una', 'und', 'une', 'ung', 'unk', 'unm', 'unn', 'unp', 'unr', 'unu', 'unx', 'unz', 'uok', 'upi', 'upv', 'ura', 'urb', 'urc', 'ure', 'urf', 'urg', 'urh', 'uri', 'urj', 'urk', 'url', 'urm', 'urn', 'uro', 'urp', 'urr', 'urt', 'uru', 'urv', 'urw', 'urx', 'ury', 'urz', 'usa', 'ush', 'usi', 'usk', 'usp', 'usu', 'uta', 'ute', 'utp', 'utr', 'utu', 'uum', 'uun', 'uur', 'uuu', 'uve', 'uvh', 'uvl', 'uwa', 'uya', 'uzn', 'uzs', 'vaa', 'vae', 'vaf', 'vag', 'vah', 'vai', 'vaj', 'val', 'vam', 'van', 'vao', 'vap', 'var', 'vas', 'vau', 'vav', 'vay', 'vbb', 'vbk', 'vec', 'ved', 'vel', 'vem', 'veo', 'vep', 'ver', 'vgr', 'vgt', 'vic', 'vid', 'vif', 'vig', 'vil', 'vin', 'vis', 'vit', 'viv', 'vka', 'vki', 'vkj', 'vkk', 'vkl', 'vkm', 'vko', 'vkp', 'vkt', 'vku', 'vlp', 'vls', 'vma', 'vmb', 'vmc', 'vmd', 'vme', 'vmf', 'vmg', 'vmh', 'vmi', 'vmj', 'vmk', 'vml', 'vmm', 'vmp', 'vmq', 'vmr', 'vms', 'vmu', 'vmv', 'vmw', 'vmx', 'vmy', 'vmz', 'vnk', 'vnm', 'vnp', 'vor', 'vot', 'vra', 'vro', 'vrs', 'vrt', 'vsi', 'vsl', 'vsv', 'vto', 'vum', 'vun', 'vut', 'vwa', 'waa', 'wab', 'wac', 'wad', 'wae', 'waf', 'wag', 'wah', 'wai', 'waj', 'wak', 'wal', 'wam', 'wan', 'wao', 'wap', 'waq', 'war', 'was', 'wat', 'wau', 'wav', 'waw', 'wax', 'way', 'waz', 'wba', 'wbb', 'wbe', 'wbf', 'wbh', 'wbi', 'wbj', 'wbk', 'wbl', 'wbm', 'wbp', 'wbq', 'wbr', 'wbs', 'wbt', 'wbv', 'wbw', 'wca', 'wci', 'wdd', 'wdg', 'wdj', 'wdk', 'wdu', 'wdy', 'wea', 'wec', 'wed', 'weg', 'weh', 'wei', 'wem', 'wen', 'weo', 'wep', 'wer', 'wes', 'wet', 'weu', 'wew', 'wfg', 'wga', 'wgb', 'wgg', 'wgi', 'wgo', 'wgu', 'wgw', 'wgy', 'wha', 'whg', 'whk', 'whu', 'wib', 'wic', 'wie', 'wif', 'wig', 'wih', 'wii', 'wij', 'wik', 'wil', 'wim', 'win', 'wir', 'wit', 'wiu', 'wiv', 'wiw', 'wiy', 'wja', 'wji', 'wka', 'wkb', 'wkd', 'wkl', 'wku', 'wkw', 'wky', 'wla', 'wlc', 'wle', 'wlg', 'wli', 'wlk', 'wll', 'wlm', 'wlo', 'wlr', 'wls', 'wlu', 'wlv', 'wlw', 'wlx', 'wly', 'wma', 'wmb', 'wmc', 'wmd', 'wme', 'wmh', 'wmi', 'wmm', 'wmn', 'wmo', 'wms', 'wmt', 'wmw', 'wmx', 'wnb', 'wnc', 'wnd', 'wne', 'wng', 'wni', 'wnk', 'wnm', 'wnn', 'wno', 'wnp', 'wnu', 'wnw', 'wny', 'woa', 'wob', 'woc', 'wod', 'woe', 'wof', 'wog', 'woi', 'wok', 'wom', 'won', 'woo', 'wor', 'wos', 'wow', 'woy', 'wpc', 'wra', 'wrb', 'wrd', 'wrg', 'wrh', 'wri', 'wrk', 'wrl', 'wrm', 'wrn', 'wro', 'wrp', 'wrr', 'wrs', 'wru', 'wrv', 'wrw', 'wrx', 'wry', 'wrz', 'wsa', 'wsg', 'wsi', 'wsk', 'wsr', 'wss', 'wsu', 'wsv', 'wtf', 'wth', 'wti', 'wtk', 'wtm', 'wtw', 'wua', 'wub', 'wud', 'wuh', 'wul', 'wum', 'wun', 'wur', 'wut', 'wuu', 'wuv', 'wux', 'wuy', 'wwa', 'wwb', 'wwo', 'wwr', 'www', 'wxa', 'wxw', 'wya', 'wyb', 'wyi', 'wym', 'wyr', 'wyy', 'xaa', 'xab', 'xac', 'xad', 'xae', 'xag', 'xai', 'xaj', 'xak', 'xal', 'xam', 'xan', 'xao', 'xap', 'xaq', 'xar', 'xas', 'xat', 'xau', 'xav', 'xaw', 'xay', 'xba', 'xbb', 'xbc', 'xbd', 'xbe', 'xbg', 'xbi', 'xbj', 'xbm', 'xbn', 'xbo', 'xbp', 'xbr', 'xbw', 'xbx', 'xby', 'xcb', 'xcc', 'xce', 'xcg', 'xch', 'xcl', 'xcm', 'xcn', 'xco', 'xcr', 'xct', 'xcu', 'xcv', 'xcw', 'xcy', 'xda', 'xdc', 'xdk', 'xdm', 'xdo', 'xdy', 'xeb', 'xed', 'xeg', 'xel', 'xem', 'xep', 'xer', 'xes', 'xet', 'xeu', 'xfa', 'xga', 'xgb', 'xgd', 'xgf', 'xgg', 'xgi', 'xgl', 'xgm', 'xgn', 'xgr', 'xgu', 'xgw', 'xha', 'xhc', 'xhd', 'xhe', 'xhr', 'xht', 'xhu', 'xhv', 'xia', 'xib', 'xii', 'xil', 'xin', 'xip', 'xir', 'xis', 'xiv', 'xiy', 'xjb', 'xjt', 'xka', 'xkb', 'xkc', 'xkd', 'xke', 'xkf', 'xkg', 'xkh', 'xki', 'xkj', 'xkk', 'xkl', 'xkn', 'xko', 'xkp', 'xkq', 'xkr', 'xks', 'xkt', 'xku', 'xkv', 'xkw', 'xkx', 'xky', 'xkz', 'xla', 'xlb', 'xlc', 'xld', 'xle', 'xlg', 'xli', 'xln', 'xlo', 'xlp', 'xls', 'xlu', 'xly', 'xma', 'xmb', 'xmc', 'xmd', 'xme', 'xmf', 'xmg', 'xmh', 'xmj', 'xmk', 'xml', 'xmm', 'xmn', 'xmo', 'xmp', 'xmq', 'xmr', 'xms', 'xmt', 'xmu', 'xmv', 'xmw', 'xmx', 'xmy', 'xmz', 'xna', 'xnb', 'xnd', 'xng', 'xnh', 'xni', 'xnk', 'xnn', 'xno', 'xnr', 'xns', 'xnt', 'xnu', 'xny', 'xnz', 'xoc', 'xod', 'xog', 'xoi', 'xok', 'xom', 'xon', 'xoo', 'xop', 'xor', 'xow', 'xpa', 'xpc', 'xpe', 'xpg', 'xpi', 'xpj', 'xpk', 'xpm', 'xpn', 'xpo', 'xpp', 'xpq', 'xpr', 'xps', 'xpt', 'xpu', 'xpy', 'xqa', 'xqt', 'xra', 'xrb', 'xrd', 'xre', 'xrg', 'xri', 'xrm', 'xrn', 'xrq', 'xrr', 'xrt', 'xru', 'xrw', 'xsa', 'xsb', 'xsc', 'xsd', 'xse', 'xsh', 'xsi', 'xsj', 'xsl', 'xsm', 'xsn', 'xso', 'xsp', 'xsq', 'xsr', 'xss', 'xsu', 'xsv', 'xsy', 'xta', 'xtb', 'xtc', 'xtd', 'xte', 'xtg', 'xth', 'xti', 'xtj', 'xtl', 'xtm', 'xtn', 'xto', 'xtp', 'xtq', 'xtr', 'xts', 'xtt', 'xtu', 'xtv', 'xtw', 'xty', 'xtz', 'xua', 'xub', 'xud', 'xug', 'xuj', 'xul', 'xum', 'xun', 'xuo', 'xup', 'xur', 'xut', 'xuu', 'xve', 'xvi', 'xvn', 'xvo', 'xvs', 'xwa', 'xwc', 'xwd', 'xwe', 'xwg', 'xwj', 'xwk', 'xwl', 'xwo', 'xwr', 'xwt', 'xww', 'xxb', 'xxk', 'xxm', 'xxr', 'xxt', 'xya', 'xyb', 'xyj', 'xyk', 'xyl', 'xyt', 'xyy', 'xzh', 'xzm', 'xzp', 'yaa', 'yab', 'yac', 'yad', 'yae', 'yaf', 'yag', 'yah', 'yai', 'yaj', 'yak', 'yal', 'yam', 'yan', 'yao', 'yap', 'yaq', 'yar', 'yas', 'yat', 'yau', 'yav', 'yaw', 'yax', 'yay', 'yaz', 'yba', 'ybb', 'ybd', 'ybe', 'ybh', 'ybi', 'ybj', 'ybk', 'ybl', 'ybm', 'ybn', 'ybo', 'ybx', 'yby', 'ych', 'ycl', 'ycn', 'ycp', 'yda', 'ydd', 'yde', 'ydg', 'ydk', 'yds', 'yea', 'yec', 'yee', 'yei', 'yej', 'yel', 'yen', 'yer', 'yes', 'yet', 'yeu', 'yev', 'yey', 'yga', 'ygi', 'ygl', 'ygm', 'ygp', 'ygr', 'ygs', 'ygu', 'ygw', 'yha', 'yhd', 'yhl', 'yhs', 'yia', 'yif', 'yig', 'yih', 'yii', 'yij', 'yik', 'yil', 'yim', 'yin', 'yip', 'yiq', 'yir', 'yis', 'yit', 'yiu', 'yiv', 'yix', 'yiy', 'yiz', 'yka', 'ykg', 'yki', 'ykk', 'ykl', 'ykm', 'ykn', 'yko', 'ykr', 'ykt', 'yku', 'yky', 'yla', 'ylb', 'yle', 'ylg', 'yli', 'yll', 'ylm', 'yln', 'ylo', 'ylr', 'ylu', 'yly', 'yma', 'ymb', 'ymc', 'ymd', 'yme', 'ymg', 'ymh', 'ymi', 'ymk', 'yml', 'ymm', 'ymn', 'ymo', 'ymp', 'ymq', 'ymr', 'yms', 'ymt', 'ymx', 'ymz', 'yna', 'ynd', 'yne', 'yng', 'ynh', 'ynk', 'ynl', 'ynn', 'yno', 'ynq', 'yns', 'ynu', 'yob', 'yog', 'yoi', 'yok', 'yol', 'yom', 'yon', 'yos', 'yot', 'yox', 'yoy', 'ypa', 'ypb', 'ypg', 'yph', 'ypk', 'ypm', 'ypn', 'ypo', 'ypp', 'ypz', 'yra', 'yrb', 'yre', 'yri', 'yrk', 'yrl', 'yrm', 'yrn', 'yro', 'yrs', 'yrw', 'yry', 'ysc', 'ysd', 'ysg', 'ysl', 'ysn', 'yso', 'ysp', 'ysr', 'yss', 'ysy', 'yta', 'ytl', 'ytp', 'ytw', 'yty', 'yua', 'yub', 'yuc', 'yud', 'yue', 'yuf', 'yug', 'yui', 'yuj', 'yuk', 'yul', 'yum', 'yun', 'yup', 'yuq', 'yur', 'yut', 'yuu', 'yuw', 'yux', 'yuy', 'yuz', 'yva', 'yvt', 'ywa', 'ywg', 'ywl', 'ywn', 'ywq', 'ywr', 'ywt', 'ywu', 'yww', 'yxa', 'yxg', 'yxl', 'yxm', 'yxu', 'yxy', 'yyr', 'yyu', 'yyz', 'yzg', 'yzk', 'zaa', 'zab', 'zac', 'zad', 'zae', 'zaf', 'zag', 'zah', 'zai', 'zaj', 'zak', 'zal', 'zam', 'zao', 'zap', 'zaq', 'zar', 'zas', 'zat', 'zau', 'zav', 'zaw', 'zax', 'zay', 'zaz', 'zbc', 'zbe', 'zbl', 'zbt', 'zbw', 'zca', 'zch', 'zdj', 'zea', 'zeg', 'zeh', 'zen', 'zga', 'zgb', 'zgh', 'zgm', 'zgn', 'zgr', 'zhb', 'zhd', 'zhi', 'zhn', 'zhw', 'zhx', 'zia', 'zib', 'zik', 'zil', 'zim', 'zin', 'zir', 'ziw', 'ziz', 'zka', 'zkb', 'zkd', 'zkg', 'zkh', 'zkk', 'zkn', 'zko', 'zkp', 'zkr', 'zkt', 'zku', 'zkv', 'zkz', 'zle', 'zlj', 'zlm', 'zln', 'zlq', 'zls', 'zlw', 'zma', 'zmb', 'zmc', 'zmd', 'zme', 'zmf', 'zmg', 'zmh', 'zmi', 'zmj', 'zmk', 'zml', 'zmm', 'zmn', 'zmo', 'zmp', 'zmq', 'zmr', 'zms', 'zmt', 'zmu', 'zmv', 'zmw', 'zmx', 'zmy', 'zmz', 'zna', 'znd', 'zne', 'zng', 'znk', 'zns', 'zoc', 'zoh', 'zom', 'zoo', 'zoq', 'zor', 'zos', 'zpa', 'zpb', 'zpc', 'zpd', 'zpe', 'zpf', 'zpg', 'zph', 'zpi', 'zpj', 'zpk', 'zpl', 'zpm', 'zpn', 'zpo', 'zpp', 'zpq', 'zpr', 'zps', 'zpt', 'zpu', 'zpv', 'zpw', 'zpx', 'zpy', 'zpz', 'zqe', 'zra', 'zrg', 'zrn', 'zro', 'zrp', 'zrs', 'zsa', 'zsk', 'zsl', 'zsm', 'zsr', 'zsu', 'zte', 'ztg', 'ztl', 'ztm', 'ztn', 'ztp', 'ztq', 'zts', 'ztt', 'ztu', 'ztx', 'zty', 'zua', 'zuh', 'zum', 'zun', 'zuy', 'zwa', 'zxx', 'zyb', 'zyg', 'zyj', 'zyn', 'zyp', 'zza', 'zzj' ]; - axe.utils.validLangs = function() { - 'use strict'; - return langs; - }; - 'use strict'; - function _toConsumableArray(arr) { - return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); - } - function _nonIterableSpread() { - throw new TypeError('Invalid attempt to spread non-iterable instance'); - } - function _iterableToArray(iter) { - if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === '[object Arguments]') { - return Array.from(iter); - } - } - function _arrayWithoutHoles(arr) { - if (Array.isArray(arr)) { - for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { - arr2[i] = arr[i]; - } - return arr2; - } - } - function _extends() { - _extends = Object.assign || function(target) { - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i]; - for (var key in source) { - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - return target; - }; - return _extends.apply(this, arguments); - } - function _typeof(obj) { - if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') { - _typeof = function _typeof(obj) { - return typeof obj; - }; - } else { - _typeof = function _typeof(obj) { - return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj; - }; - } - return _typeof(obj); - } axe._load({ data: { rules: { @@ -7323,26 +4015,10 @@ description: 'Ensures ARIA attributes are allowed for an element\'s role', help: 'Elements must only use allowed ARIA attributes' }, - 'aria-allowed-role': { - description: 'Ensures role attribute has an appropriate value for the element', - help: 'ARIA role must be appropriate for the element' - }, - 'aria-dpub-role-fallback': { - description: 'Ensures unsupported DPUB roles are only used on elements with implicit fallback roles', - help: 'Unsupported DPUB ARIA roles should be used on elements with implicit fallback roles' - }, 'aria-hidden-body': { description: 'Ensures aria-hidden=\'true\' is not present on the document body.', help: 'aria-hidden=\'true\' must not be present on the document body' }, - 'aria-hidden-focus': { - description: 'Ensures aria-hidden elements do not contain focusable elements', - help: 'ARIA hidden element must not contain focusable elements' - }, - 'aria-input-field-name': { - description: 'Ensures every ARIA input field has an accessible name', - help: 'ARIA input fields have an accessible name' - }, 'aria-required-attr': { description: 'Ensures elements with ARIA roles have all required ARIA attributes', help: 'Required ARIA attributes must be provided' @@ -7359,10 +4035,6 @@ description: 'Ensures all elements with a role attribute use a valid value', help: 'ARIA roles used must conform to valid values' }, - 'aria-toggle-field-name': { - description: 'Ensures every ARIA toggle field has an accessible name', - help: 'ARIA toggle fields have an accessible name' - }, 'aria-valid-attr-value': { description: 'Ensures all ARIA attributes have valid values', help: 'ARIA attributes must conform to valid values' @@ -7375,14 +4047,6 @@ description: 'Ensures <audio> elements have captions', help: '<audio> elements must have a captions track' }, - 'autocomplete-valid': { - description: 'Ensure the autocomplete attribute is correct and suitable for the form field', - help: 'autocomplete attribute must be used correctly' - }, - 'avoid-inline-spacing': { - description: 'Ensure that text spacing set through style attributes can be adjusted with custom stylesheets', - help: 'Inline text spacing must be adjustable with custom stylesheets' - }, blink: { description: 'Ensures <blink> elements are not used', help: '<blink> elements are deprecated and must not be used' @@ -7396,17 +4060,13 @@ help: 'Page must have means to bypass repeated blocks' }, checkboxgroup: { - description: 'Ensures related <input type="checkbox"> elements have a group and that the group designation is consistent', + description: 'Ensures related <input type="checkbox"> elements have a group and that that group designation is consistent', help: 'Checkbox inputs with the same name attribute value must be part of a group' }, 'color-contrast': { description: 'Ensures the contrast between foreground and background colors meets WCAG 2 AA contrast ratio thresholds', help: 'Elements must have sufficient color contrast' }, - 'css-orientation-lock': { - description: 'Ensures content is not locked to any specific display orientation, and the content is operable in all display orientations', - help: 'CSS Media queries are not used to lock display orientation' - }, 'definition-list': { description: 'Ensures <dl> elements are structured correctly', help: '<dl> elements must only directly contain properly-ordered <dt> and <dd> groups, <script> or <template> elements' @@ -7419,14 +4079,6 @@ description: 'Ensures each HTML document contains a non-empty <title> element', help: 'Documents must have <title> element to aid in navigation' }, - 'duplicate-id-active': { - description: 'Ensures every id attribute value of active elements is unique', - help: 'IDs of active elements must be unique' - }, - 'duplicate-id-aria': { - description: 'Ensures every id attribute value used in ARIA and in labels is unique', - help: 'IDs used in ARIA and labels must be unique' - }, 'duplicate-id': { description: 'Ensures every id attribute value is unique', help: 'id attribute value must be unique' @@ -7435,18 +4087,6 @@ description: 'Ensures headings have discernible text', help: 'Headings must not be empty' }, - 'focus-order-semantics': { - description: 'Ensures elements in the focus order have an appropriate role', - help: 'Elements in the focus order need a role appropriate for interactive content' - }, - 'form-field-multiple-labels': { - description: 'Ensures form field does not have multiple label elements', - help: 'Form field must not have multiple label elements' - }, - 'frame-tested': { - description: 'Ensures <iframe> and <frame> elements contain the axe-core script', - help: 'Frames must be tested with axe-core' - }, 'frame-title-unique': { description: 'Ensures <iframe> and <frame> elements contain a unique title attribute', help: 'Frames must have a unique title attribute' @@ -7463,6 +4103,10 @@ description: 'Informs users about hidden content.', help: 'Hidden content on the page cannot be analyzed' }, + 'href-no-hash': { + description: 'Ensures that href values are valid link references to promote only using anchors as links', + help: 'Anchors must only be used as links with valid URLs or URL fragments' + }, 'html-has-lang': { description: 'Ensures every HTML document has a lang attribute', help: '<html> element must have a lang attribute' @@ -7471,30 +4115,18 @@ description: 'Ensures the lang attribute of the <html> element has a valid value', help: '<html> element must have a valid value for the lang attribute' }, - 'html-xml-lang-mismatch': { - description: 'Ensure that HTML elements with both valid lang and xml:lang attributes agree on the base language of the page', - help: 'HTML elements with lang and xml:lang must have the same base language' - }, 'image-alt': { description: 'Ensures <img> elements have alternate text or a role of none or presentation', help: 'Images must have alternate text' }, 'image-redundant-alt': { - description: 'Ensure image alternative is not repeated as text', - help: 'Alternative text of images should not be repeated as text' - }, - 'input-button-name': { - description: 'Ensures input buttons have discernible text', - help: 'Input buttons must have discernible text' + description: 'Ensure button and link text is not repeated as image alternative', + help: 'Text of buttons and links should not be repeated in the image alternative' }, 'input-image-alt': { description: 'Ensures <input type="image"> elements have alternate text', help: 'Image buttons must have alternate text' }, - 'label-content-name-mismatch': { - description: 'Ensures that elements labelled through their content must have their visible text as part of their accessible name', - help: 'Elements must have their visible text as part of their accessible name' - }, 'label-title-only': { description: 'Ensures that every form element is not solely labeled using the title or aria-describedby attributes', help: 'Form elements should have a visible label' @@ -7503,38 +4135,6 @@ description: 'Ensures every form element has a label', help: 'Form elements must have labels' }, - 'landmark-banner-is-top-level': { - description: 'Ensures the banner landmark is at top level', - help: 'Banner landmark must not be contained in another landmark' - }, - 'landmark-complementary-is-top-level': { - description: 'Ensures the complementary landmark or aside is at top level', - help: 'Aside must not be contained in another landmark' - }, - 'landmark-contentinfo-is-top-level': { - description: 'Ensures the contentinfo landmark is at top level', - help: 'Contentinfo landmark must not be contained in another landmark' - }, - 'landmark-main-is-top-level': { - description: 'Ensures the main landmark is at top level', - help: 'Main landmark must not be contained in another landmark' - }, - 'landmark-no-duplicate-banner': { - description: 'Ensures the document has at most one banner landmark', - help: 'Document must not have more than one banner landmark' - }, - 'landmark-no-duplicate-contentinfo': { - description: 'Ensures the document has at most one contentinfo landmark', - help: 'Document must not have more than one contentinfo landmark' - }, - 'landmark-one-main': { - description: 'Ensures the document has only one main landmark and each iframe in the page has at most one main landmark', - help: 'Document must have one main landmark' - }, - 'landmark-unique': { - help: 'Ensures landmarks are unique', - description: 'Landmarks must have a unique role or role/label/title (i.e. accessible name) combination' - }, 'layout-table': { description: 'Ensures presentational <table> elements do not use <th>, <caption> elements or the summary attribute', help: 'Layout tables must not use data table elements' @@ -7579,37 +4179,25 @@ description: 'Ensure p elements are not used to style headings', help: 'Bold, italic text and font-size are not used to style p elements as a heading' }, - 'page-has-heading-one': { - description: 'Ensure that the page, or at least one of its frames contains a level-one heading', - help: 'Page must contain a level-one heading' - }, radiogroup: { description: 'Ensures related <input type="radio"> elements have a group and that the group designation is consistent', help: 'Radio inputs with the same name attribute value must be part of a group' }, region: { - description: 'Ensures all page content is contained by landmarks', - help: 'All page content must be contained by landmarks' - }, - 'role-img-alt': { - description: 'Ensures [role=\'img\'] elements have alternate text', - help: '[role=\'img\'] elements have an alternative text' + description: 'Ensures all content is contained within a landmark region', + help: 'Content should be contained in a landmark region' }, 'scope-attr-valid': { description: 'Ensures the scope attribute is used correctly on tables', help: 'scope attribute should be used correctly' }, - 'scrollable-region-focusable': { - description: 'Elements that have scrollable content should be accessible by keyboard', - help: 'Ensure that scrollable region has keyboard access' - }, 'server-side-image-map': { description: 'Ensures that server-side image maps are not used', help: 'Server-side image maps must not be used' }, 'skip-link': { - description: 'Ensure all skip links have a focusable target', - help: 'The skip-link target should exist and be focusable' + description: 'Ensures the first link on the page is a skip link', + help: 'The page should have a skip link as its first link' }, tabindex: { description: 'Ensures tabindex attribute values are not greater than 0', @@ -7633,7 +4221,7 @@ }, 'th-has-data-cells': { description: 'Ensure that each table header in a data table refers to data cells', - help: 'All th elements and elements with role=columnheader/rowheader must have data cells they describe' + help: 'All th element and elements with role=columnheader/rowheader must data cells which it describes' }, 'valid-lang': { description: 'Ensures lang attributes have valid values', @@ -7709,7 +4297,7 @@ return out; }, fail: function anonymous(it) { - var out = 'aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty'; + var out = 'aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty or not visible'; return out; } } @@ -7735,57 +4323,6 @@ } } }, - 'aria-unsupported-attr': { - impact: 'critical', - messages: { - pass: function anonymous(it) { - var out = 'ARIA attribute is supported'; - return out; - }, - fail: function anonymous(it) { - var out = 'ARIA attribute is not widely supported in screen readers and assistive technologies: '; - var arr1 = it.data; - if (arr1) { - var value, i1 = -1, l1 = arr1.length - 1; - while (i1 < l1) { - value = arr1[i1 += 1]; - out += ' ' + value; - } - } - return out; - } - } - }, - 'aria-allowed-role': { - impact: 'minor', - messages: { - pass: function anonymous(it) { - var out = 'ARIA role is allowed for given element'; - return out; - }, - fail: function anonymous(it) { - var out = 'ARIA role' + (it.data && it.data.length > 1 ? 's' : '') + ' ' + it.data.join(', ') + ' ' + (it.data && it.data.length > 1 ? 'are' : ' is') + ' not allowed for given element'; - return out; - }, - incomplete: function anonymous(it) { - var out = 'ARIA role' + (it.data && it.data.length > 1 ? 's' : '') + ' ' + it.data.join(', ') + ' must be removed when the element is made visible, as ' + (it.data && it.data.length > 1 ? 'they are' : 'it is') + ' not allowed for the element'; - return out; - } - } - }, - 'implicit-role-fallback': { - impact: 'moderate', - messages: { - pass: function anonymous(it) { - var out = 'Element’s implicit ARIA role is an appropriate fallback'; - return out; - }, - fail: function anonymous(it) { - var out = 'Element’s implicit ARIA role is not a good fallback for the (unsupported) role'; - return out; - } - } - }, 'aria-hidden-body': { impact: 'critical', messages: { @@ -7799,45 +4336,6 @@ } } }, - 'focusable-disabled': { - impact: 'serious', - messages: { - pass: function anonymous(it) { - var out = 'No focusable elements contained within element'; - return out; - }, - fail: function anonymous(it) { - var out = 'Focusable content should be disabled or be removed from the DOM'; - return out; - } - } - }, - 'focusable-not-tabbable': { - impact: 'serious', - messages: { - pass: function anonymous(it) { - var out = 'No focusable elements contained within element'; - return out; - }, - fail: function anonymous(it) { - var out = 'Focusable content should have tabindex=\'-1\' or be removed from the DOM'; - return out; - } - } - }, - 'no-implicit-explicit-label': { - impact: 'moderate', - messages: { - pass: function anonymous(it) { - var out = 'There is no mismatch between a <label> and accessible name'; - return out; - }, - incomplete: function anonymous(it) { - var out = 'Check that the <label> does not need be part of the ARIA ' + it.data + ' field\'s name'; - return out; - } - } - }, 'aria-required-attr': { impact: 'critical', messages: { @@ -7877,18 +4375,6 @@ } } return out; - }, - incomplete: function anonymous(it) { - var out = 'Expecting ARIA ' + (it.data && it.data.length > 1 ? 'children' : 'child') + ' role to be added:'; - var arr1 = it.data; - if (arr1) { - var value, i1 = -1, l1 = arr1.length - 1; - while (i1 < l1) { - value = arr1[i1 += 1]; - out += ' ' + value; - } - } - return out; } } }, @@ -7939,40 +4425,6 @@ } } }, - unsupportedrole: { - impact: 'critical', - messages: { - pass: function anonymous(it) { - var out = 'ARIA role is supported'; - return out; - }, - fail: function anonymous(it) { - var out = 'The role used is not widely supported in screen readers and assistive technologies: '; - var arr1 = it.data; - if (arr1) { - var value, i1 = -1, l1 = arr1.length - 1; - while (i1 < l1) { - value = arr1[i1 += 1]; - out += ' ' + value; - } - } - return out; - } - } - }, - 'has-visible-text': { - impact: 'minor', - messages: { - pass: function anonymous(it) { - var out = 'Element has text that is visible to screen readers'; - return out; - }, - fail: function anonymous(it) { - var out = 'Element does not have text that is visible to screen readers'; - return out; - } - } - }, 'aria-valid-attr-value': { impact: 'critical', messages: { @@ -7991,40 +4443,6 @@ } } return out; - }, - incomplete: function anonymous(it) { - var out = 'ARIA attribute' + (it.data && it.data.length > 1 ? 's' : '') + ' element ID does not exist on the page:'; - var arr1 = it.data; - if (arr1) { - var value, i1 = -1, l1 = arr1.length - 1; - while (i1 < l1) { - value = arr1[i1 += 1]; - out += ' ' + value; - } - } - return out; - } - } - }, - 'aria-errormessage': { - impact: 'critical', - messages: { - pass: function anonymous(it) { - var out = 'Uses a supported aria-errormessage technique'; - return out; - }, - fail: function anonymous(it) { - var out = 'aria-errormessage value' + (it.data && it.data.length > 1 ? 's' : '') + ' '; - var arr1 = it.data; - if (arr1) { - var value, i1 = -1, l1 = arr1.length - 1; - while (i1 < l1) { - value = arr1[i1 += 1]; - out += ' `' + value; - } - } - out += '` must use a technique to announce the message (e.g., aria-live, aria-describedby, role=alert, etc.)'; - return out; } } }, @@ -8056,47 +4474,12 @@ var out = 'The multimedia element has a captions track'; return out; }, + fail: function anonymous(it) { + var out = 'The multimedia element does not have a captions track'; + return out; + }, incomplete: function anonymous(it) { - var out = 'Check that captions is available for the element'; - return out; - } - } - }, - 'autocomplete-valid': { - impact: 'serious', - messages: { - pass: function anonymous(it) { - var out = 'the autocomplete attribute is correctly formatted'; - return out; - }, - fail: function anonymous(it) { - var out = 'the autocomplete attribute is incorrectly formatted'; - return out; - } - } - }, - 'autocomplete-appropriate': { - impact: 'serious', - messages: { - pass: function anonymous(it) { - var out = 'the autocomplete value is on an appropriate element'; - return out; - }, - fail: function anonymous(it) { - var out = 'the autocomplete value is inappropriate for this type of input'; - return out; - } - } - }, - 'avoid-inline-spacing': { - impact: 'serious', - messages: { - pass: function anonymous(it) { - var out = 'No inline styles with \'!important\' that affect text spacing has been specified'; - return out; - }, - fail: function anonymous(it) { - var out = 'Remove \'!important\' from inline style' + (it.data && it.data.length > 1 ? 's' : '') + ' ' + it.data.join(', ') + ', as overriding this is not supported by most browsers'; + var out = 'A captions track for this element could not be found'; return out; } } @@ -8114,6 +4497,37 @@ } } }, + 'non-empty-if-present': { + impact: 'critical', + messages: { + pass: function anonymous(it) { + var out = 'Element '; + if (it.data) { + out += 'has a non-empty value attribute'; + } else { + out += 'does not have a value attribute'; + } + return out; + }, + fail: function anonymous(it) { + var out = 'Element has a value attribute and the value attribute is empty'; + return out; + } + } + }, + 'non-empty-value': { + impact: 'critical', + messages: { + pass: function anonymous(it) { + var out = 'Element has a non-empty value attribute'; + return out; + }, + fail: function anonymous(it) { + var out = 'Element has no value attribute or the value attribute is empty'; + return out; + } + } + }, 'button-has-visible-text': { impact: 'critical', messages: { @@ -8153,6 +4567,19 @@ } } }, + 'focusable-no-name': { + impact: 'serious', + messages: { + pass: function anonymous(it) { + var out = 'Element is not in tab order or has accessible text'; + return out; + }, + fail: function anonymous(it) { + var out = 'Element is in tab order and does not have accessible text'; + return out; + } + } + }, 'internal-link-present': { impact: 'serious', messages: { @@ -8196,21 +4623,11 @@ impact: 'critical', messages: { pass: function anonymous(it) { - var out = 'Elements with the name "' + it.data.name + '" have both a shared label, and a unique label, referenced through aria-labelledby'; + var out = 'All elements with the name "' + it.data.name + '" reference the same element with aria-labelledby'; return out; }, fail: function anonymous(it) { - var out = ''; - var code = it.data && it.data.failureCode; - out += 'Elements with the name "' + it.data.name + '" do not all have '; - if (code === 'no-shared-label') { - out += 'a shared label'; - } else if (code === 'no-unique-label') { - out += 'a unique label'; - } else { - out += 'both a shared label, and a unique label'; - } - out += ', referenced through aria-labelledby'; + var out = 'All elements with the name "' + it.data.name + '" do not reference the same element with aria-labelledby'; return out; } } @@ -8250,7 +4667,7 @@ return out; }, fail: function anonymous(it) { - var out = 'Element has insufficient color contrast of ' + it.data.contrastRatio + ' (foreground color: ' + it.data.fgColor + ', background color: ' + it.data.bgColor + ', font size: ' + it.data.fontSize + ', font weight: ' + it.data.fontWeight + '). Expected contrast ratio of ' + it.data.expectedContrastRatio; + var out = 'Element has insufficient color contrast of ' + it.data.contrastRatio + ' (foreground color: ' + it.data.fgColor + ', background color: ' + it.data.bgColor + ', font size: ' + it.data.fontSize + ', font weight: ' + it.data.fontWeight + ')'; return out; }, incomplete: { @@ -8260,31 +4677,11 @@ bgOverlap: 'Element\'s background color could not be determined because it is overlapped by another element', fgAlpha: 'Element\'s foreground color could not be determined because of alpha transparency', elmPartiallyObscured: 'Element\'s background color could not be determined because it\'s partially obscured by another element', - elmPartiallyObscuring: 'Element\'s background color could not be determined because it partially overlaps other elements', - outsideViewport: 'Element\'s background color could not be determined because it\'s outside the viewport', equalRatio: 'Element has a 1:1 contrast ratio with the background', - shortTextContent: 'Element content is too short to determine if it is actual text content', default: 'Unable to determine contrast ratio' } } }, - 'css-orientation-lock': { - impact: 'serious', - messages: { - pass: function anonymous(it) { - var out = 'Display is operable, and orientation lock does not exist'; - return out; - }, - fail: function anonymous(it) { - var out = 'CSS Orientation lock is applied, and makes display inoperable'; - return out; - }, - incomplete: function anonymous(it) { - var out = 'CSS Orientation lock cannot be determined'; - return out; - } - } - }, 'structured-dlitems': { impact: 'serious', messages: { @@ -8337,97 +4734,28 @@ } } }, - 'duplicate-id-active': { - impact: 'serious', - messages: { - pass: function anonymous(it) { - var out = 'Document has no active elements that share the same id attribute'; - return out; - }, - fail: function anonymous(it) { - var out = 'Document has active elements with the same id attribute: ' + it.data; - return out; - } - } - }, - 'duplicate-id-aria': { - impact: 'critical', - messages: { - pass: function anonymous(it) { - var out = 'Document has no elements referenced with ARIA or labels that share the same id attribute'; - return out; - }, - fail: function anonymous(it) { - var out = 'Document has multiple elements referenced with ARIA with the same id attribute: ' + it.data; - return out; - } - } - }, 'duplicate-id': { - impact: 'minor', - messages: { - pass: function anonymous(it) { - var out = 'Document has no static elements that share the same id attribute'; - return out; - }, - fail: function anonymous(it) { - var out = 'Document has multiple static elements with the same id attribute'; - return out; - } - } - }, - 'has-widget-role': { - impact: 'minor', - messages: { - pass: function anonymous(it) { - var out = 'Element has a widget role.'; - return out; - }, - fail: function anonymous(it) { - var out = 'Element does not have a widget role.'; - return out; - } - } - }, - 'valid-scrollable-semantics': { - impact: 'minor', - messages: { - pass: function anonymous(it) { - var out = 'Element has valid semantics for an element in the focus order.'; - return out; - }, - fail: function anonymous(it) { - var out = 'Element has invalid semantics for an element in the focus order.'; - return out; - } - } - }, - 'multiple-label': { impact: 'moderate', messages: { pass: function anonymous(it) { - var out = 'Form field does not have multiple label elements'; + var out = 'Document has no elements that share the same id attribute'; return out; }, fail: function anonymous(it) { - var out = 'Multiple label elements is not widely supported in assistive technologies'; + var out = 'Document has multiple elements with the same id attribute: ' + it.data; return out; } } }, - 'frame-tested': { - impact: 'critical', + 'has-visible-text': { + impact: 'minor', messages: { pass: function anonymous(it) { - var out = 'The iframe was tested with axe-core'; + var out = 'Element has text that is visible to screen readers'; return out; }, fail: function anonymous(it) { - var out = 'The iframe could not be tested with axe-core'; - return out; - }, - incomplete: function anonymous(it) { - var out = 'The iframe still has to be tested with axe-core'; + var out = 'Element does not have text that is visible to screen readers'; return out; } } @@ -8475,6 +4803,19 @@ } } }, + 'href-no-hash': { + impact: 'moderate', + messages: { + pass: function anonymous(it) { + var out = 'Anchor does not have an href value of #'; + return out; + }, + fail: function anonymous(it) { + var out = 'Anchor has an href value of #'; + return out; + } + } + }, 'has-lang': { impact: 'serious', messages: { @@ -8501,19 +4842,6 @@ } } }, - 'xml-lang-mismatch': { - impact: 'moderate', - messages: { - pass: function anonymous(it) { - var out = 'Lang and xml:lang attributes have the same base language'; - return out; - }, - fail: function anonymous(it) { - var out = 'Lang and xml:lang attributes do not have the same base language'; - return out; - } - } - }, 'has-alt': { impact: 'critical', messages: { @@ -8527,19 +4855,6 @@ } } }, - 'alt-space-value': { - impact: 'critical', - messages: { - pass: function anonymous(it) { - var out = 'Element has a valid alt attribute value'; - return out; - }, - fail: function anonymous(it) { - var out = 'Element has an alt attribute containing only a space character, which is not ignored by all screen readers'; - return out; - } - } - }, 'duplicate-img-label': { impact: 'minor', messages: { @@ -8553,50 +4868,6 @@ } } }, - 'non-empty-if-present': { - impact: 'critical', - messages: { - pass: function anonymous(it) { - var out = 'Element '; - if (it.data) { - out += 'has a non-empty value attribute'; - } else { - out += 'does not have a value attribute'; - } - return out; - }, - fail: function anonymous(it) { - var out = 'Element has a value attribute and the value attribute is empty'; - return out; - } - } - }, - 'non-empty-value': { - impact: 'critical', - messages: { - pass: function anonymous(it) { - var out = 'Element has a non-empty value attribute'; - return out; - }, - fail: function anonymous(it) { - var out = 'Element has no value attribute or the value attribute is empty'; - return out; - } - } - }, - 'label-content-name-mismatch': { - impact: 'serious', - messages: { - pass: function anonymous(it) { - var out = 'Element contains visible text as part of it\'s accessible name'; - return out; - }, - fail: function anonymous(it) { - var out = 'Text inside the element is not included in the accessible name'; - return out; - } - } - }, 'title-only': { impact: 'serious', messages: { @@ -8649,93 +4920,15 @@ } } }, - 'hidden-explicit-label': { - impact: 'critical', + 'multiple-label': { + impact: 'serious', messages: { pass: function anonymous(it) { - var out = 'Form element has a visible explicit <label>'; + var out = 'Form element does not have multiple <label> elements'; return out; }, fail: function anonymous(it) { - var out = 'Form element has explicit <label> that is hidden'; - return out; - } - } - }, - 'landmark-is-top-level': { - impact: 'moderate', - messages: { - pass: function anonymous(it) { - var out = 'The ' + it.data.role + ' landmark is at the top level.'; - return out; - }, - fail: function anonymous(it) { - var out = 'The ' + it.data.role + ' landmark is contained in another landmark.'; - return out; - } - } - }, - 'page-no-duplicate-banner': { - impact: 'moderate', - messages: { - pass: function anonymous(it) { - var out = 'Document does not have more than one banner landmark'; - return out; - }, - fail: function anonymous(it) { - var out = 'Document has more than one banner landmark'; - return out; - } - } - }, - 'page-no-duplicate-contentinfo': { - impact: 'moderate', - messages: { - pass: function anonymous(it) { - var out = 'Document does not have more than one contentinfo landmark'; - return out; - }, - fail: function anonymous(it) { - var out = 'Document has more than one contentinfo landmark'; - return out; - } - } - }, - 'page-has-main': { - impact: 'moderate', - messages: { - pass: function anonymous(it) { - var out = 'Document has at least one main landmark'; - return out; - }, - fail: function anonymous(it) { - var out = 'Document does not have a main landmark'; - return out; - } - } - }, - 'page-no-duplicate-main': { - impact: 'moderate', - messages: { - pass: function anonymous(it) { - var out = 'Document does not have more than one main landmark'; - return out; - }, - fail: function anonymous(it) { - var out = 'Document has more than one main landmark'; - return out; - } - } - }, - 'landmark-is-unique': { - impact: 'moderate', - messages: { - pass: function anonymous(it) { - var out = 'Landmarks must have a unique role or role/label/title (i.e. accessible name) combination'; - return out; - }, - fail: function anonymous(it) { - var out = 'The landmark must have a unique aria-label, aria-labelledby, or title to make landmarks distinguishable'; + var out = 'Form element has multiple <label> elements'; return out; } } @@ -8783,11 +4976,11 @@ impact: 'serious', messages: { pass: function anonymous(it) { - var out = 'Links can be distinguished from surrounding text in some way other than by color'; + var out = 'Links can be distinguished from surrounding text in a way that does not rely on color'; return out; }, fail: function anonymous(it) { - var out = 'Links need to be distinguished from surrounding text in some way other than by color'; + var out = 'Links can not be distinguished from surrounding text in a way that does not rely on color'; return out; }, incomplete: { @@ -8800,19 +4993,6 @@ } } }, - 'focusable-no-name': { - impact: 'serious', - messages: { - pass: function anonymous(it) { - var out = 'Element is not in tab order or has accessible text'; - return out; - }, - fail: function anonymous(it) { - var out = 'Element is in tab order and does not have accessible text'; - return out; - } - } - }, 'only-listitems': { impact: 'serious', messages: { @@ -8873,7 +5053,7 @@ return out; }, fail: function anonymous(it) { - var out = '' + it.data + ' on <meta> tag disables zooming on mobile devices'; + var out = '<meta> tag disables zooming on mobile devices'; return out; } } @@ -8891,28 +5071,15 @@ } } }, - 'page-has-heading-one': { - impact: 'moderate', - messages: { - pass: function anonymous(it) { - var out = 'Page has at least one level-one heading'; - return out; - }, - fail: function anonymous(it) { - var out = 'Page must have a level-one heading'; - return out; - } - } - }, region: { impact: 'moderate', messages: { pass: function anonymous(it) { - var out = 'All page content is contained by landmarks'; + var out = 'Content contained by ARIA landmark'; return out; }, fail: function anonymous(it) { - var out = 'Some page content is not contained by landmarks'; + var out = 'Content not contained by an ARIA landmark'; return out; } } @@ -8943,32 +5110,6 @@ } } }, - 'focusable-content': { - impact: 'moderate', - messages: { - pass: function anonymous(it) { - var out = 'Element contains focusable elements'; - return out; - }, - fail: function anonymous(it) { - var out = 'Element should have focusable content'; - return out; - } - } - }, - 'focusable-element': { - impact: 'moderate', - messages: { - pass: function anonymous(it) { - var out = 'Element is focusable'; - return out; - }, - fail: function anonymous(it) { - var out = 'Element should be focusable'; - return out; - } - } - }, exists: { impact: 'minor', messages: { @@ -8986,15 +5127,11 @@ impact: 'moderate', messages: { pass: function anonymous(it) { - var out = 'Skip link target exists'; - return out; - }, - incomplete: function anonymous(it) { - var out = 'Skip link target should become visible on activation'; + var out = 'Valid skip link found'; return out; }, fail: function anonymous(it) { - var out = 'No skip link target'; + var out = 'No valid skip link found'; return out; } } @@ -9088,8 +5225,12 @@ var out = 'The multimedia element has an audio description track'; return out; }, + fail: function anonymous(it) { + var out = 'The multimedia element does not have an audio description track'; + return out; + }, incomplete: function anonymous(it) { - var out = 'Check that audio description is available for the element'; + var out = 'An audio description track for this element could not be found'; return out; } } @@ -9126,7 +5267,7 @@ } }, incompleteFallbackMessage: function anonymous(it) { - var out = 'axe couldn\'t tell the reason. Time to break out the element inspector!'; + var out = 'aXe couldn\'t tell the reason. Time to break out the element inspector!'; return out; } }, @@ -9134,7 +5275,7 @@ id: 'accesskeys', selector: '[accesskey]', excludeHidden: false, - tags: [ 'best-practice', 'cat.keyboard' ], + tags: [ 'wcag2a', 'wcag211', 'cat.keyboard' ], all: [], any: [], none: [ 'accesskeys' ] @@ -9148,53 +5289,28 @@ none: [] }, { id: 'aria-allowed-attr', - matches: function matches(node, virtualNode, context) { - var aria = /^aria-/; - if (node.hasAttributes()) { - var attrs = axe.utils.getNodeAttributes(node); - for (var i = 0, l = attrs.length; i < l; i++) { - if (aria.test(attrs[i].name)) { - return true; + matches: function matches(node, virtualNode) { + var role = node.getAttribute('role'); + if (!role) { + role = axe.commons.aria.implicitRole(node); + } + var allowed = axe.commons.aria.allowedAttr(role); + if (role && allowed) { + var aria = /^aria-/; + if (node.hasAttributes()) { + var attrs = node.attributes; + for (var i = 0, l = attrs.length; i < l; i++) { + if (aria.test(attrs[i].name)) { + return true; + } } } } return false; }, - tags: [ 'cat.aria', 'wcag2a', 'wcag412' ], + tags: [ 'cat.aria', 'wcag2a', 'wcag411', 'wcag412' ], all: [], any: [ 'aria-allowed-attr' ], - none: [ 'aria-unsupported-attr' ] - }, { - id: 'aria-allowed-role', - excludeHidden: false, - selector: '[role]', - matches: function matches(node, virtualNode, context) { - return axe.commons.aria.getRole(node, { - noImplicit: true, - dpub: true, - fallback: true - }) !== null; - }, - tags: [ 'cat.aria', 'best-practice' ], - all: [], - any: [ { - options: { - allowImplicit: true, - ignoredTags: [] - }, - id: 'aria-allowed-role' - } ], - none: [] - }, { - id: 'aria-dpub-role-fallback', - selector: '[role]', - matches: function matches(node, virtualNode, context) { - var role = node.getAttribute('role'); - return [ 'doc-backlink', 'doc-biblioentry', 'doc-biblioref', 'doc-cover', 'doc-endnote', 'doc-glossref', 'doc-noteref' ].includes(role); - }, - tags: [ 'cat.aria', 'wcag2a', 'wcag131' ], - all: [ 'implicit-role-fallback' ], - any: [], none: [] }, { id: 'aria-hidden-body', @@ -9205,60 +5321,9 @@ any: [ 'aria-hidden-body' ], none: [] }, { - id: 'aria-hidden-focus', - selector: '[aria-hidden="true"]', - matches: function matches(node, virtualNode, context) { - var getComposedParent = axe.commons.dom.getComposedParent; - function shouldMatchElement(el) { - if (!el) { - return true; - } - if (el.getAttribute('aria-hidden') === 'true') { - return false; - } - return shouldMatchElement(getComposedParent(el)); - } - return shouldMatchElement(getComposedParent(node)); - }, - excludeHidden: false, - tags: [ 'cat.name-role-value', 'wcag2a', 'wcag412', 'wcag131' ], - all: [ 'focusable-disabled', 'focusable-not-tabbable' ], - any: [], - none: [] - }, { - id: 'aria-input-field-name', - selector: '[role="combobox"], [role="listbox"], [role="searchbox"], [role="slider"], [role="spinbutton"], [role="textbox"]', - matches: function matches(node, virtualNode, context) { - var aria = axe.commons.aria; - var nodeName = node.nodeName.toUpperCase(); - var role = aria.getRole(node, { - noImplicit: true - }); - if (nodeName === 'AREA' && !!node.getAttribute('href')) { - return false; - } - if ([ 'INPUT', 'SELECT', 'TEXTAREA' ].includes(nodeName)) { - return false; - } - if (nodeName === 'IMG' || role === 'img' && nodeName !== 'SVG') { - return false; - } - if (nodeName === 'BUTTON' || role === 'button') { - return false; - } - if (role === 'combobox' && axe.utils.querySelectorAll(virtualNode, 'input:not([type="hidden"])').length) { - return false; - } - return true; - }, - tags: [ 'wcag2a', 'wcag412' ], - all: [], - any: [ 'aria-label', 'aria-labelledby', 'non-empty-title' ], - none: [ 'no-implicit-explicit-label' ] - }, { id: 'aria-required-attr', selector: '[role]', - tags: [ 'cat.aria', 'wcag2a', 'wcag412' ], + tags: [ 'cat.aria', 'wcag2a', 'wcag411', 'wcag412' ], all: [], any: [ 'aria-required-attr' ], none: [] @@ -9267,12 +5332,7 @@ selector: '[role]', tags: [ 'cat.aria', 'wcag2a', 'wcag131' ], all: [], - any: [ { - options: { - reviewEmpty: [ 'doc-bibliography', 'doc-endnotes', 'grid', 'list', 'listbox', 'table', 'tablist', 'tree', 'treegrid', 'rowgroup' ] - }, - id: 'aria-required-children' - } ], + any: [ 'aria-required-children' ], none: [] }, { id: 'aria-required-parent', @@ -9284,46 +5344,16 @@ }, { id: 'aria-roles', selector: '[role]', - tags: [ 'cat.aria', 'wcag2a', 'wcag412' ], + tags: [ 'cat.aria', 'wcag2a', 'wcag131', 'wcag411', 'wcag412' ], all: [], any: [], - none: [ 'invalidrole', 'abstractrole', 'unsupportedrole' ] - }, { - id: 'aria-toggle-field-name', - selector: '[role="checkbox"], [role="menuitemcheckbox"], [role="menuitemradio"], [role="radio"], [role="switch"]', - matches: function matches(node, virtualNode, context) { - var aria = axe.commons.aria; - var nodeName = node.nodeName.toUpperCase(); - var role = aria.getRole(node, { - noImplicit: true - }); - if (nodeName === 'AREA' && !!node.getAttribute('href')) { - return false; - } - if ([ 'INPUT', 'SELECT', 'TEXTAREA' ].includes(nodeName)) { - return false; - } - if (nodeName === 'IMG' || role === 'img' && nodeName !== 'SVG') { - return false; - } - if (nodeName === 'BUTTON' || role === 'button') { - return false; - } - if (role === 'combobox' && axe.utils.querySelectorAll(virtualNode, 'input:not([type="hidden"])').length) { - return false; - } - return true; - }, - tags: [ 'wcag2a', 'wcag412' ], - all: [], - any: [ 'aria-label', 'aria-labelledby', 'non-empty-title', 'has-visible-text' ], - none: [ 'no-implicit-explicit-label' ] + none: [ 'invalidrole', 'abstractrole' ] }, { id: 'aria-valid-attr-value', - matches: function matches(node, virtualNode, context) { + matches: function matches(node, virtualNode) { var aria = /^aria-/; if (node.hasAttributes()) { - var attrs = axe.utils.getNodeAttributes(node); + var attrs = node.attributes; for (var i = 0, l = attrs.length; i < l; i++) { if (aria.test(attrs[i].name)) { return true; @@ -9332,19 +5362,19 @@ } return false; }, - tags: [ 'cat.aria', 'wcag2a', 'wcag412' ], - all: [ { + tags: [ 'cat.aria', 'wcag2a', 'wcag131', 'wcag411', 'wcag412' ], + all: [], + any: [ { options: [], id: 'aria-valid-attr-value' - }, 'aria-errormessage' ], - any: [], + } ], none: [] }, { id: 'aria-valid-attr', - matches: function matches(node, virtualNode, context) { + matches: function matches(node, virtualNode) { var aria = /^aria-/; if (node.hasAttributes()) { - var attrs = axe.utils.getNodeAttributes(node); + var attrs = node.attributes; for (var i = 0, l = attrs.length; i < l; i++) { if (aria.test(attrs[i].name)) { return true; @@ -9353,7 +5383,7 @@ } return false; }, - tags: [ 'cat.aria', 'wcag2a', 'wcag412' ], + tags: [ 'cat.aria', 'wcag2a', 'wcag411' ], all: [], any: [ { options: [], @@ -9363,57 +5393,12 @@ }, { id: 'audio-caption', selector: 'audio', - enabled: false, excludeHidden: false, - tags: [ 'cat.time-and-media', 'wcag2a', 'wcag121', 'section508', 'section508.22.a' ], + tags: [ 'cat.time-and-media', 'wcag2a', 'wcag122', 'section508', 'section508.22.a' ], all: [], any: [], none: [ 'caption' ] }, { - id: 'autocomplete-valid', - matches: function matches(node, virtualNode, context) { - var _axe$commons = axe.commons, text = _axe$commons.text, aria = _axe$commons.aria, dom = _axe$commons.dom; - var autocomplete = virtualNode.attr('autocomplete'); - if (!autocomplete || text.sanitize(autocomplete) === '') { - return false; - } - var nodeName = virtualNode.props.nodeName; - if ([ 'textarea', 'input', 'select' ].includes(nodeName) === false) { - return false; - } - var excludedInputTypes = [ 'submit', 'reset', 'button', 'hidden' ]; - if (nodeName === 'input' && excludedInputTypes.includes(virtualNode.props.type)) { - return false; - } - var ariaDisabled = virtualNode.attr('aria-disabled') || 'false'; - if (virtualNode.hasAttr('disabled') || ariaDisabled.toLowerCase() === 'true') { - return false; - } - var role = virtualNode.attr('role'); - var tabIndex = virtualNode.attr('tabindex'); - if (tabIndex === '-1' && role) { - var roleDef = aria.lookupTable.role[role]; - if (roleDef === undefined || roleDef.type !== 'widget') { - return false; - } - } - if (tabIndex === '-1' && virtualNode.actualNode && !dom.isVisible(virtualNode.actualNode, false) && !dom.isVisible(virtualNode.actualNode, true)) { - return false; - } - return true; - }, - tags: [ 'cat.forms', 'wcag21aa', 'wcag135' ], - all: [ 'autocomplete-valid', 'autocomplete-appropriate' ], - any: [], - none: [] - }, { - id: 'avoid-inline-spacing', - selector: '[style]', - tags: [ 'wcag21aa', 'wcag1412' ], - all: [ 'avoid-inline-spacing' ], - any: [], - none: [] - }, { id: 'blink', selector: 'blink', excludeHidden: false, @@ -9423,16 +5408,16 @@ none: [ 'is-on-screen' ] }, { id: 'button-name', - selector: 'button, [role="button"]', + selector: 'button, [role="button"], input[type="button"], input[type="submit"], input[type="reset"]', tags: [ 'cat.name-role-value', 'wcag2a', 'wcag412', 'section508', 'section508.22.a' ], all: [], - any: [ 'button-has-visible-text', 'aria-label', 'aria-labelledby', 'role-presentation', 'role-none', 'non-empty-title' ], - none: [] + any: [ 'non-empty-if-present', 'non-empty-value', 'button-has-visible-text', 'aria-label', 'aria-labelledby', 'role-presentation', 'role-none' ], + none: [ 'focusable-no-name' ] }, { id: 'bypass', selector: 'html', pageLevel: true, - matches: function matches(node, virtualNode, context) { + matches: function matches(node, virtualNode) { return !!node.querySelector('a[href]'); }, tags: [ 'cat.keyboard', 'wcag2a', 'wcag241', 'section508', 'section508.22.o' ], @@ -9448,9 +5433,9 @@ none: [] }, { id: 'color-contrast', - matches: function matches(node, virtualNode, context) { + matches: function matches(node, virtualNode) { var nodeName = node.nodeName.toUpperCase(), nodeType = node.type; - if (node.getAttribute('aria-disabled') === 'true' || axe.commons.dom.findUpVirtual(virtualNode, '[aria-disabled="true"]')) { + if (node.getAttribute('aria-disabled') === 'true' || axe.commons.dom.findUp(node, '[aria-disabled="true"]')) { return false; } if (nodeName === 'INPUT') { @@ -9465,39 +5450,37 @@ if (nodeName === 'OPTION') { return false; } - if (nodeName === 'BUTTON' && node.disabled || axe.commons.dom.findUpVirtual(virtualNode, 'button[disabled]')) { + if (nodeName === 'BUTTON' && node.disabled || axe.commons.dom.findUp(node, 'button[disabled]')) { return false; } - if (nodeName === 'FIELDSET' && node.disabled || axe.commons.dom.findUpVirtual(virtualNode, 'fieldset[disabled]')) { + if (nodeName === 'FIELDSET' && node.disabled || axe.commons.dom.findUp(node, 'fieldset[disabled]')) { return false; } - var nodeParentLabel = axe.commons.dom.findUpVirtual(virtualNode, 'label'); + var nodeParentLabel = axe.commons.dom.findUp(node, 'label'); if (nodeName === 'LABEL' || nodeParentLabel) { var relevantNode = node; - var relevantVirtualNode = virtualNode; if (nodeParentLabel) { relevantNode = nodeParentLabel; - relevantVirtualNode = axe.utils.getNodeFromTree(nodeParentLabel); } var doc = axe.commons.dom.getRootNode(relevantNode); var candidate = relevantNode.htmlFor && doc.getElementById(relevantNode.htmlFor); if (candidate && candidate.disabled) { return false; } - var candidate = axe.utils.querySelectorAll(relevantVirtualNode, 'input:not([type="hidden"]):not([type="image"])' + ':not([type="button"]):not([type="submit"]):not([type="reset"]), select, textarea'); + var candidate = axe.utils.querySelectorAll(virtualNode, 'input:not([type="hidden"]):not([type="image"])' + ':not([type="button"]):not([type="submit"]):not([type="reset"]), select, textarea'); if (candidate.length && candidate[0].actualNode.disabled) { return false; } } if (node.getAttribute('id')) { - var id = axe.utils.escapeSelector(node.getAttribute('id')); + var id = axe.commons.utils.escapeSelector(node.getAttribute('id')); var _doc = axe.commons.dom.getRootNode(node); var candidate = _doc.querySelector('[aria-labelledby~=' + id + ']'); if (candidate && candidate.disabled) { return false; } } - if (axe.commons.text.visibleVirtual(virtualNode, false, true) === '') { + if (axe.commons.text.visible(virtualNode, false, true) === '') { return false; } var range = document.createRange(), childNodes = virtualNode.children, length = childNodes.length, child, index; @@ -9525,17 +5508,9 @@ any: [ 'color-contrast' ], none: [] }, { - id: 'css-orientation-lock', - selector: 'html', - tags: [ 'cat.structure', 'wcag134', 'wcag21aa', 'experimental' ], - all: [ 'css-orientation-lock' ], - any: [], - none: [], - preload: true - }, { id: 'definition-list', selector: 'dl', - matches: function matches(node, virtualNode, context) { + matches: function matches(node, virtualNode) { return !node.getAttribute('role'); }, tags: [ 'cat.structure', 'wcag2a', 'wcag131' ], @@ -9545,7 +5520,7 @@ }, { id: 'dlitem', selector: 'dd, dt', - matches: function matches(node, virtualNode, context) { + matches: function matches(node, virtualNode) { return !node.getAttribute('role'); }, tags: [ 'cat.structure', 'wcag2a', 'wcag131' ], @@ -9555,7 +5530,7 @@ }, { id: 'document-title', selector: 'html', - matches: function matches(node, virtualNode, context) { + matches: function matches(node, virtualNode) { return node.ownerDocument.defaultView.self === node.ownerDocument.defaultView.top; }, tags: [ 'cat.text-alternatives', 'wcag2a', 'wcag242' ], @@ -9563,43 +5538,8 @@ any: [ 'doc-has-title' ], none: [] }, { - id: 'duplicate-id-active', - selector: '[id]', - matches: function matches(node, virtualNode, context) { - var _axe$commons2 = axe.commons, dom = _axe$commons2.dom, aria = _axe$commons2.aria; - var id = node.getAttribute('id').trim(); - var idSelector = '*[id="'.concat(axe.utils.escapeSelector(id), '"]'); - var idMatchingElms = Array.from(dom.getRootNode(node).querySelectorAll(idSelector)); - return idMatchingElms.some(dom.isFocusable) && !aria.isAccessibleRef(node); - }, - excludeHidden: false, - tags: [ 'cat.parsing', 'wcag2a', 'wcag411' ], - all: [], - any: [ 'duplicate-id-active' ], - none: [] - }, { - id: 'duplicate-id-aria', - selector: '[id]', - matches: function matches(node, virtualNode, context) { - return axe.commons.aria.isAccessibleRef(node); - }, - excludeHidden: false, - tags: [ 'cat.parsing', 'wcag2a', 'wcag411' ], - all: [], - any: [ 'duplicate-id-aria' ], - none: [] - }, { id: 'duplicate-id', selector: '[id]', - matches: function matches(node, virtualNode, context) { - var _axe$commons3 = axe.commons, dom = _axe$commons3.dom, aria = _axe$commons3.aria; - var id = node.getAttribute('id').trim(); - var idSelector = '*[id="'.concat(axe.utils.escapeSelector(id), '"]'); - var idMatchingElms = Array.from(dom.getRootNode(node).querySelectorAll(idSelector)); - return idMatchingElms.every(function(elm) { - return !dom.isFocusable(elm); - }) && !aria.isAccessibleRef(node); - }, excludeHidden: false, tags: [ 'cat.parsing', 'wcag2a', 'wcag411' ], all: [], @@ -9608,67 +5548,15 @@ }, { id: 'empty-heading', selector: 'h1, h2, h3, h4, h5, h6, [role="heading"]', - matches: function matches(node, virtualNode, context) { - var explicitRoles; - if (node.hasAttribute('role')) { - explicitRoles = node.getAttribute('role').split(/\s+/i).filter(axe.commons.aria.isValidRole); - } - if (explicitRoles && explicitRoles.length > 0) { - return explicitRoles.includes('heading'); - } else { - return axe.commons.aria.implicitRole(node) === 'heading'; - } - }, + enabled: true, tags: [ 'cat.name-role-value', 'best-practice' ], all: [], - any: [ 'has-visible-text' ], - none: [] - }, { - id: 'focus-order-semantics', - selector: 'div, h1, h2, h3, h4, h5, h6, [role=heading], p, span', - matches: function matches(node, virtualNode, context) { - return axe.commons.dom.insertedIntoFocusOrder(node); - }, - tags: [ 'cat.keyboard', 'best-practice', 'experimental' ], - all: [], - any: [ { - options: [], - id: 'has-widget-role' - }, { - options: [], - id: 'valid-scrollable-semantics' - } ], - none: [] - }, { - id: 'form-field-multiple-labels', - selector: 'input, select, textarea', - matches: function matches(node, virtualNode, context) { - if (node.nodeName.toLowerCase() !== 'input' || node.hasAttribute('type') === false) { - return true; - } - var type = node.getAttribute('type').toLowerCase(); - return [ 'hidden', 'image', 'button', 'submit', 'reset' ].includes(type) === false; - }, - tags: [ 'cat.forms', 'wcag2a', 'wcag332' ], - all: [], - any: [], - none: [ 'multiple-label' ] - }, { - id: 'frame-tested', - selector: 'frame, iframe', - tags: [ 'cat.structure', 'review-item', 'best-practice' ], - all: [ { - options: { - isViolation: false - }, - id: 'frame-tested' - } ], - any: [], + any: [ 'has-visible-text', 'role-presentation', 'role-none' ], none: [] }, { id: 'frame-title-unique', selector: 'frame[title], iframe[title]', - matches: function matches(node, virtualNode, context) { + matches: function matches(node, virtualNode) { var title = node.getAttribute('title'); return !!(title ? axe.commons.text.sanitize(title).trim() : ''); }, @@ -9679,24 +5567,14 @@ }, { id: 'frame-title', selector: 'frame, iframe', - tags: [ 'cat.text-alternatives', 'wcag2a', 'wcag241', 'wcag412', 'section508', 'section508.22.i' ], + tags: [ 'cat.text-alternatives', 'wcag2a', 'wcag241', 'section508', 'section508.22.i' ], all: [], any: [ 'aria-label', 'aria-labelledby', 'non-empty-title', 'role-presentation', 'role-none' ], none: [] }, { id: 'heading-order', - selector: 'h1, h2, h3, h4, h5, h6, [role=heading]', - matches: function matches(node, virtualNode, context) { - var explicitRoles; - if (node.hasAttribute('role')) { - explicitRoles = node.getAttribute('role').split(/\s+/i).filter(axe.commons.aria.isValidRole); - } - if (explicitRoles && explicitRoles.length > 0) { - return explicitRoles.includes('heading'); - } else { - return axe.commons.aria.implicitRole(node) === 'heading'; - } - }, + selector: 'h1,h2,h3,h4,h5,h6,[role=heading]', + enabled: false, tags: [ 'cat.semantics', 'best-practice' ], all: [], any: [ 'heading-order' ], @@ -9705,62 +5583,48 @@ id: 'hidden-content', selector: '*', excludeHidden: false, - tags: [ 'cat.structure', 'experimental', 'review-item', 'best-practice' ], + tags: [ 'experimental', 'review-item' ], all: [], any: [ 'hidden-content' ], + none: [], + enabled: false + }, { + id: 'href-no-hash', + selector: 'a[href]', + enabled: false, + tags: [ 'cat.semantics', 'best-practice' ], + all: [], + any: [ 'href-no-hash' ], none: [] }, { id: 'html-has-lang', selector: 'html', - matches: function matches(node, virtualNode, context) { - return node.ownerDocument.defaultView.self === node.ownerDocument.defaultView.top; - }, tags: [ 'cat.language', 'wcag2a', 'wcag311' ], all: [], any: [ 'has-lang' ], none: [] }, { id: 'html-lang-valid', - selector: 'html[lang], html[xml\\:lang]', + selector: 'html[lang]', tags: [ 'cat.language', 'wcag2a', 'wcag311' ], all: [], any: [], none: [ 'valid-lang' ] }, { - id: 'html-xml-lang-mismatch', - selector: 'html[lang][xml\\:lang]', - matches: function matches(node, virtualNode, context) { - var getBaseLang = axe.utils.getBaseLang; - var primaryLangValue = getBaseLang(node.getAttribute('lang')); - var primaryXmlLangValue = getBaseLang(node.getAttribute('xml:lang')); - return axe.utils.validLangs().includes(primaryLangValue) && axe.utils.validLangs().includes(primaryXmlLangValue); - }, - tags: [ 'cat.language', 'wcag2a', 'wcag311' ], - all: [ 'xml-lang-mismatch' ], - any: [], - none: [] - }, { id: 'image-alt', - selector: 'img', + selector: 'img, [role=\'img\']', tags: [ 'cat.text-alternatives', 'wcag2a', 'wcag111', 'section508', 'section508.22.a' ], all: [], any: [ 'has-alt', 'aria-label', 'aria-labelledby', 'non-empty-title', 'role-presentation', 'role-none' ], - none: [ 'alt-space-value' ] + none: [] }, { id: 'image-redundant-alt', - selector: 'img', + selector: 'button, [role="button"], a[href], p, li, td, th', tags: [ 'cat.text-alternatives', 'best-practice' ], all: [], any: [], none: [ 'duplicate-img-label' ] }, { - id: 'input-button-name', - selector: 'input[type="button"], input[type="submit"], input[type="reset"]', - tags: [ 'cat.name-role-value', 'wcag2a', 'wcag412', 'section508', 'section508.22.a' ], - all: [], - any: [ 'non-empty-if-present', 'non-empty-value', 'aria-label', 'aria-labelledby', 'role-presentation', 'role-none', 'non-empty-title' ], - none: [] - }, { id: 'input-image-alt', selector: 'input[type="image"]', tags: [ 'cat.text-alternatives', 'wcag2a', 'wcag111', 'section508', 'section508.22.a' ], @@ -9768,43 +5632,19 @@ any: [ 'non-empty-alt', 'aria-label', 'aria-labelledby', 'non-empty-title' ], none: [] }, { - id: 'label-content-name-mismatch', - matches: function matches(node, virtualNode, context) { - var _axe$commons4 = axe.commons, aria = _axe$commons4.aria, text = _axe$commons4.text; - var role = aria.getRole(node); - if (!role) { - return false; + id: 'label-title-only', + selector: 'input, select, textarea', + matches: function matches(node, virtualNode) { + if (node.nodeName.toLowerCase() !== 'input') { + return true; } - var isWidgetType = aria.lookupTable.rolesOfType.widget.includes(role); - if (!isWidgetType) { - return false; - } - var rolesWithNameFromContents = aria.getRolesWithNameFromContents(); - if (!rolesWithNameFromContents.includes(role)) { - return false; - } - if (!text.sanitize(aria.arialabelText(node)) && !text.sanitize(aria.arialabelledbyText(node))) { - return false; - } - if (!text.sanitize(text.visibleVirtual(virtualNode))) { + var t = node.getAttribute('type').toLowerCase(); + if (t === 'hidden' || t === 'image' || t === 'button' || t === 'submit' || t === 'reset') { return false; } return true; }, - tags: [ 'wcag21a', 'wcag253', 'experimental' ], - all: [], - any: [ 'label-content-name-mismatch' ], - none: [] - }, { - id: 'label-title-only', - selector: 'input, select, textarea', - matches: function matches(node, virtualNode, context) { - if (node.nodeName.toLowerCase() !== 'input' || node.hasAttribute('type') === false) { - return true; - } - var type = node.getAttribute('type').toLowerCase(); - return [ 'hidden', 'image', 'button', 'submit', 'reset' ].includes(type) === false; - }, + enabled: false, tags: [ 'cat.forms', 'best-practice' ], all: [], any: [], @@ -9812,133 +5652,25 @@ }, { id: 'label', selector: 'input, select, textarea', - matches: function matches(node, virtualNode, context) { - if (node.nodeName.toLowerCase() !== 'input' || node.hasAttribute('type') === false) { + matches: function matches(node, virtualNode) { + if (node.nodeName.toLowerCase() !== 'input') { return true; } - var type = node.getAttribute('type').toLowerCase(); - return [ 'hidden', 'image', 'button', 'submit', 'reset' ].includes(type) === false; + var t = node.getAttribute('type').toLowerCase(); + if (t === 'hidden' || t === 'image' || t === 'button' || t === 'submit' || t === 'reset') { + return false; + } + return true; }, tags: [ 'cat.forms', 'wcag2a', 'wcag332', 'wcag131', 'section508', 'section508.22.n' ], all: [], any: [ 'aria-label', 'aria-labelledby', 'implicit-label', 'explicit-label', 'non-empty-title' ], - none: [ 'help-same-as-label', 'hidden-explicit-label' ] - }, { - id: 'landmark-banner-is-top-level', - selector: 'header:not([role]), [role=banner]', - matches: function matches(node, virtualNode, context) { - var nativeScopeFilter = 'article, aside, main, nav, section'; - return node.hasAttribute('role') || !axe.commons.dom.findUpVirtual(virtualNode, nativeScopeFilter); - }, - tags: [ 'cat.semantics', 'best-practice' ], - all: [], - any: [ 'landmark-is-top-level' ], - none: [] - }, { - id: 'landmark-complementary-is-top-level', - selector: 'aside:not([role]), [role=complementary]', - tags: [ 'cat.semantics', 'best-practice' ], - all: [], - any: [ 'landmark-is-top-level' ], - none: [] - }, { - id: 'landmark-contentinfo-is-top-level', - selector: 'footer:not([role]), [role=contentinfo]', - matches: function matches(node, virtualNode, context) { - var nativeScopeFilter = 'article, aside, main, nav, section'; - return node.hasAttribute('role') || !axe.commons.dom.findUpVirtual(virtualNode, nativeScopeFilter); - }, - tags: [ 'cat.semantics', 'best-practice' ], - all: [], - any: [ 'landmark-is-top-level' ], - none: [] - }, { - id: 'landmark-main-is-top-level', - selector: 'main:not([role]), [role=main]', - tags: [ 'cat.semantics', 'best-practice' ], - all: [], - any: [ 'landmark-is-top-level' ], - none: [] - }, { - id: 'landmark-no-duplicate-banner', - selector: 'html', - tags: [ 'cat.semantics', 'best-practice' ], - all: [], - any: [ { - options: { - selector: 'header:not([role]), [role=banner]', - nativeScopeFilter: 'article, aside, main, nav, section' - }, - id: 'page-no-duplicate-banner' - } ], - none: [] - }, { - id: 'landmark-no-duplicate-contentinfo', - selector: 'html', - tags: [ 'cat.semantics', 'best-practice' ], - all: [], - any: [ { - options: { - selector: 'footer:not([role]), [role=contentinfo]', - nativeScopeFilter: 'article, aside, main, nav, section' - }, - id: 'page-no-duplicate-contentinfo' - } ], - none: [] - }, { - id: 'landmark-one-main', - selector: 'html', - tags: [ 'cat.semantics', 'best-practice' ], - all: [ { - options: { - selector: 'main:not([role]), [role=\'main\']' - }, - id: 'page-has-main' - }, { - options: { - selector: 'main:not([role]), [role=\'main\']' - }, - id: 'page-no-duplicate-main' - } ], - any: [], - none: [] - }, { - id: 'landmark-unique', - selector: '[role=banner], [role=complementary], [role=contentinfo], [role=main], [role=navigation], [role=region], [role=search], [role=form], form, footer, header, aside, main, nav, section', - tags: [ 'cat.semantics', 'best-practice' ], - matches: function matches(node, virtualNode, context) { - var excludedParentsForHeaderFooterLandmarks = [ 'article', 'aside', 'main', 'nav', 'section' ].join(','); - function isHeaderFooterLandmark(headerFooterElement) { - return !axe.commons.dom.findUpVirtual(headerFooterElement, excludedParentsForHeaderFooterLandmarks); - } - function isLandmarkVirtual(virtualNode) { - var actualNode = virtualNode.actualNode; - var landmarkRoles = axe.commons.aria.getRolesByType('landmark'); - var role = axe.commons.aria.getRole(actualNode); - if (!role) { - return false; - } - var nodeName = actualNode.nodeName.toUpperCase(); - if (nodeName === 'HEADER' || nodeName === 'FOOTER') { - return isHeaderFooterLandmark(virtualNode); - } - if (nodeName === 'SECTION' || nodeName === 'FORM') { - var accessibleText = axe.commons.text.accessibleTextVirtual(virtualNode); - return !!accessibleText; - } - return landmarkRoles.indexOf(role) >= 0 || role === 'region'; - } - return isLandmarkVirtual(virtualNode) && axe.commons.dom.isVisible(node, true); - }, - all: [], - any: [ 'landmark-is-unique' ], - none: [] + none: [ 'help-same-as-label', 'multiple-label' ] }, { id: 'layout-table', selector: 'table', - matches: function matches(node, virtualNode, context) { - var role = (node.getAttribute('role') || '').toLowerCase(); - return !((role === 'presentation' || role === 'none') && !axe.commons.dom.isFocusable(node)) && !axe.commons.table.isDataTable(node); + matches: function matches(node, virtualNode) { + return !axe.commons.table.isDataTable(node); }, tags: [ 'cat.semantics', 'wcag2a', 'wcag131' ], all: [], @@ -9946,8 +5678,8 @@ none: [ 'has-th', 'has-caption', 'has-summary' ] }, { id: 'link-in-text-block', - selector: 'a[href], [role=link]', - matches: function matches(node, virtualNode, context) { + selector: 'a[href], *[role=link]', + matches: function matches(node, virtualNode) { var text = axe.commons.text.sanitize(node.textContent); var role = node.getAttribute('role'); if (role && role !== 'link') { @@ -9969,17 +5701,17 @@ }, { id: 'link-name', selector: 'a[href], [role=link][href]', - matches: function matches(node, virtualNode, context) { + matches: function matches(node, virtualNode) { return node.getAttribute('role') !== 'button'; }, - tags: [ 'cat.name-role-value', 'wcag2a', 'wcag412', 'wcag244', 'section508', 'section508.22.a' ], + tags: [ 'cat.name-role-value', 'wcag2a', 'wcag111', 'wcag412', 'wcag244', 'section508', 'section508.22.a' ], all: [], any: [ 'has-visible-text', 'aria-label', 'aria-labelledby', 'role-presentation', 'role-none' ], none: [ 'focusable-no-name' ] }, { id: 'list', selector: 'ul, ol', - matches: function matches(node, virtualNode, context) { + matches: function matches(node, virtualNode) { return !node.getAttribute('role'); }, tags: [ 'cat.structure', 'wcag2a', 'wcag131' ], @@ -9989,7 +5721,7 @@ }, { id: 'listitem', selector: 'li', - matches: function matches(node, virtualNode, context) { + matches: function matches(node, virtualNode) { return !node.getAttribute('role'); }, tags: [ 'cat.structure', 'wcag2a', 'wcag131' ], @@ -10044,12 +5776,12 @@ selector: 'object', tags: [ 'cat.text-alternatives', 'wcag2a', 'wcag111', 'section508', 'section508.22.a' ], all: [], - any: [ 'has-visible-text', 'aria-label', 'aria-labelledby', 'non-empty-title', 'role-presentation', 'role-none' ], + any: [ 'has-visible-text', 'aria-label', 'aria-labelledby', 'non-empty-title' ], none: [] }, { id: 'p-as-heading', selector: 'p', - matches: function matches(node, virtualNode, context) { + matches: function matches(node, virtualNode) { var children = Array.from(node.parentNode.childNodes); var nodeText = node.textContent.trim(); var isSentence = /[.!?:;](?![.!?:;])/g; @@ -10082,18 +5814,6 @@ any: [], none: [] }, { - id: 'page-has-heading-one', - selector: 'html', - tags: [ 'cat.semantics', 'best-practice' ], - all: [ { - options: { - selector: 'h1:not([role]), [role="heading"][aria-level="1"]' - }, - id: 'page-has-heading-one' - } ], - any: [], - none: [] - }, { id: 'radiogroup', selector: 'input[type=radio][name]', tags: [ 'cat.forms', 'best-practice' ], @@ -10104,46 +5824,20 @@ id: 'region', selector: 'html', pageLevel: true, + enabled: false, tags: [ 'cat.keyboard', 'best-practice' ], all: [], any: [ 'region' ], none: [] }, { - id: 'role-img-alt', - selector: '[role=\'img\']:not(svg):not(img):not(area):not(input):not(object)', - tags: [ 'cat.text-alternatives', 'wcag2a', 'wcag111', 'section508', 'section508.22.a' ], - all: [], - any: [ 'aria-label', 'aria-labelledby', 'non-empty-title' ], - none: [] - }, { id: 'scope-attr-valid', selector: 'td[scope], th[scope]', + enabled: true, tags: [ 'cat.tables', 'best-practice' ], all: [ 'html5-scope', 'scope-value' ], any: [], none: [] }, { - id: 'scrollable-region-focusable', - matches: function matches(node, virtualNode, context) { - var querySelectorAll = axe.utils.querySelectorAll; - var hasContentVirtual = axe.commons.dom.hasContentVirtual; - if (!!axe.utils.getScroll(node, 13) === false) { - return false; - } - var nodeAndDescendents = querySelectorAll(virtualNode, '*'); - var hasVisibleChildren = nodeAndDescendents.some(function(elm) { - return hasContentVirtual(elm, true, true); - }); - if (!hasVisibleChildren) { - return false; - } - return true; - }, - tags: [ 'wcag2a', 'wcag211' ], - all: [], - any: [ 'focusable-content', 'focusable-element' ], - none: [] - }, { id: 'server-side-image-map', selector: 'img[ismap]', tags: [ 'cat.text-alternatives', 'wcag2a', 'wcag211', 'section508', 'section508.22.f' ], @@ -10152,10 +5846,9 @@ none: [ 'exists' ] }, { id: 'skip-link', - selector: 'a[href^="#"], a[href^="/#"]', - matches: function matches(node, virtualNode, context) { - return axe.commons.dom.isSkipLink(node); - }, + selector: 'a[href]', + pageLevel: true, + enabled: false, tags: [ 'cat.keyboard', 'best-practice' ], all: [], any: [ 'skip-link' ], @@ -10177,7 +5870,7 @@ }, { id: 'table-fake-caption', selector: 'table', - matches: function matches(node, virtualNode, context) { + matches: function matches(node, virtualNode) { return axe.commons.table.isDataTable(node); }, tags: [ 'cat.tables', 'experimental', 'wcag2a', 'wcag131', 'section508', 'section508.22.g' ], @@ -10187,7 +5880,7 @@ }, { id: 'td-has-header', selector: 'table', - matches: function matches(node, virtualNode, context) { + matches: function matches(node, virtualNode) { if (axe.commons.table.isDataTable(node)) { var tableArray = axe.commons.table.toArray(node); return tableArray.length >= 3 && tableArray[0].length >= 3 && tableArray[1].length >= 3 && tableArray[2].length >= 3; @@ -10208,7 +5901,7 @@ }, { id: 'th-has-data-cells', selector: 'table', - matches: function matches(node, virtualNode, context) { + matches: function matches(node, virtualNode) { return axe.commons.table.isDataTable(node); }, tags: [ 'cat.tables', 'wcag2a', 'wcag131', 'section508', 'section508.22.g' ], @@ -10218,7 +5911,7 @@ }, { id: 'valid-lang', selector: '[lang], [xml\\:lang]', - matches: function matches(node, virtualNode, context) { + matches: function matches(node, virtualNode) { return node.nodeName.toLowerCase() !== 'html'; }, tags: [ 'cat.language', 'wcag2aa', 'wcag312' ], @@ -10229,7 +5922,7 @@ id: 'video-caption', selector: 'video', excludeHidden: false, - tags: [ 'cat.text-alternatives', 'wcag2a', 'wcag122', 'section508', 'section508.22.a' ], + tags: [ 'cat.text-alternatives', 'wcag2a', 'wcag122', 'wcag123', 'section508', 'section508.22.a' ], all: [], any: [], none: [ 'caption' ] @@ -10244,27 +5937,23 @@ } ], checks: [ { id: 'abstractrole', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { return axe.commons.aria.getRoleType(node.getAttribute('role')) === 'abstract'; } }, { id: 'aria-allowed-attr', - evaluate: function evaluate(node, options, virtualNode, context) { - options = options || {}; + evaluate: function evaluate(node, options, virtualNode) { var invalid = []; - var attr, attrName, allowed, role = node.getAttribute('role'), attrs = axe.utils.getNodeAttributes(node); + var attr, attrName, allowed, role = node.getAttribute('role'), attrs = node.attributes; if (!role) { role = axe.commons.aria.implicitRole(node); } allowed = axe.commons.aria.allowedAttr(role); - if (Array.isArray(options[role])) { - allowed = axe.utils.uniqueArray(options[role].concat(allowed)); - } if (role && allowed) { for (var i = 0, l = attrs.length; i < l; i++) { attr = attrs[i]; attrName = attr.name; - if (axe.commons.aria.validateAttr(attrName) && !allowed.includes(attrName)) { + if (axe.commons.aria.validateAttr(attrName) && allowed.indexOf(attrName) === -1) { invalid.push(attrName + '="' + attr.nodeValue + '"'); } } @@ -10276,130 +5965,25 @@ return true; } }, { - id: 'aria-allowed-role', - evaluate: function evaluate(node, options, virtualNode, context) { - var dom = axe.commons.dom; - var _ref = options || {}, _ref$allowImplicit = _ref.allowImplicit, allowImplicit = _ref$allowImplicit === void 0 ? true : _ref$allowImplicit, _ref$ignoredTags = _ref.ignoredTags, ignoredTags = _ref$ignoredTags === void 0 ? [] : _ref$ignoredTags; - var tagName = node.nodeName.toUpperCase(); - if (ignoredTags.map(function(t) { - return t.toUpperCase(); - }).includes(tagName)) { - return true; - } - var unallowedRoles = axe.commons.aria.getElementUnallowedRoles(node, allowImplicit); - if (unallowedRoles.length) { - this.data(unallowedRoles); - if (!dom.isVisible(node, true)) { - return undefined; - } - return false; - } - return true; - }, - options: { - allowImplicit: true, - ignoredTags: [] - } - }, { id: 'aria-hidden-body', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { return node.getAttribute('aria-hidden') !== 'true'; } }, { - id: 'aria-errormessage', - evaluate: function evaluate(node, options, virtualNode, context) { - var _axe$commons5 = axe.commons, aria = _axe$commons5.aria, dom = _axe$commons5.dom; - options = Array.isArray(options) ? options : []; - var attr = node.getAttribute('aria-errormessage'); - var hasAttr = node.hasAttribute('aria-errormessage'); - var doc = dom.getRootNode(node); - function validateAttrValue(attr) { - if (attr.trim() === '') { - return aria.lookupTable.attributes['aria-errormessage'].allowEmpty; - } - var idref = attr && doc.getElementById(attr); - if (idref) { - return idref.getAttribute('role') === 'alert' || idref.getAttribute('aria-live') === 'assertive' || axe.utils.tokenList(node.getAttribute('aria-describedby') || '').indexOf(attr) > -1; - } - } - if (options.indexOf(attr) === -1 && hasAttr) { - if (!validateAttrValue(attr)) { - this.data(axe.utils.tokenList(attr)); - return false; - } - } - return true; - } - }, { - id: 'has-widget-role', - evaluate: function evaluate(node, options, virtualNode, context) { - var role = node.getAttribute('role'); - if (role === null) { - return false; - } - var roleType = axe.commons.aria.getRoleType(role); - return roleType === 'widget' || roleType === 'composite'; - }, - options: [] - }, { - id: 'implicit-role-fallback', - evaluate: function evaluate(node, options, virtualNode, context) { - var role = node.getAttribute('role'); - if (role === null || !axe.commons.aria.isValidRole(role)) { - return true; - } - var roleType = axe.commons.aria.getRoleType(role); - return axe.commons.aria.implicitRole(node) === roleType; - } - }, { id: 'invalidrole', - evaluate: function evaluate(node, options, virtualNode, context) { - return !axe.commons.aria.isValidRole(node.getAttribute('role'), { - allowAbstract: true - }); - } - }, { - id: 'no-implicit-explicit-label', - evaluate: function evaluate(node, options, virtualNode, context) { - var _axe$commons6 = axe.commons, aria = _axe$commons6.aria, text = _axe$commons6.text; - var role = aria.getRole(node, { - noImplicit: true - }); - this.data(role); - var labelText = text.sanitize(text.labelText(virtualNode)).toLowerCase(); - var accText = text.sanitize(text.accessibleText(node)).toLowerCase(); - if (!accText && !labelText) { - return false; - } - if (!accText && labelText) { - return undefined; - } - if (!accText.includes(labelText)) { - return undefined; - } - return false; + evaluate: function evaluate(node, options, virtualNode) { + return !axe.commons.aria.isValidRole(node.getAttribute('role')); } }, { id: 'aria-required-attr', - evaluate: function evaluate(node, options, virtualNode, context) { - options = options || {}; + evaluate: function evaluate(node, options, virtualNode) { var missing = []; - var _axe$commons$forms = axe.commons.forms, isNativeTextbox = _axe$commons$forms.isNativeTextbox, isNativeSelect = _axe$commons$forms.isNativeSelect, isAriaTextbox = _axe$commons$forms.isAriaTextbox, isAriaListbox = _axe$commons$forms.isAriaListbox, isAriaCombobox = _axe$commons$forms.isAriaCombobox, isAriaRange = _axe$commons$forms.isAriaRange; - var preChecks = { - 'aria-valuenow': function ariaValuenow() { - return !(isNativeTextbox(node) || isNativeSelect(node) || isAriaTextbox(node) || isAriaListbox(node) || isAriaCombobox(node) || isAriaRange(node) && node.hasAttribute('aria-valuenow')); - } - }; if (node.hasAttributes()) { - var role = node.getAttribute('role'); - var required = axe.commons.aria.requiredAttr(role); - if (Array.isArray(options[role])) { - required = axe.utils.uniqueArray(options[role], required); - } + var attr, role = node.getAttribute('role'), required = axe.commons.aria.requiredAttr(role); if (role && required) { for (var i = 0, l = required.length; i < l; i++) { - var attr = required[i]; - if (!node.getAttribute(attr) && (preChecks[attr] ? preChecks[attr]() : true)) { + attr = required[i]; + if (!node.getAttribute(attr)) { missing.push(attr); } } @@ -10413,12 +5997,8 @@ } }, { id: 'aria-required-children', - evaluate: function evaluate(node, options, virtualNode, context) { - var requiredOwned = axe.commons.aria.requiredOwned; - var implicitNodes = axe.commons.aria.implicitNodes; - var matchesSelector = axe.utils.matchesSelector; - var idrefs = axe.commons.dom.idrefs; - var reviewEmpty = options && Array.isArray(options.reviewEmpty) ? options.reviewEmpty : []; + evaluate: function evaluate(node, options, virtualNode) { + var requiredOwned = axe.commons.aria.requiredOwned, implicitNodes = axe.commons.aria.implicitNodes, matchesSelector = axe.commons.utils.matchesSelector, idrefs = axe.commons.dom.idrefs; function owns(node, virtualTree, role, ariaOwned) { if (node === null) { return false; @@ -10436,39 +6016,27 @@ if (nodes[index] === null) { continue; } - var virtualTree = axe.utils.getNodeFromTree(nodes[index]); + var virtualTree = axe.utils.getNodeFromTree(axe._tree[0], nodes[index]); if (owns(nodes[index], virtualTree, role, true)) { return true; } } return false; } - function missingRequiredChildren(node, childRoles, all, role) { - var index, length = childRoles.length, missing = [], ownedElements = idrefs(node, 'aria-owns'); - for (index = 0; index < length; index++) { - var childRole = childRoles[index]; - if (owns(node, virtualNode, childRole) || ariaOwns(ownedElements, childRole)) { + function missingRequiredChildren(node, childRoles, all) { + var i, l = childRoles.length, missing = [], ownedElements = idrefs(node, 'aria-owns'); + for (i = 0; i < l; i++) { + var r = childRoles[i]; + if (owns(node, virtualNode, r) || ariaOwns(ownedElements, r)) { if (!all) { return null; } } else { if (all) { - missing.push(childRole); + missing.push(r); } } } - if (role === 'combobox') { - var textboxIndex = missing.indexOf('textbox'); - var textTypeInputs = [ 'text', 'search', 'email', 'url', 'tel' ]; - if (textboxIndex >= 0 && node.nodeName.toUpperCase() === 'INPUT' && textTypeInputs.includes(node.type)) { - missing.splice(textboxIndex, 1); - } - var listboxIndex = missing.indexOf('listbox'); - var expanded = node.getAttribute('aria-expanded'); - if (listboxIndex >= 0 && (!expanded || expanded === 'false')) { - missing.splice(listboxIndex, 1); - } - } if (missing.length) { return missing; } @@ -10488,29 +6056,22 @@ var all = true; childRoles = required.all; } - var missing = missingRequiredChildren(node, childRoles, all, role); + var missing = missingRequiredChildren(node, childRoles, all); if (!missing) { return true; } this.data(missing); - if (reviewEmpty.includes(role) && node.children.length === 0 && idrefs(node, 'aria-owns').length === 0) { - return undefined; - } else { - return false; - } - }, - options: { - reviewEmpty: [ 'doc-bibliography', 'doc-endnotes', 'grid', 'list', 'listbox', 'table', 'tablist', 'tree', 'treegrid', 'rowgroup' ] + return false; } }, { id: 'aria-required-parent', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { function getSelector(role) { var impliedNative = axe.commons.aria.implicitNodes(role) || []; return impliedNative.concat('[role="' + role + '"]').join(','); } - function getMissingContext(virtualNode, requiredContext, includeElement) { - var index, length, role = virtualNode.actualNode.getAttribute('role'), missing = []; + function getMissingContext(element, requiredContext, includeElement) { + var index, length, role = element.getAttribute('role'), missing = []; if (!requiredContext) { requiredContext = axe.commons.aria.requiredContext(role); } @@ -10518,10 +6079,10 @@ return null; } for (index = 0, length = requiredContext.length; index < length; index++) { - if (includeElement && axe.utils.matchesSelector(virtualNode.actualNode, getSelector(requiredContext[index]))) { + if (includeElement && axe.utils.matchesSelector(element, getSelector(requiredContext[index]))) { return null; } - if (axe.commons.dom.findUpVirtual(virtualNode, getSelector(requiredContext[index]))) { + if (axe.commons.dom.findUp(element, getSelector(requiredContext[index]))) { return null; } else { missing.push(requiredContext[index]); @@ -10533,9 +6094,9 @@ var owners = [], o = null; while (element) { if (element.getAttribute('id')) { - var id = axe.utils.escapeSelector(element.getAttribute('id')); + var id = axe.commons.utils.escapeSelector(element.getAttribute('id')); var doc = axe.commons.dom.getRootNode(element); - o = doc.querySelector('[aria-owns~='.concat(id, ']')); + o = doc.querySelector('[aria-owns~=' + id + ']'); if (o) { owners.push(o); } @@ -10544,14 +6105,14 @@ } return owners.length ? owners : null; } - var missingParents = getMissingContext(virtualNode); + var missingParents = getMissingContext(node); if (!missingParents) { return true; } var owners = getAriaOwners(node); if (owners) { for (var i = 0, l = owners.length; i < l; i++) { - missingParents = getMissingContext(axe.utils.getNodeFromTree(owners[i]), missingParents, true); + missingParents = getMissingContext(owners[i], missingParents, true); if (!missingParents) { return true; } @@ -10561,78 +6122,18 @@ return false; } }, { - id: 'aria-unsupported-attr', - evaluate: function evaluate(node, options, virtualNode, context) { - var nodeName = node.nodeName.toUpperCase(); - var lookupTable = axe.commons.aria.lookupTable; - var role = axe.commons.aria.getRole(node); - var unsupportedAttrs = Array.from(axe.utils.getNodeAttributes(node)).filter(function(_ref2) { - var name = _ref2.name; - var attribute = lookupTable.attributes[name]; - if (!axe.commons.aria.validateAttr(name)) { - return false; - } - var unsupported = attribute.unsupported; - if (_typeof(unsupported) !== 'object') { - return !!unsupported; - } - var isException = axe.commons.matches(node, unsupported.exceptions); - if (!Object.keys(lookupTable.evaluateRoleForElement).includes(nodeName)) { - return !isException; - } - return !lookupTable.evaluateRoleForElement[nodeName]({ - node: node, - role: role, - out: isException - }); - }).map(function(candidate) { - return candidate.name.toString(); - }); - if (unsupportedAttrs.length) { - this.data(unsupportedAttrs); - return true; - } - return false; - } - }, { - id: 'unsupportedrole', - evaluate: function evaluate(node, options, virtualNode, context) { - return axe.commons.aria.isUnsupportedRole(axe.commons.aria.getRole(node)); - } - }, { id: 'aria-valid-attr-value', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { options = Array.isArray(options) ? options : []; - var needsReview = []; - var invalid = []; - var aria = /^aria-/; - var attrs = axe.utils.getNodeAttributes(node); - var skipAttrs = [ 'aria-errormessage' ]; - var preChecks = { - 'aria-controls': function ariaControls() { - return node.getAttribute('aria-expanded') !== 'false' && node.getAttribute('aria-selected') !== 'false'; - }, - 'aria-owns': function ariaOwns() { - return node.getAttribute('aria-expanded') !== 'false'; - }, - 'aria-describedby': function ariaDescribedby() { - if (!axe.commons.aria.validateAttrValue(node, 'aria-describedby')) { - needsReview.push('aria-describedby="'.concat(node.getAttribute('aria-describedby'), '"')); - } - return; - } - }; + var invalid = [], aria = /^aria-/; + var attr, attrName, attrs = node.attributes; for (var i = 0, l = attrs.length; i < l; i++) { - var attr = attrs[i]; - var attrName = attr.name; - if (!skipAttrs.includes(attrName) && options.indexOf(attrName) === -1 && aria.test(attrName) && (preChecks[attrName] ? preChecks[attrName]() : true) && !axe.commons.aria.validateAttrValue(node, attrName)) { - invalid.push(''.concat(attrName, '="').concat(attr.nodeValue, '"')); + attr = attrs[i]; + attrName = attr.name; + if (options.indexOf(attrName) === -1 && aria.test(attrName) && !axe.commons.aria.validateAttrValue(node, attrName)) { + invalid.push(attrName + '="' + attr.nodeValue + '"'); } } - if (needsReview.length) { - this.data(needsReview); - return undefined; - } if (invalid.length) { this.data(invalid); return false; @@ -10642,10 +6143,10 @@ options: [] }, { id: 'aria-valid-attr', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { options = Array.isArray(options) ? options : []; var invalid = [], aria = /^aria-/; - var attr, attrs = axe.utils.getNodeAttributes(node); + var attr, attrs = node.attributes; for (var i = 0, l = attrs.length; i < l; i++) { attr = attrs[i].name; if (options.indexOf(attr) === -1 && aria.test(attr) && !axe.commons.aria.validateAttr(attr)) { @@ -10660,95 +6161,51 @@ }, options: [] }, { - id: 'valid-scrollable-semantics', - evaluate: function evaluate(node, options, virtualNode, context) { - var VALID_TAG_NAMES_FOR_SCROLLABLE_REGIONS = { - ARTICLE: true, - ASIDE: true, - NAV: true, - SECTION: true - }; - var VALID_ROLES_FOR_SCROLLABLE_REGIONS = { - application: true, - banner: false, - complementary: true, - contentinfo: true, - form: true, - main: true, - navigation: true, - region: true, - search: false - }; - function validScrollableTagName(node) { - var nodeName = node.nodeName.toUpperCase(); - return VALID_TAG_NAMES_FOR_SCROLLABLE_REGIONS[nodeName] || false; - } - function validScrollableRole(node) { - var role = node.getAttribute('role'); - if (!role) { - return false; - } - return VALID_ROLES_FOR_SCROLLABLE_REGIONS[role.toLowerCase()] || false; - } - function validScrollableSemantics(node) { - return validScrollableRole(node) || validScrollableTagName(node); - } - return validScrollableSemantics(node); - }, - options: [] - }, { id: 'color-contrast', - evaluate: function evaluate(node, options, virtualNode, context) { - var _axe$commons7 = axe.commons, dom = _axe$commons7.dom, color = _axe$commons7.color, text = _axe$commons7.text; - if (!dom.isVisible(node, false)) { + evaluate: function evaluate(node, options, virtualNode) { + if (!axe.commons.dom.isVisible(node, false)) { return true; } var noScroll = !!(options || {}).noScroll; - var bgNodes = []; - var bgColor = color.getBackgroundColor(node, bgNodes, noScroll); - var fgColor = color.getForegroundColor(node, noScroll); + var bgNodes = [], bgColor = axe.commons.color.getBackgroundColor(node, bgNodes, noScroll), fgColor = axe.commons.color.getForegroundColor(node, noScroll); var nodeStyle = window.getComputedStyle(node); var fontSize = parseFloat(nodeStyle.getPropertyValue('font-size')); var fontWeight = nodeStyle.getPropertyValue('font-weight'); var bold = [ 'bold', 'bolder', '600', '700', '800', '900' ].indexOf(fontWeight) !== -1; - var cr = color.hasValidContrastRatio(bgColor, fgColor, fontSize, bold); + var cr = axe.commons.color.hasValidContrastRatio(bgColor, fgColor, fontSize, bold); var truncatedResult = Math.floor(cr.contrastRatio * 100) / 100; var missing; if (bgColor === null) { - missing = color.incompleteData.get('bgColor'); + missing = axe.commons.color.incompleteData.get('bgColor'); } - var equalRatio = truncatedResult === 1; - var shortTextContent = text.visibleVirtual(virtualNode, false, true).length === 1; - if (equalRatio) { - missing = color.incompleteData.set('bgColor', 'equalRatio'); - } else if (shortTextContent) { - missing = 'shortTextContent'; + var equalRatio = false; + if (truncatedResult === 1) { + equalRatio = true; + missing = axe.commons.color.incompleteData.set('bgColor', 'equalRatio'); } var data = { fgColor: fgColor ? fgColor.toHexString() : undefined, bgColor: bgColor ? bgColor.toHexString() : undefined, contrastRatio: cr ? truncatedResult : undefined, - fontSize: ''.concat((fontSize * 72 / 96).toFixed(1), 'pt (').concat(fontSize, 'px)'), + fontSize: (fontSize * 72 / 96).toFixed(1) + 'pt', fontWeight: bold ? 'bold' : 'normal', - missingData: missing, - expectedContrastRatio: cr.expectedContrastRatio + ':1' + missingData: missing }; this.data(data); - if (fgColor === null || bgColor === null || equalRatio || shortTextContent && !cr.isValid) { + if (fgColor === null || bgColor === null || equalRatio) { missing = null; - color.incompleteData.clear(); + axe.commons.color.incompleteData.clear(); this.relatedNodes(bgNodes); return undefined; - } - if (!cr.isValid) { + } else if (!cr.isValid) { this.relatedNodes(bgNodes); } return cr.isValid; } }, { id: 'link-in-text-block', - evaluate: function evaluate(node, options, virtualNode, context) { - var _axe$commons8 = axe.commons, color = _axe$commons8.color, dom = _axe$commons8.dom; + evaluate: function evaluate(node, options, virtualNode) { + var _axe$commons = axe.commons, color = _axe$commons.color, dom = _axe$commons.dom; function getContrast(color1, color2) { var c1lum = color1.getRelativeLuminance(); var c2lum = color2.getRelativeLuminance(); @@ -10790,7 +6247,7 @@ nodeColor = color.getBackgroundColor(node); parentColor = color.getBackgroundColor(parentBlock); if (!nodeColor || !parentColor || getContrast(nodeColor, parentColor) >= 3) { - var reason; + var reason = void 0; if (!nodeColor || !parentColor) { reason = axe.commons.color.incompleteData.get('bgColor'); } else { @@ -10807,67 +6264,11 @@ return false; } }, { - id: 'autocomplete-appropriate', - evaluate: function evaluate(node, options, virtualNode, context) { - if (virtualNode.props.nodeName !== 'input') { - return true; - } - var number = [ 'text', 'search', 'number' ]; - var url = [ 'text', 'search', 'url' ]; - var allowedTypesMap = { - bday: [ 'text', 'search', 'date' ], - email: [ 'text', 'search', 'email' ], - 'cc-exp': [ 'text', 'search', 'month' ], - 'street-address': [ 'text' ], - tel: [ 'text', 'search', 'tel' ], - 'cc-exp-month': number, - 'cc-exp-year': number, - 'transaction-amount': number, - 'bday-day': number, - 'bday-month': number, - 'bday-year': number, - 'new-password': [ 'text', 'search', 'password' ], - 'current-password': [ 'text', 'search', 'password' ], - url: url, - photo: url, - impp: url - }; - if (_typeof(options) === 'object') { - Object.keys(options).forEach(function(key) { - if (!allowedTypesMap[key]) { - allowedTypesMap[key] = []; - } - allowedTypesMap[key] = allowedTypesMap[key].concat(options[key]); - }); - } - var autocomplete = virtualNode.attr('autocomplete'); - var autocompleteTerms = autocomplete.split(/\s+/g).map(function(term) { - return term.toLowerCase(); - }); - var purposeTerm = autocompleteTerms[autocompleteTerms.length - 1]; - if (axe.commons.text.autocomplete.stateTerms.includes(purposeTerm)) { - return true; - } - var allowedTypes = allowedTypesMap[purposeTerm]; - var type = virtualNode.hasAttr('type') ? axe.commons.text.sanitize(virtualNode.attr('type')).toLowerCase() : 'text'; - type = axe.utils.validInputTypes().includes(type) ? type : 'text'; - if (typeof allowedTypes === 'undefined') { - return type === 'text'; - } - return allowedTypes.includes(type); - } - }, { - id: 'autocomplete-valid', - evaluate: function evaluate(node, options, virtualNode, context) { - var autocomplete = virtualNode.attr('autocomplete') || ''; - return axe.commons.text.isValidAutocomplete(autocomplete, options); - } - }, { id: 'fieldset', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { var failureCode, self = this; function getUnrelatedElements(parent, name) { - return axe.utils.toArray(parent.querySelectorAll('select,textarea,button,input:not([name="' + name + '"]):not([type="hidden"])')); + return axe.commons.utils.toArray(parent.querySelectorAll('select,textarea,button,input:not([name="' + name + '"]):not([type="hidden"])')); } function checkFieldset(group, name) { var firstNode = group.firstElementChild; @@ -10908,22 +6309,22 @@ return true; } function spliceCurrentNode(nodes, current) { - return axe.utils.toArray(nodes).filter(function(candidate) { + return axe.commons.utils.toArray(nodes).filter(function(candidate) { return candidate !== current; }); } - function runCheck(virtualNode) { - var name = axe.utils.escapeSelector(virtualNode.actualNode.name); - var root = axe.commons.dom.getRootNode(virtualNode.actualNode); - var matchingNodes = root.querySelectorAll('input[type="' + axe.utils.escapeSelector(virtualNode.actualNode.type) + '"][name="' + name + '"]'); + function runCheck(element) { + var name = axe.commons.utils.escapeSelector(node.name); + var root = axe.commons.dom.getRootNode(node); + var matchingNodes = root.querySelectorAll('input[type="' + axe.commons.utils.escapeSelector(node.type) + '"][name="' + name + '"]'); if (matchingNodes.length < 2) { return true; } - var fieldset = axe.commons.dom.findUpVirtual(virtualNode, 'fieldset'); - var group = axe.commons.dom.findUpVirtual(virtualNode, '[role="group"]' + (virtualNode.actualNode.type === 'radio' ? ',[role="radiogroup"]' : '')); + var fieldset = axe.commons.dom.findUp(element, 'fieldset'); + var group = axe.commons.dom.findUp(element, '[role="group"]' + (node.type === 'radio' ? ',[role="radiogroup"]' : '')); if (!group && !fieldset) { failureCode = 'no-group'; - self.relatedNodes(spliceCurrentNode(matchingNodes, virtualNode.actualNode)); + self.relatedNodes(spliceCurrentNode(matchingNodes, element)); return false; } else if (fieldset) { return checkFieldset(fieldset, name); @@ -10935,7 +6336,7 @@ name: node.getAttribute('name'), type: node.getAttribute('type') }; - var result = runCheck(virtualNode); + var result = runCheck(node); if (!result) { data.failureCode = failureCode; } @@ -10968,58 +6369,27 @@ } }, { id: 'group-labelledby', - evaluate: function evaluate(node, options, virtualNode, context) { - var _axe$commons9 = axe.commons, dom = _axe$commons9.dom, text = _axe$commons9.text; - var type = axe.utils.escapeSelector(node.type); - var name = axe.utils.escapeSelector(node.name); - var doc = dom.getRootNode(node); - var data = { - name: node.name, - type: node.type - }; - var matchingNodes = Array.from(doc.querySelectorAll('input[type="'.concat(type, '"][name="').concat(name, '"]'))); + evaluate: function evaluate(node, options, virtualNode) { + this.data({ + name: node.getAttribute('name'), + type: node.getAttribute('type') + }); + var doc = axe.commons.dom.getRootNode(node); + var matchingNodes = doc.querySelectorAll('input[type="' + axe.commons.utils.escapeSelector(node.type) + '"][name="' + axe.commons.utils.escapeSelector(node.name) + '"]'); if (matchingNodes.length <= 1) { - this.data(data); return true; } - var sharedLabels = dom.idrefs(node, 'aria-labelledby').filter(function(label) { - return !!label; - }); - var uniqueLabels = sharedLabels.slice(); - matchingNodes.forEach(function(groupItem) { - if (groupItem === node) { - return; - } - var labels = dom.idrefs(groupItem, 'aria-labelledby').filter(function(newLabel) { - return newLabel; + return [].map.call(matchingNodes, function(m) { + var l = m.getAttribute('aria-labelledby'); + return l ? l.split(/\s+/) : []; + }).reduce(function(prev, curr) { + return prev.filter(function(n) { + return curr.includes(n); }); - sharedLabels = sharedLabels.filter(function(sharedLabel) { - return labels.includes(sharedLabel); - }); - uniqueLabels = uniqueLabels.filter(function(uniqueLabel) { - return !labels.includes(uniqueLabel); - }); - }); - var accessibleTextOptions = { - inLabelledByContext: true - }; - uniqueLabels = uniqueLabels.filter(function(labelNode) { - return text.accessibleText(labelNode, accessibleTextOptions); - }); - sharedLabels = sharedLabels.filter(function(labelNode) { - return text.accessibleText(labelNode, accessibleTextOptions); - }); - if (uniqueLabels.length > 0 && sharedLabels.length > 0) { - this.data(data); - return true; - } - if (uniqueLabels.length > 0 && sharedLabels.length === 0) { - data.failureCode = 'no-shared-label'; - } else if (uniqueLabels.length === 0 && sharedLabels.length > 0) { - data.failureCode = 'no-unique-label'; - } - this.data(data); - return false; + }).filter(function(n) { + var labelNode = doc.getElementById(n); + return labelNode && axe.commons.text.accessibleText(labelNode); + }).length !== 0; }, after: function after(results, options) { var seen = {}; @@ -11037,7 +6407,7 @@ } }, { id: 'accesskeys', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { if (axe.commons.dom.isVisible(node, false)) { this.data(node.getAttribute('accesskey')); this.relatedNodes([ node ]); @@ -11064,256 +6434,51 @@ }); } }, { - id: 'focusable-content', - evaluate: function evaluate(node, options, virtualNode, context) { - var tabbableElements = virtualNode.tabbableElements; - if (!tabbableElements) { - return false; - } - var tabbableContentElements = tabbableElements.filter(function(el) { - return el !== virtualNode; - }); - return tabbableContentElements.length > 0; - } - }, { - id: 'focusable-disabled', - evaluate: function evaluate(node, options, virtualNode, context) { - var elementsThatCanBeDisabled = [ 'BUTTON', 'FIELDSET', 'INPUT', 'SELECT', 'TEXTAREA' ]; - var tabbableElements = virtualNode.tabbableElements; - if (!tabbableElements || !tabbableElements.length) { - return true; - } - var relatedNodes = tabbableElements.reduce(function(out, _ref3) { - var el = _ref3.actualNode; - var nodeName = el.nodeName.toUpperCase(); - if (elementsThatCanBeDisabled.includes(nodeName)) { - out.push(el); - } - return out; - }, []); - this.relatedNodes(relatedNodes); - return relatedNodes.length === 0; - } - }, { - id: 'focusable-element', - evaluate: function evaluate(node, options, virtualNode, context) { - var isFocusable = virtualNode.isFocusable; - var tabIndex = parseInt(virtualNode.actualNode.getAttribute('tabindex'), 10); - tabIndex = !isNaN(tabIndex) ? tabIndex : null; - return tabIndex ? isFocusable && tabIndex >= 0 : isFocusable; - } - }, { id: 'focusable-no-name', - evaluate: function evaluate(node, options, virtualNode, context) { - var tabIndex = node.getAttribute('tabindex'), inFocusOrder = axe.commons.dom.isFocusable(node) && tabIndex > -1; - if (!inFocusOrder) { + evaluate: function evaluate(node, options, virtualNode) { + var tabIndex = node.getAttribute('tabindex'), isFocusable = axe.commons.dom.isFocusable(node) && tabIndex > -1; + if (!isFocusable) { return false; } - return !axe.commons.text.accessibleTextVirtual(virtualNode); - } - }, { - id: 'focusable-not-tabbable', - evaluate: function evaluate(node, options, virtualNode, context) { - var elementsThatCanBeDisabled = [ 'BUTTON', 'FIELDSET', 'INPUT', 'SELECT', 'TEXTAREA' ]; - var tabbableElements = virtualNode.tabbableElements; - if (!tabbableElements || !tabbableElements.length) { - return true; - } - var relatedNodes = tabbableElements.reduce(function(out, _ref4) { - var el = _ref4.actualNode; - var nodeName = el.nodeName.toUpperCase(); - if (!elementsThatCanBeDisabled.includes(nodeName)) { - out.push(el); - } - return out; - }, []); - this.relatedNodes(relatedNodes); - return relatedNodes.length === 0; - } - }, { - id: 'landmark-is-top-level', - evaluate: function evaluate(node, options, virtualNode, context) { - var landmarks = axe.commons.aria.getRolesByType('landmark'); - var parent = axe.commons.dom.getComposedParent(node); - this.data({ - role: node.getAttribute('role') || axe.commons.aria.implicitRole(node) - }); - while (parent) { - var role = parent.getAttribute('role'); - if (!role && parent.nodeName.toUpperCase() !== 'FORM') { - role = axe.commons.aria.implicitRole(parent); - } - if (role && landmarks.includes(role)) { - return false; - } - parent = axe.commons.dom.getComposedParent(parent); - } - return true; - } - }, { - id: 'page-has-heading-one', - evaluate: function evaluate(node, options, virtualNode, context) { - if (!options || !options.selector || typeof options.selector !== 'string') { - throw new TypeError('visible-in-page requires options.selector to be a string'); - } - var matchingElms = axe.utils.querySelectorAll(virtualNode, options.selector); - this.relatedNodes(matchingElms.map(function(vNode) { - return vNode.actualNode; - })); - return matchingElms.length > 0; - }, - after: function after(results, options) { - var elmUsedAnywhere = results.some(function(frameResult) { - return frameResult.result === true; - }); - if (elmUsedAnywhere) { - results.forEach(function(result) { - result.result = true; - }); - } - return results; - }, - options: { - selector: 'h1:not([role]), [role="heading"][aria-level="1"]' - } - }, { - id: 'page-has-main', - evaluate: function evaluate(node, options, virtualNode, context) { - if (!options || !options.selector || typeof options.selector !== 'string') { - throw new TypeError('visible-in-page requires options.selector to be a string'); - } - var matchingElms = axe.utils.querySelectorAll(virtualNode, options.selector); - this.relatedNodes(matchingElms.map(function(vNode) { - return vNode.actualNode; - })); - return matchingElms.length > 0; - }, - after: function after(results, options) { - var elmUsedAnywhere = results.some(function(frameResult) { - return frameResult.result === true; - }); - if (elmUsedAnywhere) { - results.forEach(function(result) { - result.result = true; - }); - } - return results; - }, - options: { - selector: 'main:not([role]), [role=\'main\']' - } - }, { - id: 'page-no-duplicate-banner', - evaluate: function evaluate(node, options, virtualNode, context) { - if (!options || !options.selector || typeof options.selector !== 'string') { - throw new TypeError('visible-in-page requires options.selector to be a string'); - } - var elms = axe.utils.querySelectorAll(virtualNode, options.selector); - if (typeof options.nativeScopeFilter === 'string') { - elms = elms.filter(function(elm) { - return elm.actualNode.hasAttribute('role') || !axe.commons.dom.findUpVirtual(elm, options.nativeScopeFilter); - }); - } - this.relatedNodes(elms.map(function(elm) { - return elm.actualNode; - })); - return elms.length <= 1; - }, - options: { - selector: 'header:not([role]), [role=banner]', - nativeScopeFilter: 'article, aside, main, nav, section' - } - }, { - id: 'page-no-duplicate-contentinfo', - evaluate: function evaluate(node, options, virtualNode, context) { - if (!options || !options.selector || typeof options.selector !== 'string') { - throw new TypeError('visible-in-page requires options.selector to be a string'); - } - var elms = axe.utils.querySelectorAll(virtualNode, options.selector); - if (typeof options.nativeScopeFilter === 'string') { - elms = elms.filter(function(elm) { - return elm.actualNode.hasAttribute('role') || !axe.commons.dom.findUpVirtual(elm, options.nativeScopeFilter); - }); - } - this.relatedNodes(elms.map(function(elm) { - return elm.actualNode; - })); - return elms.length <= 1; - }, - options: { - selector: 'footer:not([role]), [role=contentinfo]', - nativeScopeFilter: 'article, aside, main, nav, section' - } - }, { - id: 'page-no-duplicate-main', - evaluate: function evaluate(node, options, virtualNode, context) { - if (!options || !options.selector || typeof options.selector !== 'string') { - throw new TypeError('visible-in-page requires options.selector to be a string'); - } - var elms = axe.utils.querySelectorAll(virtualNode, options.selector); - if (typeof options.nativeScopeFilter === 'string') { - elms = elms.filter(function(elm) { - return elm.actualNode.hasAttribute('role') || !axe.commons.dom.findUpVirtual(elm, options.nativeScopeFilter); - }); - } - this.relatedNodes(elms.map(function(elm) { - return elm.actualNode; - })); - return elms.length <= 1; - }, - options: { - selector: 'main:not([role]), [role=\'main\']' + return !axe.commons.text.accessibleText(node); } }, { id: 'tabindex', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { return node.tabIndex <= 0; } }, { - id: 'alt-space-value', - evaluate: function evaluate(node, options, virtualNode, context) { - var validAttrValue = /^\s+$/.test(node.getAttribute('alt')); - return node.hasAttribute('alt') && validAttrValue; - } - }, { id: 'duplicate-img-label', - evaluate: function evaluate(node, options, virtualNode, context) { - var _axe$commons10 = axe.commons, aria = _axe$commons10.aria, text = _axe$commons10.text, dom = _axe$commons10.dom; - if ([ 'none', 'presentation' ].includes(aria.getRole(node))) { + evaluate: function evaluate(node, options, virtualNode) { + var text = axe.commons.text.visible(virtualNode, true).toLowerCase(); + if (text === '') { return false; } - var parent = dom.findUpVirtual(virtualNode, 'button, [role="button"], a[href], p, li, td, th'); - if (!parent) { - return false; - } - var parentVNode = axe.utils.getNodeFromTree(parent); - var visibleText = text.visibleVirtual(parentVNode, true).toLowerCase(); - if (visibleText === '') { - return false; - } - return visibleText === text.accessibleTextVirtual(virtualNode).toLowerCase(); + var images = axe.utils.querySelectorAll(virtualNode, 'img').filter(function(_ref) { + var actualNode = _ref.actualNode; + return axe.commons.dom.isVisible(actualNode) && ![ 'none', 'presentation' ].includes(actualNode.getAttribute('role')); + }); + return images.some(function(img) { + return text === axe.commons.text.accessibleText(img).toLowerCase(); + }); } }, { id: 'explicit-label', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { if (node.getAttribute('id')) { var root = axe.commons.dom.getRootNode(node); - var id = axe.utils.escapeSelector(node.getAttribute('id')); - var label = root.querySelector('label[for="'.concat(id, '"]')); + var id = axe.commons.utils.escapeSelector(node.getAttribute('id')); + var label = root.querySelector('label[for="' + id + '"]'); if (label) { - if (!axe.commons.dom.isVisible(label)) { - return true; - } else { - return !!axe.commons.text.accessibleText(label); - } + return !!axe.commons.text.accessibleText(label); } } return false; } }, { id: 'help-same-as-label', - evaluate: function evaluate(node, options, virtualNode, context) { - var labelText = axe.commons.text.labelVirtual(virtualNode), check = node.getAttribute('title'); + evaluate: function evaluate(node, options, virtualNode) { + var labelText = axe.commons.text.label(virtualNode), check = node.getAttribute('title'); if (!labelText) { return false; } @@ -11330,149 +6495,61 @@ }, enabled: false }, { - id: 'hidden-explicit-label', - evaluate: function evaluate(node, options, virtualNode, context) { - if (node.getAttribute('id')) { - var root = axe.commons.dom.getRootNode(node); - var id = axe.utils.escapeSelector(node.getAttribute('id')); - var label = root.querySelector('label[for="'.concat(id, '"]')); - if (label && !axe.commons.dom.isVisible(label, true)) { - var name = axe.commons.text.accessibleTextVirtual(virtualNode).trim(); - var isNameEmpty = name === ''; - return isNameEmpty; - } - } - return false; - } - }, { id: 'implicit-label', - evaluate: function evaluate(node, options, virtualNode, context) { - var _axe$commons11 = axe.commons, dom = _axe$commons11.dom, text = _axe$commons11.text; - var label = dom.findUpVirtual(virtualNode, 'label'); + evaluate: function evaluate(node, options, virtualNode) { + var label = axe.commons.dom.findUp(node, 'label'); if (label) { - return !!text.accessibleText(label, { - inControlContext: true - }); + return !!axe.commons.text.accessibleText(label); } return false; } }, { - id: 'label-content-name-mismatch', - evaluate: function evaluate(node, options, virtualNode, context) { - var text = axe.commons.text; - var accText = text.accessibleText(node).toLowerCase(); - if (text.isHumanInterpretable(accText) < 1) { - return undefined; - } - var visibleText = text.sanitize(text.visibleVirtual(virtualNode)).toLowerCase(); - if (text.isHumanInterpretable(visibleText) < 1) { - if (isStringContained(visibleText, accText)) { - return true; - } - return undefined; - } - return isStringContained(visibleText, accText); - function isStringContained(compare, compareWith) { - var curatedCompareWith = curateString(compareWith); - var curatedCompare = curateString(compare); - if (!curatedCompareWith || !curatedCompare) { - return false; - } - return curatedCompareWith.includes(curatedCompare); - } - function curateString(str) { - var noUnicodeStr = text.removeUnicode(str, { - emoji: true, - nonBmp: true, - punctuations: true - }); - return text.sanitize(noUnicodeStr); - } - } - }, { id: 'multiple-label', - evaluate: function evaluate(node, options, virtualNode, context) { - var id = axe.utils.escapeSelector(node.getAttribute('id')); + evaluate: function evaluate(node, options, virtualNode) { + var id = axe.commons.utils.escapeSelector(node.getAttribute('id')); + var labels = Array.from(document.querySelectorAll('label[for="' + id + '"]')); var parent = node.parentNode; - var root = axe.commons.dom.getRootNode(node); - root = root.documentElement || root; - var labels = Array.from(root.querySelectorAll('label[for="'.concat(id, '"]'))); if (labels.length) { - labels = labels.filter(function(label) { - return axe.commons.dom.isVisible(label); + labels = labels.filter(function(label, index) { + if (index === 0 && !axe.commons.dom.isVisible(label, true) || axe.commons.dom.isVisible(label, true)) { + return label; + } }); } while (parent) { - if (parent.nodeName.toUpperCase() === 'LABEL' && labels.indexOf(parent) === -1) { + if (parent.tagName === 'LABEL' && labels.indexOf(parent) === -1) { labels.push(parent); } parent = parent.parentNode; } this.relatedNodes(labels); - if (labels.length > 1) { - var ATVisibleLabels = labels.filter(function(label) { - return axe.commons.dom.isVisible(label, true); - }); - if (ATVisibleLabels.length > 1) { - return true; - } - var labelledby = axe.commons.dom.idrefs(node, 'aria-labelledby'); - return !labelledby.includes(ATVisibleLabels[0]); - } - return false; + return labels.length > 1; } }, { id: 'title-only', - evaluate: function evaluate(node, options, virtualNode, context) { - var labelText = axe.commons.text.labelVirtual(virtualNode); + evaluate: function evaluate(node, options, virtualNode) { + var labelText = axe.commons.text.label(virtualNode); return !labelText && !!(node.getAttribute('title') || node.getAttribute('aria-describedby')); } }, { - id: 'landmark-is-unique', - evaluate: function evaluate(node, options, virtualNode, context) { - var role = axe.commons.aria.getRole(node); - var accessibleText = axe.commons.text.accessibleTextVirtual(virtualNode); - accessibleText = accessibleText ? accessibleText.toLowerCase() : null; - this.data({ - role: role, - accessibleText: accessibleText - }); - this.relatedNodes([ node ]); - return true; - }, - after: function after(results, options) { - var uniqueLandmarks = []; - return results.filter(function(currentResult) { - var findMatch = function findMatch(someResult) { - return currentResult.data.role === someResult.data.role && currentResult.data.accessibleText === someResult.data.accessibleText; - }; - var matchedResult = uniqueLandmarks.find(findMatch); - if (matchedResult) { - matchedResult.result = false; - matchedResult.relatedNodes.push(currentResult.relatedNodes[0]); - return false; - } - uniqueLandmarks.push(currentResult); - currentResult.relatedNodes = []; - return true; - }); - } - }, { id: 'has-lang', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { return !!(node.getAttribute('lang') || node.getAttribute('xml:lang') || '').trim(); } }, { id: 'valid-lang', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { + function getBaseLang(lang) { + return lang.trim().split('-')[0].toLowerCase(); + } var langs, invalid; - langs = (options ? options : axe.utils.validLangs()).map(axe.utils.getBaseLang); + langs = (options ? options : axe.commons.utils.validLangs()).map(getBaseLang); invalid = [ 'lang', 'xml:lang' ].reduce(function(invalid, langAttr) { var langVal = node.getAttribute(langAttr); if (typeof langVal !== 'string') { return invalid; } - var baselangVal = axe.utils.getBaseLang(langVal); + var baselangVal = getBaseLang(langVal); if (baselangVal !== '' && langs.indexOf(baselangVal) === -1) { invalid.push(langAttr + '="' + node.getAttribute(langAttr) + '"'); } @@ -11485,146 +6562,65 @@ return false; } }, { - id: 'xml-lang-mismatch', - evaluate: function evaluate(node, options, virtualNode, context) { - var getBaseLang = axe.utils.getBaseLang; - var primaryLangValue = getBaseLang(node.getAttribute('lang')); - var primaryXmlLangValue = getBaseLang(node.getAttribute('xml:lang')); - return primaryLangValue === primaryXmlLangValue; + id: 'dlitem', + evaluate: function evaluate(node, options, virtualNode) { + var parent = axe.commons.dom.getComposedParent(node); + return parent.nodeName.toUpperCase() === 'DL'; } }, { - id: 'dlitem', - evaluate: function evaluate(node, options, virtualNode, context) { - var parent = axe.commons.dom.getComposedParent(node); - var parentTagName = parent.nodeName.toUpperCase(); - var parentRole = axe.commons.aria.getRole(parent, { - noImplicit: true + id: 'has-listitem', + evaluate: function evaluate(node, options, virtualNode) { + return virtualNode.children.every(function(_ref2) { + var actualNode = _ref2.actualNode; + return actualNode.nodeName.toUpperCase() !== 'LI'; }); - if (parentTagName === 'DIV' && [ 'presentation', 'none', null ].includes(parentRole)) { - parent = axe.commons.dom.getComposedParent(parent); - parentTagName = parent.nodeName.toUpperCase(); - parentRole = axe.commons.aria.getRole(parent, { - noImplicit: true - }); - } - if (parentTagName !== 'DL') { - return false; - } - if (!parentRole || parentRole === 'list') { - return true; - } - return false; } }, { id: 'listitem', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { var parent = axe.commons.dom.getComposedParent(node); - if (!parent) { - return undefined; - } - var parentTagName = parent.nodeName.toUpperCase(); - var parentRole = (parent.getAttribute('role') || '').toLowerCase(); - if (parentRole === 'list') { - return true; - } - if (parentRole && axe.commons.aria.isValidRole(parentRole)) { - return false; - } - return [ 'UL', 'OL' ].includes(parentTagName); + return [ 'UL', 'OL' ].includes(parent.nodeName.toUpperCase()) || (parent.getAttribute('role') || '').toLowerCase() === 'list'; } }, { id: 'only-dlitems', - evaluate: function evaluate(node, options, virtualNode, context) { - var _axe$commons12 = axe.commons, dom = _axe$commons12.dom, aria = _axe$commons12.aria; - var ALLOWED_ROLES = [ 'definition', 'term', 'list' ]; - var base = { - badNodes: [], - hasNonEmptyTextNode: false - }; - var content = virtualNode.children.reduce(function(content, child) { - var actualNode = child.actualNode; - if (actualNode.nodeName.toUpperCase() === 'DIV' && aria.getRole(actualNode) === null) { - return content.concat(child.children); - } - return content.concat(child); - }, []); - var result = content.reduce(function(out, childNode) { - var actualNode = childNode.actualNode; - var tagName = actualNode.nodeName.toUpperCase(); - if (actualNode.nodeType === 1 && dom.isVisible(actualNode, true, false)) { - var explicitRole = aria.getRole(actualNode, { - noImplicit: true - }); - if (tagName !== 'DT' && tagName !== 'DD' || explicitRole) { - if (!ALLOWED_ROLES.includes(explicitRole)) { - out.badNodes.push(actualNode); - } - } + evaluate: function evaluate(node, options, virtualNode) { + var bad = [], permitted = [ 'STYLE', 'META', 'LINK', 'MAP', 'AREA', 'SCRIPT', 'DATALIST', 'TEMPLATE' ], hasNonEmptyTextNode = false; + virtualNode.children.forEach(function(_ref3) { + var actualNode = _ref3.actualNode; + var nodeName = actualNode.nodeName.toUpperCase(); + if (actualNode.nodeType === 1 && nodeName !== 'DT' && nodeName !== 'DD' && permitted.indexOf(nodeName) === -1) { + bad.push(actualNode); } else if (actualNode.nodeType === 3 && actualNode.nodeValue.trim() !== '') { - out.hasNonEmptyTextNode = true; + hasNonEmptyTextNode = true; } - return out; - }, base); - if (result.badNodes.length) { - this.relatedNodes(result.badNodes); + }); + if (bad.length) { + this.relatedNodes(bad); } - return !!result.badNodes.length || result.hasNonEmptyTextNode; + var retVal = !!bad.length || hasNonEmptyTextNode; + return retVal; } }, { id: 'only-listitems', - evaluate: function evaluate(node, options, virtualNode, context) { - var dom = axe.commons.dom; - var getIsListItemRole = function getIsListItemRole(role, tagName) { - return role === 'listitem' || tagName === 'LI' && !role; - }; - var getHasListItem = function getHasListItem(hasListItem, tagName, isListItemRole) { - return hasListItem || tagName === 'LI' && isListItemRole || isListItemRole; - }; - var base = { - badNodes: [], - isEmpty: true, - hasNonEmptyTextNode: false, - hasListItem: false, - liItemsWithRole: 0 - }; - var out = virtualNode.children.reduce(function(out, _ref5) { - var actualNode = _ref5.actualNode; - var tagName = actualNode.nodeName.toUpperCase(); - if (actualNode.nodeType === 1 && dom.isVisible(actualNode, true, false)) { - var role = (actualNode.getAttribute('role') || '').toLowerCase(); - var isListItemRole = getIsListItemRole(role, tagName); - out.hasListItem = getHasListItem(out.hasListItem, tagName, isListItemRole); - if (isListItemRole) { - out.isEmpty = false; - } - if (tagName === 'LI' && !isListItemRole) { - out.liItemsWithRole++; - } - if (tagName !== 'LI' && !isListItemRole) { - out.badNodes.push(actualNode); - } + evaluate: function evaluate(node, options, virtualNode) { + var bad = [], permitted = [ 'STYLE', 'META', 'LINK', 'MAP', 'AREA', 'SCRIPT', 'DATALIST', 'TEMPLATE' ], hasNonEmptyTextNode = false; + virtualNode.children.forEach(function(_ref4) { + var actualNode = _ref4.actualNode; + var nodeName = actualNode.nodeName.toUpperCase(); + if (actualNode.nodeType === 1 && nodeName !== 'LI' && permitted.indexOf(nodeName) === -1) { + bad.push(actualNode); + } else if (actualNode.nodeType === 3 && actualNode.nodeValue.trim() !== '') { + hasNonEmptyTextNode = true; } - if (actualNode.nodeType === 3) { - if (actualNode.nodeValue.trim() !== '') { - out.hasNonEmptyTextNode = true; - } - } - return out; - }, base); - var virtualNodeChildrenOfTypeLi = virtualNode.children.filter(function(_ref6) { - var actualNode = _ref6.actualNode; - return actualNode.nodeName.toUpperCase() === 'LI'; }); - var allLiItemsHaveRole = out.liItemsWithRole > 0 && virtualNodeChildrenOfTypeLi.length === out.liItemsWithRole; - if (out.badNodes.length) { - this.relatedNodes(out.badNodes); + if (bad.length) { + this.relatedNodes(bad); } - var isInvalidListItem = !(out.hasListItem || out.isEmpty && !allLiItemsHaveRole); - return isInvalidListItem || !!out.badNodes.length || out.hasNonEmptyTextNode; + return !!bad.length || hasNonEmptyTextNode; } }, { id: 'structured-dlitems', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { var children = virtualNode.children; if (!children || !children.length) { return false; @@ -11646,128 +6642,35 @@ } }, { id: 'caption', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { var tracks = axe.utils.querySelectorAll(virtualNode, 'track'); - var hasCaptions = tracks.some(function(_ref7) { - var actualNode = _ref7.actualNode; - return (actualNode.getAttribute('kind') || '').toLowerCase() === 'captions'; - }); - return hasCaptions ? false : undefined; + if (tracks.length) { + return !tracks.some(function(_ref5) { + var actualNode = _ref5.actualNode; + return (actualNode.getAttribute('kind') || '').toLowerCase() === 'captions'; + }); + } + return undefined; } }, { id: 'description', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { var tracks = axe.utils.querySelectorAll(virtualNode, 'track'); - var hasDescriptions = tracks.some(function(_ref8) { - var actualNode = _ref8.actualNode; - return (actualNode.getAttribute('kind') || '').toLowerCase() === 'descriptions'; - }); - return hasDescriptions ? false : undefined; - } - }, { - id: 'frame-tested', - evaluate: function evaluate(node, options, virtualNode, context) { - var resolve = this.async(); - var _Object$assign = Object.assign({ - isViolation: false, - timeout: 500 - }, options), isViolation = _Object$assign.isViolation, timeout = _Object$assign.timeout; - var timer = setTimeout(function() { - timer = setTimeout(function() { - timer = null; - resolve(isViolation ? false : undefined); - }, 0); - }, timeout); - axe.utils.respondable(node.contentWindow, 'axe.ping', null, undefined, function() { - if (timer !== null) { - clearTimeout(timer); - resolve(true); - } - }); - }, - options: { - isViolation: false - } - }, { - id: 'css-orientation-lock', - evaluate: function evaluate(node, options, virtualNode, context) { - var _ref9 = context || {}, _ref9$cssom = _ref9.cssom, cssom = _ref9$cssom === void 0 ? undefined : _ref9$cssom; - if (!cssom || !cssom.length) { - return undefined; - } - var rulesGroupByDocumentFragment = cssom.reduce(function(out, _ref10) { - var sheet = _ref10.sheet, root = _ref10.root, shadowId = _ref10.shadowId; - var key = shadowId ? shadowId : 'topDocument'; - if (!out[key]) { - out[key] = { - root: root, - rules: [] - }; - } - if (!sheet || !sheet.cssRules) { - return out; - } - var rules = Array.from(sheet.cssRules); - out[key].rules = out[key].rules.concat(rules); + if (tracks.length) { + var out = !tracks.some(function(_ref6) { + var actualNode = _ref6.actualNode; + return (actualNode.getAttribute('kind') || '').toLowerCase() === 'descriptions'; + }); + axe.log(tracks.map(function(t) { + return t.actualNode.getAttribute('kind'); + }), out); return out; - }, {}); - var isLocked = false; - var relatedElements = []; - Object.keys(rulesGroupByDocumentFragment).forEach(function(key) { - var _rulesGroupByDocument = rulesGroupByDocumentFragment[key], root = _rulesGroupByDocument.root, rules = _rulesGroupByDocument.rules; - var mediaRules = rules.filter(function(r) { - return r.type === 4; - }); - if (!mediaRules || !mediaRules.length) { - return; - } - var orientationRules = mediaRules.filter(function(r) { - var cssText = r.cssText; - return /orientation:\s*landscape/i.test(cssText) || /orientation:\s*portrait/i.test(cssText); - }); - if (!orientationRules || !orientationRules.length) { - return; - } - orientationRules.forEach(function(r) { - if (!r.cssRules.length) { - return; - } - Array.from(r.cssRules).forEach(function(cssRule) { - if (!cssRule.selectorText) { - return; - } - if (cssRule.style.length <= 0) { - return; - } - var transformStyleValue = cssRule.style.transform || cssRule.style.webkitTransform || cssRule.style.msTransform || false; - if (!transformStyleValue) { - return; - } - var rotate = transformStyleValue.match(/rotate\(([^)]+)deg\)/); - var deg = parseInt(rotate && rotate[1] || 0); - var locked = deg % 90 === 0 && deg % 180 !== 0; - if (locked && cssRule.selectorText.toUpperCase() !== 'HTML') { - var selector = cssRule.selectorText; - var elms = Array.from(root.querySelectorAll(selector)); - if (elms && elms.length) { - relatedElements = relatedElements.concat(elms); - } - } - isLocked = locked; - }); - }); - }); - if (!isLocked) { - return true; } - if (relatedElements.length) { - this.relatedNodes(relatedElements); - } - return false; + return undefined; } }, { id: 'meta-viewport-large', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { options = options || {}; var params, content = node.getAttribute('content') || '', parsedParams = content.split(/[;,]/), result = {}, minimum = options.scaleMinimum || 2, lowerBound = options.lowerBound || false; for (var i = 0, l = parsedParams.length; i < l; i++) { @@ -11781,11 +6684,9 @@ return true; } if (!lowerBound && result['user-scalable'] === 'no') { - this.data('user-scalable=no'); return false; } if (result['maximum-scale'] && parseFloat(result['maximum-scale']) < minimum) { - this.data('maximum-scale'); return false; } return true; @@ -11796,7 +6697,7 @@ } }, { id: 'meta-viewport', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { options = options || {}; var params, content = node.getAttribute('content') || '', parsedParams = content.split(/[;,]/), result = {}, minimum = options.scaleMinimum || 2, lowerBound = options.lowerBound || false; for (var i = 0, l = parsedParams.length; i < l; i++) { @@ -11810,11 +6711,9 @@ return true; } if (!lowerBound && result['user-scalable'] === 'no') { - this.data('user-scalable=no'); return false; } if (result['maximum-scale'] && parseFloat(result['maximum-scale']) < minimum) { - this.data('maximum-scale'); return false; } return true; @@ -11824,18 +6723,18 @@ } }, { id: 'header-present', - evaluate: function evaluate(node, options, virtualNode, context) { - return !!axe.utils.querySelectorAll(virtualNode, 'h1, h2, h3, h4, h5, h6, [role="heading"]')[0]; + evaluate: function evaluate(node, options, virtualNode) { + return !!node.querySelector('h1, h2, h3, h4, h5, h6, [role="heading"]'); } }, { id: 'heading-order', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { var ariaHeadingLevel = node.getAttribute('aria-level'); if (ariaHeadingLevel !== null) { this.data(parseInt(ariaHeadingLevel, 10)); return true; } - var headingLevel = node.nodeName.toUpperCase().match(/H(\d)/); + var headingLevel = node.tagName.match(/H(\d)/); if (headingLevel) { this.data(parseInt(headingLevel[1], 10)); return true; @@ -11856,27 +6755,33 @@ return results; } }, { + id: 'href-no-hash', + evaluate: function evaluate(node, options, virtualNode) { + var href = node.getAttribute('href'); + if (href === '#') { + return false; + } + return true; + } + }, { id: 'internal-link-present', - evaluate: function evaluate(node, options, virtualNode, context) { - var links = axe.utils.querySelectorAll(virtualNode, 'a[href]'); - return links.some(function(vLink) { - return /^#[^/!]/.test(vLink.actualNode.getAttribute('href')); - }); + evaluate: function evaluate(node, options, virtualNode) { + return !!node.querySelector('a[href^="#"]'); } }, { id: 'landmark', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { return axe.utils.querySelectorAll(virtualNode, 'main, [role="main"]').length > 0; } }, { id: 'meta-refresh', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { var content = node.getAttribute('content') || '', parsedParams = content.split(/[;,]/); return content === '' || parsedParams[0] === '0'; } }, { id: 'p-as-heading', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { var siblings = Array.from(node.parentNode.children); var currentIndex = siblings.indexOf(node); options = options || {}; @@ -11941,7 +6846,7 @@ if (!nextStyle || !isHeaderStyle(currStyle, nextStyle, margins)) { return true; } - var blockquote = axe.commons.dom.findUpVirtual(virtualNode, 'blockquote'); + var blockquote = axe.commons.dom.findUp(node, 'blockquote'); if (blockquote && blockquote.nodeName.toUpperCase() === 'BLOCKQUOTE') { return undefined; } @@ -11966,45 +6871,42 @@ } }, { id: 'region', - evaluate: function evaluate(node, options, virtualNode, context) { - var _axe$commons13 = axe.commons, dom = _axe$commons13.dom, aria = _axe$commons13.aria; + evaluate: function evaluate(node, options, virtualNode) { + var _axe$commons2 = axe.commons, dom = _axe$commons2.dom, aria = _axe$commons2.aria; + function getSkiplink(virtualNode) { + var firstLink = axe.utils.querySelectorAll(virtualNode, 'a[href]')[0]; + if (firstLink && axe.commons.dom.getElementByReference(firstLink.actualNode, 'href')) { + return firstLink.actualNode; + } + } + var skipLink = getSkiplink(virtualNode); var landmarkRoles = aria.getRolesByType('landmark'); var implicitLandmarks = landmarkRoles.reduce(function(arr, role) { return arr.concat(aria.implicitNodes(role)); }, []).filter(function(r) { return r !== null; + }).map(function(r) { + return r.toUpperCase(); }); - function isRegion(virtualNode) { - var node = virtualNode.actualNode; - var explicitRole = axe.commons.aria.getRole(node, { - noImplicit: true - }); - var ariaLive = (node.getAttribute('aria-live') || '').toLowerCase().trim(); - if (explicitRole) { - return explicitRole === 'dialog' || landmarkRoles.includes(explicitRole); + function isSkipLink(node) { + return skipLink && skipLink === node; + } + function isLandmark(node) { + if (node.hasAttribute('role')) { + return landmarkRoles.includes(node.getAttribute('role').toLowerCase()); + } else { + return implicitLandmarks.includes(node.nodeName.toUpperCase()); } - if ([ 'assertive', 'polite' ].includes(ariaLive)) { - return true; - } - return implicitLandmarks.some(function(implicitSelector) { - var matches = axe.utils.matchesSelector(node, implicitSelector); - if (node.nodeName.toUpperCase() === 'FORM') { - var titleAttr = node.getAttribute('title'); - var title = titleAttr && titleAttr.trim() !== '' ? axe.commons.text.sanitize(titleAttr) : null; - return matches && (!!aria.labelVirtual(virtualNode) || !!title); - } - return matches; - }); } function findRegionlessElms(virtualNode) { var node = virtualNode.actualNode; - if (isRegion(virtualNode) || dom.isSkipLink(virtualNode.actualNode) && dom.getElementByReference(virtualNode.actualNode, 'href') || !dom.isVisible(node, true)) { + if (isLandmark(node) || isSkipLink(node) || !dom.isVisible(node, true)) { return []; } else if (dom.hasContent(node, true)) { return [ node ]; } else { - return virtualNode.children.filter(function(_ref11) { - var actualNode = _ref11.actualNode; + return virtualNode.children.filter(function(_ref7) { + var actualNode = _ref7.actualNode; return actualNode.nodeType === 1; }).map(findRegionlessElms).reduce(function(a, b) { return a.concat(b); @@ -12020,16 +6922,15 @@ } }, { id: 'skip-link', - evaluate: function evaluate(node, options, virtualNode, context) { - var target = axe.commons.dom.getElementByReference(node, 'href'); - if (target) { - return axe.commons.dom.isVisible(target, true) || undefined; - } - return false; + evaluate: function evaluate(node, options, virtualNode) { + return axe.commons.dom.isFocusable(axe.commons.dom.getElementByReference(node, 'href')); + }, + after: function after(results, options) { + return [ results[0] ]; } }, { id: 'unique-frame-title', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { var title = axe.commons.text.sanitize(node.title).trim().toLowerCase(); this.data(title); return true; @@ -12045,121 +6946,27 @@ return results; } }, { - id: 'duplicate-id-active', - evaluate: function evaluate(node, options, virtualNode, context) { - var id = node.getAttribute('id').trim(); - if (!id) { - return true; - } - var root = axe.commons.dom.getRootNode(node); - var matchingNodes = Array.from(root.querySelectorAll('[id="'.concat(axe.utils.escapeSelector(id), '"]'))).filter(function(foundNode) { - return foundNode !== node; - }); - if (matchingNodes.length) { - this.relatedNodes(matchingNodes); - } - this.data(id); - return matchingNodes.length === 0; - }, - after: function after(results, options) { - var uniqueIds = []; - return results.filter(function(r) { - if (uniqueIds.indexOf(r.data) === -1) { - uniqueIds.push(r.data); - return true; - } - return false; - }); - } - }, { - id: 'duplicate-id-aria', - evaluate: function evaluate(node, options, virtualNode, context) { - var id = node.getAttribute('id').trim(); - if (!id) { - return true; - } - var root = axe.commons.dom.getRootNode(node); - var matchingNodes = Array.from(root.querySelectorAll('[id="'.concat(axe.utils.escapeSelector(id), '"]'))).filter(function(foundNode) { - return foundNode !== node; - }); - if (matchingNodes.length) { - this.relatedNodes(matchingNodes); - } - this.data(id); - return matchingNodes.length === 0; - }, - after: function after(results, options) { - var uniqueIds = []; - return results.filter(function(r) { - if (uniqueIds.indexOf(r.data) === -1) { - uniqueIds.push(r.data); - return true; - } - return false; - }); - } - }, { - id: 'duplicate-id', - evaluate: function evaluate(node, options, virtualNode, context) { - var id = node.getAttribute('id').trim(); - if (!id) { - return true; - } - var root = axe.commons.dom.getRootNode(node); - var matchingNodes = Array.from(root.querySelectorAll('[id="'.concat(axe.utils.escapeSelector(id), '"]'))).filter(function(foundNode) { - return foundNode !== node; - }); - if (matchingNodes.length) { - this.relatedNodes(matchingNodes); - } - this.data(id); - return matchingNodes.length === 0; - }, - after: function after(results, options) { - var uniqueIds = []; - return results.filter(function(r) { - if (uniqueIds.indexOf(r.data) === -1) { - uniqueIds.push(r.data); - return true; - } - return false; - }); - } - }, { id: 'aria-label', - evaluate: function evaluate(node, options, virtualNode, context) { - var _axe$commons14 = axe.commons, text = _axe$commons14.text, aria = _axe$commons14.aria; - return !!text.sanitize(aria.arialabelText(node)); + evaluate: function evaluate(node, options, virtualNode) { + var label = node.getAttribute('aria-label'); + return !!(label ? axe.commons.text.sanitize(label).trim() : ''); } }, { id: 'aria-labelledby', - evaluate: function evaluate(node, options, virtualNode, context) { - var _axe$commons15 = axe.commons, text = _axe$commons15.text, aria = _axe$commons15.aria; - return !!text.sanitize(aria.arialabelledbyText(node)); - } - }, { - id: 'avoid-inline-spacing', - evaluate: function evaluate(node, options, virtualNode, context) { - var inlineSpacingCssProperties = [ 'line-height', 'letter-spacing', 'word-spacing' ]; - var overriddenProperties = inlineSpacingCssProperties.filter(function(property) { - if (node.style.getPropertyPriority(property) === 'important') { - return property; - } + evaluate: function evaluate(node, options, virtualNode) { + var getIdRefs = axe.commons.dom.idrefs; + return getIdRefs(node, 'aria-labelledby').some(function(elm) { + return elm && axe.commons.text.accessibleText(elm, true); }); - if (overriddenProperties.length > 0) { - this.data(overriddenProperties); - return false; - } - return true; } }, { id: 'button-has-visible-text', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { var nodeName = node.nodeName.toUpperCase(); var role = node.getAttribute('role'); - var label; + var label = void 0; if (nodeName === 'BUTTON' || role === 'button' && nodeName !== 'INPUT') { - label = axe.commons.text.accessibleTextVirtual(virtualNode); + label = axe.commons.text.accessibleText(node); this.data(label); return !!label; } else { @@ -12168,74 +6975,104 @@ } }, { id: 'doc-has-title', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { var title = document.title; return !!(title ? axe.commons.text.sanitize(title).trim() : ''); } }, { + id: 'duplicate-id', + evaluate: function evaluate(node, options, virtualNode) { + if (!node.getAttribute('id').trim()) { + return true; + } + var id = axe.commons.utils.escapeSelector(node.getAttribute('id')); + var matchingNodes = document.querySelectorAll('[id="' + id + '"]'); + var related = []; + for (var i = 0; i < matchingNodes.length; i++) { + if (matchingNodes[i] !== node) { + related.push(matchingNodes[i]); + } + } + if (related.length) { + this.relatedNodes(related); + } + this.data(node.getAttribute('id')); + return matchingNodes.length <= 1; + }, + after: function after(results, options) { + var uniqueIds = []; + return results.filter(function(r) { + if (uniqueIds.indexOf(r.data) === -1) { + uniqueIds.push(r.data); + return true; + } + return false; + }); + } + }, { id: 'exists', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { return true; } }, { id: 'has-alt', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { var nn = node.nodeName.toLowerCase(); return node.hasAttribute('alt') && (nn === 'img' || nn === 'input' || nn === 'area'); } }, { id: 'has-visible-text', - evaluate: function evaluate(node, options, virtualNode, context) { - return axe.commons.text.accessibleTextVirtual(virtualNode).length > 0; + evaluate: function evaluate(node, options, virtualNode) { + return axe.commons.text.accessibleText(node).length > 0; } }, { id: 'is-on-screen', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { return axe.commons.dom.isVisible(node, false) && !axe.commons.dom.isOffscreen(node); } }, { id: 'non-empty-alt', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { var label = node.getAttribute('alt'); return !!(label ? axe.commons.text.sanitize(label).trim() : ''); } }, { id: 'non-empty-if-present', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { var nodeName = node.nodeName.toUpperCase(); var type = (node.getAttribute('type') || '').toLowerCase(); var label = node.getAttribute('value'); this.data(label); - if (nodeName === 'INPUT' && [ 'submit', 'reset' ].includes(type)) { + if (nodeName === 'INPUT' && [ 'submit', 'reset' ].indexOf(type) !== -1) { return label === null; } return false; } }, { id: 'non-empty-title', - evaluate: function evaluate(node, options, virtualNode, context) { - var text = axe.commons.text; - return !!text.sanitize(text.titleText(node)); + evaluate: function evaluate(node, options, virtualNode) { + var title = node.getAttribute('title'); + return !!(title ? axe.commons.text.sanitize(title).trim() : ''); } }, { id: 'non-empty-value', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { var label = node.getAttribute('value'); return !!(label ? axe.commons.text.sanitize(label).trim() : ''); } }, { id: 'role-none', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { return node.getAttribute('role') === 'none'; } }, { id: 'role-presentation', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { return node.getAttribute('role') === 'presentation'; } }, { id: 'caption-faked', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { var table = axe.commons.table.toGrid(node); var firstRow = table[0]; if (table.length <= 1 || firstRow.length <= 1 || node.rows.length <= 1) { @@ -12247,17 +7084,17 @@ } }, { id: 'has-caption', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { return !!node.caption; } }, { id: 'has-summary', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { return !!node.summary; } }, { id: 'has-th', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { var row, cell, badCells = []; for (var rowIndex = 0, rowLength = node.rows.length; rowIndex < rowLength; rowIndex++) { row = node.rows[rowIndex]; @@ -12276,7 +7113,7 @@ } }, { id: 'html5-scope', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { if (!axe.commons.dom.isHTML5(document)) { return true; } @@ -12284,12 +7121,12 @@ } }, { id: 'same-caption-summary', - evaluate: function evaluate(node, options, virtualNode, context) { - return !!(node.summary && node.caption) && node.summary.toLowerCase() === axe.commons.text.accessibleText(node.caption).toLowerCase(); + evaluate: function evaluate(node, options, virtualNode) { + return !!(node.summary && node.caption) && node.summary === axe.commons.text.accessibleText(node.caption); } }, { id: 'scope-value', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { options = options || {}; var value = node.getAttribute('scope').toLowerCase(); var validVals = [ 'row', 'col', 'rowgroup', 'colgroup' ] || options.values; @@ -12297,15 +7134,16 @@ } }, { id: 'td-has-header', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { var tableUtils = axe.commons.table; var badCells = []; var cells = tableUtils.getAllCells(node); cells.forEach(function(cell) { if (axe.commons.dom.hasContent(cell) && tableUtils.isDataCell(cell) && !axe.commons.aria.label(cell)) { - var hasHeaders = tableUtils.getHeaders(cell).some(function(header) { - return header !== null && !!axe.commons.dom.hasContent(header); - }); + var hasHeaders = tableUtils.getHeaders(cell); + hasHeaders = hasHeaders.reduce(function(hasHeaders, header) { + return hasHeaders || header !== null && !!axe.commons.dom.hasContent(header); + }, false); if (!hasHeaders) { badCells.push(cell); } @@ -12319,7 +7157,7 @@ } }, { id: 'td-headers-attr', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { var cells = []; for (var rowIndex = 0, rowLength = node.rows.length; rowIndex < rowLength; rowIndex++) { var row = node.rows[rowIndex]; @@ -12364,7 +7202,7 @@ } }, { id: 'th-has-data-cells', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { var tableUtils = axe.commons.table; var cells = tableUtils.getAllCells(node); var checkResult = this; @@ -12386,35 +7224,34 @@ return cell.nodeName.toUpperCase() === 'TH' || [ 'rowheader', 'columnheader' ].indexOf(cell.getAttribute('role')) !== -1; }); var tableGrid = tableUtils.toGrid(node); - var out = true; - headers.forEach(function(header) { + var out = headers.reduce(function(res, header) { if (header.getAttribute('id') && reffedHeaders.includes(header.getAttribute('id'))) { - return; + return !res ? res : true; } - var pos = tableUtils.getCellPosition(header, tableGrid); var hasCell = false; + var pos = tableUtils.getCellPosition(header, tableGrid); if (tableUtils.isColumnHeader(header)) { - hasCell = tableUtils.traverse('down', pos, tableGrid).find(function(cell) { - return !tableUtils.isColumnHeader(cell); - }); + hasCell = tableUtils.traverse('down', pos, tableGrid).reduce(function(out, cell) { + return out || axe.commons.dom.hasContent(cell) && !tableUtils.isColumnHeader(cell); + }, false); } if (!hasCell && tableUtils.isRowHeader(header)) { - hasCell = tableUtils.traverse('right', pos, tableGrid).find(function(cell) { - return !tableUtils.isRowHeader(cell); - }); + hasCell = tableUtils.traverse('right', pos, tableGrid).reduce(function(out, cell) { + return out || axe.commons.dom.hasContent(cell) && !tableUtils.isRowHeader(cell); + }, false); } if (!hasCell) { checkResult.relatedNodes(header); } - out = out && hasCell; - }); + return res && hasCell; + }, true); return out ? true : undefined; } }, { id: 'hidden-content', - evaluate: function evaluate(node, options, virtualNode, context) { + evaluate: function evaluate(node, options, virtualNode) { var whitelist = [ 'SCRIPT', 'HEAD', 'TITLE', 'NOSCRIPT', 'STYLE', 'TEMPLATE' ]; - if (!whitelist.includes(node.nodeName.toUpperCase()) && axe.commons.dom.hasContentVirtual(virtualNode)) { + if (!whitelist.includes(node.tagName.toUpperCase()) && axe.commons.dom.hasContent(virtualNode)) { var styles = window.getComputedStyle(node); if (styles.getPropertyValue('display') === 'none') { return undefined; @@ -12431,2040 +7268,946 @@ } ], commons: function() { var commons = {}; - var aria = commons.aria = {}; - var lookupTable = aria.lookupTable = {}; - var isNull = function isNull(value) { - return value === null; - }; - var isNotNull = function isNotNull(value) { - return value !== null; - }; - lookupTable.attributes = { + var aria = commons.aria = {}, lookupTables = aria._lut = {}; + lookupTables.attributes = { 'aria-activedescendant': { - type: 'idref', - allowEmpty: true, - unsupported: false + type: 'idref' }, 'aria-atomic': { type: 'boolean', - values: [ 'true', 'false' ], - unsupported: false + values: [ 'true', 'false' ] }, 'aria-autocomplete': { type: 'nmtoken', - values: [ 'inline', 'list', 'both', 'none' ], - unsupported: false + values: [ 'inline', 'list', 'both', 'none' ] }, 'aria-busy': { type: 'boolean', - values: [ 'true', 'false' ], - unsupported: false + values: [ 'true', 'false' ] }, 'aria-checked': { type: 'nmtoken', - values: [ 'true', 'false', 'mixed', 'undefined' ], - unsupported: false + values: [ 'true', 'false', 'mixed', 'undefined' ] }, 'aria-colcount': { - type: 'int', - unsupported: false + type: 'int' }, 'aria-colindex': { - type: 'int', - unsupported: false + type: 'int' }, 'aria-colspan': { - type: 'int', - unsupported: false + type: 'int' }, 'aria-controls': { - type: 'idrefs', - allowEmpty: true, - unsupported: false + type: 'idrefs' }, 'aria-current': { type: 'nmtoken', - allowEmpty: true, - values: [ 'page', 'step', 'location', 'date', 'time', 'true', 'false' ], - unsupported: false + values: [ 'page', 'step', 'location', 'date', 'time', 'true', 'false' ] }, 'aria-describedby': { - type: 'idrefs', - allowEmpty: true, - unsupported: false - }, - 'aria-describedat': { - unsupported: true, - unstandardized: true - }, - 'aria-details': { - unsupported: true + type: 'idrefs' }, 'aria-disabled': { type: 'boolean', - values: [ 'true', 'false' ], - unsupported: false + values: [ 'true', 'false' ] }, 'aria-dropeffect': { type: 'nmtokens', - values: [ 'copy', 'move', 'reference', 'execute', 'popup', 'none' ], - unsupported: false - }, - 'aria-errormessage': { - type: 'idref', - allowEmpty: true, - unsupported: false + values: [ 'copy', 'move', 'reference', 'execute', 'popup', 'none' ] }, 'aria-expanded': { type: 'nmtoken', - values: [ 'true', 'false', 'undefined' ], - unsupported: false + values: [ 'true', 'false', 'undefined' ] }, 'aria-flowto': { - type: 'idrefs', - allowEmpty: true, - unsupported: false + type: 'idrefs' }, 'aria-grabbed': { type: 'nmtoken', - values: [ 'true', 'false', 'undefined' ], - unsupported: false + values: [ 'true', 'false', 'undefined' ] }, 'aria-haspopup': { - type: 'nmtoken', - allowEmpty: true, - values: [ 'true', 'false', 'menu', 'listbox', 'tree', 'grid', 'dialog' ], - unsupported: false + type: 'boolean', + values: [ 'true', 'false' ] }, 'aria-hidden': { type: 'boolean', - values: [ 'true', 'false' ], - unsupported: false + values: [ 'true', 'false' ] }, 'aria-invalid': { type: 'nmtoken', - allowEmpty: true, - values: [ 'true', 'false', 'spelling', 'grammar' ], - unsupported: false - }, - 'aria-keyshortcuts': { - type: 'string', - allowEmpty: true, - unsupported: false + values: [ 'true', 'false', 'spelling', 'grammar' ] }, 'aria-label': { - type: 'string', - allowEmpty: true, - unsupported: false + type: 'string' }, 'aria-labelledby': { - type: 'idrefs', - allowEmpty: true, - unsupported: false + type: 'idrefs' }, 'aria-level': { - type: 'int', - unsupported: false + type: 'int' }, 'aria-live': { type: 'nmtoken', - values: [ 'off', 'polite', 'assertive' ], - unsupported: false - }, - 'aria-modal': { - type: 'boolean', - values: [ 'true', 'false' ], - unsupported: false + values: [ 'off', 'polite', 'assertive' ] }, 'aria-multiline': { type: 'boolean', - values: [ 'true', 'false' ], - unsupported: false + values: [ 'true', 'false' ] }, 'aria-multiselectable': { type: 'boolean', - values: [ 'true', 'false' ], - unsupported: false + values: [ 'true', 'false' ] }, 'aria-orientation': { type: 'nmtoken', - values: [ 'horizontal', 'vertical' ], - unsupported: false + values: [ 'horizontal', 'vertical' ] }, 'aria-owns': { - type: 'idrefs', - allowEmpty: true, - unsupported: false - }, - 'aria-placeholder': { - type: 'string', - allowEmpty: true, - unsupported: false + type: 'idrefs' }, 'aria-posinset': { - type: 'int', - unsupported: false + type: 'int' }, 'aria-pressed': { type: 'nmtoken', - values: [ 'true', 'false', 'mixed', 'undefined' ], - unsupported: false + values: [ 'true', 'false', 'mixed', 'undefined' ] }, 'aria-readonly': { type: 'boolean', - values: [ 'true', 'false' ], - unsupported: false + values: [ 'true', 'false' ] }, 'aria-relevant': { type: 'nmtokens', - values: [ 'additions', 'removals', 'text', 'all' ], - unsupported: false + values: [ 'additions', 'removals', 'text', 'all' ] }, 'aria-required': { type: 'boolean', - values: [ 'true', 'false' ], - unsupported: false - }, - 'aria-roledescription': { - type: 'string', - allowEmpty: true, - unsupported: { - exceptions: [ 'button', { - nodeName: 'input', - properties: { - type: [ 'button', 'checkbox', 'image', 'radio', 'reset', 'submit' ] - } - }, 'img', 'select', 'summary' ] - } + values: [ 'true', 'false' ] }, 'aria-rowcount': { - type: 'int', - unsupported: false + type: 'int' }, 'aria-rowindex': { - type: 'int', - unsupported: false + type: 'int' }, 'aria-rowspan': { - type: 'int', - unsupported: false + type: 'int' }, 'aria-selected': { type: 'nmtoken', - values: [ 'true', 'false', 'undefined' ], - unsupported: false + values: [ 'true', 'false', 'undefined' ] }, 'aria-setsize': { - type: 'int', - unsupported: false + type: 'int' }, 'aria-sort': { type: 'nmtoken', - values: [ 'ascending', 'descending', 'other', 'none' ], - unsupported: false + values: [ 'ascending', 'descending', 'other', 'none' ] }, 'aria-valuemax': { - type: 'decimal', - unsupported: false + type: 'decimal' }, 'aria-valuemin': { - type: 'decimal', - unsupported: false + type: 'decimal' }, 'aria-valuenow': { - type: 'decimal', - unsupported: false + type: 'decimal' }, 'aria-valuetext': { - type: 'string', - unsupported: false + type: 'string' } }; - lookupTable.globalAttributes = [ 'aria-atomic', 'aria-busy', 'aria-controls', 'aria-current', 'aria-describedby', 'aria-disabled', 'aria-dropeffect', 'aria-flowto', 'aria-grabbed', 'aria-haspopup', 'aria-hidden', 'aria-invalid', 'aria-keyshortcuts', 'aria-label', 'aria-labelledby', 'aria-live', 'aria-owns', 'aria-relevant', 'aria-roledescription' ]; - lookupTable.role = { + lookupTables.globalAttributes = [ 'aria-atomic', 'aria-busy', 'aria-controls', 'aria-current', 'aria-describedby', 'aria-disabled', 'aria-dropeffect', 'aria-flowto', 'aria-grabbed', 'aria-haspopup', 'aria-hidden', 'aria-invalid', 'aria-label', 'aria-labelledby', 'aria-live', 'aria-owns', 'aria-relevant' ]; + lookupTables.role = { alert: { type: 'widget', attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] + allowed: [ 'aria-expanded' ] }, owned: null, nameFrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'section' ] + context: null }, alertdialog: { type: 'widget', attributes: { - allowed: [ 'aria-expanded', 'aria-modal', 'aria-errormessage' ] + allowed: [ 'aria-expanded' ] }, owned: null, nameFrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'dialog', 'section' ] + context: null }, application: { type: 'landmark', attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] + allowed: [ 'aria-expanded' ] }, owned: null, nameFrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'article', 'audio', 'embed', 'iframe', 'object', 'section', 'svg', 'video' ] + context: null }, article: { type: 'structure', attributes: { - allowed: [ 'aria-expanded', 'aria-posinset', 'aria-setsize', 'aria-errormessage' ] + allowed: [ 'aria-expanded' ] }, owned: null, nameFrom: [ 'author' ], context: null, - implicit: [ 'article' ], - unsupported: false + implicit: [ 'article' ] }, banner: { type: 'landmark', attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] + allowed: [ 'aria-expanded' ] }, owned: null, nameFrom: [ 'author' ], context: null, - implicit: [ 'header' ], - unsupported: false, - allowedElements: [ 'section' ] + implicit: [ 'header' ] }, button: { type: 'widget', attributes: { - allowed: [ 'aria-expanded', 'aria-pressed', 'aria-errormessage' ] + allowed: [ 'aria-expanded', 'aria-pressed' ] }, owned: null, nameFrom: [ 'author', 'contents' ], context: null, - implicit: [ 'button', 'input[type="button"]', 'input[type="image"]', 'input[type="reset"]', 'input[type="submit"]', 'summary' ], - unsupported: false, - allowedElements: [ { - nodeName: 'a', - attributes: { - href: isNotNull - } - } ] + implicit: [ 'button', 'input[type="button"]', 'input[type="image"]', 'input[type="reset"]', 'input[type="submit"]', 'summary' ] }, cell: { type: 'structure', attributes: { - allowed: [ 'aria-colindex', 'aria-colspan', 'aria-rowindex', 'aria-rowspan', 'aria-errormessage' ] + allowed: [ 'aria-colindex', 'aria-colspan', 'aria-rowindex', 'aria-rowspan' ] }, owned: null, nameFrom: [ 'author', 'contents' ], context: [ 'row' ], - implicit: [ 'td', 'th' ], - unsupported: false + implicit: [ 'td', 'th' ] }, checkbox: { type: 'widget', attributes: { - allowed: [ 'aria-checked', 'aria-required', 'aria-readonly', 'aria-errormessage' ] + required: [ 'aria-checked' ] }, owned: null, nameFrom: [ 'author', 'contents' ], context: null, - implicit: [ 'input[type="checkbox"]' ], - unsupported: false, - allowedElements: [ 'button' ] + implicit: [ 'input[type="checkbox"]' ] }, columnheader: { type: 'structure', attributes: { - allowed: [ 'aria-colindex', 'aria-colspan', 'aria-expanded', 'aria-rowindex', 'aria-rowspan', 'aria-required', 'aria-readonly', 'aria-selected', 'aria-sort', 'aria-errormessage' ] + allowed: [ 'aria-expanded', 'aria-sort', 'aria-readonly', 'aria-selected', 'aria-required' ] }, owned: null, nameFrom: [ 'author', 'contents' ], context: [ 'row' ], - implicit: [ 'th' ], - unsupported: false + implicit: [ 'th' ] }, combobox: { type: 'composite', attributes: { - allowed: [ 'aria-autocomplete', 'aria-required', 'aria-activedescendant', 'aria-orientation', 'aria-errormessage' ], - required: [ 'aria-expanded' ] + required: [ 'aria-expanded' ], + allowed: [ 'aria-autocomplete', 'aria-required', 'aria-activedescendant' ] }, owned: { all: [ 'listbox', 'textbox' ] }, nameFrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ { - nodeName: 'input', - properties: { - type: 'text' - } - } ] + context: null }, command: { nameFrom: [ 'author' ], - type: 'abstract', - unsupported: false + type: 'abstract' }, complementary: { type: 'landmark', attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] + allowed: [ 'aria-expanded' ] }, owned: null, nameFrom: [ 'author' ], context: null, - implicit: [ 'aside' ], - unsupported: false, - allowedElements: [ 'section' ] + implicit: [ 'aside' ] }, composite: { nameFrom: [ 'author' ], - type: 'abstract', - unsupported: false + type: 'abstract' }, contentinfo: { type: 'landmark', attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] + allowed: [ 'aria-expanded' ] }, owned: null, nameFrom: [ 'author' ], context: null, - implicit: [ 'footer' ], - unsupported: false, - allowedElements: [ 'section' ] + implicit: [ 'footer' ] }, definition: { type: 'structure', attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] + allowed: [ 'aria-expanded' ] }, owned: null, nameFrom: [ 'author' ], context: null, - implicit: [ 'dd', 'dfn' ], - unsupported: false + implicit: [ 'dd' ] }, dialog: { type: 'widget', attributes: { - allowed: [ 'aria-expanded', 'aria-modal', 'aria-errormessage' ] + allowed: [ 'aria-expanded' ] }, owned: null, nameFrom: [ 'author' ], context: null, - implicit: [ 'dialog' ], - unsupported: false, - allowedElements: [ 'section' ] + implicit: [ 'dialog' ] }, directory: { type: 'structure', attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] + allowed: [ 'aria-expanded' ] }, owned: null, nameFrom: [ 'author', 'contents' ], - context: null, - unsupported: false, - allowedElements: [ 'ol', 'ul' ] + context: null }, document: { type: 'structure', attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] + allowed: [ 'aria-expanded' ] }, owned: null, nameFrom: [ 'author' ], context: null, - implicit: [ 'body' ], - unsupported: false, - allowedElements: [ 'article', 'embed', 'iframe', 'object', 'section', 'svg' ] - }, - 'doc-abstract': { - type: 'section', - attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] - }, - owned: null, - nameFrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'section' ] - }, - 'doc-acknowledgments': { - type: 'landmark', - attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] - }, - owned: null, - nameFrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'section' ] - }, - 'doc-afterword': { - type: 'landmark', - attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] - }, - owned: null, - nameFrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'section' ] - }, - 'doc-appendix': { - type: 'landmark', - attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] - }, - owned: null, - nameFrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'section' ] - }, - 'doc-backlink': { - type: 'link', - attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] - }, - owned: null, - nameFrom: [ 'author', 'contents' ], - context: null, - unsupported: false, - allowedElements: [ { - nodeName: 'a', - attributes: { - href: isNotNull - } - } ] - }, - 'doc-biblioentry': { - type: 'listitem', - attributes: { - allowed: [ 'aria-expanded', 'aria-level', 'aria-posinset', 'aria-setsize', 'aria-errormessage' ] - }, - owned: null, - nameFrom: [ 'author' ], - context: [ 'doc-bibliography' ], - unsupported: false, - allowedElements: [ 'li' ] - }, - 'doc-bibliography': { - type: 'landmark', - attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] - }, - owned: { - one: [ 'doc-biblioentry' ] - }, - nameFrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'section' ] - }, - 'doc-biblioref': { - type: 'link', - attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] - }, - owned: null, - nameFrom: [ 'author', 'contents' ], - context: null, - unsupported: false, - allowedElements: [ { - nodeName: 'a', - attributes: { - href: isNotNull - } - } ] - }, - 'doc-chapter': { - type: 'landmark', - attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] - }, - owned: null, - namefrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'section' ] - }, - 'doc-colophon': { - type: 'section', - attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] - }, - owned: null, - namefrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'section' ] - }, - 'doc-conclusion': { - type: 'landmark', - attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] - }, - owned: null, - namefrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'section' ] - }, - 'doc-cover': { - type: 'img', - attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] - }, - owned: null, - namefrom: [ 'author' ], - context: null, - unsupported: false - }, - 'doc-credit': { - type: 'section', - attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] - }, - owned: null, - namefrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'section' ] - }, - 'doc-credits': { - type: 'landmark', - attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] - }, - owned: null, - namefrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'section' ] - }, - 'doc-dedication': { - type: 'section', - attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] - }, - owned: null, - namefrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'section' ] - }, - 'doc-endnote': { - type: 'listitem', - attributes: { - allowed: [ 'aria-expanded', 'aria-level', 'aria-posinset', 'aria-setsize', 'aria-errormessage' ] - }, - owned: null, - namefrom: [ 'author' ], - context: [ 'doc-endnotes' ], - unsupported: false, - allowedElements: [ 'li' ] - }, - 'doc-endnotes': { - type: 'landmark', - attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] - }, - owned: { - one: [ 'doc-endnote' ] - }, - namefrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'section' ] - }, - 'doc-epigraph': { - type: 'section', - attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] - }, - owned: null, - namefrom: [ 'author' ], - context: null, - unsupported: false - }, - 'doc-epilogue': { - type: 'landmark', - attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] - }, - owned: null, - namefrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'section' ] - }, - 'doc-errata': { - type: 'landmark', - attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] - }, - owned: null, - namefrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'section' ] - }, - 'doc-example': { - type: 'section', - attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] - }, - owned: null, - namefrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'aside', 'section' ] - }, - 'doc-footnote': { - type: 'section', - attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] - }, - owned: null, - namefrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'aside', 'footer', 'header' ] - }, - 'doc-foreword': { - type: 'landmark', - attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] - }, - owned: null, - namefrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'section' ] - }, - 'doc-glossary': { - type: 'landmark', - attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] - }, - owned: [ 'term', 'definition' ], - namefrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'dl' ] - }, - 'doc-glossref': { - type: 'link', - attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] - }, - owned: null, - namefrom: [ 'author', 'contents' ], - context: null, - unsupported: false, - allowedElements: [ { - nodeName: 'a', - attributes: { - href: isNotNull - } - } ] - }, - 'doc-index': { - type: 'navigation', - attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] - }, - owned: null, - namefrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'nav', 'section' ] - }, - 'doc-introduction': { - type: 'landmark', - attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] - }, - owned: null, - namefrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'section' ] - }, - 'doc-noteref': { - type: 'link', - attributes: { - allowed: [ 'aria-expanded' ] - }, - owned: null, - namefrom: [ 'author', 'contents' ], - context: null, - unsupported: false, - allowedElements: [ { - nodeName: 'a', - attributes: { - href: isNotNull - } - } ] - }, - 'doc-notice': { - type: 'note', - attributes: { - allowed: [ 'aria-expanded' ] - }, - owned: null, - namefrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'section' ] - }, - 'doc-pagebreak': { - type: 'separator', - attributes: { - allowed: [ 'aria-expanded' ] - }, - owned: null, - namefrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'hr' ] - }, - 'doc-pagelist': { - type: 'navigation', - attributes: { - allowed: [ 'aria-expanded' ] - }, - owned: null, - namefrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'nav', 'section' ] - }, - 'doc-part': { - type: 'landmark', - attributes: { - allowed: [ 'aria-expanded' ] - }, - owned: null, - namefrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'section' ] - }, - 'doc-preface': { - type: 'landmark', - attributes: { - allowed: [ 'aria-expanded' ] - }, - owned: null, - namefrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'section' ] - }, - 'doc-prologue': { - type: 'landmark', - attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] - }, - owned: null, - namefrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'section' ] - }, - 'doc-pullquote': { - type: 'none', - attributes: { - allowed: [ 'aria-expanded' ] - }, - owned: null, - namefrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'aside', 'section' ] - }, - 'doc-qna': { - type: 'section', - attributes: { - allowed: [ 'aria-expanded' ] - }, - owned: null, - namefrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'section' ] - }, - 'doc-subtitle': { - type: 'sectionhead', - attributes: { - allowed: [ 'aria-expanded' ] - }, - owned: null, - namefrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: { - nodeName: [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ] - } - }, - 'doc-tip': { - type: 'note', - attributes: { - allowed: [ 'aria-expanded' ] - }, - owned: null, - namefrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'aside' ] - }, - 'doc-toc': { - type: 'navigation', - attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] - }, - owned: null, - namefrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'nav', 'section' ] - }, - feed: { - type: 'structure', - attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] - }, - owned: { - one: [ 'article' ] - }, - nameFrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'article', 'aside', 'section' ] - }, - figure: { - type: 'structure', - unsupported: false + implicit: [ 'body' ] }, form: { type: 'landmark', attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] + allowed: [ 'aria-expanded' ] }, owned: null, nameFrom: [ 'author' ], context: null, - implicit: [ 'form' ], - unsupported: false + implicit: [ 'form' ] }, grid: { type: 'composite', attributes: { - allowed: [ 'aria-activedescendant', 'aria-expanded', 'aria-colcount', 'aria-level', 'aria-multiselectable', 'aria-readonly', 'aria-rowcount', 'aria-errormessage' ] + allowed: [ 'aria-level', 'aria-multiselectable', 'aria-readonly', 'aria-activedescendant', 'aria-expanded' ] }, owned: { one: [ 'rowgroup', 'row' ] }, nameFrom: [ 'author' ], context: null, - implicit: [ 'table' ], - unsupported: false + implicit: [ 'table' ] }, gridcell: { type: 'widget', attributes: { - allowed: [ 'aria-colindex', 'aria-colspan', 'aria-expanded', 'aria-rowindex', 'aria-rowspan', 'aria-selected', 'aria-readonly', 'aria-required', 'aria-errormessage' ] + allowed: [ 'aria-selected', 'aria-readonly', 'aria-expanded', 'aria-required' ] }, owned: null, nameFrom: [ 'author', 'contents' ], context: [ 'row' ], - implicit: [ 'td', 'th' ], - unsupported: false + implicit: [ 'td', 'th' ] }, group: { type: 'structure', attributes: { - allowed: [ 'aria-activedescendant', 'aria-expanded', 'aria-errormessage' ] + allowed: [ 'aria-activedescendant', 'aria-expanded' ] }, owned: null, nameFrom: [ 'author' ], context: null, - implicit: [ 'details', 'optgroup' ], - unsupported: false, - allowedElements: [ 'dl', 'figcaption', 'fieldset', 'figure', 'footer', 'header', 'ol', 'ul' ] + implicit: [ 'details', 'optgroup' ] }, heading: { type: 'structure', attributes: { - required: [ 'aria-level' ], - allowed: [ 'aria-expanded', 'aria-errormessage' ] + allowed: [ 'aria-level', 'aria-expanded' ] }, owned: null, nameFrom: [ 'author', 'contents' ], context: null, - implicit: [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ], - unsupported: false + implicit: [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ] }, img: { type: 'structure', attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] + allowed: [ 'aria-expanded' ] }, owned: null, nameFrom: [ 'author' ], context: null, - implicit: [ 'img' ], - unsupported: false, - allowedElements: [ 'embed', 'iframe', 'object', 'svg' ] + implicit: [ 'img' ] }, input: { nameFrom: [ 'author' ], - type: 'abstract', - unsupported: false + type: 'abstract' }, landmark: { nameFrom: [ 'author' ], - type: 'abstract', - unsupported: false + type: 'abstract' }, link: { type: 'widget', attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] + allowed: [ 'aria-expanded' ] }, owned: null, nameFrom: [ 'author', 'contents' ], context: null, - implicit: [ 'a[href]' ], - unsupported: false, - allowedElements: [ 'button', { - nodeName: 'input', - properties: { - type: [ 'image', 'button' ] - } - } ] + implicit: [ 'a[href]' ] }, list: { type: 'structure', attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] + allowed: [ 'aria-expanded' ] }, owned: { all: [ 'listitem' ] }, nameFrom: [ 'author' ], context: null, - implicit: [ 'ol', 'ul', 'dl' ], - unsupported: false + implicit: [ 'ol', 'ul', 'dl' ] }, listbox: { type: 'composite', attributes: { - allowed: [ 'aria-activedescendant', 'aria-multiselectable', 'aria-required', 'aria-expanded', 'aria-orientation', 'aria-errormessage' ] + allowed: [ 'aria-activedescendant', 'aria-multiselectable', 'aria-required', 'aria-expanded' ] }, owned: { all: [ 'option' ] }, nameFrom: [ 'author' ], context: null, - implicit: [ 'select' ], - unsupported: false, - allowedElements: [ 'ol', 'ul' ] + implicit: [ 'select' ] }, listitem: { type: 'structure', attributes: { - allowed: [ 'aria-level', 'aria-posinset', 'aria-setsize', 'aria-expanded', 'aria-errormessage' ] + allowed: [ 'aria-level', 'aria-posinset', 'aria-setsize', 'aria-expanded' ] }, owned: null, nameFrom: [ 'author', 'contents' ], context: [ 'list' ], - implicit: [ 'li', 'dt' ], - unsupported: false + implicit: [ 'li', 'dt' ] }, log: { type: 'widget', attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] + allowed: [ 'aria-expanded' ] }, owned: null, nameFrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'section' ] + context: null }, main: { type: 'landmark', attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] + allowed: [ 'aria-expanded' ] }, owned: null, nameFrom: [ 'author' ], context: null, - implicit: [ 'main' ], - unsupported: false, - allowedElements: [ 'article', 'section' ] + implicit: [ 'main' ] }, marquee: { type: 'widget', attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] + allowed: [ 'aria-expanded' ] }, owned: null, nameFrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'section' ] + context: null }, math: { type: 'structure', attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] + allowed: [ 'aria-expanded' ] }, owned: null, nameFrom: [ 'author' ], context: null, - implicit: [ 'math' ], - unsupported: false + implicit: [ 'math' ] }, menu: { type: 'composite', attributes: { - allowed: [ 'aria-activedescendant', 'aria-expanded', 'aria-orientation', 'aria-errormessage' ] + allowed: [ 'aria-activedescendant', 'aria-expanded' ] }, owned: { one: [ 'menuitem', 'menuitemradio', 'menuitemcheckbox' ] }, nameFrom: [ 'author' ], context: null, - implicit: [ 'menu[type="context"]' ], - unsupported: false, - allowedElements: [ 'ol', 'ul' ] + implicit: [ 'menu[type="context"]' ] }, menubar: { type: 'composite', attributes: { - allowed: [ 'aria-activedescendant', 'aria-expanded', 'aria-orientation', 'aria-errormessage' ] + allowed: [ 'aria-activedescendant', 'aria-expanded' ] }, - owned: { - one: [ 'menuitem', 'menuitemradio', 'menuitemcheckbox' ] - }, + owned: null, nameFrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'ol', 'ul' ] + context: null }, menuitem: { type: 'widget', - attributes: { - allowed: [ 'aria-posinset', 'aria-setsize', 'aria-expanded', 'aria-errormessage' ] - }, + attributes: null, owned: null, nameFrom: [ 'author', 'contents' ], context: [ 'menu', 'menubar' ], - implicit: [ 'menuitem[type="command"]' ], - unsupported: false, - allowedElements: [ 'button', 'li', { - nodeName: 'iput', - properties: { - type: [ 'image', 'button' ] - } - }, { - nodeName: 'a', - attributes: { - href: isNotNull - } - } ] + implicit: [ 'menuitem[type="command"]' ] }, menuitemcheckbox: { type: 'widget', attributes: { - allowed: [ 'aria-checked', 'aria-posinset', 'aria-setsize', 'aria-errormessage' ] + required: [ 'aria-checked' ] }, owned: null, nameFrom: [ 'author', 'contents' ], context: [ 'menu', 'menubar' ], - implicit: [ 'menuitem[type="checkbox"]' ], - unsupported: false, - allowedElements: [ { - nodeName: [ 'button', 'li' ] - }, { - nodeName: 'input', - properties: { - type: [ 'checkbox', 'image', 'button' ] - } - }, { - nodeName: 'a', - attributes: { - href: isNotNull - } - } ] + implicit: [ 'menuitem[type="checkbox"]' ] }, menuitemradio: { type: 'widget', attributes: { - allowed: [ 'aria-checked', 'aria-selected', 'aria-posinset', 'aria-setsize', 'aria-errormessage' ] + allowed: [ 'aria-selected', 'aria-posinset', 'aria-setsize' ], + required: [ 'aria-checked' ] }, owned: null, nameFrom: [ 'author', 'contents' ], context: [ 'menu', 'menubar' ], - implicit: [ 'menuitem[type="radio"]' ], - unsupported: false, - allowedElements: [ { - nodeName: [ 'button', 'li' ] - }, { - nodeName: 'input', - properties: { - type: [ 'image', 'button', 'radio' ] - } - }, { - nodeName: 'a', - attributes: { - href: isNotNull - } - } ] + implicit: [ 'menuitem[type="radio"]' ] }, navigation: { type: 'landmark', attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] + allowed: [ 'aria-expanded' ] }, owned: null, nameFrom: [ 'author' ], context: null, - implicit: [ 'nav' ], - unsupported: false, - allowedElements: [ 'section' ] + implicit: [ 'nav' ] }, none: { type: 'structure', attributes: null, owned: null, nameFrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ { - nodeName: [ 'article', 'aside', 'dl', 'embed', 'figcaption', 'fieldset', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'iframe', 'li', 'ol', 'section', 'ul' ] - }, { - nodeName: 'img', - attributes: { - alt: isNotNull - } - } ] + context: null }, note: { type: 'structure', attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] + allowed: [ 'aria-expanded' ] }, owned: null, nameFrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'aside' ] + context: null }, option: { type: 'widget', attributes: { - allowed: [ 'aria-selected', 'aria-posinset', 'aria-setsize', 'aria-checked', 'aria-errormessage' ] + allowed: [ 'aria-selected', 'aria-posinset', 'aria-setsize', 'aria-checked' ] }, owned: null, nameFrom: [ 'author', 'contents' ], context: [ 'listbox' ], - implicit: [ 'option' ], - unsupported: false, - allowedElements: [ { - nodeName: [ 'button', 'li' ] - }, { - nodeName: 'input', - properties: { - type: [ 'checkbox', 'button' ] - } - }, { - nodeName: 'a', - attributes: { - href: isNotNull - } - } ] + implicit: [ 'option' ] }, presentation: { type: 'structure', attributes: null, owned: null, nameFrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ { - nodeName: [ 'article', 'aside', 'dl', 'embed', 'figcaption', 'fieldset', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'iframe', 'li', 'ol', 'section', 'ul' ] - }, { - nodeName: 'img', - attributes: { - alt: isNotNull - } - } ] + context: null }, progressbar: { type: 'widget', attributes: { - allowed: [ 'aria-valuetext', 'aria-valuenow', 'aria-valuemax', 'aria-valuemin', 'aria-expanded', 'aria-errormessage' ] + allowed: [ 'aria-valuetext', 'aria-valuenow', 'aria-valuemax', 'aria-valuemin' ] }, owned: null, nameFrom: [ 'author' ], context: null, - implicit: [ 'progress' ], - unsupported: false + implicit: [ 'progress' ] }, radio: { type: 'widget', attributes: { - allowed: [ 'aria-selected', 'aria-posinset', 'aria-setsize', 'aria-required', 'aria-errormessage', 'aria-checked' ] + allowed: [ 'aria-selected', 'aria-posinset', 'aria-setsize' ], + required: [ 'aria-checked' ] }, owned: null, nameFrom: [ 'author', 'contents' ], context: null, - implicit: [ 'input[type="radio"]' ], - unsupported: false, - allowedElements: [ { - nodeName: [ 'button', 'li' ] - }, { - nodeName: 'input', - properties: { - type: [ 'image', 'button' ] - } - } ] + implicit: [ 'input[type="radio"]' ] }, radiogroup: { type: 'composite', attributes: { - allowed: [ 'aria-activedescendant', 'aria-required', 'aria-expanded', 'aria-readonly', 'aria-errormessage' ] + allowed: [ 'aria-activedescendant', 'aria-required', 'aria-expanded' ] }, owned: { all: [ 'radio' ] }, nameFrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: { - nodeName: [ 'ol', 'ul' ] - } + context: null }, range: { nameFrom: [ 'author' ], - type: 'abstract', - unsupported: false + type: 'abstract' }, region: { - type: 'landmark', + type: 'structure', attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] + allowed: [ 'aria-expanded' ] }, owned: null, nameFrom: [ 'author' ], context: null, - implicit: [ 'section[aria-label]', 'section[aria-labelledby]', 'section[title]' ], - unsupported: false, - allowedElements: { - nodeName: [ 'article', 'aside' ] - } + implicit: [ 'section' ] }, roletype: { - type: 'abstract', - unsupported: false + type: 'abstract' }, row: { type: 'structure', attributes: { - allowed: [ 'aria-activedescendant', 'aria-colindex', 'aria-expanded', 'aria-level', 'aria-selected', 'aria-rowindex', 'aria-errormessage' ] + allowed: [ 'aria-level', 'aria-selected', 'aria-activedescendant', 'aria-expanded' ] }, owned: { one: [ 'cell', 'columnheader', 'rowheader', 'gridcell' ] }, nameFrom: [ 'author', 'contents' ], context: [ 'rowgroup', 'grid', 'treegrid', 'table' ], - implicit: [ 'tr' ], - unsupported: false + implicit: [ 'tr' ] }, rowgroup: { type: 'structure', attributes: { - allowed: [ 'aria-activedescendant', 'aria-expanded', 'aria-errormessage' ] + allowed: [ 'aria-activedescendant', 'aria-expanded' ] }, owned: { all: [ 'row' ] }, nameFrom: [ 'author', 'contents' ], - context: [ 'grid', 'table', 'treegrid' ], - implicit: [ 'tbody', 'thead', 'tfoot' ], - unsupported: false + context: [ 'grid', 'table' ], + implicit: [ 'tbody', 'thead', 'tfoot' ] }, rowheader: { type: 'structure', attributes: { - allowed: [ 'aria-colindex', 'aria-colspan', 'aria-expanded', 'aria-rowindex', 'aria-rowspan', 'aria-required', 'aria-readonly', 'aria-selected', 'aria-sort', 'aria-errormessage' ] + allowed: [ 'aria-sort', 'aria-required', 'aria-readonly', 'aria-expanded', 'aria-selected' ] }, owned: null, nameFrom: [ 'author', 'contents' ], context: [ 'row' ], - implicit: [ 'th' ], - unsupported: false + implicit: [ 'th' ] }, scrollbar: { type: 'widget', attributes: { - required: [ 'aria-controls', 'aria-valuenow' ], - allowed: [ 'aria-valuetext', 'aria-orientation', 'aria-errormessage', 'aria-valuemax', 'aria-valuemin' ] + required: [ 'aria-controls', 'aria-orientation', 'aria-valuenow', 'aria-valuemax', 'aria-valuemin' ], + allowed: [ 'aria-valuetext' ] }, owned: null, nameFrom: [ 'author' ], - context: null, - unsupported: false + context: null }, search: { type: 'landmark', attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] + allowed: [ 'aria-expanded' ] }, owned: null, nameFrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: { - nodeName: [ 'aside', 'form', 'section' ] - } + context: null }, searchbox: { type: 'widget', attributes: { - allowed: [ 'aria-activedescendant', 'aria-autocomplete', 'aria-multiline', 'aria-readonly', 'aria-required', 'aria-placeholder', 'aria-errormessage' ] + allowed: [ 'aria-activedescendant', 'aria-autocomplete', 'aria-multiline', 'aria-readonly', 'aria-required' ] }, owned: null, nameFrom: [ 'author' ], context: null, - implicit: [ 'input[type="search"]' ], - unsupported: false, - allowedElements: { - nodeName: 'input', - properties: { - type: 'text' - } - } + implicit: [ 'input[type="search"]' ] }, section: { nameFrom: [ 'author', 'contents' ], - type: 'abstract', - unsupported: false + type: 'abstract' }, sectionhead: { nameFrom: [ 'author', 'contents' ], - type: 'abstract', - unsupported: false + type: 'abstract' }, select: { nameFrom: [ 'author' ], - type: 'abstract', - unsupported: false + type: 'abstract' }, separator: { type: 'structure', attributes: { - allowed: [ 'aria-expanded', 'aria-orientation', 'aria-valuenow', 'aria-valuemax', 'aria-valuemin', 'aria-valuetext', 'aria-errormessage' ] + allowed: [ 'aria-expanded', 'aria-orientation' ] }, owned: null, nameFrom: [ 'author' ], context: null, - implicit: [ 'hr' ], - unsupported: false, - allowedElements: [ 'li' ] + implicit: [ 'hr' ] }, slider: { type: 'widget', attributes: { - allowed: [ 'aria-valuetext', 'aria-orientation', 'aria-readonly', 'aria-errormessage', 'aria-valuemax', 'aria-valuemin' ], - required: [ 'aria-valuenow' ] + allowed: [ 'aria-valuetext', 'aria-orientation' ], + required: [ 'aria-valuenow', 'aria-valuemax', 'aria-valuemin' ] }, owned: null, nameFrom: [ 'author' ], context: null, - implicit: [ 'input[type="range"]' ], - unsupported: false + implicit: [ 'input[type="range"]' ] }, spinbutton: { type: 'widget', attributes: { - allowed: [ 'aria-valuetext', 'aria-required', 'aria-readonly', 'aria-errormessage', 'aria-valuemax', 'aria-valuemin' ], - required: [ 'aria-valuenow' ] + allowed: [ 'aria-valuetext', 'aria-required' ], + required: [ 'aria-valuenow', 'aria-valuemax', 'aria-valuemin' ] }, owned: null, nameFrom: [ 'author' ], context: null, - implicit: [ 'input[type="number"]' ], - unsupported: false, - allowedElements: { - nodeName: 'input', - properties: { - type: 'text' - } - } + implicit: [ 'input[type="number"]' ] }, status: { type: 'widget', attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] + allowed: [ 'aria-expanded' ] }, owned: null, nameFrom: [ 'author' ], context: null, - implicit: [ 'output' ], - unsupported: false, - allowedElements: [ 'section' ] + implicit: [ 'output' ] }, structure: { - type: 'abstract', - unsupported: false + type: 'abstract' }, switch: { type: 'widget', attributes: { - allowed: [ 'aria-errormessage' ], required: [ 'aria-checked' ] }, owned: null, nameFrom: [ 'author', 'contents' ], - context: null, - unsupported: false, - allowedElements: [ 'button', { - nodeName: 'input', - properties: { - type: [ 'checkbox', 'image', 'button' ] - } - }, { - nodeName: 'a', - attributes: { - href: isNotNull - } - } ] + context: null }, tab: { type: 'widget', attributes: { - allowed: [ 'aria-selected', 'aria-expanded', 'aria-setsize', 'aria-posinset', 'aria-errormessage' ] + allowed: [ 'aria-selected', 'aria-expanded' ] }, owned: null, nameFrom: [ 'author', 'contents' ], - context: [ 'tablist' ], - unsupported: false, - allowedElements: [ { - nodeName: [ 'button', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'li' ] - }, { - nodeName: 'input', - properties: { - type: 'button' - } - }, { - nodeName: 'a', - attributes: { - href: isNotNull - } - } ] + context: [ 'tablist' ] }, table: { type: 'structure', attributes: { - allowed: [ 'aria-colcount', 'aria-rowcount', 'aria-errormessage' ] + allowed: [ 'aria-colcount', 'aria-rowcount' ] }, owned: { one: [ 'rowgroup', 'row' ] }, nameFrom: [ 'author' ], context: null, - implicit: [ 'table' ], - unsupported: false + implicit: [ 'table' ] }, tablist: { type: 'composite', attributes: { - allowed: [ 'aria-activedescendant', 'aria-expanded', 'aria-level', 'aria-multiselectable', 'aria-orientation', 'aria-errormessage' ] + allowed: [ 'aria-activedescendant', 'aria-expanded', 'aria-level', 'aria-multiselectable' ] }, owned: { all: [ 'tab' ] }, nameFrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'ol', 'ul' ] + context: null }, tabpanel: { type: 'widget', attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] + allowed: [ 'aria-expanded' ] }, owned: null, nameFrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'section' ] + context: null }, - term: { + text: { type: 'structure', - attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] - }, owned: null, nameFrom: [ 'author', 'contents' ], - context: null, - implicit: [ 'dt' ], - unsupported: false + context: null }, textbox: { type: 'widget', attributes: { - allowed: [ 'aria-activedescendant', 'aria-autocomplete', 'aria-multiline', 'aria-readonly', 'aria-required', 'aria-placeholder', 'aria-errormessage' ] + allowed: [ 'aria-activedescendant', 'aria-autocomplete', 'aria-multiline', 'aria-readonly', 'aria-required' ] }, owned: null, nameFrom: [ 'author' ], context: null, - implicit: [ 'input[type="text"]', 'input[type="email"]', 'input[type="password"]', 'input[type="tel"]', 'input[type="url"]', 'input:not([type])', 'textarea' ], - unsupported: false + implicit: [ 'input[type="text"]', 'input[type="email"]', 'input[type="password"]', 'input[type="tel"]', 'input[type="url"]', 'input:not([type])', 'textarea' ] }, timer: { type: 'widget', attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] + allowed: [ 'aria-expanded' ] }, owned: null, nameFrom: [ 'author' ], - context: null, - unsupported: false + context: null }, toolbar: { type: 'structure', attributes: { - allowed: [ 'aria-activedescendant', 'aria-expanded', 'aria-orientation', 'aria-errormessage' ] + allowed: [ 'aria-activedescendant', 'aria-expanded' ] }, owned: null, nameFrom: [ 'author' ], context: null, - implicit: [ 'menu[type="toolbar"]' ], - unsupported: false, - allowedElements: [ 'ol', 'ul' ] + implicit: [ 'menu[type="toolbar"]' ] }, tooltip: { type: 'widget', attributes: { - allowed: [ 'aria-expanded', 'aria-errormessage' ] + allowed: [ 'aria-expanded' ] }, owned: null, nameFrom: [ 'author', 'contents' ], - context: null, - unsupported: false + context: null }, tree: { type: 'composite', attributes: { - allowed: [ 'aria-activedescendant', 'aria-multiselectable', 'aria-required', 'aria-expanded', 'aria-orientation', 'aria-errormessage' ] + allowed: [ 'aria-activedescendant', 'aria-multiselectable', 'aria-required', 'aria-expanded' ] }, owned: { all: [ 'treeitem' ] }, nameFrom: [ 'author' ], - context: null, - unsupported: false, - allowedElements: [ 'ol', 'ul' ] + context: null }, treegrid: { type: 'composite', attributes: { - allowed: [ 'aria-activedescendant', 'aria-colcount', 'aria-expanded', 'aria-level', 'aria-multiselectable', 'aria-readonly', 'aria-required', 'aria-rowcount', 'aria-orientation', 'aria-errormessage' ] + allowed: [ 'aria-activedescendant', 'aria-expanded', 'aria-level', 'aria-multiselectable', 'aria-readonly', 'aria-required' ] }, owned: { - one: [ 'rowgroup', 'row' ] + all: [ 'treeitem' ] }, nameFrom: [ 'author' ], - context: null, - unsupported: false + context: null }, treeitem: { type: 'widget', attributes: { - allowed: [ 'aria-checked', 'aria-selected', 'aria-expanded', 'aria-level', 'aria-posinset', 'aria-setsize', 'aria-errormessage' ] + allowed: [ 'aria-checked', 'aria-selected', 'aria-expanded', 'aria-level', 'aria-posinset', 'aria-setsize' ] }, owned: null, nameFrom: [ 'author', 'contents' ], - context: [ 'group', 'tree' ], - unsupported: false, - allowedElements: [ 'li', { - nodeName: 'a', - attributes: { - href: isNotNull - } - } ] + context: [ 'treegrid', 'tree' ] }, widget: { - type: 'abstract', - unsupported: false + type: 'abstract' }, window: { nameFrom: [ 'author' ], - type: 'abstract', - unsupported: false + type: 'abstract' } }; - lookupTable.elementsAllowedNoRole = [ { - nodeName: [ 'base', 'body', 'caption', 'col', 'colgroup', 'datalist', 'dd', 'details', 'dt', 'head', 'html', 'keygen', 'label', 'legend', 'main', 'map', 'math', 'meta', 'meter', 'noscript', 'optgroup', 'param', 'picture', 'progress', 'script', 'source', 'style', 'template', 'textarea', 'title', 'track' ] - }, { - nodeName: 'area', - attributes: { - href: isNotNull - } - }, { - nodeName: 'input', - properties: { - type: [ 'color', 'data', 'datatime', 'file', 'hidden', 'month', 'number', 'password', 'range', 'reset', 'submit', 'time', 'week' ] - } - }, { - nodeName: 'input', - attributes: { - list: isNull - }, - properties: { - type: [ 'email', 'search', 'tel', 'url' ] - } - }, { - nodeName: 'link', - attributes: { - href: isNotNull - } - }, { - nodeName: 'menu', - attributes: { - type: 'context' - } - }, { - nodeName: 'menuitem', - attributes: { - type: [ 'command', 'checkbox', 'radio' ] - } - }, { - nodeName: 'select', - condition: function condition(node) { - return Number(node.getAttribute('size')) > 1; - }, - properties: { - multiple: true - } - }, { - nodeName: [ 'clippath', 'cursor', 'defs', 'desc', 'feblend', 'fecolormatrix', 'fecomponenttransfer', 'fecomposite', 'feconvolvematrix', 'fediffuselighting', 'fedisplacementmap', 'fedistantlight', 'fedropshadow', 'feflood', 'fefunca', 'fefuncb', 'fefuncg', 'fefuncr', 'fegaussianblur', 'feimage', 'femerge', 'femergenode', 'femorphology', 'feoffset', 'fepointlight', 'fespecularlighting', 'fespotlight', 'fetile', 'feturbulence', 'filter', 'hatch', 'hatchpath', 'lineargradient', 'marker', 'mask', 'meshgradient', 'meshpatch', 'meshrow', 'metadata', 'mpath', 'pattern', 'radialgradient', 'solidcolor', 'stop', 'switch', 'view' ] - } ]; - lookupTable.elementsAllowedAnyRole = [ { - nodeName: 'a', - attributes: { - href: isNull - } - }, { - nodeName: [ 'abbr', 'address', 'canvas', 'div', 'p', 'pre', 'blockquote', 'ins', 'del', 'output', 'span', 'table', 'tbody', 'thead', 'tfoot', 'td', 'em', 'strong', 'small', 's', 'cite', 'q', 'dfn', 'abbr', 'time', 'code', 'var', 'samp', 'kbd', 'sub', 'sup', 'i', 'b', 'u', 'mark', 'ruby', 'rt', 'rp', 'bdi', 'bdo', 'br', 'wbr', 'th', 'tr' ] - } ]; - lookupTable.evaluateRoleForElement = { - A: function A(_ref12) { - var node = _ref12.node, out = _ref12.out; - if (node.namespaceURI === 'http://www.w3.org/2000/svg') { - return true; - } - if (node.href.length) { - return out; - } - return true; - }, - AREA: function AREA(_ref13) { - var node = _ref13.node; - return !node.href; - }, - BUTTON: function BUTTON(_ref14) { - var node = _ref14.node, role = _ref14.role, out = _ref14.out; - if (node.getAttribute('type') === 'menu') { - return role === 'menuitem'; - } - return out; - }, - IMG: function IMG(_ref15) { - var node = _ref15.node, out = _ref15.out; - if (node.alt) { - return !out; - } - return out; - }, - INPUT: function INPUT(_ref16) { - var node = _ref16.node, role = _ref16.role, out = _ref16.out; - switch (node.type) { - case 'button': - case 'image': - return out; - - case 'checkbox': - if (role === 'button' && node.hasAttribute('aria-pressed')) { - return true; - } - return out; - - case 'radio': - return role === 'menuitemradio'; - - case 'text': - return role === 'combobox' || role === 'searchbox' || role === 'spinbutton'; - - default: - return false; - } - }, - LI: function LI(_ref17) { - var node = _ref17.node, out = _ref17.out; - var hasImplicitListitemRole = axe.utils.matchesSelector(node, 'ol li, ul li'); - if (hasImplicitListitemRole) { - return out; - } - return true; - }, - MENU: function MENU(_ref18) { - var node = _ref18.node; - if (node.getAttribute('type') === 'context') { - return false; - } - return true; - }, - OPTION: function OPTION(_ref19) { - var node = _ref19.node; - var withinOptionList = axe.utils.matchesSelector(node, 'select > option, datalist > option, optgroup > option'); - return !withinOptionList; - }, - SELECT: function SELECT(_ref20) { - var node = _ref20.node, role = _ref20.role; - return !node.multiple && node.size <= 1 && role === 'menu'; - }, - SVG: function SVG(_ref21) { - var node = _ref21.node, out = _ref21.out; - if (node.parentNode && node.parentNode.namespaceURI === 'http://www.w3.org/2000/svg') { - return true; - } - return out; - } - }; - lookupTable.rolesOfType = { - widget: [ 'button', 'checkbox', 'dialog', 'gridcell', 'heading', 'link', 'log', 'marquee', 'menuitem', 'menuitemcheckbox', 'menuitemradio', 'option', 'progressbar', 'radio', 'scrollbar', 'slider', 'spinbutton', 'status', 'switch', 'tab', 'tabpanel', 'textbox', 'timer', 'tooltip', 'tree', 'treeitem' ] - }; var color = {}; commons.color = color; var dom = commons.dom = {}; - var forms = {}; - commons.forms = forms; - function matches(node, definition) { - return matches.fromDefinition(node, definition); - } - commons.matches = matches; var table = commons.table = {}; - var text = commons.text = { - EdgeFormDefaults: {} - }; + var text = commons.text = {}; var utils = commons.utils = axe.utils; - aria.arialabelText = function arialabelText(node) { - node = node.actualNode || node; - if (node.nodeType !== 1) { - return ''; - } - return node.getAttribute('aria-label') || ''; - }; - aria.arialabelledbyText = function arialabelledbyText(node) { - var context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - node = node.actualNode || node; - if (node.nodeType !== 1 || context.inLabelledByContext || context.inControlContext) { - return ''; - } - var refs = dom.idrefs(node, 'aria-labelledby').filter(function(elm) { - return elm; - }); - return refs.reduce(function(accessibleName, elm) { - var accessibleNameAdd = text.accessibleText(elm, _extends({ - inLabelledByContext: true, - startNode: context.startNode || node - }, context)); - if (!accessibleName) { - return accessibleNameAdd; - } else { - return ''.concat(accessibleName, ' ').concat(accessibleNameAdd); - } - }, ''); - }; aria.requiredAttr = function(role) { - var roles = aria.lookupTable.role[role], attr = roles && roles.attributes && roles.attributes.required; + 'use strict'; + var roles = lookupTables.role[role], attr = roles && roles.attributes && roles.attributes.required; return attr || []; }; aria.allowedAttr = function(role) { - var roles = aria.lookupTable.role[role], attr = roles && roles.attributes && roles.attributes.allowed || [], requiredAttr = roles && roles.attributes && roles.attributes.required || []; - return attr.concat(aria.lookupTable.globalAttributes).concat(requiredAttr); + 'use strict'; + var roles = lookupTables.role[role], attr = roles && roles.attributes && roles.attributes.allowed || [], requiredAttr = roles && roles.attributes && roles.attributes.required || []; + return attr.concat(lookupTables.globalAttributes).concat(requiredAttr); }; - aria.validateAttr = function validateAttr(att) { - var attrDefinition = aria.lookupTable.attributes[att]; - return !!attrDefinition; + aria.validateAttr = function(att) { + 'use strict'; + return !!lookupTables.attributes[att]; }; - function getRoleSegments(node) { - var roles = []; - if (!node) { - return roles; - } - if (node.hasAttribute('role')) { - var nodeRoles = axe.utils.tokenList(node.getAttribute('role').toLowerCase()); - roles = roles.concat(nodeRoles); - } - if (node.hasAttributeNS('http://www.idpf.org/2007/ops', 'type')) { - var epubRoles = axe.utils.tokenList(node.getAttributeNS('http://www.idpf.org/2007/ops', 'type').toLowerCase()).map(function(role) { - return 'doc-'.concat(role); - }); - roles = roles.concat(epubRoles); - } - roles = roles.filter(function(role) { - return axe.commons.aria.isValidRole(role); - }); - return roles; - } - aria.getElementUnallowedRoles = function getElementUnallowedRoles(node) { - var allowImplicit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; - var tagName = node.nodeName.toUpperCase(); - if (!axe.utils.isHtmlElement(node)) { - return []; - } - var roleSegments = getRoleSegments(node); - var implicitRole = axe.commons.aria.implicitRole(node); - var unallowedRoles = roleSegments.filter(function(role) { - if (allowImplicit && role === implicitRole) { - return false; - } - if (!allowImplicit && !(role === 'row' && tagName === 'TR' && axe.utils.matchesSelector(node, 'table[role="grid"] > tr'))) { - return true; - } - return !aria.isAriaRoleAllowedOnElement(node, role); - }); - return unallowedRoles; - }; - aria.getOwnedVirtual = function getOwned(_ref22) { - var actualNode = _ref22.actualNode, children = _ref22.children; - if (!actualNode || !children) { - throw new Error('getOwnedVirtual requires a virtual node'); - } - return dom.idrefs(actualNode, 'aria-owns').reduce(function(ownedElms, element) { - if (element) { - var virtualNode = axe.utils.getNodeFromTree(element); - ownedElms.push(virtualNode); - } - return ownedElms; - }, children); - }; - aria.getRole = function getRole(node) { - var _ref23 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, noImplicit = _ref23.noImplicit, fallback = _ref23.fallback, abstracts = _ref23.abstracts, dpub = _ref23.dpub; - node = node.actualNode || node; - if (node.nodeType !== 1) { - return null; - } - var roleAttr = (node.getAttribute('role') || '').trim().toLowerCase(); - var roleList = fallback ? axe.utils.tokenList(roleAttr) : [ roleAttr ]; - var validRoles = roleList.filter(function(role) { - if (!dpub && role.substr(0, 4) === 'doc-') { - return false; - } - return aria.isValidRole(role, { - allowAbstract: abstracts - }); - }); - var explicitRole = validRoles[0]; - if (!explicitRole && !noImplicit) { - return aria.implicitRole(node); - } - return explicitRole || null; - }; - var idRefsRegex = /^idrefs?$/; - function cacheIdRefs(node, refAttrs) { - if (node.hasAttribute) { - if (node.nodeName.toUpperCase() === 'LABEL' && node.hasAttribute('for')) { - axe._cache.get('idRefs')[node.getAttribute('for')] = true; - } - refAttrs.filter(function(attr) { - return node.hasAttribute(attr); - }).forEach(function(attr) { - var attrValue = node.getAttribute(attr); - axe.utils.tokenList(attrValue).forEach(function(id) { - axe._cache.get('idRefs')[id] = true; - }); - }); - } - for (var i = 0; i < node.children.length; i++) { - cacheIdRefs(node.children[i], refAttrs); - } - } - aria.isAccessibleRef = function isAccessibleRef(node) { - node = node.actualNode || node; - var root = dom.getRootNode(node); - root = root.documentElement || root; - var id = node.id; - if (!axe._cache.get('idRefs')) { - axe._cache.set('idRefs', {}); - var refAttrs = Object.keys(aria.lookupTable.attributes).filter(function(attr) { - var type = aria.lookupTable.attributes[attr].type; - return idRefsRegex.test(type); - }); - cacheIdRefs(root, refAttrs); - } - return axe._cache.get('idRefs')[id] === true; - }; - aria.isAriaRoleAllowedOnElement = function isAriaRoleAllowedOnElement(node, role) { - var nodeName = node.nodeName.toUpperCase(); - var lookupTable = axe.commons.aria.lookupTable; - if (matches(node, lookupTable.elementsAllowedNoRole)) { - return false; - } - if (matches(node, lookupTable.elementsAllowedAnyRole)) { + aria.validateAttrValue = function(node, attr) { + 'use strict'; + var matches, list, value = node.getAttribute(attr), attrInfo = lookupTables.attributes[attr]; + var doc = dom.getRootNode(node); + if (!attrInfo) { return true; } - var roleValue = lookupTable.role[role]; - if (!roleValue || !roleValue.allowedElements) { - return false; + switch (attrInfo.type) { + case 'boolean': + case 'nmtoken': + return typeof value === 'string' && attrInfo.values.indexOf(value.toLowerCase()) !== -1; + + case 'nmtokens': + list = axe.utils.tokenList(value); + return list.reduce(function(result, token) { + return result && attrInfo.values.indexOf(token) !== -1; + }, list.length !== 0); + + case 'idref': + return !!(value && doc.getElementById(value)); + + case 'idrefs': + list = axe.utils.tokenList(value); + return list.reduce(function(result, token) { + return !!(result && doc.getElementById(token)); + }, list.length !== 0); + + case 'string': + return true; + + case 'decimal': + matches = value.match(/^[-+]?([0-9]*)\.?([0-9]*)$/); + return !!(matches && (matches[1] || matches[2])); + + case 'int': + return /^[-+]?[0-9]+$/.test(value); } - var out = matches(node, roleValue.allowedElements); - if (Object.keys(lookupTable.evaluateRoleForElement).includes(nodeName)) { - return lookupTable.evaluateRoleForElement[nodeName]({ - node: node, - role: role, - out: out - }); - } - return out; }; - aria.isUnsupportedRole = function(role) { - var roleDefinition = aria.lookupTable.role[role]; - return roleDefinition ? roleDefinition.unsupported : false; - }; - aria.labelVirtual = function(_ref24) { - var actualNode = _ref24.actualNode; + aria.label = function(node) { var ref, candidate; - if (actualNode.getAttribute('aria-labelledby')) { - ref = dom.idrefs(actualNode, 'aria-labelledby'); + if (node.actualNode instanceof Node === false) { + node = axe.utils.getNodeFromTree(axe._tree[0], node); + } + if (node.actualNode.getAttribute('aria-labelledby')) { + ref = dom.idrefs(node.actualNode, 'aria-labelledby'); candidate = ref.map(function(thing) { - var vNode = axe.utils.getNodeFromTree(thing); - return vNode ? text.visibleVirtual(vNode, true) : ''; + var vNode = axe.utils.getNodeFromTree(axe._tree[0], thing); + return vNode ? text.visible(vNode, true) : ''; }).join(' ').trim(); if (candidate) { return candidate; } } - candidate = actualNode.getAttribute('aria-label'); + candidate = node.actualNode.getAttribute('aria-label'); if (candidate) { candidate = text.sanitize(candidate).trim(); if (candidate) { @@ -14473,52 +8216,30 @@ } return null; }; - aria.label = function(node) { - node = axe.utils.getNodeFromTree(node); - return aria.labelVirtual(node); - }; - aria.namedFromContents = function namedFromContents(node) { - var _ref25 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, strict = _ref25.strict; - node = node.actualNode || node; - if (node.nodeType !== 1) { - return false; - } - var role = aria.getRole(node); - var roleDef = aria.lookupTable.role[role]; - if (roleDef && roleDef.nameFrom.includes('contents') || node.nodeName.toUpperCase() === 'TABLE') { + aria.isValidRole = function(role) { + 'use strict'; + if (lookupTables.role[role]) { return true; } - if (strict) { - return false; - } - return !roleDef || [ 'presentation', 'none' ].includes(role); - }; - aria.isValidRole = function(role) { - var _ref26 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, allowAbstract = _ref26.allowAbstract, _ref26$flagUnsupporte = _ref26.flagUnsupported, flagUnsupported = _ref26$flagUnsupporte === void 0 ? false : _ref26$flagUnsupporte; - var roleDefinition = aria.lookupTable.role[role]; - var isRoleUnsupported = roleDefinition ? roleDefinition.unsupported : false; - if (!roleDefinition || flagUnsupported && isRoleUnsupported) { - return false; - } - return allowAbstract ? true : roleDefinition.type !== 'abstract'; + return false; }; aria.getRolesWithNameFromContents = function() { - return Object.keys(aria.lookupTable.role).filter(function(r) { - return aria.lookupTable.role[r].nameFrom && aria.lookupTable.role[r].nameFrom.indexOf('contents') !== -1; + return Object.keys(lookupTables.role).filter(function(r) { + return lookupTables.role[r].nameFrom && lookupTables.role[r].nameFrom.indexOf('contents') !== -1; }); }; aria.getRolesByType = function(roleType) { - return Object.keys(aria.lookupTable.role).filter(function(r) { - return aria.lookupTable.role[r].type === roleType; + return Object.keys(lookupTables.role).filter(function(r) { + return lookupTables.role[r].type === roleType; }); }; aria.getRoleType = function(role) { - var r = aria.lookupTable.role[role]; + var r = lookupTables.role[role]; return r && r.type || null; }; aria.requiredOwned = function(role) { 'use strict'; - var owned = null, roles = aria.lookupTable.role[role]; + var owned = null, roles = lookupTables.role[role]; if (roles) { owned = axe.utils.clone(roles.owned); } @@ -14526,7 +8247,7 @@ }; aria.requiredContext = function(role) { 'use strict'; - var context = null, roles = aria.lookupTable.role[role]; + var context = null, roles = lookupTables.role[role]; if (roles) { context = axe.utils.clone(roles.context); } @@ -14534,7 +8255,7 @@ }; aria.implicitNodes = function(role) { 'use strict'; - var implicit = null, roles = aria.lookupTable.role[role]; + var implicit = null, roles = lookupTables.role[role]; if (roles && roles.implicit) { implicit = axe.utils.clone(roles.implicit); } @@ -14571,8 +8292,8 @@ return sortedRole.name; }); }; - var roles = Object.keys(aria.lookupTable.role).map(function(role) { - var lookup = aria.lookupTable.role[role]; + var roles = Object.keys(lookupTables.role).map(function(role) { + var lookup = lookupTables.role[role]; return { name: role, implicit: lookup && lookup.implicit @@ -14582,7 +8303,7 @@ if (!availableImplicitRoles.length) { return null; } - var nodeAttributes = axe.utils.getNodeAttributes(node); + var nodeAttributes = node.attributes; var ariaAttributes = []; for (var i = 0, j = nodeAttributes.length; i < j; i++) { var attr = nodeAttributes[i]; @@ -14592,61 +8313,6 @@ } return sortRolesByOptimalAriaContext(availableImplicitRoles, ariaAttributes).shift(); }; - aria.validateAttrValue = function validateAttrValue(node, attr) { - 'use strict'; - var matches, list, value = node.getAttribute(attr), attrInfo = aria.lookupTable.attributes[attr]; - var doc = dom.getRootNode(node); - if (!attrInfo) { - return true; - } - if (attrInfo.allowEmpty && (!value || value.trim() === '')) { - return true; - } - switch (attrInfo.type) { - case 'boolean': - case 'nmtoken': - return typeof value === 'string' && attrInfo.values.includes(value.toLowerCase()); - - case 'nmtokens': - list = axe.utils.tokenList(value); - return list.reduce(function(result, token) { - return result && attrInfo.values.includes(token); - }, list.length !== 0); - - case 'idref': - return !!(value && doc.getElementById(value)); - - case 'idrefs': - list = axe.utils.tokenList(value); - return list.some(function(token) { - return doc.getElementById(token); - }); - - case 'string': - return value.trim() !== ''; - - case 'decimal': - matches = value.match(/^[-+]?([0-9]*)\.?([0-9]*)$/); - return !!(matches && (matches[1] || matches[2])); - - case 'int': - return /^[-+]?[0-9]+$/.test(value); - } - }; - color.centerPointOfRect = function centerPointOfRect(rect) { - if (rect.left > window.innerWidth) { - return undefined; - } - if (rect.top > window.innerHeight) { - return undefined; - } - var x = Math.min(Math.ceil(rect.left + rect.width / 2), window.innerWidth - 1); - var y = Math.min(Math.ceil(rect.top + rect.height / 2), window.innerHeight - 1); - return { - x: x, - y: y - }; - }; color.Color = function(red, green, blue, alpha) { this.red = red; this.green = green; @@ -14681,7 +8347,7 @@ this.red = parseInt(match[1], 10); this.green = parseInt(match[2], 10); this.blue = parseInt(match[3], 10); - this.alpha = Math.round(parseFloat(match[4]) * 100) / 100; + this.alpha = parseFloat(match[4]); return; } }; @@ -14717,29 +8383,11 @@ color.hasValidContrastRatio = function(bg, fg, fontSize, isBold) { var contrast = color.getContrast(bg, fg); var isSmallFont = isBold && Math.ceil(fontSize * 72) / 96 < 14 || !isBold && Math.ceil(fontSize * 72) / 96 < 18; - var expectedContrastRatio = isSmallFont ? 4.5 : 3; return { - isValid: contrast > expectedContrastRatio, - contrastRatio: contrast, - expectedContrastRatio: expectedContrastRatio + isValid: isSmallFont && contrast >= 4.5 || !isSmallFont && contrast >= 3, + contrastRatio: contrast }; }; - color.elementHasImage = function elementHasImage(elm, style) { - var graphicNodes = [ 'IMG', 'CANVAS', 'OBJECT', 'IFRAME', 'VIDEO', 'SVG' ]; - var nodeName = elm.nodeName.toUpperCase(); - if (graphicNodes.includes(nodeName)) { - axe.commons.color.incompleteData.set('bgColor', 'imgNode'); - return true; - } - style = style || window.getComputedStyle(elm); - var bgImageStyle = style.getPropertyValue('background-image'); - var hasBgImage = bgImageStyle !== 'none'; - if (hasBgImage) { - var hasGradient = /gradient/.test(bgImageStyle); - axe.commons.color.incompleteData.set('bgColor', hasGradient ? 'bgGradient' : 'bgImage'); - } - return hasBgImage; - }; function _getFonts(style) { return style.getPropertyValue('font-family').split(/[,;]/g).map(function(font) { return font.trim().toLowerCase(); @@ -14772,20 +8420,139 @@ return hasStyle; } color.elementIsDistinct = elementIsDistinct; - color.getBackgroundColor = function getBackgroundColor(elm) { + var graphicNodes = [ 'IMG', 'CANVAS', 'OBJECT', 'IFRAME', 'VIDEO', 'SVG' ]; + function elmHasImage(elm, style) { + var nodeName = elm.nodeName.toUpperCase(); + if (graphicNodes.includes(nodeName)) { + axe.commons.color.incompleteData.set('bgColor', 'imgNode'); + return true; + } + style = style || window.getComputedStyle(elm); + var bgImageStyle = style.getPropertyValue('background-image'); + var hasBgImage = bgImageStyle !== 'none'; + if (hasBgImage) { + var hasGradient = /gradient/.test(bgImageStyle); + axe.commons.color.incompleteData.set('bgColor', hasGradient ? 'bgGradient' : 'bgImage'); + } + return hasBgImage; + } + function getBgColor(elm, elmStyle) { + elmStyle = elmStyle || window.getComputedStyle(elm); + var bgColor = new color.Color(); + bgColor.parseRgbString(elmStyle.getPropertyValue('background-color')); + if (bgColor.alpha !== 0) { + var opacity = elmStyle.getPropertyValue('opacity'); + bgColor.alpha = bgColor.alpha * opacity; + } + return bgColor; + } + function contentOverlapping(targetElement, bgNode) { + var targetRect = targetElement.getClientRects()[0]; + var obscuringElements = document.elementsFromPoint(targetRect.left, targetRect.top); + if (obscuringElements) { + for (var i = 0; i < obscuringElements.length; i++) { + if (obscuringElements[i] !== targetElement && obscuringElements[i] === bgNode) { + return true; + } + } + } + return false; + } + function calculateObscuringAlpha(elmIndex, elmStack, originalElm) { + var totalAlpha = 0; + if (elmIndex > 0) { + for (var i = elmIndex - 1; i >= 0; i--) { + var bgElm = elmStack[i]; + var bgElmStyle = window.getComputedStyle(bgElm); + var bgColor = getBgColor(bgElm, bgElmStyle); + if (bgColor.alpha && contentOverlapping(originalElm, bgElm)) { + totalAlpha += bgColor.alpha; + } else { + elmStack.splice(i, 1); + } + } + } + return totalAlpha; + } + function elmPartiallyObscured(elm, bgElm, bgColor) { + var obscured = elm !== bgElm && !dom.visuallyContains(elm, bgElm) && bgColor.alpha !== 0; + if (obscured) { + axe.commons.color.incompleteData.set('bgColor', 'elmPartiallyObscured'); + } + return obscured; + } + function includeMissingElements(elmStack, elm) { + var elementMap = { + TD: 'TR', + INPUT: 'LABEL' + }; + var tagArray = elmStack.map(function(elm) { + return elm.tagName; + }); + var bgNodes = elmStack; + for (var candidate in elementMap) { + if (elementMap.hasOwnProperty(candidate)) { + if (elm.tagName === candidate) { + var ancestorMatch = axe.commons.dom.findUp(elm, elementMap[candidate]); + if (ancestorMatch && elmStack.indexOf(ancestorMatch) === -1) { + var overlaps = axe.commons.dom.visuallyOverlaps(elm.getBoundingClientRect(), ancestorMatch); + if (overlaps) { + bgNodes.splice(elmStack.indexOf(elm) + 1, 0, ancestorMatch); + } + } + } + if (elm.tagName === elementMap[candidate] && tagArray.indexOf(elm.tagName) === -1) { + bgNodes.splice(tagArray.indexOf(candidate) + 1, 0, elm); + } + } + } + return bgNodes; + } + function sortPageBackground(elmStack) { + var bodyIndex = elmStack.indexOf(document.body); + var bgNodes = elmStack; + if (bodyIndex > 1 && !elmHasImage(document.documentElement) && getBgColor(document.documentElement).alpha === 0) { + bgNodes.splice(bodyIndex, 1); + bgNodes.splice(elmStack.indexOf(document.documentElement), 1); + bgNodes.push(document.body); + } + return bgNodes; + } + color.getBackgroundStack = function(elm) { + var rect = elm.getBoundingClientRect(); + var x = void 0, y = void 0; + if (rect.left > window.innerWidth) { + return; + } + if (rect.top > window.innerHeight) { + return; + } + x = Math.min(Math.ceil(rect.left + rect.width / 2), window.innerWidth - 1); + y = Math.min(Math.ceil(rect.top + rect.height / 2), window.innerHeight - 1); + var elmStack = document.elementsFromPoint(x, y); + elmStack = includeMissingElements(elmStack, elm); + elmStack = dom.reduceToElementsBelowFloating(elmStack, elm); + elmStack = sortPageBackground(elmStack); + var elmIndex = elmStack.indexOf(elm); + if (calculateObscuringAlpha(elmIndex, elmStack, elm) >= .99) { + axe.commons.color.incompleteData.set('bgColor', 'bgOverlap'); + return null; + } + return elmIndex !== -1 ? elmStack : null; + }; + color.getBackgroundColor = function(elm) { var bgElms = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; var noScroll = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; if (noScroll !== true) { - var clientHeight = elm.getBoundingClientRect().height; - var alignToTop = clientHeight - 2 >= window.innerHeight * 2; + var alignToTop = elm.clientHeight - 2 >= window.innerHeight * 2; elm.scrollIntoView(alignToTop); } var bgColors = []; var elmStack = color.getBackgroundStack(elm); (elmStack || []).some(function(bgElm) { var bgElmStyle = window.getComputedStyle(bgElm); - var bgColor = color.getOwnBackgroundColor(bgElmStyle); - if (elmPartiallyObscured(elm, bgElm, bgColor) || color.elementHasImage(bgElm, bgElmStyle)) { + var bgColor = getBgColor(bgElm, bgElmStyle); + if (elmPartiallyObscured(elm, bgElm, bgColor) || elmHasImage(bgElm, bgElmStyle)) { bgColors = null; bgElms.push(bgElm); return true; @@ -14805,151 +8572,9 @@ } return null; }; - color.getBackgroundStack = function getBackgroundStack(elm) { - var elmStack = color.filteredRectStack(elm); - if (elmStack === null) { - return null; - } - elmStack = includeMissingElements(elmStack, elm); - elmStack = dom.reduceToElementsBelowFloating(elmStack, elm); - elmStack = sortPageBackground(elmStack); - var elmIndex = elmStack.indexOf(elm); - if (calculateObscuringElement(elmIndex, elmStack, elm)) { - axe.commons.color.incompleteData.set('bgColor', 'bgOverlap'); - return null; - } - return elmIndex !== -1 ? elmStack : null; - }; - color.filteredRectStack = function filteredRectStack(elm) { - var rectStack = color.getRectStack(elm); - if (rectStack && rectStack.length === 1) { - return rectStack[0]; - } - if (rectStack && rectStack.length > 1) { - var boundingStack = rectStack.shift(); - var isSame; - includeMissingElements(boundingStack, elm); - rectStack.forEach(function(rectList, index) { - if (index === 0) { - return; - } - var rectA = rectStack[index - 1], rectB = rectStack[index]; - isSame = rectA.every(function(element, elementIndex) { - return element === rectB[elementIndex]; - }) || boundingStack.includes(elm); - }); - if (!isSame) { - axe.commons.color.incompleteData.set('bgColor', 'elmPartiallyObscuring'); - return null; - } - return rectStack[0]; - } - axe.commons.color.incompleteData.set('bgColor', 'outsideViewport'); - return null; - }; - color.getRectStack = function(elm) { - var boundingCoords = axe.commons.color.centerPointOfRect(elm.getBoundingClientRect()); - if (!boundingCoords) { - return null; - } - var boundingStack = dom.shadowElementsFromPoint(boundingCoords.x, boundingCoords.y); - var rects = Array.from(elm.getClientRects()); - if (!rects || rects.length <= 1) { - return [ boundingStack ]; - } - var filteredArr = rects.filter(function(rect) { - return rect.width && rect.width > 0; - }).map(function(rect) { - var coords = axe.commons.color.centerPointOfRect(rect); - if (coords) { - return dom.shadowElementsFromPoint(coords.x, coords.y); - } - }); - if (filteredArr.some(function(stack) { - return stack === undefined; - })) { - return null; - } - filteredArr.splice(0, 0, boundingStack); - return filteredArr; - }; - function sortPageBackground(elmStack) { - var bodyIndex = elmStack.indexOf(document.body); - var bgNodes = elmStack; - var sortBodyElement = bodyIndex > 1 || bodyIndex === -1; - if (sortBodyElement && !color.elementHasImage(document.documentElement) && color.getOwnBackgroundColor(window.getComputedStyle(document.documentElement)).alpha === 0) { - if (bodyIndex > 1) { - bgNodes.splice(bodyIndex, 1); - } - bgNodes.splice(elmStack.indexOf(document.documentElement), 1); - bgNodes.push(document.body); - } - return bgNodes; - } - function includeMissingElements(elmStack, elm) { - var nodeName = elm.nodeName.toUpperCase(); - var elementMap = { - TD: [ 'TR', 'THEAD', 'TBODY', 'TFOOT' ], - TH: [ 'TR', 'THEAD', 'TBODY', 'TFOOT' ], - INPUT: [ 'LABEL' ] - }; - var tagArray = elmStack.map(function(elm) { - return elm.nodeName.toUpperCase(); - }); - var bgNodes = elmStack; - for (var candidate in elementMap) { - if (tagArray.includes(candidate)) { - for (var candidateIndex = 0; candidateIndex < elementMap[candidate].length; candidateIndex++) { - var ancestorMatch = axe.commons.dom.findUp(elm, elementMap[candidate][candidateIndex]); - if (ancestorMatch && elmStack.indexOf(ancestorMatch) === -1) { - var overlaps = axe.commons.dom.visuallyOverlaps(elm.getBoundingClientRect(), ancestorMatch); - if (overlaps) { - bgNodes.splice(tagArray.indexOf(candidate) + 1, 0, ancestorMatch); - } - } - if (nodeName === elementMap[candidate][candidateIndex] && tagArray.indexOf(nodeName) === -1) { - bgNodes.splice(tagArray.indexOf(candidate) + 1, 0, elm); - } - } - } - } - return bgNodes; - } - function elmPartiallyObscured(elm, bgElm, bgColor) { - var obscured = elm !== bgElm && !dom.visuallyContains(elm, bgElm) && bgColor.alpha !== 0; - if (obscured) { - axe.commons.color.incompleteData.set('bgColor', 'elmPartiallyObscured'); - } - return obscured; - } - function calculateObscuringElement(elmIndex, elmStack, originalElm) { - if (elmIndex > 0) { - for (var i = elmIndex - 1; i >= 0; i--) { - var bgElm = elmStack[i]; - if (contentOverlapping(originalElm, bgElm)) { - return true; - } else { - elmStack.splice(i, 1); - } - } - } - return false; - } - function contentOverlapping(targetElement, bgNode) { - var targetRect = targetElement.getClientRects()[0]; - var obscuringElements = dom.shadowElementsFromPoint(targetRect.left, targetRect.top); - if (obscuringElements) { - for (var i = 0; i < obscuringElements.length; i++) { - if (obscuringElements[i] !== targetElement && obscuringElements[i] === bgNode) { - return true; - } - } - } - return false; - } dom.isOpaque = function(node) { var style = window.getComputedStyle(node); - return color.elementHasImage(node, style) || color.getOwnBackgroundColor(style).alpha === 1; + return elmHasImage(node, style) || getBgColor(node, style).alpha === 1; }; color.getForegroundColor = function(node, noScroll) { var nodeStyle = window.getComputedStyle(node); @@ -14968,15 +8593,6 @@ } return color.flattenColors(fgColor, bgColor); }; - color.getOwnBackgroundColor = function getOwnBackgroundColor(elmStyle) { - var bgColor = new color.Color(); - bgColor.parseRgbString(elmStyle.getPropertyValue('background-color')); - if (bgColor.alpha !== 0) { - var opacity = elmStyle.getPropertyValue('opacity'); - bgColor.alpha = bgColor.alpha * opacity; - } - return bgColor; - }; color.incompleteData = function() { var data = {}; return { @@ -15013,9 +8629,10 @@ } return finalElements; }; - dom.findElmsInContext = function(_ref27) { - var context = _ref27.context, value = _ref27.value, attr = _ref27.attr, _ref27$elm = _ref27.elm, elm = _ref27$elm === void 0 ? '' : _ref27$elm; - var root; + dom.findElmsInContext = function(_ref8) { + var context = _ref8.context, value = _ref8.value, attr = _ref8.attr, _ref8$elm = _ref8.elm, elm = _ref8$elm === undefined ? '' : _ref8$elm; + var root = void 0; + context = context.actualNode || context; var escapedValue = axe.utils.escapeSelector(value); if (context.nodeType === 9 || context.nodeType === 11) { root = context; @@ -15025,30 +8642,22 @@ return Array.from(root.querySelectorAll(elm + '[' + attr + '=' + escapedValue + ']')); }; dom.findUp = function(element, target) { - return dom.findUpVirtual(axe.utils.getNodeFromTree(element), target); - }; - dom.findUpVirtual = function(element, target) { - var parent; - parent = element.actualNode; - if (!element.shadowId && typeof element.actualNode.closest === 'function') { - var match = element.actualNode.closest(target); - if (match) { - return match; - } - return null; - } + var doc = void 0, matches = void 0, parent = element; do { parent = parent.assignedSlot ? parent.assignedSlot : parent.parentNode; if (parent && parent.nodeType === 11) { + matches = null; parent = parent.host; } - } while (parent && !axe.utils.matchesSelector(parent, target) && parent !== document.documentElement); - if (!parent) { - return null; - } - if (!axe.utils.matchesSelector(parent, target)) { - return null; - } + if (!matches) { + doc = axe.commons.dom.getRootNode(parent); + matches = doc.querySelectorAll(target); + matches = axe.utils.toArray(matches); + if (doc === document && !matches.length) { + return null; + } + } + } while (parent && !matches.includes(parent)); return parent; }; dom.getComposedParent = function getComposedParent(element) { @@ -15066,21 +8675,16 @@ }; dom.getElementByReference = function(node, attr) { var fragment = node.getAttribute(attr); - if (!fragment) { - return null; - } - if (fragment.charAt(0) === '#') { - fragment = decodeURIComponent(fragment.substring(1)); - } else if (fragment.substr(0, 2) === '/#') { - fragment = decodeURIComponent(fragment.substring(2)); - } - var candidate = document.getElementById(fragment); - if (candidate) { - return candidate; - } - candidate = document.getElementsByName(fragment); - if (candidate.length) { - return candidate[0]; + if (fragment && fragment.charAt(0) === '#') { + fragment = fragment.substring(1); + var candidate = document.getElementById(fragment); + if (candidate) { + return candidate; + } + candidate = document.getElementsByName(fragment); + if (candidate.length) { + return candidate[0]; + } } return null; }; @@ -15096,7 +8700,13 @@ height: coords.bottom - coords.top }; }; - dom.getRootNode = axe.utils.getRootNode; + dom.getRootNode = function(node) { + var doc = node.getRootNode && node.getRootNode() || document; + if (doc === node) { + doc = document; + } + return doc; + }; dom.getScrollOffset = function(element) { 'use strict'; if (!element.nodeType && element.document) { @@ -15114,16 +8724,6 @@ top: element.scrollTop }; }; - dom.getTabbableElements = function getTabbableElements(virtualNode) { - var nodeAndDescendents = axe.utils.querySelectorAll(virtualNode, '*'); - var tabbableElements = nodeAndDescendents.filter(function(vNode) { - var isFocusable = vNode.isFocusable; - var tabIndex = vNode.actualNode.getAttribute('tabindex'); - tabIndex = tabIndex && !isNaN(parseInt(tabIndex, 10)) ? parseInt(tabIndex) : null; - return tabIndex ? isFocusable && tabIndex >= 0 : isFocusable; - }); - return tabbableElements; - }; dom.getViewportSize = function(win) { 'use strict'; var body, doc = win.document, docElement = doc.documentElement; @@ -15148,21 +8748,20 @@ var hiddenTextElms = [ 'HEAD', 'TITLE', 'TEMPLATE', 'SCRIPT', 'STYLE', 'IFRAME', 'OBJECT', 'VIDEO', 'AUDIO', 'NOSCRIPT' ]; function hasChildTextNodes(elm) { if (!hiddenTextElms.includes(elm.actualNode.nodeName.toUpperCase())) { - return elm.children.some(function(_ref28) { - var actualNode = _ref28.actualNode; + return elm.children.some(function(_ref9) { + var actualNode = _ref9.actualNode; return actualNode.nodeType === 3 && actualNode.nodeValue.trim(); }); } } - dom.hasContentVirtual = function(elm, noRecursion, ignoreAria) { - return hasChildTextNodes(elm) || dom.isVisualContent(elm.actualNode) || !!ignoreAria || !!aria.labelVirtual(elm) || !noRecursion && elm.children.some(function(child) { - return child.actualNode.nodeType === 1 && dom.hasContentVirtual(child); + dom.hasContent = function hasContent(elm, noRecursion) { + if (!elm.actualNode) { + elm = axe.utils.getNodeFromTree(axe._tree[0], elm); + } + return hasChildTextNodes(elm) || dom.isVisualContent(elm.actualNode) || !!aria.label(elm) || !noRecursion && elm.children.some(function(child) { + return child.actualNode.nodeType === 1 && dom.hasContent(child); }); }; - dom.hasContent = function hasContent(elm, noRecursion, ignoreAria) { - elm = axe.utils.getNodeFromTree(elm); - return dom.hasContentVirtual(elm, noRecursion, ignoreAria); - }; dom.idrefs = function(node, attr) { 'use strict'; var index, length, doc = dom.getRootNode(node), result = [], idrefs = node.getAttribute(attr); @@ -15174,25 +8773,9 @@ } return result; }; - function focusDisabled(el) { - return el.disabled || dom.isHiddenWithCSS(el) && el.nodeName.toUpperCase() !== 'AREA'; - } dom.isFocusable = function(el) { 'use strict'; - if (focusDisabled(el)) { - return false; - } else if (dom.isNativelyFocusable(el)) { - return true; - } - var tabindex = el.getAttribute('tabindex'); - if (tabindex && !isNaN(parseInt(tabindex, 10))) { - return true; - } - return false; - }; - dom.isNativelyFocusable = function(el) { - 'use strict'; - if (!el || focusDisabled(el)) { + if (!el || el.disabled || !dom.isVisible(el) && el.nodeName.toUpperCase() !== 'AREA') { return false; } switch (el.nodeName.toUpperCase()) { @@ -15212,41 +8795,10 @@ case 'BUTTON': return true; } - return false; - }; - dom.insertedIntoFocusOrder = function(el) { - return el.tabIndex > -1 && dom.isFocusable(el) && !dom.isNativelyFocusable(el); - }; - dom.isHiddenWithCSS = function isHiddenWithCSS(el, descendentVisibilityValue) { - if (el.nodeType === 9) { - return false; - } - if (el.nodeType === 11) { - el = el.host; - } - if ([ 'STYLE', 'SCRIPT' ].includes(el.nodeName.toUpperCase())) { - return false; - } - var style = window.getComputedStyle(el, null); - if (!style) { - throw new Error('Style does not exist for the given element.'); - } - var displayValue = style.getPropertyValue('display'); - if (displayValue === 'none') { + var tabindex = el.getAttribute('tabindex'); + if (tabindex && !isNaN(parseInt(tabindex, 10))) { return true; } - var HIDDEN_VISIBILITY_VALUES = [ 'hidden', 'collapse' ]; - var visibilityValue = style.getPropertyValue('visibility'); - if (HIDDEN_VISIBILITY_VALUES.includes(visibilityValue) && !descendentVisibilityValue) { - return true; - } - if (HIDDEN_VISIBILITY_VALUES.includes(visibilityValue) && descendentVisibilityValue && HIDDEN_VISIBILITY_VALUES.includes(descendentVisibilityValue)) { - return true; - } - var parent = dom.getComposedParent(el); - if (parent && !HIDDEN_VISIBILITY_VALUES.includes(visibilityValue)) { - return dom.isHiddenWithCSS(parent, visibilityValue); - } return false; }; dom.isHTML5 = function(doc) { @@ -15273,7 +8825,7 @@ while (parentBlock && !isBlock(parentBlock)) { parentBlock = dom.getComposedParent(parentBlock); } - return axe.utils.getNodeFromTree(parentBlock); + return axe.utils.getNodeFromTree(axe._tree[0], parentBlock); } dom.isInTextBlock = function isInTextBlock(node) { if (isBlock(node)) { @@ -15301,7 +8853,7 @@ } else { inBrBlock = 2; } - } else if (currNode.style.display === 'none' || currNode.style.overflow === 'hidden' || ![ '', null, 'none' ].includes(currNode.style['float']) || ![ '', null, 'relative' ].includes(currNode.style.position)) { + } else if (currNode.style.display === 'none' || currNode.style.overflow === 'hidden' || ![ '', null, 'none' ].includes(currNode.style.float) || ![ '', null, 'relative' ].includes(currNode.style.position)) { return false; } else if (nodeName === 'A' && currNode.href || (currNode.getAttribute('role') || '').toLowerCase() === 'link') { if (currNode === node) { @@ -15315,29 +8867,26 @@ linkText = axe.commons.text.sanitize(linkText); return parentText.length > linkText.length; }; - dom.isNode = function(element) { + dom.isNode = function(candidate) { 'use strict'; - return element instanceof Node; + return candidate instanceof Node; }; - function noParentScrolled(element, offset) { - element = dom.getComposedParent(element); - while (element && element.nodeName.toLowerCase() !== 'html') { - if (element.scrollTop) { - offset += element.scrollTop; - if (offset >= 0) { - return false; - } - } - element = dom.getComposedParent(element); - } - return true; - } dom.isOffscreen = function(element) { - var leftBoundary; - var docElement = document.documentElement; - var styl = window.getComputedStyle(element); - var dir = window.getComputedStyle(document.body || docElement).getPropertyValue('direction'); - var coords = dom.getElementCoordinates(element); + 'use strict'; + var noParentScrolled = function noParentScrolled(element, offset) { + element = element.parentNode; + while (element.nodeName.toLowerCase() !== 'html') { + if (element.scrollTop) { + offset += element.scrollTop; + if (offset >= 0) { + return false; + } + } + element = element.parentNode; + } + return true; + }; + var leftBoundary, docElement = document.documentElement, styl = window.getComputedStyle(element), dir = window.getComputedStyle(document.body || docElement).getPropertyValue('direction'), coords = dom.getElementCoordinates(element); if (coords.bottom < 0 && (noParentScrolled(element, coords.bottom) || styl.position === 'absolute')) { return true; } @@ -15356,23 +8905,6 @@ } return false; }; - var isInternalLinkRegex = /^\/?#[^/!]/; - dom.isSkipLink = function(element) { - if (!isInternalLinkRegex.test(element.getAttribute('href'))) { - return false; - } - var firstPageLink; - if (typeof axe._cache.get('firstPageLink') !== 'undefined') { - firstPageLink = axe._cache.get('firstPageLink'); - } else { - firstPageLink = axe.utils.querySelectorAll(axe._tree, 'a:not([href^="#"]):not([href^="/#"]):not([href^="javascript"])')[0]; - axe._cache.set('firstPageLink', firstPageLink || null); - } - if (!firstPageLink) { - return true; - } - return element.compareDocumentPosition(firstPageLink.actualNode) === element.DOCUMENT_POSITION_FOLLOWING; - }; function isClipped(clip) { 'use strict'; var matches = clip.match(/rect\s*\(([0-9]+)px,?\s*([0-9]+)px,?\s*([0-9]+)px,?\s*([0-9]+)px\s*\)/); @@ -15383,42 +8915,34 @@ } dom.isVisible = function(el, screenReader, recursed) { 'use strict'; - var node = axe.utils.getNodeFromTree(el); - var cacheName = '_isVisible' + (screenReader ? 'ScreenReader' : ''); + var style, nodeName, parent; if (el.nodeType === 9) { return true; } if (el.nodeType === 11) { el = el.host; } - if (node && typeof node[cacheName] !== 'undefined') { - return node[cacheName]; - } - var style = window.getComputedStyle(el, null); + style = window.getComputedStyle(el, null); if (style === null) { return false; } - var nodeName = el.nodeName.toUpperCase(); - if (style.getPropertyValue('display') === 'none' || [ 'STYLE', 'SCRIPT', 'NOSCRIPT', 'TEMPLATE' ].includes(nodeName) || !screenReader && isClipped(style.getPropertyValue('clip')) || !recursed && (style.getPropertyValue('visibility') === 'hidden' || !screenReader && dom.isOffscreen(el)) || screenReader && el.getAttribute('aria-hidden') === 'true') { + nodeName = el.nodeName.toUpperCase(); + if (style.getPropertyValue('display') === 'none' || nodeName.toUpperCase() === 'STYLE' || nodeName.toUpperCase() === 'SCRIPT' || !screenReader && isClipped(style.getPropertyValue('clip')) || !recursed && (style.getPropertyValue('visibility') === 'hidden' || !screenReader && dom.isOffscreen(el)) || screenReader && el.getAttribute('aria-hidden') === 'true') { return false; } - var parent = el.assignedSlot ? el.assignedSlot : el.parentNode; - var isVisible = false; + parent = el.assignedSlot ? el.assignedSlot : el.parentNode; if (parent) { - isVisible = dom.isVisible(parent, screenReader, true); + return dom.isVisible(parent, screenReader, true); } - if (node) { - node[cacheName] = isVisible; - } - return isVisible; + return false; }; var visualRoles = [ 'checkbox', 'img', 'radio', 'range', 'slider', 'spinbutton', 'textbox' ]; - dom.isVisualContent = function(element) { - var role = element.getAttribute('role'); + dom.isVisualContent = function(candidate) { + var role = candidate.getAttribute('role'); if (role) { return visualRoles.indexOf(role) !== -1; } - switch (element.nodeName.toUpperCase()) { + switch (candidate.tagName.toUpperCase()) { case 'IMG': case 'IFRAME': case 'OBJECT': @@ -15436,33 +8960,12 @@ return true; case 'INPUT': - return element.type !== 'hidden'; + return candidate.type !== 'hidden'; default: return false; } }; - dom.shadowElementsFromPoint = function(nodeX, nodeY) { - var root = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : document; - var i = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0; - if (i > 999) { - throw new Error('Infinite loop detected'); - } - return Array.from(root.elementsFromPoint(nodeX, nodeY)).filter(function(nodes) { - return dom.getRootNode(nodes) === root; - }).reduce(function(stack, elm) { - if (axe.utils.isShadowRoot(elm)) { - var shadowStack = dom.shadowElementsFromPoint(nodeX, nodeY, elm.shadowRoot, i + 1); - stack = stack.concat(shadowStack); - if (stack.length && axe.commons.dom.visuallyContains(stack[0], elm)) { - stack.push(elm); - } - } else { - stack.push(elm); - } - return stack; - }, []); - }; dom.visuallyContains = function(node, parent) { var rectBound = node.getBoundingClientRect(); var margin = .01; @@ -15512,114 +9015,6 @@ } return true; }; - forms.isAriaCombobox = function(node) { - var role = axe.commons.aria.getRole(node, { - noImplicit: true - }); - return role === 'combobox'; - }; - forms.isAriaListbox = function(node) { - var role = axe.commons.aria.getRole(node, { - noImplicit: true - }); - return role === 'listbox'; - }; - var rangeRoles = [ 'progressbar', 'scrollbar', 'slider', 'spinbutton' ]; - forms.isAriaRange = function(node) { - var role = axe.commons.aria.getRole(node, { - noImplicit: true - }); - return rangeRoles.includes(role); - }; - forms.isAriaTextbox = function(node) { - var role = axe.commons.aria.getRole(node, { - noImplicit: true - }); - return role === 'textbox'; - }; - forms.isNativeSelect = function(node) { - var nodeName = node.nodeName.toUpperCase(); - return nodeName === 'SELECT'; - }; - var nonTextInputTypes = [ 'button', 'checkbox', 'color', 'file', 'hidden', 'image', 'password', 'radio', 'reset', 'submit' ]; - forms.isNativeTextbox = function(node) { - var nodeName = node.nodeName.toUpperCase(); - return nodeName === 'TEXTAREA' || nodeName === 'INPUT' && !nonTextInputTypes.includes(node.type); - }; - matches.attributes = function matchesAttributes(node, matcher) { - node = node.actualNode || node; - return matches.fromFunction(function(attrName) { - return node.getAttribute(attrName); - }, matcher); - }; - matches.condition = function(arg, condition) { - return !!condition(arg); - }; - var matchers = [ 'nodeName', 'attributes', 'properties', 'condition' ]; - matches.fromDefinition = function matchFromDefinition(node, definition) { - node = node.actualNode || node; - if (Array.isArray(definition)) { - return definition.some(function(definitionItem) { - return matches(node, definitionItem); - }); - } - if (typeof definition === 'string') { - return axe.utils.matchesSelector(node, definition); - } - return Object.keys(definition).every(function(matcherName) { - if (!matchers.includes(matcherName)) { - throw new Error('Unknown matcher type "'.concat(matcherName, '"')); - } - var matchMethod = matches[matcherName]; - var matcher = definition[matcherName]; - return matchMethod(node, matcher); - }); - }; - matches.fromFunction = function matchFromFunction(getValue, matcher) { - var matcherType = _typeof(matcher); - if (matcherType !== 'object' || Array.isArray(matcher) || matcher instanceof RegExp) { - throw new Error('Expect matcher to be an object'); - } - return Object.keys(matcher).every(function(propName) { - return matches.fromPrimative(getValue(propName), matcher[propName]); - }); - }; - matches.fromPrimative = function matchFromPrimative(someString, matcher) { - var matcherType = _typeof(matcher); - if (Array.isArray(matcher) && typeof someString !== 'undefined') { - return matcher.includes(someString); - } - if (matcherType === 'function') { - return !!matcher(someString); - } - if (matcher instanceof RegExp) { - return matcher.test(someString); - } - return matcher === someString; - }; - var isXHTMLGlobal; - matches.nodeName = function matchNodeName(node, matcher) { - var _ref29 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}, isXHTML = _ref29.isXHTML; - node = node.actualNode || node; - if (typeof isXHTML === 'undefined') { - if (typeof matcher === 'string') { - return axe.utils.matchesSelector(node, matcher); - } - if (typeof isXHTMLGlobal === 'undefined') { - isXHTMLGlobal = axe.utils.isXHTML(node.ownerDocument); - } - isXHTML = isXHTMLGlobal; - } - var nodeName = isXHTML ? node.nodeName : node.nodeName.toLowerCase(); - return matches.fromPrimative(nodeName, matcher); - }; - matches.properties = function matchesProperties(node, matcher) { - node = node.actualNode || node; - var out = matches.fromFunction(function(propName) { - return node[propName]; - }, matcher); - return out; - }; table.getAllCells = function(tableElm) { var rowIndex, cellIndex, rowLength, cellLength; var cells = []; @@ -15687,29 +9082,24 @@ var headerCol = tableGrid.map(function(col) { return col[pos.x]; }).reduce(function(headerCol, cell) { - return headerCol && cell && cell.nodeName.toUpperCase() === 'TH'; + return headerCol && cell.nodeName.toUpperCase() === 'TH'; }, true); if (headerCol) { return 'row'; } return 'auto'; }; - table.isColumnHeader = function(element) { - return [ 'col', 'auto' ].indexOf(table.getScope(element)) !== -1; + table.isColumnHeader = function(node) { + return [ 'col', 'auto' ].indexOf(table.getScope(node)) !== -1; }; table.isDataCell = function(cell) { if (!cell.children.length && !cell.textContent.trim()) { return false; } - var role = cell.getAttribute('role'); - if (axe.commons.aria.isValidRole(role)) { - return [ 'cell', 'gridcell' ].includes(role); - } else { - return cell.nodeName.toUpperCase() === 'TD'; - } + return cell.nodeName.toUpperCase() === 'TD'; }; table.isDataTable = function(node) { - var role = (node.getAttribute('role') || '').toLowerCase(); + var role = node.getAttribute('role'); if ((role === 'presentation' || role === 'none') && !dom.isFocusable(node)) { return false; } @@ -15753,7 +9143,7 @@ if (cell.getAttribute('scope') || cell.getAttribute('headers') || cell.getAttribute('abbr')) { return true; } - if ([ 'columnheader', 'rowheader' ].includes((cell.getAttribute('role') || '').toLowerCase())) { + if ([ 'columnheader', 'rowheader' ].indexOf(cell.getAttribute('role')) !== -1) { return true; } if (cell.children.length === 1 && cell.children[0].nodeName.toUpperCase() === 'ABBR') { @@ -15812,12 +9202,12 @@ } if (cell.getAttribute('id')) { var id = axe.utils.escapeSelector(cell.getAttribute('id')); - return !!document.querySelector('[headers~="'.concat(id, '"]')); + return !!document.querySelector('[headers~="' + id + '"]'); } return false; }; - table.isRowHeader = function(cell) { - return [ 'row', 'auto' ].includes(table.getScope(cell)); + table.isRowHeader = function(node) { + return [ 'row', 'auto' ].indexOf(table.getScope(node)) !== -1; }; table.toGrid = function(node) { var table = []; @@ -15908,514 +9298,279 @@ }, tableGrid, callback); }; })(table); - text.accessibleText = function accessibleText(element, context) { - var virtualNode = axe.utils.getNodeFromTree(element); - return text.accessibleTextVirtual(virtualNode, context); + var defaultButtonValues = { + submit: 'Submit', + reset: 'Reset' }; - text.accessibleTextVirtual = function accessibleTextVirtual(virtualNode) { - var context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var actualNode = virtualNode.actualNode; - context = prepareContext(virtualNode, context); - if (shouldIgnoreHidden(virtualNode, context)) { - return ''; + var inputTypes = [ 'text', 'search', 'tel', 'url', 'email', 'date', 'time', 'number', 'range', 'color' ]; + var phrasingElements = [ 'A', 'EM', 'STRONG', 'SMALL', 'MARK', 'ABBR', 'DFN', 'I', 'B', 'S', 'U', 'CODE', 'VAR', 'SAMP', 'KBD', 'SUP', 'SUB', 'Q', 'CITE', 'SPAN', 'BDO', 'BDI', 'BR', 'WBR', 'INS', 'DEL', 'IMG', 'EMBED', 'OBJECT', 'IFRAME', 'MAP', 'AREA', 'SCRIPT', 'NOSCRIPT', 'RUBY', 'VIDEO', 'AUDIO', 'INPUT', 'TEXTAREA', 'SELECT', 'BUTTON', 'LABEL', 'OUTPUT', 'DATALIST', 'KEYGEN', 'PROGRESS', 'COMMAND', 'CANVAS', 'TIME', 'METER' ]; + function findLabel(_ref10) { + var actualNode = _ref10.actualNode; + var label = void 0; + if (actualNode.id) { + label = dom.findElmsInContext({ + elm: 'label', + attr: 'for', + value: actualNode.id, + context: actualNode + })[0]; + } else { + label = dom.findUp(actualNode, 'label'); } - var computationSteps = [ aria.arialabelledbyText, aria.arialabelText, text.nativeTextAlternative, text.formControlValue, text.subtreeText, textNodeContent, text.titleText ]; - var accName = computationSteps.reduce(function(accName, step) { - if (context.startNode === virtualNode) { - accName = text.sanitize(accName); + return axe.utils.getNodeFromTree(axe._tree[0], label); + } + function isButton(_ref11) { + var actualNode = _ref11.actualNode; + return [ 'button', 'reset', 'submit' ].includes(actualNode.type.toLowerCase()); + } + function isInput(_ref12) { + var actualNode = _ref12.actualNode; + var nodeName = actualNode.nodeName.toUpperCase(); + return nodeName === 'TEXTAREA' || nodeName === 'SELECT' || nodeName === 'INPUT' && actualNode.type.toLowerCase() !== 'hidden'; + } + function shouldCheckSubtree(_ref13) { + var actualNode = _ref13.actualNode; + return [ 'BUTTON', 'SUMMARY', 'A' ].includes(actualNode.nodeName.toUpperCase()); + } + function shouldNeverCheckSubtree(_ref14) { + var actualNode = _ref14.actualNode; + return [ 'TABLE', 'FIGURE' ].includes(actualNode.nodeName.toUpperCase()); + } + function formValueText(_ref15) { + var actualNode = _ref15.actualNode; + var nodeName = actualNode.nodeName.toUpperCase(); + if (nodeName === 'INPUT') { + if (!actualNode.hasAttribute('type') || inputTypes.includes(actualNode.type.toLowerCase())) { + return actualNode.value; } - if (accName !== '') { - return accName; + return ''; + } + if (nodeName === 'SELECT') { + var opts = actualNode.options; + if (opts && opts.length) { + var returnText = ''; + for (var i = 0; i < opts.length; i++) { + if (opts[i].selected) { + returnText += ' ' + opts[i].text; + } + } + return text.sanitize(returnText); } - return step(virtualNode, context); - }, ''); - if (context.debug) { - axe.log(accName || '{empty-value}', actualNode, context); - } - return accName; - }; - function textNodeContent(_ref30) { - var actualNode = _ref30.actualNode; - if (actualNode.nodeType !== 3) { return ''; } - return actualNode.textContent; - } - function shouldIgnoreHidden(_ref31, context) { - var actualNode = _ref31.actualNode; - if (actualNode.nodeType !== 1 || context.includeHidden) { - return false; - } - return !dom.isVisible(actualNode, true); - } - function prepareContext(virtualNode, context) { - var actualNode = virtualNode.actualNode; - if (!context.startNode) { - context = _extends({ - startNode: virtualNode - }, context); - } - if (actualNode.nodeType === 1 && context.inLabelledByContext && context.includeHidden === undefined) { - context = _extends({ - includeHidden: !dom.isVisible(actualNode, true) - }, context); - } - return context; - } - text.accessibleTextVirtual.alreadyProcessed = function alreadyProcessed(virtualnode, context) { - context.processed = context.processed || []; - if (context.processed.includes(virtualnode)) { - return true; - } - context.processed.push(virtualnode); - return false; - }; - var controlValueRoles = [ 'textbox', 'progressbar', 'scrollbar', 'slider', 'spinbutton', 'combobox', 'listbox' ]; - text.formControlValueMethods = { - nativeTextboxValue: nativeTextboxValue, - nativeSelectValue: nativeSelectValue, - ariaTextboxValue: ariaTextboxValue, - ariaListboxValue: ariaListboxValue, - ariaComboboxValue: ariaComboboxValue, - ariaRangeValue: ariaRangeValue - }; - text.formControlValue = function formControlValue(virtualNode) { - var context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var actualNode = virtualNode.actualNode; - var unsupported = text.unsupported.accessibleNameFromFieldValue || []; - var role = aria.getRole(actualNode); - if (context.startNode === virtualNode || !controlValueRoles.includes(role) || unsupported.includes(role)) { - return ''; - } - var valueMethods = Object.keys(text.formControlValueMethods).map(function(name) { - return text.formControlValueMethods[name]; - }); - var valueString = valueMethods.reduce(function(accName, step) { - return accName || step(virtualNode, context); - }, ''); - if (context.debug) { - axe.log(valueString || '{empty-value}', actualNode, context); - } - return valueString; - }; - function nativeTextboxValue(node) { - node = node.actualNode || node; - if (axe.commons.forms.isNativeTextbox(node)) { - return node.value || ''; + if (nodeName === 'TEXTAREA' && actualNode.value) { + return actualNode.value; } return ''; } - function nativeSelectValue(node) { - node = node.actualNode || node; - if (!axe.commons.forms.isNativeSelect(node)) { - return ''; + function checkDescendant(_ref16, nodeName) { + var actualNode = _ref16.actualNode; + var candidate = actualNode.querySelector(nodeName.toLowerCase()); + if (candidate) { + return text.accessibleText(candidate); } - return Array.from(node.options).filter(function(option) { - return option.selected; - }).map(function(option) { - return option.text; - }).join(' ') || ''; + return ''; } - function ariaTextboxValue(virtualNode) { - var actualNode = virtualNode.actualNode; - if (!axe.commons.forms.isAriaTextbox(actualNode)) { - return ''; + function isEmbeddedControl(elm) { + if (!elm) { + return false; } - if (!dom.isHiddenWithCSS(actualNode)) { - return text.visibleVirtual(virtualNode, true); - } else { - return actualNode.textContent; - } - } - function ariaListboxValue(virtualNode, context) { - var actualNode = virtualNode.actualNode; - if (!axe.commons.forms.isAriaListbox(actualNode)) { - return ''; - } - var selected = aria.getOwnedVirtual(virtualNode).filter(function(owned) { - return aria.getRole(owned) === 'option' && owned.actualNode.getAttribute('aria-selected') === 'true'; - }); - if (selected.length === 0) { - return ''; - } - return axe.commons.text.accessibleTextVirtual(selected[0], context); - } - function ariaComboboxValue(virtualNode, context) { - var actualNode = virtualNode.actualNode; - var listbox; - if (!axe.commons.forms.isAriaCombobox(actualNode)) { - return ''; - } - listbox = aria.getOwnedVirtual(virtualNode).filter(function(elm) { - return aria.getRole(elm) === 'listbox'; - })[0]; - return listbox ? text.formControlValueMethods.ariaListboxValue(listbox, context) : ''; - } - function ariaRangeValue(node) { - node = node.actualNode || node; - if (!axe.commons.forms.isAriaRange(node) || !node.hasAttribute('aria-valuenow')) { - return ''; - } - var valueNow = +node.getAttribute('aria-valuenow'); - return !isNaN(valueNow) ? String(valueNow) : '0'; - } - text.isHumanInterpretable = function(str) { - if (!str.length) { - return 0; - } - var alphaNumericIconMap = [ 'x', 'i' ]; - if (alphaNumericIconMap.includes(str)) { - return 0; - } - var noUnicodeStr = text.removeUnicode(str, { - emoji: true, - nonBmp: true, - punctuations: true - }); - if (!text.sanitize(noUnicodeStr)) { - return 0; - } - return 1; - }; - var autocomplete = { - stateTerms: [ 'on', 'off' ], - standaloneTerms: [ 'name', 'honorific-prefix', 'given-name', 'additional-name', 'family-name', 'honorific-suffix', 'nickname', 'username', 'new-password', 'current-password', 'organization-title', 'organization', 'street-address', 'address-line1', 'address-line2', 'address-line3', 'address-level4', 'address-level3', 'address-level2', 'address-level1', 'country', 'country-name', 'postal-code', 'cc-name', 'cc-given-name', 'cc-additional-name', 'cc-family-name', 'cc-number', 'cc-exp', 'cc-exp-month', 'cc-exp-year', 'cc-csc', 'cc-type', 'transaction-currency', 'transaction-amount', 'language', 'bday', 'bday-day', 'bday-month', 'bday-year', 'sex', 'url', 'photo' ], - qualifiers: [ 'home', 'work', 'mobile', 'fax', 'pager' ], - qualifiedTerms: [ 'tel', 'tel-country-code', 'tel-national', 'tel-area-code', 'tel-local', 'tel-local-prefix', 'tel-local-suffix', 'tel-extension', 'email', 'impp' ], - locations: [ 'billing', 'shipping' ] - }; - text.autocomplete = autocomplete; - text.isValidAutocomplete = function isValidAutocomplete(autocomplete) { - var _ref32 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, _ref32$looseTyped = _ref32.looseTyped, looseTyped = _ref32$looseTyped === void 0 ? false : _ref32$looseTyped, _ref32$stateTerms = _ref32.stateTerms, stateTerms = _ref32$stateTerms === void 0 ? [] : _ref32$stateTerms, _ref32$locations = _ref32.locations, locations = _ref32$locations === void 0 ? [] : _ref32$locations, _ref32$qualifiers = _ref32.qualifiers, qualifiers = _ref32$qualifiers === void 0 ? [] : _ref32$qualifiers, _ref32$standaloneTerm = _ref32.standaloneTerms, standaloneTerms = _ref32$standaloneTerm === void 0 ? [] : _ref32$standaloneTerm, _ref32$qualifiedTerms = _ref32.qualifiedTerms, qualifiedTerms = _ref32$qualifiedTerms === void 0 ? [] : _ref32$qualifiedTerms; - autocomplete = autocomplete.toLowerCase().trim(); - stateTerms = stateTerms.concat(text.autocomplete.stateTerms); - if (stateTerms.includes(autocomplete) || autocomplete === '') { + var actualNode = elm.actualNode; + switch (actualNode.nodeName.toUpperCase()) { + case 'SELECT': + case 'TEXTAREA': return true; + + case 'INPUT': + return !actualNode.hasAttribute('type') || inputTypes.includes(actualNode.getAttribute('type').toLowerCase()); + + default: + return false; } - qualifiers = qualifiers.concat(text.autocomplete.qualifiers); - locations = locations.concat(text.autocomplete.locations); - standaloneTerms = standaloneTerms.concat(text.autocomplete.standaloneTerms); - qualifiedTerms = qualifiedTerms.concat(text.autocomplete.qualifiedTerms); - var autocompleteTerms = autocomplete.split(/\s+/g); - if (!looseTyped) { - if (autocompleteTerms[0].length > 8 && autocompleteTerms[0].substr(0, 8) === 'section-') { - autocompleteTerms.shift(); - } - if (locations.includes(autocompleteTerms[0])) { - autocompleteTerms.shift(); - } - if (qualifiers.includes(autocompleteTerms[0])) { - autocompleteTerms.shift(); - standaloneTerms = []; - } - if (autocompleteTerms.length !== 1) { - return false; - } + } + function shouldCheckAlt(_ref17) { + var actualNode = _ref17.actualNode; + var nodeName = actualNode.nodeName.toUpperCase(); + return [ 'IMG', 'APPLET', 'AREA' ].includes(nodeName) || nodeName === 'INPUT' && actualNode.type.toLowerCase() === 'image'; + } + function nonEmptyText(t) { + return !!text.sanitize(t); + } + text.accessibleText = function(element, inLabelledByContext) { + var accessibleNameComputation = void 0; + var encounteredNodes = []; + if (element instanceof Node) { + element = axe.utils.getNodeFromTree(axe._tree[0], element); } - var purposeTerm = autocompleteTerms[autocompleteTerms.length - 1]; - return standaloneTerms.includes(purposeTerm) || qualifiedTerms.includes(purposeTerm); - }; - text.labelText = function labelText(virtualNode) { - var context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var alreadyProcessed = text.accessibleTextVirtual.alreadyProcessed; - if (context.inControlContext || context.inLabelledByContext || alreadyProcessed(virtualNode, context)) { + function getInnerText(element, inLabelledByContext, inControlContext) { + return element.children.reduce(function(returnText, child) { + var actualNode = child.actualNode; + if (actualNode.nodeType === 3) { + returnText += actualNode.nodeValue; + } else if (actualNode.nodeType === 1) { + if (!phrasingElements.includes(actualNode.nodeName.toUpperCase())) { + returnText += ' '; + } + returnText += accessibleNameComputation(child, inLabelledByContext, inControlContext); + } + return returnText; + }, ''); + } + function checkNative(element, inLabelledByContext, inControlContext) { + var returnText = ''; + var actualNode = element.actualNode; + var nodeName = actualNode.nodeName.toUpperCase(); + if (shouldCheckSubtree(element)) { + returnText = getInnerText(element, false, false) || ''; + if (nonEmptyText(returnText)) { + return returnText; + } + } + if (nodeName === 'FIGURE') { + returnText = checkDescendant(element, 'figcaption'); + if (nonEmptyText(returnText)) { + return returnText; + } + } + if (nodeName === 'TABLE') { + returnText = checkDescendant(element, 'caption'); + if (nonEmptyText(returnText)) { + return returnText; + } + returnText = actualNode.getAttribute('title') || actualNode.getAttribute('summary') || ''; + if (nonEmptyText(returnText)) { + return returnText; + } + } + if (shouldCheckAlt(element)) { + return actualNode.getAttribute('alt') || ''; + } + if (isInput(element) && !inControlContext) { + if (isButton(element)) { + return actualNode.value || actualNode.title || defaultButtonValues[actualNode.type] || ''; + } + var labelElement = findLabel(element); + if (labelElement) { + return accessibleNameComputation(labelElement, inLabelledByContext, true); + } + } return ''; } - if (!context.startNode) { - context.startNode = virtualNode; + function checkARIA(element, inLabelledByContext, inControlContext) { + var returnText = ''; + var actualNode = element.actualNode; + if (!inLabelledByContext && actualNode.hasAttribute('aria-labelledby')) { + returnText = text.sanitize(dom.idrefs(actualNode, 'aria-labelledby').map(function(label) { + if (label !== null) { + if (actualNode === label) { + encounteredNodes.pop(); + } + var vLabel = axe.utils.getNodeFromTree(axe._tree[0], label); + return accessibleNameComputation(vLabel, true, actualNode !== label); + } else { + return ''; + } + }).join(' ')); + } + if (!returnText && !(inControlContext && isEmbeddedControl(element)) && actualNode.hasAttribute('aria-label')) { + return text.sanitize(actualNode.getAttribute('aria-label')); + } + return returnText; } - var labelContext = _extends({ - inControlContext: true - }, context); - var explicitLabels = getExplicitLabels(virtualNode); - var implicitLabel = dom.findUpVirtual(virtualNode, 'label'); - var labels; - if (implicitLabel) { - labels = [].concat(_toConsumableArray(explicitLabels), [ implicitLabel ]); - labels.sort(axe.utils.nodeSorter); - } else { - labels = explicitLabels; - } - return labels.map(function(label) { - return text.accessibleText(label, labelContext); - }).filter(function(text) { - return text !== ''; - }).join(' '); + accessibleNameComputation = function accessibleNameComputation(element, inLabelledByContext, inControlContext) { + var returnText = void 0; + if (!element || encounteredNodes.includes(element)) { + return ''; + } else if (element !== null && element.actualNode instanceof Node !== true) { + throw new Error('Invalid argument. Virtual Node must be provided'); + } else if (!inLabelledByContext && !dom.isVisible(element.actualNode, true)) { + return ''; + } + encounteredNodes.push(element); + var role = element.actualNode.getAttribute('role'); + returnText = checkARIA(element, inLabelledByContext, inControlContext); + if (nonEmptyText(returnText)) { + return returnText; + } + returnText = checkNative(element, inLabelledByContext, inControlContext); + if (nonEmptyText(returnText)) { + return returnText; + } + if (inControlContext) { + returnText = formValueText(element); + if (nonEmptyText(returnText)) { + return returnText; + } + } + if (!shouldNeverCheckSubtree(element) && (!role || aria.getRolesWithNameFromContents().indexOf(role) !== -1)) { + returnText = getInnerText(element, inLabelledByContext, inControlContext); + if (nonEmptyText(returnText)) { + return returnText; + } + } + if (element.actualNode.hasAttribute('title')) { + return element.actualNode.getAttribute('title'); + } + return ''; + }; + return text.sanitize(accessibleNameComputation(element, inLabelledByContext)); }; - function getExplicitLabels(_ref33) { - var actualNode = _ref33.actualNode; - if (!actualNode.id) { - return []; - } - return dom.findElmsInContext({ - elm: 'label', - attr: 'for', - value: actualNode.id, - context: actualNode - }); - } - text.labelVirtual = function(node) { + text.label = function(node) { var ref, candidate, doc; - candidate = aria.labelVirtual(node); + candidate = aria.label(node); if (candidate) { return candidate; } if (node.actualNode.id) { - var id = axe.utils.escapeSelector(node.actualNode.getAttribute('id')); + var id = axe.commons.utils.escapeSelector(node.actualNode.getAttribute('id')); doc = axe.commons.dom.getRootNode(node.actualNode); ref = doc.querySelector('label[for="' + id + '"]'); + ref = axe.utils.getNodeFromTree(axe._tree[0], ref); candidate = ref && text.visible(ref, true); if (candidate) { return candidate; } } - ref = dom.findUpVirtual(node, 'label'); + ref = dom.findUp(node.actualNode, 'label'); + ref = axe.utils.getNodeFromTree(axe._tree[0], ref); candidate = ref && text.visible(ref, true); if (candidate) { return candidate; } return null; }; - text.label = function(node) { - node = axe.utils.getNodeFromTree(node); - return text.labelVirtual(node); - }; - text.nativeElementType = [ { - matches: [ { - nodeName: 'textarea' - }, { - nodeName: 'input', - properties: { - type: [ 'text', 'password', 'search', 'tel', 'email', 'url' ] - } - } ], - namingMethods: 'labelText' - }, { - matches: { - nodeName: 'input', - properties: { - type: [ 'button', 'submit', 'reset' ] - } - }, - namingMethods: [ 'valueText', 'titleText', 'buttonDefaultText' ] - }, { - matches: { - nodeName: 'input', - properties: { - type: 'image' - } - }, - namingMethods: [ 'altText', 'valueText', 'labelText', 'titleText', 'buttonDefaultText' ] - }, { - matches: 'button', - namingMethods: 'subtreeText' - }, { - matches: 'fieldset', - namingMethods: 'fieldsetLegendText' - }, { - matches: 'OUTPUT', - namingMethods: 'subtreeText' - }, { - matches: [ { - nodeName: 'select' - }, { - nodeName: 'input', - properties: { - type: /^(?!text|password|search|tel|email|url|button|submit|reset)/ - } - } ], - namingMethods: 'labelText' - }, { - matches: 'summary', - namingMethods: 'subtreeText' - }, { - matches: 'figure', - namingMethods: [ 'figureText', 'titleText' ] - }, { - matches: 'img', - namingMethods: 'altText' - }, { - matches: 'table', - namingMethods: [ 'tableCaptionText', 'tableSummaryText' ] - }, { - matches: [ 'hr', 'br' ], - namingMethods: [ 'titleText', 'singleSpace' ] - } ]; - text.nativeTextAlternative = function nativeTextAlternative(virtualNode) { - var context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var actualNode = virtualNode.actualNode; - if (actualNode.nodeType !== 1 || [ 'presentation', 'none' ].includes(aria.getRole(actualNode))) { - return ''; - } - var textMethods = findTextMethods(virtualNode); - var accName = textMethods.reduce(function(accName, step) { - return accName || step(virtualNode, context); - }, ''); - if (context.debug) { - axe.log(accName || '{empty-value}', actualNode, context); - } - return accName; - }; - function findTextMethods(virtualNode) { - var nativeElementType = text.nativeElementType, nativeTextMethods = text.nativeTextMethods; - var nativeType = nativeElementType.find(function(_ref34) { - var matches = _ref34.matches; - return axe.commons.matches(virtualNode, matches); - }); - var methods = nativeType ? [].concat(nativeType.namingMethods) : []; - return methods.map(function(methodName) { - return nativeTextMethods[methodName]; - }); - } - var defaultButtonValues = { - submit: 'Submit', - image: 'Submit', - reset: 'Reset', - button: '' - }; - text.nativeTextMethods = { - valueText: function valueText(_ref35) { - var actualNode = _ref35.actualNode; - return actualNode.value || ''; - }, - buttonDefaultText: function buttonDefaultText(_ref36) { - var actualNode = _ref36.actualNode; - return defaultButtonValues[actualNode.type] || ''; - }, - tableCaptionText: descendantText.bind(null, 'caption'), - figureText: descendantText.bind(null, 'figcaption'), - fieldsetLegendText: descendantText.bind(null, 'legend'), - altText: attrText.bind(null, 'alt'), - tableSummaryText: attrText.bind(null, 'summary'), - titleText: function titleText(virtualNode, context) { - return text.titleText(virtualNode, context); - }, - subtreeText: function subtreeText(virtualNode, context) { - return text.subtreeText(virtualNode, context); - }, - labelText: function labelText(virtualNode, context) { - return text.labelText(virtualNode, context); - }, - singleSpace: function singleSpace() { - return ' '; - } - }; - function attrText(attr, _ref37) { - var actualNode = _ref37.actualNode; - return actualNode.getAttribute(attr) || ''; - } - function descendantText(nodeName, _ref38, context) { - var actualNode = _ref38.actualNode; - nodeName = nodeName.toLowerCase(); - var nodeNames = [ nodeName, actualNode.nodeName.toLowerCase() ].join(','); - var candidate = actualNode.querySelector(nodeNames); - if (!candidate || candidate.nodeName.toLowerCase() !== nodeName) { - return ''; - } - return text.accessibleText(candidate, context); - } text.sanitize = function(str) { 'use strict'; return str.replace(/\r\n/g, '\n').replace(/\u00A0/g, ' ').replace(/[\s]{2,}/g, ' ').trim(); }; - text.subtreeText = function subtreeText(virtualNode) { - var context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var alreadyProcessed = text.accessibleTextVirtual.alreadyProcessed; - context.startNode = context.startNode || virtualNode; - var strict = context.strict; - if (alreadyProcessed(virtualNode, context) || !aria.namedFromContents(virtualNode, { - strict: strict - })) { - return ''; - } - return aria.getOwnedVirtual(virtualNode).reduce(function(contentText, child) { - return appendAccessibleText(contentText, child, context); - }, ''); - }; - var phrasingElements = [ 'A', 'EM', 'STRONG', 'SMALL', 'MARK', 'ABBR', 'DFN', 'I', 'B', 'S', 'U', 'CODE', 'VAR', 'SAMP', 'KBD', 'SUP', 'SUB', 'Q', 'CITE', 'SPAN', 'BDO', 'BDI', 'WBR', 'INS', 'DEL', 'MAP', 'AREA', 'NOSCRIPT', 'RUBY', 'BUTTON', 'LABEL', 'OUTPUT', 'DATALIST', 'KEYGEN', 'PROGRESS', 'COMMAND', 'CANVAS', 'TIME', 'METER', '#TEXT' ]; - function appendAccessibleText(contentText, virtualNode, context) { - var nodeName = virtualNode.actualNode.nodeName.toUpperCase(); - var contentTextAdd = text.accessibleTextVirtual(virtualNode, context); - if (!contentTextAdd) { - return contentText; - } - if (!phrasingElements.includes(nodeName)) { - if (contentTextAdd[0] !== ' ') { - contentTextAdd += ' '; - } - if (contentText && contentText[contentText.length - 1] !== ' ') { - contentTextAdd = ' ' + contentTextAdd; - } - } - return contentText + contentTextAdd; - } - var alwaysTitleElements = [ 'button', 'iframe', 'a[href]', { - nodeName: 'input', - properties: { - type: 'button' - } - } ]; - text.titleText = function titleText(node) { - node = node.actualNode || node; - if (node.nodeType !== 1 || !node.hasAttribute('title')) { - return ''; - } - if (!axe.commons.matches(node, alwaysTitleElements) && [ 'none', 'presentation' ].includes(aria.getRole(node))) { - return ''; - } - return node.getAttribute('title'); - }; - text.hasUnicode = function hasUnicode(str, options) { - var emoji = options.emoji, nonBmp = options.nonBmp, punctuations = options.punctuations; - if (emoji) { - return axe.imports.emojiRegexText().test(str); - } - if (nonBmp) { - return getUnicodeNonBmpRegExp().test(str); - } - if (punctuations) { - return getPunctuationRegExp().test(str); - } - return false; - }; - text.removeUnicode = function removeUnicode(str, options) { - var emoji = options.emoji, nonBmp = options.nonBmp, punctuations = options.punctuations; - if (emoji) { - str = str.replace(axe.imports.emojiRegexText(), ''); - } - if (nonBmp) { - str = str.replace(getUnicodeNonBmpRegExp(), ''); - } - if (punctuations) { - str = str.replace(getPunctuationRegExp(), ''); - } - return str; - }; - function getUnicodeNonBmpRegExp() { - return new RegExp('[' + 'ᴀ-ᵿ' + 'ᶀ-ᶿ' + '᷀-᷿' + '₠-' + '⃐-' + '℀-⅏' + '⅐-' + '←-⇿' + '∀-⋿' + '⌀-⏿' + '␀-' + '⑀-' + '①-⓿' + '─-╿' + '▀-▟' + '■-◿' + '☀-⛿' + '✀-➿' + ']'); - } - function getPunctuationRegExp() { - return /[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,\-.\/:;<=>?@\[\]^_`{|}~]/g; - } - text.unsupported = { - accessibleNameFromFieldValue: [ 'combobox', 'listbox', 'progressbar' ] - }; - text.visibleVirtual = function(element, screenReader, noRecursing) { - var result = element.children.map(function(child) { + text.visible = function(element, screenReader, noRecursing) { + 'use strict'; + var index, child, nodeValue, childNodes = element.children, length = childNodes.length, result = ''; + for (index = 0; index < length; index++) { + child = childNodes[index]; if (child.actualNode.nodeType === 3) { - var nodeValue = child.actualNode.nodeValue; + nodeValue = child.actualNode.nodeValue; if (nodeValue && dom.isVisible(element.actualNode, screenReader)) { - return nodeValue; + result += nodeValue; } } else if (!noRecursing) { - return text.visibleVirtual(child, screenReader); + result += text.visible(child, screenReader); } - }).join(''); + } return text.sanitize(result); }; - text.visible = function(element, screenReader, noRecursing) { - element = axe.utils.getNodeFromTree(element); - return text.visibleVirtual(element, screenReader, noRecursing); + axe.utils.toArray = function(thing) { + 'use strict'; + return Array.prototype.slice.call(thing); + }; + axe.utils.tokenList = function(str) { + 'use strict'; + return str.trim().replace(/\s{2,}/g, ' ').split(' '); + }; + var langs = [ 'aa', 'ab', 'ae', 'af', 'ak', 'am', 'an', 'ar', 'as', 'av', 'ay', 'az', 'ba', 'be', 'bg', 'bh', 'bi', 'bm', 'bn', 'bo', 'br', 'bs', 'ca', 'ce', 'ch', 'co', 'cr', 'cs', 'cu', 'cv', 'cy', 'da', 'de', 'dv', 'dz', 'ee', 'el', 'en', 'eo', 'es', 'et', 'eu', 'fa', 'ff', 'fi', 'fj', 'fo', 'fr', 'fy', 'ga', 'gd', 'gl', 'gn', 'gu', 'gv', 'ha', 'he', 'hi', 'ho', 'hr', 'ht', 'hu', 'hy', 'hz', 'ia', 'id', 'ie', 'ig', 'ii', 'ik', 'in', 'io', 'is', 'it', 'iu', 'iw', 'ja', 'ji', 'jv', 'jw', 'ka', 'kg', 'ki', 'kj', 'kk', 'kl', 'km', 'kn', 'ko', 'kr', 'ks', 'ku', 'kv', 'kw', 'ky', 'la', 'lb', 'lg', 'li', 'ln', 'lo', 'lt', 'lu', 'lv', 'mg', 'mh', 'mi', 'mk', 'ml', 'mn', 'mo', 'mr', 'ms', 'mt', 'my', 'na', 'nb', 'nd', 'ne', 'ng', 'nl', 'nn', 'no', 'nr', 'nv', 'ny', 'oc', 'oj', 'om', 'or', 'os', 'pa', 'pi', 'pl', 'ps', 'pt', 'qu', 'rm', 'rn', 'ro', 'ru', 'rw', 'sa', 'sc', 'sd', 'se', 'sg', 'sh', 'si', 'sk', 'sl', 'sm', 'sn', 'so', 'sq', 'sr', 'ss', 'st', 'su', 'sv', 'sw', 'ta', 'te', 'tg', 'th', 'ti', 'tk', 'tl', 'tn', 'to', 'tr', 'ts', 'tt', 'tw', 'ty', 'ug', 'uk', 'ur', 'uz', 've', 'vi', 'vo', 'wa', 'wo', 'xh', 'yi', 'yo', 'za', 'zh', 'zu', 'aaa', 'aab', 'aac', 'aad', 'aae', 'aaf', 'aag', 'aah', 'aai', 'aak', 'aal', 'aam', 'aan', 'aao', 'aap', 'aaq', 'aas', 'aat', 'aau', 'aav', 'aaw', 'aax', 'aaz', 'aba', 'abb', 'abc', 'abd', 'abe', 'abf', 'abg', 'abh', 'abi', 'abj', 'abl', 'abm', 'abn', 'abo', 'abp', 'abq', 'abr', 'abs', 'abt', 'abu', 'abv', 'abw', 'abx', 'aby', 'abz', 'aca', 'acb', 'acd', 'ace', 'acf', 'ach', 'aci', 'ack', 'acl', 'acm', 'acn', 'acp', 'acq', 'acr', 'acs', 'act', 'acu', 'acv', 'acw', 'acx', 'acy', 'acz', 'ada', 'adb', 'add', 'ade', 'adf', 'adg', 'adh', 'adi', 'adj', 'adl', 'adn', 'ado', 'adp', 'adq', 'adr', 'ads', 'adt', 'adu', 'adw', 'adx', 'ady', 'adz', 'aea', 'aeb', 'aec', 'aed', 'aee', 'aek', 'ael', 'aem', 'aen', 'aeq', 'aer', 'aes', 'aeu', 'aew', 'aey', 'aez', 'afa', 'afb', 'afd', 'afe', 'afg', 'afh', 'afi', 'afk', 'afn', 'afo', 'afp', 'afs', 'aft', 'afu', 'afz', 'aga', 'agb', 'agc', 'agd', 'age', 'agf', 'agg', 'agh', 'agi', 'agj', 'agk', 'agl', 'agm', 'agn', 'ago', 'agp', 'agq', 'agr', 'ags', 'agt', 'agu', 'agv', 'agw', 'agx', 'agy', 'agz', 'aha', 'ahb', 'ahg', 'ahh', 'ahi', 'ahk', 'ahl', 'ahm', 'ahn', 'aho', 'ahp', 'ahr', 'ahs', 'aht', 'aia', 'aib', 'aic', 'aid', 'aie', 'aif', 'aig', 'aih', 'aii', 'aij', 'aik', 'ail', 'aim', 'ain', 'aio', 'aip', 'aiq', 'air', 'ais', 'ait', 'aiw', 'aix', 'aiy', 'aja', 'ajg', 'aji', 'ajn', 'ajp', 'ajt', 'aju', 'ajw', 'ajz', 'akb', 'akc', 'akd', 'ake', 'akf', 'akg', 'akh', 'aki', 'akj', 'akk', 'akl', 'akm', 'ako', 'akp', 'akq', 'akr', 'aks', 'akt', 'aku', 'akv', 'akw', 'akx', 'aky', 'akz', 'ala', 'alc', 'ald', 'ale', 'alf', 'alg', 'alh', 'ali', 'alj', 'alk', 'all', 'alm', 'aln', 'alo', 'alp', 'alq', 'alr', 'als', 'alt', 'alu', 'alv', 'alw', 'alx', 'aly', 'alz', 'ama', 'amb', 'amc', 'ame', 'amf', 'amg', 'ami', 'amj', 'amk', 'aml', 'amm', 'amn', 'amo', 'amp', 'amq', 'amr', 'ams', 'amt', 'amu', 'amv', 'amw', 'amx', 'amy', 'amz', 'ana', 'anb', 'anc', 'and', 'ane', 'anf', 'ang', 'anh', 'ani', 'anj', 'ank', 'anl', 'anm', 'ann', 'ano', 'anp', 'anq', 'anr', 'ans', 'ant', 'anu', 'anv', 'anw', 'anx', 'any', 'anz', 'aoa', 'aob', 'aoc', 'aod', 'aoe', 'aof', 'aog', 'aoh', 'aoi', 'aoj', 'aok', 'aol', 'aom', 'aon', 'aor', 'aos', 'aot', 'aou', 'aox', 'aoz', 'apa', 'apb', 'apc', 'apd', 'ape', 'apf', 'apg', 'aph', 'api', 'apj', 'apk', 'apl', 'apm', 'apn', 'apo', 'app', 'apq', 'apr', 'aps', 'apt', 'apu', 'apv', 'apw', 'apx', 'apy', 'apz', 'aqa', 'aqc', 'aqd', 'aqg', 'aql', 'aqm', 'aqn', 'aqp', 'aqr', 'aqt', 'aqz', 'arb', 'arc', 'ard', 'are', 'arh', 'ari', 'arj', 'ark', 'arl', 'arn', 'aro', 'arp', 'arq', 'arr', 'ars', 'art', 'aru', 'arv', 'arw', 'arx', 'ary', 'arz', 'asa', 'asb', 'asc', 'asd', 'ase', 'asf', 'asg', 'ash', 'asi', 'asj', 'ask', 'asl', 'asn', 'aso', 'asp', 'asq', 'asr', 'ass', 'ast', 'asu', 'asv', 'asw', 'asx', 'asy', 'asz', 'ata', 'atb', 'atc', 'atd', 'ate', 'atg', 'ath', 'ati', 'atj', 'atk', 'atl', 'atm', 'atn', 'ato', 'atp', 'atq', 'atr', 'ats', 'att', 'atu', 'atv', 'atw', 'atx', 'aty', 'atz', 'aua', 'aub', 'auc', 'aud', 'aue', 'auf', 'aug', 'auh', 'aui', 'auj', 'auk', 'aul', 'aum', 'aun', 'auo', 'aup', 'auq', 'aur', 'aus', 'aut', 'auu', 'auw', 'aux', 'auy', 'auz', 'avb', 'avd', 'avi', 'avk', 'avl', 'avm', 'avn', 'avo', 'avs', 'avt', 'avu', 'avv', 'awa', 'awb', 'awc', 'awd', 'awe', 'awg', 'awh', 'awi', 'awk', 'awm', 'awn', 'awo', 'awr', 'aws', 'awt', 'awu', 'awv', 'aww', 'awx', 'awy', 'axb', 'axe', 'axg', 'axk', 'axl', 'axm', 'axx', 'aya', 'ayb', 'ayc', 'ayd', 'aye', 'ayg', 'ayh', 'ayi', 'ayk', 'ayl', 'ayn', 'ayo', 'ayp', 'ayq', 'ayr', 'ays', 'ayt', 'ayu', 'ayx', 'ayy', 'ayz', 'aza', 'azb', 'azc', 'azd', 'azg', 'azj', 'azm', 'azn', 'azo', 'azt', 'azz', 'baa', 'bab', 'bac', 'bad', 'bae', 'baf', 'bag', 'bah', 'bai', 'baj', 'bal', 'ban', 'bao', 'bap', 'bar', 'bas', 'bat', 'bau', 'bav', 'baw', 'bax', 'bay', 'baz', 'bba', 'bbb', 'bbc', 'bbd', 'bbe', 'bbf', 'bbg', 'bbh', 'bbi', 'bbj', 'bbk', 'bbl', 'bbm', 'bbn', 'bbo', 'bbp', 'bbq', 'bbr', 'bbs', 'bbt', 'bbu', 'bbv', 'bbw', 'bbx', 'bby', 'bbz', 'bca', 'bcb', 'bcc', 'bcd', 'bce', 'bcf', 'bcg', 'bch', 'bci', 'bcj', 'bck', 'bcl', 'bcm', 'bcn', 'bco', 'bcp', 'bcq', 'bcr', 'bcs', 'bct', 'bcu', 'bcv', 'bcw', 'bcy', 'bcz', 'bda', 'bdb', 'bdc', 'bdd', 'bde', 'bdf', 'bdg', 'bdh', 'bdi', 'bdj', 'bdk', 'bdl', 'bdm', 'bdn', 'bdo', 'bdp', 'bdq', 'bdr', 'bds', 'bdt', 'bdu', 'bdv', 'bdw', 'bdx', 'bdy', 'bdz', 'bea', 'beb', 'bec', 'bed', 'bee', 'bef', 'beg', 'beh', 'bei', 'bej', 'bek', 'bem', 'beo', 'bep', 'beq', 'ber', 'bes', 'bet', 'beu', 'bev', 'bew', 'bex', 'bey', 'bez', 'bfa', 'bfb', 'bfc', 'bfd', 'bfe', 'bff', 'bfg', 'bfh', 'bfi', 'bfj', 'bfk', 'bfl', 'bfm', 'bfn', 'bfo', 'bfp', 'bfq', 'bfr', 'bfs', 'bft', 'bfu', 'bfw', 'bfx', 'bfy', 'bfz', 'bga', 'bgb', 'bgc', 'bgd', 'bge', 'bgf', 'bgg', 'bgi', 'bgj', 'bgk', 'bgl', 'bgm', 'bgn', 'bgo', 'bgp', 'bgq', 'bgr', 'bgs', 'bgt', 'bgu', 'bgv', 'bgw', 'bgx', 'bgy', 'bgz', 'bha', 'bhb', 'bhc', 'bhd', 'bhe', 'bhf', 'bhg', 'bhh', 'bhi', 'bhj', 'bhk', 'bhl', 'bhm', 'bhn', 'bho', 'bhp', 'bhq', 'bhr', 'bhs', 'bht', 'bhu', 'bhv', 'bhw', 'bhx', 'bhy', 'bhz', 'bia', 'bib', 'bic', 'bid', 'bie', 'bif', 'big', 'bij', 'bik', 'bil', 'bim', 'bin', 'bio', 'bip', 'biq', 'bir', 'bit', 'biu', 'biv', 'biw', 'bix', 'biy', 'biz', 'bja', 'bjb', 'bjc', 'bjd', 'bje', 'bjf', 'bjg', 'bjh', 'bji', 'bjj', 'bjk', 'bjl', 'bjm', 'bjn', 'bjo', 'bjp', 'bjq', 'bjr', 'bjs', 'bjt', 'bju', 'bjv', 'bjw', 'bjx', 'bjy', 'bjz', 'bka', 'bkb', 'bkc', 'bkd', 'bkf', 'bkg', 'bkh', 'bki', 'bkj', 'bkk', 'bkl', 'bkm', 'bkn', 'bko', 'bkp', 'bkq', 'bkr', 'bks', 'bkt', 'bku', 'bkv', 'bkw', 'bkx', 'bky', 'bkz', 'bla', 'blb', 'blc', 'bld', 'ble', 'blf', 'blg', 'blh', 'bli', 'blj', 'blk', 'bll', 'blm', 'bln', 'blo', 'blp', 'blq', 'blr', 'bls', 'blt', 'blv', 'blw', 'blx', 'bly', 'blz', 'bma', 'bmb', 'bmc', 'bmd', 'bme', 'bmf', 'bmg', 'bmh', 'bmi', 'bmj', 'bmk', 'bml', 'bmm', 'bmn', 'bmo', 'bmp', 'bmq', 'bmr', 'bms', 'bmt', 'bmu', 'bmv', 'bmw', 'bmx', 'bmy', 'bmz', 'bna', 'bnb', 'bnc', 'bnd', 'bne', 'bnf', 'bng', 'bni', 'bnj', 'bnk', 'bnl', 'bnm', 'bnn', 'bno', 'bnp', 'bnq', 'bnr', 'bns', 'bnt', 'bnu', 'bnv', 'bnw', 'bnx', 'bny', 'bnz', 'boa', 'bob', 'boe', 'bof', 'bog', 'boh', 'boi', 'boj', 'bok', 'bol', 'bom', 'bon', 'boo', 'bop', 'boq', 'bor', 'bot', 'bou', 'bov', 'bow', 'box', 'boy', 'boz', 'bpa', 'bpb', 'bpd', 'bpg', 'bph', 'bpi', 'bpj', 'bpk', 'bpl', 'bpm', 'bpn', 'bpo', 'bpp', 'bpq', 'bpr', 'bps', 'bpt', 'bpu', 'bpv', 'bpw', 'bpx', 'bpy', 'bpz', 'bqa', 'bqb', 'bqc', 'bqd', 'bqf', 'bqg', 'bqh', 'bqi', 'bqj', 'bqk', 'bql', 'bqm', 'bqn', 'bqo', 'bqp', 'bqq', 'bqr', 'bqs', 'bqt', 'bqu', 'bqv', 'bqw', 'bqx', 'bqy', 'bqz', 'bra', 'brb', 'brc', 'brd', 'brf', 'brg', 'brh', 'bri', 'brj', 'brk', 'brl', 'brm', 'brn', 'bro', 'brp', 'brq', 'brr', 'brs', 'brt', 'bru', 'brv', 'brw', 'brx', 'bry', 'brz', 'bsa', 'bsb', 'bsc', 'bse', 'bsf', 'bsg', 'bsh', 'bsi', 'bsj', 'bsk', 'bsl', 'bsm', 'bsn', 'bso', 'bsp', 'bsq', 'bsr', 'bss', 'bst', 'bsu', 'bsv', 'bsw', 'bsx', 'bsy', 'bta', 'btb', 'btc', 'btd', 'bte', 'btf', 'btg', 'bth', 'bti', 'btj', 'btk', 'btl', 'btm', 'btn', 'bto', 'btp', 'btq', 'btr', 'bts', 'btt', 'btu', 'btv', 'btw', 'btx', 'bty', 'btz', 'bua', 'bub', 'buc', 'bud', 'bue', 'buf', 'bug', 'buh', 'bui', 'buj', 'buk', 'bum', 'bun', 'buo', 'bup', 'buq', 'bus', 'but', 'buu', 'buv', 'buw', 'bux', 'buy', 'buz', 'bva', 'bvb', 'bvc', 'bvd', 'bve', 'bvf', 'bvg', 'bvh', 'bvi', 'bvj', 'bvk', 'bvl', 'bvm', 'bvn', 'bvo', 'bvp', 'bvq', 'bvr', 'bvt', 'bvu', 'bvv', 'bvw', 'bvx', 'bvy', 'bvz', 'bwa', 'bwb', 'bwc', 'bwd', 'bwe', 'bwf', 'bwg', 'bwh', 'bwi', 'bwj', 'bwk', 'bwl', 'bwm', 'bwn', 'bwo', 'bwp', 'bwq', 'bwr', 'bws', 'bwt', 'bwu', 'bww', 'bwx', 'bwy', 'bwz', 'bxa', 'bxb', 'bxc', 'bxd', 'bxe', 'bxf', 'bxg', 'bxh', 'bxi', 'bxj', 'bxk', 'bxl', 'bxm', 'bxn', 'bxo', 'bxp', 'bxq', 'bxr', 'bxs', 'bxu', 'bxv', 'bxw', 'bxx', 'bxz', 'bya', 'byb', 'byc', 'byd', 'bye', 'byf', 'byg', 'byh', 'byi', 'byj', 'byk', 'byl', 'bym', 'byn', 'byo', 'byp', 'byq', 'byr', 'bys', 'byt', 'byv', 'byw', 'byx', 'byy', 'byz', 'bza', 'bzb', 'bzc', 'bzd', 'bze', 'bzf', 'bzg', 'bzh', 'bzi', 'bzj', 'bzk', 'bzl', 'bzm', 'bzn', 'bzo', 'bzp', 'bzq', 'bzr', 'bzs', 'bzt', 'bzu', 'bzv', 'bzw', 'bzx', 'bzy', 'bzz', 'caa', 'cab', 'cac', 'cad', 'cae', 'caf', 'cag', 'cah', 'cai', 'caj', 'cak', 'cal', 'cam', 'can', 'cao', 'cap', 'caq', 'car', 'cas', 'cau', 'cav', 'caw', 'cax', 'cay', 'caz', 'cba', 'cbb', 'cbc', 'cbd', 'cbe', 'cbg', 'cbh', 'cbi', 'cbj', 'cbk', 'cbl', 'cbn', 'cbo', 'cbq', 'cbr', 'cbs', 'cbt', 'cbu', 'cbv', 'cbw', 'cby', 'cca', 'ccc', 'ccd', 'cce', 'ccg', 'cch', 'ccj', 'ccl', 'ccm', 'ccn', 'cco', 'ccp', 'ccq', 'ccr', 'ccs', 'cda', 'cdc', 'cdd', 'cde', 'cdf', 'cdg', 'cdh', 'cdi', 'cdj', 'cdm', 'cdn', 'cdo', 'cdr', 'cds', 'cdy', 'cdz', 'cea', 'ceb', 'ceg', 'cek', 'cel', 'cen', 'cet', 'cfa', 'cfd', 'cfg', 'cfm', 'cga', 'cgc', 'cgg', 'cgk', 'chb', 'chc', 'chd', 'chf', 'chg', 'chh', 'chj', 'chk', 'chl', 'chm', 'chn', 'cho', 'chp', 'chq', 'chr', 'cht', 'chw', 'chx', 'chy', 'chz', 'cia', 'cib', 'cic', 'cid', 'cie', 'cih', 'cik', 'cim', 'cin', 'cip', 'cir', 'ciw', 'ciy', 'cja', 'cje', 'cjh', 'cji', 'cjk', 'cjm', 'cjn', 'cjo', 'cjp', 'cjr', 'cjs', 'cjv', 'cjy', 'cka', 'ckb', 'ckh', 'ckl', 'ckn', 'cko', 'ckq', 'ckr', 'cks', 'ckt', 'cku', 'ckv', 'ckx', 'cky', 'ckz', 'cla', 'clc', 'cld', 'cle', 'clh', 'cli', 'clj', 'clk', 'cll', 'clm', 'clo', 'clt', 'clu', 'clw', 'cly', 'cma', 'cmc', 'cme', 'cmg', 'cmi', 'cmk', 'cml', 'cmm', 'cmn', 'cmo', 'cmr', 'cms', 'cmt', 'cna', 'cnb', 'cnc', 'cng', 'cnh', 'cni', 'cnk', 'cnl', 'cno', 'cns', 'cnt', 'cnu', 'cnw', 'cnx', 'coa', 'cob', 'coc', 'cod', 'coe', 'cof', 'cog', 'coh', 'coj', 'cok', 'col', 'com', 'con', 'coo', 'cop', 'coq', 'cot', 'cou', 'cov', 'cow', 'cox', 'coy', 'coz', 'cpa', 'cpb', 'cpc', 'cpe', 'cpf', 'cpg', 'cpi', 'cpn', 'cpo', 'cpp', 'cps', 'cpu', 'cpx', 'cpy', 'cqd', 'cqu', 'cra', 'crb', 'crc', 'crd', 'crf', 'crg', 'crh', 'cri', 'crj', 'crk', 'crl', 'crm', 'crn', 'cro', 'crp', 'crq', 'crr', 'crs', 'crt', 'crv', 'crw', 'crx', 'cry', 'crz', 'csa', 'csb', 'csc', 'csd', 'cse', 'csf', 'csg', 'csh', 'csi', 'csj', 'csk', 'csl', 'csm', 'csn', 'cso', 'csq', 'csr', 'css', 'cst', 'csu', 'csv', 'csw', 'csy', 'csz', 'cta', 'ctc', 'ctd', 'cte', 'ctg', 'cth', 'ctl', 'ctm', 'ctn', 'cto', 'ctp', 'cts', 'ctt', 'ctu', 'ctz', 'cua', 'cub', 'cuc', 'cug', 'cuh', 'cui', 'cuj', 'cuk', 'cul', 'cum', 'cuo', 'cup', 'cuq', 'cur', 'cus', 'cut', 'cuu', 'cuv', 'cuw', 'cux', 'cvg', 'cvn', 'cwa', 'cwb', 'cwd', 'cwe', 'cwg', 'cwt', 'cya', 'cyb', 'cyo', 'czh', 'czk', 'czn', 'czo', 'czt', 'daa', 'dac', 'dad', 'dae', 'daf', 'dag', 'dah', 'dai', 'daj', 'dak', 'dal', 'dam', 'dao', 'dap', 'daq', 'dar', 'das', 'dau', 'dav', 'daw', 'dax', 'day', 'daz', 'dba', 'dbb', 'dbd', 'dbe', 'dbf', 'dbg', 'dbi', 'dbj', 'dbl', 'dbm', 'dbn', 'dbo', 'dbp', 'dbq', 'dbr', 'dbt', 'dbu', 'dbv', 'dbw', 'dby', 'dcc', 'dcr', 'dda', 'ddd', 'dde', 'ddg', 'ddi', 'ddj', 'ddn', 'ddo', 'ddr', 'dds', 'ddw', 'dec', 'ded', 'dee', 'def', 'deg', 'deh', 'dei', 'dek', 'del', 'dem', 'den', 'dep', 'deq', 'der', 'des', 'dev', 'dez', 'dga', 'dgb', 'dgc', 'dgd', 'dge', 'dgg', 'dgh', 'dgi', 'dgk', 'dgl', 'dgn', 'dgo', 'dgr', 'dgs', 'dgt', 'dgu', 'dgw', 'dgx', 'dgz', 'dha', 'dhd', 'dhg', 'dhi', 'dhl', 'dhm', 'dhn', 'dho', 'dhr', 'dhs', 'dhu', 'dhv', 'dhw', 'dhx', 'dia', 'dib', 'dic', 'did', 'dif', 'dig', 'dih', 'dii', 'dij', 'dik', 'dil', 'dim', 'din', 'dio', 'dip', 'diq', 'dir', 'dis', 'dit', 'diu', 'diw', 'dix', 'diy', 'diz', 'dja', 'djb', 'djc', 'djd', 'dje', 'djf', 'dji', 'djj', 'djk', 'djl', 'djm', 'djn', 'djo', 'djr', 'dju', 'djw', 'dka', 'dkk', 'dkl', 'dkr', 'dks', 'dkx', 'dlg', 'dlk', 'dlm', 'dln', 'dma', 'dmb', 'dmc', 'dmd', 'dme', 'dmg', 'dmk', 'dml', 'dmm', 'dmn', 'dmo', 'dmr', 'dms', 'dmu', 'dmv', 'dmw', 'dmx', 'dmy', 'dna', 'dnd', 'dne', 'dng', 'dni', 'dnj', 'dnk', 'dnn', 'dnr', 'dnt', 'dnu', 'dnv', 'dnw', 'dny', 'doa', 'dob', 'doc', 'doe', 'dof', 'doh', 'doi', 'dok', 'dol', 'don', 'doo', 'dop', 'doq', 'dor', 'dos', 'dot', 'dov', 'dow', 'dox', 'doy', 'doz', 'dpp', 'dra', 'drb', 'drc', 'drd', 'dre', 'drg', 'drh', 'dri', 'drl', 'drn', 'dro', 'drq', 'drr', 'drs', 'drt', 'dru', 'drw', 'dry', 'dsb', 'dse', 'dsh', 'dsi', 'dsl', 'dsn', 'dso', 'dsq', 'dta', 'dtb', 'dtd', 'dth', 'dti', 'dtk', 'dtm', 'dtn', 'dto', 'dtp', 'dtr', 'dts', 'dtt', 'dtu', 'dty', 'dua', 'dub', 'duc', 'dud', 'due', 'duf', 'dug', 'duh', 'dui', 'duj', 'duk', 'dul', 'dum', 'dun', 'duo', 'dup', 'duq', 'dur', 'dus', 'duu', 'duv', 'duw', 'dux', 'duy', 'duz', 'dva', 'dwa', 'dwl', 'dwr', 'dws', 'dwu', 'dww', 'dwy', 'dya', 'dyb', 'dyd', 'dyg', 'dyi', 'dym', 'dyn', 'dyo', 'dyu', 'dyy', 'dza', 'dzd', 'dze', 'dzg', 'dzl', 'dzn', 'eaa', 'ebg', 'ebk', 'ebo', 'ebr', 'ebu', 'ecr', 'ecs', 'ecy', 'eee', 'efa', 'efe', 'efi', 'ega', 'egl', 'ego', 'egx', 'egy', 'ehu', 'eip', 'eit', 'eiv', 'eja', 'eka', 'ekc', 'eke', 'ekg', 'eki', 'ekk', 'ekl', 'ekm', 'eko', 'ekp', 'ekr', 'eky', 'ele', 'elh', 'eli', 'elk', 'elm', 'elo', 'elp', 'elu', 'elx', 'ema', 'emb', 'eme', 'emg', 'emi', 'emk', 'emm', 'emn', 'emo', 'emp', 'ems', 'emu', 'emw', 'emx', 'emy', 'ena', 'enb', 'enc', 'end', 'enf', 'enh', 'enl', 'enm', 'enn', 'eno', 'enq', 'enr', 'enu', 'env', 'enw', 'enx', 'eot', 'epi', 'era', 'erg', 'erh', 'eri', 'erk', 'ero', 'err', 'ers', 'ert', 'erw', 'ese', 'esg', 'esh', 'esi', 'esk', 'esl', 'esm', 'esn', 'eso', 'esq', 'ess', 'esu', 'esx', 'esy', 'etb', 'etc', 'eth', 'etn', 'eto', 'etr', 'ets', 'ett', 'etu', 'etx', 'etz', 'euq', 'eve', 'evh', 'evn', 'ewo', 'ext', 'eya', 'eyo', 'eza', 'eze', 'faa', 'fab', 'fad', 'faf', 'fag', 'fah', 'fai', 'faj', 'fak', 'fal', 'fam', 'fan', 'fap', 'far', 'fat', 'fau', 'fax', 'fay', 'faz', 'fbl', 'fcs', 'fer', 'ffi', 'ffm', 'fgr', 'fia', 'fie', 'fil', 'fip', 'fir', 'fit', 'fiu', 'fiw', 'fkk', 'fkv', 'fla', 'flh', 'fli', 'fll', 'fln', 'flr', 'fly', 'fmp', 'fmu', 'fnb', 'fng', 'fni', 'fod', 'foi', 'fom', 'fon', 'for', 'fos', 'fox', 'fpe', 'fqs', 'frc', 'frd', 'frk', 'frm', 'fro', 'frp', 'frq', 'frr', 'frs', 'frt', 'fse', 'fsl', 'fss', 'fub', 'fuc', 'fud', 'fue', 'fuf', 'fuh', 'fui', 'fuj', 'fum', 'fun', 'fuq', 'fur', 'fut', 'fuu', 'fuv', 'fuy', 'fvr', 'fwa', 'fwe', 'gaa', 'gab', 'gac', 'gad', 'gae', 'gaf', 'gag', 'gah', 'gai', 'gaj', 'gak', 'gal', 'gam', 'gan', 'gao', 'gap', 'gaq', 'gar', 'gas', 'gat', 'gau', 'gav', 'gaw', 'gax', 'gay', 'gaz', 'gba', 'gbb', 'gbc', 'gbd', 'gbe', 'gbf', 'gbg', 'gbh', 'gbi', 'gbj', 'gbk', 'gbl', 'gbm', 'gbn', 'gbo', 'gbp', 'gbq', 'gbr', 'gbs', 'gbu', 'gbv', 'gbw', 'gbx', 'gby', 'gbz', 'gcc', 'gcd', 'gce', 'gcf', 'gcl', 'gcn', 'gcr', 'gct', 'gda', 'gdb', 'gdc', 'gdd', 'gde', 'gdf', 'gdg', 'gdh', 'gdi', 'gdj', 'gdk', 'gdl', 'gdm', 'gdn', 'gdo', 'gdq', 'gdr', 'gds', 'gdt', 'gdu', 'gdx', 'gea', 'geb', 'gec', 'ged', 'geg', 'geh', 'gei', 'gej', 'gek', 'gel', 'gem', 'geq', 'ges', 'gev', 'gew', 'gex', 'gey', 'gez', 'gfk', 'gft', 'gfx', 'gga', 'ggb', 'ggd', 'gge', 'ggg', 'ggk', 'ggl', 'ggn', 'ggo', 'ggr', 'ggt', 'ggu', 'ggw', 'gha', 'ghc', 'ghe', 'ghh', 'ghk', 'ghl', 'ghn', 'gho', 'ghr', 'ghs', 'ght', 'gia', 'gib', 'gic', 'gid', 'gie', 'gig', 'gih', 'gil', 'gim', 'gin', 'gio', 'gip', 'giq', 'gir', 'gis', 'git', 'giu', 'giw', 'gix', 'giy', 'giz', 'gji', 'gjk', 'gjm', 'gjn', 'gjr', 'gju', 'gka', 'gke', 'gkn', 'gko', 'gkp', 'gku', 'glc', 'gld', 'glh', 'gli', 'glj', 'glk', 'gll', 'glo', 'glr', 'glu', 'glw', 'gly', 'gma', 'gmb', 'gmd', 'gme', 'gmg', 'gmh', 'gml', 'gmm', 'gmn', 'gmq', 'gmu', 'gmv', 'gmw', 'gmx', 'gmy', 'gmz', 'gna', 'gnb', 'gnc', 'gnd', 'gne', 'gng', 'gnh', 'gni', 'gnk', 'gnl', 'gnm', 'gnn', 'gno', 'gnq', 'gnr', 'gnt', 'gnu', 'gnw', 'gnz', 'goa', 'gob', 'goc', 'god', 'goe', 'gof', 'gog', 'goh', 'goi', 'goj', 'gok', 'gol', 'gom', 'gon', 'goo', 'gop', 'goq', 'gor', 'gos', 'got', 'gou', 'gow', 'gox', 'goy', 'goz', 'gpa', 'gpe', 'gpn', 'gqa', 'gqi', 'gqn', 'gqr', 'gqu', 'gra', 'grb', 'grc', 'grd', 'grg', 'grh', 'gri', 'grj', 'grk', 'grm', 'gro', 'grq', 'grr', 'grs', 'grt', 'gru', 'grv', 'grw', 'grx', 'gry', 'grz', 'gse', 'gsg', 'gsl', 'gsm', 'gsn', 'gso', 'gsp', 'gss', 'gsw', 'gta', 'gti', 'gtu', 'gua', 'gub', 'guc', 'gud', 'gue', 'guf', 'gug', 'guh', 'gui', 'guk', 'gul', 'gum', 'gun', 'guo', 'gup', 'guq', 'gur', 'gus', 'gut', 'guu', 'guv', 'guw', 'gux', 'guz', 'gva', 'gvc', 'gve', 'gvf', 'gvj', 'gvl', 'gvm', 'gvn', 'gvo', 'gvp', 'gvr', 'gvs', 'gvy', 'gwa', 'gwb', 'gwc', 'gwd', 'gwe', 'gwf', 'gwg', 'gwi', 'gwj', 'gwm', 'gwn', 'gwr', 'gwt', 'gwu', 'gww', 'gwx', 'gxx', 'gya', 'gyb', 'gyd', 'gye', 'gyf', 'gyg', 'gyi', 'gyl', 'gym', 'gyn', 'gyr', 'gyy', 'gza', 'gzi', 'gzn', 'haa', 'hab', 'hac', 'had', 'hae', 'haf', 'hag', 'hah', 'hai', 'haj', 'hak', 'hal', 'ham', 'han', 'hao', 'hap', 'haq', 'har', 'has', 'hav', 'haw', 'hax', 'hay', 'haz', 'hba', 'hbb', 'hbn', 'hbo', 'hbu', 'hca', 'hch', 'hdn', 'hds', 'hdy', 'hea', 'hed', 'heg', 'heh', 'hei', 'hem', 'hgm', 'hgw', 'hhi', 'hhr', 'hhy', 'hia', 'hib', 'hid', 'hif', 'hig', 'hih', 'hii', 'hij', 'hik', 'hil', 'him', 'hio', 'hir', 'hit', 'hiw', 'hix', 'hji', 'hka', 'hke', 'hkk', 'hks', 'hla', 'hlb', 'hld', 'hle', 'hlt', 'hlu', 'hma', 'hmb', 'hmc', 'hmd', 'hme', 'hmf', 'hmg', 'hmh', 'hmi', 'hmj', 'hmk', 'hml', 'hmm', 'hmn', 'hmp', 'hmq', 'hmr', 'hms', 'hmt', 'hmu', 'hmv', 'hmw', 'hmx', 'hmy', 'hmz', 'hna', 'hnd', 'hne', 'hnh', 'hni', 'hnj', 'hnn', 'hno', 'hns', 'hnu', 'hoa', 'hob', 'hoc', 'hod', 'hoe', 'hoh', 'hoi', 'hoj', 'hok', 'hol', 'hom', 'hoo', 'hop', 'hor', 'hos', 'hot', 'hov', 'how', 'hoy', 'hoz', 'hpo', 'hps', 'hra', 'hrc', 'hre', 'hrk', 'hrm', 'hro', 'hrp', 'hrr', 'hrt', 'hru', 'hrw', 'hrx', 'hrz', 'hsb', 'hsh', 'hsl', 'hsn', 'hss', 'hti', 'hto', 'hts', 'htu', 'htx', 'hub', 'huc', 'hud', 'hue', 'huf', 'hug', 'huh', 'hui', 'huj', 'huk', 'hul', 'hum', 'huo', 'hup', 'huq', 'hur', 'hus', 'hut', 'huu', 'huv', 'huw', 'hux', 'huy', 'huz', 'hvc', 'hve', 'hvk', 'hvn', 'hvv', 'hwa', 'hwc', 'hwo', 'hya', 'hyx', 'iai', 'ian', 'iap', 'iar', 'iba', 'ibb', 'ibd', 'ibe', 'ibg', 'ibh', 'ibi', 'ibl', 'ibm', 'ibn', 'ibr', 'ibu', 'iby', 'ica', 'ich', 'icl', 'icr', 'ida', 'idb', 'idc', 'idd', 'ide', 'idi', 'idr', 'ids', 'idt', 'idu', 'ifa', 'ifb', 'ife', 'iff', 'ifk', 'ifm', 'ifu', 'ify', 'igb', 'ige', 'igg', 'igl', 'igm', 'ign', 'igo', 'igs', 'igw', 'ihb', 'ihi', 'ihp', 'ihw', 'iin', 'iir', 'ijc', 'ije', 'ijj', 'ijn', 'ijo', 'ijs', 'ike', 'iki', 'ikk', 'ikl', 'iko', 'ikp', 'ikr', 'iks', 'ikt', 'ikv', 'ikw', 'ikx', 'ikz', 'ila', 'ilb', 'ilg', 'ili', 'ilk', 'ill', 'ilm', 'ilo', 'ilp', 'ils', 'ilu', 'ilv', 'ilw', 'ima', 'ime', 'imi', 'iml', 'imn', 'imo', 'imr', 'ims', 'imy', 'inb', 'inc', 'ine', 'ing', 'inh', 'inj', 'inl', 'inm', 'inn', 'ino', 'inp', 'ins', 'int', 'inz', 'ior', 'iou', 'iow', 'ipi', 'ipo', 'iqu', 'iqw', 'ira', 'ire', 'irh', 'iri', 'irk', 'irn', 'iro', 'irr', 'iru', 'irx', 'iry', 'isa', 'isc', 'isd', 'ise', 'isg', 'ish', 'isi', 'isk', 'ism', 'isn', 'iso', 'isr', 'ist', 'isu', 'itb', 'itc', 'itd', 'ite', 'iti', 'itk', 'itl', 'itm', 'ito', 'itr', 'its', 'itt', 'itv', 'itw', 'itx', 'ity', 'itz', 'ium', 'ivb', 'ivv', 'iwk', 'iwm', 'iwo', 'iws', 'ixc', 'ixl', 'iya', 'iyo', 'iyx', 'izh', 'izi', 'izr', 'izz', 'jaa', 'jab', 'jac', 'jad', 'jae', 'jaf', 'jah', 'jaj', 'jak', 'jal', 'jam', 'jan', 'jao', 'jaq', 'jar', 'jas', 'jat', 'jau', 'jax', 'jay', 'jaz', 'jbe', 'jbi', 'jbj', 'jbk', 'jbn', 'jbo', 'jbr', 'jbt', 'jbu', 'jbw', 'jcs', 'jct', 'jda', 'jdg', 'jdt', 'jeb', 'jee', 'jeg', 'jeh', 'jei', 'jek', 'jel', 'jen', 'jer', 'jet', 'jeu', 'jgb', 'jge', 'jgk', 'jgo', 'jhi', 'jhs', 'jia', 'jib', 'jic', 'jid', 'jie', 'jig', 'jih', 'jii', 'jil', 'jim', 'jio', 'jiq', 'jit', 'jiu', 'jiv', 'jiy', 'jje', 'jjr', 'jka', 'jkm', 'jko', 'jkp', 'jkr', 'jku', 'jle', 'jls', 'jma', 'jmb', 'jmc', 'jmd', 'jmi', 'jml', 'jmn', 'jmr', 'jms', 'jmw', 'jmx', 'jna', 'jnd', 'jng', 'jni', 'jnj', 'jnl', 'jns', 'job', 'jod', 'jog', 'jor', 'jos', 'jow', 'jpa', 'jpr', 'jpx', 'jqr', 'jra', 'jrb', 'jrr', 'jrt', 'jru', 'jsl', 'jua', 'jub', 'juc', 'jud', 'juh', 'jui', 'juk', 'jul', 'jum', 'jun', 'juo', 'jup', 'jur', 'jus', 'jut', 'juu', 'juw', 'juy', 'jvd', 'jvn', 'jwi', 'jya', 'jye', 'jyy', 'kaa', 'kab', 'kac', 'kad', 'kae', 'kaf', 'kag', 'kah', 'kai', 'kaj', 'kak', 'kam', 'kao', 'kap', 'kaq', 'kar', 'kav', 'kaw', 'kax', 'kay', 'kba', 'kbb', 'kbc', 'kbd', 'kbe', 'kbf', 'kbg', 'kbh', 'kbi', 'kbj', 'kbk', 'kbl', 'kbm', 'kbn', 'kbo', 'kbp', 'kbq', 'kbr', 'kbs', 'kbt', 'kbu', 'kbv', 'kbw', 'kbx', 'kby', 'kbz', 'kca', 'kcb', 'kcc', 'kcd', 'kce', 'kcf', 'kcg', 'kch', 'kci', 'kcj', 'kck', 'kcl', 'kcm', 'kcn', 'kco', 'kcp', 'kcq', 'kcr', 'kcs', 'kct', 'kcu', 'kcv', 'kcw', 'kcx', 'kcy', 'kcz', 'kda', 'kdc', 'kdd', 'kde', 'kdf', 'kdg', 'kdh', 'kdi', 'kdj', 'kdk', 'kdl', 'kdm', 'kdn', 'kdo', 'kdp', 'kdq', 'kdr', 'kdt', 'kdu', 'kdv', 'kdw', 'kdx', 'kdy', 'kdz', 'kea', 'keb', 'kec', 'ked', 'kee', 'kef', 'keg', 'keh', 'kei', 'kej', 'kek', 'kel', 'kem', 'ken', 'keo', 'kep', 'keq', 'ker', 'kes', 'ket', 'keu', 'kev', 'kew', 'kex', 'key', 'kez', 'kfa', 'kfb', 'kfc', 'kfd', 'kfe', 'kff', 'kfg', 'kfh', 'kfi', 'kfj', 'kfk', 'kfl', 'kfm', 'kfn', 'kfo', 'kfp', 'kfq', 'kfr', 'kfs', 'kft', 'kfu', 'kfv', 'kfw', 'kfx', 'kfy', 'kfz', 'kga', 'kgb', 'kgc', 'kgd', 'kge', 'kgf', 'kgg', 'kgh', 'kgi', 'kgj', 'kgk', 'kgl', 'kgm', 'kgn', 'kgo', 'kgp', 'kgq', 'kgr', 'kgs', 'kgt', 'kgu', 'kgv', 'kgw', 'kgx', 'kgy', 'kha', 'khb', 'khc', 'khd', 'khe', 'khf', 'khg', 'khh', 'khi', 'khj', 'khk', 'khl', 'khn', 'kho', 'khp', 'khq', 'khr', 'khs', 'kht', 'khu', 'khv', 'khw', 'khx', 'khy', 'khz', 'kia', 'kib', 'kic', 'kid', 'kie', 'kif', 'kig', 'kih', 'kii', 'kij', 'kil', 'kim', 'kio', 'kip', 'kiq', 'kis', 'kit', 'kiu', 'kiv', 'kiw', 'kix', 'kiy', 'kiz', 'kja', 'kjb', 'kjc', 'kjd', 'kje', 'kjf', 'kjg', 'kjh', 'kji', 'kjj', 'kjk', 'kjl', 'kjm', 'kjn', 'kjo', 'kjp', 'kjq', 'kjr', 'kjs', 'kjt', 'kju', 'kjv', 'kjx', 'kjy', 'kjz', 'kka', 'kkb', 'kkc', 'kkd', 'kke', 'kkf', 'kkg', 'kkh', 'kki', 'kkj', 'kkk', 'kkl', 'kkm', 'kkn', 'kko', 'kkp', 'kkq', 'kkr', 'kks', 'kkt', 'kku', 'kkv', 'kkw', 'kkx', 'kky', 'kkz', 'kla', 'klb', 'klc', 'kld', 'kle', 'klf', 'klg', 'klh', 'kli', 'klj', 'klk', 'kll', 'klm', 'kln', 'klo', 'klp', 'klq', 'klr', 'kls', 'klt', 'klu', 'klv', 'klw', 'klx', 'kly', 'klz', 'kma', 'kmb', 'kmc', 'kmd', 'kme', 'kmf', 'kmg', 'kmh', 'kmi', 'kmj', 'kmk', 'kml', 'kmm', 'kmn', 'kmo', 'kmp', 'kmq', 'kmr', 'kms', 'kmt', 'kmu', 'kmv', 'kmw', 'kmx', 'kmy', 'kmz', 'kna', 'knb', 'knc', 'knd', 'kne', 'knf', 'kng', 'kni', 'knj', 'knk', 'knl', 'knm', 'knn', 'kno', 'knp', 'knq', 'knr', 'kns', 'knt', 'knu', 'knv', 'knw', 'knx', 'kny', 'knz', 'koa', 'koc', 'kod', 'koe', 'kof', 'kog', 'koh', 'koi', 'koj', 'kok', 'kol', 'koo', 'kop', 'koq', 'kos', 'kot', 'kou', 'kov', 'kow', 'kox', 'koy', 'koz', 'kpa', 'kpb', 'kpc', 'kpd', 'kpe', 'kpf', 'kpg', 'kph', 'kpi', 'kpj', 'kpk', 'kpl', 'kpm', 'kpn', 'kpo', 'kpp', 'kpq', 'kpr', 'kps', 'kpt', 'kpu', 'kpv', 'kpw', 'kpx', 'kpy', 'kpz', 'kqa', 'kqb', 'kqc', 'kqd', 'kqe', 'kqf', 'kqg', 'kqh', 'kqi', 'kqj', 'kqk', 'kql', 'kqm', 'kqn', 'kqo', 'kqp', 'kqq', 'kqr', 'kqs', 'kqt', 'kqu', 'kqv', 'kqw', 'kqx', 'kqy', 'kqz', 'kra', 'krb', 'krc', 'krd', 'kre', 'krf', 'krh', 'kri', 'krj', 'krk', 'krl', 'krm', 'krn', 'kro', 'krp', 'krr', 'krs', 'krt', 'kru', 'krv', 'krw', 'krx', 'kry', 'krz', 'ksa', 'ksb', 'ksc', 'ksd', 'kse', 'ksf', 'ksg', 'ksh', 'ksi', 'ksj', 'ksk', 'ksl', 'ksm', 'ksn', 'kso', 'ksp', 'ksq', 'ksr', 'kss', 'kst', 'ksu', 'ksv', 'ksw', 'ksx', 'ksy', 'ksz', 'kta', 'ktb', 'ktc', 'ktd', 'kte', 'ktf', 'ktg', 'kth', 'kti', 'ktj', 'ktk', 'ktl', 'ktm', 'ktn', 'kto', 'ktp', 'ktq', 'ktr', 'kts', 'ktt', 'ktu', 'ktv', 'ktw', 'ktx', 'kty', 'ktz', 'kub', 'kuc', 'kud', 'kue', 'kuf', 'kug', 'kuh', 'kui', 'kuj', 'kuk', 'kul', 'kum', 'kun', 'kuo', 'kup', 'kuq', 'kus', 'kut', 'kuu', 'kuv', 'kuw', 'kux', 'kuy', 'kuz', 'kva', 'kvb', 'kvc', 'kvd', 'kve', 'kvf', 'kvg', 'kvh', 'kvi', 'kvj', 'kvk', 'kvl', 'kvm', 'kvn', 'kvo', 'kvp', 'kvq', 'kvr', 'kvs', 'kvt', 'kvu', 'kvv', 'kvw', 'kvx', 'kvy', 'kvz', 'kwa', 'kwb', 'kwc', 'kwd', 'kwe', 'kwf', 'kwg', 'kwh', 'kwi', 'kwj', 'kwk', 'kwl', 'kwm', 'kwn', 'kwo', 'kwp', 'kwq', 'kwr', 'kws', 'kwt', 'kwu', 'kwv', 'kww', 'kwx', 'kwy', 'kwz', 'kxa', 'kxb', 'kxc', 'kxd', 'kxe', 'kxf', 'kxh', 'kxi', 'kxj', 'kxk', 'kxl', 'kxm', 'kxn', 'kxo', 'kxp', 'kxq', 'kxr', 'kxs', 'kxt', 'kxu', 'kxv', 'kxw', 'kxx', 'kxy', 'kxz', 'kya', 'kyb', 'kyc', 'kyd', 'kye', 'kyf', 'kyg', 'kyh', 'kyi', 'kyj', 'kyk', 'kyl', 'kym', 'kyn', 'kyo', 'kyp', 'kyq', 'kyr', 'kys', 'kyt', 'kyu', 'kyv', 'kyw', 'kyx', 'kyy', 'kyz', 'kza', 'kzb', 'kzc', 'kzd', 'kze', 'kzf', 'kzg', 'kzh', 'kzi', 'kzj', 'kzk', 'kzl', 'kzm', 'kzn', 'kzo', 'kzp', 'kzq', 'kzr', 'kzs', 'kzt', 'kzu', 'kzv', 'kzw', 'kzx', 'kzy', 'kzz', 'laa', 'lab', 'lac', 'lad', 'lae', 'laf', 'lag', 'lah', 'lai', 'laj', 'lak', 'lal', 'lam', 'lan', 'lap', 'laq', 'lar', 'las', 'lau', 'law', 'lax', 'lay', 'laz', 'lba', 'lbb', 'lbc', 'lbe', 'lbf', 'lbg', 'lbi', 'lbj', 'lbk', 'lbl', 'lbm', 'lbn', 'lbo', 'lbq', 'lbr', 'lbs', 'lbt', 'lbu', 'lbv', 'lbw', 'lbx', 'lby', 'lbz', 'lcc', 'lcd', 'lce', 'lcf', 'lch', 'lcl', 'lcm', 'lcp', 'lcq', 'lcs', 'lda', 'ldb', 'ldd', 'ldg', 'ldh', 'ldi', 'ldj', 'ldk', 'ldl', 'ldm', 'ldn', 'ldo', 'ldp', 'ldq', 'lea', 'leb', 'lec', 'led', 'lee', 'lef', 'leg', 'leh', 'lei', 'lej', 'lek', 'lel', 'lem', 'len', 'leo', 'lep', 'leq', 'ler', 'les', 'let', 'leu', 'lev', 'lew', 'lex', 'ley', 'lez', 'lfa', 'lfn', 'lga', 'lgb', 'lgg', 'lgh', 'lgi', 'lgk', 'lgl', 'lgm', 'lgn', 'lgq', 'lgr', 'lgt', 'lgu', 'lgz', 'lha', 'lhh', 'lhi', 'lhl', 'lhm', 'lhn', 'lhp', 'lhs', 'lht', 'lhu', 'lia', 'lib', 'lic', 'lid', 'lie', 'lif', 'lig', 'lih', 'lii', 'lij', 'lik', 'lil', 'lio', 'lip', 'liq', 'lir', 'lis', 'liu', 'liv', 'liw', 'lix', 'liy', 'liz', 'lja', 'lje', 'lji', 'ljl', 'ljp', 'ljw', 'ljx', 'lka', 'lkb', 'lkc', 'lkd', 'lke', 'lkh', 'lki', 'lkj', 'lkl', 'lkm', 'lkn', 'lko', 'lkr', 'lks', 'lkt', 'lku', 'lky', 'lla', 'llb', 'llc', 'lld', 'lle', 'llf', 'llg', 'llh', 'lli', 'llj', 'llk', 'lll', 'llm', 'lln', 'llo', 'llp', 'llq', 'lls', 'llu', 'llx', 'lma', 'lmb', 'lmc', 'lmd', 'lme', 'lmf', 'lmg', 'lmh', 'lmi', 'lmj', 'lmk', 'lml', 'lmm', 'lmn', 'lmo', 'lmp', 'lmq', 'lmr', 'lmu', 'lmv', 'lmw', 'lmx', 'lmy', 'lmz', 'lna', 'lnb', 'lnd', 'lng', 'lnh', 'lni', 'lnj', 'lnl', 'lnm', 'lnn', 'lno', 'lns', 'lnu', 'lnw', 'lnz', 'loa', 'lob', 'loc', 'loe', 'lof', 'log', 'loh', 'loi', 'loj', 'lok', 'lol', 'lom', 'lon', 'loo', 'lop', 'loq', 'lor', 'los', 'lot', 'lou', 'lov', 'low', 'lox', 'loy', 'loz', 'lpa', 'lpe', 'lpn', 'lpo', 'lpx', 'lra', 'lrc', 'lre', 'lrg', 'lri', 'lrk', 'lrl', 'lrm', 'lrn', 'lro', 'lrr', 'lrt', 'lrv', 'lrz', 'lsa', 'lsd', 'lse', 'lsg', 'lsh', 'lsi', 'lsl', 'lsm', 'lso', 'lsp', 'lsr', 'lss', 'lst', 'lsy', 'ltc', 'ltg', 'lth', 'lti', 'ltn', 'lto', 'lts', 'ltu', 'lua', 'luc', 'lud', 'lue', 'luf', 'lui', 'luj', 'luk', 'lul', 'lum', 'lun', 'luo', 'lup', 'luq', 'lur', 'lus', 'lut', 'luu', 'luv', 'luw', 'luy', 'luz', 'lva', 'lvk', 'lvs', 'lvu', 'lwa', 'lwe', 'lwg', 'lwh', 'lwl', 'lwm', 'lwo', 'lwt', 'lwu', 'lww', 'lya', 'lyg', 'lyn', 'lzh', 'lzl', 'lzn', 'lzz', 'maa', 'mab', 'mad', 'mae', 'maf', 'mag', 'mai', 'maj', 'mak', 'mam', 'man', 'map', 'maq', 'mas', 'mat', 'mau', 'mav', 'maw', 'max', 'maz', 'mba', 'mbb', 'mbc', 'mbd', 'mbe', 'mbf', 'mbh', 'mbi', 'mbj', 'mbk', 'mbl', 'mbm', 'mbn', 'mbo', 'mbp', 'mbq', 'mbr', 'mbs', 'mbt', 'mbu', 'mbv', 'mbw', 'mbx', 'mby', 'mbz', 'mca', 'mcb', 'mcc', 'mcd', 'mce', 'mcf', 'mcg', 'mch', 'mci', 'mcj', 'mck', 'mcl', 'mcm', 'mcn', 'mco', 'mcp', 'mcq', 'mcr', 'mcs', 'mct', 'mcu', 'mcv', 'mcw', 'mcx', 'mcy', 'mcz', 'mda', 'mdb', 'mdc', 'mdd', 'mde', 'mdf', 'mdg', 'mdh', 'mdi', 'mdj', 'mdk', 'mdl', 'mdm', 'mdn', 'mdp', 'mdq', 'mdr', 'mds', 'mdt', 'mdu', 'mdv', 'mdw', 'mdx', 'mdy', 'mdz', 'mea', 'meb', 'mec', 'med', 'mee', 'mef', 'meg', 'meh', 'mei', 'mej', 'mek', 'mel', 'mem', 'men', 'meo', 'mep', 'meq', 'mer', 'mes', 'met', 'meu', 'mev', 'mew', 'mey', 'mez', 'mfa', 'mfb', 'mfc', 'mfd', 'mfe', 'mff', 'mfg', 'mfh', 'mfi', 'mfj', 'mfk', 'mfl', 'mfm', 'mfn', 'mfo', 'mfp', 'mfq', 'mfr', 'mfs', 'mft', 'mfu', 'mfv', 'mfw', 'mfx', 'mfy', 'mfz', 'mga', 'mgb', 'mgc', 'mgd', 'mge', 'mgf', 'mgg', 'mgh', 'mgi', 'mgj', 'mgk', 'mgl', 'mgm', 'mgn', 'mgo', 'mgp', 'mgq', 'mgr', 'mgs', 'mgt', 'mgu', 'mgv', 'mgw', 'mgx', 'mgy', 'mgz', 'mha', 'mhb', 'mhc', 'mhd', 'mhe', 'mhf', 'mhg', 'mhh', 'mhi', 'mhj', 'mhk', 'mhl', 'mhm', 'mhn', 'mho', 'mhp', 'mhq', 'mhr', 'mhs', 'mht', 'mhu', 'mhw', 'mhx', 'mhy', 'mhz', 'mia', 'mib', 'mic', 'mid', 'mie', 'mif', 'mig', 'mih', 'mii', 'mij', 'mik', 'mil', 'mim', 'min', 'mio', 'mip', 'miq', 'mir', 'mis', 'mit', 'miu', 'miw', 'mix', 'miy', 'miz', 'mja', 'mjb', 'mjc', 'mjd', 'mje', 'mjg', 'mjh', 'mji', 'mjj', 'mjk', 'mjl', 'mjm', 'mjn', 'mjo', 'mjp', 'mjq', 'mjr', 'mjs', 'mjt', 'mju', 'mjv', 'mjw', 'mjx', 'mjy', 'mjz', 'mka', 'mkb', 'mkc', 'mke', 'mkf', 'mkg', 'mkh', 'mki', 'mkj', 'mkk', 'mkl', 'mkm', 'mkn', 'mko', 'mkp', 'mkq', 'mkr', 'mks', 'mkt', 'mku', 'mkv', 'mkw', 'mkx', 'mky', 'mkz', 'mla', 'mlb', 'mlc', 'mld', 'mle', 'mlf', 'mlh', 'mli', 'mlj', 'mlk', 'mll', 'mlm', 'mln', 'mlo', 'mlp', 'mlq', 'mlr', 'mls', 'mlu', 'mlv', 'mlw', 'mlx', 'mlz', 'mma', 'mmb', 'mmc', 'mmd', 'mme', 'mmf', 'mmg', 'mmh', 'mmi', 'mmj', 'mmk', 'mml', 'mmm', 'mmn', 'mmo', 'mmp', 'mmq', 'mmr', 'mmt', 'mmu', 'mmv', 'mmw', 'mmx', 'mmy', 'mmz', 'mna', 'mnb', 'mnc', 'mnd', 'mne', 'mnf', 'mng', 'mnh', 'mni', 'mnj', 'mnk', 'mnl', 'mnm', 'mnn', 'mno', 'mnp', 'mnq', 'mnr', 'mns', 'mnt', 'mnu', 'mnv', 'mnw', 'mnx', 'mny', 'mnz', 'moa', 'moc', 'mod', 'moe', 'mof', 'mog', 'moh', 'moi', 'moj', 'mok', 'mom', 'moo', 'mop', 'moq', 'mor', 'mos', 'mot', 'mou', 'mov', 'mow', 'mox', 'moy', 'moz', 'mpa', 'mpb', 'mpc', 'mpd', 'mpe', 'mpg', 'mph', 'mpi', 'mpj', 'mpk', 'mpl', 'mpm', 'mpn', 'mpo', 'mpp', 'mpq', 'mpr', 'mps', 'mpt', 'mpu', 'mpv', 'mpw', 'mpx', 'mpy', 'mpz', 'mqa', 'mqb', 'mqc', 'mqe', 'mqf', 'mqg', 'mqh', 'mqi', 'mqj', 'mqk', 'mql', 'mqm', 'mqn', 'mqo', 'mqp', 'mqq', 'mqr', 'mqs', 'mqt', 'mqu', 'mqv', 'mqw', 'mqx', 'mqy', 'mqz', 'mra', 'mrb', 'mrc', 'mrd', 'mre', 'mrf', 'mrg', 'mrh', 'mrj', 'mrk', 'mrl', 'mrm', 'mrn', 'mro', 'mrp', 'mrq', 'mrr', 'mrs', 'mrt', 'mru', 'mrv', 'mrw', 'mrx', 'mry', 'mrz', 'msb', 'msc', 'msd', 'mse', 'msf', 'msg', 'msh', 'msi', 'msj', 'msk', 'msl', 'msm', 'msn', 'mso', 'msp', 'msq', 'msr', 'mss', 'mst', 'msu', 'msv', 'msw', 'msx', 'msy', 'msz', 'mta', 'mtb', 'mtc', 'mtd', 'mte', 'mtf', 'mtg', 'mth', 'mti', 'mtj', 'mtk', 'mtl', 'mtm', 'mtn', 'mto', 'mtp', 'mtq', 'mtr', 'mts', 'mtt', 'mtu', 'mtv', 'mtw', 'mtx', 'mty', 'mua', 'mub', 'muc', 'mud', 'mue', 'mug', 'muh', 'mui', 'muj', 'muk', 'mul', 'mum', 'mun', 'muo', 'mup', 'muq', 'mur', 'mus', 'mut', 'muu', 'muv', 'mux', 'muy', 'muz', 'mva', 'mvb', 'mvd', 'mve', 'mvf', 'mvg', 'mvh', 'mvi', 'mvk', 'mvl', 'mvm', 'mvn', 'mvo', 'mvp', 'mvq', 'mvr', 'mvs', 'mvt', 'mvu', 'mvv', 'mvw', 'mvx', 'mvy', 'mvz', 'mwa', 'mwb', 'mwc', 'mwd', 'mwe', 'mwf', 'mwg', 'mwh', 'mwi', 'mwj', 'mwk', 'mwl', 'mwm', 'mwn', 'mwo', 'mwp', 'mwq', 'mwr', 'mws', 'mwt', 'mwu', 'mwv', 'mww', 'mwx', 'mwy', 'mwz', 'mxa', 'mxb', 'mxc', 'mxd', 'mxe', 'mxf', 'mxg', 'mxh', 'mxi', 'mxj', 'mxk', 'mxl', 'mxm', 'mxn', 'mxo', 'mxp', 'mxq', 'mxr', 'mxs', 'mxt', 'mxu', 'mxv', 'mxw', 'mxx', 'mxy', 'mxz', 'myb', 'myc', 'myd', 'mye', 'myf', 'myg', 'myh', 'myi', 'myj', 'myk', 'myl', 'mym', 'myn', 'myo', 'myp', 'myq', 'myr', 'mys', 'myt', 'myu', 'myv', 'myw', 'myx', 'myy', 'myz', 'mza', 'mzb', 'mzc', 'mzd', 'mze', 'mzg', 'mzh', 'mzi', 'mzj', 'mzk', 'mzl', 'mzm', 'mzn', 'mzo', 'mzp', 'mzq', 'mzr', 'mzs', 'mzt', 'mzu', 'mzv', 'mzw', 'mzx', 'mzy', 'mzz', 'naa', 'nab', 'nac', 'nad', 'nae', 'naf', 'nag', 'nah', 'nai', 'naj', 'nak', 'nal', 'nam', 'nan', 'nao', 'nap', 'naq', 'nar', 'nas', 'nat', 'naw', 'nax', 'nay', 'naz', 'nba', 'nbb', 'nbc', 'nbd', 'nbe', 'nbf', 'nbg', 'nbh', 'nbi', 'nbj', 'nbk', 'nbm', 'nbn', 'nbo', 'nbp', 'nbq', 'nbr', 'nbs', 'nbt', 'nbu', 'nbv', 'nbw', 'nbx', 'nby', 'nca', 'ncb', 'ncc', 'ncd', 'nce', 'ncf', 'ncg', 'nch', 'nci', 'ncj', 'nck', 'ncl', 'ncm', 'ncn', 'nco', 'ncp', 'ncq', 'ncr', 'ncs', 'nct', 'ncu', 'ncx', 'ncz', 'nda', 'ndb', 'ndc', 'ndd', 'ndf', 'ndg', 'ndh', 'ndi', 'ndj', 'ndk', 'ndl', 'ndm', 'ndn', 'ndp', 'ndq', 'ndr', 'nds', 'ndt', 'ndu', 'ndv', 'ndw', 'ndx', 'ndy', 'ndz', 'nea', 'neb', 'nec', 'ned', 'nee', 'nef', 'neg', 'neh', 'nei', 'nej', 'nek', 'nem', 'nen', 'neo', 'neq', 'ner', 'nes', 'net', 'neu', 'nev', 'new', 'nex', 'ney', 'nez', 'nfa', 'nfd', 'nfl', 'nfr', 'nfu', 'nga', 'ngb', 'ngc', 'ngd', 'nge', 'ngf', 'ngg', 'ngh', 'ngi', 'ngj', 'ngk', 'ngl', 'ngm', 'ngn', 'ngo', 'ngp', 'ngq', 'ngr', 'ngs', 'ngt', 'ngu', 'ngv', 'ngw', 'ngx', 'ngy', 'ngz', 'nha', 'nhb', 'nhc', 'nhd', 'nhe', 'nhf', 'nhg', 'nhh', 'nhi', 'nhk', 'nhm', 'nhn', 'nho', 'nhp', 'nhq', 'nhr', 'nht', 'nhu', 'nhv', 'nhw', 'nhx', 'nhy', 'nhz', 'nia', 'nib', 'nic', 'nid', 'nie', 'nif', 'nig', 'nih', 'nii', 'nij', 'nik', 'nil', 'nim', 'nin', 'nio', 'niq', 'nir', 'nis', 'nit', 'niu', 'niv', 'niw', 'nix', 'niy', 'niz', 'nja', 'njb', 'njd', 'njh', 'nji', 'njj', 'njl', 'njm', 'njn', 'njo', 'njr', 'njs', 'njt', 'nju', 'njx', 'njy', 'njz', 'nka', 'nkb', 'nkc', 'nkd', 'nke', 'nkf', 'nkg', 'nkh', 'nki', 'nkj', 'nkk', 'nkm', 'nkn', 'nko', 'nkp', 'nkq', 'nkr', 'nks', 'nkt', 'nku', 'nkv', 'nkw', 'nkx', 'nkz', 'nla', 'nlc', 'nle', 'nlg', 'nli', 'nlj', 'nlk', 'nll', 'nln', 'nlo', 'nlq', 'nlr', 'nlu', 'nlv', 'nlw', 'nlx', 'nly', 'nlz', 'nma', 'nmb', 'nmc', 'nmd', 'nme', 'nmf', 'nmg', 'nmh', 'nmi', 'nmj', 'nmk', 'nml', 'nmm', 'nmn', 'nmo', 'nmp', 'nmq', 'nmr', 'nms', 'nmt', 'nmu', 'nmv', 'nmw', 'nmx', 'nmy', 'nmz', 'nna', 'nnb', 'nnc', 'nnd', 'nne', 'nnf', 'nng', 'nnh', 'nni', 'nnj', 'nnk', 'nnl', 'nnm', 'nnn', 'nnp', 'nnq', 'nnr', 'nns', 'nnt', 'nnu', 'nnv', 'nnw', 'nnx', 'nny', 'nnz', 'noa', 'noc', 'nod', 'noe', 'nof', 'nog', 'noh', 'noi', 'noj', 'nok', 'nol', 'nom', 'non', 'noo', 'nop', 'noq', 'nos', 'not', 'nou', 'nov', 'now', 'noy', 'noz', 'npa', 'npb', 'npg', 'nph', 'npi', 'npl', 'npn', 'npo', 'nps', 'npu', 'npx', 'npy', 'nqg', 'nqk', 'nql', 'nqm', 'nqn', 'nqo', 'nqq', 'nqy', 'nra', 'nrb', 'nrc', 'nre', 'nrf', 'nrg', 'nri', 'nrk', 'nrl', 'nrm', 'nrn', 'nrp', 'nrr', 'nrt', 'nru', 'nrx', 'nrz', 'nsa', 'nsc', 'nsd', 'nse', 'nsf', 'nsg', 'nsh', 'nsi', 'nsk', 'nsl', 'nsm', 'nsn', 'nso', 'nsp', 'nsq', 'nsr', 'nss', 'nst', 'nsu', 'nsv', 'nsw', 'nsx', 'nsy', 'nsz', 'ntd', 'nte', 'ntg', 'nti', 'ntj', 'ntk', 'ntm', 'nto', 'ntp', 'ntr', 'nts', 'ntu', 'ntw', 'ntx', 'nty', 'ntz', 'nua', 'nub', 'nuc', 'nud', 'nue', 'nuf', 'nug', 'nuh', 'nui', 'nuj', 'nuk', 'nul', 'num', 'nun', 'nuo', 'nup', 'nuq', 'nur', 'nus', 'nut', 'nuu', 'nuv', 'nuw', 'nux', 'nuy', 'nuz', 'nvh', 'nvm', 'nvo', 'nwa', 'nwb', 'nwc', 'nwe', 'nwg', 'nwi', 'nwm', 'nwo', 'nwr', 'nwx', 'nwy', 'nxa', 'nxd', 'nxe', 'nxg', 'nxi', 'nxk', 'nxl', 'nxm', 'nxn', 'nxo', 'nxq', 'nxr', 'nxu', 'nxx', 'nyb', 'nyc', 'nyd', 'nye', 'nyf', 'nyg', 'nyh', 'nyi', 'nyj', 'nyk', 'nyl', 'nym', 'nyn', 'nyo', 'nyp', 'nyq', 'nyr', 'nys', 'nyt', 'nyu', 'nyv', 'nyw', 'nyx', 'nyy', 'nza', 'nzb', 'nzi', 'nzk', 'nzm', 'nzs', 'nzu', 'nzy', 'nzz', 'oaa', 'oac', 'oar', 'oav', 'obi', 'obk', 'obl', 'obm', 'obo', 'obr', 'obt', 'obu', 'oca', 'och', 'oco', 'ocu', 'oda', 'odk', 'odt', 'odu', 'ofo', 'ofs', 'ofu', 'ogb', 'ogc', 'oge', 'ogg', 'ogo', 'ogu', 'oht', 'ohu', 'oia', 'oin', 'ojb', 'ojc', 'ojg', 'ojp', 'ojs', 'ojv', 'ojw', 'oka', 'okb', 'okd', 'oke', 'okg', 'okh', 'oki', 'okj', 'okk', 'okl', 'okm', 'okn', 'oko', 'okr', 'oks', 'oku', 'okv', 'okx', 'ola', 'old', 'ole', 'olk', 'olm', 'olo', 'olr', 'olt', 'olu', 'oma', 'omb', 'omc', 'ome', 'omg', 'omi', 'omk', 'oml', 'omn', 'omo', 'omp', 'omq', 'omr', 'omt', 'omu', 'omv', 'omw', 'omx', 'ona', 'onb', 'one', 'ong', 'oni', 'onj', 'onk', 'onn', 'ono', 'onp', 'onr', 'ons', 'ont', 'onu', 'onw', 'onx', 'ood', 'oog', 'oon', 'oor', 'oos', 'opa', 'opk', 'opm', 'opo', 'opt', 'opy', 'ora', 'orc', 'ore', 'org', 'orh', 'orn', 'oro', 'orr', 'ors', 'ort', 'oru', 'orv', 'orw', 'orx', 'ory', 'orz', 'osa', 'osc', 'osi', 'oso', 'osp', 'ost', 'osu', 'osx', 'ota', 'otb', 'otd', 'ote', 'oti', 'otk', 'otl', 'otm', 'otn', 'oto', 'otq', 'otr', 'ots', 'ott', 'otu', 'otw', 'otx', 'oty', 'otz', 'oua', 'oub', 'oue', 'oui', 'oum', 'oun', 'ovd', 'owi', 'owl', 'oyb', 'oyd', 'oym', 'oyy', 'ozm', 'paa', 'pab', 'pac', 'pad', 'pae', 'paf', 'pag', 'pah', 'pai', 'pak', 'pal', 'pam', 'pao', 'pap', 'paq', 'par', 'pas', 'pat', 'pau', 'pav', 'paw', 'pax', 'pay', 'paz', 'pbb', 'pbc', 'pbe', 'pbf', 'pbg', 'pbh', 'pbi', 'pbl', 'pbn', 'pbo', 'pbp', 'pbr', 'pbs', 'pbt', 'pbu', 'pbv', 'pby', 'pbz', 'pca', 'pcb', 'pcc', 'pcd', 'pce', 'pcf', 'pcg', 'pch', 'pci', 'pcj', 'pck', 'pcl', 'pcm', 'pcn', 'pcp', 'pcr', 'pcw', 'pda', 'pdc', 'pdi', 'pdn', 'pdo', 'pdt', 'pdu', 'pea', 'peb', 'ped', 'pee', 'pef', 'peg', 'peh', 'pei', 'pej', 'pek', 'pel', 'pem', 'peo', 'pep', 'peq', 'pes', 'pev', 'pex', 'pey', 'pez', 'pfa', 'pfe', 'pfl', 'pga', 'pgd', 'pgg', 'pgi', 'pgk', 'pgl', 'pgn', 'pgs', 'pgu', 'pgy', 'pgz', 'pha', 'phd', 'phg', 'phh', 'phi', 'phk', 'phl', 'phm', 'phn', 'pho', 'phq', 'phr', 'pht', 'phu', 'phv', 'phw', 'pia', 'pib', 'pic', 'pid', 'pie', 'pif', 'pig', 'pih', 'pii', 'pij', 'pil', 'pim', 'pin', 'pio', 'pip', 'pir', 'pis', 'pit', 'piu', 'piv', 'piw', 'pix', 'piy', 'piz', 'pjt', 'pka', 'pkb', 'pkc', 'pkg', 'pkh', 'pkn', 'pko', 'pkp', 'pkr', 'pks', 'pkt', 'pku', 'pla', 'plb', 'plc', 'pld', 'ple', 'plf', 'plg', 'plh', 'plj', 'plk', 'pll', 'pln', 'plo', 'plp', 'plq', 'plr', 'pls', 'plt', 'plu', 'plv', 'plw', 'ply', 'plz', 'pma', 'pmb', 'pmc', 'pmd', 'pme', 'pmf', 'pmh', 'pmi', 'pmj', 'pmk', 'pml', 'pmm', 'pmn', 'pmo', 'pmq', 'pmr', 'pms', 'pmt', 'pmu', 'pmw', 'pmx', 'pmy', 'pmz', 'pna', 'pnb', 'pnc', 'pne', 'png', 'pnh', 'pni', 'pnj', 'pnk', 'pnl', 'pnm', 'pnn', 'pno', 'pnp', 'pnq', 'pnr', 'pns', 'pnt', 'pnu', 'pnv', 'pnw', 'pnx', 'pny', 'pnz', 'poc', 'pod', 'poe', 'pof', 'pog', 'poh', 'poi', 'pok', 'pom', 'pon', 'poo', 'pop', 'poq', 'pos', 'pot', 'pov', 'pow', 'pox', 'poy', 'poz', 'ppa', 'ppe', 'ppi', 'ppk', 'ppl', 'ppm', 'ppn', 'ppo', 'ppp', 'ppq', 'ppr', 'pps', 'ppt', 'ppu', 'pqa', 'pqe', 'pqm', 'pqw', 'pra', 'prb', 'prc', 'prd', 'pre', 'prf', 'prg', 'prh', 'pri', 'prk', 'prl', 'prm', 'prn', 'pro', 'prp', 'prq', 'prr', 'prs', 'prt', 'pru', 'prw', 'prx', 'pry', 'prz', 'psa', 'psc', 'psd', 'pse', 'psg', 'psh', 'psi', 'psl', 'psm', 'psn', 'pso', 'psp', 'psq', 'psr', 'pss', 'pst', 'psu', 'psw', 'psy', 'pta', 'pth', 'pti', 'ptn', 'pto', 'ptp', 'ptq', 'ptr', 'ptt', 'ptu', 'ptv', 'ptw', 'pty', 'pua', 'pub', 'puc', 'pud', 'pue', 'puf', 'pug', 'pui', 'puj', 'puk', 'pum', 'puo', 'pup', 'puq', 'pur', 'put', 'puu', 'puw', 'pux', 'puy', 'puz', 'pwa', 'pwb', 'pwg', 'pwi', 'pwm', 'pwn', 'pwo', 'pwr', 'pww', 'pxm', 'pye', 'pym', 'pyn', 'pys', 'pyu', 'pyx', 'pyy', 'pzn', 'qaa..qtz', 'qua', 'qub', 'quc', 'qud', 'quf', 'qug', 'quh', 'qui', 'quk', 'qul', 'qum', 'qun', 'qup', 'quq', 'qur', 'qus', 'quv', 'quw', 'qux', 'quy', 'quz', 'qva', 'qvc', 'qve', 'qvh', 'qvi', 'qvj', 'qvl', 'qvm', 'qvn', 'qvo', 'qvp', 'qvs', 'qvw', 'qvy', 'qvz', 'qwa', 'qwc', 'qwe', 'qwh', 'qwm', 'qws', 'qwt', 'qxa', 'qxc', 'qxh', 'qxl', 'qxn', 'qxo', 'qxp', 'qxq', 'qxr', 'qxs', 'qxt', 'qxu', 'qxw', 'qya', 'qyp', 'raa', 'rab', 'rac', 'rad', 'raf', 'rag', 'rah', 'rai', 'raj', 'rak', 'ral', 'ram', 'ran', 'rao', 'rap', 'raq', 'rar', 'ras', 'rat', 'rau', 'rav', 'raw', 'rax', 'ray', 'raz', 'rbb', 'rbk', 'rbl', 'rbp', 'rcf', 'rdb', 'rea', 'reb', 'ree', 'reg', 'rei', 'rej', 'rel', 'rem', 'ren', 'rer', 'res', 'ret', 'rey', 'rga', 'rge', 'rgk', 'rgn', 'rgr', 'rgs', 'rgu', 'rhg', 'rhp', 'ria', 'rie', 'rif', 'ril', 'rim', 'rin', 'rir', 'rit', 'riu', 'rjg', 'rji', 'rjs', 'rka', 'rkb', 'rkh', 'rki', 'rkm', 'rkt', 'rkw', 'rma', 'rmb', 'rmc', 'rmd', 'rme', 'rmf', 'rmg', 'rmh', 'rmi', 'rmk', 'rml', 'rmm', 'rmn', 'rmo', 'rmp', 'rmq', 'rmr', 'rms', 'rmt', 'rmu', 'rmv', 'rmw', 'rmx', 'rmy', 'rmz', 'rna', 'rnd', 'rng', 'rnl', 'rnn', 'rnp', 'rnr', 'rnw', 'roa', 'rob', 'roc', 'rod', 'roe', 'rof', 'rog', 'rol', 'rom', 'roo', 'rop', 'ror', 'rou', 'row', 'rpn', 'rpt', 'rri', 'rro', 'rrt', 'rsb', 'rsi', 'rsl', 'rsm', 'rtc', 'rth', 'rtm', 'rts', 'rtw', 'rub', 'ruc', 'rue', 'ruf', 'rug', 'ruh', 'rui', 'ruk', 'ruo', 'rup', 'ruq', 'rut', 'ruu', 'ruy', 'ruz', 'rwa', 'rwk', 'rwm', 'rwo', 'rwr', 'rxd', 'rxw', 'ryn', 'rys', 'ryu', 'rzh', 'saa', 'sab', 'sac', 'sad', 'sae', 'saf', 'sah', 'sai', 'saj', 'sak', 'sal', 'sam', 'sao', 'sap', 'saq', 'sar', 'sas', 'sat', 'sau', 'sav', 'saw', 'sax', 'say', 'saz', 'sba', 'sbb', 'sbc', 'sbd', 'sbe', 'sbf', 'sbg', 'sbh', 'sbi', 'sbj', 'sbk', 'sbl', 'sbm', 'sbn', 'sbo', 'sbp', 'sbq', 'sbr', 'sbs', 'sbt', 'sbu', 'sbv', 'sbw', 'sbx', 'sby', 'sbz', 'sca', 'scb', 'sce', 'scf', 'scg', 'sch', 'sci', 'sck', 'scl', 'scn', 'sco', 'scp', 'scq', 'scs', 'sct', 'scu', 'scv', 'scw', 'scx', 'sda', 'sdb', 'sdc', 'sde', 'sdf', 'sdg', 'sdh', 'sdj', 'sdk', 'sdl', 'sdm', 'sdn', 'sdo', 'sdp', 'sdr', 'sds', 'sdt', 'sdu', 'sdv', 'sdx', 'sdz', 'sea', 'seb', 'sec', 'sed', 'see', 'sef', 'seg', 'seh', 'sei', 'sej', 'sek', 'sel', 'sem', 'sen', 'seo', 'sep', 'seq', 'ser', 'ses', 'set', 'seu', 'sev', 'sew', 'sey', 'sez', 'sfb', 'sfe', 'sfm', 'sfs', 'sfw', 'sga', 'sgb', 'sgc', 'sgd', 'sge', 'sgg', 'sgh', 'sgi', 'sgj', 'sgk', 'sgl', 'sgm', 'sgn', 'sgo', 'sgp', 'sgr', 'sgs', 'sgt', 'sgu', 'sgw', 'sgx', 'sgy', 'sgz', 'sha', 'shb', 'shc', 'shd', 'she', 'shg', 'shh', 'shi', 'shj', 'shk', 'shl', 'shm', 'shn', 'sho', 'shp', 'shq', 'shr', 'shs', 'sht', 'shu', 'shv', 'shw', 'shx', 'shy', 'shz', 'sia', 'sib', 'sid', 'sie', 'sif', 'sig', 'sih', 'sii', 'sij', 'sik', 'sil', 'sim', 'sio', 'sip', 'siq', 'sir', 'sis', 'sit', 'siu', 'siv', 'siw', 'six', 'siy', 'siz', 'sja', 'sjb', 'sjd', 'sje', 'sjg', 'sjk', 'sjl', 'sjm', 'sjn', 'sjo', 'sjp', 'sjr', 'sjs', 'sjt', 'sju', 'sjw', 'ska', 'skb', 'skc', 'skd', 'ske', 'skf', 'skg', 'skh', 'ski', 'skj', 'skk', 'skm', 'skn', 'sko', 'skp', 'skq', 'skr', 'sks', 'skt', 'sku', 'skv', 'skw', 'skx', 'sky', 'skz', 'sla', 'slc', 'sld', 'sle', 'slf', 'slg', 'slh', 'sli', 'slj', 'sll', 'slm', 'sln', 'slp', 'slq', 'slr', 'sls', 'slt', 'slu', 'slw', 'slx', 'sly', 'slz', 'sma', 'smb', 'smc', 'smd', 'smf', 'smg', 'smh', 'smi', 'smj', 'smk', 'sml', 'smm', 'smn', 'smp', 'smq', 'smr', 'sms', 'smt', 'smu', 'smv', 'smw', 'smx', 'smy', 'smz', 'snb', 'snc', 'sne', 'snf', 'sng', 'snh', 'sni', 'snj', 'snk', 'snl', 'snm', 'snn', 'sno', 'snp', 'snq', 'snr', 'sns', 'snu', 'snv', 'snw', 'snx', 'sny', 'snz', 'soa', 'sob', 'soc', 'sod', 'soe', 'sog', 'soh', 'soi', 'soj', 'sok', 'sol', 'son', 'soo', 'sop', 'soq', 'sor', 'sos', 'sou', 'sov', 'sow', 'sox', 'soy', 'soz', 'spb', 'spc', 'spd', 'spe', 'spg', 'spi', 'spk', 'spl', 'spm', 'spn', 'spo', 'spp', 'spq', 'spr', 'sps', 'spt', 'spu', 'spv', 'spx', 'spy', 'sqa', 'sqh', 'sqj', 'sqk', 'sqm', 'sqn', 'sqo', 'sqq', 'sqr', 'sqs', 'sqt', 'squ', 'sra', 'srb', 'src', 'sre', 'srf', 'srg', 'srh', 'sri', 'srk', 'srl', 'srm', 'srn', 'sro', 'srq', 'srr', 'srs', 'srt', 'sru', 'srv', 'srw', 'srx', 'sry', 'srz', 'ssa', 'ssb', 'ssc', 'ssd', 'sse', 'ssf', 'ssg', 'ssh', 'ssi', 'ssj', 'ssk', 'ssl', 'ssm', 'ssn', 'sso', 'ssp', 'ssq', 'ssr', 'sss', 'sst', 'ssu', 'ssv', 'ssx', 'ssy', 'ssz', 'sta', 'stb', 'std', 'ste', 'stf', 'stg', 'sth', 'sti', 'stj', 'stk', 'stl', 'stm', 'stn', 'sto', 'stp', 'stq', 'str', 'sts', 'stt', 'stu', 'stv', 'stw', 'sty', 'sua', 'sub', 'suc', 'sue', 'sug', 'sui', 'suj', 'suk', 'sul', 'sum', 'suq', 'sur', 'sus', 'sut', 'suv', 'suw', 'sux', 'suy', 'suz', 'sva', 'svb', 'svc', 'sve', 'svk', 'svm', 'svr', 'svs', 'svx', 'swb', 'swc', 'swf', 'swg', 'swh', 'swi', 'swj', 'swk', 'swl', 'swm', 'swn', 'swo', 'swp', 'swq', 'swr', 'sws', 'swt', 'swu', 'swv', 'sww', 'swx', 'swy', 'sxb', 'sxc', 'sxe', 'sxg', 'sxk', 'sxl', 'sxm', 'sxn', 'sxo', 'sxr', 'sxs', 'sxu', 'sxw', 'sya', 'syb', 'syc', 'syd', 'syi', 'syk', 'syl', 'sym', 'syn', 'syo', 'syr', 'sys', 'syw', 'syx', 'syy', 'sza', 'szb', 'szc', 'szd', 'sze', 'szg', 'szl', 'szn', 'szp', 'szs', 'szv', 'szw', 'taa', 'tab', 'tac', 'tad', 'tae', 'taf', 'tag', 'tai', 'taj', 'tak', 'tal', 'tan', 'tao', 'tap', 'taq', 'tar', 'tas', 'tau', 'tav', 'taw', 'tax', 'tay', 'taz', 'tba', 'tbb', 'tbc', 'tbd', 'tbe', 'tbf', 'tbg', 'tbh', 'tbi', 'tbj', 'tbk', 'tbl', 'tbm', 'tbn', 'tbo', 'tbp', 'tbq', 'tbr', 'tbs', 'tbt', 'tbu', 'tbv', 'tbw', 'tbx', 'tby', 'tbz', 'tca', 'tcb', 'tcc', 'tcd', 'tce', 'tcf', 'tcg', 'tch', 'tci', 'tck', 'tcl', 'tcm', 'tcn', 'tco', 'tcp', 'tcq', 'tcs', 'tct', 'tcu', 'tcw', 'tcx', 'tcy', 'tcz', 'tda', 'tdb', 'tdc', 'tdd', 'tde', 'tdf', 'tdg', 'tdh', 'tdi', 'tdj', 'tdk', 'tdl', 'tdm', 'tdn', 'tdo', 'tdq', 'tdr', 'tds', 'tdt', 'tdu', 'tdv', 'tdx', 'tdy', 'tea', 'teb', 'tec', 'ted', 'tee', 'tef', 'teg', 'teh', 'tei', 'tek', 'tem', 'ten', 'teo', 'tep', 'teq', 'ter', 'tes', 'tet', 'teu', 'tev', 'tew', 'tex', 'tey', 'tfi', 'tfn', 'tfo', 'tfr', 'tft', 'tga', 'tgb', 'tgc', 'tgd', 'tge', 'tgf', 'tgg', 'tgh', 'tgi', 'tgj', 'tgn', 'tgo', 'tgp', 'tgq', 'tgr', 'tgs', 'tgt', 'tgu', 'tgv', 'tgw', 'tgx', 'tgy', 'tgz', 'thc', 'thd', 'the', 'thf', 'thh', 'thi', 'thk', 'thl', 'thm', 'thn', 'thp', 'thq', 'thr', 'ths', 'tht', 'thu', 'thv', 'thw', 'thx', 'thy', 'thz', 'tia', 'tic', 'tid', 'tie', 'tif', 'tig', 'tih', 'tii', 'tij', 'tik', 'til', 'tim', 'tin', 'tio', 'tip', 'tiq', 'tis', 'tit', 'tiu', 'tiv', 'tiw', 'tix', 'tiy', 'tiz', 'tja', 'tjg', 'tji', 'tjl', 'tjm', 'tjn', 'tjo', 'tjs', 'tju', 'tjw', 'tka', 'tkb', 'tkd', 'tke', 'tkf', 'tkg', 'tkk', 'tkl', 'tkm', 'tkn', 'tkp', 'tkq', 'tkr', 'tks', 'tkt', 'tku', 'tkv', 'tkw', 'tkx', 'tkz', 'tla', 'tlb', 'tlc', 'tld', 'tlf', 'tlg', 'tlh', 'tli', 'tlj', 'tlk', 'tll', 'tlm', 'tln', 'tlo', 'tlp', 'tlq', 'tlr', 'tls', 'tlt', 'tlu', 'tlv', 'tlw', 'tlx', 'tly', 'tma', 'tmb', 'tmc', 'tmd', 'tme', 'tmf', 'tmg', 'tmh', 'tmi', 'tmj', 'tmk', 'tml', 'tmm', 'tmn', 'tmo', 'tmp', 'tmq', 'tmr', 'tms', 'tmt', 'tmu', 'tmv', 'tmw', 'tmy', 'tmz', 'tna', 'tnb', 'tnc', 'tnd', 'tne', 'tnf', 'tng', 'tnh', 'tni', 'tnk', 'tnl', 'tnm', 'tnn', 'tno', 'tnp', 'tnq', 'tnr', 'tns', 'tnt', 'tnu', 'tnv', 'tnw', 'tnx', 'tny', 'tnz', 'tob', 'toc', 'tod', 'toe', 'tof', 'tog', 'toh', 'toi', 'toj', 'tol', 'tom', 'too', 'top', 'toq', 'tor', 'tos', 'tou', 'tov', 'tow', 'tox', 'toy', 'toz', 'tpa', 'tpc', 'tpe', 'tpf', 'tpg', 'tpi', 'tpj', 'tpk', 'tpl', 'tpm', 'tpn', 'tpo', 'tpp', 'tpq', 'tpr', 'tpt', 'tpu', 'tpv', 'tpw', 'tpx', 'tpy', 'tpz', 'tqb', 'tql', 'tqm', 'tqn', 'tqo', 'tqp', 'tqq', 'tqr', 'tqt', 'tqu', 'tqw', 'tra', 'trb', 'trc', 'trd', 'tre', 'trf', 'trg', 'trh', 'tri', 'trj', 'trk', 'trl', 'trm', 'trn', 'tro', 'trp', 'trq', 'trr', 'trs', 'trt', 'tru', 'trv', 'trw', 'trx', 'try', 'trz', 'tsa', 'tsb', 'tsc', 'tsd', 'tse', 'tsf', 'tsg', 'tsh', 'tsi', 'tsj', 'tsk', 'tsl', 'tsm', 'tsp', 'tsq', 'tsr', 'tss', 'tst', 'tsu', 'tsv', 'tsw', 'tsx', 'tsy', 'tsz', 'tta', 'ttb', 'ttc', 'ttd', 'tte', 'ttf', 'ttg', 'tth', 'tti', 'ttj', 'ttk', 'ttl', 'ttm', 'ttn', 'tto', 'ttp', 'ttq', 'ttr', 'tts', 'ttt', 'ttu', 'ttv', 'ttw', 'tty', 'ttz', 'tua', 'tub', 'tuc', 'tud', 'tue', 'tuf', 'tug', 'tuh', 'tui', 'tuj', 'tul', 'tum', 'tun', 'tuo', 'tup', 'tuq', 'tus', 'tut', 'tuu', 'tuv', 'tuw', 'tux', 'tuy', 'tuz', 'tva', 'tvd', 'tve', 'tvk', 'tvl', 'tvm', 'tvn', 'tvo', 'tvs', 'tvt', 'tvu', 'tvw', 'tvy', 'twa', 'twb', 'twc', 'twd', 'twe', 'twf', 'twg', 'twh', 'twl', 'twm', 'twn', 'two', 'twp', 'twq', 'twr', 'twt', 'twu', 'tww', 'twx', 'twy', 'txa', 'txb', 'txc', 'txe', 'txg', 'txh', 'txi', 'txj', 'txm', 'txn', 'txo', 'txq', 'txr', 'txs', 'txt', 'txu', 'txx', 'txy', 'tya', 'tye', 'tyh', 'tyi', 'tyj', 'tyl', 'tyn', 'typ', 'tyr', 'tys', 'tyt', 'tyu', 'tyv', 'tyx', 'tyz', 'tza', 'tzh', 'tzj', 'tzl', 'tzm', 'tzn', 'tzo', 'tzx', 'uam', 'uan', 'uar', 'uba', 'ubi', 'ubl', 'ubr', 'ubu', 'uby', 'uda', 'ude', 'udg', 'udi', 'udj', 'udl', 'udm', 'udu', 'ues', 'ufi', 'uga', 'ugb', 'uge', 'ugn', 'ugo', 'ugy', 'uha', 'uhn', 'uis', 'uiv', 'uji', 'uka', 'ukg', 'ukh', 'ukk', 'ukl', 'ukp', 'ukq', 'uks', 'uku', 'ukw', 'uky', 'ula', 'ulb', 'ulc', 'ule', 'ulf', 'uli', 'ulk', 'ull', 'ulm', 'uln', 'ulu', 'ulw', 'uma', 'umb', 'umc', 'umd', 'umg', 'umi', 'umm', 'umn', 'umo', 'ump', 'umr', 'ums', 'umu', 'una', 'und', 'une', 'ung', 'unk', 'unm', 'unn', 'unp', 'unr', 'unu', 'unx', 'unz', 'uok', 'upi', 'upv', 'ura', 'urb', 'urc', 'ure', 'urf', 'urg', 'urh', 'uri', 'urj', 'urk', 'url', 'urm', 'urn', 'uro', 'urp', 'urr', 'urt', 'uru', 'urv', 'urw', 'urx', 'ury', 'urz', 'usa', 'ush', 'usi', 'usk', 'usp', 'usu', 'uta', 'ute', 'utp', 'utr', 'utu', 'uum', 'uun', 'uur', 'uuu', 'uve', 'uvh', 'uvl', 'uwa', 'uya', 'uzn', 'uzs', 'vaa', 'vae', 'vaf', 'vag', 'vah', 'vai', 'vaj', 'val', 'vam', 'van', 'vao', 'vap', 'var', 'vas', 'vau', 'vav', 'vay', 'vbb', 'vbk', 'vec', 'ved', 'vel', 'vem', 'veo', 'vep', 'ver', 'vgr', 'vgt', 'vic', 'vid', 'vif', 'vig', 'vil', 'vin', 'vis', 'vit', 'viv', 'vka', 'vki', 'vkj', 'vkk', 'vkl', 'vkm', 'vko', 'vkp', 'vkt', 'vku', 'vlp', 'vls', 'vma', 'vmb', 'vmc', 'vmd', 'vme', 'vmf', 'vmg', 'vmh', 'vmi', 'vmj', 'vmk', 'vml', 'vmm', 'vmp', 'vmq', 'vmr', 'vms', 'vmu', 'vmv', 'vmw', 'vmx', 'vmy', 'vmz', 'vnk', 'vnm', 'vnp', 'vor', 'vot', 'vra', 'vro', 'vrs', 'vrt', 'vsi', 'vsl', 'vsv', 'vto', 'vum', 'vun', 'vut', 'vwa', 'waa', 'wab', 'wac', 'wad', 'wae', 'waf', 'wag', 'wah', 'wai', 'waj', 'wak', 'wal', 'wam', 'wan', 'wao', 'wap', 'waq', 'war', 'was', 'wat', 'wau', 'wav', 'waw', 'wax', 'way', 'waz', 'wba', 'wbb', 'wbe', 'wbf', 'wbh', 'wbi', 'wbj', 'wbk', 'wbl', 'wbm', 'wbp', 'wbq', 'wbr', 'wbs', 'wbt', 'wbv', 'wbw', 'wca', 'wci', 'wdd', 'wdg', 'wdj', 'wdk', 'wdu', 'wdy', 'wea', 'wec', 'wed', 'weg', 'weh', 'wei', 'wem', 'wen', 'weo', 'wep', 'wer', 'wes', 'wet', 'weu', 'wew', 'wfg', 'wga', 'wgb', 'wgg', 'wgi', 'wgo', 'wgu', 'wgw', 'wgy', 'wha', 'whg', 'whk', 'whu', 'wib', 'wic', 'wie', 'wif', 'wig', 'wih', 'wii', 'wij', 'wik', 'wil', 'wim', 'win', 'wir', 'wit', 'wiu', 'wiv', 'wiw', 'wiy', 'wja', 'wji', 'wka', 'wkb', 'wkd', 'wkl', 'wku', 'wkw', 'wky', 'wla', 'wlc', 'wle', 'wlg', 'wli', 'wlk', 'wll', 'wlm', 'wlo', 'wlr', 'wls', 'wlu', 'wlv', 'wlw', 'wlx', 'wly', 'wma', 'wmb', 'wmc', 'wmd', 'wme', 'wmh', 'wmi', 'wmm', 'wmn', 'wmo', 'wms', 'wmt', 'wmw', 'wmx', 'wnb', 'wnc', 'wnd', 'wne', 'wng', 'wni', 'wnk', 'wnm', 'wnn', 'wno', 'wnp', 'wnu', 'wnw', 'wny', 'woa', 'wob', 'woc', 'wod', 'woe', 'wof', 'wog', 'woi', 'wok', 'wom', 'won', 'woo', 'wor', 'wos', 'wow', 'woy', 'wpc', 'wra', 'wrb', 'wrd', 'wrg', 'wrh', 'wri', 'wrk', 'wrl', 'wrm', 'wrn', 'wro', 'wrp', 'wrr', 'wrs', 'wru', 'wrv', 'wrw', 'wrx', 'wry', 'wrz', 'wsa', 'wsg', 'wsi', 'wsk', 'wsr', 'wss', 'wsu', 'wsv', 'wtf', 'wth', 'wti', 'wtk', 'wtm', 'wtw', 'wua', 'wub', 'wud', 'wuh', 'wul', 'wum', 'wun', 'wur', 'wut', 'wuu', 'wuv', 'wux', 'wuy', 'wwa', 'wwb', 'wwo', 'wwr', 'www', 'wxa', 'wxw', 'wya', 'wyb', 'wyi', 'wym', 'wyr', 'wyy', 'xaa', 'xab', 'xac', 'xad', 'xae', 'xag', 'xai', 'xaj', 'xak', 'xal', 'xam', 'xan', 'xao', 'xap', 'xaq', 'xar', 'xas', 'xat', 'xau', 'xav', 'xaw', 'xay', 'xba', 'xbb', 'xbc', 'xbd', 'xbe', 'xbg', 'xbi', 'xbj', 'xbm', 'xbn', 'xbo', 'xbp', 'xbr', 'xbw', 'xbx', 'xby', 'xcb', 'xcc', 'xce', 'xcg', 'xch', 'xcl', 'xcm', 'xcn', 'xco', 'xcr', 'xct', 'xcu', 'xcv', 'xcw', 'xcy', 'xda', 'xdc', 'xdk', 'xdm', 'xdo', 'xdy', 'xeb', 'xed', 'xeg', 'xel', 'xem', 'xep', 'xer', 'xes', 'xet', 'xeu', 'xfa', 'xga', 'xgb', 'xgd', 'xgf', 'xgg', 'xgi', 'xgl', 'xgm', 'xgn', 'xgr', 'xgu', 'xgw', 'xha', 'xhc', 'xhd', 'xhe', 'xhr', 'xht', 'xhu', 'xhv', 'xia', 'xib', 'xii', 'xil', 'xin', 'xip', 'xir', 'xis', 'xiv', 'xiy', 'xjb', 'xjt', 'xka', 'xkb', 'xkc', 'xkd', 'xke', 'xkf', 'xkg', 'xkh', 'xki', 'xkj', 'xkk', 'xkl', 'xkn', 'xko', 'xkp', 'xkq', 'xkr', 'xks', 'xkt', 'xku', 'xkv', 'xkw', 'xkx', 'xky', 'xkz', 'xla', 'xlb', 'xlc', 'xld', 'xle', 'xlg', 'xli', 'xln', 'xlo', 'xlp', 'xls', 'xlu', 'xly', 'xma', 'xmb', 'xmc', 'xmd', 'xme', 'xmf', 'xmg', 'xmh', 'xmj', 'xmk', 'xml', 'xmm', 'xmn', 'xmo', 'xmp', 'xmq', 'xmr', 'xms', 'xmt', 'xmu', 'xmv', 'xmw', 'xmx', 'xmy', 'xmz', 'xna', 'xnb', 'xnd', 'xng', 'xnh', 'xni', 'xnk', 'xnn', 'xno', 'xnr', 'xns', 'xnt', 'xnu', 'xny', 'xnz', 'xoc', 'xod', 'xog', 'xoi', 'xok', 'xom', 'xon', 'xoo', 'xop', 'xor', 'xow', 'xpa', 'xpc', 'xpe', 'xpg', 'xpi', 'xpj', 'xpk', 'xpm', 'xpn', 'xpo', 'xpp', 'xpq', 'xpr', 'xps', 'xpt', 'xpu', 'xpy', 'xqa', 'xqt', 'xra', 'xrb', 'xrd', 'xre', 'xrg', 'xri', 'xrm', 'xrn', 'xrq', 'xrr', 'xrt', 'xru', 'xrw', 'xsa', 'xsb', 'xsc', 'xsd', 'xse', 'xsh', 'xsi', 'xsj', 'xsl', 'xsm', 'xsn', 'xso', 'xsp', 'xsq', 'xsr', 'xss', 'xsu', 'xsv', 'xsy', 'xta', 'xtb', 'xtc', 'xtd', 'xte', 'xtg', 'xth', 'xti', 'xtj', 'xtl', 'xtm', 'xtn', 'xto', 'xtp', 'xtq', 'xtr', 'xts', 'xtt', 'xtu', 'xtv', 'xtw', 'xty', 'xtz', 'xua', 'xub', 'xud', 'xug', 'xuj', 'xul', 'xum', 'xun', 'xuo', 'xup', 'xur', 'xut', 'xuu', 'xve', 'xvi', 'xvn', 'xvo', 'xvs', 'xwa', 'xwc', 'xwd', 'xwe', 'xwg', 'xwj', 'xwk', 'xwl', 'xwo', 'xwr', 'xwt', 'xww', 'xxb', 'xxk', 'xxm', 'xxr', 'xxt', 'xya', 'xyb', 'xyj', 'xyk', 'xyl', 'xyt', 'xyy', 'xzh', 'xzm', 'xzp', 'yaa', 'yab', 'yac', 'yad', 'yae', 'yaf', 'yag', 'yah', 'yai', 'yaj', 'yak', 'yal', 'yam', 'yan', 'yao', 'yap', 'yaq', 'yar', 'yas', 'yat', 'yau', 'yav', 'yaw', 'yax', 'yay', 'yaz', 'yba', 'ybb', 'ybd', 'ybe', 'ybh', 'ybi', 'ybj', 'ybk', 'ybl', 'ybm', 'ybn', 'ybo', 'ybx', 'yby', 'ych', 'ycl', 'ycn', 'ycp', 'yda', 'ydd', 'yde', 'ydg', 'ydk', 'yds', 'yea', 'yec', 'yee', 'yei', 'yej', 'yel', 'yen', 'yer', 'yes', 'yet', 'yeu', 'yev', 'yey', 'yga', 'ygi', 'ygl', 'ygm', 'ygp', 'ygr', 'ygs', 'ygu', 'ygw', 'yha', 'yhd', 'yhl', 'yhs', 'yia', 'yif', 'yig', 'yih', 'yii', 'yij', 'yik', 'yil', 'yim', 'yin', 'yip', 'yiq', 'yir', 'yis', 'yit', 'yiu', 'yiv', 'yix', 'yiy', 'yiz', 'yka', 'ykg', 'yki', 'ykk', 'ykl', 'ykm', 'ykn', 'yko', 'ykr', 'ykt', 'yku', 'yky', 'yla', 'ylb', 'yle', 'ylg', 'yli', 'yll', 'ylm', 'yln', 'ylo', 'ylr', 'ylu', 'yly', 'yma', 'ymb', 'ymc', 'ymd', 'yme', 'ymg', 'ymh', 'ymi', 'ymk', 'yml', 'ymm', 'ymn', 'ymo', 'ymp', 'ymq', 'ymr', 'yms', 'ymt', 'ymx', 'ymz', 'yna', 'ynd', 'yne', 'yng', 'ynh', 'ynk', 'ynl', 'ynn', 'yno', 'ynq', 'yns', 'ynu', 'yob', 'yog', 'yoi', 'yok', 'yol', 'yom', 'yon', 'yos', 'yot', 'yox', 'yoy', 'ypa', 'ypb', 'ypg', 'yph', 'ypk', 'ypm', 'ypn', 'ypo', 'ypp', 'ypz', 'yra', 'yrb', 'yre', 'yri', 'yrk', 'yrl', 'yrm', 'yrn', 'yro', 'yrs', 'yrw', 'yry', 'ysc', 'ysd', 'ysg', 'ysl', 'ysn', 'yso', 'ysp', 'ysr', 'yss', 'ysy', 'yta', 'ytl', 'ytp', 'ytw', 'yty', 'yua', 'yub', 'yuc', 'yud', 'yue', 'yuf', 'yug', 'yui', 'yuj', 'yuk', 'yul', 'yum', 'yun', 'yup', 'yuq', 'yur', 'yut', 'yuu', 'yuw', 'yux', 'yuy', 'yuz', 'yva', 'yvt', 'ywa', 'ywg', 'ywl', 'ywn', 'ywq', 'ywr', 'ywt', 'ywu', 'yww', 'yxa', 'yxg', 'yxl', 'yxm', 'yxu', 'yxy', 'yyr', 'yyu', 'yyz', 'yzg', 'yzk', 'zaa', 'zab', 'zac', 'zad', 'zae', 'zaf', 'zag', 'zah', 'zai', 'zaj', 'zak', 'zal', 'zam', 'zao', 'zap', 'zaq', 'zar', 'zas', 'zat', 'zau', 'zav', 'zaw', 'zax', 'zay', 'zaz', 'zbc', 'zbe', 'zbl', 'zbt', 'zbw', 'zca', 'zch', 'zdj', 'zea', 'zeg', 'zeh', 'zen', 'zga', 'zgb', 'zgh', 'zgm', 'zgn', 'zgr', 'zhb', 'zhd', 'zhi', 'zhn', 'zhw', 'zhx', 'zia', 'zib', 'zik', 'zil', 'zim', 'zin', 'zir', 'ziw', 'ziz', 'zka', 'zkb', 'zkd', 'zkg', 'zkh', 'zkk', 'zkn', 'zko', 'zkp', 'zkr', 'zkt', 'zku', 'zkv', 'zkz', 'zle', 'zlj', 'zlm', 'zln', 'zlq', 'zls', 'zlw', 'zma', 'zmb', 'zmc', 'zmd', 'zme', 'zmf', 'zmg', 'zmh', 'zmi', 'zmj', 'zmk', 'zml', 'zmm', 'zmn', 'zmo', 'zmp', 'zmq', 'zmr', 'zms', 'zmt', 'zmu', 'zmv', 'zmw', 'zmx', 'zmy', 'zmz', 'zna', 'znd', 'zne', 'zng', 'znk', 'zns', 'zoc', 'zoh', 'zom', 'zoo', 'zoq', 'zor', 'zos', 'zpa', 'zpb', 'zpc', 'zpd', 'zpe', 'zpf', 'zpg', 'zph', 'zpi', 'zpj', 'zpk', 'zpl', 'zpm', 'zpn', 'zpo', 'zpp', 'zpq', 'zpr', 'zps', 'zpt', 'zpu', 'zpv', 'zpw', 'zpx', 'zpy', 'zpz', 'zqe', 'zra', 'zrg', 'zrn', 'zro', 'zrp', 'zrs', 'zsa', 'zsk', 'zsl', 'zsm', 'zsr', 'zsu', 'zte', 'ztg', 'ztl', 'ztm', 'ztn', 'ztp', 'ztq', 'zts', 'ztt', 'ztu', 'ztx', 'zty', 'zua', 'zuh', 'zum', 'zun', 'zuy', 'zwa', 'zxx', 'zyb', 'zyg', 'zyj', 'zyn', 'zyp', 'zza', 'zzj' ]; + axe.utils.validLangs = function() { + 'use strict'; + return langs; }; return commons; }()
diff --git a/third_party/axe-core/axe.min.js b/third_party/axe-core/axe.min.js index 91b00bf..a06be242 100644 --- a/third_party/axe-core/axe.min.js +++ b/third_party/axe-core/axe.min.js
@@ -1,5 +1,5 @@ -/*! axe v3.3.2 - * Copyright (c) 2019 Deque Systems, Inc. +/*! aXe v3.0.0-alpha-1 + * Copyright (c) 2017 Deque Systems, Inc. * * Your use of this Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -9,4 +9,34 @@ * distribute or in any file that contains substantial portions of this source * code. */ -!function e(window){var a=window,document=window.document;function S(e){return(S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function l(e){this.name="SupportError",this.cause=e.cause,this.message="`".concat(e.cause,"` - feature unsupported in your environment."),e.ruleId&&(this.ruleId=e.ruleId,this.message+=" Skipping ".concat(this.ruleId," rule.")),this.stack=(new Error).stack}(axe=axe||{}).version="3.3.2","function"==typeof define&&define.amd&&define("axe-core",[],function(){"use strict";return axe}),"object"===("undefined"==typeof module?"undefined":S(module))&&module.exports&&"function"==typeof e.toString&&(axe.source="("+e.toString()+')(typeof window === "object" ? window : this);',module.exports=axe),"function"==typeof window.getComputedStyle&&(window.axe=axe),(l.prototype=Object.create(Error.prototype)).constructor=l,function o(i,u,s){function l(t,e){if(!u[t]){if(!i[t]){var n="function"==typeof require&&require;if(!e&&n)return n(t,!0);if(c)return c(t,!0);var r=new Error("Cannot find module '"+t+"'");throw r.code="MODULE_NOT_FOUND",r}var a=u[t]={exports:{}};i[t][0].call(a.exports,function(e){return l(i[t][1][e]||e)},a,a.exports,o,i,u,s)}return u[t].exports}for(var c="function"==typeof require&&require,e=0;e<s.length;e++)l(s[e]);return l}({1:[function(e,t,n){"Promise"in window||e("es6-promise").polyfill(),e("weakmap-polyfill"),axe.imports={axios:e("axios"),CssSelectorParser:e("css-selector-parser").CssSelectorParser,doT:e("@deque/dot"),emojiRegexText:e("emoji-regex")}},{"@deque/dot":2,axios:3,"css-selector-parser":29,"emoji-regex":31,"es6-promise":32,"weakmap-polyfill":34}],2:[function(e,t,n){!function(){"use strict";var s={name:"doT",version:"1.1.1",templateSettings:{evaluate:/\{\{([\s\S]+?(\}?)+)\}\}/g,interpolate:/\{\{=([\s\S]+?)\}\}/g,encode:/\{\{!([\s\S]+?)\}\}/g,use:/\{\{#([\s\S]+?)\}\}/g,useParams:/(^|[^\w$])def(?:\.|\[[\'\"])([\w$\.]+)(?:[\'\"]\])?\s*\:\s*([\w$\.]+|\"[^\"]+\"|\'[^\']+\'|\{[^\}]+\})/g,define:/\{\{##\s*([\w\.$]+)\s*(\:|=)([\s\S]+?)#\}\}/g,defineParams:/^\s*([\w$]+):([\s\S]+)/,conditional:/\{\{\?(\?)?\s*([\s\S]*?)\s*\}\}/g,iterate:/\{\{~\s*(?:\}\}|([\s\S]+?)\s*\:\s*([\w$]+)\s*(?:\:\s*([\w$]+))?\s*\}\})/g,varname:"it",strip:!0,append:!0,selfcontained:!1,doNotSkipEncoded:!1},template:void 0,compile:void 0,log:!0};"object"!=typeof globalThis&&(Object.defineProperty(Object.prototype,"__magic__",{get:function(){return this},configurable:!0}),__magic__.globalThis=__magic__,delete Object.prototype.__magic__),s.encodeHTMLSource=function(e){var t={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},n=e?/[&<>"'\/]/g:/&(?!#?\w+;)|<|>|"|'|\//g;return function(e){return e?e.toString().replace(n,function(e){return t[e]||e}):""}},void 0!==t&&t.exports?t.exports=s:"function"==typeof define&&define.amd?define(function(){return s}):globalThis.doT=s;var l={append:{start:"'+(",end:")+'",startencode:"'+encodeHTML("},split:{start:"';out+=(",end:");out+='",startencode:"';out+=encodeHTML("}},c=/$^/;function d(e){return e.replace(/\\('|\\)/g,"$1").replace(/[\r\t\n]/g," ")}s.template=function(e,t,n){var r,a,o=(t=t||s.templateSettings).append?l.append:l.split,i=0,u=t.use||t.define?function r(a,e,o){return("string"==typeof e?e:e.toString()).replace(a.define||c,function(e,r,t,n){return 0===r.indexOf("def.")&&(r=r.substring(4)),r in o||(":"===t?(a.defineParams&&n.replace(a.defineParams,function(e,t,n){o[r]={arg:t,text:n}}),r in o||(o[r]=n)):new Function("def","def['"+r+"']="+n)(o)),""}).replace(a.use||c,function(e,t){a.useParams&&(t=t.replace(a.useParams,function(e,t,n,r){if(o[n]&&o[n].arg&&r){var a=(n+":"+r).replace(/'|\\/g,"_");return o.__exp=o.__exp||{},o.__exp[a]=o[n].text.replace(new RegExp("(^|[^\\w$])"+o[n].arg+"([^\\w$])","g"),"$1"+r+"$2"),t+"def.__exp['"+a+"']"}}));var n=new Function("def","return "+t)(o);return n?r(a,n,o):n})}(t,e,n||{}):e;u=("var out='"+(t.strip?u.replace(/(^|\r|\n)\t* +| +\t*(\r|\n|$)/g," ").replace(/\r|\n|\t|\/\*[\s\S]*?\*\//g,""):u).replace(/'|\\/g,"\\$&").replace(t.interpolate||c,function(e,t){return o.start+d(t)+o.end}).replace(t.encode||c,function(e,t){return r=!0,o.startencode+d(t)+o.end}).replace(t.conditional||c,function(e,t,n){return t?n?"';}else if("+d(n)+"){out+='":"';}else{out+='":n?"';if("+d(n)+"){out+='":"';}out+='"}).replace(t.iterate||c,function(e,t,n,r){return t?(i+=1,a=r||"i"+i,t=d(t),"';var arr"+i+"="+t+";if(arr"+i+"){var "+n+","+a+"=-1,l"+i+"=arr"+i+".length-1;while("+a+"<l"+i+"){"+n+"=arr"+i+"["+a+"+=1];out+='"):"';} } out+='"}).replace(t.evaluate||c,function(e,t){return"';"+d(t)+"out+='"})+"';return out;").replace(/\n/g,"\\n").replace(/\t/g,"\\t").replace(/\r/g,"\\r").replace(/(\s|;|\}|^|\{)out\+='';/g,"$1").replace(/\+''/g,""),r&&(t.selfcontained||!globalThis||globalThis._encodeHTML||(globalThis._encodeHTML=s.encodeHTMLSource(t.doNotSkipEncoded)),u="var encodeHTML = typeof _encodeHTML !== 'undefined' ? _encodeHTML : ("+s.encodeHTMLSource.toString()+"("+(t.doNotSkipEncoded||"")+"));"+u);try{return new Function(t.varname,u)}catch(e){throw"undefined"!=typeof console&&console.log("Could not create a template function: "+u),e}},s.compile=function(e,t){return s.template(e,null,t)}}()},{}],3:[function(e,t,n){t.exports=e("./lib/axios")},{"./lib/axios":5}],4:[function(c,e,t){"use strict";var utils=c("./../utils"),d=c("./../core/settle"),m=c("./../helpers/buildURL"),p=c("./../helpers/parseHeaders"),f=c("./../helpers/isURLSameOrigin"),h=c("../core/createError");e.exports=function(l){return new Promise(function(n,r){var a=l.data,o=l.headers;utils.isFormData(a)&&delete o["Content-Type"];var i=new XMLHttpRequest;if(l.auth){var e=l.auth.username||"",t=l.auth.password||"";o.Authorization="Basic "+btoa(e+":"+t)}if(i.open(l.method.toUpperCase(),m(l.url,l.params,l.paramsSerializer),!0),i.timeout=l.timeout,i.onreadystatechange=function(){if(i&&4===i.readyState&&(0!==i.status||i.responseURL&&0===i.responseURL.indexOf("file:"))){var e="getAllResponseHeaders"in i?p(i.getAllResponseHeaders()):null,t={data:l.responseType&&"text"!==l.responseType?i.response:i.responseText,status:i.status,statusText:i.statusText,headers:e,config:l,request:i};d(n,r,t),i=null}},i.onabort=function(){i&&(r(h("Request aborted",l,"ECONNABORTED",i)),i=null)},i.onerror=function(){r(h("Network Error",l,null,i)),i=null},i.ontimeout=function(){r(h("timeout of "+l.timeout+"ms exceeded",l,"ECONNABORTED",i)),i=null},utils.isStandardBrowserEnv()){var u=c("./../helpers/cookies"),s=(l.withCredentials||f(l.url))&&l.xsrfCookieName?u.read(l.xsrfCookieName):void 0;s&&(o[l.xsrfHeaderName]=s)}if("setRequestHeader"in i&&utils.forEach(o,function(e,t){void 0===a&&"content-type"===t.toLowerCase()?delete o[t]:i.setRequestHeader(t,e)}),l.withCredentials&&(i.withCredentials=!0),l.responseType)try{i.responseType=l.responseType}catch(e){if("json"!==l.responseType)throw e}"function"==typeof l.onDownloadProgress&&i.addEventListener("progress",l.onDownloadProgress),"function"==typeof l.onUploadProgress&&i.upload&&i.upload.addEventListener("progress",l.onUploadProgress),l.cancelToken&&l.cancelToken.promise.then(function(e){i&&(i.abort(),r(e),i=null)}),void 0===a&&(a=null),i.send(a)})}},{"../core/createError":11,"./../core/settle":15,"./../helpers/buildURL":19,"./../helpers/cookies":21,"./../helpers/isURLSameOrigin":23,"./../helpers/parseHeaders":25,"./../utils":27}],5:[function(e,t,n){"use strict";var utils=e("./utils"),r=e("./helpers/bind"),a=e("./core/Axios"),o=e("./core/mergeConfig");function i(e){var t=new a(e),n=r(a.prototype.request,t);return utils.extend(n,a.prototype,t),utils.extend(n,t),n}var u=i(e("./defaults"));u.Axios=a,u.create=function(e){return i(o(u.defaults,e))},u.Cancel=e("./cancel/Cancel"),u.CancelToken=e("./cancel/CancelToken"),u.isCancel=e("./cancel/isCancel"),u.all=function(e){return Promise.all(e)},u.spread=e("./helpers/spread"),t.exports=u,t.exports.default=u},{"./cancel/Cancel":6,"./cancel/CancelToken":7,"./cancel/isCancel":8,"./core/Axios":9,"./core/mergeConfig":14,"./defaults":17,"./helpers/bind":18,"./helpers/spread":26,"./utils":27}],6:[function(e,t,n){"use strict";function r(e){this.message=e}r.prototype.toString=function(){return"Cancel"+(this.message?": "+this.message:"")},r.prototype.__CANCEL__=!0,t.exports=r},{}],7:[function(e,t,n){"use strict";var r=e("./Cancel");function a(e){if("function"!=typeof e)throw new TypeError("executor must be a function.");var t;this.promise=new Promise(function(e){t=e});var n=this;e(function(e){n.reason||(n.reason=new r(e),t(n.reason))})}a.prototype.throwIfRequested=function(){if(this.reason)throw this.reason},a.source=function(){var t;return{token:new a(function(e){t=e}),cancel:t}},t.exports=a},{"./Cancel":6}],8:[function(e,t,n){"use strict";t.exports=function(e){return!(!e||!e.__CANCEL__)}},{}],9:[function(e,t,n){"use strict";var utils=e("./../utils"),r=e("../helpers/buildURL"),a=e("./InterceptorManager"),o=e("./dispatchRequest"),i=e("./mergeConfig");function u(e){this.defaults=e,this.interceptors={request:new a,response:new a}}u.prototype.request=function(e,t){"string"==typeof e?(e=t||{}).url=arguments[0]:e=e||{},(e=i(this.defaults,e)).method=e.method?e.method.toLowerCase():"get";var n=[o,void 0],r=Promise.resolve(e);for(this.interceptors.request.forEach(function(e){n.unshift(e.fulfilled,e.rejected)}),this.interceptors.response.forEach(function(e){n.push(e.fulfilled,e.rejected)});n.length;)r=r.then(n.shift(),n.shift());return r},u.prototype.getUri=function(e){return e=i(this.defaults,e),r(e.url,e.params,e.paramsSerializer).replace(/^\?/,"")},utils.forEach(["delete","get","head","options"],function(n){u.prototype[n]=function(e,t){return this.request(utils.merge(t||{},{method:n,url:e}))}}),utils.forEach(["post","put","patch"],function(r){u.prototype[r]=function(e,t,n){return this.request(utils.merge(n||{},{method:r,url:e,data:t}))}}),t.exports=u},{"../helpers/buildURL":19,"./../utils":27,"./InterceptorManager":10,"./dispatchRequest":12,"./mergeConfig":14}],10:[function(e,t,n){"use strict";var utils=e("./../utils");function r(){this.handlers=[]}r.prototype.use=function(e,t){return this.handlers.push({fulfilled:e,rejected:t}),this.handlers.length-1},r.prototype.eject=function(e){this.handlers[e]&&(this.handlers[e]=null)},r.prototype.forEach=function(t){utils.forEach(this.handlers,function(e){null!==e&&t(e)})},t.exports=r},{"./../utils":27}],11:[function(e,t,n){"use strict";var i=e("./enhanceError");t.exports=function(e,t,n,r,a){var o=new Error(e);return i(o,t,n,r,a)}},{"./enhanceError":13}],12:[function(e,t,n){"use strict";var utils=e("./../utils"),r=e("./transformData"),a=e("../cancel/isCancel"),o=e("../defaults"),i=e("./../helpers/isAbsoluteURL"),u=e("./../helpers/combineURLs");function s(e){e.cancelToken&&e.cancelToken.throwIfRequested()}t.exports=function(t){return s(t),t.baseURL&&!i(t.url)&&(t.url=u(t.baseURL,t.url)),t.headers=t.headers||{},t.data=r(t.data,t.headers,t.transformRequest),t.headers=utils.merge(t.headers.common||{},t.headers[t.method]||{},t.headers||{}),utils.forEach(["delete","get","head","post","put","patch","common"],function(e){delete t.headers[e]}),(t.adapter||o.adapter)(t).then(function(e){return s(t),e.data=r(e.data,e.headers,t.transformResponse),e},function(e){return a(e)||(s(t),e&&e.response&&(e.response.data=r(e.response.data,e.response.headers,t.transformResponse))),Promise.reject(e)})}},{"../cancel/isCancel":8,"../defaults":17,"./../helpers/combineURLs":20,"./../helpers/isAbsoluteURL":22,"./../utils":27,"./transformData":16}],13:[function(e,t,n){"use strict";t.exports=function(e,t,n,r,a){return e.config=t,n&&(e.code=n),e.request=r,e.response=a,e.isAxiosError=!0,e.toJSON=function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:this.config,code:this.code}},e}},{}],14:[function(e,t,n){"use strict";var utils=e("../utils");t.exports=function(t,n){n=n||{};var r={};return utils.forEach(["url","method","params","data"],function(e){void 0!==n[e]&&(r[e]=n[e])}),utils.forEach(["headers","auth","proxy"],function(e){utils.isObject(n[e])?r[e]=utils.deepMerge(t[e],n[e]):void 0!==n[e]?r[e]=n[e]:utils.isObject(t[e])?r[e]=utils.deepMerge(t[e]):void 0!==t[e]&&(r[e]=t[e])}),utils.forEach(["baseURL","transformRequest","transformResponse","paramsSerializer","timeout","withCredentials","adapter","responseType","xsrfCookieName","xsrfHeaderName","onUploadProgress","onDownloadProgress","maxContentLength","validateStatus","maxRedirects","httpAgent","httpsAgent","cancelToken","socketPath"],function(e){void 0!==n[e]?r[e]=n[e]:void 0!==t[e]&&(r[e]=t[e])}),r}},{"../utils":27}],15:[function(e,t,n){"use strict";var a=e("./createError");t.exports=function(e,t,n){var r=n.config.validateStatus;!r||r(n.status)?e(n):t(a("Request failed with status code "+n.status,n.config,null,n.request,n))}},{"./createError":11}],16:[function(e,t,n){"use strict";var utils=e("./../utils");t.exports=function(t,n,e){return utils.forEach(e,function(e){t=e(t,n)}),t}},{"./../utils":27}],17:[function(i,u,e){(function(e){"use strict";var utils=i("./utils"),n=i("./helpers/normalizeHeaderName"),t={"Content-Type":"application/x-www-form-urlencoded"};function r(e,t){!utils.isUndefined(e)&&utils.isUndefined(e["Content-Type"])&&(e["Content-Type"]=t)}var a,o={adapter:(void 0!==e&&"[object process]"===Object.prototype.toString.call(e)?a=i("./adapters/http"):"undefined"!=typeof XMLHttpRequest&&(a=i("./adapters/xhr")),a),transformRequest:[function(e,t){return n(t,"Accept"),n(t,"Content-Type"),utils.isFormData(e)||utils.isArrayBuffer(e)||utils.isBuffer(e)||utils.isStream(e)||utils.isFile(e)||utils.isBlob(e)?e:utils.isArrayBufferView(e)?e.buffer:utils.isURLSearchParams(e)?(r(t,"application/x-www-form-urlencoded;charset=utf-8"),e.toString()):utils.isObject(e)?(r(t,"application/json;charset=utf-8"),JSON.stringify(e)):e}],transformResponse:[function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(e){}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,validateStatus:function(e){return 200<=e&&e<300}};o.headers={common:{Accept:"application/json, text/plain, */*"}},utils.forEach(["delete","get","head"],function(e){o.headers[e]={}}),utils.forEach(["post","put","patch"],function(e){o.headers[e]=utils.merge(t)}),u.exports=o}).call(this,i("_process"))},{"./adapters/http":4,"./adapters/xhr":4,"./helpers/normalizeHeaderName":24,"./utils":27,_process:33}],18:[function(e,t,n){"use strict";t.exports=function(n,r){return function(){for(var e=new Array(arguments.length),t=0;t<e.length;t++)e[t]=arguments[t];return n.apply(r,e)}}},{}],19:[function(e,t,n){"use strict";var utils=e("./../utils");function i(e){return encodeURIComponent(e).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}t.exports=function(e,t,n){if(!t)return e;var r;if(n)r=n(t);else if(utils.isURLSearchParams(t))r=t.toString();else{var a=[];utils.forEach(t,function(e,t){null!=e&&(utils.isArray(e)?t+="[]":e=[e],utils.forEach(e,function(e){utils.isDate(e)?e=e.toISOString():utils.isObject(e)&&(e=JSON.stringify(e)),a.push(i(t)+"="+i(e))}))}),r=a.join("&")}if(r){var o=e.indexOf("#");-1!==o&&(e=e.slice(0,o)),e+=(-1===e.indexOf("?")?"?":"&")+r}return e}},{"./../utils":27}],20:[function(e,t,n){"use strict";t.exports=function(e,t){return t?e.replace(/\/+$/,"")+"/"+t.replace(/^\/+/,""):e}},{}],21:[function(e,t,n){"use strict";var utils=e("./../utils");t.exports=utils.isStandardBrowserEnv()?{write:function(e,t,n,r,a,o){var i=[];i.push(e+"="+encodeURIComponent(t)),utils.isNumber(n)&&i.push("expires="+new Date(n).toGMTString()),utils.isString(r)&&i.push("path="+r),utils.isString(a)&&i.push("domain="+a),!0===o&&i.push("secure"),document.cookie=i.join("; ")},read:function(e){var t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove:function(e){this.write(e,"",Date.now()-864e5)}}:{write:function(){},read:function(){return null},remove:function(){}}},{"./../utils":27}],22:[function(e,t,n){"use strict";t.exports=function(e){return/^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(e)}},{}],23:[function(e,t,n){"use strict";var r,a,o,utils=e("./../utils");function i(e){var t=e;return a&&(o.setAttribute("href",t),t=o.href),o.setAttribute("href",t),{href:o.href,protocol:o.protocol?o.protocol.replace(/:$/,""):"",host:o.host,search:o.search?o.search.replace(/^\?/,""):"",hash:o.hash?o.hash.replace(/^#/,""):"",hostname:o.hostname,port:o.port,pathname:"/"===o.pathname.charAt(0)?o.pathname:"/"+o.pathname}}t.exports=utils.isStandardBrowserEnv()?(a=/(msie|trident)/i.test(navigator.userAgent),o=document.createElement("a"),r=i(window.location.href),function(e){var t=utils.isString(e)?i(e):e;return t.protocol===r.protocol&&t.host===r.host}):function(){return!0}},{"./../utils":27}],24:[function(e,t,n){"use strict";var utils=e("../utils");t.exports=function(n,r){utils.forEach(n,function(e,t){t!==r&&t.toUpperCase()===r.toUpperCase()&&(n[r]=e,delete n[t])})}},{"../utils":27}],25:[function(e,t,n){"use strict";var utils=e("./../utils"),o=["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"];t.exports=function(e){var t,n,r,a={};return e&&utils.forEach(e.split("\n"),function(e){if(r=e.indexOf(":"),t=utils.trim(e.substr(0,r)).toLowerCase(),n=utils.trim(e.substr(r+1)),t){if(a[t]&&0<=o.indexOf(t))return;a[t]="set-cookie"===t?(a[t]?a[t]:[]).concat([n]):a[t]?a[t]+", "+n:n}}),a}},{"./../utils":27}],26:[function(e,t,n){"use strict";t.exports=function(t){return function(e){return t.apply(null,e)}}},{}],27:[function(e,t,n){"use strict";var a=e("./helpers/bind"),r=e("is-buffer"),o=Object.prototype.toString;function i(e){return"[object Array]"===o.call(e)}function u(e){return null!==e&&"object"==typeof e}function s(e){return"[object Function]"===o.call(e)}function l(e,t){if(null!=e)if("object"!=typeof e&&(e=[e]),i(e))for(var n=0,r=e.length;n<r;n++)t.call(null,e[n],n,e);else for(var a in e)Object.prototype.hasOwnProperty.call(e,a)&&t.call(null,e[a],a,e)}t.exports={isArray:i,isArrayBuffer:function(e){return"[object ArrayBuffer]"===o.call(e)},isBuffer:r,isFormData:function(e){return"undefined"!=typeof FormData&&e instanceof FormData},isArrayBufferView:function(e){return"undefined"!=typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer&&e.buffer instanceof ArrayBuffer},isString:function(e){return"string"==typeof e},isNumber:function(e){return"number"==typeof e},isObject:u,isUndefined:function(e){return void 0===e},isDate:function(e){return"[object Date]"===o.call(e)},isFile:function(e){return"[object File]"===o.call(e)},isBlob:function(e){return"[object Blob]"===o.call(e)},isFunction:s,isStream:function(e){return u(e)&&s(e.pipe)},isURLSearchParams:function(e){return"undefined"!=typeof URLSearchParams&&e instanceof URLSearchParams},isStandardBrowserEnv:function(){return("undefined"==typeof navigator||"ReactNative"!==navigator.product&&"NativeScript"!==navigator.product&&"NS"!==navigator.product)&&(void 0!==window&&void 0!==document)},forEach:l,merge:function n(){var r={};function e(e,t){"object"==typeof r[t]&&"object"==typeof e?r[t]=n(r[t],e):r[t]=e}for(var t=0,a=arguments.length;t<a;t++)l(arguments[t],e);return r},deepMerge:function n(){var r={};function e(e,t){"object"==typeof r[t]&&"object"==typeof e?r[t]=n(r[t],e):r[t]="object"==typeof e?n({},e):e}for(var t=0,a=arguments.length;t<a;t++)l(arguments[t],e);return r},extend:function(n,e,r){return l(e,function(e,t){n[t]=r&&"function"==typeof e?a(e,r):e}),n},trim:function(e){return e.replace(/^\s*/,"").replace(/\s*$/,"")}}},{"./helpers/bind":18,"is-buffer":28}],28:[function(e,t,n){t.exports=function(e){return null!=e&&null!=e.constructor&&"function"==typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}},{}],29:[function(e,t,n){t.exports={CssSelectorParser:e("./lib/css-selector-parser.js").CssSelectorParser}},{"./lib/css-selector-parser.js":30}],30:[function(e,t,n){function r(){this.pseudos={},this.attrEqualityMods={},this.ruleNestingOperators={},this.substitutesEnabled=!1}function o(e){return"a"<=e&&e<="f"||"A"<=e&&e<="F"||"0"<=e&&e<="9"}r.prototype.registerSelectorPseudos=function(e){for(var t=0,n=arguments.length;t<n;t++)e=arguments[t],this.pseudos[e]="selector";return this},r.prototype.unregisterSelectorPseudos=function(e){for(var t=0,n=arguments.length;t<n;t++)e=arguments[t],delete this.pseudos[e];return this},r.prototype.registerNumericPseudos=function(e){for(var t=0,n=arguments.length;t<n;t++)e=arguments[t],this.pseudos[e]="numeric";return this},r.prototype.unregisterNumericPseudos=function(e){for(var t=0,n=arguments.length;t<n;t++)e=arguments[t],delete this.pseudos[e];return this},r.prototype.registerNestingOperators=function(e){for(var t=0,n=arguments.length;t<n;t++)e=arguments[t],this.ruleNestingOperators[e]=!0;return this},r.prototype.unregisterNestingOperators=function(e){for(var t=0,n=arguments.length;t<n;t++)e=arguments[t],delete this.ruleNestingOperators[e];return this},r.prototype.registerAttrEqualityMods=function(e){for(var t=0,n=arguments.length;t<n;t++)e=arguments[t],this.attrEqualityMods[e]=!0;return this},r.prototype.unregisterAttrEqualityMods=function(e){for(var t=0,n=arguments.length;t<n;t++)e=arguments[t],delete this.attrEqualityMods[e];return this},r.prototype.enableSubstitutes=function(){return this.substitutesEnabled=!0,this},r.prototype.disableSubstitutes=function(){return this.substitutesEnabled=!1,this};var u={"!":!0,'"':!0,"#":!0,$:!0,"%":!0,"&":!0,"'":!0,"(":!0,")":!0,"*":!0,"+":!0,",":!0,".":!0,"/":!0,";":!0,"<":!0,"=":!0,">":!0,"?":!0,"@":!0,"[":!0,"\\":!0,"]":!0,"^":!0,"`":!0,"{":!0,"|":!0,"}":!0,"~":!0},i={"\n":"\\n","\r":"\\r","\t":"\\t","\f":"\\f","\v":"\\v"},y={n:"\n",r:"\r",t:"\t",f:"\f","\\":"\\","'":"'"},v={n:"\n",r:"\r",t:"\t",f:"\f","\\":"\\",'"':'"'};function a(s,l,c,d,a,m){var p,f,h,b,g;return b=s.length,p=null,h=function(e,t){var n,r,a;for(a="",l++,p=s.charAt(l);l<b;){if(p===e)return l++,a;if("\\"===p)if(l++,(p=s.charAt(l))===e)a+=e;else if(n=t[p])a+=n;else{if(o(p)){for(r=p,l++,p=s.charAt(l);o(p);)r+=p,l++,p=s.charAt(l);" "===p&&(l++,p=s.charAt(l)),a+=String.fromCharCode(parseInt(r,16));continue}a+=p}else a+=p;l++,p=s.charAt(l)}return a},f=function(){var e,t="";for(p=s.charAt(l);l<b;){if("a"<=(e=p)&&e<="z"||"A"<=e&&e<="Z"||"0"<=e&&e<="9"||"-"===e||"_"===e)t+=p;else{if("\\"!==p)return t;if(b<=++l)throw Error("Expected symbol but end of file reached.");if(p=s.charAt(l),u[p])t+=p;else{if(o(p)){var n=p;for(l++,p=s.charAt(l);o(p);)n+=p,l++,p=s.charAt(l);" "===p&&(l++,p=s.charAt(l)),t+=String.fromCharCode(parseInt(n,16));continue}t+=p}}l++,p=s.charAt(l)}return t},g=function(){p=s.charAt(l);for(var e=!1;" "===p||"\t"===p||"\n"===p||"\r"===p||"\f"===p;)e=!0,l++,p=s.charAt(l);return e},this.parse=function(){var e=this.parseSelector();if(l<b)throw Error('Rule expected but "'+s.charAt(l)+'" found.');return e},this.parseSelector=function(){var e,t=e=this.parseSingleSelector();for(p=s.charAt(l);","===p;){if(l++,g(),"selectors"!==e.type&&(e={type:"selectors",selectors:[t]}),!(t=this.parseSingleSelector()))throw Error('Rule expected after ",".');e.selectors.push(t)}return e},this.parseSingleSelector=function(){g();var e={type:"ruleSet"},t=this.parseRule();if(!t)return null;for(var n=e;t&&(t.type="rule",n.rule=t,n=t,g(),p=s.charAt(l),!(b<=l||","===p||")"===p));)if(a[p]){var r=p;if(l++,g(),!(t=this.parseRule()))throw Error('Rule expected after "'+r+'".');t.nestingOperator=r}else(t=this.parseRule())&&(t.nestingOperator=null);return e},this.parseRule=function(){for(var e,t=null;l<b;)if("*"===(p=s.charAt(l)))l++,(t=t||{}).tagName="*";else if("a"<=(e=p)&&e<="z"||"A"<=e&&e<="Z"||"-"===e||"_"===e||"\\"===p)(t=t||{}).tagName=f();else if("."===p)l++,((t=t||{}).classNames=t.classNames||[]).push(f());else if("#"===p)l++,(t=t||{}).id=f();else if("["===p){l++,g();var n={name:f()};if(g(),"]"===p)l++;else{var r="";if(d[p]&&(r=p,l++,p=s.charAt(l)),b<=l)throw Error('Expected "=" but end of file reached.');if("="!==p)throw Error('Expected "=" but "'+p+'" found.');n.operator=r+"=",l++,g();var a="";if(n.valueType="string",'"'===p)a=h('"',v);else if("'"===p)a=h("'",y);else if(m&&"$"===p)l++,a=f(),n.valueType="substitute";else{for(;l<b&&"]"!==p;)a+=p,l++,p=s.charAt(l);a=a.trim()}if(g(),b<=l)throw Error('Expected "]" but end of file reached.');if("]"!==p)throw Error('Expected "]" but "'+p+'" found.');l++,n.value=a}((t=t||{}).attrs=t.attrs||[]).push(n)}else{if(":"!==p)break;l++;var o=f(),i={name:o};if("("===p){l++;var u="";if(g(),"selector"===c[o])i.valueType="selector",u=this.parseSelector();else{if(i.valueType=c[o]||"string",'"'===p)u=h('"',v);else if("'"===p)u=h("'",y);else if(m&&"$"===p)l++,u=f(),i.valueType="substitute";else{for(;l<b&&")"!==p;)u+=p,l++,p=s.charAt(l);u=u.trim()}g()}if(b<=l)throw Error('Expected ")" but end of file reached.');if(")"!==p)throw Error('Expected ")" but "'+p+'" found.');l++,i.value=u}((t=t||{}).pseudos=t.pseudos||[]).push(i)}return t},this}r.prototype.parse=function(e){return new a(e,0,this.pseudos,this.attrEqualityMods,this.ruleNestingOperators,this.substitutesEnabled).parse()},r.prototype.escapeIdentifier=function(e){for(var t="",n=0,r=e.length;n<r;){var a=e.charAt(n);if(u[a])t+="\\"+a;else if("_"===a||"-"===a||"A"<=a&&a<="Z"||"a"<=a&&a<="z"||0!==n&&"0"<=a&&a<="9")t+=a;else{var o=a.charCodeAt(0);if(55296==(63488&o)){var i=e.charCodeAt(n++);if(55296!=(64512&o)||56320!=(64512&i))throw Error("UCS-2(decode): illegal sequence");o=((1023&o)<<10)+(1023&i)+65536}t+="\\"+o.toString(16)+" "}n++}return t},r.prototype.escapeStr=function(e){for(var t,n,r="",a=0,o=e.length;a<o;)'"'===(t=e.charAt(a))?t='\\"':"\\"===t?t="\\\\":(n=i[t])&&(t=n),r+=t,a++;return'"'+r+'"'},r.prototype.render=function(e){return this._renderEntity(e).trim()},r.prototype._renderEntity=function(e){var t,n,r;switch(r="",e.type){case"ruleSet":for(t=e.rule,n=[];t;)t.nestingOperator&&n.push(t.nestingOperator),n.push(this._renderEntity(t)),t=t.rule;r=n.join(" ");break;case"selectors":r=e.selectors.map(this._renderEntity,this).join(", ");break;case"rule":e.tagName&&(r="*"===e.tagName?"*":this.escapeIdentifier(e.tagName)),e.id&&(r+="#"+this.escapeIdentifier(e.id)),e.classNames&&(r+=e.classNames.map(function(e){return"."+this.escapeIdentifier(e)},this).join("")),e.attrs&&(r+=e.attrs.map(function(e){return e.operator?"substitute"===e.valueType?"["+this.escapeIdentifier(e.name)+e.operator+"$"+e.value+"]":"["+this.escapeIdentifier(e.name)+e.operator+this.escapeStr(e.value)+"]":"["+this.escapeIdentifier(e.name)+"]"},this).join("")),e.pseudos&&(r+=e.pseudos.map(function(e){return e.valueType?"selector"===e.valueType?":"+this.escapeIdentifier(e.name)+"("+this._renderEntity(e.value)+")":"substitute"===e.valueType?":"+this.escapeIdentifier(e.name)+"($"+e.value+")":"numeric"===e.valueType?":"+this.escapeIdentifier(e.name)+"("+e.value+")":":"+this.escapeIdentifier(e.name)+"("+this.escapeIdentifier(e.value)+")":":"+this.escapeIdentifier(e.name)},this).join(""));break;default:throw Error('Unknown entity type: "'+e.type(NaN))}return r},n.CssSelectorParser=r},{}],31:[function(e,t,n){"use strict";t.exports=function(){return/\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F|\uD83D\uDC68(?:\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68\uD83C\uDFFB|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|[\u2695\u2696\u2708]\uFE0F|\uD83D[\uDC66\uDC67]|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708])\uFE0F|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C[\uDFFB-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)\uD83C\uDFFB|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB\uDFFC])|\uD83D\uDC69(?:\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB-\uDFFD])|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|(?:(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)\uFE0F|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\u200D[\u2640\u2642])|\uD83C\uDFF4\u200D\u2620)\uFE0F|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF4\uD83C\uDDF2|\uD83C\uDDF6\uD83C\uDDE6|[#\*0-9]\uFE0F\u20E3|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83D\uDC69(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270A-\u270D]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC70\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDCAA\uDD74\uDD7A\uDD90\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD36\uDDB5\uDDB6\uDDBB\uDDD2-\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5\uDEEB\uDEEC\uDEF4-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g}},{}],32:[function(V,n,r){(function(P,U){var e,t;e=this,t=function(){"use strict";function s(e){return"function"==typeof e}var n=Array.isArray?Array.isArray:function(e){return"[object Array]"===Object.prototype.toString.call(e)},r=0,t=void 0,a=void 0,i=function(e,t){m[r]=e,m[r+1]=t,2===(r+=2)&&(a?a(p):y())};var e=void 0!==window?window:void 0,o=e||{},u=o.MutationObserver||o.WebKitMutationObserver,l="undefined"==typeof self&&void 0!==P&&"[object process]"==={}.toString.call(P),c="undefined"!=typeof Uint8ClampedArray&&"undefined"!=typeof importScripts&&"undefined"!=typeof MessageChannel;function d(){var e=setTimeout;return function(){return e(p,1)}}var m=new Array(1e3);function p(){for(var e=0;e<r;e+=2){(0,m[e])(m[e+1]),m[e]=void 0,m[e+1]=void 0}r=0}var f,h,b,g,y=void 0;function v(e,t){var n=this,r=new this.constructor(k);void 0===r[w]&&O(r);var a=n._state;if(a){var o=arguments[a-1];i(function(){return S(a,r,o,n._result)})}else N(n,r,e,t);return r}function D(e){if(e&&"object"==typeof e&&e.constructor===this)return e;var t=new this(k);return F(t,e),t}y=l?function(){return P.nextTick(p)}:u?(h=0,b=new u(p),g=document.createTextNode(""),b.observe(g,{characterData:!0}),function(){g.data=h=++h%2}):c?((f=new MessageChannel).port1.onmessage=p,function(){return f.port2.postMessage(0)}):void 0===e&&"function"==typeof V?function(){try{var e=Function("return this")().require("vertx");return void 0!==(t=e.runOnLoop||e.runOnContext)?function(){t(p)}:d()}catch(e){return d()}}():d();var w=Math.random().toString(36).substring(2);function k(){}var x=void 0,E=1,C=2;function A(e,t,n){t.constructor===e.constructor&&n===v&&t.constructor.resolve===D?function(t,e){e._state===E?z(t,e._result):e._state===C?q(t,e._result):N(e,void 0,function(e){return F(t,e)},function(e){return q(t,e)})}(e,t):void 0===n?z(e,t):s(n)?function(e,r,a){i(function(t){var n=!1,e=function(e,t,n,r){try{e.call(t,n,r)}catch(e){return e}}(a,r,function(e){n||(n=!0,r!==e?F(t,e):z(t,e))},function(e){n||(n=!0,q(t,e))},t._label);!n&&e&&(n=!0,q(t,e))},e)}(e,t,n):z(e,t)}function F(t,e){if(t===e)q(t,new TypeError("You cannot resolve a promise with itself"));else if(function(e){var t=typeof e;return null!==e&&("object"==t||"function"==t)}(e)){var n=void 0;try{n=e.then}catch(e){return void q(t,e)}A(t,e,n)}else z(t,e)}function j(e){e._onerror&&e._onerror(e._result),T(e)}function z(e,t){e._state===x&&(e._result=t,e._state=E,0!==e._subscribers.length&&i(T,e))}function q(e,t){e._state===x&&(e._state=C,e._result=t,i(j,e))}function N(e,t,n,r){var a=e._subscribers,o=a.length;e._onerror=null,a[o]=t,a[o+E]=n,a[o+C]=r,0===o&&e._state&&i(T,e)}function T(e){var t=e._subscribers,n=e._state;if(0!==t.length){for(var r=void 0,a=void 0,o=e._result,i=0;i<t.length;i+=3)r=t[i],a=t[i+n],r?S(n,r,a,o):a(o);e._subscribers.length=0}}function S(e,t,n,r){var a=s(n),o=void 0,i=void 0,u=!0;if(a){try{o=n(r)}catch(e){u=!1,i=e}if(t===o)return void q(t,new TypeError("A promises callback cannot return that same promise."))}else o=r;t._state!==x||(a&&u?F(t,o):!1===u?q(t,i):e===E?z(t,o):e===C&&q(t,o))}var R=0;function O(e){e[w]=R++,e._state=void 0,e._result=void 0,e._subscribers=[]}var _=(B.prototype._enumerate=function(e){for(var t=0;this._state===x&&t<e.length;t++)this._eachEntry(e[t],t)},B.prototype._eachEntry=function(t,e){var n=this._instanceConstructor,r=n.resolve;if(r===D){var a=void 0,o=void 0,i=!1;try{a=t.then}catch(e){i=!0,o=e}if(a===v&&t._state!==x)this._settledAt(t._state,e,t._result);else if("function"!=typeof a)this._remaining--,this._result[e]=t;else if(n===L){var u=new n(k);i?q(u,o):A(u,t,a),this._willSettleAt(u,e)}else this._willSettleAt(new n(function(e){return e(t)}),e)}else this._willSettleAt(r(t),e)},B.prototype._settledAt=function(e,t,n){var r=this.promise;r._state===x&&(this._remaining--,e===C?q(r,n):this._result[t]=n),0===this._remaining&&z(r,this._result)},B.prototype._willSettleAt=function(e,t){var n=this;N(e,void 0,function(e){return n._settledAt(E,t,e)},function(e){return n._settledAt(C,t,e)})},B);function B(e,t){this._instanceConstructor=e,this.promise=new e(k),this.promise[w]||O(this.promise),n(t)?(this.length=t.length,this._remaining=t.length,this._result=new Array(this.length),0===this.length?z(this.promise,this._result):(this.length=this.length||0,this._enumerate(t),0===this._remaining&&z(this.promise,this._result))):q(this.promise,new Error("Array Methods must be provided an Array"))}var L=(I.prototype.catch=function(e){return this.then(null,e)},I.prototype.finally=function(t){var n=this.constructor;return s(t)?this.then(function(e){return n.resolve(t()).then(function(){return e})},function(e){return n.resolve(t()).then(function(){throw e})}):this.then(t,t)},I);function I(e){this[w]=R++,this._result=this._state=void 0,this._subscribers=[],k!==e&&("function"!=typeof e&&function(){throw new TypeError("You must pass a resolver function as the first argument to the promise constructor")}(),this instanceof I?function(t,e){try{e(function(e){F(t,e)},function(e){q(t,e)})}catch(e){q(t,e)}}(this,e):function(){throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.")}())}return L.prototype.then=v,L.all=function(e){return new _(this,e).promise},L.race=function(a){var o=this;return n(a)?new o(function(e,t){for(var n=a.length,r=0;r<n;r++)o.resolve(a[r]).then(e,t)}):new o(function(e,t){return t(new TypeError("You must pass an array to race."))})},L.resolve=D,L.reject=function(e){var t=new this(k);return q(t,e),t},L._setScheduler=function(e){a=e},L._setAsap=function(e){i=e},L._asap=i,L.polyfill=function(){var e=void 0;if(void 0!==U)e=U;else if("undefined"!=typeof self)e=self;else try{e=Function("return this")()}catch(e){throw new Error("polyfill failed because global object is unavailable in this environment")}var t=e.Promise;if(t){var n=null;try{n=Object.prototype.toString.call(t.resolve())}catch(e){}if("[object Promise]"===n&&!t.cast)return}e.Promise=L},L.Promise=L},"object"==typeof r&&void 0!==n?n.exports=t():"function"==typeof define&&define.amd?define(t):e.ES6Promise=t()}).call(this,V("_process"),void 0!==a?a:"undefined"!=typeof self?self:void 0!==window?window:{})},{_process:33}],33:[function(e,t,n){var r,a,o=t.exports={};function i(){throw new Error("setTimeout has not been defined")}function u(){throw new Error("clearTimeout has not been defined")}function s(t){if(r===setTimeout)return setTimeout(t,0);if((r===i||!r)&&setTimeout)return r=setTimeout,setTimeout(t,0);try{return r(t,0)}catch(e){try{return r.call(null,t,0)}catch(e){return r.call(this,t,0)}}}!function(){try{r="function"==typeof setTimeout?setTimeout:i}catch(e){r=i}try{a="function"==typeof clearTimeout?clearTimeout:u}catch(e){a=u}}();var l,c=[],d=!1,m=-1;function p(){d&&l&&(d=!1,l.length?c=l.concat(c):m=-1,c.length&&f())}function f(){if(!d){var e=s(p);d=!0;for(var t=c.length;t;){for(l=c,c=[];++m<t;)l&&l[m].run();m=-1,t=c.length}l=null,d=!1,function(t){if(a===clearTimeout)return clearTimeout(t);if((a===u||!a)&&clearTimeout)return a=clearTimeout,clearTimeout(t);try{a(t)}catch(e){try{return a.call(null,t)}catch(e){return a.call(this,t)}}}(e)}}function h(e,t){this.fun=e,this.array=t}function b(){}o.nextTick=function(e){var t=new Array(arguments.length-1);if(1<arguments.length)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];c.push(new h(e,t)),1!==c.length||d||s(f)},h.prototype.run=function(){this.fun.apply(null,this.array)},o.title="browser",o.browser=!0,o.env={},o.argv=[],o.version="",o.versions={},o.on=b,o.addListener=b,o.once=b,o.off=b,o.removeListener=b,o.removeAllListeners=b,o.emit=b,o.prependListener=b,o.prependOnceListener=b,o.listeners=function(e){return[]},o.binding=function(e){throw new Error("process.binding is not supported")},o.cwd=function(){return"/"},o.chdir=function(e){throw new Error("process.chdir is not supported")},o.umask=function(){return 0}},{}],34:[function(e,t,n){(function(e){!function(e){"use strict";if(!e.WeakMap){var n=Object.prototype.hasOwnProperty,r=function(e,t,n){Object.defineProperty?Object.defineProperty(e,t,{configurable:!0,writable:!0,value:n}):e[t]=n};e.WeakMap=(r(t.prototype,"delete",function(e){if(a(this,"delete"),!i(e))return!1;var t=e[this._id];return!(!t||t[0]!==e||(delete e[this._id],0))}),r(t.prototype,"get",function(e){if(a(this,"get"),i(e)){var t=e[this._id];return t&&t[0]===e?t[1]:void 0}}),r(t.prototype,"has",function(e){if(a(this,"has"),!i(e))return!1;var t=e[this._id];return!(!t||t[0]!==e)}),r(t.prototype,"set",function(e,t){if(a(this,"set"),!i(e))throw new TypeError("Invalid value used as weak map key");var n=e[this._id];return n&&n[0]===e?n[1]=t:r(e,this._id,[e,t]),this}),r(t,"_polyfill",!0),t)}function t(){if(void 0===this)throw new TypeError("Constructor WeakMap requires 'new'");if(r(this,"_id",function(e){return e+"_"+o()+"."+o()}("_WeakMap")),0<arguments.length)throw new TypeError("WeakMap iterable is not supported")}function a(e,t){if(!i(e)||!n.call(e,"_id"))throw new TypeError(t+" method called on incompatible receiver "+typeof e)}function o(){return Math.random().toString().substring(2)}function i(e){return Object(e)===e}}("undefined"!=typeof self?self:void 0!==window?window:void 0!==e?e:this)}).call(this,void 0!==a?a:"undefined"!=typeof self?self:void 0!==window?window:{})},{}]},{},[1]);var utils=axe.utils={},u={};function S(e){return(S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function R(){return(R=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}function t(e,t,n){"use strict";var r,a;for(r=0,a=e.length;r<a;r++)t[n](e[r])}function n(e){this.brand="axe",this.application="axeAPI",this.tagExclude=["experimental"],this.defaultConfig=e,this._init(),this._defaultLocale=null}n.prototype._setDefaultLocale=function(){if(!this._defaultLocale){for(var e={checks:{},rules:{}},t=Object.keys(this.data.checks),n=0;n<t.length;n++){var r=t[n],a=this.data.checks[r].messages,o=a.pass,i=a.fail,u=a.incomplete;e.checks[r]={pass:o,fail:i,incomplete:u}}for(var s=Object.keys(this.data.rules),l=0;l<s.length;l++){var c=s[l],d=this.data.rules[c],m=d.description,p=d.help;e.rules[c]={description:m,help:p}}this._defaultLocale=e}},n.prototype._resetLocale=function(){var e=this._defaultLocale;e&&this.applyLocale(e)};function c(a,e,o){return o.performanceTimer&&axe.utils.performanceTimer.mark("mark_rule_start_"+a.id),function(n,r){a.run(e,o,function(e){n(e)},function(e){if(o.debug)r(e);else{var t=Object.assign(new f(a),{result:axe.constants.CANTTELL,description:"An error occured while running this rule",message:e.message,stack:e.stack,error:e,errorNode:e.errorNode});n(t)}})}}function o(e,t,n){var r=e.brand,a=e.application;return axe.constants.helpUrlBase+r+"/"+(n||axe.version.substring(0,axe.version.lastIndexOf(".")))+"/"+t+"?application="+a}function d(e){"use strict";this.id=e.id,this.data=null,this.relatedNodes=[],this.result=null}function r(e){"use strict";return"string"==typeof e?new Function("return "+e+";")():e}function i(e){e&&(this.id=e.id,this.configure(e))}function S(e){return(S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function s(e,t,n){"use strict";var r,a;e.frames=e.frames||[];var o=document.querySelectorAll(n.shift());e:for(var i=0,u=o.length;i<u;i++){a=o[i];for(var s=0,l=e.frames.length;s<l;s++)if(e.frames[s].node===a){e.frames[s][t].push(n);break e}r={node:a,include:[],exclude:[]},n&&r[t].push(n),e.frames.push(r)}}function m(e,t){"use strict";for(var n,r,a=[],o=0,i=e[t].length;o<i;o++){if("string"==typeof(n=e[t][o])){r=Array.from(document.querySelectorAll(n)),a=a.concat(r.map(function(e){return axe.utils.getNodeFromTree(e)}));break}!n||!n.length||n instanceof Node?n instanceof Node&&(n.documentElement instanceof Node?a.push(e.flatTree[0]):a.push(axe.utils.getNodeFromTree(n))):1<n.length?s(e,t,n):(r=Array.from(document.querySelectorAll(n[0])),a=a.concat(r.map(function(e){return axe.utils.getNodeFromTree(e)})))}return a.filter(function(e){return e})}function p(e){"use strict";var t=this;this.frames=[],this.initiator=!e||"boolean"!=typeof e.initiator||e.initiator,this.page=!1,e=function(e){"use strict";if(e&&"object"===S(e)||e instanceof NodeList){if(e instanceof Node)return{include:[e],exclude:[]};if(e.hasOwnProperty("include")||e.hasOwnProperty("exclude"))return{include:e.include&&+e.include.length?e.include:[document],exclude:e.exclude||[]};if(e.length===+e.length)return{include:e,exclude:[]}}return"string"==typeof e?{include:[e],exclude:[]}:{include:[document],exclude:[]}}(e),this.flatTree=axe.utils.getFlattenedTree(function(e){var t=e.include,n=e.exclude;return(Array.from(t).concat(Array.from(n)).reduce(function(e,t){return e||(t instanceof Element?t.ownerDocument:t instanceof Document?t:void 0)},null)||document).documentElement}(e)),this.exclude=e.exclude,this.include=e.include,this.include=m(this,"include"),this.exclude=m(this,"exclude"),axe.utils.select("frame, iframe",this).forEach(function(e){Be(e,t)&&function(e,t){"use strict";axe.utils.isHidden(t)||axe.utils.findBy(e,"node",t)||e.push({node:t,include:[],exclude:[]})}(t.frames,e.actualNode)}),1===this.include.length&&this.include[0].actualNode===document.documentElement&&(this.page=!0);var n=function(e){"use strict";if(0===e.include.length){if(0===e.frames.length){var t=axe.utils.respondable.isInFrame()?"frame":"page";return new Error("No elements found for include in "+t+" Context")}e.frames.forEach(function(e,t){if(0===e.include.length)return new Error("No elements found for include in Context of frame "+t)})}}(this);if(n instanceof Error)throw n;Array.isArray(this.include)||(this.include=Array.from(this.include)),this.include.sort(axe.utils.nodeSorter)}function f(e){"use strict";this.id=e.id,this.result=axe.constants.NA,this.pageLevel=e.pageLevel,this.impact=null,this.nodes=[]}function h(e,t){"use strict";this._audit=t,this.id=e.id,this.selector=e.selector||"*",this.excludeHidden="boolean"!=typeof e.excludeHidden||e.excludeHidden,this.enabled="boolean"!=typeof e.enabled||e.enabled,this.pageLevel="boolean"==typeof e.pageLevel&&e.pageLevel,this.any=e.any||[],this.all=e.all||[],this.none=e.none||[],this.tags=e.tags||[],this.preload=!!e.preload,e.matches&&(this.matches=r(e.matches))}function b(e){if(e.length){var n=!1,r={};return e.forEach(function(e){var t=e.results.filter(function(e){return e});(r[e.type]=t).length&&(n=!0)}),n?r:null}}function S(e){return(S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function g(e){return(g=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function y(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function v(e,t){return(v=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function D(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function w(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function k(e,t,n){return t&&w(e.prototype,t),n&&w(e,n),e}n.prototype._applyCheckLocale=function(e){for(var t,n,r,a,o=Object.keys(e),i=0;i<o.length;i++){var u=o[i];if(!this.data.checks[u])throw new Error('Locale provided for unknown check: "'.concat(u,'"'));this.data.checks[u]=(t=this.data.checks[u],n=e[u],a=r=void 0,r=n.pass,a=n.fail,"string"==typeof r&&(r=axe.imports.doT.compile(r)),"string"==typeof a&&(a=axe.imports.doT.compile(a)),R({},t,{messages:{pass:r||t.messages.pass,fail:a||t.messages.fail,incomplete:"object"===S(t.messages.incomplete)?R({},t.messages.incomplete,{},n.incomplete):n.incomplete}}))}},n.prototype._applyRuleLocale=function(e){for(var t,n,r,a,o=Object.keys(e),i=0;i<o.length;i++){var u=o[i];if(!this.data.rules[u])throw new Error('Locale provided for unknown rule: "'.concat(u,'"'));this.data.rules[u]=(t=this.data.rules[u],n=e[u],a=r=void 0,r=n.help,a=n.description,"string"==typeof r&&(r=axe.imports.doT.compile(r)),"string"==typeof a&&(a=axe.imports.doT.compile(a)),R({},t,{help:r||t.help,description:a||t.description}))}},n.prototype.applyLocale=function(e){this._setDefaultLocale(),e.checks&&this._applyCheckLocale(e.checks),e.rules&&this._applyRuleLocale(e.rules)},n.prototype._init=function(){var e=function(e){"use strict";var t;return e?(t=axe.utils.clone(e)).commons=e.commons:t={},t.reporter=t.reporter||null,t.rules=t.rules||[],t.checks=t.checks||[],t.data=R({checks:{},rules:{}},t.data),t}(this.defaultConfig);axe.commons=e.commons,this.reporter=e.reporter,this.commands={},this.rules=[],this.checks={},t(e.rules,this,"addRule"),t(e.checks,this,"addCheck"),this.data={},this.data.checks=e.data&&e.data.checks||{},this.data.rules=e.data&&e.data.rules||{},this.data.failureSummaries=e.data&&e.data.failureSummaries||{},this.data.incompleteFallbackMessage=e.data&&e.data.incompleteFallbackMessage||"",this._constructHelpUrls()},n.prototype.registerCommand=function(e){"use strict";this.commands[e.id]=e.callback},n.prototype.addRule=function(e){"use strict";e.metadata&&(this.data.rules[e.id]=e.metadata);var t=this.getRule(e.id);t?t.configure(e):this.rules.push(new h(e,this))},n.prototype.addCheck=function(e){"use strict";var t=e.metadata;"object"===S(t)&&(this.data.checks[e.id]=t,"object"===S(t.messages)&&Object.keys(t.messages).filter(function(e){return t.messages.hasOwnProperty(e)&&"string"==typeof t.messages[e]}).forEach(function(e){0===t.messages[e].indexOf("function")&&(t.messages[e]=new Function("return "+t.messages[e]+";")())})),this.checks[e.id]?this.checks[e.id].configure(e):this.checks[e.id]=new i(e)},n.prototype.run=function(o,i,u,s){"use strict";this.normalizeOptions(i),axe._selectCache=[];var e=function(e,n,r){return e.reduce(function(e,t){return axe.utils.ruleShouldRun(t,n,r)&&(t.preload?e.later.push(t):e.now.push(t)),e},{now:[],later:[]})}(this.rules,o,i),t=e.now,l=e.later,n=axe.utils.queue();t.forEach(function(e){n.defer(c(e,o,i))});var r=axe.utils.queue();l.length&&r.defer(function(t){axe.utils.preload(i).then(function(e){return t(e)}).catch(function(e){console.warn("Couldn't load preload assets: ",e),t(void 0)})});var a=axe.utils.queue();a.defer(n),a.defer(r),a.then(function(e){var t=e.pop();if(t&&t.length){var n=t[0];n&&(o=R({},o,{},n))}var r=e[0];if(!l.length)return axe._selectCache=void 0,void u(r.filter(function(e){return!!e}));var a=axe.utils.queue();l.forEach(function(e){var t=c(e,o,i);a.defer(t)}),a.then(function(e){axe._selectCache=void 0,u(r.concat(e).filter(function(e){return!!e}))}).catch(s)}).catch(s)},n.prototype.after=function(e,n){"use strict";var r=this.rules;return e.map(function(e){var t=axe.utils.findBy(r,"id",e.id);if(!t)throw new Error("Result for unknown rule. You may be running mismatch axe-core versions");return t.after(e,n)})},n.prototype.getRule=function(t){return this.rules.find(function(e){return e.id===t})},n.prototype.normalizeOptions=function(e){"use strict";var t=this;if("object"===S(e.runOnly)){Array.isArray(e.runOnly)&&(e.runOnly={type:"tag",values:e.runOnly});var n=e.runOnly;if(n.value&&!n.values&&(n.values=n.value,delete n.value),!Array.isArray(n.values)||0===n.values.length)throw new Error("runOnly.values must be a non-empty array");if(["rule","rules"].includes(n.type))n.type="rule",n.values.forEach(function(e){if(!t.getRule(e))throw new Error("unknown rule `"+e+"` in options.runOnly")});else{if(!["tag","tags",void 0].includes(n.type))throw new Error("Unknown runOnly type '".concat(n.type,"'"));n.type="tag";var r=t.rules.reduce(function(e,t){return e.length?e.filter(function(e){return!t.tags.includes(e)}):e},n.values);0!==r.length&&axe.log("Could not find tags `"+r.join("`, `")+"`")}}return"object"===S(e.rules)&&Object.keys(e.rules).forEach(function(e){if(!t.getRule(e))throw new Error("unknown rule `"+e+"` in options.rules")}),e},n.prototype.setBranding=function(e){"use strict";var t={brand:this.brand,application:this.application};e&&e.hasOwnProperty("brand")&&e.brand&&"string"==typeof e.brand&&(this.brand=e.brand),e&&e.hasOwnProperty("application")&&e.application&&"string"==typeof e.application&&(this.application=e.application),this._constructHelpUrls(t)},n.prototype._constructHelpUrls=function(){var n=this,r=0<arguments.length&&void 0!==arguments[0]?arguments[0]:null,a=(axe.version.match(/^[1-9][0-9]*\.[0-9]+/)||["x.y"])[0];this.rules.forEach(function(e){n.data.rules[e.id]||(n.data.rules[e.id]={});var t=n.data.rules[e.id];("string"!=typeof t.helpUrl||r&&t.helpUrl===o(r,e.id,a))&&(t.helpUrl=o(n,e.id,a))})},n.prototype.resetRulesAndChecks=function(){"use strict";this._init(),this._resetLocale()},function(){"use strict";var n={},e={set:function(e,t){n[e]=t},get:function(e){return n[e]},clear:function(){n={}}};axe._cache=e}(),i.prototype.enabled=!0,i.prototype.run=function(t,e,n,r,a){"use strict";var o=(e=e||{}).hasOwnProperty("enabled")?e.enabled:this.enabled,i=e.options||this.options;if(o){var u,s=new d(this),l=axe.utils.checkHelper(s,e,r,a);try{u=this.evaluate.call(l,t.actualNode,i,t,n)}catch(e){return t&&t.actualNode&&(e.errorNode=new X(t.actualNode).toJSON()),void a(e)}l.isAsync||(s.result=u,r(s))}else r(null)},i.prototype.runSync=function(t,e,n){var r=(e=e||{}).enabled;if(!(void 0===r?this.enabled:r))return null;var a,o=e.options||this.options,i=new d(this),u=axe.utils.checkHelper(i,e);u.async=function(){throw new Error("Cannot run async check while in a synchronous run")};try{a=this.evaluate.call(u,t.actualNode,o,t,n)}catch(e){throw t&&t.actualNode&&(e.errorNode=new X(t.actualNode).toJSON()),e}return i.result=a,i},i.prototype.configure=function(t){var n=this;["options","enabled"].filter(function(e){return t.hasOwnProperty(e)}).forEach(function(e){return n[e]=t[e]}),["evaluate","after"].filter(function(e){return t.hasOwnProperty(e)}).forEach(function(e){return n[e]=r(t[e])})},h.prototype.matches=function(){"use strict";return!0},h.prototype.gather=function(e){var t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{},n="mark_gather_start_"+this.id,r="mark_gather_end_"+this.id,a="mark_isHidden_start_"+this.id,o="mark_isHidden_end_"+this.id;t.performanceTimer&&axe.utils.performanceTimer.mark(n);var i=axe.utils.select(this.selector,e);return this.excludeHidden&&(t.performanceTimer&&axe.utils.performanceTimer.mark(a),i=i.filter(function(e){return!axe.utils.isHidden(e.actualNode)}),t.performanceTimer&&(axe.utils.performanceTimer.mark(o),axe.utils.performanceTimer.measure("rule_"+this.id+"#gather_axe.utils.isHidden",a,o))),t.performanceTimer&&(axe.utils.performanceTimer.mark(r),axe.utils.performanceTimer.measure("rule_"+this.id+"#gather",n,r)),i},h.prototype.runChecks=function(t,a,o,i,n,e){"use strict";var u=this,s=axe.utils.queue();this[t].forEach(function(e){var n=u._audit.checks[e.id||e],r=axe.utils.getCheckOption(n,u.id,o);s.defer(function(e,t){n.run(a,r,i,e,t)})}),s.then(function(e){e=e.filter(function(e){return e}),n({type:t,results:e})}).catch(e)},h.prototype.runChecksSync=function(e,r,a,o){"use strict";var i=this,u=[];return this[e].forEach(function(e){var t=i._audit.checks[e.id||e],n=axe.utils.getCheckOption(t,i.id,a);u.push(t.runSync(r,n,o))}),{type:e,results:u=u.filter(function(e){return e})}},h.prototype.run=function(a){var o=this,i=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{},e=2<arguments.length?arguments[2]:void 0,t=3<arguments.length?arguments[3]:void 0;i.performanceTimer&&this._trackPerformance();var n,u=axe.utils.queue(),s=new f(this);try{n=this.gatherAndMatchNodes(a,i)}catch(e){return void t(new l({cause:e,ruleId:this.id}))}i.performanceTimer&&this._logGatherPerformance(n),n.forEach(function(r){u.defer(function(n,t){var e=axe.utils.queue();["any","all","none"].forEach(function(n){e.defer(function(e,t){o.runChecks(n,r,i,a,e,t)})}),e.then(function(e){var t=b(e);t&&(t.node=new axe.utils.DqElement(r.actualNode,i),s.nodes.push(t)),n()}).catch(function(e){return t(e)})})}),u.defer(function(e){return setTimeout(e,0)}),i.performanceTimer&&this._logRulePerformance(),u.then(function(){return e(s)}).catch(function(e){return t(e)})},h.prototype.runSync=function(r){var a=this,o=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{};o.performanceTimer&&this._trackPerformance();var e,i=new f(this);try{e=this.gatherAndMatchNodes(r,o)}catch(e){throw new l({cause:e,ruleId:this.id})}return o.performanceTimer&&this._logGatherPerformance(e),e.forEach(function(t){var n=[];["any","all","none"].forEach(function(e){n.push(a.runChecksSync(e,t,o,r))});var e=b(n);e&&(e.node=t.actualNode?new axe.utils.DqElement(t.actualNode,o):null,i.nodes.push(e))}),o.performanceTimer&&this._logRulePerformance(),i},h.prototype._trackPerformance=function(){this._markStart="mark_rule_start_"+this.id,this._markEnd="mark_rule_end_"+this.id,this._markChecksStart="mark_runchecks_start_"+this.id,this._markChecksEnd="mark_runchecks_end_"+this.id},h.prototype._logGatherPerformance=function(e){axe.log("gather (",e.length,"):",axe.utils.performanceTimer.timeElapsed()+"ms"),axe.utils.performanceTimer.mark(this._markChecksStart)},h.prototype._logRulePerformance=function(){axe.utils.performanceTimer.mark(this._markChecksEnd),axe.utils.performanceTimer.mark(this._markEnd),axe.utils.performanceTimer.measure("runchecks_"+this.id,this._markChecksStart,this._markChecksEnd),axe.utils.performanceTimer.measure("rule_"+this.id,this._markStart,this._markEnd)},h.prototype.gatherAndMatchNodes=function(t,e){var n=this,r="mark_matches_start_"+this.id,a="mark_matches_end_"+this.id,o=this.gather(t,e);return e.performanceTimer&&axe.utils.performanceTimer.mark(r),o=o.filter(function(e){return n.matches(e.actualNode,e,t)}),e.performanceTimer&&(axe.utils.performanceTimer.mark(a),axe.utils.performanceTimer.measure("rule_"+this.id+"#matches",r,a)),o},h.prototype.after=function(a,o){"use strict";var e=function(n){"use strict";return axe.utils.getAllChecks(n).map(function(e){var t=n._audit.checks[e.id||e];return t&&"function"==typeof t.after?t:null}).filter(Boolean)}(this),i=this.id;return e.forEach(function(e){var t=function(e,t){"use strict";var n=[];return e.forEach(function(e){axe.utils.getAllChecks(e).forEach(function(e){e.id===t&&n.push(e)})}),n}(a.nodes,e.id),n=axe.utils.getCheckOption(e,i,o),r=e.after(t,n);t.forEach(function(e){-1===r.indexOf(e)&&(e.filtered=!0)})}),a.nodes=function(e){"use strict";var r=["any","all","none"],t=e.nodes.filter(function(t){var n=0;return r.forEach(function(e){t[e]=function(e){"use strict";return e.filter(function(e){return!0!==e.filtered})}(t[e]),n+=t[e].length}),0<n});return e.pageLevel&&t.length&&(t=[t.reduce(function(t,n){if(t)return r.forEach(function(e){t[e].push.apply(t[e],n[e])}),t})]),t}(a),a},h.prototype.configure=function(e){"use strict";e.hasOwnProperty("selector")&&(this.selector=e.selector),e.hasOwnProperty("excludeHidden")&&(this.excludeHidden="boolean"!=typeof e.excludeHidden||e.excludeHidden),e.hasOwnProperty("enabled")&&(this.enabled="boolean"!=typeof e.enabled||e.enabled),e.hasOwnProperty("pageLevel")&&(this.pageLevel="boolean"==typeof e.pageLevel&&e.pageLevel),e.hasOwnProperty("any")&&(this.any=e.any),e.hasOwnProperty("all")&&(this.all=e.all),e.hasOwnProperty("none")&&(this.none=e.none),e.hasOwnProperty("tags")&&(this.tags=e.tags),e.hasOwnProperty("matches")&&("string"==typeof e.matches?this.matches=new Function("return "+e.matches+";")():this.matches=e.matches)};var x=/[\t\r\n\f]/g,E=(k(C,[{key:"hasClass",value:function(){throw new Error('VirtualNode class must have a "hasClass" function')}},{key:"attr",value:function(){throw new Error('VirtualNode class must have a "attr" function')}},{key:"hasAttr",value:function(){throw new Error('VirtualNode class must have a "hasAttr" function')}},{key:"props",get:function(){throw new Error('VirtualNode class must have a "props" object consisting of "nodeType" and "nodeName" properties')}}]),C);function C(){D(this,C),this.children=[],this.parent=null}var A=(function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&v(e,t)}(F,E),k(F,[{key:"hasClass",value:function(e){var t=this.attr("class");if(!t)return!1;var n=" "+e+" ";return 0<=(" "+t+" ").replace(x," ").indexOf(n)}},{key:"attr",value:function(e){return"function"!=typeof this.actualNode.getAttribute?null:this.actualNode.getAttribute(e)}},{key:"hasAttr",value:function(e){return"function"==typeof this.actualNode.hasAttribute&&this.actualNode.hasAttribute(e)}},{key:"props",get:function(){var e=this.actualNode,t=e.nodeType,n=e.nodeName,r=e.id,a=e.type;return{nodeType:t,nodeName:n.toLowerCase(),id:r,type:a}}},{key:"isFocusable",get:function(){return this._cache.hasOwnProperty("isFocusable")||(this._cache.isFocusable=axe.commons.dom.isFocusable(this.actualNode)),this._cache.isFocusable}},{key:"tabbableElements",get:function(){return this._cache.hasOwnProperty("tabbableElements")||(this._cache.tabbableElements=axe.commons.dom.getTabbableElements(this)),this._cache.tabbableElements}}]),F);function F(e,t,n){var r;return D(this,F),(r=function(e,t){return!t||"object"!==S(t)&&"function"!=typeof t?y(e):t}(this,g(F).call(this))).shadowId=n,r.children=[],r.actualNode=e,r.parent=t,r._isHidden=null,r._cache={},axe._cache.get("nodeMap")&&axe._cache.get("nodeMap").set(e,y(r)),r}function S(e){return(S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function j(t,n){"use strict";if(t=t||function(){},n=n||axe.log,!axe._audit)throw new Error("No audit configured");var r=axe.utils.queue(),a=[];Object.keys(axe.plugins).forEach(function(e){r.defer(function(t){function n(e){a.push(e),t()}try{axe.plugins[e].cleanup(t,n)}catch(e){n(e)}})});var e=axe.utils.getFlattenedTree(document.body);axe.utils.querySelectorAll(e,"iframe, frame").forEach(function(n){r.defer(function(e,t){return axe.utils.sendCommandToFrame(n.actualNode,{command:"cleanup-plugin"},e,t)})}),r.then(function(e){0===a.length?t(e):n(a)}).catch(n)}function z(e,t,n){"use strict";function r(e){e instanceof Error==!1&&(e=new Error(e)),n(e)}var a=n,o=e&&e.context||{};o.hasOwnProperty("include")&&!o.include.length&&(o.include=[document]);var i=e&&e.options||{};switch(e.command){case"rules":return _(o,i,function(e,t){a(e),t()},r);case"cleanup-plugin":return j(a,r);default:if(axe._audit&&axe._audit.commands&&axe._audit.commands[e.command])return axe._audit.commands[e.command](e,n)}}function q(e){"use strict";this._run=e.run,this._collect=e.collect,this._registry={},e.commands.forEach(function(e){axe._audit.registerCommand(e)})}axe.AbstractVirtualNode=E,function(axe){var o={helpUrlBase:"https://dequeuniversity.com/rules/",results:[],resultGroups:[],resultGroupMap:{},impact:Object.freeze(["minor","moderate","serious","critical"]),preload:Object.freeze({assets:["cssom"],timeout:1e4})};[{name:"NA",value:"inapplicable",priority:0,group:"inapplicable"},{name:"PASS",value:"passed",priority:1,group:"passes"},{name:"CANTTELL",value:"cantTell",priority:2,group:"incomplete"},{name:"FAIL",value:"failed",priority:3,group:"violations"}].forEach(function(e){var t=e.name,n=e.value,r=e.priority,a=e.group;o[t]=n,o[t+"_PRIO"]=r,o[t+"_GROUP"]=a,o.results[r]=n,o.resultGroups[r]=a,o.resultGroupMap[n]=a}),Object.freeze(o.results),Object.freeze(o.resultGroups),Object.freeze(o.resultGroupMap),Object.freeze(o),Object.defineProperty(axe,"constants",{value:o,enumerable:!0,configurable:!1,writable:!1})}(axe),axe.log=function(){"use strict";"object"===("undefined"==typeof console?"undefined":S(console))&&console.log&&Function.prototype.apply.call(console.log,console,arguments)},axe.cleanup=j,axe.configure=function(e){"use strict";var t;if(!(t=axe._audit))throw new Error("No audit configured");e.reporter&&("function"==typeof e.reporter||T[e.reporter])&&(t.reporter=e.reporter),e.checks&&e.checks.forEach(function(e){t.addCheck(e)});var n=[];e.rules&&e.rules.forEach(function(e){n.push(e.id),t.addRule(e)}),e.disableOtherRules&&t.rules.forEach(function(e){!1===n.includes(e.id)&&(e.enabled=!1)}),void 0!==e.branding?t.setBranding(e.branding):t._constructHelpUrls(),e.tagExclude&&(t.tagExclude=e.tagExclude),e.locale&&t.applyLocale(e.locale)},axe.getRules=function(e){"use strict";var t=(e=e||[]).length?axe._audit.rules.filter(function(t){return!!e.filter(function(e){return-1!==t.tags.indexOf(e)}).length}):axe._audit.rules,n=axe._audit.data.rules||{};return t.map(function(e){var t=n[e.id]||{};return{ruleId:e.id,description:t.description,help:t.help,helpUrl:t.helpUrl,tags:e.tags}})},axe._load=function(e){"use strict";axe.utils.respondable.subscribe("axe.ping",function(e,t,n){n({axe:!0})}),axe.utils.respondable.subscribe("axe.start",z),axe._audit=new n(e)},(axe=axe||{}).plugins={},q.prototype.run=function(){"use strict";return this._run.apply(this,arguments)},q.prototype.collect=function(){"use strict";return this._collect.apply(this,arguments)},q.prototype.cleanup=function(e){"use strict";var n=axe.utils.queue(),r=this;Object.keys(this._registry).forEach(function(t){n.defer(function(e){r._registry[t].cleanup(e)})}),n.then(function(){e()})},q.prototype.add=function(e){"use strict";this._registry[e.id]=e},axe.registerPlugin=function(e){"use strict";axe.plugins[e.id]=new q(e)};var N,T={};function O(){axe._cache.clear(),axe._tree=void 0,axe._selectorData=void 0}function _(n,r,a,o){"use strict";try{n=new p(n),axe._tree=n.flatTree,axe._selectorData=axe.utils.getSelectorData(n.flatTree)}catch(e){return O(),o(e)}var i,e=axe.utils.queue(),u=axe._audit;r.performanceTimer&&axe.utils.performanceTimer.auditStart(),n.frames.length&&!1!==r.iframes&&e.defer(function(e,t){axe.utils.collectResultsFromFrames(n,r,"rules",null,e,t)}),e.defer(function(e,t){r.restoreScroll&&(i=axe.utils.getScrollState()),u.run(n,r,e,t)}),e.then(function(e){try{i&&axe.utils.setScrollState(i),r.performanceTimer&&axe.utils.performanceTimer.auditEnd();var t=axe.utils.mergeResults(e.map(function(e){return{results:e}}));n.initiator&&((t=u.after(t,r)).forEach(axe.utils.publishMetaData),t=t.map(axe.utils.finalizeRuleResult));try{a(t,O)}catch(e){O(),axe.log(e)}}catch(e){O(),o(e)}}).catch(function(e){O(),o(e)})}function R(){return(R=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}function S(e){return(S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}axe.getReporter=function(e){"use strict";return"string"==typeof e&&T[e]?T[e]:"function"==typeof e?e:N},axe.addReporter=function(e,t,n){"use strict";T[e]=t,n&&(N=t)},axe.reset=function(){"use strict";var e=axe._audit;if(!e)throw new Error("No audit configured");e.resetRulesAndChecks()},axe._runRules=_,axe.runVirtualRule=function(t,e){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{};n.reporter=n.reporter||axe._audit.reporter||"v1",axe._selectorData={};var r=axe._audit.rules.find(function(e){return e.id===t});if(!r)throw new Error("unknown rule `"+t+"`");var a={include:[e]},o=(r=Object.create(r,{excludeHidden:{value:!1}})).runSync(a,n);axe.utils.publishMetaData(o),axe.utils.finalizeRuleResult(o);var i=axe.utils.aggregateResult([o]);return i.violations.forEach(function(e){return e.nodes.forEach(function(e){e.failureSummary=u.failureSummary(e)})}),R({},u.getEnvironmentData(),{},i,{toolOptions:n})};function B(){}function L(e,t,n){"use strict";var r=new TypeError("axe.run arguments are invalid");if(!function(e){"use strict";switch(!0){case"string"==typeof e:case Array.isArray(e):case Node&&e instanceof Node:case NodeList&&e instanceof NodeList:return!0;case"object"!==S(e):return!1;case void 0!==e.include:case void 0!==e.exclude:case"number"==typeof e.length:return!0;default:return!1}}(e)){if(void 0!==n)throw r;n=t,t=e,e=document}if("object"!==S(t)){if(void 0!==n)throw r;n=t,t={}}if("function"!=typeof n&&void 0!==n)throw r;return{context:e,options:t,callback:n||B}}function S(e){return(S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}axe.run=function(e,a,o){"use strict";if(!axe._audit)throw new Error("No audit configured");var t,n=L(e,a,o);e=n.context,a=n.options,o=n.callback,a.reporter=a.reporter||axe._audit.reporter||"v1",a.performanceTimer&&axe.utils.performanceTimer.start();var i=B,u=B;return"function"==typeof Promise&&o===B&&(t=new Promise(function(e,t){i=t,u=e})),axe._runRules(e,a,function(e,t){function n(e){t();try{o(null,e)}catch(e){axe.log(e)}u(e)}a.performanceTimer&&axe.utils.performanceTimer.end();try{var r=axe.getReporter(a.reporter)(e,a,n);void 0!==r&&n(r)}catch(e){t(),o(e),i(e)}},function(e){o(e),i(e)}),t},u.failureSummary=function(e){"use strict";var n={};return n.none=e.none.concat(e.all),n.any=e.any,Object.keys(n).map(function(e){if(n[e].length){var t=axe._audit.data.failureSummaries[e];return t&&"function"==typeof t.failureMessage?t.failureMessage(n[e].map(function(e){return e.message||""})):void 0}}).filter(function(e){return void 0!==e}).join("\n\n")},u.getEnvironmentData=function(e){var t=0<arguments.length&&void 0!==e?e:window,n=t.screen,r=void 0===n?{}:n,a=t.navigator,o=void 0===a?{}:a,i=t.location,u=void 0===i?{}:i,s=t.innerHeight,l=t.innerWidth,c=r.msOrientation||r.orientation||r.mozOrientation||{};return{testEngine:{name:"axe-core",version:axe.version},testRunner:{name:axe._audit.brand},testEnvironment:{userAgent:o.userAgent,windowWidth:l,windowHeight:s,orientationAngle:c.angle,orientationType:c.type},timestamp:(new Date).toISOString(),url:u.href}},u.incompleteFallbackMessage=function(){"use strict";return axe._audit.data.incompleteFallbackMessage()};var I=axe.constants.resultGroups;function R(){return(R=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}function R(){return(R=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}function R(){return(R=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}function R(){return(R=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}function R(){return(R=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}u.processAggregate=function(e,n){var t=axe.utils.aggregateResult(e);return I.forEach(function(e){n.resultTypes&&!n.resultTypes.includes(e)&&(t[e]||[]).forEach(function(e){Array.isArray(e.nodes)&&0<e.nodes.length&&(e.nodes=[e.nodes[0]])}),t[e]=(t[e]||[]).map(function(t){return t=Object.assign({},t),Array.isArray(t.nodes)&&0<t.nodes.length&&(t.nodes=t.nodes.map(function(e){return"object"===S(e.node)&&(e.html=e.node.source,n.elementRef&&!e.node.fromFrame&&(e.element=e.node.element),!1===n.selectors&&!e.node.fromFrame||(e.target=e.node.selector),n.xpath&&(e.xpath=e.node.xpath)),delete e.result,delete e.node,function(t,n){"use strict";["any","all","none"].forEach(function(e){Array.isArray(t[e])&&t[e].filter(function(e){return Array.isArray(e.relatedNodes)}).forEach(function(e){e.relatedNodes=e.relatedNodes.map(function(e){var t={html:e.source};return n.elementRef&&!e.fromFrame&&(t.element=e.element),!1===n.selectors&&!e.fromFrame||(t.target=e.selector),n.xpath&&(t.xpath=e.xpath),t})})})}(e,n),e})),I.forEach(function(e){return delete t[e]}),delete t.pageLevel,delete t.result,t})}),t},axe.addReporter("na",function(e,t,n){"use strict";console.warn('"na" reporter will be deprecated in axe v4.0. Use the "v2" reporter instead.'),"function"==typeof t&&(n=t,t={});var r=u.processAggregate(e,t);n(R({},u.getEnvironmentData(),{toolOptions:t,violations:r.violations,passes:r.passes,incomplete:r.incomplete,inapplicable:r.inapplicable}))}),axe.addReporter("no-passes",function(e,t,n){"use strict";"function"==typeof t&&(n=t,t={}),t.resultTypes=["violations"];var r=u.processAggregate(e,t);n(R({},u.getEnvironmentData(),{toolOptions:t,violations:r.violations}))}),axe.addReporter("rawEnv",function(e,t,n){"function"==typeof t&&(n=t,t={}),axe.getReporter("raw")(e,t,function(e){var t=u.getEnvironmentData();n({raw:e,env:t})})}),axe.addReporter("raw",function(e,t,n){"use strict";if("function"==typeof t&&(n=t,t={}),!e||!Array.isArray(e))return n(e);n(e.map(function(e){for(var t=R({},e),n=0,r=["passes","violations","incomplete","inapplicable"];n<r.length;n++){var a=r[n];t[a]&&Array.isArray(t[a])&&(t[a]=t[a].map(function(e){return R({},e,{node:e.node.toJSON()})}))}return t}))}),axe.addReporter("v1",function(e,t,n){"use strict";"function"==typeof t&&(n=t,t={});var r=u.processAggregate(e,t);r.violations.forEach(function(e){return e.nodes.forEach(function(e){e.failureSummary=u.failureSummary(e)})}),n(R({},u.getEnvironmentData(),{toolOptions:t,violations:r.violations,passes:r.passes,incomplete:r.incomplete,inapplicable:r.inapplicable}))}),axe.addReporter("v2",function(e,t,n){"use strict";"function"==typeof t&&(n=t,t={});var r=u.processAggregate(e,t);n(R({},u.getEnvironmentData(),{toolOptions:t,violations:r.violations,passes:r.passes,incomplete:r.incomplete,inapplicable:r.inapplicable}))},!0),axe.utils.aggregate=function(t,e,n){e=e.slice(),n&&e.push(n);var r=e.map(function(e){return t.indexOf(e)}).sort();return t[r.pop()]};var P=axe.constants,U=P.CANTTELL_PRIO,V=P.FAIL_PRIO,M=[];M[axe.constants.PASS_PRIO]=!0,M[axe.constants.CANTTELL_PRIO]=null,M[axe.constants.FAIL_PRIO]=!1;var axe,H=["any","all","none"];function G(n,r){return H.reduce(function(e,t){return e[t]=(n[t]||[]).map(function(e){return r(e,t)}),e},{})}function W(e,t,n){var r=Object.assign({},t);r.nodes=(r[n]||[]).concat(),axe.constants.resultGroups.forEach(function(e){delete r[e]}),e[n].push(r)}function S(e){return(S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function $(e,t){"use strict";var n;return axe._tree&&(n=axe.utils.getSelector(t)),new Error(e+": "+(n||t))}function X(e,t,n){this._fromFrame=!!n,this.spec=n||{},t&&t.absolutePaths&&(this._options={toRoot:!0}),this.source=void 0!==this.spec.source?this.spec.source:function(e){var t=e.outerHTML;return t||"function"!=typeof XMLSerializer||(t=(new XMLSerializer).serializeToString(e)),function(e,t){if(t=t||300,e.length>t){var n=e.indexOf(">");e=e.substring(0,n+1)}return e}(t||"")}(e),this._element=e}function S(e){return(S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function Y(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=[],r=!0,a=!1,o=void 0;try{for(var i,u=e[Symbol.iterator]();!(r=(i=u.next()).done)&&(n.push(i.value),!t||n.length!==t);r=!0);}catch(e){a=!0,o=e}finally{try{r||null==u.return||u.return()}finally{if(a)throw o}}return n}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}function J(e,t){return[e.substring(0,t),e.substring(t)]}function K(e){return e.replace(/\s+$/,"")}axe.utils.aggregateChecks=function(e){var n=Object.assign({},e);G(n,function(e,t){var n=void 0===e.result?-1:M.indexOf(e.result);e.priority=-1!==n?n:axe.constants.CANTTELL_PRIO,"none"===t&&(e.priority===axe.constants.PASS_PRIO?e.priority=axe.constants.FAIL_PRIO:e.priority===axe.constants.FAIL_PRIO&&(e.priority=axe.constants.PASS_PRIO))});var r={all:n.all.reduce(function(e,t){return Math.max(e,t.priority)},0),none:n.none.reduce(function(e,t){return Math.max(e,t.priority)},0),any:n.any.reduce(function(e,t){return Math.min(e,t.priority)},4)%4};n.priority=Math.max(r.all,r.none,r.any);var a=[];return H.forEach(function(t){n[t]=n[t].filter(function(e){return e.priority===n.priority&&e.priority===r[t]}),n[t].forEach(function(e){return a.push(e.impact)})}),[U,V].includes(n.priority)?n.impact=axe.utils.aggregate(axe.constants.impact,a):n.impact=null,G(n,function(e){delete e.result,delete e.priority}),n.result=axe.constants.results[n.priority],delete n.priority,n},axe.utils.aggregateNodeResults=function(e){var n={};if((e=e.map(function(e){if(e.any&&e.all&&e.none)return axe.utils.aggregateChecks(e);if(Array.isArray(e.node))return axe.utils.finalizeRuleResult(e);throw new TypeError("Invalid Result type")}))&&e.length){var t=e.map(function(e){return e.result});n.result=axe.utils.aggregate(axe.constants.results,t,n.result)}else n.result="inapplicable";axe.constants.resultGroups.forEach(function(e){return n[e]=[]}),e.forEach(function(e){var t=axe.constants.resultGroupMap[e.result];n[t].push(e)});var r=axe.constants.FAIL_GROUP;if(0===n[r].length&&(r=axe.constants.CANTTELL_GROUP),0<n[r].length){var a=n[r].map(function(e){return e.impact});n.impact=axe.utils.aggregate(axe.constants.impact,a)||null}else n.impact=null;return n},axe.utils.aggregateResult=function(e){var n={};return axe.constants.resultGroups.forEach(function(e){return n[e]=[]}),e.forEach(function(t){t.error?W(n,t,axe.constants.CANTTELL_GROUP):t.result===axe.constants.NA?W(n,t,axe.constants.NA_GROUP):axe.constants.resultGroups.forEach(function(e){Array.isArray(t[e])&&0<t[e].length&&W(n,t,e)})}),n},axe.utils.areStylesSet=function e(t,n,r){"use strict";var a=window.getComputedStyle(t,null),o=!1;return!!a&&(n.forEach(function(e){a.getPropertyValue(e.property)===e.value&&(o=!0)}),!!o||!(t.nodeName.toUpperCase()===r.toUpperCase()||!t.parentNode)&&e(t.parentNode,n,r))},axe.utils.checkHelper=function(t,n,r,a){"use strict";return{isAsync:!1,async:function(){return this.isAsync=!0,function(e){e instanceof Error==!1?(t.result=e,r(t)):a(e)}},data:function(e){t.data=e},relatedNodes:function(e){e=e instanceof Node?[e]:axe.utils.toArray(e),t.relatedNodes=e.map(function(e){return new axe.utils.DqElement(e,n)})}}},axe.utils.clone=function(e){"use strict";var t,n,r=e;if(null!==e&&"object"===S(e))if(Array.isArray(e))for(r=[],t=0,n=e.length;t<n;t++)r[t]=axe.utils.clone(e[t]);else for(t in r={},e)r[t]=axe.utils.clone(e[t]);return r},axe.utils.sendCommandToFrame=function(t,n,r,a){"use strict";var o=t.contentWindow;if(!o)return axe.log("Frame does not have a content window",t),void r(null);var i=setTimeout(function(){i=setTimeout(function(){n.debug?a($("No response from frame",t)):r(null)},0)},500);axe.utils.respondable(o,"axe.ping",null,void 0,function(){clearTimeout(i);var e=n.options&&n.options.frameWaitTime||6e4;i=setTimeout(function(){a($("Axe in frame timed out",t))},e),axe.utils.respondable(o,"axe.start",n,void 0,function(e){clearTimeout(i),e instanceof Error==!1?r(e):a(e)})})},axe.utils.collectResultsFromFrames=function(e,t,n,o,r,a){"use strict";var i=axe.utils.queue();e.frames.forEach(function(r){var a={options:t,command:n,parameter:o,context:{initiator:!1,page:e.page,include:r.include||[],exclude:r.exclude||[]}};i.defer(function(t,e){var n=r.node;axe.utils.sendCommandToFrame(n,a,function(e){if(e)return t({results:e,frameElement:n,frame:axe.utils.getSelector(n)});t(null)},e)})}),i.then(function(e){r(axe.utils.mergeResults(e,t))}).catch(a)},axe.utils.contains=function(e,t){"use strict";if(e.shadowId||t.shadowId)return function t(e,n){return e.shadowId===n.shadowId||!!e.children.find(function(e){return t(e,n)})}(e,t);if(e.actualNode)return"function"==typeof e.actualNode.contains?e.actualNode.contains(t.actualNode):!!(16&e.actualNode.compareDocumentPosition(t.actualNode));do{if(t===e)return!0}while(t=t&&t.parent);return!1},function(axe){var e=new axe.imports.CssSelectorParser;e.registerSelectorPseudos("not"),e.registerNestingOperators(">"),e.registerAttrEqualityMods("^","$","*"),axe.utils.cssParser=e}(axe),X.prototype={get selector(){return this.spec.selector||[axe.utils.getSelector(this.element,this._options)]},get xpath(){return this.spec.xpath||[axe.utils.getXpath(this.element)]},get element(){return this._element},get fromFrame(){return this._fromFrame},toJSON:function(){"use strict";return{selector:this.selector,source:this.source,xpath:this.xpath}}},X.fromFrame=function(e,t,n){return e.selector.unshift(n.selector),e.xpath.unshift(n.xpath),new axe.utils.DqElement(n.element,t,e)},axe.utils.DqElement=X,axe.utils.matchesSelector=function(){"use strict";var n;return function(e,t){return n&&e[n]||(n=function(e){var t,n,r=["matches","matchesSelector","mozMatchesSelector","webkitMatchesSelector","msMatchesSelector"],a=r.length;for(t=0;t<a;t++)if(e[n=r[t]])return n}(e)),!!e[n]&&e[n](t)}}(),axe.utils.escapeSelector=function(e){"use strict";for(var t,n=String(e),r=n.length,a=-1,o="",i=n.charCodeAt(0);++a<r;)0!=(t=n.charCodeAt(a))?o+=1<=t&&t<=31||127==t||0==a&&48<=t&&t<=57||1==a&&48<=t&&t<=57&&45==i?"\\"+t.toString(16)+" ":(0!=a||1!=r||45!=t)&&(128<=t||45==t||95==t||48<=t&&t<=57||65<=t&&t<=90||97<=t&&t<=122)?n.charAt(a):"\\"+n.charAt(a):o+="�";return o},axe.utils.extendMetaData=function(t,n){Object.assign(t,n),Object.keys(n).filter(function(e){return"function"==typeof n[e]}).forEach(function(e){t[e]=null;try{t[e]=n[e](t)}catch(e){}})},axe.utils.finalizeRuleResult=function(e){return Object.assign(e,axe.utils.aggregateNodeResults(e.nodes)),delete e.nodes,e},axe.utils.findBy=function(e,t,n){if(Array.isArray(e))return e.find(function(e){return"object"===S(e)&&e[t]===n})},(axe=axe||{utils:{}}).utils.getFlattenedTree=function(e,t){return axe._cache.set("nodeMap",new WeakMap),function a(e,o,n){var r,t,i;function u(e,t,n){var r=a(t,o,n);return r&&(e=e.concat(r)),e}if(e.documentElement&&(e=e.documentElement),i=e.nodeName.toLowerCase(),axe.utils.isShadowRoot(e))return r=new A(e,n,o),o="a"+Math.random().toString().substring(2),t=Array.from(e.shadowRoot.childNodes),r.children=t.reduce(function(e,t){return u(e,t,r)},[]),[r];if("content"===i&&"function"==typeof e.getDistributedNodes)return(t=Array.from(e.getDistributedNodes())).reduce(function(e,t){return u(e,t,n)},[]);if("slot"!==i||"function"!=typeof e.assignedNodes)return 1===e.nodeType?(r=new A(e,n,o),t=Array.from(e.childNodes),r.children=t.reduce(function(e,t){return u(e,t,r)},[]),[r]):3===e.nodeType?[new A(e,n)]:void 0;(t=Array.from(e.assignedNodes())).length||(t=function(e){var t=[];for(e=e.firstChild;e;)t.push(e),e=e.nextSibling;return t}(e));window.getComputedStyle(e);return t.reduce(function(e,t){return u(e,t,n)},[])}(e,t)},axe.utils.getNodeFromTree=function(e,t){var n=t||e;return axe._cache.get("nodeMap")?axe._cache.get("nodeMap").get(n):null},axe.utils.getAllChecks=function(e){"use strict";return[].concat(e.any||[]).concat(e.all||[]).concat(e.none||[])},axe.utils.getBaseLang=function(e){return e?e.trim().split("-")[0].toLowerCase():""},axe.utils.getCheckOption=function(e,t,n){var r=((n.rules&&n.rules[t]||{}).checks||{})[e.id],a=(n.checks||{})[e.id],o=e.enabled,i=e.options;return a&&(a.hasOwnProperty("enabled")&&(o=a.enabled),a.hasOwnProperty("options")&&(i=a.options)),r&&(r.hasOwnProperty("enabled")&&(o=r.enabled),r.hasOwnProperty("options")&&(i=r.options)),{enabled:o,options:i,absolutePaths:n.absolutePaths}},axe.utils.getFriendlyUriEnd=function(e,t){var n=0<arguments.length&&void 0!==e?e:"",r=1<arguments.length&&void 0!==t?t:{};if(!(n.length<=1||"data:"===n.substr(0,5)||"javascript:"===n.substr(0,11)||n.includes("?"))){var a=r.currentDomain,o=r.maxLength,i=void 0===o?25:o,u=function(e){var t=e,n="",r="",a="",o="",i="";if(e.includes("#")){var u=Y(J(e,e.indexOf("#")),2);e=u[0],i=u[1]}if(e.includes("?")){var s=Y(J(e,e.indexOf("?")),2);e=s[0],o=s[1]}if(e.includes("://")){var l=Y(e.split("://"),2);n=l[0];var c=Y(J(e=l[1],e.indexOf("/")),2);r=c[0],e=c[1]}else if("//"===e.substr(0,2)){var d=Y(J(e=e.substr(2),e.indexOf("/")),2);r=d[0],e=d[1]}if("www."===r.substr(0,4)&&(r=r.substr(4)),r&&r.includes(":")){var m=Y(J(r,r.indexOf(":")),2);r=m[0],a=m[1]}return{original:t,protocol:n,domain:r,port:a,path:e,query:o,hash:i}}(n),s=u.path,l=u.domain,c=u.hash,d=s.substr(s.substr(0,s.length-2).lastIndexOf("/")+1);if(c)return d&&(d+c).length<=i?K(d+c):d.length<2&&2<c.length&&c.length<=i?K(c):void 0;if(l&&l.length<i&&s.length<=1)return K(l+s);if(s==="/"+d&&l&&a&&l!==a&&(l+s).length<=i)return K(l+s);var m=d.lastIndexOf(".");return(-1===m||1<m)&&(-1!==m||2<d.length)&&d.length<=i&&!d.match(/index(\.[a-zA-Z]{2-4})?/)&&!function(e){var t=0<arguments.length&&void 0!==e?e:"";return 0!==t.length&&(t.match(/[0-9]/g)||"").length>=t.length/2}(d)?K(d):void 0}},axe.utils.getNodeAttributes=function(e){return e.attributes instanceof window.NamedNodeMap?e.attributes:e.cloneNode(!1).attributes},axe.utils.getRootNode=function(e){var t=e.getRootNode&&e.getRootNode()||document;return t===e&&(t=document),t},axe.utils.getScroll=function(e,t){var n=1<arguments.length&&void 0!==t?t:0,r=e.scrollWidth>e.clientWidth+n,a=e.scrollHeight>e.clientHeight+n;if(r||a){var o=window.getComputedStyle(e),i=o.getPropertyValue("overflow-x"),u=o.getPropertyValue("overflow-y");return r&&("visible"!==i&&"hidden"!==i)||a&&("visible"!==u&&"hidden"!==u)?{elm:e,top:e.scrollTop,left:e.scrollLeft}:void 0}};var Z,Q,ee=axe.utils.escapeSelector,te=["class","style","id","selected","checked","disabled","tabindex","aria-checked","aria-selected","aria-invalid","aria-activedescendant","aria-busy","aria-disabled","aria-expanded","aria-grabbed","aria-pressed","aria-valuenow"],ne=31;function re(e,t){var n,r=t.name;if(-1!==r.indexOf("href")||-1!==r.indexOf("src")){var a=axe.utils.getFriendlyUriEnd(e.getAttribute(r));if(a){var o=encodeURI(a);if(!o)return;n=ee(t.name)+'$="'+ee(o)+'"'}else n=ee(t.name)+'="'+ee(e.getAttribute(r))+'"'}else n=ee(r)+'="'+ee(t.value)+'"';return n}function ae(e,t){return e.count<t.count?-1:e.count===t.count?0:1}function oe(e){return!te.includes(e.name)&&-1===e.name.indexOf(":")&&(!e.value||e.value.length<ne)}function ie(t,n){var e=t.parentNode&&Array.from(t.parentNode.children||"")||[];return e.find(function(e){return e!==t&&axe.utils.matchesSelector(e,n)})?":nth-child("+(1+e.indexOf(t))+")":""}function ue(e){if(e.getAttribute("id")){var t=e.getRootNode&&e.getRootNode()||document,n="#"+ee(e.getAttribute("id")||"");return n.match(/player_uid_/)||1!==t.querySelectorAll(n).length?void 0:n}}function se(e){return void 0===Z&&(Z=axe.utils.isXHTML(document)),ee(Z?e.localName:e.nodeName.toLowerCase())}function le(e,t){var n,r="",a=function(n,e){var r=[],a=e.classes,o=e.tags;return n.classList&&Array.from(n.classList).forEach(function(e){var t=ee(e);a[t]<o[n.nodeName]&&r.push({name:t,count:a[t],species:"class"})}),r.sort(ae)}(e,t),o=function(n,e){var r=[],a=e.attributes,o=e.tags;return n.hasAttributes()&&Array.from(axe.utils.getNodeAttributes(n)).filter(oe).forEach(function(e){var t=re(n,e);t&&a[t]<o[n.nodeName]&&r.push({name:t,count:a[t],species:"attribute"})}),r.sort(ae)}(e,t);return a.length&&1===a[0].count?n=[a[0]]:o.length&&1===o[0].count?(n=[o[0]],r=se(e)):((n=a.concat(o)).sort(ae),(n=n.slice(0,3)).some(function(e){return"class"===e.species})?n.sort(function(e,t){return e.species!==t.species&&"class"===e.species?-1:e.species===t.species?0:1}):r=se(e)),r+n.reduce(function(e,t){switch(t.species){case"class":return e+"."+t.name;case"attribute":return e+"["+t.name+"]"}return e},"")}function ce(e,t,n){if(!axe._selectorData)throw new Error("Expect axe._selectorData to be set up");var r,a,o=t.toRoot,i=void 0!==o&&o;do{var u=ue(e);u||(u=le(e,axe._selectorData),u+=ie(e,u)),r=r?u+" > "+r:u,a=a?a.filter(function(e){return axe.utils.matchesSelector(e,r)}):Array.from(n.querySelectorAll(r)),e=e.parentElement}while((1<a.length||i)&&e&&11!==e.nodeType);return 1===a.length?r:-1!==r.indexOf(" > ")?":root"+r.substring(r.indexOf(" > ")):":root"}axe.utils.getSelectorData=function(e){function t(){var e=a.pop(),n=e.actualNode;if(n.querySelectorAll){var t=n.nodeName;r.tags[t]?r.tags[t]++:r.tags[t]=1,n.classList&&Array.from(n.classList).forEach(function(e){var t=ee(e);r.classes[t]?r.classes[t]++:r.classes[t]=1}),n.hasAttributes()&&Array.from(axe.utils.getNodeAttributes(n)).filter(oe).forEach(function(e){var t=re(n,e);t&&(r.attributes[t]?r.attributes[t]++:r.attributes[t]=1)})}for(e.children.length&&(o.push(a),a=e.children.slice());!a.length&&o.length;)a=o.pop()}for(var r={classes:{},tags:{},attributes:{}},a=(e=Array.isArray(e)?e:[e]).slice(),o=[];a.length;)t();return r},axe.utils.getSelector=function(e,t){var n=1<arguments.length&&void 0!==t?t:{};if(!e)return"";var r=e.getRootNode&&e.getRootNode()||document;if(11!==r.nodeType)return ce(e,n,r);for(var a=[];11===r.nodeType;)a.push({elm:e,doc:r}),r=(e=r.host).getRootNode();return a.push({elm:e,doc:r}),a.reverse().map(function(e){return ce(e.elm,n,e.doc)})},axe.utils.getStyleSheetFactory=function(d){if(!d)throw new Error("axe.utils.getStyleSheetFactory should be invoked with an argument");return function(e){var t=e.data,n=e.isCrossOrigin,r=void 0!==n&&n,a=e.shadowId,o=e.root,i=e.priority,u=e.isLink,s=void 0!==u&&u,l=d.createElement("style");if(s){var c=d.createTextNode('@import "'.concat(t.href,'"'));l.appendChild(c)}else l.appendChild(d.createTextNode(t));return d.head.appendChild(l),{sheet:l.sheet,isCrossOrigin:r,shadowId:a,root:o,priority:i}}},axe.utils.getXpath=function(e){return function(e){return e.reduce(function(e,t){return t.id?"/".concat(t.str,"[@id='").concat(t.id,"']"):e+"/".concat(t.str)+(0<t.count?"[".concat(t.count,"]"):"")},"")}(function e(t,n){var r,a;if(!t)return[];if(!n&&9===t.nodeType)return n=[{str:"html"}];if(n=n||[],t.parentNode&&t.parentNode!==t&&(n=e(t.parentNode,n)),t.previousSibling){for(a=1,r=t.previousSibling;1===r.nodeType&&r.nodeName===t.nodeName&&a++,r=r.previousSibling;);1===a&&(a=null)}else if(t.nextSibling)for(r=t.nextSibling;r=1===r.nodeType&&r.nodeName===t.nodeName?(a=1,null):(a=null,r.previousSibling););if(1===t.nodeType){var o={};o.str=t.nodeName.toLowerCase();var i=t.getAttribute&&axe.utils.escapeSelector(t.getAttribute("id"));i&&1===t.ownerDocument.querySelectorAll("#"+i).length&&(o.id=t.getAttribute("id")),1<a&&(o.count=a),n.push(o)}return n}(e))},axe.utils.injectStyle=function(e){"use strict";if(Q&&Q.parentNode)return void 0===Q.styleSheet?Q.appendChild(document.createTextNode(e)):Q.styleSheet.cssText+=e,Q;if(e){var t=document.head||document.getElementsByTagName("head")[0];return(Q=document.createElement("style")).type="text/css",void 0===Q.styleSheet?Q.appendChild(document.createTextNode(e)):Q.styleSheet.cssText=e,t.appendChild(Q),Q}},axe.utils.isHidden=function(e,t){"use strict";var n=axe.utils.getNodeFromTree(e);if(9===e.nodeType)return!1;if(11===e.nodeType&&(e=e.host),n&&null!==n._isHidden)return n._isHidden;var r=window.getComputedStyle(e,null);if(!r||!e.parentNode||"none"===r.getPropertyValue("display")||!t&&"hidden"===r.getPropertyValue("visibility")||"true"===e.getAttribute("aria-hidden"))return!0;var a=e.assignedSlot?e.assignedSlot:e.parentNode,o=axe.utils.isHidden(a,!0);return n&&(n._isHidden=o),o};var de=["a","abbr","address","area","article","aside","audio","b","base","bdi","bdo","blockquote","body","br","button","canvas","caption","cite","code","col","colgroup","data","datalist","dd","del","details","dfn","dialog","div","dl","dt","em","embed","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe","img","input","ins","kbd","keygen","label","legend","li","link","main","map","mark","math","menu","menuitem","meta","meter","nav","noscript","object","ol","optgroup","option","output","p","param","picture","pre","progress","q","rb","rp","rt","rtc","ruby","s","samp","script","section","select","slot","small","source","span","strong","style","sub","summary","sup","svg","table","tbody","td","template","textarea","tfoot","th","thead","time","title","tr","track","u","ul","var","video","wbr"];axe.utils.isHtmlElement=function(e){var t=e.nodeName.toLowerCase();return de.includes(t)&&"http://www.w3.org/2000/svg"!==e.namespaceURI};var me,pe,fe=["article","aside","blockquote","body","div","footer","h1","h2","h3","h4","h5","h6","header","main","nav","p","section","span"];function he(e){return function(e){if(Array.isArray(e)){for(var t=0,n=new Array(e.length);t<e.length;t++)n[t]=e[t];return n}}(e)||function(e){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e))return Array.from(e)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}()}function be(){throw new TypeError("Invalid attempt to spread non-iterable instance")}function ge(e){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e))return Array.from(e)}function ye(e){if(Array.isArray(e)){for(var t=0,n=new Array(e.length);t<e.length;t++)n[t]=e[t];return n}}function ve(e){return"function"==typeof e||"[object Function]"===me.call(e)}function De(e){var t=function(e){var t=Number(e);return isNaN(t)?0:0!==t&&isFinite(t)?(0<t?1:-1)*Math.floor(Math.abs(t)):t}(e);return Math.min(Math.max(t,0),pe)}function we(e){var t=e.nodeName.toUpperCase(),n=e.getAttribute("href"),r=e.getAttribute("rel"),a="LINK"===t&&n&&r&&e.rel.toUpperCase().includes("STYLESHEET");return"STYLE"===t||a&&ke(e.media)}function ke(e){return!e||!e.toUpperCase().includes("PRINT")}function R(){return(R=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}function S(e){return(S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function S(e){return(S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function xe(a,o){"use strict";return function(e){var t=a[e.id]||{},n=t.messages||{},r=Object.assign({},t);delete r.messages,void 0===e.result?"object"===S(n.incomplete)?r.message=function(){return function(t,n){function r(e){return e.incomplete&&e.incomplete.default?e.incomplete.default:u.incompleteFallbackMessage()}if(!t||!t.missingData)return r(n);try{var e=n.incomplete[t.missingData[0].reason];if(!e)throw new Error;return e}catch(e){return"string"==typeof t.missingData?n.incomplete[t.missingData]:r(n)}}(e.data,n)}:r.message=n.incomplete:r.message=e.result===o?n.pass:n.fail,axe.utils.extendMetaData(e,r)}}axe.utils.isShadowRoot=function(e){var t=e.nodeName.toLowerCase();return!(!e.shadowRoot||!/^[a-z][a-z0-9_.-]*-[a-z0-9_.-]*$/.test(t)&&!fe.includes(t))},axe.utils.isXHTML=function(e){"use strict";return!!e.createElement&&"A"===e.createElement("A").localName},axe.utils.mergeResults=function(e,r){"use strict";var a=[];return e.forEach(function(n){var e=function(e){"use strict";return e&&e.results?Array.isArray(e.results)?e.results.length?e.results:null:[e.results]:null}(n);e&&e.length&&e.forEach(function(e){e.nodes&&n.frame&&function(e,n,t,r){"use strict";var a={element:t,selector:r,xpath:axe.utils.getXpath(t)};e.forEach(function(e){e.node=axe.utils.DqElement.fromFrame(e.node,n,a);var t=axe.utils.getAllChecks(e);t.length&&t.forEach(function(e){e.relatedNodes=e.relatedNodes.map(function(e){return axe.utils.DqElement.fromFrame(e,n,a)})})})}(e.nodes,r,n.frameElement,n.frame);var t=axe.utils.findBy(a,"id",e.id);t?e.nodes.length&&function(e,t){"use strict";for(var n,r,a=t[0].node,o=0,i=e.length;o<i;o++)if(r=e[o].node,0<(n=axe.utils.nodeSorter({actualNode:r.element},{actualNode:a.element}))||0===n&&a.selector.length<r.selector.length)return e.splice.apply(e,[o,0].concat(t));e.push.apply(e,t)}(t.nodes,e.nodes):a.push(e)})}),a},axe.utils.nodeSorter=function(e,t){return(e=e.actualNode||e)===(t=t.actualNode||t)?0:4&e.compareDocumentPosition(t)?-1:1},axe.utils.parseCrossOriginStylesheet=function(e,r,a,o,i){var t={method:"get",url:e};return o.push(e),axe.imports.axios(t).then(function(e){var t=e.data,n=r.convertDataToStylesheet({data:t,isCrossOrigin:i,priority:a,root:r.rootNode,shadowId:r.shadowId});return axe.utils.parseStylesheet(n.sheet,r,a,o,n.isCrossOrigin)})},axe.utils.parseSameOriginStylesheet=function(e,a,o,i,t){var n=4<arguments.length&&void 0!==t&&t,r=Array.from(e.cssRules);if(!r)return Promise.resolve();var u=r.filter(function(e){return 3===e.type});if(!u.length)return Promise.resolve({isCrossOrigin:n,priority:o,root:a.rootNode,shadowId:a.shadowId,sheet:e});var s=u.filter(function(e){return e.href}).map(function(e){return e.href}).filter(function(e){return!i.includes(e)}).map(function(e,t){var n=[].concat(he(o),[t]),r=/^https?:\/\/|^\/\//i.test(e);return axe.utils.parseCrossOriginStylesheet(e,a,n,i,r)}),l=r.filter(function(e){return 3!==e.type});return l.length&&s.push(Promise.resolve(a.convertDataToStylesheet({data:l.map(function(e){return e.cssText}).join(),isCrossOrigin:n,priority:o,root:a.rootNode,shadowId:a.shadowId}))),Promise.all(s)},axe.utils.parseStylesheet=function(e,t,n,r,a){var o=4<arguments.length&&void 0!==a&&a;return function(e){try{return!(!e.cssRules&&e.href)}catch(e){return!1}}(e)?axe.utils.parseSameOriginStylesheet(e,t,n,r,o):axe.utils.parseCrossOriginStylesheet(e.href,t,n,r,!0)},utils.performanceTimer=function(){"use strict";function e(){if(window.performance&&window.performance)return window.performance.now()}var t=null,n=e();return{start:function(){this.mark("mark_axe_start")},end:function(){this.mark("mark_axe_end"),this.measure("axe","mark_axe_start","mark_axe_end"),this.logMeasures("axe")},auditStart:function(){this.mark("mark_audit_start")},auditEnd:function(){this.mark("mark_audit_end"),this.measure("audit_start_to_end","mark_audit_start","mark_audit_end"),this.logMeasures()},mark:function(e){window.performance&&void 0!==window.performance.mark&&window.performance.mark(e)},measure:function(e,t,n){window.performance&&void 0!==window.performance.measure&&window.performance.measure(e,t,n)},logMeasures:function(e){function t(e){axe.log("Measure "+e.name+" took "+e.duration+"ms")}if(window.performance&&void 0!==window.performance.getEntriesByType)for(var n=window.performance.getEntriesByName("mark_axe_start")[0],r=window.performance.getEntriesByType("measure").filter(function(e){return e.startTime>=n.startTime}),a=0;a<r.length;++a){var o=r[a];if(o.name===e)return void t(o);t(o)}},timeElapsed:function(){return e()-n},reset:function(){t=t||e(),n=e()}}}(),"function"!=typeof Object.assign&&(Object.assign=function(e){"use strict";if(null==e)throw new TypeError("Cannot convert undefined or null to object");for(var t=Object(e),n=1;n<arguments.length;n++){var r=arguments[n];if(null!=r)for(var a in r)r.hasOwnProperty(a)&&(t[a]=r[a])}return t}),Array.prototype.find||Object.defineProperty(Array.prototype,"find",{value:function(e){if(null===this)throw new TypeError("Array.prototype.find called on null or undefined");if("function"!=typeof e)throw new TypeError("predicate must be a function");for(var t,n=Object(this),r=n.length>>>0,a=arguments[1],o=0;o<r;o++)if(t=n[o],e.call(a,t,o,n))return t}}),axe.utils.pollyfillElementsFromPoint=function(){if(document.elementsFromPoint)return document.elementsFromPoint;if(document.msElementsFromPoint)return document.msElementsFromPoint;var e,t=((e=document.createElement("x")).style.cssText="pointer-events:auto","auto"===e.style.pointerEvents),u=t?"pointer-events":"visibility",s=t?"none":"hidden",l=document.createElement("style");return l.innerHTML=t?"* { pointer-events: all }":"* { visibility: visible }",function(e,t){var n,r,a,o=[],i=[];for(document.head.appendChild(l);(n=document.elementFromPoint(e,t))&&-1===o.indexOf(n);)o.push(n),i.push({value:n.style.getPropertyValue(u),priority:n.style.getPropertyPriority(u)}),n.style.setProperty(u,s,"important");for(o.indexOf(document.documentElement)<o.length-1&&(o.splice(o.indexOf(document.documentElement),1),o.push(document.documentElement)),r=i.length;a=i[--r];)o[r].style.setProperty(u,a.value?a.value:"",a.priority);return document.head.removeChild(l),o}},"function"==typeof window.addEventListener&&(document.elementsFromPoint=axe.utils.pollyfillElementsFromPoint()),Array.prototype.includes||Object.defineProperty(Array.prototype,"includes",{value:function(e,t){"use strict";var n=Object(this),r=parseInt(n.length,10)||0;if(0===r)return!1;var a,o,i=parseInt(t,10)||0;for(0<=i?a=i:(a=r+i)<0&&(a=0);a<r;){if(e===(o=n[a])||e!=e&&o!=o)return!0;a++}return!1}}),Array.prototype.some||Object.defineProperty(Array.prototype,"some",{value:function(e,t){"use strict";if(null==this)throw new TypeError("Array.prototype.some called on null or undefined");if("function"!=typeof e)throw new TypeError;for(var n=Object(this),r=n.length>>>0,a=2<=arguments.length?t:void 0,o=0;o<r;o++)if(o in n&&e.call(a,n[o],o,n))return!0;return!1}}),Array.from||Object.defineProperty(Array,"from",{value:(me=Object.prototype.toString,pe=Math.pow(2,53)-1,function(e,t,n){var r=Object(e);if(null==e)throw new TypeError("Array.from requires an array-like object - not null or undefined");var a,o=1<arguments.length?t:void 0;if(void 0!==o){if(!ve(o))throw new TypeError("Array.from: when provided, the second argument must be a function");2<arguments.length&&(a=n)}for(var i,u=De(r.length),s=ve(this)?Object(new this(u)):new Array(u),l=0;l<u;)i=r[l],s[l]=o?void 0===a?o(i,l):o.call(a,i,l):i,l+=1;return s.length=u,s})}),String.prototype.includes||(String.prototype.includes=function(e,t){return"number"!=typeof t&&(t=0),!(t+e.length>this.length)&&-1!==this.indexOf(e,t)}),axe.utils.preloadCssom=function(e){var t=e.treeRoot,n=function(e){var t=[],n=axe.utils.querySelectorAllFilter(e,"*",function(e){return!t.includes(e.shadowId)&&(t.push(e.shadowId),!0)}).map(function(e){return{shadowId:e.shadowId,rootNode:axe.utils.getRootNode(e.actualNode)}});return axe.utils.uniqueArray(n,[])}(void 0===t?axe._tree[0]:t);if(!n.length)return Promise.resolve();var r=document.implementation.createHTMLDocument("Dynamic document for loading cssom");return function(e,l){var c=[];return e.forEach(function(e,t){var n=e.rootNode,r=e.shadowId,a=function(e,t,n){var r;r=11===e.nodeType&&t?function(o,i){return Array.from(o.children).filter(we).reduce(function(e,t){var n=t.nodeName.toUpperCase(),r="STYLE"===n?t.textContent:t,a=i({data:r,isLink:"LINK"===n,root:o});return e.push(a.sheet),e},[])}(e,n):function(e){return Array.from(e.styleSheets).filter(function(e){return ke(e.media.mediaText)})}(e);return function(e){var t=[];return e.filter(function(e){return!e.href||!t.includes(e.href)&&(t.push(e.href),!0)})}(r)}(n,r,l);if(!a)return Promise.all(c);var o=t+1,i={rootNode:n,shadowId:r,convertDataToStylesheet:l,rootIndex:o},u=[],s=Promise.all(a.map(function(e,t){var n=[o,t];return axe.utils.parseStylesheet(e,i,n,u)}));c.push(s)}),Promise.all(c)}(n,axe.utils.getStyleSheetFactory(r)).then(function(e){return function n(e){return e.reduce(function(e,t){return Array.isArray(t)?e.concat(n(t)):e.concat(t)},[])}(e)})},axe.utils.shouldPreload=function(e){return!e||void 0===e.preload||null===e.preload||("boolean"==typeof e.preload?e.preload:function(e){return"object"===S(e)&&Array.isArray(e.assets)}(e.preload))},axe.utils.getPreloadConfig=function(e){var t=axe.constants.preload,n=t.assets,r=t.timeout,a={assets:n,timeout:r};if(!e.preload)return a;if("boolean"==typeof e.preload)return a;if(!e.preload.assets.every(function(e){return n.includes(e.toLowerCase())}))throw new Error("Requested assets, not supported. "+"Supported assets are: ".concat(n.join(", "),"."));return a.assets=axe.utils.uniqueArray(e.preload.assets.map(function(e){return e.toLowerCase()}),[]),e.preload.timeout&&"number"==typeof e.preload.timeout&&!Number.isNaN(e.preload.timeout)&&(a.timeout=e.preload.timeout),a},axe.utils.preload=function(o){var i={cssom:axe.utils.preloadCssom};return axe.utils.shouldPreload(o)?new Promise(function(n,e){var t=axe.utils.getPreloadConfig(o),r=t.assets,a=t.timeout;setTimeout(function(){return e("Preload assets timed out.")},a),Promise.all(r.map(function(t){return i[t](o).then(function(e){return function(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}({},t,e)})})).then(function(e){var t=e.reduce(function(e,t){return R({},e,{},t)},{});n(t)})}):Promise.resolve()},axe.utils.publishMetaData=function(e){"use strict";var t=axe._audit.data.checks||{},n=axe._audit.data.rules||{},r=axe.utils.findBy(axe._audit.rules,"id",e.id)||{};e.tags=axe.utils.clone(r.tags||[]);var a=xe(t,!0),o=xe(t,!1);e.nodes.forEach(function(e){e.any.forEach(a),e.all.forEach(a),e.none.forEach(o)}),axe.utils.extendMetaData(e,axe.utils.clone(n[e.id]||{}))};var Ee=function(){},Ce=function(){};var Ae,Fe,je=(Ae=/(?=[\-\[\]{}()*+?.\\\^$|,#\s])/g,function(e){return e.replace(Ae,"\\")}),ze=/\\/g;function qe(e){if(e)return e.map(function(e){var t,n,r=e.name.replace(ze,""),a=(e.value||"").replace(ze,"");switch(e.operator){case"^=":n=new RegExp("^"+je(a));break;case"$=":n=new RegExp(je(a)+"$");break;case"~=":n=new RegExp("(^|\\s)"+je(a)+"(\\s|$)");break;case"|=":n=new RegExp("^"+je(a)+"(-|$)");break;case"=":t=function(e){return a===e};break;case"*=":t=function(e){return e&&e.includes(a)};break;case"!=":t=function(e){return a!==e};break;default:t=function(e){return!!e}}return""===a&&/^[*$^]=$/.test(e.operator)&&(t=function(){return!1}),{key:r,value:a,test:t=t||function(e){return e&&n.test(e)}}})}function Ne(e){if(e)return e.map(function(e){return{value:e=e.replace(ze,""),regexp:new RegExp("(^|\\s)"+je(e)+"(\\s|$)")}})}function Te(e){if(e)return e.map(function(e){var t;return"not"===e.name&&(t=(t=e.value).selectors?t.selectors:[t],t=Ee(t)),{name:e.name,expressions:t,value:e.value}})}function Se(e,t,n,r){var a={vNodes:e.slice(),anyLevel:t,thisLevel:n,parentShadowId:r};return a.vNodes.reverse(),a}function Re(e,t){return function(e,t){return 1===e.props.nodeType&&("*"===t.tag||e.props.nodeName===t.tag)}(e,t[0])&&function(t,e){return!e.classes||e.classes.every(function(e){return t.hasClass(e.value)})}(e,t[0])&&function(r,e){return!e.attributes||e.attributes.reduce(function(e,t){var n=r.attr(t.key);return e&&null!==n&&(!t.value||t.test(n))},!0)}(e,t[0])&&function(e,t){return!t.id||e.props.id===t.id}(e,t[0])&&function(n,e){return!(e.pseudos&&!e.pseudos.reduce(function(e,t){if("not"===t.name)return e&&!Ce([n],t.expressions,!1).length;throw new Error("the pseudo selector "+t.name+" has not yet been implemented")},!0))}(e,t[0])}function S(e){return(S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function S(e){return(S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function Oe(t,e){"use strict";var n,r,a=axe._audit&&axe._audit.tagExclude?axe._audit.tagExclude:[];return r=e.hasOwnProperty("include")||e.hasOwnProperty("exclude")?(n=e.include||[],n=Array.isArray(n)?n:[n],r=e.exclude||[],(r=Array.isArray(r)?r:[r]).concat(a.filter(function(e){return-1===n.indexOf(e)}))):(n=Array.isArray(e)?e:[e],a.filter(function(e){return-1===n.indexOf(e)})),!!(n.some(function(e){return-1!==t.tags.indexOf(e)})||0===n.length&&!1!==t.enabled)&&r.every(function(e){return-1===t.tags.indexOf(e)})}function _e(e){"use strict";return e.sort(function(e,t){return axe.utils.contains(e,t)?1:-1})[0]}function Be(t,e){"use strict";var n=e.include&&_e(e.include.filter(function(e){return axe.utils.contains(e,t)})),r=e.exclude&&_e(e.exclude.filter(function(e){return axe.utils.contains(e,t)}));return!!(!r&&n||r&&axe.utils.contains(r,n))}function Le(e,t){"use strict";var n;if(0===e.length)return t;e.length<t.length&&(n=e,e=t,t=n);for(var r=0,a=t.length;r<a;r++)e.includes(t[r])||e.push(t[r]);return e}Ee=function(e){return e.map(function(e){for(var t=[],n=e.rule;n;)t.push({tag:n.tagName?n.tagName.toLowerCase():"*",combinator:n.nestingOperator?n.nestingOperator:" ",id:n.id,attributes:qe(n.attrs),classes:Ne(n.classNames),pseudos:Te(n.pseudos)}),n=n.rule;return t})},Ce=function(e,t,n,r){for(var a=[],o=Se(Array.isArray(e)?e:[e],t,[],e[0].shadowId),i=[];o.vNodes.length;){for(var u=o.vNodes.pop(),s=[],l=[],c=o.anyLevel.slice().concat(o.thisLevel),d=!1,m=0;m<c.length;m++){var p=c[m];if(Re(u,p)&&(!p[0].id||u.shadowId===o.parentShadowId))if(1===p.length)d||r&&!r(u)||(i.push(u),d=!0);else{var f=p.slice(1);if(!1===[" ",">"].includes(f[0].combinator))throw new Error("axe.utils.querySelectorAll does not support the combinator: "+p[1].combinator);">"===f[0].combinator?s.push(f):l.push(f)}!o.anyLevel.includes(p)||p[0].id&&u.shadowId!==o.parentShadowId||l.push(p)}for(u.children&&u.children.length&&n&&(a.push(o),o=Se(u.children,l,s,u.shadowId));!o.vNodes.length&&a.length;)o=a.pop()}return i},axe.utils.querySelectorAll=function(e,t){return axe.utils.querySelectorAllFilter(e,t)},axe.utils.querySelectorAllFilter=function(e,t,n){e=Array.isArray(e)?e:[e];var r=axe.utils.cssParser.parse(t);return r=r.selectors?r.selectors:[r],r=Ee(r),Ce(e,r,!0,n)},function(){"use strict";function m(){}function p(e){if("function"!=typeof e)throw new TypeError("Queue methods require functions as arguments")}axe.utils.queue=function(){function t(e){r=e,setTimeout(function(){null!=r&&axe.log("Uncaught error (of queue)",r)},1)}var r,a=[],o=0,i=0,n=m,u=!1,s=t;function l(t){return function(e){a[t]=e,(i-=1)||n===m||(u=!0,n(a))}}function c(e){return n=m,s(e),a}var d={defer:function(e){if("object"===S(e)&&e.then&&e.catch){var n=e;e=function(e,t){n.then(e).catch(t)}}if(p(e),void 0===r){if(u)throw new Error("Queue already completed");return a.push(e),++i,function(){for(var e=a.length;o<e;o++){var t=a[o];try{t.call(null,l(o),c)}catch(e){c(e)}}}(),d}},then:function(e){if(p(e),n!==m)throw new Error("queue `then` already set");return r||(n=e,i||(u=!0,n(a))),d},catch:function(e){if(p(e),s!==t)throw new Error("queue `catch` already set");return r?(e(r),r=null):s=e,d},abort:c};return d}}(),function(e){"use strict";var s={},i={},a=Object.freeze(["EvalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"]);function l(){var e="axeAPI",t="";return void 0!==axe&&axe._audit&&axe._audit.application&&(e=axe._audit.application),void 0!==axe&&(t=axe.version),e+"."+t}function u(e,t,n,r,a,o){var i;n instanceof Error&&(i={name:n.name,message:n.message,stack:n.stack},n=void 0);var u={uuid:r,topic:t,message:n,error:i,_respondable:!0,_source:l(),_keepalive:a};"function"==typeof o&&(s[r]=o),e.postMessage(JSON.stringify(u),"*")}function t(e,t,n,r,a){u(e,t,n,Fe.v1(),r,a)}function c(r,a,o){return function(e,t,n){u(r,a,e,o,t,n)}}function o(e){var t;if("string"==typeof e){try{t=JSON.parse(e)}catch(e){}if(function(e){if("object"!==S(e)||"string"!=typeof e.uuid||!0!==e._respondable)return!1;var t=l();return e._source===t||"axeAPI.x.y.z"===e._source||"axeAPI.x.y.z"===t}(t))return"object"===S(t.error)?t.error=function(e){var t=e.message||"Unknown error occurred",n=a.includes(e.name)?e.name:"Error",r=window[n]||Error;return e.stack&&(t+="\n"+e.stack.replace(e.message,"")),new r(t)}(t.error):t.error=void 0,t}}t.subscribe=function(e,t){i[e]=t},t.isInFrame=function(e){return!!(e=e||window).frameElement},"function"==typeof window.addEventListener&&window.addEventListener("message",function(t){var n=o(t.data);if(n){var r=n.uuid,e=n._keepalive,a=s[r];if(a)a(n.error||n.message,e,c(t.source,n.topic,r)),e||delete s[r];if(!n.error)try{!function(e,t,n){var r=t.topic,a=i[r];if(a){var o=c(e,null,t.uuid);a(t.message,n,o)}}(t.source,n,e)}catch(e){u(t.source,n.topic,e,r,!1)}}},!1),e.respondable=t}(utils),axe.utils.ruleShouldRun=function(e,t,n){"use strict";var r=n.runOnly||{},a=(n.rules||{})[e.id];return!(e.pageLevel&&!t.page)&&("rule"===r.type?-1!==r.values.indexOf(e.id):a&&"boolean"==typeof a.enabled?a.enabled:"tag"===r.type&&r.values?Oe(e,r.values):Oe(e,[]))},axe.utils.getScrollState=function(e){var t=0<arguments.length&&void 0!==e?e:window,n=t.document.documentElement;return[void 0!==t.pageXOffset?{elm:t,top:t.pageYOffset,left:t.pageXOffset}:{elm:n,top:n.scrollTop,left:n.scrollLeft}].concat(function r(e){return Array.from(e.children).reduce(function(e,t){var n=axe.utils.getScroll(t);return n&&e.push(n),e.concat(r(t))},[])}(document.body))},axe.utils.setScrollState=function(e){e.forEach(function(e){return function(e,t,n){if(e===window)return e.scroll(n,t);e.scrollTop=t,e.scrollLeft=n}(e.elm,e.top,e.left)})},axe.utils.select=function(e,t){"use strict";var n,r=[];if(axe._selectCache)for(var a=0,o=axe._selectCache.length;a<o;a++){var i=axe._selectCache[a];if(i.selector===e)return i.result}for(var u,s=(u=t,function(e){return Be(e,u)}),l=function(e){return e.reduce(function(e,t){return e.length&&axe.utils.contains(e[e.length-1],t)||e.push(t),e},[])}(t.include),c=0;c<l.length;c++)n=l[c],r=Le(r,axe.utils.querySelectorAllFilter(n,e,s));return axe._selectCache&&axe._selectCache.push({selector:e,result:r}),r},axe.utils.toArray=function(e){"use strict";return Array.prototype.slice.call(e)},axe.utils.uniqueArray=function(e,t){return e.concat(t).filter(function(e,t,n){return n.indexOf(e)===t})},axe.utils.tokenList=function(e){"use strict";return e.trim().replace(/\s{2,}/g," ").split(" ")},function(e){var i,t=e.crypto||e.msCrypto;if(!i&&t&&t.getRandomValues){var n=new Uint8Array(16);i=function(){return t.getRandomValues(n),n}}if(!i){var r=new Array(16);i=function(){for(var e,t=0;t<16;t++)0==(3&t)&&(e=4294967296*Math.random()),r[t]=e>>>((3&t)<<3)&255;return r}}for(var u="function"==typeof e.Buffer?e.Buffer:Array,a=[],o={},s=0;s<256;s++)a[s]=(s+256).toString(16).substr(1),o[a[s]]=s;function p(e,t){var n=t||0,r=a;return r[e[n++]]+r[e[n++]]+r[e[n++]]+r[e[n++]]+"-"+r[e[n++]]+r[e[n++]]+"-"+r[e[n++]]+r[e[n++]]+"-"+r[e[n++]]+r[e[n++]]+"-"+r[e[n++]]+r[e[n++]]+r[e[n++]]+r[e[n++]]+r[e[n++]]+r[e[n++]]}var l=i(),f=[1|l[0],l[1],l[2],l[3],l[4],l[5]],h=16383&(l[6]<<8|l[7]),b=0,g=0;function c(e,t,n){var r=t&&n||0;"string"==typeof e&&(t="binary"==e?new u(16):null,e=null);var a=(e=e||{}).random||(e.rng||i)();if(a[6]=15&a[6]|64,a[8]=63&a[8]|128,t)for(var o=0;o<16;o++)t[r+o]=a[o];return t||p(a)}(Fe=c).v1=function(e,t,n){var r=t&&n||0,a=t||[],o=null!=(e=e||{}).clockseq?e.clockseq:h,i=null!=e.msecs?e.msecs:(new Date).getTime(),u=null!=e.nsecs?e.nsecs:g+1,s=i-b+(u-g)/1e4;if(s<0&&null==e.clockseq&&(o=o+1&16383),(s<0||b<i)&&null==e.nsecs&&(u=0),1e4<=u)throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");b=i,h=o;var l=(1e4*(268435455&(i+=122192928e5))+(g=u))%4294967296;a[r++]=l>>>24&255,a[r++]=l>>>16&255,a[r++]=l>>>8&255,a[r++]=255&l;var c=i/4294967296*1e4&268435455;a[r++]=c>>>8&255,a[r++]=255&c,a[r++]=c>>>24&15|16,a[r++]=c>>>16&255,a[r++]=o>>>8|128,a[r++]=255&o;for(var d=e.node||f,m=0;m<6;m++)a[r+m]=d[m];return t||p(a)},Fe.v4=c,Fe.parse=function(e,t,n){var r=t&&n||0,a=0;for(t=t||[],e.toLowerCase().replace(/[0-9a-f]{2}/g,function(e){a<16&&(t[r+a++]=o[e])});a<16;)t[r+a++]=0;return t},Fe.unparse=p,Fe.BufferClass=u}(window),axe.utils.validInputTypes=function(){"use strict";return["hidden","text","search","tel","url","email","password","date","month","week","time","datetime-local","number","range","color","checkbox","radio","file","submit","image","reset","button"]};var Ie=["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","in","io","is","it","iu","iw","ja","ji","jv","jw","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mo","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","sh","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu","aaa","aab","aac","aad","aae","aaf","aag","aah","aai","aak","aal","aam","aan","aao","aap","aaq","aas","aat","aau","aav","aaw","aax","aaz","aba","abb","abc","abd","abe","abf","abg","abh","abi","abj","abl","abm","abn","abo","abp","abq","abr","abs","abt","abu","abv","abw","abx","aby","abz","aca","acb","acd","ace","acf","ach","aci","ack","acl","acm","acn","acp","acq","acr","acs","act","acu","acv","acw","acx","acy","acz","ada","adb","add","ade","adf","adg","adh","adi","adj","adl","adn","ado","adp","adq","adr","ads","adt","adu","adw","adx","ady","adz","aea","aeb","aec","aed","aee","aek","ael","aem","aen","aeq","aer","aes","aeu","aew","aey","aez","afa","afb","afd","afe","afg","afh","afi","afk","afn","afo","afp","afs","aft","afu","afz","aga","agb","agc","agd","age","agf","agg","agh","agi","agj","agk","agl","agm","agn","ago","agp","agq","agr","ags","agt","agu","agv","agw","agx","agy","agz","aha","ahb","ahg","ahh","ahi","ahk","ahl","ahm","ahn","aho","ahp","ahr","ahs","aht","aia","aib","aic","aid","aie","aif","aig","aih","aii","aij","aik","ail","aim","ain","aio","aip","aiq","air","ais","ait","aiw","aix","aiy","aja","ajg","aji","ajn","ajp","ajt","aju","ajw","ajz","akb","akc","akd","ake","akf","akg","akh","aki","akj","akk","akl","akm","ako","akp","akq","akr","aks","akt","aku","akv","akw","akx","aky","akz","ala","alc","ald","ale","alf","alg","alh","ali","alj","alk","all","alm","aln","alo","alp","alq","alr","als","alt","alu","alv","alw","alx","aly","alz","ama","amb","amc","ame","amf","amg","ami","amj","amk","aml","amm","amn","amo","amp","amq","amr","ams","amt","amu","amv","amw","amx","amy","amz","ana","anb","anc","and","ane","anf","ang","anh","ani","anj","ank","anl","anm","ann","ano","anp","anq","anr","ans","ant","anu","anv","anw","anx","any","anz","aoa","aob","aoc","aod","aoe","aof","aog","aoh","aoi","aoj","aok","aol","aom","aon","aor","aos","aot","aou","aox","aoz","apa","apb","apc","apd","ape","apf","apg","aph","api","apj","apk","apl","apm","apn","apo","app","apq","apr","aps","apt","apu","apv","apw","apx","apy","apz","aqa","aqc","aqd","aqg","aql","aqm","aqn","aqp","aqr","aqt","aqz","arb","arc","ard","are","arh","ari","arj","ark","arl","arn","aro","arp","arq","arr","ars","art","aru","arv","arw","arx","ary","arz","asa","asb","asc","asd","ase","asf","asg","ash","asi","asj","ask","asl","asn","aso","asp","asq","asr","ass","ast","asu","asv","asw","asx","asy","asz","ata","atb","atc","atd","ate","atg","ath","ati","atj","atk","atl","atm","atn","ato","atp","atq","atr","ats","att","atu","atv","atw","atx","aty","atz","aua","aub","auc","aud","aue","auf","aug","auh","aui","auj","auk","aul","aum","aun","auo","aup","auq","aur","aus","aut","auu","auw","aux","auy","auz","avb","avd","avi","avk","avl","avm","avn","avo","avs","avt","avu","avv","awa","awb","awc","awd","awe","awg","awh","awi","awk","awm","awn","awo","awr","aws","awt","awu","awv","aww","awx","awy","axb","axe","axg","axk","axl","axm","axx","aya","ayb","ayc","ayd","aye","ayg","ayh","ayi","ayk","ayl","ayn","ayo","ayp","ayq","ayr","ays","ayt","ayu","ayx","ayy","ayz","aza","azb","azc","azd","azg","azj","azm","azn","azo","azt","azz","baa","bab","bac","bad","bae","baf","bag","bah","bai","baj","bal","ban","bao","bap","bar","bas","bat","bau","bav","baw","bax","bay","baz","bba","bbb","bbc","bbd","bbe","bbf","bbg","bbh","bbi","bbj","bbk","bbl","bbm","bbn","bbo","bbp","bbq","bbr","bbs","bbt","bbu","bbv","bbw","bbx","bby","bbz","bca","bcb","bcc","bcd","bce","bcf","bcg","bch","bci","bcj","bck","bcl","bcm","bcn","bco","bcp","bcq","bcr","bcs","bct","bcu","bcv","bcw","bcy","bcz","bda","bdb","bdc","bdd","bde","bdf","bdg","bdh","bdi","bdj","bdk","bdl","bdm","bdn","bdo","bdp","bdq","bdr","bds","bdt","bdu","bdv","bdw","bdx","bdy","bdz","bea","beb","bec","bed","bee","bef","beg","beh","bei","bej","bek","bem","beo","bep","beq","ber","bes","bet","beu","bev","bew","bex","bey","bez","bfa","bfb","bfc","bfd","bfe","bff","bfg","bfh","bfi","bfj","bfk","bfl","bfm","bfn","bfo","bfp","bfq","bfr","bfs","bft","bfu","bfw","bfx","bfy","bfz","bga","bgb","bgc","bgd","bge","bgf","bgg","bgi","bgj","bgk","bgl","bgm","bgn","bgo","bgp","bgq","bgr","bgs","bgt","bgu","bgv","bgw","bgx","bgy","bgz","bha","bhb","bhc","bhd","bhe","bhf","bhg","bhh","bhi","bhj","bhk","bhl","bhm","bhn","bho","bhp","bhq","bhr","bhs","bht","bhu","bhv","bhw","bhx","bhy","bhz","bia","bib","bic","bid","bie","bif","big","bij","bik","bil","bim","bin","bio","bip","biq","bir","bit","biu","biv","biw","bix","biy","biz","bja","bjb","bjc","bjd","bje","bjf","bjg","bjh","bji","bjj","bjk","bjl","bjm","bjn","bjo","bjp","bjq","bjr","bjs","bjt","bju","bjv","bjw","bjx","bjy","bjz","bka","bkb","bkc","bkd","bkf","bkg","bkh","bki","bkj","bkk","bkl","bkm","bkn","bko","bkp","bkq","bkr","bks","bkt","bku","bkv","bkw","bkx","bky","bkz","bla","blb","blc","bld","ble","blf","blg","blh","bli","blj","blk","bll","blm","bln","blo","blp","blq","blr","bls","blt","blv","blw","blx","bly","blz","bma","bmb","bmc","bmd","bme","bmf","bmg","bmh","bmi","bmj","bmk","bml","bmm","bmn","bmo","bmp","bmq","bmr","bms","bmt","bmu","bmv","bmw","bmx","bmy","bmz","bna","bnb","bnc","bnd","bne","bnf","bng","bni","bnj","bnk","bnl","bnm","bnn","bno","bnp","bnq","bnr","bns","bnt","bnu","bnv","bnw","bnx","bny","bnz","boa","bob","boe","bof","bog","boh","boi","boj","bok","bol","bom","bon","boo","bop","boq","bor","bot","bou","bov","bow","box","boy","boz","bpa","bpb","bpd","bpg","bph","bpi","bpj","bpk","bpl","bpm","bpn","bpo","bpp","bpq","bpr","bps","bpt","bpu","bpv","bpw","bpx","bpy","bpz","bqa","bqb","bqc","bqd","bqf","bqg","bqh","bqi","bqj","bqk","bql","bqm","bqn","bqo","bqp","bqq","bqr","bqs","bqt","bqu","bqv","bqw","bqx","bqy","bqz","bra","brb","brc","brd","brf","brg","brh","bri","brj","brk","brl","brm","brn","bro","brp","brq","brr","brs","brt","bru","brv","brw","brx","bry","brz","bsa","bsb","bsc","bse","bsf","bsg","bsh","bsi","bsj","bsk","bsl","bsm","bsn","bso","bsp","bsq","bsr","bss","bst","bsu","bsv","bsw","bsx","bsy","bta","btb","btc","btd","bte","btf","btg","bth","bti","btj","btk","btl","btm","btn","bto","btp","btq","btr","bts","btt","btu","btv","btw","btx","bty","btz","bua","bub","buc","bud","bue","buf","bug","buh","bui","buj","buk","bum","bun","buo","bup","buq","bus","but","buu","buv","buw","bux","buy","buz","bva","bvb","bvc","bvd","bve","bvf","bvg","bvh","bvi","bvj","bvk","bvl","bvm","bvn","bvo","bvp","bvq","bvr","bvt","bvu","bvv","bvw","bvx","bvy","bvz","bwa","bwb","bwc","bwd","bwe","bwf","bwg","bwh","bwi","bwj","bwk","bwl","bwm","bwn","bwo","bwp","bwq","bwr","bws","bwt","bwu","bww","bwx","bwy","bwz","bxa","bxb","bxc","bxd","bxe","bxf","bxg","bxh","bxi","bxj","bxk","bxl","bxm","bxn","bxo","bxp","bxq","bxr","bxs","bxu","bxv","bxw","bxx","bxz","bya","byb","byc","byd","bye","byf","byg","byh","byi","byj","byk","byl","bym","byn","byo","byp","byq","byr","bys","byt","byv","byw","byx","byy","byz","bza","bzb","bzc","bzd","bze","bzf","bzg","bzh","bzi","bzj","bzk","bzl","bzm","bzn","bzo","bzp","bzq","bzr","bzs","bzt","bzu","bzv","bzw","bzx","bzy","bzz","caa","cab","cac","cad","cae","caf","cag","cah","cai","caj","cak","cal","cam","can","cao","cap","caq","car","cas","cau","cav","caw","cax","cay","caz","cba","cbb","cbc","cbd","cbe","cbg","cbh","cbi","cbj","cbk","cbl","cbn","cbo","cbq","cbr","cbs","cbt","cbu","cbv","cbw","cby","cca","ccc","ccd","cce","ccg","cch","ccj","ccl","ccm","ccn","cco","ccp","ccq","ccr","ccs","cda","cdc","cdd","cde","cdf","cdg","cdh","cdi","cdj","cdm","cdn","cdo","cdr","cds","cdy","cdz","cea","ceb","ceg","cek","cel","cen","cet","cfa","cfd","cfg","cfm","cga","cgc","cgg","cgk","chb","chc","chd","chf","chg","chh","chj","chk","chl","chm","chn","cho","chp","chq","chr","cht","chw","chx","chy","chz","cia","cib","cic","cid","cie","cih","cik","cim","cin","cip","cir","ciw","ciy","cja","cje","cjh","cji","cjk","cjm","cjn","cjo","cjp","cjr","cjs","cjv","cjy","cka","ckb","ckh","ckl","ckn","cko","ckq","ckr","cks","ckt","cku","ckv","ckx","cky","ckz","cla","clc","cld","cle","clh","cli","clj","clk","cll","clm","clo","clt","clu","clw","cly","cma","cmc","cme","cmg","cmi","cmk","cml","cmm","cmn","cmo","cmr","cms","cmt","cna","cnb","cnc","cng","cnh","cni","cnk","cnl","cno","cnr","cns","cnt","cnu","cnw","cnx","coa","cob","coc","cod","coe","cof","cog","coh","coj","cok","col","com","con","coo","cop","coq","cot","cou","cov","cow","cox","coy","coz","cpa","cpb","cpc","cpe","cpf","cpg","cpi","cpn","cpo","cpp","cps","cpu","cpx","cpy","cqd","cqu","cra","crb","crc","crd","crf","crg","crh","cri","crj","crk","crl","crm","crn","cro","crp","crq","crr","crs","crt","crv","crw","crx","cry","crz","csa","csb","csc","csd","cse","csf","csg","csh","csi","csj","csk","csl","csm","csn","cso","csq","csr","css","cst","csu","csv","csw","csy","csz","cta","ctc","ctd","cte","ctg","cth","ctl","ctm","ctn","cto","ctp","cts","ctt","ctu","ctz","cua","cub","cuc","cug","cuh","cui","cuj","cuk","cul","cum","cuo","cup","cuq","cur","cus","cut","cuu","cuv","cuw","cux","cuy","cvg","cvn","cwa","cwb","cwd","cwe","cwg","cwt","cya","cyb","cyo","czh","czk","czn","czo","czt","daa","dac","dad","dae","daf","dag","dah","dai","daj","dak","dal","dam","dao","dap","daq","dar","das","dau","dav","daw","dax","day","daz","dba","dbb","dbd","dbe","dbf","dbg","dbi","dbj","dbl","dbm","dbn","dbo","dbp","dbq","dbr","dbt","dbu","dbv","dbw","dby","dcc","dcr","dda","ddd","dde","ddg","ddi","ddj","ddn","ddo","ddr","dds","ddw","dec","ded","dee","def","deg","deh","dei","dek","del","dem","den","dep","deq","der","des","dev","dez","dga","dgb","dgc","dgd","dge","dgg","dgh","dgi","dgk","dgl","dgn","dgo","dgr","dgs","dgt","dgu","dgw","dgx","dgz","dha","dhd","dhg","dhi","dhl","dhm","dhn","dho","dhr","dhs","dhu","dhv","dhw","dhx","dia","dib","dic","did","dif","dig","dih","dii","dij","dik","dil","dim","din","dio","dip","diq","dir","dis","dit","diu","diw","dix","diy","diz","dja","djb","djc","djd","dje","djf","dji","djj","djk","djl","djm","djn","djo","djr","dju","djw","dka","dkk","dkl","dkr","dks","dkx","dlg","dlk","dlm","dln","dma","dmb","dmc","dmd","dme","dmg","dmk","dml","dmm","dmn","dmo","dmr","dms","dmu","dmv","dmw","dmx","dmy","dna","dnd","dne","dng","dni","dnj","dnk","dnn","dnr","dnt","dnu","dnv","dnw","dny","doa","dob","doc","doe","dof","doh","doi","dok","dol","don","doo","dop","doq","dor","dos","dot","dov","dow","dox","doy","doz","dpp","dra","drb","drc","drd","dre","drg","drh","dri","drl","drn","dro","drq","drr","drs","drt","dru","drw","dry","dsb","dse","dsh","dsi","dsl","dsn","dso","dsq","dta","dtb","dtd","dth","dti","dtk","dtm","dtn","dto","dtp","dtr","dts","dtt","dtu","dty","dua","dub","duc","dud","due","duf","dug","duh","dui","duj","duk","dul","dum","dun","duo","dup","duq","dur","dus","duu","duv","duw","dux","duy","duz","dva","dwa","dwl","dwr","dws","dwu","dww","dwy","dya","dyb","dyd","dyg","dyi","dym","dyn","dyo","dyu","dyy","dza","dzd","dze","dzg","dzl","dzn","eaa","ebg","ebk","ebo","ebr","ebu","ecr","ecs","ecy","eee","efa","efe","efi","ega","egl","ego","egx","egy","ehu","eip","eit","eiv","eja","eka","ekc","eke","ekg","eki","ekk","ekl","ekm","eko","ekp","ekr","eky","ele","elh","eli","elk","elm","elo","elp","elu","elx","ema","emb","eme","emg","emi","emk","emm","emn","emo","emp","ems","emu","emw","emx","emy","ena","enb","enc","end","enf","enh","enl","enm","enn","eno","enq","enr","enu","env","enw","enx","eot","epi","era","erg","erh","eri","erk","ero","err","ers","ert","erw","ese","esg","esh","esi","esk","esl","esm","esn","eso","esq","ess","esu","esx","esy","etb","etc","eth","etn","eto","etr","ets","ett","etu","etx","etz","euq","eve","evh","evn","ewo","ext","eya","eyo","eza","eze","faa","fab","fad","faf","fag","fah","fai","faj","fak","fal","fam","fan","fap","far","fat","fau","fax","fay","faz","fbl","fcs","fer","ffi","ffm","fgr","fia","fie","fil","fip","fir","fit","fiu","fiw","fkk","fkv","fla","flh","fli","fll","fln","flr","fly","fmp","fmu","fnb","fng","fni","fod","foi","fom","fon","for","fos","fox","fpe","fqs","frc","frd","frk","frm","fro","frp","frq","frr","frs","frt","fse","fsl","fss","fub","fuc","fud","fue","fuf","fuh","fui","fuj","fum","fun","fuq","fur","fut","fuu","fuv","fuy","fvr","fwa","fwe","gaa","gab","gac","gad","gae","gaf","gag","gah","gai","gaj","gak","gal","gam","gan","gao","gap","gaq","gar","gas","gat","gau","gav","gaw","gax","gay","gaz","gba","gbb","gbc","gbd","gbe","gbf","gbg","gbh","gbi","gbj","gbk","gbl","gbm","gbn","gbo","gbp","gbq","gbr","gbs","gbu","gbv","gbw","gbx","gby","gbz","gcc","gcd","gce","gcf","gcl","gcn","gcr","gct","gda","gdb","gdc","gdd","gde","gdf","gdg","gdh","gdi","gdj","gdk","gdl","gdm","gdn","gdo","gdq","gdr","gds","gdt","gdu","gdx","gea","geb","gec","ged","geg","geh","gei","gej","gek","gel","gem","geq","ges","gev","gew","gex","gey","gez","gfk","gft","gfx","gga","ggb","ggd","gge","ggg","ggk","ggl","ggn","ggo","ggr","ggt","ggu","ggw","gha","ghc","ghe","ghh","ghk","ghl","ghn","gho","ghr","ghs","ght","gia","gib","gic","gid","gie","gig","gih","gil","gim","gin","gio","gip","giq","gir","gis","git","giu","giw","gix","giy","giz","gji","gjk","gjm","gjn","gjr","gju","gka","gkd","gke","gkn","gko","gkp","gku","glc","gld","glh","gli","glj","glk","gll","glo","glr","glu","glw","gly","gma","gmb","gmd","gme","gmg","gmh","gml","gmm","gmn","gmq","gmu","gmv","gmw","gmx","gmy","gmz","gna","gnb","gnc","gnd","gne","gng","gnh","gni","gnj","gnk","gnl","gnm","gnn","gno","gnq","gnr","gnt","gnu","gnw","gnz","goa","gob","goc","god","goe","gof","gog","goh","goi","goj","gok","gol","gom","gon","goo","gop","goq","gor","gos","got","gou","gow","gox","goy","goz","gpa","gpe","gpn","gqa","gqi","gqn","gqr","gqu","gra","grb","grc","grd","grg","grh","gri","grj","grk","grm","gro","grq","grr","grs","grt","gru","grv","grw","grx","gry","grz","gse","gsg","gsl","gsm","gsn","gso","gsp","gss","gsw","gta","gti","gtu","gua","gub","guc","gud","gue","guf","gug","guh","gui","guk","gul","gum","gun","guo","gup","guq","gur","gus","gut","guu","guv","guw","gux","guz","gva","gvc","gve","gvf","gvj","gvl","gvm","gvn","gvo","gvp","gvr","gvs","gvy","gwa","gwb","gwc","gwd","gwe","gwf","gwg","gwi","gwj","gwm","gwn","gwr","gwt","gwu","gww","gwx","gxx","gya","gyb","gyd","gye","gyf","gyg","gyi","gyl","gym","gyn","gyo","gyr","gyy","gza","gzi","gzn","haa","hab","hac","had","hae","haf","hag","hah","hai","haj","hak","hal","ham","han","hao","hap","haq","har","has","hav","haw","hax","hay","haz","hba","hbb","hbn","hbo","hbu","hca","hch","hdn","hds","hdy","hea","hed","heg","heh","hei","hem","hgm","hgw","hhi","hhr","hhy","hia","hib","hid","hif","hig","hih","hii","hij","hik","hil","him","hio","hir","hit","hiw","hix","hji","hka","hke","hkk","hkn","hks","hla","hlb","hld","hle","hlt","hlu","hma","hmb","hmc","hmd","hme","hmf","hmg","hmh","hmi","hmj","hmk","hml","hmm","hmn","hmp","hmq","hmr","hms","hmt","hmu","hmv","hmw","hmx","hmy","hmz","hna","hnd","hne","hnh","hni","hnj","hnn","hno","hns","hnu","hoa","hob","hoc","hod","hoe","hoh","hoi","hoj","hok","hol","hom","hoo","hop","hor","hos","hot","hov","how","hoy","hoz","hpo","hps","hra","hrc","hre","hrk","hrm","hro","hrp","hrr","hrt","hru","hrw","hrx","hrz","hsb","hsh","hsl","hsn","hss","hti","hto","hts","htu","htx","hub","huc","hud","hue","huf","hug","huh","hui","huj","huk","hul","hum","huo","hup","huq","hur","hus","hut","huu","huv","huw","hux","huy","huz","hvc","hve","hvk","hvn","hvv","hwa","hwc","hwo","hya","hyw","hyx","iai","ian","iap","iar","iba","ibb","ibd","ibe","ibg","ibh","ibi","ibl","ibm","ibn","ibr","ibu","iby","ica","ich","icl","icr","ida","idb","idc","idd","ide","idi","idr","ids","idt","idu","ifa","ifb","ife","iff","ifk","ifm","ifu","ify","igb","ige","igg","igl","igm","ign","igo","igs","igw","ihb","ihi","ihp","ihw","iin","iir","ijc","ije","ijj","ijn","ijo","ijs","ike","iki","ikk","ikl","iko","ikp","ikr","iks","ikt","ikv","ikw","ikx","ikz","ila","ilb","ilg","ili","ilk","ill","ilm","ilo","ilp","ils","ilu","ilv","ilw","ima","ime","imi","iml","imn","imo","imr","ims","imy","inb","inc","ine","ing","inh","inj","inl","inm","inn","ino","inp","ins","int","inz","ior","iou","iow","ipi","ipo","iqu","iqw","ira","ire","irh","iri","irk","irn","iro","irr","iru","irx","iry","isa","isc","isd","ise","isg","ish","isi","isk","ism","isn","iso","isr","ist","isu","itb","itc","itd","ite","iti","itk","itl","itm","ito","itr","its","itt","itv","itw","itx","ity","itz","ium","ivb","ivv","iwk","iwm","iwo","iws","ixc","ixl","iya","iyo","iyx","izh","izi","izr","izz","jaa","jab","jac","jad","jae","jaf","jah","jaj","jak","jal","jam","jan","jao","jaq","jar","jas","jat","jau","jax","jay","jaz","jbe","jbi","jbj","jbk","jbn","jbo","jbr","jbt","jbu","jbw","jcs","jct","jda","jdg","jdt","jeb","jee","jeg","jeh","jei","jek","jel","jen","jer","jet","jeu","jgb","jge","jgk","jgo","jhi","jhs","jia","jib","jic","jid","jie","jig","jih","jii","jil","jim","jio","jiq","jit","jiu","jiv","jiy","jje","jjr","jka","jkm","jko","jkp","jkr","jku","jle","jls","jma","jmb","jmc","jmd","jmi","jml","jmn","jmr","jms","jmw","jmx","jna","jnd","jng","jni","jnj","jnl","jns","job","jod","jog","jor","jos","jow","jpa","jpr","jpx","jqr","jra","jrb","jrr","jrt","jru","jsl","jua","jub","juc","jud","juh","jui","juk","jul","jum","jun","juo","jup","jur","jus","jut","juu","juw","juy","jvd","jvn","jwi","jya","jye","jyy","kaa","kab","kac","kad","kae","kaf","kag","kah","kai","kaj","kak","kam","kao","kap","kaq","kar","kav","kaw","kax","kay","kba","kbb","kbc","kbd","kbe","kbf","kbg","kbh","kbi","kbj","kbk","kbl","kbm","kbn","kbo","kbp","kbq","kbr","kbs","kbt","kbu","kbv","kbw","kbx","kby","kbz","kca","kcb","kcc","kcd","kce","kcf","kcg","kch","kci","kcj","kck","kcl","kcm","kcn","kco","kcp","kcq","kcr","kcs","kct","kcu","kcv","kcw","kcx","kcy","kcz","kda","kdc","kdd","kde","kdf","kdg","kdh","kdi","kdj","kdk","kdl","kdm","kdn","kdo","kdp","kdq","kdr","kdt","kdu","kdv","kdw","kdx","kdy","kdz","kea","keb","kec","ked","kee","kef","keg","keh","kei","kej","kek","kel","kem","ken","keo","kep","keq","ker","kes","ket","keu","kev","kew","kex","key","kez","kfa","kfb","kfc","kfd","kfe","kff","kfg","kfh","kfi","kfj","kfk","kfl","kfm","kfn","kfo","kfp","kfq","kfr","kfs","kft","kfu","kfv","kfw","kfx","kfy","kfz","kga","kgb","kgc","kgd","kge","kgf","kgg","kgh","kgi","kgj","kgk","kgl","kgm","kgn","kgo","kgp","kgq","kgr","kgs","kgt","kgu","kgv","kgw","kgx","kgy","kha","khb","khc","khd","khe","khf","khg","khh","khi","khj","khk","khl","khn","kho","khp","khq","khr","khs","kht","khu","khv","khw","khx","khy","khz","kia","kib","kic","kid","kie","kif","kig","kih","kii","kij","kil","kim","kio","kip","kiq","kis","kit","kiu","kiv","kiw","kix","kiy","kiz","kja","kjb","kjc","kjd","kje","kjf","kjg","kjh","kji","kjj","kjk","kjl","kjm","kjn","kjo","kjp","kjq","kjr","kjs","kjt","kju","kjv","kjx","kjy","kjz","kka","kkb","kkc","kkd","kke","kkf","kkg","kkh","kki","kkj","kkk","kkl","kkm","kkn","kko","kkp","kkq","kkr","kks","kkt","kku","kkv","kkw","kkx","kky","kkz","kla","klb","klc","kld","kle","klf","klg","klh","kli","klj","klk","kll","klm","kln","klo","klp","klq","klr","kls","klt","klu","klv","klw","klx","kly","klz","kma","kmb","kmc","kmd","kme","kmf","kmg","kmh","kmi","kmj","kmk","kml","kmm","kmn","kmo","kmp","kmq","kmr","kms","kmt","kmu","kmv","kmw","kmx","kmy","kmz","kna","knb","knc","knd","kne","knf","kng","kni","knj","knk","knl","knm","knn","kno","knp","knq","knr","kns","knt","knu","knv","knw","knx","kny","knz","koa","koc","kod","koe","kof","kog","koh","koi","koj","kok","kol","koo","kop","koq","kos","kot","kou","kov","kow","kox","koy","koz","kpa","kpb","kpc","kpd","kpe","kpf","kpg","kph","kpi","kpj","kpk","kpl","kpm","kpn","kpo","kpp","kpq","kpr","kps","kpt","kpu","kpv","kpw","kpx","kpy","kpz","kqa","kqb","kqc","kqd","kqe","kqf","kqg","kqh","kqi","kqj","kqk","kql","kqm","kqn","kqo","kqp","kqq","kqr","kqs","kqt","kqu","kqv","kqw","kqx","kqy","kqz","kra","krb","krc","krd","kre","krf","krh","kri","krj","krk","krl","krm","krn","kro","krp","krr","krs","krt","kru","krv","krw","krx","kry","krz","ksa","ksb","ksc","ksd","kse","ksf","ksg","ksh","ksi","ksj","ksk","ksl","ksm","ksn","kso","ksp","ksq","ksr","kss","kst","ksu","ksv","ksw","ksx","ksy","ksz","kta","ktb","ktc","ktd","kte","ktf","ktg","kth","kti","ktj","ktk","ktl","ktm","ktn","kto","ktp","ktq","ktr","kts","ktt","ktu","ktv","ktw","ktx","kty","ktz","kub","kuc","kud","kue","kuf","kug","kuh","kui","kuj","kuk","kul","kum","kun","kuo","kup","kuq","kus","kut","kuu","kuv","kuw","kux","kuy","kuz","kva","kvb","kvc","kvd","kve","kvf","kvg","kvh","kvi","kvj","kvk","kvl","kvm","kvn","kvo","kvp","kvq","kvr","kvs","kvt","kvu","kvv","kvw","kvx","kvy","kvz","kwa","kwb","kwc","kwd","kwe","kwf","kwg","kwh","kwi","kwj","kwk","kwl","kwm","kwn","kwo","kwp","kwq","kwr","kws","kwt","kwu","kwv","kww","kwx","kwy","kwz","kxa","kxb","kxc","kxd","kxe","kxf","kxh","kxi","kxj","kxk","kxl","kxm","kxn","kxo","kxp","kxq","kxr","kxs","kxt","kxu","kxv","kxw","kxx","kxy","kxz","kya","kyb","kyc","kyd","kye","kyf","kyg","kyh","kyi","kyj","kyk","kyl","kym","kyn","kyo","kyp","kyq","kyr","kys","kyt","kyu","kyv","kyw","kyx","kyy","kyz","kza","kzb","kzc","kzd","kze","kzf","kzg","kzh","kzi","kzj","kzk","kzl","kzm","kzn","kzo","kzp","kzq","kzr","kzs","kzt","kzu","kzv","kzw","kzx","kzy","kzz","laa","lab","lac","lad","lae","laf","lag","lah","lai","laj","lak","lal","lam","lan","lap","laq","lar","las","lau","law","lax","lay","laz","lba","lbb","lbc","lbe","lbf","lbg","lbi","lbj","lbk","lbl","lbm","lbn","lbo","lbq","lbr","lbs","lbt","lbu","lbv","lbw","lbx","lby","lbz","lcc","lcd","lce","lcf","lch","lcl","lcm","lcp","lcq","lcs","lda","ldb","ldd","ldg","ldh","ldi","ldj","ldk","ldl","ldm","ldn","ldo","ldp","ldq","lea","leb","lec","led","lee","lef","leg","leh","lei","lej","lek","lel","lem","len","leo","lep","leq","ler","les","let","leu","lev","lew","lex","ley","lez","lfa","lfn","lga","lgb","lgg","lgh","lgi","lgk","lgl","lgm","lgn","lgq","lgr","lgt","lgu","lgz","lha","lhh","lhi","lhl","lhm","lhn","lhp","lhs","lht","lhu","lia","lib","lic","lid","lie","lif","lig","lih","lii","lij","lik","lil","lio","lip","liq","lir","lis","liu","liv","liw","lix","liy","liz","lja","lje","lji","ljl","ljp","ljw","ljx","lka","lkb","lkc","lkd","lke","lkh","lki","lkj","lkl","lkm","lkn","lko","lkr","lks","lkt","lku","lky","lla","llb","llc","lld","lle","llf","llg","llh","lli","llj","llk","lll","llm","lln","llo","llp","llq","lls","llu","llx","lma","lmb","lmc","lmd","lme","lmf","lmg","lmh","lmi","lmj","lmk","lml","lmm","lmn","lmo","lmp","lmq","lmr","lmu","lmv","lmw","lmx","lmy","lmz","lna","lnb","lnd","lng","lnh","lni","lnj","lnl","lnm","lnn","lno","lns","lnu","lnw","lnz","loa","lob","loc","loe","lof","log","loh","loi","loj","lok","lol","lom","lon","loo","lop","loq","lor","los","lot","lou","lov","low","lox","loy","loz","lpa","lpe","lpn","lpo","lpx","lra","lrc","lre","lrg","lri","lrk","lrl","lrm","lrn","lro","lrr","lrt","lrv","lrz","lsa","lsd","lse","lsg","lsh","lsi","lsl","lsm","lso","lsp","lsr","lss","lst","lsy","ltc","ltg","lth","lti","ltn","lto","lts","ltu","lua","luc","lud","lue","luf","lui","luj","luk","lul","lum","lun","luo","lup","luq","lur","lus","lut","luu","luv","luw","luy","luz","lva","lvk","lvs","lvu","lwa","lwe","lwg","lwh","lwl","lwm","lwo","lws","lwt","lwu","lww","lya","lyg","lyn","lzh","lzl","lzn","lzz","maa","mab","mad","mae","maf","mag","mai","maj","mak","mam","man","map","maq","mas","mat","mau","mav","maw","max","maz","mba","mbb","mbc","mbd","mbe","mbf","mbh","mbi","mbj","mbk","mbl","mbm","mbn","mbo","mbp","mbq","mbr","mbs","mbt","mbu","mbv","mbw","mbx","mby","mbz","mca","mcb","mcc","mcd","mce","mcf","mcg","mch","mci","mcj","mck","mcl","mcm","mcn","mco","mcp","mcq","mcr","mcs","mct","mcu","mcv","mcw","mcx","mcy","mcz","mda","mdb","mdc","mdd","mde","mdf","mdg","mdh","mdi","mdj","mdk","mdl","mdm","mdn","mdp","mdq","mdr","mds","mdt","mdu","mdv","mdw","mdx","mdy","mdz","mea","meb","mec","med","mee","mef","meg","meh","mei","mej","mek","mel","mem","men","meo","mep","meq","mer","mes","met","meu","mev","mew","mey","mez","mfa","mfb","mfc","mfd","mfe","mff","mfg","mfh","mfi","mfj","mfk","mfl","mfm","mfn","mfo","mfp","mfq","mfr","mfs","mft","mfu","mfv","mfw","mfx","mfy","mfz","mga","mgb","mgc","mgd","mge","mgf","mgg","mgh","mgi","mgj","mgk","mgl","mgm","mgn","mgo","mgp","mgq","mgr","mgs","mgt","mgu","mgv","mgw","mgx","mgy","mgz","mha","mhb","mhc","mhd","mhe","mhf","mhg","mhh","mhi","mhj","mhk","mhl","mhm","mhn","mho","mhp","mhq","mhr","mhs","mht","mhu","mhw","mhx","mhy","mhz","mia","mib","mic","mid","mie","mif","mig","mih","mii","mij","mik","mil","mim","min","mio","mip","miq","mir","mis","mit","miu","miw","mix","miy","miz","mja","mjb","mjc","mjd","mje","mjg","mjh","mji","mjj","mjk","mjl","mjm","mjn","mjo","mjp","mjq","mjr","mjs","mjt","mju","mjv","mjw","mjx","mjy","mjz","mka","mkb","mkc","mke","mkf","mkg","mkh","mki","mkj","mkk","mkl","mkm","mkn","mko","mkp","mkq","mkr","mks","mkt","mku","mkv","mkw","mkx","mky","mkz","mla","mlb","mlc","mld","mle","mlf","mlh","mli","mlj","mlk","mll","mlm","mln","mlo","mlp","mlq","mlr","mls","mlu","mlv","mlw","mlx","mlz","mma","mmb","mmc","mmd","mme","mmf","mmg","mmh","mmi","mmj","mmk","mml","mmm","mmn","mmo","mmp","mmq","mmr","mmt","mmu","mmv","mmw","mmx","mmy","mmz","mna","mnb","mnc","mnd","mne","mnf","mng","mnh","mni","mnj","mnk","mnl","mnm","mnn","mno","mnp","mnq","mnr","mns","mnt","mnu","mnv","mnw","mnx","mny","mnz","moa","moc","mod","moe","mof","mog","moh","moi","moj","mok","mom","moo","mop","moq","mor","mos","mot","mou","mov","mow","mox","moy","moz","mpa","mpb","mpc","mpd","mpe","mpg","mph","mpi","mpj","mpk","mpl","mpm","mpn","mpo","mpp","mpq","mpr","mps","mpt","mpu","mpv","mpw","mpx","mpy","mpz","mqa","mqb","mqc","mqe","mqf","mqg","mqh","mqi","mqj","mqk","mql","mqm","mqn","mqo","mqp","mqq","mqr","mqs","mqt","mqu","mqv","mqw","mqx","mqy","mqz","mra","mrb","mrc","mrd","mre","mrf","mrg","mrh","mrj","mrk","mrl","mrm","mrn","mro","mrp","mrq","mrr","mrs","mrt","mru","mrv","mrw","mrx","mry","mrz","msb","msc","msd","mse","msf","msg","msh","msi","msj","msk","msl","msm","msn","mso","msp","msq","msr","mss","mst","msu","msv","msw","msx","msy","msz","mta","mtb","mtc","mtd","mte","mtf","mtg","mth","mti","mtj","mtk","mtl","mtm","mtn","mto","mtp","mtq","mtr","mts","mtt","mtu","mtv","mtw","mtx","mty","mua","mub","muc","mud","mue","mug","muh","mui","muj","muk","mul","mum","mun","muo","mup","muq","mur","mus","mut","muu","muv","mux","muy","muz","mva","mvb","mvd","mve","mvf","mvg","mvh","mvi","mvk","mvl","mvm","mvn","mvo","mvp","mvq","mvr","mvs","mvt","mvu","mvv","mvw","mvx","mvy","mvz","mwa","mwb","mwc","mwd","mwe","mwf","mwg","mwh","mwi","mwj","mwk","mwl","mwm","mwn","mwo","mwp","mwq","mwr","mws","mwt","mwu","mwv","mww","mwx","mwy","mwz","mxa","mxb","mxc","mxd","mxe","mxf","mxg","mxh","mxi","mxj","mxk","mxl","mxm","mxn","mxo","mxp","mxq","mxr","mxs","mxt","mxu","mxv","mxw","mxx","mxy","mxz","myb","myc","myd","mye","myf","myg","myh","myi","myj","myk","myl","mym","myn","myo","myp","myq","myr","mys","myt","myu","myv","myw","myx","myy","myz","mza","mzb","mzc","mzd","mze","mzg","mzh","mzi","mzj","mzk","mzl","mzm","mzn","mzo","mzp","mzq","mzr","mzs","mzt","mzu","mzv","mzw","mzx","mzy","mzz","naa","nab","nac","nad","nae","naf","nag","nah","nai","naj","nak","nal","nam","nan","nao","nap","naq","nar","nas","nat","naw","nax","nay","naz","nba","nbb","nbc","nbd","nbe","nbf","nbg","nbh","nbi","nbj","nbk","nbm","nbn","nbo","nbp","nbq","nbr","nbs","nbt","nbu","nbv","nbw","nbx","nby","nca","ncb","ncc","ncd","nce","ncf","ncg","nch","nci","ncj","nck","ncl","ncm","ncn","nco","ncp","ncq","ncr","ncs","nct","ncu","ncx","ncz","nda","ndb","ndc","ndd","ndf","ndg","ndh","ndi","ndj","ndk","ndl","ndm","ndn","ndp","ndq","ndr","nds","ndt","ndu","ndv","ndw","ndx","ndy","ndz","nea","neb","nec","ned","nee","nef","neg","neh","nei","nej","nek","nem","nen","neo","neq","ner","nes","net","neu","nev","new","nex","ney","nez","nfa","nfd","nfl","nfr","nfu","nga","ngb","ngc","ngd","nge","ngf","ngg","ngh","ngi","ngj","ngk","ngl","ngm","ngn","ngo","ngp","ngq","ngr","ngs","ngt","ngu","ngv","ngw","ngx","ngy","ngz","nha","nhb","nhc","nhd","nhe","nhf","nhg","nhh","nhi","nhk","nhm","nhn","nho","nhp","nhq","nhr","nht","nhu","nhv","nhw","nhx","nhy","nhz","nia","nib","nic","nid","nie","nif","nig","nih","nii","nij","nik","nil","nim","nin","nio","niq","nir","nis","nit","niu","niv","niw","nix","niy","niz","nja","njb","njd","njh","nji","njj","njl","njm","njn","njo","njr","njs","njt","nju","njx","njy","njz","nka","nkb","nkc","nkd","nke","nkf","nkg","nkh","nki","nkj","nkk","nkm","nkn","nko","nkp","nkq","nkr","nks","nkt","nku","nkv","nkw","nkx","nkz","nla","nlc","nle","nlg","nli","nlj","nlk","nll","nlm","nln","nlo","nlq","nlr","nlu","nlv","nlw","nlx","nly","nlz","nma","nmb","nmc","nmd","nme","nmf","nmg","nmh","nmi","nmj","nmk","nml","nmm","nmn","nmo","nmp","nmq","nmr","nms","nmt","nmu","nmv","nmw","nmx","nmy","nmz","nna","nnb","nnc","nnd","nne","nnf","nng","nnh","nni","nnj","nnk","nnl","nnm","nnn","nnp","nnq","nnr","nns","nnt","nnu","nnv","nnw","nnx","nny","nnz","noa","noc","nod","noe","nof","nog","noh","noi","noj","nok","nol","nom","non","noo","nop","noq","nos","not","nou","nov","now","noy","noz","npa","npb","npg","nph","npi","npl","npn","npo","nps","npu","npx","npy","nqg","nqk","nql","nqm","nqn","nqo","nqq","nqy","nra","nrb","nrc","nre","nrf","nrg","nri","nrk","nrl","nrm","nrn","nrp","nrr","nrt","nru","nrx","nrz","nsa","nsc","nsd","nse","nsf","nsg","nsh","nsi","nsk","nsl","nsm","nsn","nso","nsp","nsq","nsr","nss","nst","nsu","nsv","nsw","nsx","nsy","nsz","ntd","nte","ntg","nti","ntj","ntk","ntm","nto","ntp","ntr","nts","ntu","ntw","ntx","nty","ntz","nua","nub","nuc","nud","nue","nuf","nug","nuh","nui","nuj","nuk","nul","num","nun","nuo","nup","nuq","nur","nus","nut","nuu","nuv","nuw","nux","nuy","nuz","nvh","nvm","nvo","nwa","nwb","nwc","nwe","nwg","nwi","nwm","nwo","nwr","nwx","nwy","nxa","nxd","nxe","nxg","nxi","nxk","nxl","nxm","nxn","nxo","nxq","nxr","nxu","nxx","nyb","nyc","nyd","nye","nyf","nyg","nyh","nyi","nyj","nyk","nyl","nym","nyn","nyo","nyp","nyq","nyr","nys","nyt","nyu","nyv","nyw","nyx","nyy","nza","nzb","nzd","nzi","nzk","nzm","nzs","nzu","nzy","nzz","oaa","oac","oar","oav","obi","obk","obl","obm","obo","obr","obt","obu","oca","och","oco","ocu","oda","odk","odt","odu","ofo","ofs","ofu","ogb","ogc","oge","ogg","ogo","ogu","oht","ohu","oia","oin","ojb","ojc","ojg","ojp","ojs","ojv","ojw","oka","okb","okd","oke","okg","okh","oki","okj","okk","okl","okm","okn","oko","okr","oks","oku","okv","okx","ola","old","ole","olk","olm","olo","olr","olt","olu","oma","omb","omc","ome","omg","omi","omk","oml","omn","omo","omp","omq","omr","omt","omu","omv","omw","omx","ona","onb","one","ong","oni","onj","onk","onn","ono","onp","onr","ons","ont","onu","onw","onx","ood","oog","oon","oor","oos","opa","opk","opm","opo","opt","opy","ora","orc","ore","org","orh","orn","oro","orr","ors","ort","oru","orv","orw","orx","ory","orz","osa","osc","osi","oso","osp","ost","osu","osx","ota","otb","otd","ote","oti","otk","otl","otm","otn","oto","otq","otr","ots","ott","otu","otw","otx","oty","otz","oua","oub","oue","oui","oum","oun","ovd","owi","owl","oyb","oyd","oym","oyy","ozm","paa","pab","pac","pad","pae","paf","pag","pah","pai","pak","pal","pam","pao","pap","paq","par","pas","pat","pau","pav","paw","pax","pay","paz","pbb","pbc","pbe","pbf","pbg","pbh","pbi","pbl","pbm","pbn","pbo","pbp","pbr","pbs","pbt","pbu","pbv","pby","pbz","pca","pcb","pcc","pcd","pce","pcf","pcg","pch","pci","pcj","pck","pcl","pcm","pcn","pcp","pcr","pcw","pda","pdc","pdi","pdn","pdo","pdt","pdu","pea","peb","ped","pee","pef","peg","peh","pei","pej","pek","pel","pem","peo","pep","peq","pes","pev","pex","pey","pez","pfa","pfe","pfl","pga","pgd","pgg","pgi","pgk","pgl","pgn","pgs","pgu","pgy","pgz","pha","phd","phg","phh","phi","phk","phl","phm","phn","pho","phq","phr","pht","phu","phv","phw","pia","pib","pic","pid","pie","pif","pig","pih","pii","pij","pil","pim","pin","pio","pip","pir","pis","pit","piu","piv","piw","pix","piy","piz","pjt","pka","pkb","pkc","pkg","pkh","pkn","pko","pkp","pkr","pks","pkt","pku","pla","plb","plc","pld","ple","plf","plg","plh","plj","plk","pll","pln","plo","plp","plq","plr","pls","plt","plu","plv","plw","ply","plz","pma","pmb","pmc","pmd","pme","pmf","pmh","pmi","pmj","pmk","pml","pmm","pmn","pmo","pmq","pmr","pms","pmt","pmu","pmw","pmx","pmy","pmz","pna","pnb","pnc","pne","png","pnh","pni","pnj","pnk","pnl","pnm","pnn","pno","pnp","pnq","pnr","pns","pnt","pnu","pnv","pnw","pnx","pny","pnz","poc","pod","poe","pof","pog","poh","poi","pok","pom","pon","poo","pop","poq","pos","pot","pov","pow","pox","poy","poz","ppa","ppe","ppi","ppk","ppl","ppm","ppn","ppo","ppp","ppq","ppr","pps","ppt","ppu","pqa","pqe","pqm","pqw","pra","prb","prc","prd","pre","prf","prg","prh","pri","prk","prl","prm","prn","pro","prp","prq","prr","prs","prt","pru","prw","prx","pry","prz","psa","psc","psd","pse","psg","psh","psi","psl","psm","psn","pso","psp","psq","psr","pss","pst","psu","psw","psy","pta","pth","pti","ptn","pto","ptp","ptq","ptr","ptt","ptu","ptv","ptw","pty","pua","pub","puc","pud","pue","puf","pug","pui","puj","puk","pum","puo","pup","puq","pur","put","puu","puw","pux","puy","puz","pwa","pwb","pwg","pwi","pwm","pwn","pwo","pwr","pww","pxm","pye","pym","pyn","pys","pyu","pyx","pyy","pzn","qaa..qtz","qua","qub","quc","qud","quf","qug","quh","qui","quk","qul","qum","qun","qup","quq","qur","qus","quv","quw","qux","quy","quz","qva","qvc","qve","qvh","qvi","qvj","qvl","qvm","qvn","qvo","qvp","qvs","qvw","qvy","qvz","qwa","qwc","qwe","qwh","qwm","qws","qwt","qxa","qxc","qxh","qxl","qxn","qxo","qxp","qxq","qxr","qxs","qxt","qxu","qxw","qya","qyp","raa","rab","rac","rad","raf","rag","rah","rai","raj","rak","ral","ram","ran","rao","rap","raq","rar","ras","rat","rau","rav","raw","rax","ray","raz","rbb","rbk","rbl","rbp","rcf","rdb","rea","reb","ree","reg","rei","rej","rel","rem","ren","rer","res","ret","rey","rga","rge","rgk","rgn","rgr","rgs","rgu","rhg","rhp","ria","rie","rif","ril","rim","rin","rir","rit","riu","rjg","rji","rjs","rka","rkb","rkh","rki","rkm","rkt","rkw","rma","rmb","rmc","rmd","rme","rmf","rmg","rmh","rmi","rmk","rml","rmm","rmn","rmo","rmp","rmq","rmr","rms","rmt","rmu","rmv","rmw","rmx","rmy","rmz","rna","rnd","rng","rnl","rnn","rnp","rnr","rnw","roa","rob","roc","rod","roe","rof","rog","rol","rom","roo","rop","ror","rou","row","rpn","rpt","rri","rro","rrt","rsb","rsi","rsl","rsm","rtc","rth","rtm","rts","rtw","rub","ruc","rue","ruf","rug","ruh","rui","ruk","ruo","rup","ruq","rut","ruu","ruy","ruz","rwa","rwk","rwm","rwo","rwr","rxd","rxw","ryn","rys","ryu","rzh","saa","sab","sac","sad","sae","saf","sah","sai","saj","sak","sal","sam","sao","sap","saq","sar","sas","sat","sau","sav","saw","sax","say","saz","sba","sbb","sbc","sbd","sbe","sbf","sbg","sbh","sbi","sbj","sbk","sbl","sbm","sbn","sbo","sbp","sbq","sbr","sbs","sbt","sbu","sbv","sbw","sbx","sby","sbz","sca","scb","sce","scf","scg","sch","sci","sck","scl","scn","sco","scp","scq","scs","sct","scu","scv","scw","scx","sda","sdb","sdc","sde","sdf","sdg","sdh","sdj","sdk","sdl","sdm","sdn","sdo","sdp","sdr","sds","sdt","sdu","sdv","sdx","sdz","sea","seb","sec","sed","see","sef","seg","seh","sei","sej","sek","sel","sem","sen","seo","sep","seq","ser","ses","set","seu","sev","sew","sey","sez","sfb","sfe","sfm","sfs","sfw","sga","sgb","sgc","sgd","sge","sgg","sgh","sgi","sgj","sgk","sgl","sgm","sgn","sgo","sgp","sgr","sgs","sgt","sgu","sgw","sgx","sgy","sgz","sha","shb","shc","shd","she","shg","shh","shi","shj","shk","shl","shm","shn","sho","shp","shq","shr","shs","sht","shu","shv","shw","shx","shy","shz","sia","sib","sid","sie","sif","sig","sih","sii","sij","sik","sil","sim","sio","sip","siq","sir","sis","sit","siu","siv","siw","six","siy","siz","sja","sjb","sjd","sje","sjg","sjk","sjl","sjm","sjn","sjo","sjp","sjr","sjs","sjt","sju","sjw","ska","skb","skc","skd","ske","skf","skg","skh","ski","skj","skk","skm","skn","sko","skp","skq","skr","sks","skt","sku","skv","skw","skx","sky","skz","sla","slc","sld","sle","slf","slg","slh","sli","slj","sll","slm","sln","slp","slq","slr","sls","slt","slu","slw","slx","sly","slz","sma","smb","smc","smd","smf","smg","smh","smi","smj","smk","sml","smm","smn","smp","smq","smr","sms","smt","smu","smv","smw","smx","smy","smz","snb","snc","sne","snf","sng","snh","sni","snj","snk","snl","snm","snn","sno","snp","snq","snr","sns","snu","snv","snw","snx","sny","snz","soa","sob","soc","sod","soe","sog","soh","soi","soj","sok","sol","son","soo","sop","soq","sor","sos","sou","sov","sow","sox","soy","soz","spb","spc","spd","spe","spg","spi","spk","spl","spm","spn","spo","spp","spq","spr","sps","spt","spu","spv","spx","spy","sqa","sqh","sqj","sqk","sqm","sqn","sqo","sqq","sqr","sqs","sqt","squ","sra","srb","src","sre","srf","srg","srh","sri","srk","srl","srm","srn","sro","srq","srr","srs","srt","sru","srv","srw","srx","sry","srz","ssa","ssb","ssc","ssd","sse","ssf","ssg","ssh","ssi","ssj","ssk","ssl","ssm","ssn","sso","ssp","ssq","ssr","sss","sst","ssu","ssv","ssx","ssy","ssz","sta","stb","std","ste","stf","stg","sth","sti","stj","stk","stl","stm","stn","sto","stp","stq","str","sts","stt","stu","stv","stw","sty","sua","sub","suc","sue","sug","sui","suj","suk","sul","sum","suq","sur","sus","sut","suv","suw","sux","suy","suz","sva","svb","svc","sve","svk","svm","svr","svs","svx","swb","swc","swf","swg","swh","swi","swj","swk","swl","swm","swn","swo","swp","swq","swr","sws","swt","swu","swv","sww","swx","swy","sxb","sxc","sxe","sxg","sxk","sxl","sxm","sxn","sxo","sxr","sxs","sxu","sxw","sya","syb","syc","syd","syi","syk","syl","sym","syn","syo","syr","sys","syw","syx","syy","sza","szb","szc","szd","sze","szg","szl","szn","szp","szs","szv","szw","taa","tab","tac","tad","tae","taf","tag","tai","taj","tak","tal","tan","tao","tap","taq","tar","tas","tau","tav","taw","tax","tay","taz","tba","tbb","tbc","tbd","tbe","tbf","tbg","tbh","tbi","tbj","tbk","tbl","tbm","tbn","tbo","tbp","tbq","tbr","tbs","tbt","tbu","tbv","tbw","tbx","tby","tbz","tca","tcb","tcc","tcd","tce","tcf","tcg","tch","tci","tck","tcl","tcm","tcn","tco","tcp","tcq","tcs","tct","tcu","tcw","tcx","tcy","tcz","tda","tdb","tdc","tdd","tde","tdf","tdg","tdh","tdi","tdj","tdk","tdl","tdm","tdn","tdo","tdq","tdr","tds","tdt","tdu","tdv","tdx","tdy","tea","teb","tec","ted","tee","tef","teg","teh","tei","tek","tem","ten","teo","tep","teq","ter","tes","tet","teu","tev","tew","tex","tey","tez","tfi","tfn","tfo","tfr","tft","tga","tgb","tgc","tgd","tge","tgf","tgg","tgh","tgi","tgj","tgn","tgo","tgp","tgq","tgr","tgs","tgt","tgu","tgv","tgw","tgx","tgy","tgz","thc","thd","the","thf","thh","thi","thk","thl","thm","thn","thp","thq","thr","ths","tht","thu","thv","thw","thx","thy","thz","tia","tic","tid","tie","tif","tig","tih","tii","tij","tik","til","tim","tin","tio","tip","tiq","tis","tit","tiu","tiv","tiw","tix","tiy","tiz","tja","tjg","tji","tjl","tjm","tjn","tjo","tjs","tju","tjw","tka","tkb","tkd","tke","tkf","tkg","tkk","tkl","tkm","tkn","tkp","tkq","tkr","tks","tkt","tku","tkv","tkw","tkx","tkz","tla","tlb","tlc","tld","tlf","tlg","tlh","tli","tlj","tlk","tll","tlm","tln","tlo","tlp","tlq","tlr","tls","tlt","tlu","tlv","tlw","tlx","tly","tma","tmb","tmc","tmd","tme","tmf","tmg","tmh","tmi","tmj","tmk","tml","tmm","tmn","tmo","tmp","tmq","tmr","tms","tmt","tmu","tmv","tmw","tmy","tmz","tna","tnb","tnc","tnd","tne","tnf","tng","tnh","tni","tnk","tnl","tnm","tnn","tno","tnp","tnq","tnr","tns","tnt","tnu","tnv","tnw","tnx","tny","tnz","tob","toc","tod","toe","tof","tog","toh","toi","toj","tol","tom","too","top","toq","tor","tos","tou","tov","tow","tox","toy","toz","tpa","tpc","tpe","tpf","tpg","tpi","tpj","tpk","tpl","tpm","tpn","tpo","tpp","tpq","tpr","tpt","tpu","tpv","tpw","tpx","tpy","tpz","tqb","tql","tqm","tqn","tqo","tqp","tqq","tqr","tqt","tqu","tqw","tra","trb","trc","trd","tre","trf","trg","trh","tri","trj","trk","trl","trm","trn","tro","trp","trq","trr","trs","trt","tru","trv","trw","trx","try","trz","tsa","tsb","tsc","tsd","tse","tsf","tsg","tsh","tsi","tsj","tsk","tsl","tsm","tsp","tsq","tsr","tss","tst","tsu","tsv","tsw","tsx","tsy","tsz","tta","ttb","ttc","ttd","tte","ttf","ttg","tth","tti","ttj","ttk","ttl","ttm","ttn","tto","ttp","ttq","ttr","tts","ttt","ttu","ttv","ttw","tty","ttz","tua","tub","tuc","tud","tue","tuf","tug","tuh","tui","tuj","tul","tum","tun","tuo","tup","tuq","tus","tut","tuu","tuv","tuw","tux","tuy","tuz","tva","tvd","tve","tvk","tvl","tvm","tvn","tvo","tvs","tvt","tvu","tvw","tvy","twa","twb","twc","twd","twe","twf","twg","twh","twl","twm","twn","two","twp","twq","twr","twt","twu","tww","twx","twy","txa","txb","txc","txe","txg","txh","txi","txj","txm","txn","txo","txq","txr","txs","txt","txu","txx","txy","tya","tye","tyh","tyi","tyj","tyl","tyn","typ","tyr","tys","tyt","tyu","tyv","tyx","tyz","tza","tzh","tzj","tzl","tzm","tzn","tzo","tzx","uam","uan","uar","uba","ubi","ubl","ubr","ubu","uby","uda","ude","udg","udi","udj","udl","udm","udu","ues","ufi","uga","ugb","uge","ugn","ugo","ugy","uha","uhn","uis","uiv","uji","uka","ukg","ukh","ukk","ukl","ukp","ukq","uks","uku","ukw","uky","ula","ulb","ulc","ule","ulf","uli","ulk","ull","ulm","uln","ulu","ulw","uma","umb","umc","umd","umg","umi","umm","umn","umo","ump","umr","ums","umu","una","und","une","ung","unk","unm","unn","unp","unr","unu","unx","unz","uok","upi","upv","ura","urb","urc","ure","urf","urg","urh","uri","urj","urk","url","urm","urn","uro","urp","urr","urt","uru","urv","urw","urx","ury","urz","usa","ush","usi","usk","usp","usu","uta","ute","utp","utr","utu","uum","uun","uur","uuu","uve","uvh","uvl","uwa","uya","uzn","uzs","vaa","vae","vaf","vag","vah","vai","vaj","val","vam","van","vao","vap","var","vas","vau","vav","vay","vbb","vbk","vec","ved","vel","vem","veo","vep","ver","vgr","vgt","vic","vid","vif","vig","vil","vin","vis","vit","viv","vka","vki","vkj","vkk","vkl","vkm","vko","vkp","vkt","vku","vlp","vls","vma","vmb","vmc","vmd","vme","vmf","vmg","vmh","vmi","vmj","vmk","vml","vmm","vmp","vmq","vmr","vms","vmu","vmv","vmw","vmx","vmy","vmz","vnk","vnm","vnp","vor","vot","vra","vro","vrs","vrt","vsi","vsl","vsv","vto","vum","vun","vut","vwa","waa","wab","wac","wad","wae","waf","wag","wah","wai","waj","wak","wal","wam","wan","wao","wap","waq","war","was","wat","wau","wav","waw","wax","way","waz","wba","wbb","wbe","wbf","wbh","wbi","wbj","wbk","wbl","wbm","wbp","wbq","wbr","wbs","wbt","wbv","wbw","wca","wci","wdd","wdg","wdj","wdk","wdu","wdy","wea","wec","wed","weg","weh","wei","wem","wen","weo","wep","wer","wes","wet","weu","wew","wfg","wga","wgb","wgg","wgi","wgo","wgu","wgw","wgy","wha","whg","whk","whu","wib","wic","wie","wif","wig","wih","wii","wij","wik","wil","wim","win","wir","wit","wiu","wiv","wiw","wiy","wja","wji","wka","wkb","wkd","wkl","wku","wkw","wky","wla","wlc","wle","wlg","wli","wlk","wll","wlm","wlo","wlr","wls","wlu","wlv","wlw","wlx","wly","wma","wmb","wmc","wmd","wme","wmh","wmi","wmm","wmn","wmo","wms","wmt","wmw","wmx","wnb","wnc","wnd","wne","wng","wni","wnk","wnm","wnn","wno","wnp","wnu","wnw","wny","woa","wob","woc","wod","woe","wof","wog","woi","wok","wom","won","woo","wor","wos","wow","woy","wpc","wra","wrb","wrd","wrg","wrh","wri","wrk","wrl","wrm","wrn","wro","wrp","wrr","wrs","wru","wrv","wrw","wrx","wry","wrz","wsa","wsg","wsi","wsk","wsr","wss","wsu","wsv","wtf","wth","wti","wtk","wtm","wtw","wua","wub","wud","wuh","wul","wum","wun","wur","wut","wuu","wuv","wux","wuy","wwa","wwb","wwo","wwr","www","wxa","wxw","wya","wyb","wyi","wym","wyr","wyy","xaa","xab","xac","xad","xae","xag","xai","xaj","xak","xal","xam","xan","xao","xap","xaq","xar","xas","xat","xau","xav","xaw","xay","xba","xbb","xbc","xbd","xbe","xbg","xbi","xbj","xbm","xbn","xbo","xbp","xbr","xbw","xbx","xby","xcb","xcc","xce","xcg","xch","xcl","xcm","xcn","xco","xcr","xct","xcu","xcv","xcw","xcy","xda","xdc","xdk","xdm","xdo","xdy","xeb","xed","xeg","xel","xem","xep","xer","xes","xet","xeu","xfa","xga","xgb","xgd","xgf","xgg","xgi","xgl","xgm","xgn","xgr","xgu","xgw","xha","xhc","xhd","xhe","xhr","xht","xhu","xhv","xia","xib","xii","xil","xin","xip","xir","xis","xiv","xiy","xjb","xjt","xka","xkb","xkc","xkd","xke","xkf","xkg","xkh","xki","xkj","xkk","xkl","xkn","xko","xkp","xkq","xkr","xks","xkt","xku","xkv","xkw","xkx","xky","xkz","xla","xlb","xlc","xld","xle","xlg","xli","xln","xlo","xlp","xls","xlu","xly","xma","xmb","xmc","xmd","xme","xmf","xmg","xmh","xmj","xmk","xml","xmm","xmn","xmo","xmp","xmq","xmr","xms","xmt","xmu","xmv","xmw","xmx","xmy","xmz","xna","xnb","xnd","xng","xnh","xni","xnk","xnn","xno","xnr","xns","xnt","xnu","xny","xnz","xoc","xod","xog","xoi","xok","xom","xon","xoo","xop","xor","xow","xpa","xpc","xpe","xpg","xpi","xpj","xpk","xpm","xpn","xpo","xpp","xpq","xpr","xps","xpt","xpu","xpy","xqa","xqt","xra","xrb","xrd","xre","xrg","xri","xrm","xrn","xrq","xrr","xrt","xru","xrw","xsa","xsb","xsc","xsd","xse","xsh","xsi","xsj","xsl","xsm","xsn","xso","xsp","xsq","xsr","xss","xsu","xsv","xsy","xta","xtb","xtc","xtd","xte","xtg","xth","xti","xtj","xtl","xtm","xtn","xto","xtp","xtq","xtr","xts","xtt","xtu","xtv","xtw","xty","xtz","xua","xub","xud","xug","xuj","xul","xum","xun","xuo","xup","xur","xut","xuu","xve","xvi","xvn","xvo","xvs","xwa","xwc","xwd","xwe","xwg","xwj","xwk","xwl","xwo","xwr","xwt","xww","xxb","xxk","xxm","xxr","xxt","xya","xyb","xyj","xyk","xyl","xyt","xyy","xzh","xzm","xzp","yaa","yab","yac","yad","yae","yaf","yag","yah","yai","yaj","yak","yal","yam","yan","yao","yap","yaq","yar","yas","yat","yau","yav","yaw","yax","yay","yaz","yba","ybb","ybd","ybe","ybh","ybi","ybj","ybk","ybl","ybm","ybn","ybo","ybx","yby","ych","ycl","ycn","ycp","yda","ydd","yde","ydg","ydk","yds","yea","yec","yee","yei","yej","yel","yen","yer","yes","yet","yeu","yev","yey","yga","ygi","ygl","ygm","ygp","ygr","ygs","ygu","ygw","yha","yhd","yhl","yhs","yia","yif","yig","yih","yii","yij","yik","yil","yim","yin","yip","yiq","yir","yis","yit","yiu","yiv","yix","yiy","yiz","yka","ykg","yki","ykk","ykl","ykm","ykn","yko","ykr","ykt","yku","yky","yla","ylb","yle","ylg","yli","yll","ylm","yln","ylo","ylr","ylu","yly","yma","ymb","ymc","ymd","yme","ymg","ymh","ymi","ymk","yml","ymm","ymn","ymo","ymp","ymq","ymr","yms","ymt","ymx","ymz","yna","ynd","yne","yng","ynh","ynk","ynl","ynn","yno","ynq","yns","ynu","yob","yog","yoi","yok","yol","yom","yon","yos","yot","yox","yoy","ypa","ypb","ypg","yph","ypk","ypm","ypn","ypo","ypp","ypz","yra","yrb","yre","yri","yrk","yrl","yrm","yrn","yro","yrs","yrw","yry","ysc","ysd","ysg","ysl","ysn","yso","ysp","ysr","yss","ysy","yta","ytl","ytp","ytw","yty","yua","yub","yuc","yud","yue","yuf","yug","yui","yuj","yuk","yul","yum","yun","yup","yuq","yur","yut","yuu","yuw","yux","yuy","yuz","yva","yvt","ywa","ywg","ywl","ywn","ywq","ywr","ywt","ywu","yww","yxa","yxg","yxl","yxm","yxu","yxy","yyr","yyu","yyz","yzg","yzk","zaa","zab","zac","zad","zae","zaf","zag","zah","zai","zaj","zak","zal","zam","zao","zap","zaq","zar","zas","zat","zau","zav","zaw","zax","zay","zaz","zbc","zbe","zbl","zbt","zbw","zca","zch","zdj","zea","zeg","zeh","zen","zga","zgb","zgh","zgm","zgn","zgr","zhb","zhd","zhi","zhn","zhw","zhx","zia","zib","zik","zil","zim","zin","zir","ziw","ziz","zka","zkb","zkd","zkg","zkh","zkk","zkn","zko","zkp","zkr","zkt","zku","zkv","zkz","zle","zlj","zlm","zln","zlq","zls","zlw","zma","zmb","zmc","zmd","zme","zmf","zmg","zmh","zmi","zmj","zmk","zml","zmm","zmn","zmo","zmp","zmq","zmr","zms","zmt","zmu","zmv","zmw","zmx","zmy","zmz","zna","znd","zne","zng","znk","zns","zoc","zoh","zom","zoo","zoq","zor","zos","zpa","zpb","zpc","zpd","zpe","zpf","zpg","zph","zpi","zpj","zpk","zpl","zpm","zpn","zpo","zpp","zpq","zpr","zps","zpt","zpu","zpv","zpw","zpx","zpy","zpz","zqe","zra","zrg","zrn","zro","zrp","zrs","zsa","zsk","zsl","zsm","zsr","zsu","zte","ztg","ztl","ztm","ztn","ztp","ztq","zts","ztt","ztu","ztx","zty","zua","zuh","zum","zun","zuy","zwa","zxx","zyb","zyg","zyj","zyn","zyp","zza","zzj"];function he(e){return ye(e)||ge(e)||be()}function be(){throw new TypeError("Invalid attempt to spread non-iterable instance")}function ge(e){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e))return Array.from(e)}function ye(e){if(Array.isArray(e)){for(var t=0,n=new Array(e.length);t<e.length;t++)n[t]=e[t];return n}}function R(){return(R=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}function S(e){return(S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}axe.utils.validLangs=function(){"use strict";return Ie},axe._load({data:{rules:{accesskeys:{description:"Ensures every accesskey attribute value is unique",help:"accesskey attribute value must be unique"},"area-alt":{description:"Ensures <area> elements of image maps have alternate text",help:"Active <area> elements must have alternate text"},"aria-allowed-attr":{description:"Ensures ARIA attributes are allowed for an element's role",help:"Elements must only use allowed ARIA attributes"},"aria-allowed-role":{description:"Ensures role attribute has an appropriate value for the element",help:"ARIA role must be appropriate for the element"},"aria-dpub-role-fallback":{description:"Ensures unsupported DPUB roles are only used on elements with implicit fallback roles",help:"Unsupported DPUB ARIA roles should be used on elements with implicit fallback roles"},"aria-hidden-body":{description:"Ensures aria-hidden='true' is not present on the document body.",help:"aria-hidden='true' must not be present on the document body"},"aria-hidden-focus":{description:"Ensures aria-hidden elements do not contain focusable elements",help:"ARIA hidden element must not contain focusable elements"},"aria-input-field-name":{description:"Ensures every ARIA input field has an accessible name",help:"ARIA input fields have an accessible name"},"aria-required-attr":{description:"Ensures elements with ARIA roles have all required ARIA attributes",help:"Required ARIA attributes must be provided"},"aria-required-children":{description:"Ensures elements with an ARIA role that require child roles contain them",help:"Certain ARIA roles must contain particular children"},"aria-required-parent":{description:"Ensures elements with an ARIA role that require parent roles are contained by them",help:"Certain ARIA roles must be contained by particular parents"},"aria-roles":{description:"Ensures all elements with a role attribute use a valid value",help:"ARIA roles used must conform to valid values"},"aria-toggle-field-name":{description:"Ensures every ARIA toggle field has an accessible name",help:"ARIA toggle fields have an accessible name"},"aria-valid-attr-value":{description:"Ensures all ARIA attributes have valid values",help:"ARIA attributes must conform to valid values"},"aria-valid-attr":{description:"Ensures attributes that begin with aria- are valid ARIA attributes",help:"ARIA attributes must conform to valid names"},"audio-caption":{description:"Ensures <audio> elements have captions",help:"<audio> elements must have a captions track"},"autocomplete-valid":{description:"Ensure the autocomplete attribute is correct and suitable for the form field",help:"autocomplete attribute must be used correctly"},"avoid-inline-spacing":{description:"Ensure that text spacing set through style attributes can be adjusted with custom stylesheets",help:"Inline text spacing must be adjustable with custom stylesheets"},blink:{description:"Ensures <blink> elements are not used",help:"<blink> elements are deprecated and must not be used"},"button-name":{description:"Ensures buttons have discernible text",help:"Buttons must have discernible text"},bypass:{description:"Ensures each page has at least one mechanism for a user to bypass navigation and jump straight to the content",help:"Page must have means to bypass repeated blocks"},checkboxgroup:{description:'Ensures related <input type="checkbox"> elements have a group and that the group designation is consistent',help:"Checkbox inputs with the same name attribute value must be part of a group"},"color-contrast":{description:"Ensures the contrast between foreground and background colors meets WCAG 2 AA contrast ratio thresholds",help:"Elements must have sufficient color contrast"},"css-orientation-lock":{description:"Ensures content is not locked to any specific display orientation, and the content is operable in all display orientations",help:"CSS Media queries are not used to lock display orientation"},"definition-list":{description:"Ensures <dl> elements are structured correctly",help:"<dl> elements must only directly contain properly-ordered <dt> and <dd> groups, <script> or <template> elements"},dlitem:{description:"Ensures <dt> and <dd> elements are contained by a <dl>",help:"<dt> and <dd> elements must be contained by a <dl>"},"document-title":{description:"Ensures each HTML document contains a non-empty <title> element",help:"Documents must have <title> element to aid in navigation"},"duplicate-id-active":{description:"Ensures every id attribute value of active elements is unique",help:"IDs of active elements must be unique"},"duplicate-id-aria":{description:"Ensures every id attribute value used in ARIA and in labels is unique",help:"IDs used in ARIA and labels must be unique"},"duplicate-id":{description:"Ensures every id attribute value is unique",help:"id attribute value must be unique"},"empty-heading":{description:"Ensures headings have discernible text",help:"Headings must not be empty"},"focus-order-semantics":{description:"Ensures elements in the focus order have an appropriate role",help:"Elements in the focus order need a role appropriate for interactive content"},"form-field-multiple-labels":{description:"Ensures form field does not have multiple label elements",help:"Form field must not have multiple label elements"},"frame-tested":{description:"Ensures <iframe> and <frame> elements contain the axe-core script",help:"Frames must be tested with axe-core"},"frame-title-unique":{description:"Ensures <iframe> and <frame> elements contain a unique title attribute",help:"Frames must have a unique title attribute"},"frame-title":{description:"Ensures <iframe> and <frame> elements contain a non-empty title attribute",help:"Frames must have title attribute"},"heading-order":{description:"Ensures the order of headings is semantically correct",help:"Heading levels should only increase by one"},"hidden-content":{description:"Informs users about hidden content.",help:"Hidden content on the page cannot be analyzed"},"html-has-lang":{description:"Ensures every HTML document has a lang attribute",help:"<html> element must have a lang attribute"},"html-lang-valid":{description:"Ensures the lang attribute of the <html> element has a valid value",help:"<html> element must have a valid value for the lang attribute"},"html-xml-lang-mismatch":{description:"Ensure that HTML elements with both valid lang and xml:lang attributes agree on the base language of the page",help:"HTML elements with lang and xml:lang must have the same base language"},"image-alt":{description:"Ensures <img> elements have alternate text or a role of none or presentation",help:"Images must have alternate text"},"image-redundant-alt":{description:"Ensure image alternative is not repeated as text",help:"Alternative text of images should not be repeated as text"},"input-button-name":{description:"Ensures input buttons have discernible text",help:"Input buttons must have discernible text"},"input-image-alt":{description:'Ensures <input type="image"> elements have alternate text',help:"Image buttons must have alternate text"},"label-content-name-mismatch":{description:"Ensures that elements labelled through their content must have their visible text as part of their accessible name",help:"Elements must have their visible text as part of their accessible name"},"label-title-only":{description:"Ensures that every form element is not solely labeled using the title or aria-describedby attributes",help:"Form elements should have a visible label"},label:{description:"Ensures every form element has a label",help:"Form elements must have labels"},"landmark-banner-is-top-level":{description:"Ensures the banner landmark is at top level",help:"Banner landmark must not be contained in another landmark"},"landmark-complementary-is-top-level":{description:"Ensures the complementary landmark or aside is at top level",help:"Aside must not be contained in another landmark"},"landmark-contentinfo-is-top-level":{description:"Ensures the contentinfo landmark is at top level",help:"Contentinfo landmark must not be contained in another landmark"},"landmark-main-is-top-level":{description:"Ensures the main landmark is at top level",help:"Main landmark must not be contained in another landmark"},"landmark-no-duplicate-banner":{description:"Ensures the document has at most one banner landmark",help:"Document must not have more than one banner landmark"},"landmark-no-duplicate-contentinfo":{description:"Ensures the document has at most one contentinfo landmark",help:"Document must not have more than one contentinfo landmark"},"landmark-one-main":{description:"Ensures the document has only one main landmark and each iframe in the page has at most one main landmark",help:"Document must have one main landmark"},"landmark-unique":{help:"Ensures landmarks are unique",description:"Landmarks must have a unique role or role/label/title (i.e. accessible name) combination"},"layout-table":{description:"Ensures presentational <table> elements do not use <th>, <caption> elements or the summary attribute",help:"Layout tables must not use data table elements"},"link-in-text-block":{description:"Links can be distinguished without relying on color",help:"Links must be distinguished from surrounding text in a way that does not rely on color"},"link-name":{description:"Ensures links have discernible text",help:"Links must have discernible text"},list:{description:"Ensures that lists are structured correctly",help:"<ul> and <ol> must only directly contain <li>, <script> or <template> elements"},listitem:{description:"Ensures <li> elements are used semantically",help:"<li> elements must be contained in a <ul> or <ol>"},marquee:{description:"Ensures <marquee> elements are not used",help:"<marquee> elements are deprecated and must not be used"},"meta-refresh":{description:'Ensures <meta http-equiv="refresh"> is not used',help:"Timed refresh must not exist"},"meta-viewport-large":{description:'Ensures <meta name="viewport"> can scale a significant amount',help:"Users should be able to zoom and scale the text up to 500%"},"meta-viewport":{description:'Ensures <meta name="viewport"> does not disable text scaling and zooming',help:"Zooming and scaling must not be disabled"},"object-alt":{description:"Ensures <object> elements have alternate text",help:"<object> elements must have alternate text"},"p-as-heading":{description:"Ensure p elements are not used to style headings",help:"Bold, italic text and font-size are not used to style p elements as a heading"},"page-has-heading-one":{description:"Ensure that the page, or at least one of its frames contains a level-one heading",help:"Page must contain a level-one heading"},radiogroup:{description:'Ensures related <input type="radio"> elements have a group and that the group designation is consistent',help:"Radio inputs with the same name attribute value must be part of a group"},region:{description:"Ensures all page content is contained by landmarks",help:"All page content must be contained by landmarks"},"role-img-alt":{description:"Ensures [role='img'] elements have alternate text",help:"[role='img'] elements have an alternative text"},"scope-attr-valid":{description:"Ensures the scope attribute is used correctly on tables",help:"scope attribute should be used correctly"},"scrollable-region-focusable":{description:"Elements that have scrollable content should be accessible by keyboard",help:"Ensure that scrollable region has keyboard access"},"server-side-image-map":{description:"Ensures that server-side image maps are not used",help:"Server-side image maps must not be used"},"skip-link":{description:"Ensure all skip links have a focusable target",help:"The skip-link target should exist and be focusable"},tabindex:{description:"Ensures tabindex attribute values are not greater than 0",help:"Elements should not have tabindex greater than zero"},"table-duplicate-name":{description:"Ensure that tables do not have the same summary and caption",help:"The <caption> element should not contain the same text as the summary attribute"},"table-fake-caption":{description:"Ensure that tables with a caption use the <caption> element.",help:"Data or header cells should not be used to give caption to a data table."},"td-has-header":{description:"Ensure that each non-empty data cell in a large table has one or more table headers",help:"All non-empty td element in table larger than 3 by 3 must have an associated table header"},"td-headers-attr":{description:"Ensure that each cell in a table using the headers refers to another cell in that table",help:"All cells in a table element that use the headers attribute must only refer to other cells of that same table"},"th-has-data-cells":{description:"Ensure that each table header in a data table refers to data cells",help:"All th elements and elements with role=columnheader/rowheader must have data cells they describe"},"valid-lang":{description:"Ensures lang attributes have valid values",help:"lang attribute must have a valid value"},"video-caption":{description:"Ensures <video> elements have captions",help:"<video> elements must have captions"},"video-description":{description:"Ensures <video> elements have audio descriptions",help:"<video> elements must have an audio description track"}},checks:{accesskeys:{impact:"serious",messages:{pass:function(e){return"Accesskey attribute value is unique"},fail:function(e){return"Document has multiple elements with the same accesskey"}}},"non-empty-alt":{impact:"critical",messages:{pass:function(e){return"Element has a non-empty alt attribute"},fail:function(e){return"Element has no alt attribute or the alt attribute is empty"}}},"non-empty-title":{impact:"serious",messages:{pass:function(e){return"Element has a title attribute"},fail:function(e){return"Element has no title attribute or the title attribute is empty"}}},"aria-label":{impact:"serious",messages:{pass:function(e){return"aria-label attribute exists and is not empty"},fail:function(e){return"aria-label attribute does not exist or is empty"}}},"aria-labelledby":{impact:"serious",messages:{pass:function(e){return"aria-labelledby attribute exists and references elements that are visible to screen readers"},fail:function(e){return"aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty"}}},"aria-allowed-attr":{impact:"critical",messages:{pass:function(e){return"ARIA attributes are used correctly for the defined role"},fail:function(e){var t="ARIA attribute"+(e.data&&1<e.data.length?"s are":" is")+" not allowed:",n=e.data;if(n)for(var r=-1,a=n.length-1;r<a;)t+=" "+n[r+=1];return t}}},"aria-unsupported-attr":{impact:"critical",messages:{pass:function(e){return"ARIA attribute is supported"},fail:function(e){var t="ARIA attribute is not widely supported in screen readers and assistive technologies: ",n=e.data;if(n)for(var r=-1,a=n.length-1;r<a;)t+=" "+n[r+=1];return t}}},"aria-allowed-role":{impact:"minor",messages:{pass:function(e){return"ARIA role is allowed for given element"},fail:function(e){return"ARIA role"+(e.data&&1<e.data.length?"s":"")+" "+e.data.join(", ")+" "+(e.data&&1<e.data.length?"are":" is")+" not allowed for given element"},incomplete:function(e){return"ARIA role"+(e.data&&1<e.data.length?"s":"")+" "+e.data.join(", ")+" must be removed when the element is made visible, as "+(e.data&&1<e.data.length?"they are":"it is")+" not allowed for the element"}}},"implicit-role-fallback":{impact:"moderate",messages:{pass:function(e){return"Element’s implicit ARIA role is an appropriate fallback"},fail:function(e){return"Element’s implicit ARIA role is not a good fallback for the (unsupported) role"}}},"aria-hidden-body":{impact:"critical",messages:{pass:function(e){return"No aria-hidden attribute is present on document body"},fail:function(e){return"aria-hidden=true should not be present on the document body"}}},"focusable-disabled":{impact:"serious",messages:{pass:function(e){return"No focusable elements contained within element"},fail:function(e){return"Focusable content should be disabled or be removed from the DOM"}}},"focusable-not-tabbable":{impact:"serious",messages:{pass:function(e){return"No focusable elements contained within element"},fail:function(e){return"Focusable content should have tabindex='-1' or be removed from the DOM"}}},"no-implicit-explicit-label":{impact:"moderate",messages:{pass:function(e){return"There is no mismatch between a <label> and accessible name"},incomplete:function(e){return"Check that the <label> does not need be part of the ARIA "+e.data+" field's name"}}},"aria-required-attr":{impact:"critical",messages:{pass:function(e){return"All required ARIA attributes are present"},fail:function(e){var t="Required ARIA attribute"+(e.data&&1<e.data.length?"s":"")+" not present:",n=e.data;if(n)for(var r=-1,a=n.length-1;r<a;)t+=" "+n[r+=1];return t}}},"aria-required-children":{impact:"critical",messages:{pass:function(e){return"Required ARIA children are present"},fail:function(e){var t="Required ARIA "+(e.data&&1<e.data.length?"children":"child")+" role not present:",n=e.data;if(n)for(var r=-1,a=n.length-1;r<a;)t+=" "+n[r+=1];return t},incomplete:function(e){var t="Expecting ARIA "+(e.data&&1<e.data.length?"children":"child")+" role to be added:",n=e.data;if(n)for(var r=-1,a=n.length-1;r<a;)t+=" "+n[r+=1];return t}}},"aria-required-parent":{impact:"critical",messages:{pass:function(e){return"Required ARIA parent role present"},fail:function(e){var t="Required ARIA parent"+(e.data&&1<e.data.length?"s":"")+" role not present:",n=e.data;if(n)for(var r=-1,a=n.length-1;r<a;)t+=" "+n[r+=1];return t}}},invalidrole:{impact:"critical",messages:{pass:function(e){return"ARIA role is valid"},fail:function(e){return"Role must be one of the valid ARIA roles"}}},abstractrole:{impact:"serious",messages:{pass:function(e){return"Abstract roles are not used"},fail:function(e){return"Abstract roles cannot be directly used"}}},unsupportedrole:{impact:"critical",messages:{pass:function(e){return"ARIA role is supported"},fail:function(e){var t="The role used is not widely supported in screen readers and assistive technologies: ",n=e.data;if(n)for(var r=-1,a=n.length-1;r<a;)t+=" "+n[r+=1];return t}}},"has-visible-text":{impact:"minor",messages:{pass:function(e){return"Element has text that is visible to screen readers"},fail:function(e){return"Element does not have text that is visible to screen readers"}}},"aria-valid-attr-value":{impact:"critical",messages:{pass:function(e){return"ARIA attribute values are valid"},fail:function(e){var t="Invalid ARIA attribute value"+(e.data&&1<e.data.length?"s":"")+":",n=e.data;if(n)for(var r=-1,a=n.length-1;r<a;)t+=" "+n[r+=1];return t},incomplete:function(e){var t="ARIA attribute"+(e.data&&1<e.data.length?"s":"")+" element ID does not exist on the page:",n=e.data;if(n)for(var r=-1,a=n.length-1;r<a;)t+=" "+n[r+=1];return t}}},"aria-errormessage":{impact:"critical",messages:{pass:function(e){return"Uses a supported aria-errormessage technique"},fail:function(e){var t="aria-errormessage value"+(e.data&&1<e.data.length?"s":"")+" ",n=e.data;if(n)for(var r=-1,a=n.length-1;r<a;)t+=" `"+n[r+=1];return t+="` must use a technique to announce the message (e.g., aria-live, aria-describedby, role=alert, etc.)"}}},"aria-valid-attr":{impact:"critical",messages:{pass:function(e){return"ARIA attribute name"+(e.data&&1<e.data.length?"s":"")+" are valid"},fail:function(e){var t="Invalid ARIA attribute name"+(e.data&&1<e.data.length?"s":"")+":",n=e.data;if(n)for(var r=-1,a=n.length-1;r<a;)t+=" "+n[r+=1];return t}}},caption:{impact:"critical",messages:{pass:function(e){return"The multimedia element has a captions track"},incomplete:function(e){return"Check that captions is available for the element"}}},"autocomplete-valid":{impact:"serious",messages:{pass:function(e){return"the autocomplete attribute is correctly formatted"},fail:function(e){return"the autocomplete attribute is incorrectly formatted"}}},"autocomplete-appropriate":{impact:"serious",messages:{pass:function(e){return"the autocomplete value is on an appropriate element"},fail:function(e){return"the autocomplete value is inappropriate for this type of input"}}},"avoid-inline-spacing":{impact:"serious",messages:{pass:function(e){return"No inline styles with '!important' that affect text spacing has been specified"},fail:function(e){return"Remove '!important' from inline style"+(e.data&&1<e.data.length?"s":"")+" "+e.data.join(", ")+", as overriding this is not supported by most browsers"}}},"is-on-screen":{impact:"serious",messages:{pass:function(e){return"Element is not visible"},fail:function(e){return"Element is visible"}}},"button-has-visible-text":{impact:"critical",messages:{pass:function(e){return"Element has inner text that is visible to screen readers"},fail:function(e){return"Element does not have inner text that is visible to screen readers"}}},"role-presentation":{impact:"minor",messages:{pass:function(e){return'Element\'s default semantics were overriden with role="presentation"'},fail:function(e){return'Element\'s default semantics were not overridden with role="presentation"'}}},"role-none":{impact:"minor",messages:{pass:function(e){return'Element\'s default semantics were overriden with role="none"'},fail:function(e){return'Element\'s default semantics were not overridden with role="none"'}}},"internal-link-present":{impact:"serious",messages:{pass:function(e){return"Valid skip link found"},fail:function(e){return"No valid skip link found"}}},"header-present":{impact:"serious",messages:{pass:function(e){return"Page has a header"},fail:function(e){return"Page does not have a header"}}},landmark:{impact:"serious",messages:{pass:function(e){return"Page has a landmark region"},fail:function(e){return"Page does not have a landmark region"}}},"group-labelledby":{impact:"critical",messages:{pass:function(e){return'Elements with the name "'+e.data.name+'" have both a shared label, and a unique label, referenced through aria-labelledby'},fail:function(e){var t="",n=e.data&&e.data.failureCode;return t+='Elements with the name "'+e.data.name+'" do not all have ',t+="no-shared-label"===n?"a shared label":"no-unique-label"===n?"a unique label":"both a shared label, and a unique label",t+=", referenced through aria-labelledby"}}},fieldset:{impact:"critical",messages:{pass:function(e){return"Element is contained in a fieldset"},fail:function(e){var t="",n=e.data&&e.data.failureCode;return t+="no-legend"===n?"Fieldset does not have a legend as its first child":"empty-legend"===n?"Legend does not have text that is visible to screen readers":"mixed-inputs"===n?"Fieldset contains unrelated inputs":"no-group-label"===n?"ARIA group does not have aria-label or aria-labelledby":"group-mixed-inputs"===n?"ARIA group contains unrelated inputs":"Element does not have a containing fieldset or ARIA group"}}},"color-contrast":{impact:"serious",messages:{pass:function(e){return"Element has sufficient color contrast of "+e.data.contrastRatio},fail:function(e){return"Element has insufficient color contrast of "+e.data.contrastRatio+" (foreground color: "+e.data.fgColor+", background color: "+e.data.bgColor+", font size: "+e.data.fontSize+", font weight: "+e.data.fontWeight+"). Expected contrast ratio of "+e.data.expectedContrastRatio},incomplete:{bgImage:"Element's background color could not be determined due to a background image",bgGradient:"Element's background color could not be determined due to a background gradient",imgNode:"Element's background color could not be determined because element contains an image node",bgOverlap:"Element's background color could not be determined because it is overlapped by another element",fgAlpha:"Element's foreground color could not be determined because of alpha transparency",elmPartiallyObscured:"Element's background color could not be determined because it's partially obscured by another element",elmPartiallyObscuring:"Element's background color could not be determined because it partially overlaps other elements",outsideViewport:"Element's background color could not be determined because it's outside the viewport",equalRatio:"Element has a 1:1 contrast ratio with the background",shortTextContent:"Element content is too short to determine if it is actual text content",default:"Unable to determine contrast ratio"}}},"css-orientation-lock":{impact:"serious",messages:{pass:function(e){return"Display is operable, and orientation lock does not exist"},fail:function(e){return"CSS Orientation lock is applied, and makes display inoperable"},incomplete:function(e){return"CSS Orientation lock cannot be determined"}}},"structured-dlitems":{impact:"serious",messages:{pass:function(e){return"When not empty, element has both <dt> and <dd> elements"},fail:function(e){return"When not empty, element does not have at least one <dt> element followed by at least one <dd> element"}}},"only-dlitems":{impact:"serious",messages:{pass:function(e){return"List element only has direct children that are allowed inside <dt> or <dd> elements"},fail:function(e){return"List element has direct children that are not allowed inside <dt> or <dd> elements"}}},dlitem:{impact:"serious",messages:{pass:function(e){return"Description list item has a <dl> parent element"},fail:function(e){return"Description list item does not have a <dl> parent element"}}},"doc-has-title":{impact:"serious",messages:{pass:function(e){return"Document has a non-empty <title> element"},fail:function(e){return"Document does not have a non-empty <title> element"}}},"duplicate-id-active":{impact:"serious",messages:{pass:function(e){return"Document has no active elements that share the same id attribute"},fail:function(e){return"Document has active elements with the same id attribute: "+e.data}}},"duplicate-id-aria":{impact:"critical",messages:{pass:function(e){return"Document has no elements referenced with ARIA or labels that share the same id attribute"},fail:function(e){return"Document has multiple elements referenced with ARIA with the same id attribute: "+e.data}}},"duplicate-id":{impact:"minor",messages:{pass:function(e){return"Document has no static elements that share the same id attribute"},fail:function(e){return"Document has multiple static elements with the same id attribute"}}},"has-widget-role":{impact:"minor",messages:{pass:function(e){return"Element has a widget role."},fail:function(e){return"Element does not have a widget role."}}},"valid-scrollable-semantics":{impact:"minor",messages:{pass:function(e){return"Element has valid semantics for an element in the focus order."},fail:function(e){return"Element has invalid semantics for an element in the focus order."}}},"multiple-label":{impact:"moderate",messages:{pass:function(e){return"Form field does not have multiple label elements"},fail:function(e){return"Multiple label elements is not widely supported in assistive technologies"}}},"frame-tested":{impact:"critical",messages:{pass:function(e){return"The iframe was tested with axe-core"},fail:function(e){return"The iframe could not be tested with axe-core"},incomplete:function(e){return"The iframe still has to be tested with axe-core"}}},"unique-frame-title":{impact:"serious",messages:{pass:function(e){return"Element's title attribute is unique"},fail:function(e){return"Element's title attribute is not unique"}}},"heading-order":{impact:"moderate",messages:{pass:function(e){return"Heading order valid"},fail:function(e){return"Heading order invalid"}}},"hidden-content":{impact:"minor",messages:{pass:function(e){return"All content on the page has been analyzed."},fail:function(e){return"There were problems analyzing the content on this page."},incomplete:function(e){return"There is hidden content on the page that was not analyzed. You will need to trigger the display of this content in order to analyze it."}}},"has-lang":{impact:"serious",messages:{pass:function(e){return"The <html> element has a lang attribute"},fail:function(e){return"The <html> element does not have a lang attribute"}}},"valid-lang":{impact:"serious",messages:{pass:function(e){return"Value of lang attribute is included in the list of valid languages"},fail:function(e){return"Value of lang attribute not included in the list of valid languages"}}},"xml-lang-mismatch":{impact:"moderate",messages:{pass:function(e){return"Lang and xml:lang attributes have the same base language"},fail:function(e){return"Lang and xml:lang attributes do not have the same base language"}}},"has-alt":{impact:"critical",messages:{pass:function(e){return"Element has an alt attribute"},fail:function(e){return"Element does not have an alt attribute"}}},"alt-space-value":{impact:"critical",messages:{pass:function(e){return"Element has a valid alt attribute value"},fail:function(e){return"Element has an alt attribute containing only a space character, which is not ignored by all screen readers"}}},"duplicate-img-label":{impact:"minor",messages:{pass:function(e){return"Element does not duplicate existing text in <img> alt text"},fail:function(e){return"Element contains <img> element with alt text that duplicates existing text"}}},"non-empty-if-present":{impact:"critical",messages:{pass:function(e){var t="Element ";return e.data?t+="has a non-empty value attribute":t+="does not have a value attribute",t},fail:function(e){return"Element has a value attribute and the value attribute is empty"}}},"non-empty-value":{impact:"critical",messages:{pass:function(e){return"Element has a non-empty value attribute"},fail:function(e){return"Element has no value attribute or the value attribute is empty"}}},"label-content-name-mismatch":{impact:"serious",messages:{pass:function(e){return"Element contains visible text as part of it's accessible name"},fail:function(e){return"Text inside the element is not included in the accessible name"}}},"title-only":{impact:"serious",messages:{pass:function(e){return"Form element does not solely use title attribute for its label"},fail:function(e){return"Only title used to generate label for form element"}}},"implicit-label":{impact:"critical",messages:{pass:function(e){return"Form element has an implicit (wrapped) <label>"},fail:function(e){return"Form element does not have an implicit (wrapped) <label>"}}},"explicit-label":{impact:"critical",messages:{pass:function(e){return"Form element has an explicit <label>"},fail:function(e){return"Form element does not have an explicit <label>"}}},"help-same-as-label":{impact:"minor",messages:{pass:function(e){return"Help text (title or aria-describedby) does not duplicate label text"},fail:function(e){return"Help text (title or aria-describedby) text is the same as the label text"}}},"hidden-explicit-label":{impact:"critical",messages:{pass:function(e){return"Form element has a visible explicit <label>"},fail:function(e){return"Form element has explicit <label> that is hidden"}}},"landmark-is-top-level":{impact:"moderate",messages:{pass:function(e){return"The "+e.data.role+" landmark is at the top level."},fail:function(e){return"The "+e.data.role+" landmark is contained in another landmark."}}},"page-no-duplicate-banner":{impact:"moderate",messages:{pass:function(e){return"Document does not have more than one banner landmark"},fail:function(e){return"Document has more than one banner landmark"}}},"page-no-duplicate-contentinfo":{impact:"moderate",messages:{pass:function(e){return"Document does not have more than one contentinfo landmark"},fail:function(e){return"Document has more than one contentinfo landmark"}}},"page-has-main":{impact:"moderate",messages:{pass:function(e){return"Document has at least one main landmark"},fail:function(e){return"Document does not have a main landmark"}}},"page-no-duplicate-main":{impact:"moderate",messages:{pass:function(e){return"Document does not have more than one main landmark"},fail:function(e){return"Document has more than one main landmark"}}},"landmark-is-unique":{impact:"moderate",messages:{pass:function(e){return"Landmarks must have a unique role or role/label/title (i.e. accessible name) combination"},fail:function(e){return"The landmark must have a unique aria-label, aria-labelledby, or title to make landmarks distinguishable"}}},"has-th":{impact:"serious",messages:{pass:function(e){return"Layout table does not use <th> elements"},fail:function(e){return"Layout table uses <th> elements"}}},"has-caption":{impact:"serious",messages:{pass:function(e){return"Layout table does not use <caption> element"},fail:function(e){return"Layout table uses <caption> element"}}},"has-summary":{impact:"serious",messages:{pass:function(e){return"Layout table does not use summary attribute"},fail:function(e){return"Layout table uses summary attribute"}}},"link-in-text-block":{impact:"serious",messages:{pass:function(e){return"Links can be distinguished from surrounding text in some way other than by color"},fail:function(e){return"Links need to be distinguished from surrounding text in some way other than by color"},incomplete:{bgContrast:"Element's contrast ratio could not be determined. Check for a distinct hover/focus style",bgImage:"Element's contrast ratio could not be determined due to a background image",bgGradient:"Element's contrast ratio could not be determined due to a background gradient",imgNode:"Element's contrast ratio could not be determined because element contains an image node",bgOverlap:"Element's contrast ratio could not be determined because of element overlap",default:"Unable to determine contrast ratio"}}},"focusable-no-name":{impact:"serious",messages:{pass:function(e){return"Element is not in tab order or has accessible text"},fail:function(e){return"Element is in tab order and does not have accessible text"}}},"only-listitems":{impact:"serious",messages:{pass:function(e){return"List element only has direct children that are allowed inside <li> elements"},fail:function(e){return"List element has direct children that are not allowed inside <li> elements"}}},listitem:{impact:"serious",messages:{pass:function(e){return'List item has a <ul>, <ol> or role="list" parent element'},fail:function(e){return'List item does not have a <ul>, <ol> or role="list" parent element'}}},"meta-refresh":{impact:"critical",messages:{pass:function(e){return"<meta> tag does not immediately refresh the page"},fail:function(e){return"<meta> tag forces timed refresh of page"}}},"meta-viewport-large":{impact:"minor",messages:{pass:function(e){return"<meta> tag does not prevent significant zooming on mobile devices"},fail:function(e){return"<meta> tag limits zooming on mobile devices"}}},"meta-viewport":{impact:"critical",messages:{pass:function(e){return"<meta> tag does not disable zooming on mobile devices"},fail:function(e){return e.data+" on <meta> tag disables zooming on mobile devices"}}},"p-as-heading":{impact:"serious",messages:{pass:function(e){return"<p> elements are not styled as headings"},fail:function(e){return"Heading elements should be used instead of styled p elements"}}},"page-has-heading-one":{impact:"moderate",messages:{pass:function(e){return"Page has at least one level-one heading"},fail:function(e){return"Page must have a level-one heading"}}},region:{impact:"moderate",messages:{pass:function(e){return"All page content is contained by landmarks"},fail:function(e){return"Some page content is not contained by landmarks"}}},"html5-scope":{impact:"moderate",messages:{pass:function(e){return"Scope attribute is only used on table header elements (<th>)"},fail:function(e){return"In HTML 5, scope attributes may only be used on table header elements (<th>)"}}},"scope-value":{impact:"critical",messages:{pass:function(e){return"Scope attribute is used correctly"},fail:function(e){return"The value of the scope attribute may only be 'row' or 'col'"}}},"focusable-content":{impact:"moderate",messages:{pass:function(e){return"Element contains focusable elements"},fail:function(e){return"Element should have focusable content"}}},"focusable-element":{impact:"moderate",messages:{pass:function(e){return"Element is focusable"},fail:function(e){return"Element should be focusable"}}},exists:{impact:"minor",messages:{pass:function(e){return"Element does not exist"},fail:function(e){return"Element exists"}}},"skip-link":{impact:"moderate",messages:{pass:function(e){return"Skip link target exists"},incomplete:function(e){return"Skip link target should become visible on activation"},fail:function(e){return"No skip link target"}}},tabindex:{impact:"serious",messages:{pass:function(e){return"Element does not have a tabindex greater than 0"},fail:function(e){return"Element has a tabindex greater than 0"}}},"same-caption-summary":{impact:"minor",messages:{pass:function(e){return"Content of summary attribute and <caption> are not duplicated"},fail:function(e){return"Content of summary attribute and <caption> element are identical"}}},"caption-faked":{impact:"serious",messages:{pass:function(e){return"The first row of a table is not used as a caption"},fail:function(e){return"The first row of the table should be a caption instead of a table cell"}}},"td-has-header":{impact:"critical",messages:{pass:function(e){return"All non-empty data cells have table headers"},fail:function(e){return"Some non-empty data cells do not have table headers"}}},"td-headers-attr":{impact:"serious",messages:{pass:function(e){return"The headers attribute is exclusively used to refer to other cells in the table"},fail:function(e){return"The headers attribute is not exclusively used to refer to other cells in the table"}}},"th-has-data-cells":{impact:"serious",messages:{pass:function(e){return"All table header cells refer to data cells"},fail:function(e){return"Not all table header cells refer to data cells"},incomplete:function(e){return"Table data cells are missing or empty"}}},description:{impact:"critical",messages:{pass:function(e){return"The multimedia element has an audio description track"},incomplete:function(e){return"Check that audio description is available for the element"}}}},failureSummaries:{any:{failureMessage:function(e){var t="Fix any of the following:",n=e;if(n)for(var r=-1,a=n.length-1;r<a;)t+="\n "+n[r+=1].split("\n").join("\n ");return t}},none:{failureMessage:function(e){var t="Fix all of the following:",n=e;if(n)for(var r=-1,a=n.length-1;r<a;)t+="\n "+n[r+=1].split("\n").join("\n ");return t}}},incompleteFallbackMessage:function(e){return"axe couldn't tell the reason. Time to break out the element inspector!"}},rules:[{id:"accesskeys",selector:"[accesskey]",excludeHidden:!1,tags:["best-practice","cat.keyboard"],all:[],any:[],none:["accesskeys"]},{id:"area-alt",selector:"map area[href]",excludeHidden:!1,tags:["cat.text-alternatives","wcag2a","wcag111","section508","section508.22.a"],all:[],any:["non-empty-alt","non-empty-title","aria-label","aria-labelledby"],none:[]},{id:"aria-allowed-attr",matches:function(e,t,n){var r=/^aria-/;if(e.hasAttributes())for(var a=axe.utils.getNodeAttributes(e),o=0,i=a.length;o<i;o++)if(r.test(a[o].name))return!0;return!1},tags:["cat.aria","wcag2a","wcag412"],all:[],any:["aria-allowed-attr"],none:["aria-unsupported-attr"]},{id:"aria-allowed-role",excludeHidden:!1,selector:"[role]",matches:function(e,t,n){return null!==axe.commons.aria.getRole(e,{noImplicit:!0,dpub:!0,fallback:!0})},tags:["cat.aria","best-practice"],all:[],any:[{options:{allowImplicit:!0,ignoredTags:[]},id:"aria-allowed-role"}],none:[]},{id:"aria-dpub-role-fallback",selector:"[role]",matches:function(e,t,n){var r=e.getAttribute("role");return["doc-backlink","doc-biblioentry","doc-biblioref","doc-cover","doc-endnote","doc-glossref","doc-noteref"].includes(r)},tags:["cat.aria","wcag2a","wcag131"],all:["implicit-role-fallback"],any:[],none:[]},{id:"aria-hidden-body",selector:"body",excludeHidden:!1,tags:["cat.aria","wcag2a","wcag412"],all:[],any:["aria-hidden-body"],none:[]},{id:"aria-hidden-focus",selector:'[aria-hidden="true"]',matches:function(e,t,n){var r=axe.commons.dom.getComposedParent;return function e(t){return!t||"true"!==t.getAttribute("aria-hidden")&&e(r(t))}(r(e))},excludeHidden:!1,tags:["cat.name-role-value","wcag2a","wcag412","wcag131"],all:["focusable-disabled","focusable-not-tabbable"],any:[],none:[]},{id:"aria-input-field-name",selector:'[role="combobox"], [role="listbox"], [role="searchbox"], [role="slider"], [role="spinbutton"], [role="textbox"]',matches:function(e,t,n){var r=axe.commons.aria,a=e.nodeName.toUpperCase(),o=r.getRole(e,{noImplicit:!0});return("AREA"!==a||!e.getAttribute("href"))&&(!["INPUT","SELECT","TEXTAREA"].includes(a)&&("IMG"!==a&&("img"!==o||"SVG"===a)&&("BUTTON"!==a&&"button"!==o&&("combobox"!==o||!axe.utils.querySelectorAll(t,'input:not([type="hidden"])').length))))},tags:["wcag2a","wcag412"],all:[],any:["aria-label","aria-labelledby","non-empty-title"],none:["no-implicit-explicit-label"]},{id:"aria-required-attr",selector:"[role]",tags:["cat.aria","wcag2a","wcag412"],all:[],any:["aria-required-attr"],none:[]},{id:"aria-required-children",selector:"[role]",tags:["cat.aria","wcag2a","wcag131"],all:[],any:[{options:{reviewEmpty:["doc-bibliography","doc-endnotes","grid","list","listbox","table","tablist","tree","treegrid","rowgroup"]},id:"aria-required-children"}],none:[]},{id:"aria-required-parent",selector:"[role]",tags:["cat.aria","wcag2a","wcag131"],all:[],any:["aria-required-parent"],none:[]},{id:"aria-roles",selector:"[role]",tags:["cat.aria","wcag2a","wcag412"],all:[],any:[],none:["invalidrole","abstractrole","unsupportedrole"]},{id:"aria-toggle-field-name",selector:'[role="checkbox"], [role="menuitemcheckbox"], [role="menuitemradio"], [role="radio"], [role="switch"]',matches:function(e,t,n){var r=axe.commons.aria,a=e.nodeName.toUpperCase(),o=r.getRole(e,{noImplicit:!0});return("AREA"!==a||!e.getAttribute("href"))&&(!["INPUT","SELECT","TEXTAREA"].includes(a)&&("IMG"!==a&&("img"!==o||"SVG"===a)&&("BUTTON"!==a&&"button"!==o&&("combobox"!==o||!axe.utils.querySelectorAll(t,'input:not([type="hidden"])').length))))},tags:["wcag2a","wcag412"],all:[],any:["aria-label","aria-labelledby","non-empty-title","has-visible-text"],none:["no-implicit-explicit-label"]},{id:"aria-valid-attr-value",matches:function(e,t,n){var r=/^aria-/;if(e.hasAttributes())for(var a=axe.utils.getNodeAttributes(e),o=0,i=a.length;o<i;o++)if(r.test(a[o].name))return!0;return!1},tags:["cat.aria","wcag2a","wcag412"],all:[{options:[],id:"aria-valid-attr-value"},"aria-errormessage"],any:[],none:[]},{id:"aria-valid-attr",matches:function(e,t,n){var r=/^aria-/;if(e.hasAttributes())for(var a=axe.utils.getNodeAttributes(e),o=0,i=a.length;o<i;o++)if(r.test(a[o].name))return!0;return!1},tags:["cat.aria","wcag2a","wcag412"],all:[],any:[{options:[],id:"aria-valid-attr"}],none:[]},{id:"audio-caption",selector:"audio",enabled:!1,excludeHidden:!1,tags:["cat.time-and-media","wcag2a","wcag121","section508","section508.22.a"],all:[],any:[],none:["caption"]},{id:"autocomplete-valid",matches:function(e,t,n){var r=axe.commons,a=r.text,o=r.aria,i=r.dom,u=t.attr("autocomplete");if(!u||""===a.sanitize(u))return!1;var s=t.props.nodeName;if(!1===["textarea","input","select"].includes(s))return!1;if("input"===s&&["submit","reset","button","hidden"].includes(t.props.type))return!1;var l=t.attr("aria-disabled")||"false";if(t.hasAttr("disabled")||"true"===l.toLowerCase())return!1;var c=t.attr("role"),d=t.attr("tabindex");if("-1"===d&&c){var m=o.lookupTable.role[c];if(void 0===m||"widget"!==m.type)return!1}return!("-1"===d&&t.actualNode&&!i.isVisible(t.actualNode,!1)&&!i.isVisible(t.actualNode,!0))},tags:["cat.forms","wcag21aa","wcag135"],all:["autocomplete-valid","autocomplete-appropriate"],any:[],none:[]},{id:"avoid-inline-spacing",selector:"[style]",tags:["wcag21aa","wcag1412"],all:["avoid-inline-spacing"],any:[],none:[]},{id:"blink",selector:"blink",excludeHidden:!1,tags:["cat.time-and-media","wcag2a","wcag222","section508","section508.22.j"],all:[],any:[],none:["is-on-screen"]},{id:"button-name",selector:'button, [role="button"]',tags:["cat.name-role-value","wcag2a","wcag412","section508","section508.22.a"],all:[],any:["button-has-visible-text","aria-label","aria-labelledby","role-presentation","role-none","non-empty-title"],none:[]},{id:"bypass",selector:"html",pageLevel:!0,matches:function(e,t,n){return!!e.querySelector("a[href]")},tags:["cat.keyboard","wcag2a","wcag241","section508","section508.22.o"],all:[],any:["internal-link-present","header-present","landmark"],none:[]},{id:"checkboxgroup",selector:"input[type=checkbox][name]",tags:["cat.forms","best-practice"],all:[],any:["group-labelledby","fieldset"],none:[]},{id:"color-contrast",matches:function(e,t,n){var r=e.nodeName.toUpperCase(),a=e.type;if("true"===e.getAttribute("aria-disabled")||axe.commons.dom.findUpVirtual(t,'[aria-disabled="true"]'))return!1;if("INPUT"===r)return-1===["hidden","range","color","checkbox","radio","image"].indexOf(a)&&!e.disabled;if("SELECT"===r)return!!e.options.length&&!e.disabled;if("TEXTAREA"===r)return!e.disabled;if("OPTION"===r)return!1;if("BUTTON"===r&&e.disabled||axe.commons.dom.findUpVirtual(t,"button[disabled]"))return!1;if("FIELDSET"===r&&e.disabled||axe.commons.dom.findUpVirtual(t,"fieldset[disabled]"))return!1;var o=axe.commons.dom.findUpVirtual(t,"label");if("LABEL"===r||o){var i=e,u=t;o&&(i=o,u=axe.utils.getNodeFromTree(o));var s=axe.commons.dom.getRootNode(i);if((l=i.htmlFor&&s.getElementById(i.htmlFor))&&l.disabled)return!1;if((l=axe.utils.querySelectorAll(u,'input:not([type="hidden"]):not([type="image"]):not([type="button"]):not([type="submit"]):not([type="reset"]), select, textarea')).length&&l[0].actualNode.disabled)return!1}if(e.getAttribute("id")){var l,c=axe.utils.escapeSelector(e.getAttribute("id"));if((l=axe.commons.dom.getRootNode(e).querySelector("[aria-labelledby~="+c+"]"))&&l.disabled)return!1}if(""===axe.commons.text.visibleVirtual(t,!1,!0))return!1;var d,m,p=document.createRange(),f=t.children,h=f.length;for(m=0;m<h;m++)3===(d=f[m]).actualNode.nodeType&&""!==axe.commons.text.sanitize(d.actualNode.nodeValue)&&p.selectNodeContents(d.actualNode);var b=p.getClientRects();for(h=b.length,m=0;m<h;m++)if(axe.commons.dom.visuallyOverlaps(b[m],e))return!0;return!1},excludeHidden:!1,options:{noScroll:!1},tags:["cat.color","wcag2aa","wcag143"],all:[],any:["color-contrast"],none:[]},{id:"css-orientation-lock",selector:"html",tags:["cat.structure","wcag134","wcag21aa","experimental"],all:["css-orientation-lock"],any:[],none:[],preload:!0},{id:"definition-list",selector:"dl",matches:function(e,t,n){return!e.getAttribute("role")},tags:["cat.structure","wcag2a","wcag131"],all:[],any:[],none:["structured-dlitems","only-dlitems"]},{id:"dlitem",selector:"dd, dt",matches:function(e,t,n){return!e.getAttribute("role")},tags:["cat.structure","wcag2a","wcag131"],all:[],any:["dlitem"],none:[]},{id:"document-title",selector:"html",matches:function(e,t,n){return e.ownerDocument.defaultView.self===e.ownerDocument.defaultView.top},tags:["cat.text-alternatives","wcag2a","wcag242"],all:[],any:["doc-has-title"],none:[]},{id:"duplicate-id-active",selector:"[id]",matches:function(e,t,n){var r=axe.commons,a=r.dom,o=r.aria,i=e.getAttribute("id").trim(),u='*[id="'.concat(axe.utils.escapeSelector(i),'"]');return Array.from(a.getRootNode(e).querySelectorAll(u)).some(a.isFocusable)&&!o.isAccessibleRef(e)},excludeHidden:!1,tags:["cat.parsing","wcag2a","wcag411"],all:[],any:["duplicate-id-active"],none:[]},{id:"duplicate-id-aria",selector:"[id]",matches:function(e,t,n){return axe.commons.aria.isAccessibleRef(e)},excludeHidden:!1,tags:["cat.parsing","wcag2a","wcag411"],all:[],any:["duplicate-id-aria"],none:[]},{id:"duplicate-id",selector:"[id]",matches:function(e,t,n){var r=axe.commons,a=r.dom,o=r.aria,i=e.getAttribute("id").trim(),u='*[id="'.concat(axe.utils.escapeSelector(i),'"]');return Array.from(a.getRootNode(e).querySelectorAll(u)).every(function(e){return!a.isFocusable(e)})&&!o.isAccessibleRef(e)},excludeHidden:!1,tags:["cat.parsing","wcag2a","wcag411"],all:[],any:["duplicate-id"],none:[]},{id:"empty-heading",selector:'h1, h2, h3, h4, h5, h6, [role="heading"]',matches:function(e,t,n){var r;return e.hasAttribute("role")&&(r=e.getAttribute("role").split(/\s+/i).filter(axe.commons.aria.isValidRole)),r&&0<r.length?r.includes("heading"):"heading"===axe.commons.aria.implicitRole(e)},tags:["cat.name-role-value","best-practice"],all:[],any:["has-visible-text"],none:[]},{id:"focus-order-semantics",selector:"div, h1, h2, h3, h4, h5, h6, [role=heading], p, span",matches:function(e,t,n){return axe.commons.dom.insertedIntoFocusOrder(e)},tags:["cat.keyboard","best-practice","experimental"],all:[],any:[{options:[],id:"has-widget-role"},{options:[],id:"valid-scrollable-semantics"}],none:[]},{id:"form-field-multiple-labels",selector:"input, select, textarea",matches:function(e,t,n){if("input"!==e.nodeName.toLowerCase()||!1===e.hasAttribute("type"))return!0;var r=e.getAttribute("type").toLowerCase();return!1===["hidden","image","button","submit","reset"].includes(r)},tags:["cat.forms","wcag2a","wcag332"],all:[],any:[],none:["multiple-label"]},{id:"frame-tested",selector:"frame, iframe",tags:["cat.structure","review-item","best-practice"],all:[{options:{isViolation:!1},id:"frame-tested"}],any:[],none:[]},{id:"frame-title-unique",selector:"frame[title], iframe[title]",matches:function(e,t,n){var r=e.getAttribute("title");return!(!r||!axe.commons.text.sanitize(r).trim())},tags:["cat.text-alternatives","best-practice"],all:[],any:[],none:["unique-frame-title"]},{id:"frame-title",selector:"frame, iframe",tags:["cat.text-alternatives","wcag2a","wcag241","wcag412","section508","section508.22.i"],all:[],any:["aria-label","aria-labelledby","non-empty-title","role-presentation","role-none"],none:[]},{id:"heading-order",selector:"h1, h2, h3, h4, h5, h6, [role=heading]",matches:function(e,t,n){var r;return e.hasAttribute("role")&&(r=e.getAttribute("role").split(/\s+/i).filter(axe.commons.aria.isValidRole)),r&&0<r.length?r.includes("heading"):"heading"===axe.commons.aria.implicitRole(e)},tags:["cat.semantics","best-practice"],all:[],any:["heading-order"],none:[]},{id:"hidden-content",selector:"*",excludeHidden:!1,tags:["cat.structure","experimental","review-item","best-practice"],all:[],any:["hidden-content"],none:[]},{id:"html-has-lang",selector:"html",matches:function(e,t,n){return e.ownerDocument.defaultView.self===e.ownerDocument.defaultView.top},tags:["cat.language","wcag2a","wcag311"],all:[],any:["has-lang"],none:[]},{id:"html-lang-valid",selector:"html[lang], html[xml\\:lang]",tags:["cat.language","wcag2a","wcag311"],all:[],any:[],none:["valid-lang"]},{id:"html-xml-lang-mismatch",selector:"html[lang][xml\\:lang]",matches:function(e,t,n){var r=axe.utils.getBaseLang,a=r(e.getAttribute("lang")),o=r(e.getAttribute("xml:lang"));return axe.utils.validLangs().includes(a)&&axe.utils.validLangs().includes(o)},tags:["cat.language","wcag2a","wcag311"],all:["xml-lang-mismatch"],any:[],none:[]},{id:"image-alt",selector:"img",tags:["cat.text-alternatives","wcag2a","wcag111","section508","section508.22.a"],all:[],any:["has-alt","aria-label","aria-labelledby","non-empty-title","role-presentation","role-none"],none:["alt-space-value"]},{id:"image-redundant-alt",selector:"img",tags:["cat.text-alternatives","best-practice"],all:[],any:[],none:["duplicate-img-label"]},{id:"input-button-name",selector:'input[type="button"], input[type="submit"], input[type="reset"]',tags:["cat.name-role-value","wcag2a","wcag412","section508","section508.22.a"],all:[],any:["non-empty-if-present","non-empty-value","aria-label","aria-labelledby","role-presentation","role-none","non-empty-title"],none:[]},{id:"input-image-alt",selector:'input[type="image"]',tags:["cat.text-alternatives","wcag2a","wcag111","section508","section508.22.a"],all:[],any:["non-empty-alt","aria-label","aria-labelledby","non-empty-title"],none:[]},{id:"label-content-name-mismatch",matches:function(e,t,n){var r=axe.commons,a=r.aria,o=r.text,i=a.getRole(e);return!!i&&(!!a.lookupTable.rolesOfType.widget.includes(i)&&(!!a.getRolesWithNameFromContents().includes(i)&&(!(!o.sanitize(a.arialabelText(e))&&!o.sanitize(a.arialabelledbyText(e)))&&!!o.sanitize(o.visibleVirtual(t)))))},tags:["wcag21a","wcag253","experimental"],all:[],any:["label-content-name-mismatch"],none:[]},{id:"label-title-only",selector:"input, select, textarea",matches:function(e,t,n){if("input"!==e.nodeName.toLowerCase()||!1===e.hasAttribute("type"))return!0;var r=e.getAttribute("type").toLowerCase();return!1===["hidden","image","button","submit","reset"].includes(r)},tags:["cat.forms","best-practice"],all:[],any:[],none:["title-only"]},{id:"label",selector:"input, select, textarea",matches:function(e,t,n){if("input"!==e.nodeName.toLowerCase()||!1===e.hasAttribute("type"))return!0;var r=e.getAttribute("type").toLowerCase();return!1===["hidden","image","button","submit","reset"].includes(r)},tags:["cat.forms","wcag2a","wcag332","wcag131","section508","section508.22.n"],all:[],any:["aria-label","aria-labelledby","implicit-label","explicit-label","non-empty-title"],none:["help-same-as-label","hidden-explicit-label"]},{id:"landmark-banner-is-top-level",selector:"header:not([role]), [role=banner]",matches:function(e,t,n){return e.hasAttribute("role")||!axe.commons.dom.findUpVirtual(t,"article, aside, main, nav, section")},tags:["cat.semantics","best-practice"],all:[],any:["landmark-is-top-level"],none:[]},{id:"landmark-complementary-is-top-level",selector:"aside:not([role]), [role=complementary]",tags:["cat.semantics","best-practice"],all:[],any:["landmark-is-top-level"],none:[]},{id:"landmark-contentinfo-is-top-level",selector:"footer:not([role]), [role=contentinfo]",matches:function(e,t,n){return e.hasAttribute("role")||!axe.commons.dom.findUpVirtual(t,"article, aside, main, nav, section")},tags:["cat.semantics","best-practice"],all:[],any:["landmark-is-top-level"],none:[]},{id:"landmark-main-is-top-level",selector:"main:not([role]), [role=main]",tags:["cat.semantics","best-practice"],all:[],any:["landmark-is-top-level"],none:[]},{id:"landmark-no-duplicate-banner",selector:"html",tags:["cat.semantics","best-practice"],all:[],any:[{options:{selector:"header:not([role]), [role=banner]",nativeScopeFilter:"article, aside, main, nav, section"},id:"page-no-duplicate-banner"}],none:[]},{id:"landmark-no-duplicate-contentinfo",selector:"html",tags:["cat.semantics","best-practice"],all:[],any:[{options:{selector:"footer:not([role]), [role=contentinfo]",nativeScopeFilter:"article, aside, main, nav, section"},id:"page-no-duplicate-contentinfo"}],none:[]},{id:"landmark-one-main",selector:"html",tags:["cat.semantics","best-practice"],all:[{options:{selector:"main:not([role]), [role='main']"},id:"page-has-main"},{options:{selector:"main:not([role]), [role='main']"},id:"page-no-duplicate-main"}],any:[],none:[]},{id:"landmark-unique",selector:"[role=banner], [role=complementary], [role=contentinfo], [role=main], [role=navigation], [role=region], [role=search], [role=form], form, footer, header, aside, main, nav, section",tags:["cat.semantics","best-practice"],matches:function(e,t,n){var o=["article","aside","main","nav","section"].join(",");return function(e){var t=e.actualNode,n=axe.commons.aria.getRolesByType("landmark"),r=axe.commons.aria.getRole(t);if(!r)return!1;var a=t.nodeName.toUpperCase();return"HEADER"===a||"FOOTER"===a?function(e){return!axe.commons.dom.findUpVirtual(e,o)}(e):"SECTION"!==a&&"FORM"!==a?0<=n.indexOf(r)||"region"===r:!!axe.commons.text.accessibleTextVirtual(e)}(t)&&axe.commons.dom.isVisible(e,!0)},all:[],any:["landmark-is-unique"],none:[]},{id:"layout-table",selector:"table",matches:function(e,t,n){var r=(e.getAttribute("role")||"").toLowerCase();return!(("presentation"===r||"none"===r)&&!axe.commons.dom.isFocusable(e)||axe.commons.table.isDataTable(e))},tags:["cat.semantics","wcag2a","wcag131"],all:[],any:[],none:["has-th","has-caption","has-summary"]},{id:"link-in-text-block",selector:"a[href], [role=link]",matches:function(e,t,n){var r=axe.commons.text.sanitize(e.textContent),a=e.getAttribute("role");return(!a||"link"===a)&&(!!r&&(!!axe.commons.dom.isVisible(e,!1)&&axe.commons.dom.isInTextBlock(e)))},excludeHidden:!1,tags:["cat.color","experimental","wcag2a","wcag141"],all:["link-in-text-block"],any:[],none:[]},{id:"link-name",selector:"a[href], [role=link][href]",matches:function(e,t,n){return"button"!==e.getAttribute("role")},tags:["cat.name-role-value","wcag2a","wcag412","wcag244","section508","section508.22.a"],all:[],any:["has-visible-text","aria-label","aria-labelledby","role-presentation","role-none"],none:["focusable-no-name"]},{id:"list",selector:"ul, ol",matches:function(e,t,n){return!e.getAttribute("role")},tags:["cat.structure","wcag2a","wcag131"],all:[],any:[],none:["only-listitems"]},{id:"listitem",selector:"li",matches:function(e,t,n){return!e.getAttribute("role")},tags:["cat.structure","wcag2a","wcag131"],all:[],any:["listitem"],none:[]},{id:"marquee",selector:"marquee",excludeHidden:!1,tags:["cat.parsing","wcag2a","wcag222"],all:[],any:[],none:["is-on-screen"]},{id:"meta-refresh",selector:'meta[http-equiv="refresh"]',excludeHidden:!1,tags:["cat.time","wcag2a","wcag2aaa","wcag221","wcag224","wcag325"],all:[],any:["meta-refresh"],none:[]},{id:"meta-viewport-large",selector:'meta[name="viewport"]',excludeHidden:!1,tags:["cat.sensory-and-visual-cues","best-practice"],all:[],any:[{options:{scaleMinimum:5,lowerBound:2},id:"meta-viewport-large"}],none:[]},{id:"meta-viewport",selector:'meta[name="viewport"]',excludeHidden:!1,tags:["cat.sensory-and-visual-cues","wcag2aa","wcag144"],all:[],any:[{options:{scaleMinimum:2},id:"meta-viewport"}],none:[]},{id:"object-alt",selector:"object",tags:["cat.text-alternatives","wcag2a","wcag111","section508","section508.22.a"],all:[],any:["has-visible-text","aria-label","aria-labelledby","non-empty-title","role-presentation","role-none"],none:[]},{id:"p-as-heading",selector:"p",matches:function(e,t,n){var r=Array.from(e.parentNode.childNodes),a=e.textContent.trim();return!(0===a.length||2<=(a.match(/[.!?:;](?![.!?:;])/g)||[]).length)&&0!==r.slice(r.indexOf(e)+1).filter(function(e){return"P"===e.nodeName.toUpperCase()&&""!==e.textContent.trim()}).length},tags:["cat.semantics","wcag2a","wcag131","experimental"],all:[{options:{margins:[{weight:150,italic:!0},{weight:150,size:1.15},{italic:!0,size:1.15},{size:1.4}]},id:"p-as-heading"}],any:[],none:[]},{id:"page-has-heading-one",selector:"html",tags:["cat.semantics","best-practice"],all:[{options:{selector:'h1:not([role]), [role="heading"][aria-level="1"]'},id:"page-has-heading-one"}],any:[],none:[]},{id:"radiogroup",selector:"input[type=radio][name]",tags:["cat.forms","best-practice"],all:[],any:["group-labelledby","fieldset"],none:[]},{id:"region",selector:"html",pageLevel:!0,tags:["cat.keyboard","best-practice"],all:[],any:["region"],none:[]},{id:"role-img-alt",selector:"[role='img']:not(svg):not(img):not(area):not(input):not(object)",tags:["cat.text-alternatives","wcag2a","wcag111","section508","section508.22.a"],all:[],any:["aria-label","aria-labelledby","non-empty-title"],none:[]},{id:"scope-attr-valid",selector:"td[scope], th[scope]",tags:["cat.tables","best-practice"],all:["html5-scope","scope-value"],any:[],none:[]},{id:"scrollable-region-focusable",matches:function(e,t,n){var r=axe.utils.querySelectorAll,a=axe.commons.dom.hasContentVirtual;return!1!=!!axe.utils.getScroll(e,13)&&!!r(t,"*").some(function(e){return a(e,!0,!0)})},tags:["wcag2a","wcag211"],all:[],any:["focusable-content","focusable-element"],none:[]},{id:"server-side-image-map",selector:"img[ismap]",tags:["cat.text-alternatives","wcag2a","wcag211","section508","section508.22.f"],all:[],any:[],none:["exists"]},{id:"skip-link",selector:'a[href^="#"], a[href^="/#"]',matches:function(e,t,n){return axe.commons.dom.isSkipLink(e)},tags:["cat.keyboard","best-practice"],all:[],any:["skip-link"],none:[]},{id:"tabindex",selector:"[tabindex]",tags:["cat.keyboard","best-practice"],all:[],any:["tabindex"],none:[]},{id:"table-duplicate-name",selector:"table",tags:["cat.tables","best-practice"],all:[],any:[],none:["same-caption-summary"]},{id:"table-fake-caption",selector:"table",matches:function(e,t,n){return axe.commons.table.isDataTable(e)},tags:["cat.tables","experimental","wcag2a","wcag131","section508","section508.22.g"],all:["caption-faked"],any:[],none:[]},{id:"td-has-header",selector:"table",matches:function(e,t,n){if(axe.commons.table.isDataTable(e)){var r=axe.commons.table.toArray(e);return 3<=r.length&&3<=r[0].length&&3<=r[1].length&&3<=r[2].length}return!1},tags:["cat.tables","experimental","wcag2a","wcag131","section508","section508.22.g"],all:["td-has-header"],any:[],none:[]},{id:"td-headers-attr",selector:"table",tags:["cat.tables","wcag2a","wcag131","section508","section508.22.g"],all:["td-headers-attr"],any:[],none:[]},{id:"th-has-data-cells",selector:"table",matches:function(e,t,n){return axe.commons.table.isDataTable(e)},tags:["cat.tables","wcag2a","wcag131","section508","section508.22.g"],all:["th-has-data-cells"],any:[],none:[]},{id:"valid-lang",selector:"[lang], [xml\\:lang]",matches:function(e,t,n){return"html"!==e.nodeName.toLowerCase()},tags:["cat.language","wcag2aa","wcag312"],all:[],any:[],none:["valid-lang"]},{id:"video-caption",selector:"video",excludeHidden:!1,tags:["cat.text-alternatives","wcag2a","wcag122","section508","section508.22.a"],all:[],any:[],none:["caption"]},{id:"video-description",selector:"video",excludeHidden:!1,tags:["cat.text-alternatives","wcag2aa","wcag125","section508","section508.22.b"],all:[],any:[],none:["description"]}],checks:[{id:"abstractrole",evaluate:function(e,t,n,r){return"abstract"===axe.commons.aria.getRoleType(e.getAttribute("role"))}},{id:"aria-allowed-attr",evaluate:function(e,t,n,r){t=t||{};var a,o,i,u=[],s=e.getAttribute("role"),l=axe.utils.getNodeAttributes(e);if(s=s||axe.commons.aria.implicitRole(e),i=axe.commons.aria.allowedAttr(s),Array.isArray(t[s])&&(i=axe.utils.uniqueArray(t[s].concat(i))),s&&i)for(var c=0,d=l.length;c<d;c++)o=(a=l[c]).name,axe.commons.aria.validateAttr(o)&&!i.includes(o)&&u.push(o+'="'+a.nodeValue+'"');return!u.length||(this.data(u),!1)}},{id:"aria-allowed-role",evaluate:function(e,t,n,r){var a=axe.commons.dom,o=t||{},i=o.allowImplicit,u=void 0===i||i,s=o.ignoredTags,l=void 0===s?[]:s,c=e.nodeName.toUpperCase();if(l.map(function(e){return e.toUpperCase()}).includes(c))return!0;var d=axe.commons.aria.getElementUnallowedRoles(e,u);if(d.length){if(this.data(d),!a.isVisible(e,!0))return;return!1}return!0},options:{allowImplicit:!0,ignoredTags:[]}},{id:"aria-hidden-body",evaluate:function(e,t,n,r){return"true"!==e.getAttribute("aria-hidden")}},{id:"aria-errormessage",evaluate:function(n,e,t,r){var a=axe.commons,o=a.aria,i=a.dom;e=Array.isArray(e)?e:[];var u=n.getAttribute("aria-errormessage"),s=n.hasAttribute("aria-errormessage"),l=i.getRootNode(n);return!(-1===e.indexOf(u)&&s&&!function(e){if(""===e.trim())return o.lookupTable.attributes["aria-errormessage"].allowEmpty;var t=e&&l.getElementById(e);return t?"alert"===t.getAttribute("role")||"assertive"===t.getAttribute("aria-live")||-1<axe.utils.tokenList(n.getAttribute("aria-describedby")||"").indexOf(e):void 0}(u))||(this.data(axe.utils.tokenList(u)),!1)}},{id:"has-widget-role",evaluate:function(e,t,n,r){var a=e.getAttribute("role");if(null===a)return!1;var o=axe.commons.aria.getRoleType(a);return"widget"===o||"composite"===o},options:[]},{id:"implicit-role-fallback",evaluate:function(e,t,n,r){var a=e.getAttribute("role");if(null===a||!axe.commons.aria.isValidRole(a))return!0;var o=axe.commons.aria.getRoleType(a);return axe.commons.aria.implicitRole(e)===o}},{id:"invalidrole",evaluate:function(e,t,n,r){return!axe.commons.aria.isValidRole(e.getAttribute("role"),{allowAbstract:!0})}},{id:"no-implicit-explicit-label",evaluate:function(e,t,n,r){var a=axe.commons,o=a.aria,i=a.text,u=o.getRole(e,{noImplicit:!0});this.data(u);var s=i.sanitize(i.labelText(n)).toLowerCase(),l=i.sanitize(i.accessibleText(e)).toLowerCase();return!(!l&&!s)&&(!((l||!s)&&l.includes(s))&&void 0)}},{id:"aria-required-attr",evaluate:function(e,t,n,r){t=t||{};var a=[],o=axe.commons.forms,i=o.isNativeTextbox,u=o.isNativeSelect,s=o.isAriaTextbox,l=o.isAriaListbox,c=o.isAriaCombobox,d=o.isAriaRange,m={"aria-valuenow":function(){return!(i(e)||u(e)||s(e)||l(e)||c(e)||d(e)&&e.hasAttribute("aria-valuenow"))}};if(e.hasAttributes()){var p=e.getAttribute("role"),f=axe.commons.aria.requiredAttr(p);if(Array.isArray(t[p])&&(f=axe.utils.uniqueArray(t[p],f)),p&&f)for(var h=0,b=f.length;h<b;h++){var g=f[h];e.getAttribute(g)||m[g]&&!m[g]()||a.push(g)}}return!a.length||(this.data(a),!1)}},{id:"aria-required-children",evaluate:function(e,t,m,n){var r=axe.commons.aria.requiredOwned,i=axe.commons.aria.implicitNodes,u=axe.utils.matchesSelector,p=axe.commons.dom.idrefs,a=t&&Array.isArray(t.reviewEmpty)?t.reviewEmpty:[];function f(e,t,n,r){if(null===e)return!1;var a=i(n),o=['[role="'+n+'"]'];return a&&(o=o.concat(a)),o=o.join(","),r&&u(e,o)||!!axe.utils.querySelectorAll(t,o)[0]}function h(e,t){var n,r;for(n=0,r=e.length;n<r;n++)if(null!==e[n]){var a=axe.utils.getNodeFromTree(e[n]);if(f(e[n],a,t,!0))return!0}return!1}var o=e.getAttribute("role"),s=r(o);if(!s)return!0;var l=!1,c=s.one;if(!c){l=!0;c=s.all}var d=function(e,t,n,r){var a,o=t.length,i=[],u=p(e,"aria-owns");for(a=0;a<o;a++){var s=t[a];if(f(e,m,s)||h(u,s)){if(!n)return null}else n&&i.push(s)}if("combobox"===r){var l=i.indexOf("textbox");0<=l&&"INPUT"===e.nodeName.toUpperCase()&&["text","search","email","url","tel"].includes(e.type)&&i.splice(l,1);var c=i.indexOf("listbox"),d=e.getAttribute("aria-expanded");0<=c&&(!d||"false"===d)&&i.splice(c,1)}return i.length?i:!n&&t.length?t:null}(e,c,l,o);return!d||(this.data(d),!(!a.includes(o)||0!==e.children.length||0!==p(e,"aria-owns").length)&&void 0)},options:{reviewEmpty:["doc-bibliography","doc-endnotes","grid","list","listbox","table","tablist","tree","treegrid","rowgroup"]}},{id:"aria-required-parent",evaluate:function(e,t,n,r){function u(e){return(axe.commons.aria.implicitNodes(e)||[]).concat('[role="'+e+'"]').join(",")}function a(e,t,n){var r,a,o=e.actualNode.getAttribute("role"),i=[];if(!(t=t||axe.commons.aria.requiredContext(o)))return null;for(r=0,a=t.length;r<a;r++){if(n&&axe.utils.matchesSelector(e.actualNode,u(t[r])))return null;if(axe.commons.dom.findUpVirtual(e,u(t[r])))return null;i.push(t[r])}return i}var o=a(n);if(!o)return!0;var i=function(e){for(var t=[],n=null;e;){if(e.getAttribute("id")){var r=axe.utils.escapeSelector(e.getAttribute("id"));(n=axe.commons.dom.getRootNode(e).querySelector("[aria-owns~=".concat(r,"]")))&&t.push(n)}e=e.parentElement}return t.length?t:null}(e);if(i)for(var s=0,l=i.length;s<l;s++)if(!(o=a(axe.utils.getNodeFromTree(i[s]),o,!0)))return!0;return this.data(o),!1}},{id:"aria-unsupported-attr",evaluate:function(o,e,t,n){var i=o.nodeName.toUpperCase(),u=axe.commons.aria.lookupTable,s=axe.commons.aria.getRole(o),r=Array.from(axe.utils.getNodeAttributes(o)).filter(function(e){var t=e.name,n=u.attributes[t];if(!axe.commons.aria.validateAttr(t))return!1;var r=n.unsupported;if("object"!==S(r))return!!r;var a=axe.commons.matches(o,r.exceptions);return Object.keys(u.evaluateRoleForElement).includes(i)?!u.evaluateRoleForElement[i]({node:o,role:s,out:a}):!a}).map(function(e){return e.name.toString()});return!!r.length&&(this.data(r),!0)}},{id:"unsupportedrole",evaluate:function(e,t,n,r){return axe.commons.aria.isUnsupportedRole(axe.commons.aria.getRole(e))}},{id:"aria-valid-attr-value",evaluate:function(e,t,n,r){t=Array.isArray(t)?t:[];for(var a=[],o=[],i=/^aria-/,u=axe.utils.getNodeAttributes(e),s=["aria-errormessage"],l={"aria-controls":function(){return"false"!==e.getAttribute("aria-expanded")&&"false"!==e.getAttribute("aria-selected")},"aria-owns":function(){return"false"!==e.getAttribute("aria-expanded")},"aria-describedby":function(){axe.commons.aria.validateAttrValue(e,"aria-describedby")||a.push('aria-describedby="'.concat(e.getAttribute("aria-describedby"),'"'))}},c=0,d=u.length;c<d;c++){var m=u[c],p=m.name;s.includes(p)||-1!==t.indexOf(p)||!i.test(p)||l[p]&&!l[p]()||axe.commons.aria.validateAttrValue(e,p)||o.push("".concat(p,'="').concat(m.nodeValue,'"'))}if(!a.length)return!o.length||(this.data(o),!1);this.data(a)},options:[]},{id:"aria-valid-attr",evaluate:function(e,t,n,r){t=Array.isArray(t)?t:[];for(var a,o=[],i=/^aria-/,u=axe.utils.getNodeAttributes(e),s=0,l=u.length;s<l;s++)a=u[s].name,-1===t.indexOf(a)&&i.test(a)&&!axe.commons.aria.validateAttr(a)&&o.push(a);return!o.length||(this.data(o),!1)},options:[]},{id:"valid-scrollable-semantics",evaluate:function(e,t,n,r){var a,o,i,u={ARTICLE:!0,ASIDE:!0,NAV:!0,SECTION:!0},s={application:!0,banner:!1,complementary:!0,contentinfo:!0,form:!0,main:!0,navigation:!0,region:!0,search:!1};return(o=(i=e).getAttribute("role"))&&s[o.toLowerCase()]||!1||(a=i.nodeName.toUpperCase(),u[a]||!1)},options:[]},{id:"color-contrast",evaluate:function(e,t,n,r){var a=axe.commons,o=a.dom,i=a.color,u=a.text;if(!o.isVisible(e,!1))return!0;var s,l=!!(t||{}).noScroll,c=[],d=i.getBackgroundColor(e,c,l),m=i.getForegroundColor(e,l),p=window.getComputedStyle(e),f=parseFloat(p.getPropertyValue("font-size")),h=p.getPropertyValue("font-weight"),b=-1!==["bold","bolder","600","700","800","900"].indexOf(h),g=i.hasValidContrastRatio(d,m,f,b),y=Math.floor(100*g.contrastRatio)/100;null===d&&(s=i.incompleteData.get("bgColor"));var v=1==y,D=1===u.visibleVirtual(n,!1,!0).length;v?s=i.incompleteData.set("bgColor","equalRatio"):D&&(s="shortTextContent");var w={fgColor:m?m.toHexString():void 0,bgColor:d?d.toHexString():void 0,contrastRatio:g?y:void 0,fontSize:"".concat((72*f/96).toFixed(1),"pt (").concat(f,"px)"),fontWeight:b?"bold":"normal",missingData:s,expectedContrastRatio:g.expectedContrastRatio+":1"};return this.data(w),null===m||null===d||v||D&&!g.isValid?(s=null,i.incompleteData.clear(),void this.relatedNodes(c)):(g.isValid||this.relatedNodes(c),g.isValid)}},{id:"link-in-text-block",evaluate:function(e,t,n,r){var a=axe.commons,o=a.color,i=a.dom;function u(e,t){var n=e.getRelativeLuminance(),r=t.getRelativeLuminance();return(Math.max(n,r)+.05)/(Math.min(n,r)+.05)}var s=["block","list-item","table","flex","grid","inline-block"];function l(e){var t=window.getComputedStyle(e).getPropertyValue("display");return-1!==s.indexOf(t)||"table-"===t.substr(0,6)}if(l(e))return!1;for(var c,d,m=i.getComposedParent(e);1===m.nodeType&&!l(m);)m=i.getComposedParent(m);if(this.relatedNodes([m]),o.elementIsDistinct(e,m))return!0;if(c=o.getForegroundColor(e),d=o.getForegroundColor(m),c&&d){var p,f=u(c,d);return 1===f||(3<=f?(axe.commons.color.incompleteData.set("fgColor","bgContrast"),this.data({missingData:axe.commons.color.incompleteData.get("fgColor")}),void axe.commons.color.incompleteData.clear()):(c=o.getBackgroundColor(e),d=o.getBackgroundColor(m),(!c||!d||3<=u(c,d))&&(p=c&&d?"bgContrast":axe.commons.color.incompleteData.get("bgColor"),axe.commons.color.incompleteData.set("fgColor",p),this.data({missingData:axe.commons.color.incompleteData.get("fgColor")}),void axe.commons.color.incompleteData.clear())))}}},{id:"autocomplete-appropriate",evaluate:function(e,t,n,r){if("input"!==n.props.nodeName)return!0;var a=["text","search","number"],o=["text","search","url"],i={bday:["text","search","date"],email:["text","search","email"],"cc-exp":["text","search","month"],"street-address":["text"],tel:["text","search","tel"],"cc-exp-month":a,"cc-exp-year":a,"transaction-amount":a,"bday-day":a,"bday-month":a,"bday-year":a,"new-password":["text","search","password"],"current-password":["text","search","password"],url:o,photo:o,impp:o};"object"===S(t)&&Object.keys(t).forEach(function(e){i[e]||(i[e]=[]),i[e]=i[e].concat(t[e])});var u=n.attr("autocomplete").split(/\s+/g).map(function(e){return e.toLowerCase()}),s=u[u.length-1];if(axe.commons.text.autocomplete.stateTerms.includes(s))return!0;var l=i[s],c=n.hasAttr("type")?axe.commons.text.sanitize(n.attr("type")).toLowerCase():"text";return c=axe.utils.validInputTypes().includes(c)?c:"text",void 0===l?"text"===c:l.includes(c)}},{id:"autocomplete-valid",evaluate:function(e,t,n,r){var a=n.attr("autocomplete")||"";return axe.commons.text.isValidAutocomplete(a,t)}},{id:"fieldset",evaluate:function(e,t,n,r){var o,i=this;function u(e,t){return axe.utils.toArray(e.querySelectorAll('select,textarea,button,input:not([name="'+t+'"]):not([type="hidden"])'))}var a={name:e.getAttribute("name"),type:e.getAttribute("type")},s=function(e){var t=axe.utils.escapeSelector(e.actualNode.name),n=axe.commons.dom.getRootNode(e.actualNode).querySelectorAll('input[type="'+axe.utils.escapeSelector(e.actualNode.type)+'"][name="'+t+'"]');if(n.length<2)return!0;var r=axe.commons.dom.findUpVirtual(e,"fieldset"),a=axe.commons.dom.findUpVirtual(e,'[role="group"]'+("radio"===e.actualNode.type?',[role="radiogroup"]':""));return a||r?r?function(e,t){var n=e.firstElementChild;if(!n||"LEGEND"!==n.nodeName.toUpperCase())return i.relatedNodes([e]),!(o="no-legend");if(!axe.commons.text.accessibleText(n))return i.relatedNodes([n]),!(o="empty-legend");var r=u(e,t);return!r.length||(i.relatedNodes(r),!(o="mixed-inputs"))}(r,t):function(e,t){var n=axe.commons.dom.idrefs(e,"aria-labelledby").some(function(e){return e&&axe.commons.text.accessibleText(e)}),r=e.getAttribute("aria-label");if(!(n||r&&axe.commons.text.sanitize(r)))return i.relatedNodes(e),!(o="no-group-label");var a=u(e,t);return!a.length||(i.relatedNodes(a),!(o="group-mixed-inputs"))}(a,t):(o="no-group",i.relatedNodes(function(e,t){return axe.utils.toArray(e).filter(function(e){return e!==t})}(n,e.actualNode)),!1)}(n);return s||(a.failureCode=o),this.data(a),s},after:function(e,t){var r={};return e.filter(function(e){if(e.result)return!0;var t=e.data;if(t){if(r[t.type]=r[t.type]||{},!r[t.type][t.name])return r[t.type][t.name]=[t],!0;var n=r[t.type][t.name].some(function(e){return e.failureCode===t.failureCode});return n||r[t.type][t.name].push(t),!n}return!1})}},{id:"group-labelledby",evaluate:function(n,e,t,r){var a=axe.commons,o=a.dom,i=a.text,u=axe.utils.escapeSelector(n.type),s=axe.utils.escapeSelector(n.name),l=o.getRootNode(n),c={name:n.name,type:n.type},d=Array.from(l.querySelectorAll('input[type="'.concat(u,'"][name="').concat(s,'"]')));if(d.length<=1)return this.data(c),!0;var m=o.idrefs(n,"aria-labelledby").filter(function(e){return!!e}),p=m.slice();d.forEach(function(e){if(e!==n){var t=o.idrefs(e,"aria-labelledby").filter(function(e){return e});m=m.filter(function(e){return t.includes(e)}),p=p.filter(function(e){return!t.includes(e)})}});var f={inLabelledByContext:!0};return p=p.filter(function(e){return i.accessibleText(e,f)}),m=m.filter(function(e){return i.accessibleText(e,f)}),0<p.length&&0<m.length?(this.data(c),!0):(0<p.length&&0===m.length?c.failureCode="no-shared-label":0===p.length&&0<m.length&&(c.failureCode="no-unique-label"),this.data(c),!1)},after:function(e,t){var n={};return e.filter(function(e){var t=e.data;return!(!t||(n[t.type]=n[t.type]||{},n[t.type][t.name]))&&(n[t.type][t.name]=!0)})}},{id:"accesskeys",evaluate:function(e,t,n,r){return axe.commons.dom.isVisible(e,!1)&&(this.data(e.getAttribute("accesskey")),this.relatedNodes([e])),!0},after:function(e,t){var n={};return e.filter(function(e){if(!e.data)return!1;var t=e.data.toUpperCase();return n[t]?(n[t].relatedNodes.push(e.relatedNodes[0]),!1):((n[t]=e).relatedNodes=[],!0)}).map(function(e){return e.result=!!e.relatedNodes.length,e})}},{id:"focusable-content",evaluate:function(e,t,n,r){var a=n.tabbableElements;return!!a&&0<a.filter(function(e){return e!==n}).length}},{id:"focusable-disabled",evaluate:function(e,t,n,r){var a=["BUTTON","FIELDSET","INPUT","SELECT","TEXTAREA"],o=n.tabbableElements;if(!o||!o.length)return!0;var i=o.reduce(function(e,t){var n=t.actualNode,r=n.nodeName.toUpperCase();return a.includes(r)&&e.push(n),e},[]);return this.relatedNodes(i),0===i.length}},{id:"focusable-element",evaluate:function(e,t,n,r){var a=n.isFocusable,o=parseInt(n.actualNode.getAttribute("tabindex"),10);return(o=isNaN(o)?null:o)?a&&0<=o:a}},{id:"focusable-no-name",evaluate:function(e,t,n,r){var a=e.getAttribute("tabindex");return!!(axe.commons.dom.isFocusable(e)&&-1<a)&&!axe.commons.text.accessibleTextVirtual(n)}},{id:"focusable-not-tabbable",evaluate:function(e,t,n,r){var a=["BUTTON","FIELDSET","INPUT","SELECT","TEXTAREA"],o=n.tabbableElements;if(!o||!o.length)return!0;var i=o.reduce(function(e,t){var n=t.actualNode,r=n.nodeName.toUpperCase();return a.includes(r)||e.push(n),e},[]);return this.relatedNodes(i),0===i.length}},{id:"landmark-is-top-level",evaluate:function(e,t,n,r){var a=axe.commons.aria.getRolesByType("landmark"),o=axe.commons.dom.getComposedParent(e);for(this.data({role:e.getAttribute("role")||axe.commons.aria.implicitRole(e)});o;){var i=o.getAttribute("role");if(i||"FORM"===o.nodeName.toUpperCase()||(i=axe.commons.aria.implicitRole(o)),i&&a.includes(i))return!1;o=axe.commons.dom.getComposedParent(o)}return!0}},{id:"page-has-heading-one",evaluate:function(e,t,n,r){if(!t||!t.selector||"string"!=typeof t.selector)throw new TypeError("visible-in-page requires options.selector to be a string");var a=axe.utils.querySelectorAll(n,t.selector);return this.relatedNodes(a.map(function(e){return e.actualNode})),0<a.length},after:function(e,t){return e.some(function(e){return!0===e.result})&&e.forEach(function(e){e.result=!0}),e},options:{selector:'h1:not([role]), [role="heading"][aria-level="1"]'}},{id:"page-has-main",evaluate:function(e,t,n,r){if(!t||!t.selector||"string"!=typeof t.selector)throw new TypeError("visible-in-page requires options.selector to be a string");var a=axe.utils.querySelectorAll(n,t.selector);return this.relatedNodes(a.map(function(e){return e.actualNode})),0<a.length},after:function(e,t){return e.some(function(e){return!0===e.result})&&e.forEach(function(e){e.result=!0}),e},options:{selector:"main:not([role]), [role='main']"}},{id:"page-no-duplicate-banner",evaluate:function(e,t,n,r){if(!t||!t.selector||"string"!=typeof t.selector)throw new TypeError("visible-in-page requires options.selector to be a string");var a=axe.utils.querySelectorAll(n,t.selector);return"string"==typeof t.nativeScopeFilter&&(a=a.filter(function(e){return e.actualNode.hasAttribute("role")||!axe.commons.dom.findUpVirtual(e,t.nativeScopeFilter)})),this.relatedNodes(a.map(function(e){return e.actualNode})),a.length<=1},options:{selector:"header:not([role]), [role=banner]",nativeScopeFilter:"article, aside, main, nav, section"}},{id:"page-no-duplicate-contentinfo",evaluate:function(e,t,n,r){if(!t||!t.selector||"string"!=typeof t.selector)throw new TypeError("visible-in-page requires options.selector to be a string");var a=axe.utils.querySelectorAll(n,t.selector);return"string"==typeof t.nativeScopeFilter&&(a=a.filter(function(e){return e.actualNode.hasAttribute("role")||!axe.commons.dom.findUpVirtual(e,t.nativeScopeFilter)})),this.relatedNodes(a.map(function(e){return e.actualNode})),a.length<=1},options:{selector:"footer:not([role]), [role=contentinfo]",nativeScopeFilter:"article, aside, main, nav, section"}},{id:"page-no-duplicate-main",evaluate:function(e,t,n,r){if(!t||!t.selector||"string"!=typeof t.selector)throw new TypeError("visible-in-page requires options.selector to be a string");var a=axe.utils.querySelectorAll(n,t.selector);return"string"==typeof t.nativeScopeFilter&&(a=a.filter(function(e){return e.actualNode.hasAttribute("role")||!axe.commons.dom.findUpVirtual(e,t.nativeScopeFilter)})),this.relatedNodes(a.map(function(e){return e.actualNode})),a.length<=1},options:{selector:"main:not([role]), [role='main']"}},{id:"tabindex",evaluate:function(e,t,n,r){return e.tabIndex<=0}},{id:"alt-space-value",evaluate:function(e,t,n,r){var a=/^\s+$/.test(e.getAttribute("alt"));return e.hasAttribute("alt")&&a}},{id:"duplicate-img-label",evaluate:function(e,t,n,r){var a=axe.commons,o=a.aria,i=a.text,u=a.dom;if(["none","presentation"].includes(o.getRole(e)))return!1;var s=u.findUpVirtual(n,'button, [role="button"], a[href], p, li, td, th');if(!s)return!1;var l=axe.utils.getNodeFromTree(s),c=i.visibleVirtual(l,!0).toLowerCase();return""!==c&&c===i.accessibleTextVirtual(n).toLowerCase()}},{id:"explicit-label",evaluate:function(e,t,n,r){if(e.getAttribute("id")){var a=axe.commons.dom.getRootNode(e),o=axe.utils.escapeSelector(e.getAttribute("id")),i=a.querySelector('label[for="'.concat(o,'"]'));if(i)return!axe.commons.dom.isVisible(i)||!!axe.commons.text.accessibleText(i)}return!1}},{id:"help-same-as-label",evaluate:function(e,t,n,r){var a=axe.commons.text.labelVirtual(n),o=e.getAttribute("title");if(!a)return!1;o||(o="",e.getAttribute("aria-describedby")&&(o=axe.commons.dom.idrefs(e,"aria-describedby").map(function(e){return e?axe.commons.text.accessibleText(e):""}).join("")));return axe.commons.text.sanitize(o)===axe.commons.text.sanitize(a)},enabled:!1},{id:"hidden-explicit-label",evaluate:function(e,t,n,r){if(e.getAttribute("id")){var a=axe.commons.dom.getRootNode(e),o=axe.utils.escapeSelector(e.getAttribute("id")),i=a.querySelector('label[for="'.concat(o,'"]'));if(i&&!axe.commons.dom.isVisible(i,!0))return""===axe.commons.text.accessibleTextVirtual(n).trim()}return!1}},{id:"implicit-label",evaluate:function(e,t,n,r){var a=axe.commons,o=a.dom,i=a.text,u=o.findUpVirtual(n,"label");return!!u&&!!i.accessibleText(u,{inControlContext:!0})}},{id:"label-content-name-mismatch",evaluate:function(e,t,n,r){var a=axe.commons.text,o=a.accessibleText(e).toLowerCase();if(!(a.isHumanInterpretable(o)<1)){var i=a.sanitize(a.visibleVirtual(n)).toLowerCase();return a.isHumanInterpretable(i)<1?!!u(i,o)||void 0:u(i,o)}function u(e,t){var n=s(t),r=s(e);return!(!n||!r)&&n.includes(r)}function s(e){var t=a.removeUnicode(e,{emoji:!0,nonBmp:!0,punctuations:!0});return a.sanitize(t)}}},{id:"multiple-label",evaluate:function(e,t,n,r){var a=axe.utils.escapeSelector(e.getAttribute("id")),o=e.parentNode,i=axe.commons.dom.getRootNode(e);i=i.documentElement||i;var u=Array.from(i.querySelectorAll('label[for="'.concat(a,'"]')));for(u.length&&(u=u.filter(function(e){return axe.commons.dom.isVisible(e)}));o;)"LABEL"===o.nodeName.toUpperCase()&&-1===u.indexOf(o)&&u.push(o),o=o.parentNode;if(this.relatedNodes(u),1<u.length){var s=u.filter(function(e){return axe.commons.dom.isVisible(e,!0)});return 1<s.length||!axe.commons.dom.idrefs(e,"aria-labelledby").includes(s[0])}return!1}},{id:"title-only",evaluate:function(e,t,n,r){return!(axe.commons.text.labelVirtual(n)||!e.getAttribute("title")&&!e.getAttribute("aria-describedby"))}},{id:"landmark-is-unique",evaluate:function(e,t,n,r){var a=axe.commons.aria.getRole(e),o=axe.commons.text.accessibleTextVirtual(n);return o=o?o.toLowerCase():null,this.data({role:a,accessibleText:o}),this.relatedNodes([e]),!0},after:function(e,t){var n=[];return e.filter(function(t){var e=n.find(function(e){return t.data.role===e.data.role&&t.data.accessibleText===e.data.accessibleText});return e?(e.result=!1,e.relatedNodes.push(t.relatedNodes[0]),!1):(n.push(t),t.relatedNodes=[],!0)})}},{id:"has-lang",evaluate:function(e,t,n,r){return!!(e.getAttribute("lang")||e.getAttribute("xml:lang")||"").trim()}},{id:"valid-lang",evaluate:function(a,e,t,n){var o,r;return o=(e||axe.utils.validLangs()).map(axe.utils.getBaseLang),!!(r=["lang","xml:lang"].reduce(function(e,t){var n=a.getAttribute(t);if("string"!=typeof n)return e;var r=axe.utils.getBaseLang(n);return""!==r&&-1===o.indexOf(r)&&e.push(t+'="'+a.getAttribute(t)+'"'),e},[])).length&&(this.data(r),!0)}},{id:"xml-lang-mismatch",evaluate:function(e,t,n,r){var a=axe.utils.getBaseLang;return a(e.getAttribute("lang"))===a(e.getAttribute("xml:lang"))}},{id:"dlitem",evaluate:function(e,t,n,r){var a=axe.commons.dom.getComposedParent(e),o=a.nodeName.toUpperCase(),i=axe.commons.aria.getRole(a,{noImplicit:!0});return"DIV"===o&&["presentation","none",null].includes(i)&&(o=(a=axe.commons.dom.getComposedParent(a)).nodeName.toUpperCase(),i=axe.commons.aria.getRole(a,{noImplicit:!0})),"DL"===o&&(!i||"list"===i)}},{id:"listitem",evaluate:function(e,t,n,r){var a=axe.commons.dom.getComposedParent(e);if(a){var o=a.nodeName.toUpperCase(),i=(a.getAttribute("role")||"").toLowerCase();return"list"===i||(!i||!axe.commons.aria.isValidRole(i))&&["UL","OL"].includes(o)}}},{id:"only-dlitems",evaluate:function(e,t,n,r){var a=axe.commons,o=a.dom,i=a.aria,u=["definition","term","list"],s=n.children.reduce(function(e,t){var n=t.actualNode;return"DIV"===n.nodeName.toUpperCase()&&null===i.getRole(n)?e.concat(t.children):e.concat(t)},[]).reduce(function(e,t){var n=t.actualNode,r=n.nodeName.toUpperCase();if(1===n.nodeType&&o.isVisible(n,!0,!1)){var a=i.getRole(n,{noImplicit:!0});("DT"!==r&&"DD"!==r||a)&&(u.includes(a)||e.badNodes.push(n))}else 3===n.nodeType&&""!==n.nodeValue.trim()&&(e.hasNonEmptyTextNode=!0);return e},{badNodes:[],hasNonEmptyTextNode:!1});return s.badNodes.length&&this.relatedNodes(s.badNodes),!!s.badNodes.length||s.hasNonEmptyTextNode}},{id:"only-listitems",evaluate:function(e,t,n,r){var o=axe.commons.dom,a=n.children.reduce(function(e,t){var n=t.actualNode,r=n.nodeName.toUpperCase();if(1===n.nodeType&&o.isVisible(n,!0,!1)){var a=function(e,t){return"listitem"===e||"LI"===t&&!e}((n.getAttribute("role")||"").toLowerCase(),r);e.hasListItem=function(e,t,n){return e||"LI"===t&&n||n}(e.hasListItem,r,a),a&&(e.isEmpty=!1),"LI"!==r||a||e.liItemsWithRole++,"LI"===r||a||e.badNodes.push(n)}return 3===n.nodeType&&""!==n.nodeValue.trim()&&(e.hasNonEmptyTextNode=!0),e},{badNodes:[],isEmpty:!0,hasNonEmptyTextNode:!1,hasListItem:!1,liItemsWithRole:0}),i=n.children.filter(function(e){return"LI"===e.actualNode.nodeName.toUpperCase()}),u=0<a.liItemsWithRole&&i.length===a.liItemsWithRole;return a.badNodes.length&&this.relatedNodes(a.badNodes),!(a.hasListItem||a.isEmpty&&!u)||!!a.badNodes.length||a.hasNonEmptyTextNode}},{id:"structured-dlitems",evaluate:function(e,t,n,r){var a=n.children;if(!a||!a.length)return!1;for(var o,i=!1,u=!1,s=0;s<a.length;s++){if("DT"===(o=a[s].actualNode.nodeName.toUpperCase())&&(i=!0),i&&"DD"===o)return!1;"DD"===o&&(u=!0)}return i||u}},{id:"caption",evaluate:function(e,t,n,r){return!axe.utils.querySelectorAll(n,"track").some(function(e){return"captions"===(e.actualNode.getAttribute("kind")||"").toLowerCase()})&&void 0}},{id:"description",evaluate:function(e,t,n,r){return!axe.utils.querySelectorAll(n,"track").some(function(e){return"descriptions"===(e.actualNode.getAttribute("kind")||"").toLowerCase()})&&void 0}},{id:"frame-tested",evaluate:function(e,t,n,r){var a=this.async(),o=Object.assign({isViolation:!1,timeout:500},t),i=o.isViolation,u=o.timeout,s=setTimeout(function(){s=setTimeout(function(){s=null,a(!i&&void 0)},0)},u);axe.utils.respondable(e.contentWindow,"axe.ping",null,void 0,function(){null!==s&&(clearTimeout(s),a(!0))})},options:{isViolation:!1}},{id:"css-orientation-lock",evaluate:function(e,t,n,r){var a=(r||{}).cssom,o=void 0===a?void 0:a;if(o&&o.length){var i=o.reduce(function(e,t){var n=t.sheet,r=t.root,a=t.shadowId,o=a||"topDocument";if(e[o]||(e[o]={root:r,rules:[]}),!n||!n.cssRules)return e;var i=Array.from(n.cssRules);return e[o].rules=e[o].rules.concat(i),e},{}),s=!1,l=[];return Object.keys(i).forEach(function(e){var t=i[e],u=t.root,n=t.rules.filter(function(e){return 4===e.type});if(n&&n.length){var r=n.filter(function(e){var t=e.cssText;return/orientation:\s*landscape/i.test(t)||/orientation:\s*portrait/i.test(t)});r&&r.length&&r.forEach(function(e){e.cssRules.length&&Array.from(e.cssRules).forEach(function(e){if(e.selectorText&&!(e.style.length<=0)){var t=e.style.transform||e.style.webkitTransform||e.style.msTransform||!1;if(t){var n=t.match(/rotate\(([^)]+)deg\)/),r=parseInt(n&&n[1]||0),a=r%90==0&&r%180!=0;if(a&&"HTML"!==e.selectorText.toUpperCase()){var o=e.selectorText,i=Array.from(u.querySelectorAll(o));i&&i.length&&(l=l.concat(i))}s=a}}})})}}),s?(l.length&&this.relatedNodes(l),!1):!0}}},{id:"meta-viewport-large",evaluate:function(e,t,n,r){t=t||{};for(var a,o=(e.getAttribute("content")||"").split(/[;,]/),i={},u=t.scaleMinimum||2,s=t.lowerBound||!1,l=0,c=o.length;l<c;l++){var d=(a=o[l].split("=")).shift().toLowerCase();d&&a.length&&(i[d.trim()]=a.shift().trim().toLowerCase())}return!!(s&&i["maximum-scale"]&&parseFloat(i["maximum-scale"])<s)||(s||"no"!==i["user-scalable"]?!(i["maximum-scale"]&&parseFloat(i["maximum-scale"])<u)||(this.data("maximum-scale"),!1):(this.data("user-scalable=no"),!1))},options:{scaleMinimum:5,lowerBound:2}},{id:"meta-viewport",evaluate:function(e,t,n,r){t=t||{};for(var a,o=(e.getAttribute("content")||"").split(/[;,]/),i={},u=t.scaleMinimum||2,s=t.lowerBound||!1,l=0,c=o.length;l<c;l++){var d=(a=o[l].split("=")).shift().toLowerCase();d&&a.length&&(i[d.trim()]=a.shift().trim().toLowerCase())}return!!(s&&i["maximum-scale"]&&parseFloat(i["maximum-scale"])<s)||(s||"no"!==i["user-scalable"]?!(i["maximum-scale"]&&parseFloat(i["maximum-scale"])<u)||(this.data("maximum-scale"),!1):(this.data("user-scalable=no"),!1))},options:{scaleMinimum:2}},{id:"header-present",evaluate:function(e,t,n,r){return!!axe.utils.querySelectorAll(n,'h1, h2, h3, h4, h5, h6, [role="heading"]')[0]}},{id:"heading-order",evaluate:function(e,t,n,r){var a=e.getAttribute("aria-level");if(null!==a)return this.data(parseInt(a,10)),!0;var o=e.nodeName.toUpperCase().match(/H(\d)/);return o&&this.data(parseInt(o[1],10)),!0},after:function(e,t){if(e.length<2)return e;for(var n=e[0].data,r=1;r<e.length;r++)e[r].result&&e[r].data>n+1&&(e[r].result=!1),n=e[r].data;return e}},{id:"internal-link-present",evaluate:function(e,t,n,r){return axe.utils.querySelectorAll(n,"a[href]").some(function(e){return/^#[^/!]/.test(e.actualNode.getAttribute("href"))})}},{id:"landmark",evaluate:function(e,t,n,r){return 0<axe.utils.querySelectorAll(n,'main, [role="main"]').length}},{id:"meta-refresh",evaluate:function(e,t,n,r){var a=e.getAttribute("content")||"",o=a.split(/[;,]/);return""===a||"0"===o[0]}},{id:"p-as-heading",evaluate:function(e,t,n,r){var a=Array.from(e.parentNode.children),o=a.indexOf(e),i=(t=t||{}).margins||[],u=a.slice(o+1).find(function(e){return"P"===e.nodeName.toUpperCase()}),s=a.slice(0,o).reverse().find(function(e){return"P"===e.nodeName.toUpperCase()});function l(e){var t=window.getComputedStyle(function(e){for(var t=e,n=e.textContent.trim(),r=n;r===n&&void 0!==t;){var a=-1;if(0===(e=t).children.length)return e;for(;a++,""===(r=e.children[a].textContent.trim())&&a+1<e.children.length;);t=e.children[a]}return e}(e));return{fontWeight:function(e){switch(e){case"lighter":return 100;case"normal":return 400;case"bold":return 700;case"bolder":return 900}return e=parseInt(e),isNaN(e)?400:e}(t.getPropertyValue("font-weight")),fontSize:parseInt(t.getPropertyValue("font-size")),isItalic:"italic"===t.getPropertyValue("font-style")}}function c(n,r,e){return e.reduce(function(e,t){return e||(!t.size||n.fontSize/t.size>r.fontSize)&&(!t.weight||n.fontWeight-t.weight>r.fontWeight)&&(!t.italic||n.isItalic&&!r.isItalic)},!1)}var d=l(e),m=u?l(u):null,p=s?l(s):null;if(!m||!c(d,m,i))return!0;var f=axe.commons.dom.findUpVirtual(n,"blockquote");return!!(f&&"BLOCKQUOTE"===f.nodeName.toUpperCase()||p&&!c(d,p,i))&&void 0},options:{margins:[{weight:150,italic:!0},{weight:150,size:1.15},{italic:!0,size:1.15},{size:1.4}]}},{id:"region",evaluate:function(e,t,n,r){var a=axe.commons,o=a.dom,i=a.aria,u=i.getRolesByType("landmark"),s=u.reduce(function(e,t){return e.concat(i.implicitNodes(t))},[]).filter(function(e){return null!==e});var l=function e(t){var n=t.actualNode;return function(a){var o=a.actualNode,e=axe.commons.aria.getRole(o,{noImplicit:!0}),t=(o.getAttribute("aria-live")||"").toLowerCase().trim();return e?"dialog"===e||u.includes(e):!!["assertive","polite"].includes(t)||s.some(function(e){var t=axe.utils.matchesSelector(o,e);if("FORM"!==o.nodeName.toUpperCase())return t;var n=o.getAttribute("title"),r=n&&""!==n.trim()?axe.commons.text.sanitize(n):null;return t&&(!!i.labelVirtual(a)||!!r)})}(t)||o.isSkipLink(t.actualNode)&&o.getElementByReference(t.actualNode,"href")||!o.isVisible(n,!0)?[]:o.hasContent(n,!0)?[n]:t.children.filter(function(e){return 1===e.actualNode.nodeType}).map(e).reduce(function(e,t){return e.concat(t)},[])}(n);return this.relatedNodes(l),0===l.length},after:function(e,t){return[e[0]]}},{id:"skip-link",evaluate:function(e,t,n,r){var a=axe.commons.dom.getElementByReference(e,"href");return!!a&&(axe.commons.dom.isVisible(a,!0)||void 0)}},{id:"unique-frame-title",evaluate:function(e,t,n,r){var a=axe.commons.text.sanitize(e.title).trim().toLowerCase();return this.data(a),!0},after:function(e,t){var n={};return e.forEach(function(e){n[e.data]=void 0!==n[e.data]?++n[e.data]:0}),e.forEach(function(e){e.result=!!n[e.data]}),e}},{id:"duplicate-id-active",evaluate:function(t,e,n,r){var a=t.getAttribute("id").trim();if(!a)return!0;var o=axe.commons.dom.getRootNode(t),i=Array.from(o.querySelectorAll('[id="'.concat(axe.utils.escapeSelector(a),'"]'))).filter(function(e){return e!==t});return i.length&&this.relatedNodes(i),this.data(a),0===i.length},after:function(e,t){var n=[];return e.filter(function(e){return-1===n.indexOf(e.data)&&(n.push(e.data),!0)})}},{id:"duplicate-id-aria",evaluate:function(t,e,n,r){var a=t.getAttribute("id").trim();if(!a)return!0;var o=axe.commons.dom.getRootNode(t),i=Array.from(o.querySelectorAll('[id="'.concat(axe.utils.escapeSelector(a),'"]'))).filter(function(e){return e!==t});return i.length&&this.relatedNodes(i),this.data(a),0===i.length},after:function(e,t){var n=[];return e.filter(function(e){return-1===n.indexOf(e.data)&&(n.push(e.data),!0)})}},{id:"duplicate-id",evaluate:function(t,e,n,r){var a=t.getAttribute("id").trim();if(!a)return!0;var o=axe.commons.dom.getRootNode(t),i=Array.from(o.querySelectorAll('[id="'.concat(axe.utils.escapeSelector(a),'"]'))).filter(function(e){return e!==t});return i.length&&this.relatedNodes(i),this.data(a),0===i.length},after:function(e,t){var n=[];return e.filter(function(e){return-1===n.indexOf(e.data)&&(n.push(e.data),!0)})}},{id:"aria-label",evaluate:function(e,t,n,r){var a=axe.commons,o=a.text,i=a.aria;return!!o.sanitize(i.arialabelText(e))}},{id:"aria-labelledby",evaluate:function(e,t,n,r){var a=axe.commons,o=a.text,i=a.aria;return!!o.sanitize(i.arialabelledbyText(e))}},{id:"avoid-inline-spacing",evaluate:function(t,e,n,r){var a=["line-height","letter-spacing","word-spacing"].filter(function(e){if("important"===t.style.getPropertyPriority(e))return e});return!(0<a.length)||(this.data(a),!1)}},{id:"button-has-visible-text",evaluate:function(e,t,n,r){var a,o=e.nodeName.toUpperCase(),i=e.getAttribute("role");return("BUTTON"===o||"button"===i&&"INPUT"!==o)&&(a=axe.commons.text.accessibleTextVirtual(n),this.data(a),!!a)}},{id:"doc-has-title",evaluate:function(e,t,n,r){var a=document.title;return!(!a||!axe.commons.text.sanitize(a).trim())}},{id:"exists",evaluate:function(e,t,n,r){return!0}},{id:"has-alt",evaluate:function(e,t,n,r){var a=e.nodeName.toLowerCase();return e.hasAttribute("alt")&&("img"===a||"input"===a||"area"===a)}},{id:"has-visible-text",evaluate:function(e,t,n,r){return 0<axe.commons.text.accessibleTextVirtual(n).length}},{id:"is-on-screen",evaluate:function(e,t,n,r){return axe.commons.dom.isVisible(e,!1)&&!axe.commons.dom.isOffscreen(e)}},{id:"non-empty-alt",evaluate:function(e,t,n,r){var a=e.getAttribute("alt");return!(!a||!axe.commons.text.sanitize(a).trim())}},{id:"non-empty-if-present",evaluate:function(e,t,n,r){var a=e.nodeName.toUpperCase(),o=(e.getAttribute("type")||"").toLowerCase(),i=e.getAttribute("value");return this.data(i),!("INPUT"!==a||!["submit","reset"].includes(o))&&null===i}},{id:"non-empty-title",evaluate:function(e,t,n,r){var a=axe.commons.text;return!!a.sanitize(a.titleText(e))}},{id:"non-empty-value",evaluate:function(e,t,n,r){var a=e.getAttribute("value");return!(!a||!axe.commons.text.sanitize(a).trim())}},{id:"role-none",evaluate:function(e,t,n,r){return"none"===e.getAttribute("role")}},{id:"role-presentation",evaluate:function(e,t,n,r){return"presentation"===e.getAttribute("role")}},{id:"caption-faked",evaluate:function(e,t,n,r){var a=axe.commons.table.toGrid(e),o=a[0];return a.length<=1||o.length<=1||e.rows.length<=1||o.reduce(function(e,t,n){return e||t!==o[n+1]&&void 0!==o[n+1]},!1)}},{id:"has-caption",evaluate:function(e,t,n,r){return!!e.caption}},{id:"has-summary",evaluate:function(e,t,n,r){return!!e.summary}},{id:"has-th",evaluate:function(e,t,n,r){for(var a,o,i=[],u=0,s=e.rows.length;u<s;u++)for(var l=0,c=(a=e.rows[u]).cells.length;l<c;l++)"TH"!==(o=a.cells[l]).nodeName.toUpperCase()&&-1===["rowheader","columnheader"].indexOf(o.getAttribute("role"))||i.push(o);return!!i.length&&(this.relatedNodes(i),!0)}},{id:"html5-scope",evaluate:function(e,t,n,r){return!axe.commons.dom.isHTML5(document)||"TH"===e.nodeName.toUpperCase()}},{id:"same-caption-summary",evaluate:function(e,t,n,r){return!(!e.summary||!e.caption)&&e.summary.toLowerCase()===axe.commons.text.accessibleText(e.caption).toLowerCase()}},{id:"scope-value",evaluate:function(e,t,n,r){var a=e.getAttribute("scope").toLowerCase();return-1!==["row","col","rowgroup","colgroup"].indexOf(a)}},{id:"td-has-header",evaluate:function(e,t,n,r){var a=axe.commons.table,o=[];return a.getAllCells(e).forEach(function(e){axe.commons.dom.hasContent(e)&&a.isDataCell(e)&&!axe.commons.aria.label(e)&&(a.getHeaders(e).some(function(e){return null!==e&&!!axe.commons.dom.hasContent(e)})||o.push(e))}),!o.length||(this.relatedNodes(o),!1)}},{id:"td-headers-attr",evaluate:function(e,t,n,r){for(var a=[],o=0,i=e.rows.length;o<i;o++)for(var u=e.rows[o],s=0,l=u.cells.length;s<l;s++)a.push(u.cells[s]);var c=a.reduce(function(e,t){return t.getAttribute("id")&&e.push(t.getAttribute("id")),e},[]),d=a.reduce(function(e,t){var n,r,a=(t.getAttribute("headers")||"").split(/\s/).reduce(function(e,t){return(t=t.trim())&&e.push(t),e},[]);return 0!==a.length&&(t.getAttribute("id")&&(n=-1!==a.indexOf(t.getAttribute("id").trim())),r=a.reduce(function(e,t){return e||-1===c.indexOf(t)},!1),(n||r)&&e.push(t)),e},[]);return!(0<d.length)||(this.relatedNodes(d),!1)}},{id:"th-has-data-cells",evaluate:function(e,t,n,r){var a=axe.commons.table,o=a.getAllCells(e),i=this,u=[];o.forEach(function(e){var t=e.getAttribute("headers");t&&(u=u.concat(t.split(/\s+/)));var n=e.getAttribute("aria-labelledby");n&&(u=u.concat(n.split(/\s+/)))});var s=o.filter(function(e){return""!==axe.commons.text.sanitize(e.textContent)&&("TH"===e.nodeName.toUpperCase()||-1!==["rowheader","columnheader"].indexOf(e.getAttribute("role")))}),l=a.toGrid(e),c=!0;return s.forEach(function(e){if(!e.getAttribute("id")||!u.includes(e.getAttribute("id"))){var t=a.getCellPosition(e,l),n=!1;a.isColumnHeader(e)&&(n=a.traverse("down",t,l).find(function(e){return!a.isColumnHeader(e)})),!n&&a.isRowHeader(e)&&(n=a.traverse("right",t,l).find(function(e){return!a.isRowHeader(e)})),n||i.relatedNodes(e),c=c&&n}}),!!c||void 0}},{id:"hidden-content",evaluate:function(e,t,n,r){if(!["SCRIPT","HEAD","TITLE","NOSCRIPT","STYLE","TEMPLATE"].includes(e.nodeName.toUpperCase())&&axe.commons.dom.hasContentVirtual(n)){var a=window.getComputedStyle(e);if("none"===a.getPropertyValue("display"))return;if("hidden"===a.getPropertyValue("visibility")){var o=axe.commons.dom.getComposedParent(e),i=o&&window.getComputedStyle(o);if(!i||"hidden"!==i.getPropertyValue("visibility"))return}}return!0}}],commons:function(){function e(e){return null===e}function t(e){return null!==e}var commons={},l=commons.aria={},n=l.lookupTable={};n.attributes={"aria-activedescendant":{type:"idref",allowEmpty:!0,unsupported:!1},"aria-atomic":{type:"boolean",values:["true","false"],unsupported:!1},"aria-autocomplete":{type:"nmtoken",values:["inline","list","both","none"],unsupported:!1},"aria-busy":{type:"boolean",values:["true","false"],unsupported:!1},"aria-checked":{type:"nmtoken",values:["true","false","mixed","undefined"],unsupported:!1},"aria-colcount":{type:"int",unsupported:!1},"aria-colindex":{type:"int",unsupported:!1},"aria-colspan":{type:"int",unsupported:!1},"aria-controls":{type:"idrefs",allowEmpty:!0,unsupported:!1},"aria-current":{type:"nmtoken",allowEmpty:!0,values:["page","step","location","date","time","true","false"],unsupported:!1},"aria-describedby":{type:"idrefs",allowEmpty:!0,unsupported:!1},"aria-describedat":{unsupported:!0,unstandardized:!0},"aria-details":{unsupported:!0},"aria-disabled":{type:"boolean",values:["true","false"],unsupported:!1},"aria-dropeffect":{type:"nmtokens",values:["copy","move","reference","execute","popup","none"],unsupported:!1},"aria-errormessage":{type:"idref",allowEmpty:!0,unsupported:!1},"aria-expanded":{type:"nmtoken",values:["true","false","undefined"],unsupported:!1},"aria-flowto":{type:"idrefs",allowEmpty:!0,unsupported:!1},"aria-grabbed":{type:"nmtoken",values:["true","false","undefined"],unsupported:!1},"aria-haspopup":{type:"nmtoken",allowEmpty:!0,values:["true","false","menu","listbox","tree","grid","dialog"],unsupported:!1},"aria-hidden":{type:"boolean",values:["true","false"],unsupported:!1},"aria-invalid":{type:"nmtoken",allowEmpty:!0,values:["true","false","spelling","grammar"],unsupported:!1},"aria-keyshortcuts":{type:"string",allowEmpty:!0,unsupported:!1},"aria-label":{type:"string",allowEmpty:!0,unsupported:!1},"aria-labelledby":{type:"idrefs",allowEmpty:!0,unsupported:!1},"aria-level":{type:"int",unsupported:!1},"aria-live":{type:"nmtoken",values:["off","polite","assertive"],unsupported:!1},"aria-modal":{type:"boolean",values:["true","false"],unsupported:!1},"aria-multiline":{type:"boolean",values:["true","false"],unsupported:!1},"aria-multiselectable":{type:"boolean",values:["true","false"],unsupported:!1},"aria-orientation":{type:"nmtoken",values:["horizontal","vertical"],unsupported:!1},"aria-owns":{type:"idrefs",allowEmpty:!0,unsupported:!1},"aria-placeholder":{type:"string",allowEmpty:!0,unsupported:!1},"aria-posinset":{type:"int",unsupported:!1},"aria-pressed":{type:"nmtoken",values:["true","false","mixed","undefined"],unsupported:!1},"aria-readonly":{type:"boolean",values:["true","false"],unsupported:!1},"aria-relevant":{type:"nmtokens",values:["additions","removals","text","all"],unsupported:!1},"aria-required":{type:"boolean",values:["true","false"],unsupported:!1},"aria-roledescription":{type:"string",allowEmpty:!0,unsupported:{exceptions:["button",{nodeName:"input",properties:{type:["button","checkbox","image","radio","reset","submit"]}},"img","select","summary"]}},"aria-rowcount":{type:"int",unsupported:!1},"aria-rowindex":{type:"int",unsupported:!1},"aria-rowspan":{type:"int",unsupported:!1},"aria-selected":{type:"nmtoken",values:["true","false","undefined"],unsupported:!1},"aria-setsize":{type:"int",unsupported:!1},"aria-sort":{type:"nmtoken",values:["ascending","descending","other","none"],unsupported:!1},"aria-valuemax":{type:"decimal",unsupported:!1},"aria-valuemin":{type:"decimal",unsupported:!1},"aria-valuenow":{type:"decimal",unsupported:!1},"aria-valuetext":{type:"string",unsupported:!1}},n.globalAttributes=["aria-atomic","aria-busy","aria-controls","aria-current","aria-describedby","aria-disabled","aria-dropeffect","aria-flowto","aria-grabbed","aria-haspopup","aria-hidden","aria-invalid","aria-keyshortcuts","aria-label","aria-labelledby","aria-live","aria-owns","aria-relevant","aria-roledescription"],n.role={alert:{type:"widget",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},alertdialog:{type:"widget",attributes:{allowed:["aria-expanded","aria-modal","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,unsupported:!1,allowedElements:["dialog","section"]},application:{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,unsupported:!1,allowedElements:["article","audio","embed","iframe","object","section","svg","video"]},article:{type:"structure",attributes:{allowed:["aria-expanded","aria-posinset","aria-setsize","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["article"],unsupported:!1},banner:{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["header"],unsupported:!1,allowedElements:["section"]},button:{type:"widget",attributes:{allowed:["aria-expanded","aria-pressed","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:null,implicit:["button",'input[type="button"]','input[type="image"]','input[type="reset"]','input[type="submit"]',"summary"],unsupported:!1,allowedElements:[{nodeName:"a",attributes:{href:t}}]},cell:{type:"structure",attributes:{allowed:["aria-colindex","aria-colspan","aria-rowindex","aria-rowspan","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:["row"],implicit:["td","th"],unsupported:!1},checkbox:{type:"widget",attributes:{allowed:["aria-checked","aria-required","aria-readonly","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:null,implicit:['input[type="checkbox"]'],unsupported:!1,allowedElements:["button"]},columnheader:{type:"structure",attributes:{allowed:["aria-colindex","aria-colspan","aria-expanded","aria-rowindex","aria-rowspan","aria-required","aria-readonly","aria-selected","aria-sort","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:["row"],implicit:["th"],unsupported:!1},combobox:{type:"composite",attributes:{allowed:["aria-autocomplete","aria-required","aria-activedescendant","aria-orientation","aria-errormessage"],required:["aria-expanded"]},owned:{all:["listbox","textbox"]},nameFrom:["author"],context:null,unsupported:!1,allowedElements:[{nodeName:"input",properties:{type:"text"}}]},command:{nameFrom:["author"],type:"abstract",unsupported:!1},complementary:{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["aside"],unsupported:!1,allowedElements:["section"]},composite:{nameFrom:["author"],type:"abstract",unsupported:!1},contentinfo:{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["footer"],unsupported:!1,allowedElements:["section"]},definition:{type:"structure",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["dd","dfn"],unsupported:!1},dialog:{type:"widget",attributes:{allowed:["aria-expanded","aria-modal","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["dialog"],unsupported:!1,allowedElements:["section"]},directory:{type:"structure",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:null,unsupported:!1,allowedElements:["ol","ul"]},document:{type:"structure",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["body"],unsupported:!1,allowedElements:["article","embed","iframe","object","section","svg"]},"doc-abstract":{type:"section",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-acknowledgments":{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-afterword":{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-appendix":{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-backlink":{type:"link",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:null,unsupported:!1,allowedElements:[{nodeName:"a",attributes:{href:t}}]},"doc-biblioentry":{type:"listitem",attributes:{allowed:["aria-expanded","aria-level","aria-posinset","aria-setsize","aria-errormessage"]},owned:null,nameFrom:["author"],context:["doc-bibliography"],unsupported:!1,allowedElements:["li"]},"doc-bibliography":{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:{one:["doc-biblioentry"]},nameFrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-biblioref":{type:"link",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:null,unsupported:!1,allowedElements:[{nodeName:"a",attributes:{href:t}}]},"doc-chapter":{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-colophon":{type:"section",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-conclusion":{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-cover":{type:"img",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1},"doc-credit":{type:"section",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-credits":{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-dedication":{type:"section",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-endnote":{type:"listitem",attributes:{allowed:["aria-expanded","aria-level","aria-posinset","aria-setsize","aria-errormessage"]},owned:null,namefrom:["author"],context:["doc-endnotes"],unsupported:!1,allowedElements:["li"]},"doc-endnotes":{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:{one:["doc-endnote"]},namefrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-epigraph":{type:"section",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1},"doc-epilogue":{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-errata":{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-example":{type:"section",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["aside","section"]},"doc-footnote":{type:"section",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["aside","footer","header"]},"doc-foreword":{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-glossary":{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:["term","definition"],namefrom:["author"],context:null,unsupported:!1,allowedElements:["dl"]},"doc-glossref":{type:"link",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author","contents"],context:null,unsupported:!1,allowedElements:[{nodeName:"a",attributes:{href:t}}]},"doc-index":{type:"navigation",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["nav","section"]},"doc-introduction":{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-noteref":{type:"link",attributes:{allowed:["aria-expanded"]},owned:null,namefrom:["author","contents"],context:null,unsupported:!1,allowedElements:[{nodeName:"a",attributes:{href:t}}]},"doc-notice":{type:"note",attributes:{allowed:["aria-expanded"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-pagebreak":{type:"separator",attributes:{allowed:["aria-expanded"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["hr"]},"doc-pagelist":{type:"navigation",attributes:{allowed:["aria-expanded"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["nav","section"]},"doc-part":{type:"landmark",attributes:{allowed:["aria-expanded"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-preface":{type:"landmark",attributes:{allowed:["aria-expanded"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-prologue":{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-pullquote":{type:"none",attributes:{allowed:["aria-expanded"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["aside","section"]},"doc-qna":{type:"section",attributes:{allowed:["aria-expanded"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-subtitle":{type:"sectionhead",attributes:{allowed:["aria-expanded"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:{nodeName:["h1","h2","h3","h4","h5","h6"]}},"doc-tip":{type:"note",attributes:{allowed:["aria-expanded"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["aside"]},"doc-toc":{type:"navigation",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["nav","section"]},feed:{type:"structure",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:{one:["article"]},nameFrom:["author"],context:null,unsupported:!1,allowedElements:["article","aside","section"]},figure:{type:"structure",unsupported:!1},form:{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["form"],unsupported:!1},grid:{type:"composite",attributes:{allowed:["aria-activedescendant","aria-expanded","aria-colcount","aria-level","aria-multiselectable","aria-readonly","aria-rowcount","aria-errormessage"]},owned:{one:["rowgroup","row"]},nameFrom:["author"],context:null,implicit:["table"],unsupported:!1},gridcell:{type:"widget",attributes:{allowed:["aria-colindex","aria-colspan","aria-expanded","aria-rowindex","aria-rowspan","aria-selected","aria-readonly","aria-required","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:["row"],implicit:["td","th"],unsupported:!1},group:{type:"structure",attributes:{allowed:["aria-activedescendant","aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["details","optgroup"],unsupported:!1,allowedElements:["dl","figcaption","fieldset","figure","footer","header","ol","ul"]},heading:{type:"structure",attributes:{required:["aria-level"],allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:null,implicit:["h1","h2","h3","h4","h5","h6"],unsupported:!1},img:{type:"structure",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["img"],unsupported:!1,allowedElements:["embed","iframe","object","svg"]},input:{nameFrom:["author"],type:"abstract",unsupported:!1},landmark:{nameFrom:["author"],type:"abstract",unsupported:!1},link:{type:"widget",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:null,implicit:["a[href]"],unsupported:!1,allowedElements:["button",{nodeName:"input",properties:{type:["image","button"]}}]},list:{type:"structure",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:{all:["listitem"]},nameFrom:["author"],context:null,implicit:["ol","ul","dl"],unsupported:!1},listbox:{type:"composite",attributes:{allowed:["aria-activedescendant","aria-multiselectable","aria-required","aria-expanded","aria-orientation","aria-errormessage"]},owned:{all:["option"]},nameFrom:["author"],context:null,implicit:["select"],unsupported:!1,allowedElements:["ol","ul"]},listitem:{type:"structure",attributes:{allowed:["aria-level","aria-posinset","aria-setsize","aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:["list"],implicit:["li","dt"],unsupported:!1},log:{type:"widget",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},main:{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["main"],unsupported:!1,allowedElements:["article","section"]},marquee:{type:"widget",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},math:{type:"structure",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["math"],unsupported:!1},menu:{type:"composite",attributes:{allowed:["aria-activedescendant","aria-expanded","aria-orientation","aria-errormessage"]},owned:{one:["menuitem","menuitemradio","menuitemcheckbox"]},nameFrom:["author"],context:null,implicit:['menu[type="context"]'],unsupported:!1,allowedElements:["ol","ul"]},menubar:{type:"composite",attributes:{allowed:["aria-activedescendant","aria-expanded","aria-orientation","aria-errormessage"]},owned:{one:["menuitem","menuitemradio","menuitemcheckbox"]},nameFrom:["author"],context:null,unsupported:!1,allowedElements:["ol","ul"]},menuitem:{type:"widget",attributes:{allowed:["aria-posinset","aria-setsize","aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:["menu","menubar"],implicit:['menuitem[type="command"]'],unsupported:!1,allowedElements:["button","li",{nodeName:"iput",properties:{type:["image","button"]}},{nodeName:"a",attributes:{href:t}}]},menuitemcheckbox:{type:"widget",attributes:{allowed:["aria-checked","aria-posinset","aria-setsize","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:["menu","menubar"],implicit:['menuitem[type="checkbox"]'],unsupported:!1,allowedElements:[{nodeName:["button","li"]},{nodeName:"input",properties:{type:["checkbox","image","button"]}},{nodeName:"a",attributes:{href:t}}]},menuitemradio:{type:"widget",attributes:{allowed:["aria-checked","aria-selected","aria-posinset","aria-setsize","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:["menu","menubar"],implicit:['menuitem[type="radio"]'],unsupported:!1,allowedElements:[{nodeName:["button","li"]},{nodeName:"input",properties:{type:["image","button","radio"]}},{nodeName:"a",attributes:{href:t}}]},navigation:{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["nav"],unsupported:!1,allowedElements:["section"]},none:{type:"structure",attributes:null,owned:null,nameFrom:["author"],context:null,unsupported:!1,allowedElements:[{nodeName:["article","aside","dl","embed","figcaption","fieldset","figure","footer","form","h1","h2","h3","h4","h5","h6","header","iframe","li","ol","section","ul"]},{nodeName:"img",attributes:{alt:t}}]},note:{type:"structure",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,unsupported:!1,allowedElements:["aside"]},option:{type:"widget",attributes:{allowed:["aria-selected","aria-posinset","aria-setsize","aria-checked","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:["listbox"],implicit:["option"],unsupported:!1,allowedElements:[{nodeName:["button","li"]},{nodeName:"input",properties:{type:["checkbox","button"]}},{nodeName:"a",attributes:{href:t}}]},presentation:{type:"structure",attributes:null,owned:null,nameFrom:["author"],context:null,unsupported:!1,allowedElements:[{nodeName:["article","aside","dl","embed","figcaption","fieldset","figure","footer","form","h1","h2","h3","h4","h5","h6","header","iframe","li","ol","section","ul"]},{nodeName:"img",attributes:{alt:t}}]},progressbar:{type:"widget",attributes:{allowed:["aria-valuetext","aria-valuenow","aria-valuemax","aria-valuemin","aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["progress"],unsupported:!1},radio:{type:"widget",attributes:{allowed:["aria-selected","aria-posinset","aria-setsize","aria-required","aria-errormessage","aria-checked"]},owned:null,nameFrom:["author","contents"],context:null,implicit:['input[type="radio"]'],unsupported:!1,allowedElements:[{nodeName:["button","li"]},{nodeName:"input",properties:{type:["image","button"]}}]},radiogroup:{type:"composite",attributes:{allowed:["aria-activedescendant","aria-required","aria-expanded","aria-readonly","aria-errormessage"]},owned:{all:["radio"]},nameFrom:["author"],context:null,unsupported:!1,allowedElements:{nodeName:["ol","ul"]}},range:{nameFrom:["author"],type:"abstract",unsupported:!1},region:{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["section[aria-label]","section[aria-labelledby]","section[title]"],unsupported:!1,allowedElements:{nodeName:["article","aside"]}},roletype:{type:"abstract",unsupported:!1},row:{type:"structure",attributes:{allowed:["aria-activedescendant","aria-colindex","aria-expanded","aria-level","aria-selected","aria-rowindex","aria-errormessage"]},owned:{one:["cell","columnheader","rowheader","gridcell"]},nameFrom:["author","contents"],context:["rowgroup","grid","treegrid","table"],implicit:["tr"],unsupported:!1},rowgroup:{type:"structure",attributes:{allowed:["aria-activedescendant","aria-expanded","aria-errormessage"]},owned:{all:["row"]},nameFrom:["author","contents"],context:["grid","table","treegrid"],implicit:["tbody","thead","tfoot"],unsupported:!1},rowheader:{type:"structure",attributes:{allowed:["aria-colindex","aria-colspan","aria-expanded","aria-rowindex","aria-rowspan","aria-required","aria-readonly","aria-selected","aria-sort","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:["row"],implicit:["th"],unsupported:!1},scrollbar:{type:"widget",attributes:{required:["aria-controls","aria-valuenow"],allowed:["aria-valuetext","aria-orientation","aria-errormessage","aria-valuemax","aria-valuemin"]},owned:null,nameFrom:["author"],context:null,unsupported:!1},search:{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,unsupported:!1,allowedElements:{nodeName:["aside","form","section"]}},searchbox:{type:"widget",attributes:{allowed:["aria-activedescendant","aria-autocomplete","aria-multiline","aria-readonly","aria-required","aria-placeholder","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:['input[type="search"]'],unsupported:!1,allowedElements:{nodeName:"input",properties:{type:"text"}}},section:{nameFrom:["author","contents"],type:"abstract",unsupported:!1},sectionhead:{nameFrom:["author","contents"],type:"abstract",unsupported:!1},select:{nameFrom:["author"],type:"abstract",unsupported:!1},separator:{type:"structure",attributes:{allowed:["aria-expanded","aria-orientation","aria-valuenow","aria-valuemax","aria-valuemin","aria-valuetext","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["hr"],unsupported:!1,allowedElements:["li"]},slider:{type:"widget",attributes:{allowed:["aria-valuetext","aria-orientation","aria-readonly","aria-errormessage","aria-valuemax","aria-valuemin"],required:["aria-valuenow"]},owned:null,nameFrom:["author"],context:null,implicit:['input[type="range"]'],unsupported:!1},spinbutton:{type:"widget",attributes:{allowed:["aria-valuetext","aria-required","aria-readonly","aria-errormessage","aria-valuemax","aria-valuemin"],required:["aria-valuenow"]},owned:null,nameFrom:["author"],context:null,implicit:['input[type="number"]'],unsupported:!1,allowedElements:{nodeName:"input",properties:{type:"text"}}},status:{type:"widget",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["output"],unsupported:!1,allowedElements:["section"]},structure:{type:"abstract",unsupported:!1},switch:{type:"widget",attributes:{allowed:["aria-errormessage"],required:["aria-checked"]},owned:null,nameFrom:["author","contents"],context:null,unsupported:!1,allowedElements:["button",{nodeName:"input",properties:{type:["checkbox","image","button"]}},{nodeName:"a",attributes:{href:t}}]},tab:{type:"widget",attributes:{allowed:["aria-selected","aria-expanded","aria-setsize","aria-posinset","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:["tablist"],unsupported:!1,allowedElements:[{nodeName:["button","h1","h2","h3","h4","h5","h6","li"]},{nodeName:"input",properties:{type:"button"}},{nodeName:"a",attributes:{href:t}}]},table:{type:"structure",attributes:{allowed:["aria-colcount","aria-rowcount","aria-errormessage"]},owned:{one:["rowgroup","row"]},nameFrom:["author"],context:null,implicit:["table"],unsupported:!1},tablist:{type:"composite",attributes:{allowed:["aria-activedescendant","aria-expanded","aria-level","aria-multiselectable","aria-orientation","aria-errormessage"]},owned:{all:["tab"]},nameFrom:["author"],context:null,unsupported:!1,allowedElements:["ol","ul"]},tabpanel:{type:"widget",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},term:{type:"structure",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:null,implicit:["dt"],unsupported:!1},textbox:{type:"widget",attributes:{allowed:["aria-activedescendant","aria-autocomplete","aria-multiline","aria-readonly","aria-required","aria-placeholder","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:['input[type="text"]','input[type="email"]','input[type="password"]','input[type="tel"]','input[type="url"]',"input:not([type])","textarea"],unsupported:!1},timer:{type:"widget",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,unsupported:!1},toolbar:{type:"structure",attributes:{allowed:["aria-activedescendant","aria-expanded","aria-orientation","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:['menu[type="toolbar"]'],unsupported:!1,allowedElements:["ol","ul"]},tooltip:{type:"widget",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:null,unsupported:!1},tree:{type:"composite",attributes:{allowed:["aria-activedescendant","aria-multiselectable","aria-required","aria-expanded","aria-orientation","aria-errormessage"]},owned:{all:["treeitem"]},nameFrom:["author"],context:null,unsupported:!1,allowedElements:["ol","ul"]},treegrid:{type:"composite",attributes:{allowed:["aria-activedescendant","aria-colcount","aria-expanded","aria-level","aria-multiselectable","aria-readonly","aria-required","aria-rowcount","aria-orientation","aria-errormessage"]},owned:{one:["rowgroup","row"]},nameFrom:["author"],context:null,unsupported:!1},treeitem:{type:"widget",attributes:{allowed:["aria-checked","aria-selected","aria-expanded","aria-level","aria-posinset","aria-setsize","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:["group","tree"],unsupported:!1,allowedElements:["li",{nodeName:"a",attributes:{href:t}}]},widget:{type:"abstract",unsupported:!1},window:{nameFrom:["author"],type:"abstract",unsupported:!1}},n.elementsAllowedNoRole=[{nodeName:["base","body","caption","col","colgroup","datalist","dd","details","dt","head","html","keygen","label","legend","main","map","math","meta","meter","noscript","optgroup","param","picture","progress","script","source","style","template","textarea","title","track"]},{nodeName:"area",attributes:{href:t}},{nodeName:"input",properties:{type:["color","data","datatime","file","hidden","month","number","password","range","reset","submit","time","week"]}},{nodeName:"input",attributes:{list:e},properties:{type:["email","search","tel","url"]}},{nodeName:"link",attributes:{href:t}},{nodeName:"menu",attributes:{type:"context"}},{nodeName:"menuitem",attributes:{type:["command","checkbox","radio"]}},{nodeName:"select",condition:function(e){return 1<Number(e.getAttribute("size"))},properties:{multiple:!0}},{nodeName:["clippath","cursor","defs","desc","feblend","fecolormatrix","fecomponenttransfer","fecomposite","feconvolvematrix","fediffuselighting","fedisplacementmap","fedistantlight","fedropshadow","feflood","fefunca","fefuncb","fefuncg","fefuncr","fegaussianblur","feimage","femerge","femergenode","femorphology","feoffset","fepointlight","fespecularlighting","fespotlight","fetile","feturbulence","filter","hatch","hatchpath","lineargradient","marker","mask","meshgradient","meshpatch","meshrow","metadata","mpath","pattern","radialgradient","solidcolor","stop","switch","view"]}],n.elementsAllowedAnyRole=[{nodeName:"a",attributes:{href:e}},{nodeName:["abbr","address","canvas","div","p","pre","blockquote","ins","del","output","span","table","tbody","thead","tfoot","td","em","strong","small","s","cite","q","dfn","abbr","time","code","var","samp","kbd","sub","sup","i","b","u","mark","ruby","rt","rp","bdi","bdo","br","wbr","th","tr"]}],n.evaluateRoleForElement={A:function(e){var t=e.node,n=e.out;return"http://www.w3.org/2000/svg"===t.namespaceURI||(!t.href.length||n)},AREA:function(e){return!e.node.href},BUTTON:function(e){var t=e.node,n=e.role,r=e.out;return"menu"===t.getAttribute("type")?"menuitem"===n:r},IMG:function(e){var t=e.node,n=e.out;return t.alt?!n:n},INPUT:function(e){var t=e.node,n=e.role,r=e.out;switch(t.type){case"button":case"image":return r;case"checkbox":return!("button"!==n||!t.hasAttribute("aria-pressed"))||r;case"radio":return"menuitemradio"===n;case"text":return"combobox"===n||"searchbox"===n||"spinbutton"===n;default:return!1}},LI:function(e){var t=e.node,n=e.out;return!axe.utils.matchesSelector(t,"ol li, ul li")||n},MENU:function(e){return"context"!==e.node.getAttribute("type")},OPTION:function(e){var t=e.node;return!axe.utils.matchesSelector(t,"select > option, datalist > option, optgroup > option")},SELECT:function(e){var t=e.node,n=e.role;return!t.multiple&&t.size<=1&&"menu"===n},SVG:function(e){var t=e.node,n=e.out;return!(!t.parentNode||"http://www.w3.org/2000/svg"!==t.parentNode.namespaceURI)||n}},n.rolesOfType={widget:["button","checkbox","dialog","gridcell","heading","link","log","marquee","menuitem","menuitemcheckbox","menuitemradio","option","progressbar","radio","scrollbar","slider","spinbutton","status","switch","tab","tabpanel","textbox","timer","tooltip","tree","treeitem"]};var s={};commons.color=s;var h=commons.dom={},r={};function i(e,t){return i.fromDefinition(e,t)}commons.forms=r,commons.matches=i;var o=commons.table={},g=commons.text={EdgeFormDefaults:{}};commons.utils=axe.utils;l.arialabelText=function(e){return 1!==(e=e.actualNode||e).nodeType?"":e.getAttribute("aria-label")||""},l.arialabelledbyText=function(r,e){var a=1<arguments.length&&void 0!==e?e:{};return 1!==(r=r.actualNode||r).nodeType||a.inLabelledByContext||a.inControlContext?"":h.idrefs(r,"aria-labelledby").filter(function(e){return e}).reduce(function(e,t){var n=g.accessibleText(t,R({inLabelledByContext:!0,startNode:a.startNode||r},a));return e?"".concat(e," ").concat(n):n},"")},l.requiredAttr=function(e){var t=l.lookupTable.role[e];return t&&t.attributes&&t.attributes.required||[]},l.allowedAttr=function(e){var t=l.lookupTable.role[e],n=t&&t.attributes&&t.attributes.allowed||[],r=t&&t.attributes&&t.attributes.required||[];return n.concat(l.lookupTable.globalAttributes).concat(r)},l.validateAttr=function(e){return!!l.lookupTable.attributes[e]},l.getElementUnallowedRoles=function(t,e){var n=!(1<arguments.length&&void 0!==e)||e,r=t.nodeName.toUpperCase();if(!axe.utils.isHtmlElement(t))return[];var a=function(e){var t=[];if(!e)return t;if(e.hasAttribute("role")){var n=axe.utils.tokenList(e.getAttribute("role").toLowerCase());t=t.concat(n)}if(e.hasAttributeNS("http://www.idpf.org/2007/ops","type")){var r=axe.utils.tokenList(e.getAttributeNS("http://www.idpf.org/2007/ops","type").toLowerCase()).map(function(e){return"doc-".concat(e)});t=t.concat(r)}return t=t.filter(function(e){return axe.commons.aria.isValidRole(e)})}(t),o=axe.commons.aria.implicitRole(t);return a.filter(function(e){return(!n||e!==o)&&(!(n||"row"===e&&"TR"===r&&axe.utils.matchesSelector(t,'table[role="grid"] > tr'))||!l.isAriaRoleAllowedOnElement(t,e))})},l.getOwnedVirtual=function(e){var t=e.actualNode,n=e.children;if(!t||!n)throw new Error("getOwnedVirtual requires a virtual node");return h.idrefs(t,"aria-owns").reduce(function(e,t){if(t){var n=axe.utils.getNodeFromTree(t);e.push(n)}return e},n)},l.getRole=function(e,t){var n=1<arguments.length&&void 0!==t?t:{},r=n.noImplicit,a=n.fallback,o=n.abstracts,i=n.dpub;if(1!==(e=e.actualNode||e).nodeType)return null;var u=(e.getAttribute("role")||"").trim().toLowerCase(),s=(a?axe.utils.tokenList(u):[u]).filter(function(e){return!(!i&&"doc-"===e.substr(0,4))&&l.isValidRole(e,{allowAbstract:o})})[0];return s||r?s||null:l.implicitRole(e)};var a,u=/^idrefs?$/;function c(e){return e.getPropertyValue("font-family").split(/[,;]/g).map(function(e){return e.trim().toLowerCase()})}function d(e,t){var n=t.nodeName.toUpperCase(),r={TD:["TR","THEAD","TBODY","TFOOT"],TH:["TR","THEAD","TBODY","TFOOT"],INPUT:["LABEL"]},a=e.map(function(e){return e.nodeName.toUpperCase()}),o=e;for(var i in r)if(a.includes(i))for(var u=0;u<r[i].length;u++){var s=axe.commons.dom.findUp(t,r[i][u]);if(s&&-1===e.indexOf(s))axe.commons.dom.visuallyOverlaps(t.getBoundingClientRect(),s)&&o.splice(a.indexOf(i)+1,0,s);n===r[i][u]&&-1===a.indexOf(n)&&o.splice(a.indexOf(i)+1,0,t)}return o}function m(e,t){var n=e.getClientRects()[0],r=h.shadowElementsFromPoint(n.left,n.top);if(r)for(var a=0;a<r.length;a++)if(r[a]!==e&&r[a]===t)return!0;return!1}l.isAccessibleRef=function(e){e=e.actualNode||e;var t=h.getRootNode(e);t=t.documentElement||t;var n=e.id;axe._cache.get("idRefs")||(axe._cache.set("idRefs",{}),function e(n,t){n.hasAttribute&&("LABEL"===n.nodeName.toUpperCase()&&n.hasAttribute("for")&&(axe._cache.get("idRefs")[n.getAttribute("for")]=!0),t.filter(function(e){return n.hasAttribute(e)}).forEach(function(e){var t=n.getAttribute(e);axe.utils.tokenList(t).forEach(function(e){axe._cache.get("idRefs")[e]=!0})}));for(var r=0;r<n.children.length;r++)e(n.children[r],t)}(t,Object.keys(l.lookupTable.attributes).filter(function(e){var t=l.lookupTable.attributes[e].type;return u.test(t)})));return!0===axe._cache.get("idRefs")[n]},l.isAriaRoleAllowedOnElement=function(e,t){var n=e.nodeName.toUpperCase(),r=axe.commons.aria.lookupTable;if(i(e,r.elementsAllowedNoRole))return!1;if(i(e,r.elementsAllowedAnyRole))return!0;var a=r.role[t];if(!a||!a.allowedElements)return!1;var o=i(e,a.allowedElements);return Object.keys(r.evaluateRoleForElement).includes(n)?r.evaluateRoleForElement[n]({node:e,role:t,out:o}):o},l.isUnsupportedRole=function(e){var t=l.lookupTable.role[e];return!!t&&t.unsupported},l.labelVirtual=function(e){var t,n=e.actualNode;return n.getAttribute("aria-labelledby")&&(t=h.idrefs(n,"aria-labelledby").map(function(e){var t=axe.utils.getNodeFromTree(e);return t?g.visibleVirtual(t,!0):""}).join(" ").trim())?t:(t=(t=n.getAttribute("aria-label"))&&g.sanitize(t).trim())?t:null},l.label=function(e){return e=axe.utils.getNodeFromTree(e),l.labelVirtual(e)},l.namedFromContents=function(e,t){var n=(1<arguments.length&&void 0!==t?t:{}).strict;if(1!==(e=e.actualNode||e).nodeType)return!1;var r=l.getRole(e),a=l.lookupTable.role[r];return!!(a&&a.nameFrom.includes("contents")||"TABLE"===e.nodeName.toUpperCase())||!n&&(!a||["presentation","none"].includes(r))},l.isValidRole=function(e){var t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{},n=t.allowAbstract,r=t.flagUnsupported,a=void 0!==r&&r,o=l.lookupTable.role[e],i=!!o&&o.unsupported;return!(!o||a&&i)&&(!!n||"abstract"!==o.type)},l.getRolesWithNameFromContents=function(){return Object.keys(l.lookupTable.role).filter(function(e){return l.lookupTable.role[e].nameFrom&&-1!==l.lookupTable.role[e].nameFrom.indexOf("contents")})},l.getRolesByType=function(t){return Object.keys(l.lookupTable.role).filter(function(e){return l.lookupTable.role[e].type===t})},l.getRoleType=function(e){var t=l.lookupTable.role[e];return t&&t.type||null},l.requiredOwned=function(e){"use strict";var t=null,n=l.lookupTable.role[e];return n&&(t=axe.utils.clone(n.owned)),t},l.requiredContext=function(e){"use strict";var t=null,n=l.lookupTable.role[e];return n&&(t=axe.utils.clone(n.context)),t},l.implicitNodes=function(e){"use strict";var t=null,n=l.lookupTable.role[e];return n&&n.implicit&&(t=axe.utils.clone(n.implicit)),t},l.implicitRole=function(n){"use strict";var e=Object.keys(l.lookupTable.role).map(function(e){var t=l.lookupTable.role[e];return{name:e,implicit:t&&t.implicit}}).reduce(function(e,t){return t.implicit&&t.implicit.some(function(e){return axe.utils.matchesSelector(n,e)})&&e.push(t.name),e},[]);if(!e.length)return null;for(var r,t=axe.utils.getNodeAttributes(n),a=[],o=0,i=t.length;o<i;o++){var u=t[o];u.name.match(/^aria-/)&&a.push(u.name)}return(r=a,e.map(function(e){return{score:function(e){return l.allowedAttr(e).reduce(function(e,t){return e+(-1<r.indexOf(t)?1:0)},0)}(e),name:e}}).sort(function(e,t){return t.score-e.score}).map(function(e){return e.name})).shift()},l.validateAttrValue=function(e,t){"use strict";var n,r,a=e.getAttribute(t),o=l.lookupTable.attributes[t],i=h.getRootNode(e);if(!o)return!0;if(o.allowEmpty&&(!a||""===a.trim()))return!0;switch(o.type){case"boolean":case"nmtoken":return"string"==typeof a&&o.values.includes(a.toLowerCase());case"nmtokens":return(r=axe.utils.tokenList(a)).reduce(function(e,t){return e&&o.values.includes(t)},0!==r.length);case"idref":return!(!a||!i.getElementById(a));case"idrefs":return(r=axe.utils.tokenList(a)).some(function(e){return i.getElementById(e)});case"string":return""!==a.trim();case"decimal":return!(!(n=a.match(/^[-+]?([0-9]*)\.?([0-9]*)$/))||!n[1]&&!n[2]);case"int":return/^[-+]?[0-9]+$/.test(a)}},s.centerPointOfRect=function(e){if(!(e.left>window.innerWidth)&&!(e.top>window.innerHeight))return{x:Math.min(Math.ceil(e.left+e.width/2),window.innerWidth-1),y:Math.min(Math.ceil(e.top+e.height/2),window.innerHeight-1)}},s.Color=function(e,t,n,r){this.red=e,this.green=t,this.blue=n,this.alpha=r,this.toHexString=function(){var e=Math.round(this.red).toString(16),t=Math.round(this.green).toString(16),n=Math.round(this.blue).toString(16);return"#"+(15.5<this.red?e:"0"+e)+(15.5<this.green?t:"0"+t)+(15.5<this.blue?n:"0"+n)};var a=/^rgb\((\d+), (\d+), (\d+)\)$/,o=/^rgba\((\d+), (\d+), (\d+), (\d*(\.\d+)?)\)/;this.parseRgbString=function(e){if("transparent"===e)return this.red=0,this.green=0,this.blue=0,void(this.alpha=0);var t=e.match(a);return t?(this.red=parseInt(t[1],10),this.green=parseInt(t[2],10),this.blue=parseInt(t[3],10),void(this.alpha=1)):(t=e.match(o))?(this.red=parseInt(t[1],10),this.green=parseInt(t[2],10),this.blue=parseInt(t[3],10),void(this.alpha=Math.round(100*parseFloat(t[4]))/100)):void 0},this.getRelativeLuminance=function(){var e=this.red/255,t=this.green/255,n=this.blue/255;return.2126*(e<=.03928?e/12.92:Math.pow((.055+e)/1.055,2.4))+.7152*(t<=.03928?t/12.92:Math.pow((.055+t)/1.055,2.4))+.0722*(n<=.03928?n/12.92:Math.pow((.055+n)/1.055,2.4))}},s.flattenColors=function(e,t){var n=e.alpha,r=(1-n)*t.red+n*e.red,a=(1-n)*t.green+n*e.green,o=(1-n)*t.blue+n*e.blue,i=e.alpha+t.alpha*(1-e.alpha);return new s.Color(r,a,o,i)},s.getContrast=function(e,t){if(!t||!e)return null;t.alpha<1&&(t=s.flattenColors(t,e));var n=e.getRelativeLuminance(),r=t.getRelativeLuminance();return(Math.max(r,n)+.05)/(Math.min(r,n)+.05)},s.hasValidContrastRatio=function(e,t,n,r){var a=s.getContrast(e,t),o=r&&Math.ceil(72*n)/96<14||!r&&Math.ceil(72*n)/96<18?4.5:3;return{isValid:o<a,contrastRatio:a,expectedContrastRatio:o}},s.elementHasImage=function(e,t){var n=e.nodeName.toUpperCase();if(["IMG","CANVAS","OBJECT","IFRAME","VIDEO","SVG"].includes(n))return axe.commons.color.incompleteData.set("bgColor","imgNode"),!0;var r=(t=t||window.getComputedStyle(e)).getPropertyValue("background-image"),a="none"!==r;if(a){var o=/gradient/.test(r);axe.commons.color.incompleteData.set("bgColor",o?"bgGradient":"bgImage")}return a},s.elementIsDistinct=function(e,t){var r=window.getComputedStyle(e);if("none"!==r.getPropertyValue("background-image"))return!0;if(["border-bottom","border-top","outline"].reduce(function(e,t){var n=new s.Color;return n.parseRgbString(r.getPropertyValue(t+"-color")),e||"none"!==r.getPropertyValue(t+"-style")&&0<parseFloat(r.getPropertyValue(t+"-width"))&&0!==n.alpha},!1))return!0;var n=window.getComputedStyle(t);if(c(r)[0]!==c(n)[0])return!0;var a=["text-decoration-line","text-decoration-style","font-weight","font-style","font-size"].reduce(function(e,t){return e||r.getPropertyValue(t)!==n.getPropertyValue(t)},!1),o=r.getPropertyValue("text-decoration");return o.split(" ").length<3&&(a=a||o!==n.getPropertyValue("text-decoration")),a},s.getBackgroundColor=function(r,e,t){var a=1<arguments.length&&void 0!==e?e:[];if(!0!==(2<arguments.length&&void 0!==t&&t)){var n=r.getBoundingClientRect().height-2>=2*window.innerHeight;r.scrollIntoView(n)}var o=[],i=s.getBackgroundStack(r);return(i||[]).some(function(e){var t=window.getComputedStyle(e),n=s.getOwnBackgroundColor(t);return function(e,t,n){var r=e!==t&&!h.visuallyContains(e,t)&&0!==n.alpha;r&&axe.commons.color.incompleteData.set("bgColor","elmPartiallyObscured");return r}(r,e,n)||s.elementHasImage(e,t)?(o=null,a.push(e),!0):0!==n.alpha&&(a.push(e),o.push(n),1===n.alpha)}),null===o||null===i?null:(o.push(new s.Color(255,255,255,1)),o.reduce(s.flattenColors))},s.getBackgroundStack=function(e){var t=s.filteredRectStack(e);if(null===t)return null;t=d(t,e);var n=(t=function(e){var t=e.indexOf(document.body),n=e;(1<t||-1===t)&&!s.elementHasImage(document.documentElement)&&0===s.getOwnBackgroundColor(window.getComputedStyle(document.documentElement)).alpha&&(1<t&&n.splice(t,1),n.splice(e.indexOf(document.documentElement),1),n.push(document.body));return n}(t=h.reduceToElementsBelowFloating(t,e))).indexOf(e);return function(e,t,n){if(0<e)for(var r=e-1;0<=r;r--){var a=t[r];if(m(n,a))return!0;t.splice(r,1)}return!1}(n,t,e)?(axe.commons.color.incompleteData.set("bgColor","bgOverlap"),null):-1!==n?t:null},s.filteredRectStack=function(a){var o=s.getRectStack(a);if(o&&1===o.length)return o[0];if(o&&1<o.length){var i,u=o.shift();return d(u,a),o.forEach(function(e,t){if(0!==t){var n=o[t-1],r=o[t];i=n.every(function(e,t){return e===r[t]})||u.includes(a)}}),i?o[0]:(axe.commons.color.incompleteData.set("bgColor","elmPartiallyObscuring"),null)}return axe.commons.color.incompleteData.set("bgColor","outsideViewport"),null},s.getRectStack=function(e){var t=axe.commons.color.centerPointOfRect(e.getBoundingClientRect());if(!t)return null;var n=h.shadowElementsFromPoint(t.x,t.y),r=Array.from(e.getClientRects());if(!r||r.length<=1)return[n];var a=r.filter(function(e){return e.width&&0<e.width}).map(function(e){var t=axe.commons.color.centerPointOfRect(e);if(t)return h.shadowElementsFromPoint(t.x,t.y)});return a.some(function(e){return void 0===e})?null:(a.splice(0,0,n),a)},h.isOpaque=function(e){var t=window.getComputedStyle(e);return s.elementHasImage(e,t)||1===s.getOwnBackgroundColor(t).alpha},s.getForegroundColor=function(e,t){var n=window.getComputedStyle(e),r=new s.Color;r.parseRgbString(n.getPropertyValue("color"));var a=n.getPropertyValue("opacity");if(r.alpha=r.alpha*a,1===r.alpha)return r;var o=s.getBackgroundColor(e,[],t);if(null!==o)return s.flattenColors(r,o);var i=axe.commons.color.incompleteData.get("bgColor");return axe.commons.color.incompleteData.set("fgColor",i),null},s.getOwnBackgroundColor=function(e){var t=new s.Color;if(t.parseRgbString(e.getPropertyValue("background-color")),0!==t.alpha){var n=e.getPropertyValue("opacity");t.alpha=t.alpha*n}return t},s.incompleteData=(a={},{set:function(e,t){if("string"!=typeof e)throw new Error("Incomplete data: key must be a string");return t&&(a[e]=t),a[e]},get:function(e){return a[e]},clear:function(){a={}}}),h.reduceToElementsBelowFloating=function(e,t){var n,r,a,o=["fixed","sticky"],i=[],u=!1;for(n=0;n<e.length;++n)(r=e[n])===t&&(u=!0),a=window.getComputedStyle(r),u||-1===o.indexOf(a.position)?i.push(r):i=[];return i},h.findElmsInContext=function(e){var t,n=e.context,r=e.value,a=e.attr,o=e.elm,i=void 0===o?"":o,u=axe.utils.escapeSelector(r);return t=9===n.nodeType||11===n.nodeType?n:h.getRootNode(n),Array.from(t.querySelectorAll(i+"["+a+"="+u+"]"))},h.findUp=function(e,t){return h.findUpVirtual(axe.utils.getNodeFromTree(e),t)},h.findUpVirtual=function(e,t){var n;if(n=e.actualNode,!e.shadowId&&"function"==typeof e.actualNode.closest){var r=e.actualNode.closest(t);return r||null}for(;(n=n.assignedSlot?n.assignedSlot:n.parentNode)&&11===n.nodeType&&(n=n.host),n&&!axe.utils.matchesSelector(n,t)&&n!==document.documentElement;);return n&&axe.utils.matchesSelector(n,t)?n:null},h.getComposedParent=function e(t){if(t.assignedSlot)return e(t.assignedSlot);if(t.parentNode){var n=t.parentNode;if(1===n.nodeType)return n;if(n.host)return n.host}return null},h.getElementByReference=function(e,t){var n=e.getAttribute(t);if(!n)return null;"#"===n.charAt(0)?n=decodeURIComponent(n.substring(1)):"/#"===n.substr(0,2)&&(n=decodeURIComponent(n.substring(2)));var r=document.getElementById(n);return r||((r=document.getElementsByName(n)).length?r[0]:null)},h.getElementCoordinates=function(e){"use strict";var t=h.getScrollOffset(document),n=t.left,r=t.top,a=e.getBoundingClientRect();return{top:a.top+r,right:a.right+n,bottom:a.bottom+r,left:a.left+n,width:a.right-a.left,height:a.bottom-a.top}},h.getRootNode=axe.utils.getRootNode,h.getScrollOffset=function(e){"use strict";if(!e.nodeType&&e.document&&(e=e.document),9!==e.nodeType)return{left:e.scrollLeft,top:e.scrollTop};var t=e.documentElement,n=e.body;return{left:t&&t.scrollLeft||n&&n.scrollLeft||0,top:t&&t.scrollTop||n&&n.scrollTop||0}},h.getTabbableElements=function(e){return axe.utils.querySelectorAll(e,"*").filter(function(e){var t=e.isFocusable,n=e.actualNode.getAttribute("tabindex");return(n=n&&!isNaN(parseInt(n,10))?parseInt(n):null)?t&&0<=n:t})},h.getViewportSize=function(e){"use strict";var t,n=e.document,r=n.documentElement;return e.innerWidth?{width:e.innerWidth,height:e.innerHeight}:r?{width:r.clientWidth,height:r.clientHeight}:{width:(t=n.body).clientWidth,height:t.clientHeight}};var p=["HEAD","TITLE","TEMPLATE","SCRIPT","STYLE","IFRAME","OBJECT","VIDEO","AUDIO","NOSCRIPT"];function f(e){return e.disabled||h.isHiddenWithCSS(e)&&"AREA"!==e.nodeName.toUpperCase()}h.hasContentVirtual=function(e,t,n){return function(e){if(!p.includes(e.actualNode.nodeName.toUpperCase()))return e.children.some(function(e){var t=e.actualNode;return 3===t.nodeType&&t.nodeValue.trim()})}(e)||h.isVisualContent(e.actualNode)||!!n||!!l.labelVirtual(e)||!t&&e.children.some(function(e){return 1===e.actualNode.nodeType&&h.hasContentVirtual(e)})},h.hasContent=function(e,t,n){return e=axe.utils.getNodeFromTree(e),h.hasContentVirtual(e,t,n)},h.idrefs=function(e,t){"use strict";var n,r,a=h.getRootNode(e),o=[],i=e.getAttribute(t);if(i)for(n=0,r=(i=axe.utils.tokenList(i)).length;n<r;n++)o.push(a.getElementById(i[n]));return o},h.isFocusable=function(e){"use strict";if(f(e))return!1;if(h.isNativelyFocusable(e))return!0;var t=e.getAttribute("tabindex");return!(!t||isNaN(parseInt(t,10)))},h.isNativelyFocusable=function(e){"use strict";if(!e||f(e))return!1;switch(e.nodeName.toUpperCase()){case"A":case"AREA":if(e.href)return!0;break;case"INPUT":return"hidden"!==e.type;case"TEXTAREA":case"SELECT":case"DETAILS":case"BUTTON":return!0}return!1},h.insertedIntoFocusOrder=function(e){return-1<e.tabIndex&&h.isFocusable(e)&&!h.isNativelyFocusable(e)},h.isHiddenWithCSS=function(e,t){if(9===e.nodeType)return!1;if(11===e.nodeType&&(e=e.host),["STYLE","SCRIPT"].includes(e.nodeName.toUpperCase()))return!1;var n=window.getComputedStyle(e,null);if(!n)throw new Error("Style does not exist for the given element.");if("none"===n.getPropertyValue("display"))return!0;var r=["hidden","collapse"],a=n.getPropertyValue("visibility");if(r.includes(a)&&!t)return!0;if(r.includes(a)&&t&&r.includes(t))return!0;var o=h.getComposedParent(e);return!(!o||r.includes(a))&&h.isHiddenWithCSS(o,a)},h.isHTML5=function(e){var t=e.doctype;return null!==t&&("html"===t.name&&!t.publicId&&!t.systemId)};var b=["block","list-item","table","flex","grid","inline-block"];function y(e){var t=window.getComputedStyle(e).getPropertyValue("display");return b.includes(t)||"table-"===t.substr(0,6)}h.isInTextBlock=function(n){if(y(n))return!1;var e=function(e){for(var t=h.getComposedParent(e);t&&!y(t);)t=h.getComposedParent(t);return axe.utils.getNodeFromTree(t)}(n),r="",a="",o=0;return function t(e,n){!1!==n(e.actualNode)&&e.children.forEach(function(e){return t(e,n)})}(e,function(e){if(2===o)return!1;if(3===e.nodeType&&(r+=e.nodeValue),1===e.nodeType){var t=(e.nodeName||"").toUpperCase();if(["BR","HR"].includes(t))0===o?a=r="":o=2;else{if("none"===e.style.display||"hidden"===e.style.overflow||!["",null,"none"].includes(e.style.float)||!["",null,"relative"].includes(e.style.position))return!1;if("A"===t&&e.href||"link"===(e.getAttribute("role")||"").toLowerCase())return e===n&&(o=1),a+=e.textContent,!1}}}),r=axe.commons.text.sanitize(r),a=axe.commons.text.sanitize(a),r.length>a.length},h.isNode=function(e){"use strict";return e instanceof Node},h.isOffscreen=function(e){var t,n=document.documentElement,r=window.getComputedStyle(e),a=window.getComputedStyle(document.body||n).getPropertyValue("direction"),o=h.getElementCoordinates(e);if(o.bottom<0&&(function(e,t){for(e=h.getComposedParent(e);e&&"html"!==e.nodeName.toLowerCase();){if(e.scrollTop&&0<=(t+=e.scrollTop))return!1;e=h.getComposedParent(e)}return!0}(e,o.bottom)||"absolute"===r.position))return!0;if(0===o.left&&0===o.right)return!1;if("ltr"===a){if(o.right<=0)return!0}else if(t=Math.max(n.scrollWidth,h.getViewportSize(window).width),o.left>=t)return!0;return!1};var v=/^\/?#[^/!]/;h.isSkipLink=function(e){return!!v.test(e.getAttribute("href"))&&(void 0!==axe._cache.get("firstPageLink")?t=axe._cache.get("firstPageLink"):(t=axe.utils.querySelectorAll(axe._tree,'a:not([href^="#"]):not([href^="/#"]):not([href^="javascript"])')[0],axe._cache.set("firstPageLink",t||null)),!t||e.compareDocumentPosition(t.actualNode)===e.DOCUMENT_POSITION_FOLLOWING);var t},h.isVisible=function(e,t,n){"use strict";var r=axe.utils.getNodeFromTree(e),a="_isVisible"+(t?"ScreenReader":"");if(9===e.nodeType)return!0;if(11===e.nodeType&&(e=e.host),r&&void 0!==r[a])return r[a];var o=window.getComputedStyle(e,null);if(null===o)return!1;var i=e.nodeName.toUpperCase();if("none"===o.getPropertyValue("display")||["STYLE","SCRIPT","NOSCRIPT","TEMPLATE"].includes(i)||!t&&function(e){"use strict";var t=e.match(/rect\s*\(([0-9]+)px,?\s*([0-9]+)px,?\s*([0-9]+)px,?\s*([0-9]+)px\s*\)/);return!(!t||5!==t.length)&&(t[3]-t[1]<=0&&t[2]-t[4]<=0)}(o.getPropertyValue("clip"))||!n&&("hidden"===o.getPropertyValue("visibility")||!t&&h.isOffscreen(e))||t&&"true"===e.getAttribute("aria-hidden"))return!1;var u=e.assignedSlot?e.assignedSlot:e.parentNode,s=!1;return u&&(s=h.isVisible(u,t,!0)),r&&(r[a]=s),s};var D=["checkbox","img","radio","range","slider","spinbutton","textbox"];h.isVisualContent=function(e){var t=e.getAttribute("role");if(t)return-1!==D.indexOf(t);switch(e.nodeName.toUpperCase()){case"IMG":case"IFRAME":case"OBJECT":case"VIDEO":case"AUDIO":case"CANVAS":case"SVG":case"MATH":case"BUTTON":case"SELECT":case"TEXTAREA":case"KEYGEN":case"PROGRESS":case"METER":return!0;case"INPUT":return"hidden"!==e.type;default:return!1}},h.shadowElementsFromPoint=function(r,a){var t=2<arguments.length&&void 0!==arguments[2]?arguments[2]:document,o=3<arguments.length&&void 0!==arguments[3]?arguments[3]:0;if(999<o)throw new Error("Infinite loop detected");return Array.from(t.elementsFromPoint(r,a)).filter(function(e){return h.getRootNode(e)===t}).reduce(function(e,t){if(axe.utils.isShadowRoot(t)){var n=h.shadowElementsFromPoint(r,a,t.shadowRoot,o+1);(e=e.concat(n)).length&&axe.commons.dom.visuallyContains(e[0],t)&&e.push(t)}else e.push(t);return e},[])},h.visuallyContains=function(e,t){var n=e.getBoundingClientRect(),r=n.top+.01,a=n.bottom-.01,o=n.left+.01,i=n.right-.01,u=t.getBoundingClientRect(),s=u.top,l=u.left,c=s-t.scrollTop,d=s-t.scrollTop+t.scrollHeight,m=l-t.scrollLeft,p=l-t.scrollLeft+t.scrollWidth,f=window.getComputedStyle(t);return"inline"===f.getPropertyValue("display")||!(o<m&&o<u.left||r<c&&r<u.top||p<i&&i>u.right||d<a&&a>u.bottom)&&(!(i>u.right||a>u.bottom)||("scroll"===f.overflow||"auto"===f.overflow||"hidden"===f.overflow||t instanceof HTMLBodyElement||t instanceof HTMLHtmlElement))},h.visuallyOverlaps=function(e,t){var n=t.getBoundingClientRect(),r=n.top,a=n.left,o=r-t.scrollTop,i=r-t.scrollTop+t.scrollHeight,u=a-t.scrollLeft,s=a-t.scrollLeft+t.scrollWidth;if(e.left>s&&e.left>n.right||e.top>i&&e.top>n.bottom||e.right<u&&e.right<n.left||e.bottom<o&&e.bottom<n.top)return!1;var l=window.getComputedStyle(t);return!(e.left>n.right||e.top>n.bottom)||("scroll"===l.overflow||"auto"===l.overflow||t instanceof HTMLBodyElement||t instanceof HTMLHtmlElement)},r.isAriaCombobox=function(e){return"combobox"===axe.commons.aria.getRole(e,{noImplicit:!0})},r.isAriaListbox=function(e){return"listbox"===axe.commons.aria.getRole(e,{noImplicit:!0})};var w=["progressbar","scrollbar","slider","spinbutton"];r.isAriaRange=function(e){var t=axe.commons.aria.getRole(e,{noImplicit:!0});return w.includes(t)},r.isAriaTextbox=function(e){return"textbox"===axe.commons.aria.getRole(e,{noImplicit:!0})},r.isNativeSelect=function(e){return"SELECT"===e.nodeName.toUpperCase()};var k=["button","checkbox","color","file","hidden","image","password","radio","reset","submit"];r.isNativeTextbox=function(e){var t=e.nodeName.toUpperCase();return"TEXTAREA"===t||"INPUT"===t&&!k.includes(e.type)},i.attributes=function(t,e){return t=t.actualNode||t,i.fromFunction(function(e){return t.getAttribute(e)},e)},i.condition=function(e,t){return!!t(e)};var x,E=["nodeName","attributes","properties","condition"];function C(e){var t=e.actualNode;return 3!==t.nodeType?"":t.textContent}i.fromDefinition=function(r,a){return r=r.actualNode||r,Array.isArray(a)?a.some(function(e){return i(r,e)}):"string"==typeof a?axe.utils.matchesSelector(r,a):Object.keys(a).every(function(e){if(!E.includes(e))throw new Error('Unknown matcher type "'.concat(e,'"'));var t=i[e],n=a[e];return t(r,n)})},i.fromFunction=function(t,n){if("object"!==S(n)||Array.isArray(n)||n instanceof RegExp)throw new Error("Expect matcher to be an object");return Object.keys(n).every(function(e){return i.fromPrimative(t(e),n[e])})},i.fromPrimative=function(e,t){var n=S(t);return Array.isArray(t)&&void 0!==e?t.includes(e):"function"===n?!!t(e):t instanceof RegExp?t.test(e):t===e},i.nodeName=function(e,t,n){var r=(2<arguments.length&&void 0!==n?n:{}).isXHTML;if(e=e.actualNode||e,void 0===r){if("string"==typeof t)return axe.utils.matchesSelector(e,t);void 0===x&&(x=axe.utils.isXHTML(e.ownerDocument)),r=x}var a=r?e.nodeName:e.nodeName.toLowerCase();return i.fromPrimative(a,t)},i.properties=function(t,e){return t=t.actualNode||t,i.fromFunction(function(e){return t[e]},e)},o.getAllCells=function(e){var t,n,r,a,o=[];for(t=0,r=e.rows.length;t<r;t++)for(n=0,a=e.rows[t].cells.length;n<a;n++)o.push(e.rows[t].cells[n]);return o},o.getCellPosition=function(e,t){var n,r;for(t=t||o.toGrid(h.findUp(e,"table")),n=0;n<t.length;n++)if(t[n]&&-1!==(r=t[n].indexOf(e)))return{x:r,y:n}},o.getHeaders=function(e){if(e.hasAttribute("headers"))return commons.dom.idrefs(e,"headers");var t=commons.table.toGrid(commons.dom.findUp(e,"table")),n=commons.table.getCellPosition(e,t),r=o.traverse("left",n,t).filter(function(e){return o.isRowHeader(e)}),a=o.traverse("up",n,t).filter(function(e){return o.isColumnHeader(e)});return[].concat(r,a).reverse()},o.getScope=function(e){var t=e.getAttribute("scope"),n=e.getAttribute("role");if(e instanceof Element==!1||-1===["TD","TH"].indexOf(e.nodeName.toUpperCase()))throw new TypeError("Expected TD or TH element");if("columnheader"===n)return"col";if("rowheader"===n)return"row";if("col"===t||"row"===t)return t;if("TH"!==e.nodeName.toUpperCase())return!1;var r=o.toGrid(h.findUp(e,"table")),a=o.getCellPosition(e);return r[a.y].reduce(function(e,t){return e&&"TH"===t.nodeName.toUpperCase()},!0)?"col":r.map(function(e){return e[a.x]}).reduce(function(e,t){return e&&t&&"TH"===t.nodeName.toUpperCase()},!0)?"row":"auto"},o.isColumnHeader=function(e){return-1!==["col","auto"].indexOf(o.getScope(e))},o.isDataCell=function(e){if(!e.children.length&&!e.textContent.trim())return!1;var t=e.getAttribute("role");return axe.commons.aria.isValidRole(t)?["cell","gridcell"].includes(t):"TD"===e.nodeName.toUpperCase()},o.isDataTable=function(e){var t=(e.getAttribute("role")||"").toLowerCase();if(("presentation"===t||"none"===t)&&!h.isFocusable(e))return!1;if("true"===e.getAttribute("contenteditable")||h.findUp(e,'[contenteditable="true"]'))return!0;if("grid"===t||"treegrid"===t||"table"===t)return!0;if("landmark"===commons.aria.getRoleType(t))return!0;if("0"===e.getAttribute("datatable"))return!1;if(e.getAttribute("summary"))return!0;if(e.tHead||e.tFoot||e.caption)return!0;for(var n=0,r=e.children.length;n<r;n++)if("COLGROUP"===e.children[n].nodeName.toUpperCase())return!0;for(var a,o,i=0,u=e.rows.length,s=!1,l=0;l<u;l++)for(var c=0,d=(a=e.rows[l]).cells.length;c<d;c++){if("TH"===(o=a.cells[c]).nodeName.toUpperCase())return!0;if(s||o.offsetWidth===o.clientWidth&&o.offsetHeight===o.clientHeight||(s=!0),o.getAttribute("scope")||o.getAttribute("headers")||o.getAttribute("abbr"))return!0;if(["columnheader","rowheader"].includes((o.getAttribute("role")||"").toLowerCase()))return!0;if(1===o.children.length&&"ABBR"===o.children[0].nodeName.toUpperCase())return!0;i++}if(e.getElementsByTagName("table").length)return!1;if(u<2)return!1;var m,p,f=e.rows[Math.ceil(u/2)];if(1===f.cells.length&&1===f.cells[0].colSpan)return!1;if(5<=f.cells.length)return!0;if(s)return!0;for(l=0;l<u;l++){if(a=e.rows[l],m&&m!==window.getComputedStyle(a).getPropertyValue("background-color"))return!0;if(m=window.getComputedStyle(a).getPropertyValue("background-color"),p&&p!==window.getComputedStyle(a).getPropertyValue("background-image"))return!0;p=window.getComputedStyle(a).getPropertyValue("background-image")}return 20<=u||!(h.getElementCoordinates(e).width>.95*h.getViewportSize(window).width)&&(!(i<10)&&!e.querySelector("object, embed, iframe, applet"))},o.isHeader=function(e){if(o.isColumnHeader(e)||o.isRowHeader(e))return!0;if(e.getAttribute("id")){var t=axe.utils.escapeSelector(e.getAttribute("id"));return!!document.querySelector('[headers~="'.concat(t,'"]'))}return!1},o.isRowHeader=function(e){return["row","auto"].includes(o.getScope(e))},o.toGrid=function(e){for(var t=[],n=e.rows,r=0,a=n.length;r<a;r++){var o=n[r].cells;t[r]=t[r]||[];for(var i=0,u=0,s=o.length;u<s;u++)for(var l=0;l<o[u].colSpan;l++){for(var c=0;c<o[u].rowSpan;c++){for(t[r+c]=t[r+c]||[];t[r+c][i];)i++;t[r+c][i]=o[u]}i++}}return t},o.toArray=o.toGrid,o.traverse=function(e,t,n,r){if(Array.isArray(t)&&(r=n,n=t,t={x:0,y:0}),"string"==typeof e)switch(e){case"left":e={x:-1,y:0};break;case"up":e={x:0,y:-1};break;case"right":e={x:1,y:0};break;case"down":e={x:0,y:1}}return function e(t,n,r,a){var o,i=r[n.y]?r[n.y][n.x]:void 0;return i?"function"==typeof a&&!0===(o=a(i,n,r))?[i]:((o=e(t,{x:n.x+t.x,y:n.y+t.y},r,a)).unshift(i),o):[]}(e,{x:t.x+e.x,y:t.y+e.y},n,r)},g.accessibleText=function(e,t){var n=axe.utils.getNodeFromTree(e);return g.accessibleTextVirtual(n,t)},g.accessibleTextVirtual=function(n,e){var r=1<arguments.length&&void 0!==e?e:{},t=n.actualNode;if(r=function(e,t){var n=e.actualNode;t.startNode||(t=R({startNode:e},t));1===n.nodeType&&t.inLabelledByContext&&void 0===t.includeHidden&&(t=R({includeHidden:!h.isVisible(n,!0)},t));return t}(n,r),function(e,t){var n=e.actualNode;if(1!==n.nodeType||t.includeHidden)return!1;return!h.isVisible(n,!0)}(n,r))return"";var a=[l.arialabelledbyText,l.arialabelText,g.nativeTextAlternative,g.formControlValue,g.subtreeText,C,g.titleText].reduce(function(e,t){return r.startNode===n&&(e=g.sanitize(e)),""!==e?e:t(n,r)},"");return r.debug&&axe.log(a||"{empty-value}",t,r),a},g.accessibleTextVirtual.alreadyProcessed=function(e,t){return t.processed=t.processed||[],!!t.processed.includes(e)||(t.processed.push(e),!1)};var A=["textbox","progressbar","scrollbar","slider","spinbutton","combobox","listbox"];g.formControlValueMethods={nativeTextboxValue:function(e){if(e=e.actualNode||e,axe.commons.forms.isNativeTextbox(e))return e.value||"";return""},nativeSelectValue:function(e){return e=e.actualNode||e,axe.commons.forms.isNativeSelect(e)&&Array.from(e.options).filter(function(e){return e.selected}).map(function(e){return e.text}).join(" ")||""},ariaTextboxValue:function(e){var t=e.actualNode;if(!axe.commons.forms.isAriaTextbox(t))return"";return h.isHiddenWithCSS(t)?t.textContent:g.visibleVirtual(e,!0)},ariaListboxValue:function(e,t){var n=e.actualNode;if(!axe.commons.forms.isAriaListbox(n))return"";var r=l.getOwnedVirtual(e).filter(function(e){return"option"===l.getRole(e)&&"true"===e.actualNode.getAttribute("aria-selected")});return 0!==r.length?axe.commons.text.accessibleTextVirtual(r[0],t):""},ariaComboboxValue:function(e,t){var n,r=e.actualNode;return axe.commons.forms.isAriaCombobox(r)&&(n=l.getOwnedVirtual(e).filter(function(e){return"listbox"===l.getRole(e)})[0])?g.formControlValueMethods.ariaListboxValue(n,t):""},ariaRangeValue:function(e){if(e=e.actualNode||e,!axe.commons.forms.isAriaRange(e)||!e.hasAttribute("aria-valuenow"))return"";var t=+e.getAttribute("aria-valuenow");return isNaN(t)?"0":String(t)}},g.formControlValue=function(n,e){var r=1<arguments.length&&void 0!==e?e:{},t=n.actualNode,a=g.unsupported.accessibleNameFromFieldValue||[],o=l.getRole(t);if(r.startNode===n||!A.includes(o)||a.includes(o))return"";var i=Object.keys(g.formControlValueMethods).map(function(e){return g.formControlValueMethods[e]}).reduce(function(e,t){return e||t(n,r)},"");return r.debug&&axe.log(i||"{empty-value}",t,r),i},g.isHumanInterpretable=function(e){if(!e.length)return 0;if(["x","i"].includes(e))return 0;var t=g.removeUnicode(e,{emoji:!0,nonBmp:!0,punctuations:!0});return g.sanitize(t)?1:0};g.autocomplete={stateTerms:["on","off"],standaloneTerms:["name","honorific-prefix","given-name","additional-name","family-name","honorific-suffix","nickname","username","new-password","current-password","organization-title","organization","street-address","address-line1","address-line2","address-line3","address-level4","address-level3","address-level2","address-level1","country","country-name","postal-code","cc-name","cc-given-name","cc-additional-name","cc-family-name","cc-number","cc-exp","cc-exp-month","cc-exp-year","cc-csc","cc-type","transaction-currency","transaction-amount","language","bday","bday-day","bday-month","bday-year","sex","url","photo"],qualifiers:["home","work","mobile","fax","pager"],qualifiedTerms:["tel","tel-country-code","tel-national","tel-area-code","tel-local","tel-local-prefix","tel-local-suffix","tel-extension","email","impp"],locations:["billing","shipping"]},g.isValidAutocomplete=function(e,t){var n=1<arguments.length&&void 0!==t?t:{},r=n.looseTyped,a=void 0!==r&&r,o=n.stateTerms,i=void 0===o?[]:o,u=n.locations,s=void 0===u?[]:u,l=n.qualifiers,c=void 0===l?[]:l,d=n.standaloneTerms,m=void 0===d?[]:d,p=n.qualifiedTerms,f=void 0===p?[]:p;if(e=e.toLowerCase().trim(),(i=i.concat(g.autocomplete.stateTerms)).includes(e)||""===e)return!0;c=c.concat(g.autocomplete.qualifiers),s=s.concat(g.autocomplete.locations),m=m.concat(g.autocomplete.standaloneTerms),f=f.concat(g.autocomplete.qualifiedTerms);var h=e.split(/\s+/g);if(!a&&(8<h[0].length&&"section-"===h[0].substr(0,8)&&h.shift(),s.includes(h[0])&&h.shift(),c.includes(h[0])&&(h.shift(),m=[]),1!==h.length))return!1;var b=h[h.length-1];return m.includes(b)||f.includes(b)},g.labelText=function(e,t){var n=1<arguments.length&&void 0!==t?t:{},r=g.accessibleTextVirtual.alreadyProcessed;if(n.inControlContext||n.inLabelledByContext||r(e,n))return"";n.startNode||(n.startNode=e);var a,o=R({inControlContext:!0},n),i=function(e){var t=e.actualNode;return t.id?h.findElmsInContext({elm:"label",attr:"for",value:t.id,context:t}):[]}(e),u=h.findUpVirtual(e,"label");return u?(a=[].concat(he(i),[u])).sort(axe.utils.nodeSorter):a=i,a.map(function(e){return g.accessibleText(e,o)}).filter(function(e){return""!==e}).join(" ")},g.labelVirtual=function(e){var t,n;if(n=l.labelVirtual(e))return n;if(e.actualNode.id){var r=axe.utils.escapeSelector(e.actualNode.getAttribute("id"));if(n=(t=axe.commons.dom.getRootNode(e.actualNode).querySelector('label[for="'+r+'"]'))&&g.visible(t,!0))return n}return(n=(t=h.findUpVirtual(e,"label"))&&g.visible(t,!0))||null},g.label=function(e){return e=axe.utils.getNodeFromTree(e),g.labelVirtual(e)},g.nativeElementType=[{matches:[{nodeName:"textarea"},{nodeName:"input",properties:{type:["text","password","search","tel","email","url"]}}],namingMethods:"labelText"},{matches:{nodeName:"input",properties:{type:["button","submit","reset"]}},namingMethods:["valueText","titleText","buttonDefaultText"]},{matches:{nodeName:"input",properties:{type:"image"}},namingMethods:["altText","valueText","labelText","titleText","buttonDefaultText"]},{matches:"button",namingMethods:"subtreeText"},{matches:"fieldset",namingMethods:"fieldsetLegendText"},{matches:"OUTPUT",namingMethods:"subtreeText"},{matches:[{nodeName:"select"},{nodeName:"input",properties:{type:/^(?!text|password|search|tel|email|url|button|submit|reset)/}}],namingMethods:"labelText"},{matches:"summary",namingMethods:"subtreeText"},{matches:"figure",namingMethods:["figureText","titleText"]},{matches:"img",namingMethods:"altText"},{matches:"table",namingMethods:["tableCaptionText","tableSummaryText"]},{matches:["hr","br"],namingMethods:["titleText","singleSpace"]}],g.nativeTextAlternative=function(n,e){var r=1<arguments.length&&void 0!==e?e:{},t=n.actualNode;if(1!==t.nodeType||["presentation","none"].includes(l.getRole(t)))return"";var a=function(n){var e=g.nativeElementType,t=g.nativeTextMethods,r=e.find(function(e){var t=e.matches;return axe.commons.matches(n,t)});return(r?[].concat(r.namingMethods):[]).map(function(e){return t[e]})}(n).reduce(function(e,t){return e||t(n,r)},"");return r.debug&&axe.log(a||"{empty-value}",t,r),a};var F={submit:"Submit",image:"Submit",reset:"Reset",button:""};function j(e,t){return t.actualNode.getAttribute(e)||""}function z(e,t,n){var r=t.actualNode,a=[e=e.toLowerCase(),r.nodeName.toLowerCase()].join(","),o=r.querySelector(a);return o&&o.nodeName.toLowerCase()===e?g.accessibleText(o,n):""}g.nativeTextMethods={valueText:function(e){return e.actualNode.value||""},buttonDefaultText:function(e){var t=e.actualNode;return F[t.type]||""},tableCaptionText:z.bind(null,"caption"),figureText:z.bind(null,"figcaption"),fieldsetLegendText:z.bind(null,"legend"),altText:j.bind(null,"alt"),tableSummaryText:j.bind(null,"summary"),titleText:function(e,t){return g.titleText(e,t)},subtreeText:function(e,t){return g.subtreeText(e,t)},labelText:function(e,t){return g.labelText(e,t)},singleSpace:function(){return" "}},g.sanitize=function(e){"use strict";return e.replace(/\r\n/g,"\n").replace(/\u00A0/g," ").replace(/[\s]{2,}/g," ").trim()},g.subtreeText=function(e,t){var n=1<arguments.length&&void 0!==t?t:{},r=g.accessibleTextVirtual.alreadyProcessed;n.startNode=n.startNode||e;var a=n.strict;return r(e,n)||!l.namedFromContents(e,{strict:a})?"":l.getOwnedVirtual(e).reduce(function(e,t){return function(e,t,n){var r=t.actualNode.nodeName.toUpperCase(),a=g.accessibleTextVirtual(t,n);if(!a)return e;q.includes(r)||(" "!==a[0]&&(a+=" "),e&&" "!==e[e.length-1]&&(a=" "+a));return e+a}(e,t,n)},"")};var q=["A","EM","STRONG","SMALL","MARK","ABBR","DFN","I","B","S","U","CODE","VAR","SAMP","KBD","SUP","SUB","Q","CITE","SPAN","BDO","BDI","WBR","INS","DEL","MAP","AREA","NOSCRIPT","RUBY","BUTTON","LABEL","OUTPUT","DATALIST","KEYGEN","PROGRESS","COMMAND","CANVAS","TIME","METER","#TEXT"];var N=["button","iframe","a[href]",{nodeName:"input",properties:{type:"button"}}];function T(){return new RegExp("[ᴀ-ᵿᶀ-ᶿ᷀-᷿₠-⃐-℀-⅏⅐-←-⇿∀-⋿⌀-⏿␀-⑀-①-⓿─-╿▀-▟■-◿☀-⛿✀-➿]")}return g.titleText=function(e){return 1===(e=e.actualNode||e).nodeType&&e.hasAttribute("title")?!axe.commons.matches(e,N)&&["none","presentation"].includes(l.getRole(e))?"":e.getAttribute("title"):""},g.hasUnicode=function(e,t){var n=t.emoji,r=t.nonBmp,a=t.punctuations;return n?axe.imports.emojiRegexText().test(e):r?T().test(e):!!a&&/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,\-.\/:;<=>?@\[\]^_`{|}~]/g.test(e)},g.removeUnicode=function(e,t){var n=t.emoji,r=t.nonBmp,a=t.punctuations;return n&&(e=e.replace(axe.imports.emojiRegexText(),"")),r&&(e=e.replace(T(),"")),a&&(e=e.replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,\-.\/:;<=>?@\[\]^_`{|}~]/g,"")),e},g.unsupported={accessibleNameFromFieldValue:["combobox","listbox","progressbar"]},g.visibleVirtual=function(n,r,a){var e=n.children.map(function(e){if(3===e.actualNode.nodeType){var t=e.actualNode.nodeValue;if(t&&h.isVisible(n.actualNode,r))return t}else if(!a)return g.visibleVirtual(e,r)}).join("");return g.sanitize(e)},g.visible=function(e,t,n){return e=axe.utils.getNodeFromTree(e),g.visibleVirtual(e,t,n)},commons}()})}("object"==typeof window?window:this); \ No newline at end of file +!function a(window){function b(a){this.name="SupportError",this.cause=a.cause,this.message="`"+a.cause+"` - feature unsupported in your environment.",a.ruleId&&(this.ruleId=a.ruleId,this.message+=" Skipping "+this.ruleId+" rule."),this.stack=(new Error).stack}function c(a){"use strict";var b;return a?(b=axe.utils.clone(a),b.commons=a.commons):b={},b.reporter=b.reporter||null,b.rules=b.rules||[],b.checks=b.checks||[],b.data=Object.assign({checks:{},rules:{}},b.data),b}function d(a,b,c){"use strict";var d,e;for(d=0,e=a.length;d<e;d++)b[c](a[d])}function e(a){this.brand="axe",this.application="axeAPI",this.tagExclude=["experimental"],this.defaultConfig=a,this._init()}function f(a,b,c){var d=a.brand,e=a.application;return axe.constants.helpUrlBase+d+"/"+(c||axe.version.substring(0,axe.version.lastIndexOf(".")))+"/"+b+"?application="+e}function g(a){"use strict";this.id=a.id,this.data=null,this.relatedNodes=[],this.result=null}function h(a){"use strict";return"string"==typeof a?new Function("return "+a+";")():a}function i(a){a&&(this.id=a.id,this.configure(a))}function j(a,b){"use strict";if(!axe.utils.isHidden(b)){axe.utils.findBy(a,"node",b)||a.push({node:b,include:[],exclude:[]})}}function k(a,b,c){"use strict";a.frames=a.frames||[];var d,e,f=document.querySelectorAll(c.shift());a:for(var g=0,h=f.length;g<h;g++){e=f[g];for(var i=0,j=a.frames.length;i<j;i++)if(a.frames[i].node===e){a.frames[i][b].push(c);break a}d={node:e,include:[],exclude:[]},c&&d[b].push(c),a.frames.push(d)}}function l(a){"use strict";if(a&&"object"===(void 0===a?"undefined":ta(a))||a instanceof NodeList){if(a instanceof Node)return{include:[a],exclude:[]};if(a.hasOwnProperty("include")||a.hasOwnProperty("exclude"))return{include:a.include&&+a.include.length?a.include:[document],exclude:a.exclude||[]};if(a.length===+a.length)return{include:a,exclude:[]}}return"string"==typeof a?{include:[a],exclude:[]}:{include:[document],exclude:[]}}function m(a,b){"use strict";for(var c,d,e=[],f=0,g=a[b].length;f<g;f++){if("string"==typeof(c=a[b][f])){d=Array.from(document.querySelectorAll(c)),e=e.concat(d.map(function(a){return axe.utils.getFlattenedTree(a)[0]}));break}!c||!c.length||c instanceof Node?c instanceof Node&&e.push(axe.utils.getFlattenedTree(c)[0]):c.length>1?k(a,b,c):(d=Array.from(document.querySelectorAll(c[0])),e=e.concat(d.map(function(a){return axe.utils.getFlattenedTree(a)[0]})))}return e.filter(function(a){return a})}function n(a){"use strict";if(0===a.include.length){if(0===a.frames.length){var b=axe.utils.respondable.isInFrame()?"frame":"page";return new Error("No elements found for include in "+b+" Context")}a.frames.forEach(function(a,b){if(0===a.include.length)return new Error("No elements found for include in Context of frame "+b)})}}function o(a){"use strict";var b=this;this.frames=[],this.initiator=!a||"boolean"!=typeof a.initiator||a.initiator,this.page=!1,a=l(a),this.exclude=a.exclude,this.include=a.include,this.include=m(this,"include"),this.exclude=m(this,"exclude"),axe.utils.select("frame, iframe",this).forEach(function(a){ra(a,b)&&j(b.frames,a.actualNode)}),1===this.include.length&&this.include[0].actualNode===document.documentElement&&(this.page=!0);var c=n(this);if(c instanceof Error)throw c}function p(a){"use strict";this.id=a.id,this.result=axe.constants.NA,this.pageLevel=a.pageLevel,this.impact=null,this.nodes=[]}function q(a,b){"use strict";this._audit=b,this.id=a.id,this.selector=a.selector||"*",this.excludeHidden="boolean"!=typeof a.excludeHidden||a.excludeHidden,this.enabled="boolean"!=typeof a.enabled||a.enabled,this.pageLevel="boolean"==typeof a.pageLevel&&a.pageLevel,this.any=a.any||[],this.all=a.all||[],this.none=a.none||[],this.tags=a.tags||[],a.matches&&(this.matches=h(a.matches))}function r(a){"use strict";return axe.utils.getAllChecks(a).map(function(b){var c=a._audit.checks[b.id||b];return c&&"function"==typeof c.after?c:null}).filter(Boolean)}function s(a,b){"use strict";var c=[];return a.forEach(function(a){axe.utils.getAllChecks(a).forEach(function(a){a.id===b&&c.push(a)})}),c}function t(a){"use strict";return a.filter(function(a){return!0!==a.filtered})}function u(a){"use strict";var b=["any","all","none"],c=a.nodes.filter(function(a){var c=0;return b.forEach(function(b){a[b]=t(a[b]),c+=a[b].length}),c>0});return a.pageLevel&&c.length&&(c=[c.reduce(function(a,c){if(a)return b.forEach(function(b){a[b].push.apply(a[b],c[b])}),a})]),c}function v(a,b){"use strict";if(!axe._audit)throw new Error("No audit configured");var c=axe.utils.queue(),d=[];Object.keys(axe.plugins).forEach(function(a){c.defer(function(b){var c=function(a){d.push(a),b()};try{axe.plugins[a].cleanup(b,c)}catch(a){c(a)}})}),axe.utils.toArray(document.querySelectorAll("frame, iframe")).forEach(function(a){c.defer(function(b,c){return axe.utils.sendCommandToFrame(a,{command:"cleanup-plugin"},b,c)})}),c.then(function(c){0===d.length?a(c):b(d)}).catch(b)}function w(a){"use strict";var b;if(!(b=axe._audit))throw new Error("No audit configured");a.reporter&&("function"==typeof a.reporter||wa[a.reporter])&&(b.reporter=a.reporter),a.checks&&a.checks.forEach(function(a){b.addCheck(a)}),a.rules&&a.rules.forEach(function(a){b.addRule(a)}),void 0!==a.branding?b.setBranding(a.branding):b._constructHelpUrls(),a.tagExclude&&(b.tagExclude=a.tagExclude)}function x(a,b,c){"use strict";var d=c,e=function(a){a instanceof Error==!1&&(a=new Error(a)),c(a)},f=a&&a.context||{};f.include&&!f.include.length&&(f.include=[document]);var g=a&&a.options||{};switch(a.command){case"rules":return A(f,g,d,e);case"cleanup-plugin":return v(d,e);default:if(axe._audit&&axe._audit.commands&&axe._audit.commands[a.command])return axe._audit.commands[a.command](a,c)}}function y(a){"use strict";this._run=a.run,this._collect=a.collect,this._registry={},a.commands.forEach(function(a){axe._audit.registerCommand(a)})}function z(){"use strict";var a=axe._audit;if(!a)throw new Error("No audit configured");a.resetRulesAndChecks()}function A(a,b,c,d){"use strict";try{a=new o(a)}catch(a){return d(a)}var e=axe.utils.queue(),f=axe._audit;b.performanceTimer&&axe.utils.performanceTimer.auditStart(),a.frames.length&&!1!==b.iframes&&e.defer(function(c,d){axe.utils.collectResultsFromFrames(a,b,"rules",null,c,d)}),e.defer(function(c,d){if(b.restoreScroll){var e=axe.utils.getScrollState();f.run(a,b,c,d),axe.utils.setScrollState(e)}else f.run(a,b,c,d)}),e.then(function(e){try{b.performanceTimer&&axe.utils.performanceTimer.auditEnd();var g=axe.utils.mergeResults(e.map(function(a){return{results:a}}));a.initiator&&(g=f.after(g,b),g.forEach(axe.utils.publishMetaData),g=g.map(axe.utils.finalizeRuleResult));try{c(g)}catch(a){axe.log(a)}}catch(a){d(a)}}).catch(d)}function B(a){"use strict";switch(!0){case"string"==typeof a:case Array.isArray(a):case Node&&a instanceof Node:case NodeList&&a instanceof NodeList:return!0;case"object"!==(void 0===a?"undefined":ta(a)):return!1;case void 0!==a.include:case void 0!==a.exclude:case"number"==typeof a.length:return!0;default:return!1}}function C(a,b,c){"use strict";var d=new TypeError("axe.run arguments are invalid");if(!B(a)){if(void 0!==c)throw d;c=b,b=a,a=document}if("object"!==(void 0===b?"undefined":ta(b))){if(void 0!==c)throw d;c=b,b={}}if("function"!=typeof c&&void 0!==c)throw d;return{context:a,options:b,callback:c||xa}}function D(a,b){"use strict";["any","all","none"].forEach(function(c){Array.isArray(a[c])&&a[c].filter(function(a){return Array.isArray(a.relatedNodes)}).forEach(function(a){a.relatedNodes=a.relatedNodes.map(function(a){var c={html:a.source};return b.elementRef&&!a.fromFrame&&(c.element=a.element),(!1!==b.selectors||a.fromFrame)&&(c.target=a.selector),b.xpath&&(c.xpath=a.xpath),c})})})}function E(a,b){return Aa.reduce(function(c,d){return c[d]=(a[d]||[]).map(function(a){return b(a,d)}),c},{})}function F(a,b,c){var d=Object.assign({},b);d.nodes=(d[c]||[]).concat(),axe.constants.resultGroups.forEach(function(a){delete d[a]}),a[c].push(d)}function G(a,b,c){"use strict";var d=window.getComputedStyle(a,null),e=!1;return!!d&&(b.forEach(function(a){d.getPropertyValue(a.property)===a.value&&(e=!0)}),!!e||!(a.nodeName.toUpperCase()===c.toUpperCase()||!a.parentNode)&&G(a.parentNode,b,c))}function H(a,b){"use strict";return new Error(a+": "+axe.utils.getSelector(b))}function I(a,b,c,d,e,f){"use strict";var g=axe.utils.queue();a.frames.forEach(function(e){var f={options:b,command:c,parameter:d,context:{initiator:!1,page:a.page,include:e.include||[],exclude:e.exclude||[]}};g.defer(function(a,b){var c=e.node;axe.utils.sendCommandToFrame(c,f,function(b){if(b)return a({results:b,frameElement:c,frame:axe.utils.getSelector(c)});a(null)},b)})}),g.then(function(a){e(axe.utils.mergeResults(a,b))}).catch(f)}function J(a,b){if(b=b||300,a.length>b){var c=a.indexOf(">");a=a.substring(0,c+1)}return a}function K(a){var b=a.outerHTML;return b||"function"!=typeof XMLSerializer||(b=(new XMLSerializer).serializeToString(a)),J(b||"")}function L(a,b,c){this._fromFrame=!!c,this.spec=c||{},b&&b.absolutePaths&&(this._options={toRoot:!0}),this.source=void 0!==this.spec.source?this.spec.source:K(a),this._element=a}function M(a,b){return{shadowId:b,children:[],actualNode:a}}function N(a){var b=[];for(a=a.firstChild;a;)b.push(a),a=a.nextSibling;return b}function O(){var a=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";return 0!==a.length&&(a.match(/[0-9]/g)||"").length>=a.length/2}function P(a,b){return[a.substring(0,b),a.substring(b)]}function Q(a){var b=a,c="",d="",e="",f="",g="",h="";if(a.includes("#")){var i=P(a,a.indexOf("#")),j=Ba(i,2);a=j[0],h=j[1]}if(a.includes("?")){var k=P(a,a.indexOf("?")),l=Ba(k,2);a=l[0],g=l[1]}if(a.includes("://")){var m=a.split("://"),n=Ba(m,2);c=n[0],a=n[1];var o=P(a,a.indexOf("/")),p=Ba(o,2);d=p[0],a=p[1]}else if("//"===a.substr(0,2)){a=a.substr(2);var q=P(a,a.indexOf("/")),r=Ba(q,2);d=r[0],a=r[1]}if("www."===d.substr(0,4)&&(d=d.substr(4)),d&&d.includes(":")){var s=P(d,d.indexOf(":")),t=Ba(s,2);d=t[0],e=t[1]}return f=a,{original:b,protocol:c,domain:d,port:e,path:f,query:g,hash:h}}function R(a){if(Array.isArray(a)){for(var b=0,c=Array(a.length);b<a.length;b++)c[b]=a[b];return c}return Array.from(a)}function S(a){return!["focus","hover","hidden","visible","dirty","touched","valid","disable","enable","active","col-"].find(function(b){return a.includes(b)})}function T(a){return a.classList&&0!==a.classList.length?(a.parentNode&&Array.from(a.parentNode.children||"")||[]).reduce(function(b,c){return a===c?b:b.filter(function(a){return!c.classList.contains(a)})},Array.from(a.classList).filter(S)):[]}function U(a,b){var c=a.parentNode&&Array.from(a.parentNode.children||"")||[];if(c.find(function(c){return c!==a&&axe.utils.matchesSelector(c,b)}))return":nth-child("+(1+c.indexOf(a))+")";return""}function V(a,b){var c=a.nodeName.toLowerCase(),d=Array.from(a.classList)||[],e={nodeName:c,classList:d,isCustomElm:c.includes("-"),isCommonElm:Da.includes(c),distinctClassList:T(a)};return[Ea.getCustomElm,Ea.getElmRoleProp,Ea.getUncommonElm,Ea.getElmNameProp,Ea.getDistinctClass,Ea.getFileRefProp,Ea.getCommonName].reduce(function(c,d){if(c.length===b)return c;var f=d(a,e);return f&&(f[0].match(/[a-z]/)?c.unshift(f):c.push(f)),c},[])}function W(a,b,c){var d=void 0,e=void 0,f=b.isUnique,g=void 0!==f&&f,h=Ea.getElmId(a),i=b.featureCount,j=void 0===i?2:i,k=b.minDepth,l=void 0===k?1:k,m=b.toRoot,n=void 0!==m&&m,o=b.childSelectors,p=void 0===o?[]:o;h?(d=h,g=!0):(d=V(a,j).join(""),d+=U(a,d),g=b.isUnique||1===c.querySelectorAll(d).length,g||a!==document.documentElement||(d+=":root"),e=0!==l||!g);var q=[d].concat(R(p));return a.parentElement&&11!==a.parentElement.nodeType&&(n||e)?W(a.parentNode,{toRoot:n,isUnique:g,childSelectors:q,featureCount:1,minDepth:l-1},c):q.join(" > ")}function X(a,b){var c,d;if(!a)return[];if(!b&&9===a.nodeType)return b=[{str:"html"}];if(b=b||[],a.parentNode&&a.parentNode!==a&&(b=X(a.parentNode,b)),a.previousSibling){d=1,c=a.previousSibling;do{1===c.nodeType&&c.nodeName===a.nodeName&&d++,c=c.previousSibling}while(c);1===d&&(d=null)}else if(a.nextSibling){c=a.nextSibling;do{1===c.nodeType&&c.nodeName===a.nodeName?(d=1,c=null):(d=null,c=c.previousSibling)}while(c)}if(1===a.nodeType){var e={};e.str=a.nodeName.toLowerCase();var f=a.getAttribute&&axe.utils.escapeSelector(a.getAttribute("id"));f&&1===a.ownerDocument.querySelectorAll("#"+f).length&&(e.id=a.getAttribute("id")),d>1&&(e.count=d),b.push(e)}return b}function Y(a){return a.reduce(function(a,b){return b.id?"/"+b.str+"[@id='"+b.id+"']":a+"/"+b.str+(b.count>0?"["+b.count+"]":"")},"")}function Z(a){"use strict";if(Fa&&Fa.parentNode)return void 0===Fa.styleSheet?Fa.appendChild(document.createTextNode(a)):Fa.styleSheet.cssText+=a,Fa;if(a){var b=document.head||document.getElementsByTagName("head")[0];return Fa=document.createElement("style"),Fa.type="text/css",void 0===Fa.styleSheet?Fa.appendChild(document.createTextNode(a)):Fa.styleSheet.cssText=a,b.appendChild(Fa),Fa}}function $(a,b,c,d){"use strict";var e=axe.utils.getXpath(c),f={element:c,selector:d,xpath:e};a.forEach(function(a){a.node=axe.utils.DqElement.fromFrame(a.node,b,f);var c=axe.utils.getAllChecks(a);c.length&&c.forEach(function(a){a.relatedNodes=a.relatedNodes.map(function(a){return axe.utils.DqElement.fromFrame(a,b,f)})})})}function _(a,b){"use strict";for(var c,d,e=b[0].node,f=0,g=a.length;f<g;f++)if(d=a[f].node,(c=axe.utils.nodeSorter({actualNode:d.element},{actualNode:e.element}))>0||0===c&&e.selector.length<d.selector.length)return void a.splice.apply(a,[f,0].concat(b));a.push.apply(a,b)}function aa(a){"use strict";return a&&a.results?Array.isArray(a.results)?a.results.length?a.results:null:[a.results]:null}function ba(a,b){function c(a){return a.incomplete&&a.incomplete.default?a.incomplete.default:ua.incompleteFallbackMessage()}if(!a||!a.missingData)return c(b);try{var d=b.incomplete[a.missingData[0].reason];if(!d)throw new Error;return d}catch(d){return"string"==typeof a.missingData?b.incomplete[a.missingData]:c(b)}}function ca(a,b){"use strict";return function(c){var d=a[c.id]||{},e=d.messages||{},f=Object.assign({},d);delete f.messages,void 0===c.result?"object"===ta(e.incomplete)?f.message=function(){return ba(c.data,e)}:f.message=e.incomplete:f.message=c.result===b?e.pass:e.fail,axe.utils.extendMetaData(c,f)}}function da(a,b){return 1===a.nodeType&&("*"===b.tag||a.nodeName.toLowerCase()===b.tag)}function ea(a,b){return!b.classes||b.classes.reduce(function(b,c){return b&&a.className&&a.className.match(c.regexp)},!0)}function fa(a,b){return!b.attributes||b.attributes.reduce(function(b,c){var d=a.getAttribute(c.key);return b&&null!==d&&(!c.value||c.test(d))},!0)}function ga(a,b){return!b.id||a.id===b.id}function ha(a,b){return!(b.pseudos&&!b.pseudos.reduce(function(b,c){if("not"===c.name)return b&&!Ha([a],c.expressions,!1).length;throw new Error("the pseudo selector "+c.name+" has not yet been implemented")},!0))}function ia(a,b,c){var d=[];return a=Array.isArray(a)?a:[a],a.forEach(function(a){da(a.actualNode,b)&&ea(a.actualNode,b)&&fa(a.actualNode,b)&&ga(a.actualNode,b)&&ha(a,b)&&d.push(a),c&&(d=d.concat(ia(a.children.filter(function(c){return!b.id||c.shadowId===a.shadowId}),b,c)))}),d}function ja(a){/*! Credit Mootools Copyright Mootools, MIT License */ +if(a)return a.map(function(a){var b,c,d=a.name.replace(Ja,""),e=(a.value||"").replace(Ja,"");switch(a.operator){case"^=":c=new RegExp("^"+Ia(e));break;case"$=":c=new RegExp(Ia(e)+"$");break;case"~=":c=new RegExp("(^|\\s)"+Ia(e)+"(\\s|$)");break;case"|=":c=new RegExp("^"+Ia(e)+"(-|$)");break;case"=":b=function(a){return e===a};break;case"*=":b=function(a){return a&&a.indexOf(e)>-1};break;case"!=":b=function(a){return e!==a};break;default:b=function(a){return!!a}}return""===e&&/^[*$^]=$/.test(a.operator)&&(b=function(){return!1}),b||(b=function(a){return a&&c.test(a)}),{key:d,value:e,test:b}})}function ka(a){if(a)return a.map(function(a){return a=a.replace(Ja,""),{value:a,regexp:new RegExp("(^|\\s)"+Ia(a)+"(\\s|$)")}})}function la(a){if(a)return a.map(function(a){var b;return"not"===a.name&&(b=axe.utils.cssParser.parse(a.value),b=b.selectors?b.selectors:[b],b=Ga(b)),{name:a.name,expressions:b,value:a.value}})}function ma(a,b){"use strict";var c,d,e=axe._audit&&axe._audit.tagExclude?axe._audit.tagExclude:[];return b.include||b.exclude?(c=b.include||[],c=Array.isArray(c)?c:[c],d=b.exclude||[],d=Array.isArray(d)?d:[d],d=d.concat(e.filter(function(a){return-1===c.indexOf(a)}))):(c=Array.isArray(b)?b:[b],d=e.filter(function(a){return-1===c.indexOf(a)})),!!(c.some(function(b){return-1!==a.tags.indexOf(b)})||0===c.length&&!1!==a.enabled)&&d.every(function(b){return-1===a.tags.indexOf(b)})}function na(a){var b=window.getComputedStyle(a),c="visible"===b.getPropertyValue("overflow-y"),d="visible"===b.getPropertyValue("overflow-x");if(!c&&a.scrollHeight>a.clientHeight||!d&&a.scrollWidth>a.clientWidth)return{elm:a,top:a.scrollTop,left:a.scrollLeft}}function oa(a,b,c){if(a===window)return a.scroll(b,c);a.scrollTop=b,a.scrollLeft=c}function pa(a){return Array.from(a.children).reduce(function(a,b){var c=na(b);return c&&a.push(c),a.concat(pa(b))},[])}function qa(a){"use strict";return a.sort(function(a,b){return axe.utils.contains(a,b)?1:-1})[0]}function ra(a,b){"use strict";var c=b.include&&qa(b.include.filter(function(b){return axe.utils.contains(b,a)})),d=b.exclude&&qa(b.exclude.filter(function(b){return axe.utils.contains(b,a)}));return!!(!d&&c||d&&axe.utils.contains(d,c))}function sa(a,b,c){"use strict";for(var d=0,e=b.length;d<e;d++)!a.find(function(a){return a.actualNode===b[d].actualNode})&&ra(b[d],c)&&a.push(b[d])}var document=window.document,ta="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},axe=axe||{};axe.version="3.0.0-alpha-1","function"==typeof define&&define.amd&&define([],function(){"use strict";return axe}),"object"===("undefined"==typeof module?"undefined":ta(module))&&module.exports&&"function"==typeof a.toString&&(axe.source="("+a.toString()+')(typeof window === "object" ? window : this);',module.exports=axe),"function"==typeof window.getComputedStyle&&(window.axe=axe);var commons;b.prototype=Object.create(Error.prototype),b.prototype.constructor=b;var utils=axe.utils={},ua={},ta="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a};e.prototype._init=function(){var a=c(this.defaultConfig);axe.commons=commons=a.commons,this.reporter=a.reporter,this.commands={},this.rules=[],this.checks={},d(a.rules,this,"addRule"),d(a.checks,this,"addCheck"),this.data={},this.data.checks=a.data&&a.data.checks||{},this.data.rules=a.data&&a.data.rules||{},this.data.failureSummaries=a.data&&a.data.failureSummaries||{},this.data.incompleteFallbackMessage=a.data&&a.data.incompleteFallbackMessage||"",this._constructHelpUrls()},e.prototype.registerCommand=function(a){"use strict";this.commands[a.id]=a.callback},e.prototype.addRule=function(a){"use strict";a.metadata&&(this.data.rules[a.id]=a.metadata);var b=this.getRule(a.id);b?b.configure(a):this.rules.push(new q(a,this))},e.prototype.addCheck=function(a){"use strict";var b=a.metadata;"object"===(void 0===b?"undefined":ta(b))&&(this.data.checks[a.id]=b,"object"===ta(b.messages)&&Object.keys(b.messages).filter(function(a){return b.messages.hasOwnProperty(a)&&"string"==typeof b.messages[a]}).forEach(function(a){0===b.messages[a].indexOf("function")&&(b.messages[a]=new Function("return "+b.messages[a]+";")())})),this.checks[a.id]?this.checks[a.id].configure(a):this.checks[a.id]=new i(a)},e.prototype.run=function(a,b,c,d){"use strict";this.validateOptions(b),axe._tree=axe.utils.getFlattenedTree(document.documentElement);var e=axe.utils.queue();this.rules.forEach(function(c){if(axe.utils.ruleShouldRun(c,a,b)){if(b.performanceTimer){var d="mark_rule_end_"+c.id,f="mark_rule_start_"+c.id;axe.utils.performanceTimer.mark(f)}e.defer(function(e,g){c.run(a,b,function(a){b.performanceTimer&&(axe.utils.performanceTimer.mark(d),axe.utils.performanceTimer.measure("rule_"+c.id,f,d)),e(a)},function(a){if(b.debug)g(a);else{var d=Object.assign(new p(c),{result:axe.constants.CANTTELL,description:"An error occured while running this rule",message:a.message,stack:a.stack,error:a});e(d)}})})}}),e.then(function(a){axe._tree=void 0,c(a.filter(function(a){return!!a}))}).catch(d)},e.prototype.after=function(a,b){"use strict";var c=this.rules;return a.map(function(a){return axe.utils.findBy(c,"id",a.id).after(a,b)})},e.prototype.getRule=function(a){return this.rules.find(function(b){return b.id===a})},e.prototype.validateOptions=function(a){"use strict";var b=this;if("object"===ta(a.runOnly)){var c=a.runOnly;if("rule"===c.type&&Array.isArray(c.value))c.value.forEach(function(a){if(!b.getRule(a))throw new Error("unknown rule `"+a+"` in options.runOnly")});else if(Array.isArray(c.value)&&c.value.length>0){var d=[].concat(c.value);if(b.rules.forEach(function(a){var b,c,e;if(d)for(c=0,e=a.tags.length;c<e;c++)-1!==(b=d.indexOf(a.tags[c]))&&d.splice(b,1)}),0!==d.length)throw new Error("could not find tags `"+d.join("`, `")+"`")}}return"object"===ta(a.rules)&&Object.keys(a.rules).forEach(function(a){if(!b.getRule(a))throw new Error("unknown rule `"+a+"` in options.rules")}),a},e.prototype.setBranding=function(a){"use strict";var b={brand:this.brand,application:this.application};a&&a.hasOwnProperty("brand")&&a.brand&&"string"==typeof a.brand&&(this.brand=a.brand),a&&a.hasOwnProperty("application")&&a.application&&"string"==typeof a.application&&(this.application=a.application),this._constructHelpUrls(b)},e.prototype._constructHelpUrls=function(){var a=this,b=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,c=axe.version.substring(0,axe.version.lastIndexOf("."));this.rules.forEach(function(d){a.data.rules[d.id]||(a.data.rules[d.id]={});var e=a.data.rules[d.id];("string"!=typeof e.helpUrl||b&&e.helpUrl===f(b,d.id,c))&&(e.helpUrl=f(a,d.id,c))})},e.prototype.resetRulesAndChecks=function(){"use strict";this._init()},i.prototype.enabled=!0,i.prototype.run=function(a,b,c,d){"use strict";b=b||{};var e=b.hasOwnProperty("enabled")?b.enabled:this.enabled,f=b.options||this.options;if(e){var h,i=new g(this),j=axe.utils.checkHelper(i,b,c,d);try{h=this.evaluate.call(j,a.actualNode,f,a)}catch(a){return void d(a)}j.isAsync||(i.result=h,setTimeout(function(){c(i)},0))}else c(null)},i.prototype.configure=function(a){var b=this;["options","enabled"].filter(function(b){return a.hasOwnProperty(b)}).forEach(function(c){return b[c]=a[c]}),["evaluate","after"].filter(function(b){return a.hasOwnProperty(b)}).forEach(function(c){return b[c]=h(a[c])})};var ta="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a};q.prototype.matches=function(){"use strict";return!0},q.prototype.gather=function(a){"use strict";var b=axe.utils.select(this.selector,a);return this.excludeHidden?b.filter(function(a){return!axe.utils.isHidden(a.actualNode)}):b},q.prototype.runChecks=function(a,b,c,d,e){"use strict";var f=this,g=axe.utils.queue();this[a].forEach(function(a){var d=f._audit.checks[a.id||a],e=axe.utils.getCheckOption(d,f.id,c);g.defer(function(a,c){d.run(b,e,a,c)})}),g.then(function(b){b=b.filter(function(a){return a}),d({type:a,results:b})}).catch(e)},q.prototype.run=function(a,c,d,e){var f=this,g=axe.utils.queue(),h=new p(this),i=void 0;try{i=this.gather(a).filter(function(a){return f.matches(a.actualNode,a)})}catch(a){return void e(new b({cause:a,ruleId:this.id}))}c.performanceTimer&&axe.log("gather (",i.length,"):",axe.utils.performanceTimer.timeElapsed()+"ms"),i.forEach(function(a){g.defer(function(b,d){var e=axe.utils.queue();e.defer(function(b,d){f.runChecks("any",a,c,b,d)}),e.defer(function(b,d){f.runChecks("all",a,c,b,d)}),e.defer(function(b,d){f.runChecks("none",a,c,b,d)}),e.then(function(d){if(d.length){var e=!1,f={};d.forEach(function(a){var b=a.results.filter(function(a){return a});f[a.type]=b,b.length&&(e=!0)}),e&&(f.node=new axe.utils.DqElement(a.actualNode,c),h.nodes.push(f))}b()}).catch(function(a){return d(a)})})}),g.then(function(){return d(h)}).catch(function(a){return e(a)})},q.prototype.after=function(a,b){"use strict";var c=r(this),d=this.id;return c.forEach(function(c){var e=s(a.nodes,c.id),f=axe.utils.getCheckOption(c,d,b),g=c.after(e,f);e.forEach(function(a){-1===g.indexOf(a)&&(a.filtered=!0)})}),a.nodes=u(a),a},q.prototype.configure=function(a){"use strict";a.hasOwnProperty("selector")&&(this.selector=a.selector),a.hasOwnProperty("excludeHidden")&&(this.excludeHidden="boolean"!=typeof a.excludeHidden||a.excludeHidden),a.hasOwnProperty("enabled")&&(this.enabled="boolean"!=typeof a.enabled||a.enabled),a.hasOwnProperty("pageLevel")&&(this.pageLevel="boolean"==typeof a.pageLevel&&a.pageLevel),a.hasOwnProperty("any")&&(this.any=a.any),a.hasOwnProperty("all")&&(this.all=a.all),a.hasOwnProperty("none")&&(this.none=a.none),a.hasOwnProperty("tags")&&(this.tags=a.tags),a.hasOwnProperty("matches")&&("string"==typeof a.matches?this.matches=new Function("return "+a.matches+";")():this.matches=a.matches)},function(axe){var a=[{name:"NA",value:"inapplicable",priority:0,group:"inapplicable"},{name:"PASS",value:"passed",priority:1,group:"passes"},{name:"CANTTELL",value:"cantTell",priority:2,group:"incomplete"},{name:"FAIL",value:"failed",priority:3,group:"violations"}],b={helpUrlBase:"https://dequeuniversity.com/rules/",results:[],resultGroups:[],resultGroupMap:{},impact:Object.freeze(["minor","moderate","serious","critical"])};a.forEach(function(a){var c=a.name,d=a.value,e=a.priority,f=a.group;b[c]=d,b[c+"_PRIO"]=e,b[c+"_GROUP"]=f,b.results[e]=d,b.resultGroups[e]=f,b.resultGroupMap[d]=f}),Object.freeze(b.results),Object.freeze(b.resultGroups),Object.freeze(b.resultGroupMap),Object.freeze(b),Object.defineProperty(axe,"constants",{value:b,enumerable:!0,configurable:!1,writable:!1})}(axe);var ta="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a};axe.log=function(){"use strict";"object"===("undefined"==typeof console?"undefined":ta(console))&&console.log&&Function.prototype.apply.call(console.log,console,arguments)};var ta="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a};axe.a11yCheck=function(a,b,c){"use strict";"function"==typeof b&&(c=b,b={}),b&&"object"===(void 0===b?"undefined":ta(b))||(b={});var d=axe._audit;if(!d)throw new Error("No audit configured");b.reporter=b.reporter||d.reporter||"v2",b.performanceTimer&&axe.utils.performanceTimer.start();var e=axe.getReporter(b.reporter);axe._runRules(a,b,function(a){var d=e(a,b,c);void 0!==d&&(b.performanceTimer&&axe.utils.performanceTimer.end(),c(d))},axe.log)},axe.cleanup=v,axe.configure=w,axe.getRules=function(a){"use strict";a=a||[];var b=a.length?axe._audit.rules.filter(function(b){return!!a.filter(function(a){return-1!==b.tags.indexOf(a)}).length}):axe._audit.rules,c=axe._audit.data.rules||{};return b.map(function(a){var b=c[a.id]||{};return{ruleId:a.id,description:b.description,help:b.help,helpUrl:b.helpUrl,tags:a.tags}})},axe._load=function(a){"use strict";axe.utils.respondable.subscribe("axe.ping",function(a,b,c){c({axe:!0})}),axe.utils.respondable.subscribe("axe.start",x),axe._audit=new e(a)};var axe=axe||{};axe.plugins={},y.prototype.run=function(){"use strict";return this._run.apply(this,arguments)},y.prototype.collect=function(){"use strict";return this._collect.apply(this,arguments)},y.prototype.cleanup=function(a){"use strict";var b=axe.utils.queue(),c=this;Object.keys(this._registry).forEach(function(a){b.defer(function(b){c._registry[a].cleanup(b)})}),b.then(function(){a()})},y.prototype.add=function(a){"use strict";this._registry[a.id]=a},axe.registerPlugin=function(a){"use strict";axe.plugins[a.id]=new y(a)};var va,wa={};axe.getReporter=function(a){"use strict";return"string"==typeof a&&wa[a]?wa[a]:"function"==typeof a?a:va},axe.addReporter=function(a,b,c){"use strict";wa[a]=b,c&&(va=b)},axe.reset=z,axe._runRules=A;var ta="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},xa=function(){};axe.run=function(a,b,c){"use strict";if(!axe._audit)throw new Error("No audit configured");var d=C(a,b,c);a=d.context,b=d.options,c=d.callback,b.reporter=b.reporter||axe._audit.reporter||"v1",b.performanceTimer&&axe.utils.performanceTimer.start();var e=void 0,f=xa,g=xa;return window.Promise&&c===xa&&(e=new Promise(function(a,b){f=b,g=a})),axe._runRules(a,b,function(a){var d=function(a){try{c(null,a)}catch(a){axe.log(a)}g(a)};b.performanceTimer&&axe.utils.performanceTimer.end();try{var e=axe.getReporter(b.reporter),h=e(a,b,d);void 0!==h&&d(h)}catch(a){c(a),f(a)}},function(a){c(a),f(a)}),e},ua.failureSummary=function(a){"use strict";var b={};return b.none=a.none.concat(a.all),b.any=a.any,Object.keys(b).map(function(a){if(b[a].length){var c=axe._audit.data.failureSummaries[a];return c&&"function"==typeof c.failureMessage?c.failureMessage(b[a].map(function(a){return a.message||""})):void 0}}).filter(function(a){return void 0!==a}).join("\n\n")},ua.incompleteFallbackMessage=function(){"use strict";return axe._audit.data.incompleteFallbackMessage()};var ta="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},ya=axe.constants.resultGroups;ua.processAggregate=function(a,b){var c=axe.utils.aggregateResult(a);return c.timestamp=(new Date).toISOString(),c.url=window.location.href,ya.forEach(function(a){c[a]=(c[a]||[]).map(function(a){return a=Object.assign({},a),Array.isArray(a.nodes)&&a.nodes.length>0&&(a.nodes=a.nodes.map(function(a){return"object"===ta(a.node)&&(a.html=a.node.source,b.elementRef&&!a.node.fromFrame&&(a.element=a.node.element),(!1!==b.selectors||a.node.fromFrame)&&(a.target=a.node.selector),b.xpath&&(a.xpath=a.node.xpath)),delete a.result,delete a.node,D(a,b),a})),ya.forEach(function(b){return delete a[b]}),delete a.pageLevel,delete a.result,a})}),c},axe.addReporter("na",function(a,b,c){"use strict";"function"==typeof b&&(c=b,b={});var d=ua.processAggregate(a,b);c({violations:d.violations,passes:d.passes,incomplete:d.incomplete,inapplicable:d.inapplicable,timestamp:d.timestamp,url:d.url})}),axe.addReporter("no-passes",function(a,b,c){"use strict";"function"==typeof b&&(c=b,b={});var d=ua.processAggregate(a,b);c({violations:d.violations,timestamp:d.timestamp,url:d.url})}),axe.addReporter("raw",function(a,b,c){"use strict";"function"==typeof b&&(c=b,b={}),c(a)}),axe.addReporter("v1",function(a,b,c){"use strict";"function"==typeof b&&(c=b,b={});var d=ua.processAggregate(a,b);d.violations.forEach(function(a){return a.nodes.forEach(function(a){a.failureSummary=ua.failureSummary(a)})}),c({violations:d.violations,passes:d.passes,incomplete:d.incomplete,inapplicable:d.inapplicable,timestamp:d.timestamp,url:d.url})}),axe.addReporter("v2",function(a,b,c){"use strict";"function"==typeof b&&(c=b,b={});var d=ua.processAggregate(a,b);c({violations:d.violations,passes:d.passes,incomplete:d.incomplete,inapplicable:d.inapplicable,timestamp:d.timestamp,url:d.url})},!0),axe.utils.aggregate=function(a,b,c){b=b.slice(),c&&b.push(c);var d=b.map(function(b){return a.indexOf(b)}).sort();return a[d.pop()]};var za=[];za[axe.constants.PASS_PRIO]=!0,za[axe.constants.CANTTELL_PRIO]=null,za[axe.constants.FAIL_PRIO]=!1;var Aa=["any","all","none"];axe.utils.aggregateChecks=function(a){var b=Object.assign({},a);E(b,function(a,b){var c=za.indexOf(a.result);a.priority=-1!==c?c:axe.constants.CANTTELL_PRIO,"none"===b&&(a.priority=4-a.priority)});var c=E(b,function(a){return a.priority});b.priority=Math.max(c.all.reduce(function(a,b){return Math.max(a,b)},0),c.none.reduce(function(a,b){return Math.max(a,b)},0),c.any.reduce(function(a,b){return Math.min(a,b)},4)%4);var d=[];return Aa.forEach(function(a){b[a]=b[a].filter(function(a){return a.priority===b.priority}),b[a].forEach(function(a){return d.push(a.impact)})}),b.priority===axe.constants.FAIL_PRIO?b.impact=axe.utils.aggregate(axe.constants.impact,d):b.impact=null,E(b,function(a){delete a.result,delete a.priority}),b.result=axe.constants.results[b.priority],delete b.priority,b},axe.utils.aggregateResult=function(a){var b={};return axe.constants.resultGroups.forEach(function(a){return b[a]=[]}),a.forEach(function(a){a.error?F(b,a,axe.constants.CANTTELL_GROUP):a.result===axe.constants.NA?F(b,a,axe.constants.NA_GROUP):axe.constants.resultGroups.forEach(function(c){Array.isArray(a[c])&&a[c].length>0&&F(b,a,c)})}),b},function(){axe.utils.aggregateRule=function(a){var b={};a=a.map(function(a){if(a.any&&a.all&&a.none)return axe.utils.aggregateChecks(a);if(Array.isArray(a.node))return axe.utils.finalizeRuleResult(a);throw new TypeError("Invalid Result type")});var c=a.map(function(a){return a.result});b.result=axe.utils.aggregate(axe.constants.results,c,b.result),axe.constants.resultGroups.forEach(function(a){return b[a]=[]}),a.forEach(function(a){var c=axe.constants.resultGroupMap[a.result];b[c].push(a)});var d=axe.constants.FAIL_GROUP;if(b[d].length>0){var e=b[d].map(function(a){return a.impact});b.impact=axe.utils.aggregate(axe.constants.impact,e)||null}else b.impact=null;return b}}(),axe.utils.areStylesSet=G,axe.utils.checkHelper=function(a,b,c,d){"use strict";return{isAsync:!1,async:function(){return this.isAsync=!0,function(b){b instanceof Error==!1?(a.value=b,c(a)):d(b)}},data:function(b){a.data=b},relatedNodes:function(c){c=c instanceof Node?[c]:axe.utils.toArray(c),a.relatedNodes=c.map(function(a){return new axe.utils.DqElement(a,b)})}}};var ta="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a};axe.utils.clone=function(a){"use strict";var b,c,d=a;if(null!==a&&"object"===(void 0===a?"undefined":ta(a)))if(Array.isArray(a))for(d=[],b=0,c=a.length;b<c;b++)d[b]=axe.utils.clone(a[b]);else{d={};for(b in a)d[b]=axe.utils.clone(a[b])}return d},axe.utils.sendCommandToFrame=function(a,b,c,d){"use strict";var e=a.contentWindow;if(!e)return axe.log("Frame does not have a content window",a),void c(null);var f=setTimeout(function(){f=setTimeout(function(){var e=H("No response from frame",a);b.debug?d(e):(axe.log(e),c(null))},0)},500);axe.utils.respondable(e,"axe.ping",null,void 0,function(){clearTimeout(f),f=setTimeout(function(){d(H("Axe in frame timed out",a))},3e4),axe.utils.respondable(e,"axe.start",b,void 0,function(a){clearTimeout(f),a instanceof Error==!1?c(a):d(a)})})},axe.utils.collectResultsFromFrames=I,axe.utils.contains=function(a,b){"use strict";function c(a,b){return a.shadowId===b.shadowId||!!a.children.find(function(a){return c(a,b)})}return a.shadowId||b.shadowId?c(a,b):"function"==typeof a.actualNode.contains?a.actualNode.contains(b.actualNode):!!(16&a.actualNode.compareDocumentPosition(b.actualNode))},function(axe){/*! + * The copyright below covers the code within this function block only + * + * Copyright (c) 2013 Dulin Marat + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +function a(){this.pseudos={},this.attrEqualityMods={},this.ruleNestingOperators={},this.substitutesEnabled=!1}function b(a){return a>="a"&&a<="z"||a>="A"&&a<="Z"||"-"===a||"_"===a}function c(a){return a>="a"&&a<="z"||a>="A"&&a<="Z"||a>="0"&&a<="9"||"-"===a||"_"===a}function d(a){return a>="a"&&a<="f"||a>="A"&&a<="F"||a>="0"&&a<="9"}function e(a,e,g,j,k,l){var m,n,o,p,q;return p=a.length,m=null,o=function(b,c){var f,g,h;for(h="",e++,m=a.charAt(e);e<p;){if(m===b)return e++,h;if("\\"===m)if(e++,(m=a.charAt(e))===b)h+=b;else if(f=c[m])h+=f;else{if(d(m)){for(g=m,e++,m=a.charAt(e);d(m);)g+=m,e++,m=a.charAt(e);" "===m&&(e++,m=a.charAt(e)),h+=String.fromCharCode(parseInt(g,16));continue}h+=m}else h+=m;e++,m=a.charAt(e)}return h},n=function(){var b="";for(m=a.charAt(e);e<p;){if(c(m))b+=m;else{if("\\"!==m)return b;if(++e>=p)throw Error("Expected symbol but end of file reached.");if(m=a.charAt(e),f[m])b+=m;else{if(d(m)){var g=m;for(e++,m=a.charAt(e);d(m);)g+=m,e++,m=a.charAt(e);" "===m&&(e++,m=a.charAt(e)),b+=String.fromCharCode(parseInt(g,16));continue}b+=m}}e++,m=a.charAt(e)}return b},q=function(){m=a.charAt(e);for(var b=!1;" "===m||"\t"===m||"\n"===m||"\r"===m||"\f"===m;)b=!0,e++,m=a.charAt(e);return b},this.parse=function(){var b=this.parseSelector();if(e<p)throw Error('Rule expected but "'+a.charAt(e)+'" found.');return b},this.parseSelector=function(){var b,c=b=this.parseSingleSelector();for(m=a.charAt(e);","===m;){if(e++,q(),"selectors"!==b.type&&(b={type:"selectors",selectors:[c]}),!(c=this.parseSingleSelector()))throw Error('Rule expected after ",".');b.selectors.push(c)}return b},this.parseSingleSelector=function(){q();var b={type:"ruleSet"},c=this.parseRule();if(!c)return null;for(var d=b;c&&(c.type="rule",d.rule=c,d=c,q(),m=a.charAt(e),!(e>=p||","===m||")"===m));)if(k[m]){var f=m;if(e++,q(),!(c=this.parseRule()))throw Error('Rule expected after "'+f+'".');c.nestingOperator=f}else(c=this.parseRule())&&(c.nestingOperator=null);return b},this.parseRule=function(){for(var c=null;e<p;)if("*"===(m=a.charAt(e)))e++,(c=c||{}).tagName="*";else if(b(m)||"\\"===m)(c=c||{}).tagName=n();else if("."===m)e++,c=c||{},(c.classNames=c.classNames||[]).push(n());else if("#"===m)e++,(c=c||{}).id=n();else if("["===m){e++,q();var d={name:n()};if(q(),"]"===m)e++;else{var f="";if(j[m]&&(f=m,e++,m=a.charAt(e)),e>=p)throw Error('Expected "=" but end of file reached.');if("="!==m)throw Error('Expected "=" but "'+m+'" found.');d.operator=f+"=",e++,q();var k="";if(d.valueType="string",'"'===m)k=o('"',i);else if("'"===m)k=o("'",h);else if(l&&"$"===m)e++,k=n(),d.valueType="substitute";else{for(;e<p&&"]"!==m;)k+=m,e++,m=a.charAt(e);k=k.trim()}if(q(),e>=p)throw Error('Expected "]" but end of file reached.');if("]"!==m)throw Error('Expected "]" but "'+m+'" found.');e++,d.value=k}c=c||{},(c.attrs=c.attrs||[]).push(d)}else{if(":"!==m)break;e++;var r=n(),s={name:r};if("("===m){e++;var t="";if(q(),"selector"===g[r])s.valueType="selector",t=this.parseSelector();else{if(s.valueType=g[r]||"string",'"'===m)t=o('"',i);else if("'"===m)t=o("'",h);else if(l&&"$"===m)e++,t=n(),s.valueType="substitute";else{for(;e<p&&")"!==m;)t+=m,e++,m=a.charAt(e);t=t.trim()}q()}if(e>=p)throw Error('Expected ")" but end of file reached.');if(")"!==m)throw Error('Expected ")" but "'+m+'" found.');e++,s.value=t}c=c||{},(c.pseudos=c.pseudos||[]).push(s)}return c},this}a.prototype.registerSelectorPseudos=function(a){for(var b=0,c=arguments.length;b<c;b++)a=arguments[b],this.pseudos[a]="selector";return this},a.prototype.unregisterSelectorPseudos=function(a){for(var b=0,c=arguments.length;b<c;b++)a=arguments[b],delete this.pseudos[a];return this},a.prototype.registerNumericPseudos=function(a){for(var b=0,c=arguments.length;b<c;b++)a=arguments[b],this.pseudos[a]="numeric";return this},a.prototype.unregisterNumericPseudos=function(a){for(var b=0,c=arguments.length;b<c;b++)a=arguments[b],delete this.pseudos[a];return this},a.prototype.registerNestingOperators=function(a){for(var b=0,c=arguments.length;b<c;b++)a=arguments[b],this.ruleNestingOperators[a]=!0;return this},a.prototype.unregisterNestingOperators=function(a){for(var b=0,c=arguments.length;b<c;b++)a=arguments[b],delete this.ruleNestingOperators[a];return this},a.prototype.registerAttrEqualityMods=function(a){for(var b=0,c=arguments.length;b<c;b++)a=arguments[b],this.attrEqualityMods[a]=!0;return this},a.prototype.unregisterAttrEqualityMods=function(a){for(var b=0,c=arguments.length;b<c;b++)a=arguments[b],delete this.attrEqualityMods[a];return this},a.prototype.enableSubstitutes=function(){return this.substitutesEnabled=!0,this},a.prototype.disableSubstitutes=function(){return this.substitutesEnabled=!1,this};var f={"!":!0,'"':!0,"#":!0,$:!0,"%":!0,"&":!0,"'":!0,"(":!0,")":!0,"*":!0,"+":!0,",":!0,".":!0,"/":!0,";":!0,"<":!0,"=":!0,">":!0,"?":!0,"@":!0,"[":!0,"\\":!0,"]":!0,"^":!0,"`":!0,"{":!0,"|":!0,"}":!0,"~":!0},g={"\n":"\\n","\r":"\\r","\t":"\\t","\f":"\\f","\v":"\\v"},h={n:"\n",r:"\r",t:"\t",f:"\f","\\":"\\","'":"'"},i={n:"\n",r:"\r",t:"\t",f:"\f","\\":"\\",'"':'"'};a.prototype.parse=function(a){return new e(a,0,this.pseudos,this.attrEqualityMods,this.ruleNestingOperators,this.substitutesEnabled).parse()},a.prototype.escapeIdentifier=function(a){for(var b="",c=0,d=a.length;c<d;){var e=a.charAt(c);if(f[e])b+="\\"+e;else if("_"===e||"-"===e||e>="A"&&e<="Z"||e>="a"&&e<="z"||0!==c&&e>="0"&&e<="9")b+=e;else{var g=e.charCodeAt(0);if(55296==(63488&g)){var h=a.charCodeAt(c++);if(55296!=(64512&g)||56320!=(64512&h))throw Error("UCS-2(decode): illegal sequence");g=((1023&g)<<10)+(1023&h)+65536}b+="\\"+g.toString(16)+" "}c++}return b},a.prototype.escapeStr=function(a){for(var b,c,d="",e=0,f=a.length;e<f;)b=a.charAt(e),'"'===b?b='\\"':"\\"===b?b="\\\\":(c=g[b])&&(b=c),d+=b,e++;return'"'+d+'"'},a.prototype.render=function(a){return this._renderEntity(a).trim()},a.prototype._renderEntity=function(a){var b,c,d;switch(d="",a.type){case"ruleSet":for(b=a.rule,c=[];b;)b.nestingOperator&&c.push(b.nestingOperator),c.push(this._renderEntity(b)),b=b.rule;d=c.join(" ");break;case"selectors":d=a.selectors.map(this._renderEntity,this).join(", ");break;case"rule":a.tagName&&(d="*"===a.tagName?"*":this.escapeIdentifier(a.tagName)),a.id&&(d+="#"+this.escapeIdentifier(a.id)),a.classNames&&(d+=a.classNames.map(function(a){return"."+this.escapeIdentifier(a)},this).join("")),a.attrs&&(d+=a.attrs.map(function(a){return a.operator?"substitute"===a.valueType?"["+this.escapeIdentifier(a.name)+a.operator+"$"+a.value+"]":"["+this.escapeIdentifier(a.name)+a.operator+this.escapeStr(a.value)+"]":"["+this.escapeIdentifier(a.name)+"]"},this).join("")),a.pseudos&&(d+=a.pseudos.map(function(a){return a.valueType?"selector"===a.valueType?":"+this.escapeIdentifier(a.name)+"("+this._renderEntity(a.value)+")":"substitute"===a.valueType?":"+this.escapeIdentifier(a.name)+"($"+a.value+")":"numeric"===a.valueType?":"+this.escapeIdentifier(a.name)+"("+a.value+")":":"+this.escapeIdentifier(a.name)+"("+this.escapeIdentifier(a.value)+")":":"+this.escapeIdentifier(a.name)},this).join(""));break;default:throw Error('Unknown entity type: "'+a.type(NaN))}return d};var j=new a;j.registerNestingOperators(">"),axe.utils.cssParser=j}(axe),L.prototype={get selector(){return this.spec.selector||[axe.utils.getSelector(this.element,this._options)]},get xpath(){return this.spec.xpath||[axe.utils.getXpath(this.element)]},get element(){return this._element},get fromFrame(){return this._fromFrame},toJSON:function(){"use strict";return{selector:this.selector,source:this.source,xpath:this.xpath}}},L.fromFrame=function(a,b,c){return a.selector.unshift(c.selector),a.xpath.unshift(c.xpath),new axe.utils.DqElement(c.element,b,a)},axe.utils.DqElement=L,axe.utils.matchesSelector=function(){"use strict";function a(a){var b,c,d=a.Element.prototype,e=["matches","matchesSelector","mozMatchesSelector","webkitMatchesSelector","msMatchesSelector"],f=e.length;for(b=0;b<f;b++)if(c=e[b],d[c])return c}var b;return function(c,d){return b&&c[b]||(b=a(c.ownerDocument.defaultView)),c[b](d)}}(),axe.utils.escapeSelector=function(a){"use strict";for(var b,c=String(a),d=c.length,e=-1,f="",g=c.charCodeAt(0);++e<d;){if(0==(b=c.charCodeAt(e)))throw new Error("INVALID_CHARACTER_ERR");b>=1&&b<=31||b>=127&&b<=159||0==e&&b>=48&&b<=57||1==e&&b>=48&&b<=57&&45==g?f+="\\"+b.toString(16)+" ":f+=(1!=e||45!=b||45!=g)&&(b>=128||45==b||95==b||b>=48&&b<=57||b>=65&&b<=90||b>=97&&b<=122)?c.charAt(e):"\\"+c.charAt(e)}return f},axe.utils.extendMetaData=function(a,b){Object.assign(a,b),Object.keys(b).filter(function(a){return"function"==typeof b[a]}).forEach(function(c){a[c]=null;try{a[c]=b[c](a)}catch(a){}})},axe.utils.finalizeRuleResult=function(a){return Object.assign(a,axe.utils.aggregateRule(a.nodes)),delete a.nodes,a};var ta="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a};axe.utils.findBy=function(a,b,c){if(Array.isArray(a))return a.find(function(a){return"object"===(void 0===a?"undefined":ta(a))&&a[b]===c})};var axe=axe||{utils:{}};axe.utils.getFlattenedTree=function(a,b){function c(a,c){var d=axe.utils.getFlattenedTree(c,b);return d&&(a=a.concat(d)),a}var d,e,f;if(a.documentElement&&(a=a.documentElement),f=a.nodeName.toLowerCase(),a.shadowRoot&&"marquee"!==f)return d=M(a,b),b="a"+Math.random().toString().substring(2),e=Array.from(a.shadowRoot.childNodes),d.children=e.reduce(c,[]),[d];if("content"===f)return e=Array.from(a.getDistributedNodes()),e.reduce(c,[]);if("slot"===f){e=Array.from(a.assignedNodes()),e.length||(e=N(a));window.getComputedStyle(a);return e.reduce(c,[])}return 1===a.nodeType?(d=M(a,b),e=Array.from(a.childNodes),d.children=e.reduce(c,[]),[d]):3===a.nodeType?[M(a)]:void 0},axe.utils.getNodeFromTree=function(a,b){var c;return a.actualNode===b?a:(a.children.forEach(function(a){var d;a.actualNode===b?c=a:(d=axe.utils.getNodeFromTree(a,b))&&(c=d)}),c)},axe.utils.getAllChecks=function(a){"use strict";return[].concat(a.any||[]).concat(a.all||[]).concat(a.none||[])},axe.utils.getCheckOption=function(a,b,c){var d=((c.rules&&c.rules[b]||{}).checks||{})[a.id],e=(c.checks||{})[a.id],f=a.enabled,g=a.options;return e&&(e.hasOwnProperty("enabled")&&(f=e.enabled),e.hasOwnProperty("options")&&(g=e.options)),d&&(d.hasOwnProperty("enabled")&&(f=d.enabled),d.hasOwnProperty("options")&&(g=d.options)),{enabled:f,options:g,absolutePaths:c.absolutePaths}};var Ba=function(){function a(a,b){var c=[],d=!0,e=!1,f=void 0;try{for(var g,h=a[Symbol.iterator]();!(d=(g=h.next()).done)&&(c.push(g.value),!b||c.length!==b);d=!0);}catch(a){e=!0,f=a}finally{try{!d&&h.return&&h.return()}finally{if(e)throw f}}return c}return function(b,c){if(Array.isArray(b))return b;if(Symbol.iterator in Object(b))return a(b,c);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}();axe.utils.getFriendlyUriEnd=function(){var a=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",b=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!(a.length<=1||"data:"===a.substr(0,5)||"javascript:"===a.substr(0,11)||a.includes("?"))){var c=b.currentDomain,d=b.maxLength,e=void 0===d?25:d,f=Q(a),g=f.path,h=f.domain,i=f.hash,j=g.substr(g.substr(0,g.length-2).lastIndexOf("/")+1);if(i)return j&&(j+i).length<=e?j+i:j.length<2&&i.length>2&&i.length<=e?i:void 0;if(h&&h.length<e&&g.length<=1)return h+g;if(g==="/"+j&&h&&c&&h!==c&&(h+g).length<=e)return h+g;var k=j.lastIndexOf(".");return(-1===k||k>1)&&(-1!==k||j.length>2)&&j.length<=e&&!j.match(/index(\.[a-zA-Z]{2-4})?/)&&!O(j)?j:void 0}};var Ca=axe.utils.escapeSelector,Da=["div","span","p","b","i","u","strong","em","h2","h3"],Ea={getElmId:function(a){if(a.getAttribute("id")){var b=a.getRootNode&&a.getRootNode()||document,c="#"+Ca(a.getAttribute("id")||"");return c.match(/player_uid_/)||1!==b.querySelectorAll(c).length?void 0:c}},getCustomElm:function(a,b){var c=b.isCustomElm,d=b.nodeName;if(c)return d},getElmRoleProp:function(a){if(a.hasAttribute("role"))return'[role="'+Ca(a.getAttribute("role"))+'"]'},getUncommonElm:function(a,b){var c=b.isCommonElm,d=b.isCustomElm,e=b.nodeName;if(!c&&!d)return e=Ca(e),"input"===e&&a.hasAttribute("type")&&(e+='[type="'+a.type+'"]'),e},getElmNameProp:function(a){if(!a.hasAttribute("id")&&a.name)return'[name="'+Ca(a.name)+'"]'},getDistinctClass:function(a,b){var c=b.distinctClassList;if(c.length>0&&c.length<3)return"."+c.map(Ca).join(".")},getFileRefProp:function(a){var b=void 0;if(a.hasAttribute("href"))b="href";else{if(!a.hasAttribute("src"))return;b="src"}var c=axe.utils.getFriendlyUriEnd(a.getAttribute(b));if(c)return"["+b+'$="'+encodeURI(c)+'"]'},getCommonName:function(a,b){var c=b.nodeName;if(b.isCommonElm)return c}};axe.utils.getSelector=function(a){var b=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!a)return"";var c=a.getRootNode&&a.getRootNode()||document;if(11===c.nodeType){for(var d=[];11===c.nodeType;)d.push({elm:a,doc:c}),a=c.host,c=a.getRootNode();return d.push({elm:a,doc:c}),d.reverse().map(function(a){return W(a.elm,b,a.doc)})}return W(a,b,c)},axe.utils.getXpath=function(a){return Y(X(a))};var Fa;axe.utils.injectStyle=Z,axe.utils.isHidden=function(a,b){"use strict";var c;if(9===a.nodeType)return!1;11===a.nodeType&&(a=a.host);var d=window.getComputedStyle(a,null);return!d||!a.parentNode||"none"===d.getPropertyValue("display")||!b&&"hidden"===d.getPropertyValue("visibility")||"true"===a.getAttribute("aria-hidden")||(c=a.assignedSlot?a.assignedSlot:a.parentNode,axe.utils.isHidden(c,!0))},axe.utils.mergeResults=function(a,b){"use strict";var c=[];return a.forEach(function(a){var d=aa(a);d&&d.length&&d.forEach(function(d){d.nodes&&a.frame&&$(d.nodes,b,a.frameElement,a.frame);var e=axe.utils.findBy(c,"id",d.id);e?d.nodes.length&&_(e.nodes,d.nodes):c.push(d)})}),c},axe.utils.nodeSorter=function(a,b){"use strict";return a.actualNode===b.actualNode?0:4&a.actualNode.compareDocumentPosition(b.actualNode)?-1:1},utils.performanceTimer=function(){"use strict";function a(){if(window.performance&&window.performance)return window.performance.now()}var b=null,c=a();return{start:function(){this.mark("mark_axe_start")},end:function(){this.mark("mark_axe_end"),this.measure("axe","mark_axe_start","mark_axe_end"),this.logMeasures("axe")},auditStart:function(){this.mark("mark_audit_start")},auditEnd:function(){this.mark("mark_audit_end"),this.measure("audit_start_to_end","mark_audit_start","mark_audit_end"),this.logMeasures()},mark:function(a){window.performance&&void 0!==window.performance.mark&&window.performance.mark(a)},measure:function(a,b,c){window.performance&&void 0!==window.performance.measure&&window.performance.measure(a,b,c)},logMeasures:function(a){function b(a){axe.log("Measure "+a.name+" took "+a.duration+"ms")}if(window.performance&&void 0!==window.performance.getEntriesByType)for(var c=window.performance.getEntriesByType("measure"),d=0;d<c.length;++d){var e=c[d];if(e.name===a)return void b(e);b(e)}},timeElapsed:function(){return a()-c},reset:function(){b||(b=a()),c=a()}}}(),"function"!=typeof Object.assign&&function(){Object.assign=function(a){"use strict";if(void 0===a||null===a)throw new TypeError("Cannot convert undefined or null to object");for(var b=Object(a),c=1;c<arguments.length;c++){var d=arguments[c];if(void 0!==d&&null!==d)for(var e in d)d.hasOwnProperty(e)&&(b[e]=d[e])}return b}}(),Array.prototype.find||(Array.prototype.find=function(a){if(null===this)throw new TypeError("Array.prototype.find called on null or undefined");if("function"!=typeof a)throw new TypeError("predicate must be a function");for(var b,c=Object(this),d=c.length>>>0,e=arguments[1],f=0;f<d;f++)if(b=c[f],a.call(e,b,f,c))return b}),axe.utils.pollyfillElementsFromPoint=function(){if(document.elementsFromPoint)return document.elementsFromPoint;if(document.msElementsFromPoint)return document.msElementsFromPoint;var a=function(){var a=document.createElement("x");return a.style.cssText="pointer-events:auto","auto"===a.style.pointerEvents}(),b=a?"pointer-events":"visibility",c=a?"none":"hidden",d=document.createElement("style");return d.innerHTML=a?"* { pointer-events: all }":"* { visibility: visible }",function(a,e){var f,g,h,i=[],j=[];for(document.head.appendChild(d);(f=document.elementFromPoint(a,e))&&-1===i.indexOf(f);)i.push(f),j.push({value:f.style.getPropertyValue(b),priority:f.style.getPropertyPriority(b)}),f.style.setProperty(b,c,"important");for(g=j.length;h=j[--g];)i[g].style.setProperty(b,h.value?h.value:"",h.priority);return document.head.removeChild(d),i}},"function"==typeof window.addEventListener&&(document.elementsFromPoint=axe.utils.pollyfillElementsFromPoint()),Array.prototype.includes||(Array.prototype.includes=function(a){"use strict";var b=Object(this),c=parseInt(b.length,10)||0;if(0===c)return!1;var d,e=parseInt(arguments[1],10)||0;e>=0?d=e:(d=c+e)<0&&(d=0);for(var f;d<c;){if(f=b[d],a===f||a!==a&&f!==f)return!0;d++}return!1}),Array.prototype.some||(Array.prototype.some=function(a){"use strict";if(null==this)throw new TypeError("Array.prototype.some called on null or undefined");if("function"!=typeof a)throw new TypeError;for(var b=Object(this),c=b.length>>>0,d=arguments.length>=2?arguments[1]:void 0,e=0;e<c;e++)if(e in b&&a.call(d,b[e],e,b))return!0;return!1}),Array.from||(Array.from=function(){var a=Object.prototype.toString,b=function(b){return"function"==typeof b||"[object Function]"===a.call(b)},c=function(a){var b=Number(a);return isNaN(b)?0:0!==b&&isFinite(b)?(b>0?1:-1)*Math.floor(Math.abs(b)):b},d=Math.pow(2,53)-1,e=function(a){var b=c(a);return Math.min(Math.max(b,0),d)};return function(a){var c=this,d=Object(a);if(null==a)throw new TypeError("Array.from requires an array-like object - not null or undefined");var f,g=arguments.length>1?arguments[1]:void 0;if(void 0!==g){if(!b(g))throw new TypeError("Array.from: when provided, the second argument must be a function");arguments.length>2&&(f=arguments[2])}for(var h,i=e(d.length),j=b(c)?Object(new c(i)):new Array(i),k=0;k<i;)h=d[k],j[k]=g?void 0===f?g(h,k):g.call(f,h,k):h,k+=1;return j.length=i,j}}()),String.prototype.includes||(String.prototype.includes=function(a,b){return"number"!=typeof b&&(b=0),!(b+a.length>this.length)&&-1!==this.indexOf(a,b)});var ta="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a};axe.utils.publishMetaData=function(a){"use strict";var b=axe._audit.data.checks||{},c=axe._audit.data.rules||{},d=axe.utils.findBy(axe._audit.rules,"id",a.id)||{};a.tags=axe.utils.clone(d.tags||[]);var e=ca(b,!0),f=ca(b,!1);a.nodes.forEach(function(a){a.any.forEach(e),a.all.forEach(e),a.none.forEach(f)}),axe.utils.extendMetaData(a,axe.utils.clone(c[a.id]||{}))};var Ga=function(){},Ha=function(){},Ia=function(){/*! Credit: XRegExp 0.6.1 (c) 2007-2008 Steven Levithan <http://stevenlevithan.com/regex/xregexp/> MIT License */ +var a=/(?=[\-\[\]{}()*+?.\\\^$|,#\s])/g;return function(b){return b.replace(a,"\\")}}(),Ja=/\\/g;Ga=function(a){return a.map(function(a){for(var b=[],c=a.rule;c;)b.push({tag:c.tagName?c.tagName.toLowerCase():"*",combinator:c.nestingOperator?c.nestingOperator:" ",id:c.id,attributes:ja(c.attrs),classes:ka(c.classNames),pseudos:la(c.pseudos)}),c=c.rule;return b})},Ha=function(a,b,c){return b.reduce(function(b,d){var e=a;return d.forEach(function(a,b){if(c=">"!==a.combinator&&c,-1===[" ",">"].indexOf(a.combinator))throw new Error("axe.utils.querySelectorAll does not support the combinator: "+a.combinator);e=e.reduce(function(d,e){return d.concat(ia(b?e.children:e,a,c))},[])}),b.concat(e)},[])},axe.utils.querySelectorAll=function(a,b){a=Array.isArray(a)?a:[a];var c=axe.utils.cssParser.parse(b);return c=c.selectors?c.selectors:[c],c=Ga(c),Ha(a,c,!0)};var ta="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a};!function(){"use strict";function a(){}function b(a){if("function"!=typeof a)throw new TypeError("Queue methods require functions as arguments")}function c(){function c(b){return function(c){g[b]=c,(i-=1)||j===a||(k=!0,j(g))}}function d(b){return j=a,m(b),g}function e(){for(var a=g.length;h<a;h++){var b=g[h];try{b.call(null,c(h),d)}catch(a){d(a)}}}var f,g=[],h=0,i=0,j=a,k=!1,l=function(a){f=a,setTimeout(function(){void 0!==f&&null!==f&&axe.log("Uncaught error (of queue)",f)},1)},m=l,n={defer:function(a){if("object"===(void 0===a?"undefined":ta(a))&&a.then&&a.catch){var c=a;a=function(a,b){c.then(a).catch(b)}}if(b(a),void 0===f){if(k)throw new Error("Queue already completed");return g.push(a),++i,e(),n}},then:function(c){if(b(c),j!==a)throw new Error("queue `then` already set");return f||(j=c,i||(k=!0,j(g))),n},catch:function(a){if(b(a),m!==l)throw new Error("queue `catch` already set");return f?(a(f),f=null):m=a,n},abort:d};return n}axe.utils.queue=c}();var ta="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a};!function(a){"use strict";function b(){var a="axe",b="";return void 0!==axe&&axe._audit&&!axe._audit.application&&(a=axe._audit.application),void 0!==axe&&(b=axe.version),a+"."+b}function c(a){if("object"===(void 0===a?"undefined":ta(a))&&"string"==typeof a.uuid&&!0===a._respondable){var c=b();return a._source===c||"axe.x.y.z"===a._source||"axe.x.y.z"===c}return!1}function d(a,c,d,e,f,g){var h;d instanceof Error&&(h={name:d.name,message:d.message,stack:d.stack},d=void 0);var i={uuid:e,topic:c,message:d,error:h,_respondable:!0,_source:b(),_keepalive:f};"function"==typeof g&&(j[e]=g),a.postMessage(JSON.stringify(i),"*")}function e(a,b,c,e,f){d(a,b,c,Ka.v1(),e,f)}function f(a,b,c){return function(e,f,g){d(a,b,e,c,f,g)}}function g(a,b,c){var d=b.topic,e=k[d];if(e){var g=f(a,null,b.uuid);e(b.message,c,g)}}function h(a){var b=a.message||"Unknown error occurred",c=window[a.name]||Error;return a.stack&&(b+="\n"+a.stack.replace(a.message,"")),new c(b)}function i(a){var b;if("string"==typeof a){try{b=JSON.parse(a)}catch(a){}if(c(b))return"object"===ta(b.error)?b.error=h(b.error):b.error=void 0,b}}var j={},k={};e.subscribe=function(a,b){k[a]=b},e.isInFrame=function(a){return a=a||window,!!a.frameElement},"function"==typeof window.addEventListener&&window.addEventListener("message",function(a){var b=i(a.data);if(b){var c=b.uuid,e=b._keepalive,h=j[c];if(h){h(b.error||b.message,e,f(a.source,b.topic,c)),e||delete j[c]}if(!b.error)try{g(a.source,b,e)}catch(e){d(a.source,b.topic,e,c,!1)}}},!1),a.respondable=e}(utils),axe.utils.ruleShouldRun=function(a,b,c){"use strict";var d=c.runOnly||{},e=(c.rules||{})[a.id];return!(a.pageLevel&&!b.page)&&("rule"===d.type?-1!==d.values.indexOf(a.id):e&&"boolean"==typeof e.enabled?e.enabled:"tag"===d.type&&d.values?ma(a,d.values):ma(a,[]))},axe.utils.getScrollState=function(){var a=arguments.length>0&&void 0!==arguments[0]?arguments[0]:window,b=a.document.documentElement;return[void 0!==a.pageXOffset?{elm:a,top:a.pageYOffset,left:a.pageXOffset}:{elm:b,top:b.scrollTop,left:b.scrollLeft}].concat(pa(document.body))},axe.utils.setScrollState=function(a){a.forEach(function(a){return oa(a.elm,a.top,a.left)})},axe.utils.select=function(a,b){"use strict";for(var c,d=[],e=0,f=b.include.length;e<f;e++)c=b.include[e],c.actualNode.nodeType===c.actualNode.ELEMENT_NODE&&axe.utils.matchesSelector(c.actualNode,a)&&sa(d,[c],b),sa(d,axe.utils.querySelectorAll(c,a),b);return d.sort(axe.utils.nodeSorter)},axe.utils.toArray=function(a){"use strict";return Array.prototype.slice.call(a)};var Ka;!function(a){function b(a,b,c){var d=b&&c||0,e=0;for(b=b||[],a.toLowerCase().replace(/[0-9a-f]{2}/g,function(a){e<16&&(b[d+e++]=l[a])});e<16;)b[d+e++]=0;return b}function c(a,b){var c=b||0,d=k;return d[a[c++]]+d[a[c++]]+d[a[c++]]+d[a[c++]]+"-"+d[a[c++]]+d[a[c++]]+"-"+d[a[c++]]+d[a[c++]]+"-"+d[a[c++]]+d[a[c++]]+"-"+d[a[c++]]+d[a[c++]]+d[a[c++]]+d[a[c++]]+d[a[c++]]+d[a[c++]]}function d(a,b,d){var e=b&&d||0,f=b||[];a=a||{};var g=null!=a.clockseq?a.clockseq:p,h=null!=a.msecs?a.msecs:(new Date).getTime(),i=null!=a.nsecs?a.nsecs:r+1,j=h-q+(i-r)/1e4;if(j<0&&null==a.clockseq&&(g=g+1&16383),(j<0||h>q)&&null==a.nsecs&&(i=0),i>=1e4)throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");q=h,r=i,p=g,h+=122192928e5;var k=(1e4*(268435455&h)+i)%4294967296;f[e++]=k>>>24&255,f[e++]=k>>>16&255,f[e++]=k>>>8&255,f[e++]=255&k;var l=h/4294967296*1e4&268435455;f[e++]=l>>>8&255,f[e++]=255&l,f[e++]=l>>>24&15|16,f[e++]=l>>>16&255,f[e++]=g>>>8|128,f[e++]=255&g;for(var m=a.node||o,n=0;n<6;n++)f[e+n]=m[n];return b||c(f)}function e(a,b,d){var e=b&&d||0;"string"==typeof a&&(b="binary"==a?new j(16):null,a=null),a=a||{};var g=a.random||(a.rng||f)();if(g[6]=15&g[6]|64,g[8]=63&g[8]|128,b)for(var h=0;h<16;h++)b[e+h]=g[h];return b||c(g)}var f,g=a.crypto||a.msCrypto;if(!f&&g&&g.getRandomValues){var h=new Uint8Array(16);f=function(){return g.getRandomValues(h),h}}if(!f){var i=new Array(16);f=function(){for(var a,b=0;b<16;b++)0==(3&b)&&(a=4294967296*Math.random()),i[b]=a>>>((3&b)<<3)&255;return i}}for(var j="function"==typeof a.Buffer?a.Buffer:Array,k=[],l={},m=0;m<256;m++)k[m]=(m+256).toString(16).substr(1),l[k[m]]=m;var n=f(),o=[1|n[0],n[1],n[2],n[3],n[4],n[5]],p=16383&(n[6]<<8|n[7]),q=0,r=0;Ka=e,Ka.v1=d,Ka.v4=e,Ka.parse=b,Ka.unparse=c,Ka.BufferClass=j}(window),axe._load({data:{rules:{accesskeys:{description:"Ensures every accesskey attribute value is unique",help:"accesskey attribute value must be unique"},"area-alt":{description:"Ensures <area> elements of image maps have alternate text",help:"Active <area> elements must have alternate text"},"aria-allowed-attr":{description:"Ensures ARIA attributes are allowed for an element's role",help:"Elements must only use allowed ARIA attributes"},"aria-hidden-body":{description:"Ensures aria-hidden='true' is not present on the document body.",help:"aria-hidden='true' must not be present on the document body"},"aria-required-attr":{description:"Ensures elements with ARIA roles have all required ARIA attributes",help:"Required ARIA attributes must be provided"},"aria-required-children":{description:"Ensures elements with an ARIA role that require child roles contain them",help:"Certain ARIA roles must contain particular children"},"aria-required-parent":{description:"Ensures elements with an ARIA role that require parent roles are contained by them",help:"Certain ARIA roles must be contained by particular parents"},"aria-roles":{description:"Ensures all elements with a role attribute use a valid value",help:"ARIA roles used must conform to valid values"},"aria-valid-attr-value":{description:"Ensures all ARIA attributes have valid values",help:"ARIA attributes must conform to valid values"},"aria-valid-attr":{description:"Ensures attributes that begin with aria- are valid ARIA attributes",help:"ARIA attributes must conform to valid names"},"audio-caption":{description:"Ensures <audio> elements have captions",help:"<audio> elements must have a captions track"},blink:{description:"Ensures <blink> elements are not used",help:"<blink> elements are deprecated and must not be used"},"button-name":{description:"Ensures buttons have discernible text",help:"Buttons must have discernible text"},bypass:{description:"Ensures each page has at least one mechanism for a user to bypass navigation and jump straight to the content",help:"Page must have means to bypass repeated blocks"},checkboxgroup:{description:'Ensures related <input type="checkbox"> elements have a group and that that group designation is consistent',help:"Checkbox inputs with the same name attribute value must be part of a group"},"color-contrast":{description:"Ensures the contrast between foreground and background colors meets WCAG 2 AA contrast ratio thresholds",help:"Elements must have sufficient color contrast"},"definition-list":{description:"Ensures <dl> elements are structured correctly",help:"<dl> elements must only directly contain properly-ordered <dt> and <dd> groups, <script> or <template> elements"},dlitem:{description:"Ensures <dt> and <dd> elements are contained by a <dl>",help:"<dt> and <dd> elements must be contained by a <dl>"},"document-title":{description:"Ensures each HTML document contains a non-empty <title> element",help:"Documents must have <title> element to aid in navigation"},"duplicate-id":{description:"Ensures every id attribute value is unique",help:"id attribute value must be unique"},"empty-heading":{description:"Ensures headings have discernible text",help:"Headings must not be empty"},"frame-title-unique":{description:"Ensures <iframe> and <frame> elements contain a unique title attribute",help:"Frames must have a unique title attribute"},"frame-title":{description:"Ensures <iframe> and <frame> elements contain a non-empty title attribute",help:"Frames must have title attribute"},"heading-order":{description:"Ensures the order of headings is semantically correct",help:"Heading levels should only increase by one"},"hidden-content":{description:"Informs users about hidden content.",help:"Hidden content on the page cannot be analyzed"},"href-no-hash":{description:"Ensures that href values are valid link references to promote only using anchors as links",help:"Anchors must only be used as links with valid URLs or URL fragments"},"html-has-lang":{description:"Ensures every HTML document has a lang attribute",help:"<html> element must have a lang attribute"},"html-lang-valid":{description:"Ensures the lang attribute of the <html> element has a valid value",help:"<html> element must have a valid value for the lang attribute"},"image-alt":{description:"Ensures <img> elements have alternate text or a role of none or presentation",help:"Images must have alternate text"},"image-redundant-alt":{description:"Ensure button and link text is not repeated as image alternative",help:"Text of buttons and links should not be repeated in the image alternative"},"input-image-alt":{description:'Ensures <input type="image"> elements have alternate text',help:"Image buttons must have alternate text"},"label-title-only":{description:"Ensures that every form element is not solely labeled using the title or aria-describedby attributes",help:"Form elements should have a visible label"},label:{description:"Ensures every form element has a label",help:"Form elements must have labels"},"layout-table":{description:"Ensures presentational <table> elements do not use <th>, <caption> elements or the summary attribute",help:"Layout tables must not use data table elements"},"link-in-text-block":{description:"Links can be distinguished without relying on color",help:"Links must be distinguished from surrounding text in a way that does not rely on color"},"link-name":{description:"Ensures links have discernible text",help:"Links must have discernible text"},list:{description:"Ensures that lists are structured correctly",help:"<ul> and <ol> must only directly contain <li>, <script> or <template> elements"},listitem:{description:"Ensures <li> elements are used semantically",help:"<li> elements must be contained in a <ul> or <ol>"},marquee:{description:"Ensures <marquee> elements are not used",help:"<marquee> elements are deprecated and must not be used"},"meta-refresh":{description:'Ensures <meta http-equiv="refresh"> is not used',help:"Timed refresh must not exist"},"meta-viewport-large":{description:'Ensures <meta name="viewport"> can scale a significant amount',help:"Users should be able to zoom and scale the text up to 500%"},"meta-viewport":{description:'Ensures <meta name="viewport"> does not disable text scaling and zooming',help:"Zooming and scaling must not be disabled"},"object-alt":{description:"Ensures <object> elements have alternate text",help:"<object> elements must have alternate text"},"p-as-heading":{description:"Ensure p elements are not used to style headings",help:"Bold, italic text and font-size are not used to style p elements as a heading"},radiogroup:{description:'Ensures related <input type="radio"> elements have a group and that the group designation is consistent',help:"Radio inputs with the same name attribute value must be part of a group"},region:{description:"Ensures all content is contained within a landmark region",help:"Content should be contained in a landmark region"},"scope-attr-valid":{description:"Ensures the scope attribute is used correctly on tables",help:"scope attribute should be used correctly"},"server-side-image-map":{description:"Ensures that server-side image maps are not used",help:"Server-side image maps must not be used"},"skip-link":{description:"Ensures the first link on the page is a skip link",help:"The page should have a skip link as its first link"},tabindex:{description:"Ensures tabindex attribute values are not greater than 0",help:"Elements should not have tabindex greater than zero"},"table-duplicate-name":{description:"Ensure that tables do not have the same summary and caption",help:"The <caption> element should not contain the same text as the summary attribute"},"table-fake-caption":{description:"Ensure that tables with a caption use the <caption> element.",help:"Data or header cells should not be used to give caption to a data table."},"td-has-header":{description:"Ensure that each non-empty data cell in a large table has one or more table headers",help:"All non-empty td element in table larger than 3 by 3 must have an associated table header"},"td-headers-attr":{description:"Ensure that each cell in a table using the headers refers to another cell in that table",help:"All cells in a table element that use the headers attribute must only refer to other cells of that same table"},"th-has-data-cells":{description:"Ensure that each table header in a data table refers to data cells",help:"All th element and elements with role=columnheader/rowheader must data cells which it describes"},"valid-lang":{description:"Ensures lang attributes have valid values",help:"lang attribute must have a valid value"},"video-caption":{description:"Ensures <video> elements have captions",help:"<video> elements must have captions"},"video-description":{description:"Ensures <video> elements have audio descriptions",help:"<video> elements must have an audio description track"}},checks:{accesskeys:{impact:"serious",messages:{pass:function(a){return"Accesskey attribute value is unique"},fail:function(a){return"Document has multiple elements with the same accesskey"}}},"non-empty-alt":{impact:"critical",messages:{pass:function(a){return"Element has a non-empty alt attribute"},fail:function(a){return"Element has no alt attribute or the alt attribute is empty"}}},"non-empty-title":{impact:"serious",messages:{pass:function(a){return"Element has a title attribute"},fail:function(a){return"Element has no title attribute or the title attribute is empty"}}},"aria-label":{impact:"serious",messages:{pass:function(a){return"aria-label attribute exists and is not empty"},fail:function(a){return"aria-label attribute does not exist or is empty"}}},"aria-labelledby":{impact:"serious",messages:{pass:function(a){return"aria-labelledby attribute exists and references elements that are visible to screen readers"},fail:function(a){return"aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty or not visible"}}},"aria-allowed-attr":{impact:"critical",messages:{pass:function(a){return"ARIA attributes are used correctly for the defined role"},fail:function(a){var b="ARIA attribute"+(a.data&&a.data.length>1?"s are":" is")+" not allowed:",c=a.data;if(c)for(var d,e=-1,f=c.length-1;e<f;)d=c[e+=1],b+=" "+d;return b}}},"aria-hidden-body":{impact:"critical",messages:{pass:function(a){return"No aria-hidden attribute is present on document body"},fail:function(a){return"aria-hidden=true should not be present on the document body"}}},"aria-required-attr":{impact:"critical",messages:{pass:function(a){return"All required ARIA attributes are present"},fail:function(a){var b="Required ARIA attribute"+(a.data&&a.data.length>1?"s":"")+" not present:",c=a.data;if(c)for(var d,e=-1,f=c.length-1;e<f;)d=c[e+=1],b+=" "+d;return b}}},"aria-required-children":{impact:"critical",messages:{pass:function(a){return"Required ARIA children are present"},fail:function(a){var b="Required ARIA "+(a.data&&a.data.length>1?"children":"child")+" role not present:",c=a.data;if(c)for(var d,e=-1,f=c.length-1;e<f;)d=c[e+=1],b+=" "+d;return b}}},"aria-required-parent":{impact:"critical",messages:{pass:function(a){return"Required ARIA parent role present"},fail:function(a){var b="Required ARIA parent"+(a.data&&a.data.length>1?"s":"")+" role not present:",c=a.data;if(c)for(var d,e=-1,f=c.length-1;e<f;)d=c[e+=1],b+=" "+d;return b}}},invalidrole:{impact:"critical",messages:{pass:function(a){return"ARIA role is valid"},fail:function(a){return"Role must be one of the valid ARIA roles"}}},abstractrole:{impact:"serious",messages:{pass:function(a){return"Abstract roles are not used"},fail:function(a){return"Abstract roles cannot be directly used"}}},"aria-valid-attr-value":{impact:"critical",messages:{pass:function(a){return"ARIA attribute values are valid"},fail:function(a){var b="Invalid ARIA attribute value"+(a.data&&a.data.length>1?"s":"")+":",c=a.data;if(c)for(var d,e=-1,f=c.length-1;e<f;)d=c[e+=1],b+=" "+d;return b}}},"aria-valid-attr":{impact:"critical",messages:{pass:function(a){return"ARIA attribute name"+(a.data&&a.data.length>1?"s":"")+" are valid"},fail:function(a){var b="Invalid ARIA attribute name"+(a.data&&a.data.length>1?"s":"")+":",c=a.data;if(c)for(var d,e=-1,f=c.length-1;e<f;)d=c[e+=1],b+=" "+d;return b}}},caption:{impact:"critical",messages:{pass:function(a){return"The multimedia element has a captions track"},fail:function(a){return"The multimedia element does not have a captions track"},incomplete:function(a){return"A captions track for this element could not be found"}}},"is-on-screen":{impact:"serious",messages:{pass:function(a){return"Element is not visible"},fail:function(a){return"Element is visible"}}},"non-empty-if-present":{impact:"critical",messages:{pass:function(a){var b="Element ";return a.data?b+="has a non-empty value attribute":b+="does not have a value attribute",b},fail:function(a){return"Element has a value attribute and the value attribute is empty"}}},"non-empty-value":{impact:"critical",messages:{pass:function(a){return"Element has a non-empty value attribute"},fail:function(a){return"Element has no value attribute or the value attribute is empty"}}},"button-has-visible-text":{impact:"critical",messages:{pass:function(a){return"Element has inner text that is visible to screen readers"},fail:function(a){return"Element does not have inner text that is visible to screen readers"}}},"role-presentation":{impact:"minor",messages:{pass:function(a){return'Element\'s default semantics were overriden with role="presentation"'},fail:function(a){return'Element\'s default semantics were not overridden with role="presentation"'}}},"role-none":{impact:"minor",messages:{pass:function(a){return'Element\'s default semantics were overriden with role="none"'},fail:function(a){return'Element\'s default semantics were not overridden with role="none"'}}},"focusable-no-name":{impact:"serious",messages:{pass:function(a){return"Element is not in tab order or has accessible text"},fail:function(a){return"Element is in tab order and does not have accessible text"}}},"internal-link-present":{impact:"serious",messages:{pass:function(a){return"Valid skip link found"},fail:function(a){return"No valid skip link found"}}},"header-present":{impact:"serious",messages:{pass:function(a){return"Page has a header"},fail:function(a){return"Page does not have a header"}}},landmark:{impact:"serious",messages:{pass:function(a){return"Page has a landmark region"},fail:function(a){return"Page does not have a landmark region"}}},"group-labelledby":{impact:"critical",messages:{pass:function(a){return'All elements with the name "'+a.data.name+'" reference the same element with aria-labelledby'},fail:function(a){return'All elements with the name "'+a.data.name+'" do not reference the same element with aria-labelledby'}}},fieldset:{impact:"critical",messages:{pass:function(a){return"Element is contained in a fieldset"},fail:function(a){var b="",c=a.data&&a.data.failureCode;return b+="no-legend"===c?"Fieldset does not have a legend as its first child":"empty-legend"===c?"Legend does not have text that is visible to screen readers":"mixed-inputs"===c?"Fieldset contains unrelated inputs":"no-group-label"===c?"ARIA group does not have aria-label or aria-labelledby":"group-mixed-inputs"===c?"ARIA group contains unrelated inputs":"Element does not have a containing fieldset or ARIA group"}}},"color-contrast":{impact:"serious",messages:{pass:function(a){return"Element has sufficient color contrast of "+a.data.contrastRatio},fail:function(a){return"Element has insufficient color contrast of "+a.data.contrastRatio+" (foreground color: "+a.data.fgColor+", background color: "+a.data.bgColor+", font size: "+a.data.fontSize+", font weight: "+a.data.fontWeight+")"},incomplete:{bgImage:"Element's background color could not be determined due to a background image",bgGradient:"Element's background color could not be determined due to a background gradient",imgNode:"Element's background color could not be determined because element contains an image node",bgOverlap:"Element's background color could not be determined because it is overlapped by another element",fgAlpha:"Element's foreground color could not be determined because of alpha transparency",elmPartiallyObscured:"Element's background color could not be determined because it's partially obscured by another element",equalRatio:"Element has a 1:1 contrast ratio with the background",default:"Unable to determine contrast ratio"}}},"structured-dlitems":{impact:"serious",messages:{pass:function(a){return"When not empty, element has both <dt> and <dd> elements"},fail:function(a){return"When not empty, element does not have at least one <dt> element followed by at least one <dd> element"}}},"only-dlitems":{impact:"serious",messages:{pass:function(a){return"List element only has direct children that are allowed inside <dt> or <dd> elements"},fail:function(a){return"List element has direct children that are not allowed inside <dt> or <dd> elements"}}},dlitem:{impact:"serious",messages:{pass:function(a){return"Description list item has a <dl> parent element"},fail:function(a){return"Description list item does not have a <dl> parent element"}}},"doc-has-title":{impact:"serious",messages:{pass:function(a){return"Document has a non-empty <title> element"},fail:function(a){return"Document does not have a non-empty <title> element"}}},"duplicate-id":{impact:"moderate",messages:{pass:function(a){return"Document has no elements that share the same id attribute"},fail:function(a){return"Document has multiple elements with the same id attribute: "+a.data}}},"has-visible-text":{impact:"minor",messages:{pass:function(a){return"Element has text that is visible to screen readers"},fail:function(a){return"Element does not have text that is visible to screen readers"}}},"unique-frame-title":{impact:"serious",messages:{pass:function(a){return"Element's title attribute is unique"},fail:function(a){return"Element's title attribute is not unique"}}},"heading-order":{impact:"moderate",messages:{pass:function(a){return"Heading order valid"},fail:function(a){return"Heading order invalid"}}},"hidden-content":{impact:"minor",messages:{pass:function(a){return"All content on the page has been analyzed."},fail:function(a){return"There were problems analyzing the content on this page."},incomplete:function(a){return"There is hidden content on the page that was not analyzed. You will need to trigger the display of this content in order to analyze it."}}},"href-no-hash":{impact:"moderate",messages:{pass:function(a){return"Anchor does not have an href value of #"},fail:function(a){return"Anchor has an href value of #"}}},"has-lang":{impact:"serious",messages:{pass:function(a){return"The <html> element has a lang attribute"},fail:function(a){return"The <html> element does not have a lang attribute"}}},"valid-lang":{impact:"serious",messages:{pass:function(a){return"Value of lang attribute is included in the list of valid languages"},fail:function(a){return"Value of lang attribute not included in the list of valid languages"}}},"has-alt":{impact:"critical",messages:{pass:function(a){return"Element has an alt attribute"},fail:function(a){return"Element does not have an alt attribute"}}},"duplicate-img-label":{impact:"minor",messages:{pass:function(a){return"Element does not duplicate existing text in <img> alt text"},fail:function(a){return"Element contains <img> element with alt text that duplicates existing text"}}},"title-only":{impact:"serious",messages:{pass:function(a){return"Form element does not solely use title attribute for its label"},fail:function(a){return"Only title used to generate label for form element"}}},"implicit-label":{impact:"critical",messages:{pass:function(a){return"Form element has an implicit (wrapped) <label>"},fail:function(a){return"Form element does not have an implicit (wrapped) <label>"}}},"explicit-label":{impact:"critical",messages:{pass:function(a){return"Form element has an explicit <label>"},fail:function(a){return"Form element does not have an explicit <label>"}}},"help-same-as-label":{impact:"minor",messages:{pass:function(a){return"Help text (title or aria-describedby) does not duplicate label text"},fail:function(a){return"Help text (title or aria-describedby) text is the same as the label text"}}},"multiple-label":{impact:"serious",messages:{pass:function(a){return"Form element does not have multiple <label> elements"},fail:function(a){return"Form element has multiple <label> elements"}}},"has-th":{impact:"serious",messages:{pass:function(a){return"Layout table does not use <th> elements"},fail:function(a){return"Layout table uses <th> elements"}}},"has-caption":{impact:"serious",messages:{pass:function(a){return"Layout table does not use <caption> element"},fail:function(a){return"Layout table uses <caption> element"}}},"has-summary":{impact:"serious",messages:{pass:function(a){return"Layout table does not use summary attribute"},fail:function(a){return"Layout table uses summary attribute"}}},"link-in-text-block":{impact:"serious",messages:{pass:function(a){return"Links can be distinguished from surrounding text in a way that does not rely on color"},fail:function(a){return"Links can not be distinguished from surrounding text in a way that does not rely on color"},incomplete:{bgContrast:"Element's contrast ratio could not be determined. Check for a distinct hover/focus style",bgImage:"Element's contrast ratio could not be determined due to a background image",bgGradient:"Element's contrast ratio could not be determined due to a background gradient",imgNode:"Element's contrast ratio could not be determined because element contains an image node",bgOverlap:"Element's contrast ratio could not be determined because of element overlap",default:"Unable to determine contrast ratio"}}},"only-listitems":{impact:"serious",messages:{pass:function(a){return"List element only has direct children that are allowed inside <li> elements"},fail:function(a){return"List element has direct children that are not allowed inside <li> elements"}}},listitem:{impact:"serious",messages:{pass:function(a){return'List item has a <ul>, <ol> or role="list" parent element'},fail:function(a){return'List item does not have a <ul>, <ol> or role="list" parent element'}}},"meta-refresh":{impact:"critical",messages:{pass:function(a){return"<meta> tag does not immediately refresh the page"},fail:function(a){return"<meta> tag forces timed refresh of page"}}},"meta-viewport-large":{impact:"minor",messages:{pass:function(a){return"<meta> tag does not prevent significant zooming on mobile devices"},fail:function(a){return"<meta> tag limits zooming on mobile devices"}}},"meta-viewport":{impact:"critical",messages:{pass:function(a){return"<meta> tag does not disable zooming on mobile devices"},fail:function(a){return"<meta> tag disables zooming on mobile devices"}}},"p-as-heading":{impact:"serious",messages:{pass:function(a){return"<p> elements are not styled as headings"},fail:function(a){return"Heading elements should be used instead of styled p elements"}}},region:{impact:"moderate",messages:{pass:function(a){return"Content contained by ARIA landmark"},fail:function(a){return"Content not contained by an ARIA landmark"}}},"html5-scope":{impact:"moderate",messages:{pass:function(a){return"Scope attribute is only used on table header elements (<th>)"},fail:function(a){return"In HTML 5, scope attributes may only be used on table header elements (<th>)"}}},"scope-value":{impact:"critical",messages:{pass:function(a){return"Scope attribute is used correctly"},fail:function(a){return"The value of the scope attribute may only be 'row' or 'col'"}}},exists:{impact:"minor",messages:{pass:function(a){return"Element does not exist"},fail:function(a){return"Element exists"}}},"skip-link":{impact:"moderate",messages:{pass:function(a){return"Valid skip link found"},fail:function(a){return"No valid skip link found"}}},tabindex:{impact:"serious",messages:{pass:function(a){return"Element does not have a tabindex greater than 0"},fail:function(a){return"Element has a tabindex greater than 0"}}},"same-caption-summary":{impact:"minor",messages:{pass:function(a){return"Content of summary attribute and <caption> are not duplicated"},fail:function(a){return"Content of summary attribute and <caption> element are identical"}}},"caption-faked":{impact:"serious",messages:{pass:function(a){return"The first row of a table is not used as a caption"},fail:function(a){return"The first row of the table should be a caption instead of a table cell"}}},"td-has-header":{impact:"critical",messages:{pass:function(a){return"All non-empty data cells have table headers"},fail:function(a){return"Some non-empty data cells do not have table headers"}}},"td-headers-attr":{impact:"serious",messages:{pass:function(a){return"The headers attribute is exclusively used to refer to other cells in the table"},fail:function(a){return"The headers attribute is not exclusively used to refer to other cells in the table"}}},"th-has-data-cells":{impact:"serious",messages:{pass:function(a){return"All table header cells refer to data cells"},fail:function(a){return"Not all table header cells refer to data cells"},incomplete:function(a){return"Table data cells are missing or empty"}}},description:{impact:"critical",messages:{pass:function(a){ +return"The multimedia element has an audio description track"},fail:function(a){return"The multimedia element does not have an audio description track"},incomplete:function(a){return"An audio description track for this element could not be found"}}}},failureSummaries:{any:{failureMessage:function(a){var b="Fix any of the following:",c=a;if(c)for(var d,e=-1,f=c.length-1;e<f;)d=c[e+=1],b+="\n "+d.split("\n").join("\n ");return b}},none:{failureMessage:function(a){var b="Fix all of the following:",c=a;if(c)for(var d,e=-1,f=c.length-1;e<f;)d=c[e+=1],b+="\n "+d.split("\n").join("\n ");return b}}},incompleteFallbackMessage:function(a){return"aXe couldn't tell the reason. Time to break out the element inspector!"}},rules:[{id:"accesskeys",selector:"[accesskey]",excludeHidden:!1,tags:["wcag2a","wcag211","cat.keyboard"],all:[],any:[],none:["accesskeys"]},{id:"area-alt",selector:"map area[href]",excludeHidden:!1,tags:["cat.text-alternatives","wcag2a","wcag111","section508","section508.22.a"],all:[],any:["non-empty-alt","non-empty-title","aria-label","aria-labelledby"],none:[]},{id:"aria-allowed-attr",matches:function(a,b){var c=a.getAttribute("role");c||(c=axe.commons.aria.implicitRole(a));var d=axe.commons.aria.allowedAttr(c);if(c&&d){var e=/^aria-/;if(a.hasAttributes())for(var f=a.attributes,g=0,h=f.length;g<h;g++)if(e.test(f[g].name))return!0}return!1},tags:["cat.aria","wcag2a","wcag411","wcag412"],all:[],any:["aria-allowed-attr"],none:[]},{id:"aria-hidden-body",selector:"body",excludeHidden:!1,tags:["cat.aria","wcag2a","wcag412"],all:[],any:["aria-hidden-body"],none:[]},{id:"aria-required-attr",selector:"[role]",tags:["cat.aria","wcag2a","wcag411","wcag412"],all:[],any:["aria-required-attr"],none:[]},{id:"aria-required-children",selector:"[role]",tags:["cat.aria","wcag2a","wcag131"],all:[],any:["aria-required-children"],none:[]},{id:"aria-required-parent",selector:"[role]",tags:["cat.aria","wcag2a","wcag131"],all:[],any:["aria-required-parent"],none:[]},{id:"aria-roles",selector:"[role]",tags:["cat.aria","wcag2a","wcag131","wcag411","wcag412"],all:[],any:[],none:["invalidrole","abstractrole"]},{id:"aria-valid-attr-value",matches:function(a,b){var c=/^aria-/;if(a.hasAttributes())for(var d=a.attributes,e=0,f=d.length;e<f;e++)if(c.test(d[e].name))return!0;return!1},tags:["cat.aria","wcag2a","wcag131","wcag411","wcag412"],all:[],any:[{options:[],id:"aria-valid-attr-value"}],none:[]},{id:"aria-valid-attr",matches:function(a,b){var c=/^aria-/;if(a.hasAttributes())for(var d=a.attributes,e=0,f=d.length;e<f;e++)if(c.test(d[e].name))return!0;return!1},tags:["cat.aria","wcag2a","wcag411"],all:[],any:[{options:[],id:"aria-valid-attr"}],none:[]},{id:"audio-caption",selector:"audio",excludeHidden:!1,tags:["cat.time-and-media","wcag2a","wcag122","section508","section508.22.a"],all:[],any:[],none:["caption"]},{id:"blink",selector:"blink",excludeHidden:!1,tags:["cat.time-and-media","wcag2a","wcag222","section508","section508.22.j"],all:[],any:[],none:["is-on-screen"]},{id:"button-name",selector:'button, [role="button"], input[type="button"], input[type="submit"], input[type="reset"]',tags:["cat.name-role-value","wcag2a","wcag412","section508","section508.22.a"],all:[],any:["non-empty-if-present","non-empty-value","button-has-visible-text","aria-label","aria-labelledby","role-presentation","role-none"],none:["focusable-no-name"]},{id:"bypass",selector:"html",pageLevel:!0,matches:function(a,b){return!!a.querySelector("a[href]")},tags:["cat.keyboard","wcag2a","wcag241","section508","section508.22.o"],all:[],any:["internal-link-present","header-present","landmark"],none:[]},{id:"checkboxgroup",selector:"input[type=checkbox][name]",tags:["cat.forms","best-practice"],all:[],any:["group-labelledby","fieldset"],none:[]},{id:"color-contrast",matches:function(a,b){var c=a.nodeName.toUpperCase(),d=a.type;if("true"===a.getAttribute("aria-disabled")||axe.commons.dom.findUp(a,'[aria-disabled="true"]'))return!1;if("INPUT"===c)return-1===["hidden","range","color","checkbox","radio","image"].indexOf(d)&&!a.disabled;if("SELECT"===c)return!!a.options.length&&!a.disabled;if("TEXTAREA"===c)return!a.disabled;if("OPTION"===c)return!1;if("BUTTON"===c&&a.disabled||axe.commons.dom.findUp(a,"button[disabled]"))return!1;if("FIELDSET"===c&&a.disabled||axe.commons.dom.findUp(a,"fieldset[disabled]"))return!1;var e=axe.commons.dom.findUp(a,"label");if("LABEL"===c||e){var f=a;e&&(f=e);var g=axe.commons.dom.getRootNode(f),h=f.htmlFor&&g.getElementById(f.htmlFor);if(h&&h.disabled)return!1;var h=axe.utils.querySelectorAll(b,'input:not([type="hidden"]):not([type="image"]):not([type="button"]):not([type="submit"]):not([type="reset"]), select, textarea');if(h.length&&h[0].actualNode.disabled)return!1}if(a.getAttribute("id")){var i=axe.commons.utils.escapeSelector(a.getAttribute("id")),j=axe.commons.dom.getRootNode(a),h=j.querySelector("[aria-labelledby~="+i+"]");if(h&&h.disabled)return!1}if(""===axe.commons.text.visible(b,!1,!0))return!1;var k,l,m=document.createRange(),n=b.children,o=n.length;for(l=0;l<o;l++)k=n[l],3===k.actualNode.nodeType&&""!==axe.commons.text.sanitize(k.actualNode.nodeValue)&&m.selectNodeContents(k.actualNode);var p=m.getClientRects();for(o=p.length,l=0;l<o;l++)if(axe.commons.dom.visuallyOverlaps(p[l],a))return!0;return!1},excludeHidden:!1,options:{noScroll:!1},tags:["cat.color","wcag2aa","wcag143"],all:[],any:["color-contrast"],none:[]},{id:"definition-list",selector:"dl",matches:function(a,b){return!a.getAttribute("role")},tags:["cat.structure","wcag2a","wcag131"],all:[],any:[],none:["structured-dlitems","only-dlitems"]},{id:"dlitem",selector:"dd, dt",matches:function(a,b){return!a.getAttribute("role")},tags:["cat.structure","wcag2a","wcag131"],all:[],any:["dlitem"],none:[]},{id:"document-title",selector:"html",matches:function(a,b){return a.ownerDocument.defaultView.self===a.ownerDocument.defaultView.top},tags:["cat.text-alternatives","wcag2a","wcag242"],all:[],any:["doc-has-title"],none:[]},{id:"duplicate-id",selector:"[id]",excludeHidden:!1,tags:["cat.parsing","wcag2a","wcag411"],all:[],any:["duplicate-id"],none:[]},{id:"empty-heading",selector:'h1, h2, h3, h4, h5, h6, [role="heading"]',enabled:!0,tags:["cat.name-role-value","best-practice"],all:[],any:["has-visible-text","role-presentation","role-none"],none:[]},{id:"frame-title-unique",selector:"frame[title], iframe[title]",matches:function(a,b){var c=a.getAttribute("title");return!!(c?axe.commons.text.sanitize(c).trim():"")},tags:["cat.text-alternatives","best-practice"],all:[],any:[],none:["unique-frame-title"]},{id:"frame-title",selector:"frame, iframe",tags:["cat.text-alternatives","wcag2a","wcag241","section508","section508.22.i"],all:[],any:["aria-label","aria-labelledby","non-empty-title","role-presentation","role-none"],none:[]},{id:"heading-order",selector:"h1,h2,h3,h4,h5,h6,[role=heading]",enabled:!1,tags:["cat.semantics","best-practice"],all:[],any:["heading-order"],none:[]},{id:"hidden-content",selector:"*",excludeHidden:!1,tags:["experimental","review-item"],all:[],any:["hidden-content"],none:[],enabled:!1},{id:"href-no-hash",selector:"a[href]",enabled:!1,tags:["cat.semantics","best-practice"],all:[],any:["href-no-hash"],none:[]},{id:"html-has-lang",selector:"html",tags:["cat.language","wcag2a","wcag311"],all:[],any:["has-lang"],none:[]},{id:"html-lang-valid",selector:"html[lang]",tags:["cat.language","wcag2a","wcag311"],all:[],any:[],none:["valid-lang"]},{id:"image-alt",selector:"img, [role='img']",tags:["cat.text-alternatives","wcag2a","wcag111","section508","section508.22.a"],all:[],any:["has-alt","aria-label","aria-labelledby","non-empty-title","role-presentation","role-none"],none:[]},{id:"image-redundant-alt",selector:'button, [role="button"], a[href], p, li, td, th',tags:["cat.text-alternatives","best-practice"],all:[],any:[],none:["duplicate-img-label"]},{id:"input-image-alt",selector:'input[type="image"]',tags:["cat.text-alternatives","wcag2a","wcag111","section508","section508.22.a"],all:[],any:["non-empty-alt","aria-label","aria-labelledby","non-empty-title"],none:[]},{id:"label-title-only",selector:"input, select, textarea",matches:function(a,b){if("input"!==a.nodeName.toLowerCase())return!0;var c=a.getAttribute("type").toLowerCase();return"hidden"!==c&&"image"!==c&&"button"!==c&&"submit"!==c&&"reset"!==c},enabled:!1,tags:["cat.forms","best-practice"],all:[],any:[],none:["title-only"]},{id:"label",selector:"input, select, textarea",matches:function(a,b){if("input"!==a.nodeName.toLowerCase())return!0;var c=a.getAttribute("type").toLowerCase();return"hidden"!==c&&"image"!==c&&"button"!==c&&"submit"!==c&&"reset"!==c},tags:["cat.forms","wcag2a","wcag332","wcag131","section508","section508.22.n"],all:[],any:["aria-label","aria-labelledby","implicit-label","explicit-label","non-empty-title"],none:["help-same-as-label","multiple-label"]},{id:"layout-table",selector:"table",matches:function(a,b){return!axe.commons.table.isDataTable(a)},tags:["cat.semantics","wcag2a","wcag131"],all:[],any:[],none:["has-th","has-caption","has-summary"]},{id:"link-in-text-block",selector:"a[href], *[role=link]",matches:function(a,b){var c=axe.commons.text.sanitize(a.textContent),d=a.getAttribute("role");return(!d||"link"===d)&&(!!c&&(!!axe.commons.dom.isVisible(a,!1)&&axe.commons.dom.isInTextBlock(a)))},excludeHidden:!1,tags:["cat.color","experimental","wcag2a","wcag141"],all:["link-in-text-block"],any:[],none:[]},{id:"link-name",selector:"a[href], [role=link][href]",matches:function(a,b){return"button"!==a.getAttribute("role")},tags:["cat.name-role-value","wcag2a","wcag111","wcag412","wcag244","section508","section508.22.a"],all:[],any:["has-visible-text","aria-label","aria-labelledby","role-presentation","role-none"],none:["focusable-no-name"]},{id:"list",selector:"ul, ol",matches:function(a,b){return!a.getAttribute("role")},tags:["cat.structure","wcag2a","wcag131"],all:[],any:[],none:["only-listitems"]},{id:"listitem",selector:"li",matches:function(a,b){return!a.getAttribute("role")},tags:["cat.structure","wcag2a","wcag131"],all:[],any:["listitem"],none:[]},{id:"marquee",selector:"marquee",excludeHidden:!1,tags:["cat.parsing","wcag2a","wcag222"],all:[],any:[],none:["is-on-screen"]},{id:"meta-refresh",selector:'meta[http-equiv="refresh"]',excludeHidden:!1,tags:["cat.time","wcag2a","wcag2aaa","wcag221","wcag224","wcag325"],all:[],any:["meta-refresh"],none:[]},{id:"meta-viewport-large",selector:'meta[name="viewport"]',excludeHidden:!1,tags:["cat.sensory-and-visual-cues","best-practice"],all:[],any:[{options:{scaleMinimum:5,lowerBound:2},id:"meta-viewport-large"}],none:[]},{id:"meta-viewport",selector:'meta[name="viewport"]',excludeHidden:!1,tags:["cat.sensory-and-visual-cues","wcag2aa","wcag144"],all:[],any:[{options:{scaleMinimum:2},id:"meta-viewport"}],none:[]},{id:"object-alt",selector:"object",tags:["cat.text-alternatives","wcag2a","wcag111","section508","section508.22.a"],all:[],any:["has-visible-text","aria-label","aria-labelledby","non-empty-title"],none:[]},{id:"p-as-heading",selector:"p",matches:function(a,b){var c=Array.from(a.parentNode.childNodes),d=a.textContent.trim(),e=/[.!?:;](?![.!?:;])/g;return!(0===d.length||(d.match(e)||[]).length>=2)&&0!==c.slice(c.indexOf(a)+1).filter(function(a){return"P"===a.nodeName.toUpperCase()&&""!==a.textContent.trim()}).length},tags:["cat.semantics","wcag2a","wcag131","experimental"],all:[{options:{margins:[{weight:150,italic:!0},{weight:150,size:1.15},{italic:!0,size:1.15},{size:1.4}]},id:"p-as-heading"}],any:[],none:[]},{id:"radiogroup",selector:"input[type=radio][name]",tags:["cat.forms","best-practice"],all:[],any:["group-labelledby","fieldset"],none:[]},{id:"region",selector:"html",pageLevel:!0,enabled:!1,tags:["cat.keyboard","best-practice"],all:[],any:["region"],none:[]},{id:"scope-attr-valid",selector:"td[scope], th[scope]",enabled:!0,tags:["cat.tables","best-practice"],all:["html5-scope","scope-value"],any:[],none:[]},{id:"server-side-image-map",selector:"img[ismap]",tags:["cat.text-alternatives","wcag2a","wcag211","section508","section508.22.f"],all:[],any:[],none:["exists"]},{id:"skip-link",selector:"a[href]",pageLevel:!0,enabled:!1,tags:["cat.keyboard","best-practice"],all:[],any:["skip-link"],none:[]},{id:"tabindex",selector:"[tabindex]",tags:["cat.keyboard","best-practice"],all:[],any:["tabindex"],none:[]},{id:"table-duplicate-name",selector:"table",tags:["cat.tables","best-practice"],all:[],any:[],none:["same-caption-summary"]},{id:"table-fake-caption",selector:"table",matches:function(a,b){return axe.commons.table.isDataTable(a)},tags:["cat.tables","experimental","wcag2a","wcag131","section508","section508.22.g"],all:["caption-faked"],any:[],none:[]},{id:"td-has-header",selector:"table",matches:function(a,b){if(axe.commons.table.isDataTable(a)){var c=axe.commons.table.toArray(a);return c.length>=3&&c[0].length>=3&&c[1].length>=3&&c[2].length>=3}return!1},tags:["cat.tables","experimental","wcag2a","wcag131","section508","section508.22.g"],all:["td-has-header"],any:[],none:[]},{id:"td-headers-attr",selector:"table",tags:["cat.tables","wcag2a","wcag131","section508","section508.22.g"],all:["td-headers-attr"],any:[],none:[]},{id:"th-has-data-cells",selector:"table",matches:function(a,b){return axe.commons.table.isDataTable(a)},tags:["cat.tables","wcag2a","wcag131","section508","section508.22.g"],all:["th-has-data-cells"],any:[],none:[]},{id:"valid-lang",selector:"[lang], [xml\\:lang]",matches:function(a,b){return"html"!==a.nodeName.toLowerCase()},tags:["cat.language","wcag2aa","wcag312"],all:[],any:[],none:["valid-lang"]},{id:"video-caption",selector:"video",excludeHidden:!1,tags:["cat.text-alternatives","wcag2a","wcag122","wcag123","section508","section508.22.a"],all:[],any:[],none:["caption"]},{id:"video-description",selector:"video",excludeHidden:!1,tags:["cat.text-alternatives","wcag2aa","wcag125","section508","section508.22.b"],all:[],any:[],none:["description"]}],checks:[{id:"abstractrole",evaluate:function(a,b,c){return"abstract"===axe.commons.aria.getRoleType(a.getAttribute("role"))}},{id:"aria-allowed-attr",evaluate:function(a,b,c){var d,e,f,g=[],h=a.getAttribute("role"),i=a.attributes;if(h||(h=axe.commons.aria.implicitRole(a)),f=axe.commons.aria.allowedAttr(h),h&&f)for(var j=0,k=i.length;j<k;j++)d=i[j],e=d.name,axe.commons.aria.validateAttr(e)&&-1===f.indexOf(e)&&g.push(e+'="'+d.nodeValue+'"');return!g.length||(this.data(g),!1)}},{id:"aria-hidden-body",evaluate:function(a,b,c){return"true"!==a.getAttribute("aria-hidden")}},{id:"invalidrole",evaluate:function(a,b,c){return!axe.commons.aria.isValidRole(a.getAttribute("role"))}},{id:"aria-required-attr",evaluate:function(a,b,c){var d=[];if(a.hasAttributes()){var e,f=a.getAttribute("role"),g=axe.commons.aria.requiredAttr(f);if(f&&g)for(var h=0,i=g.length;h<i;h++)e=g[h],a.getAttribute(e)||d.push(e)}return!d.length||(this.data(d),!1)}},{id:"aria-required-children",evaluate:function(a,b,c){function d(a,b,c,d){if(null===a)return!1;var e=g(c),f=['[role="'+c+'"]'];return e&&(f=f.concat(e)),f=f.join(","),d?h(a,f)||!!axe.utils.querySelectorAll(b,f)[0]:!!axe.utils.querySelectorAll(b,f)[0]}function e(a,b){var c,e;for(c=0,e=a.length;c<e;c++)if(null!==a[c]){var f=axe.utils.getNodeFromTree(axe._tree[0],a[c]);if(d(a[c],f,b,!0))return!0}return!1}var f=axe.commons.aria.requiredOwned,g=axe.commons.aria.implicitNodes,h=axe.commons.utils.matchesSelector,i=axe.commons.dom.idrefs,j=a.getAttribute("role"),k=f(j);if(!k)return!0;var l=!1,m=k.one;if(!m){var l=!0;m=k.all}var n=function(a,b,f){var g,h=b.length,j=[],k=i(a,"aria-owns");for(g=0;g<h;g++){var l=b[g];if(d(a,c,l)||e(k,l)){if(!f)return null}else f&&j.push(l)}return j.length?j:!f&&b.length?b:null}(a,m,l);return!n||(this.data(n),!1)}},{id:"aria-required-parent",evaluate:function(a,b,c){function d(a){return(axe.commons.aria.implicitNodes(a)||[]).concat('[role="'+a+'"]').join(",")}function e(a,b,c){var e,f,g=a.getAttribute("role"),h=[];if(b||(b=axe.commons.aria.requiredContext(g)),!b)return null;for(e=0,f=b.length;e<f;e++){if(c&&axe.utils.matchesSelector(a,d(b[e])))return null;if(axe.commons.dom.findUp(a,d(b[e])))return null;h.push(b[e])}return h}var f=e(a);if(!f)return!0;var g=function(a){for(var b=[],c=null;a;){if(a.getAttribute("id")){var d=axe.commons.utils.escapeSelector(a.getAttribute("id"));c=axe.commons.dom.getRootNode(a).querySelector("[aria-owns~="+d+"]"),c&&b.push(c)}a=a.parentElement}return b.length?b:null}(a);if(g)for(var h=0,i=g.length;h<i;h++)if(!(f=e(g[h],f,!0)))return!0;return this.data(f),!1}},{id:"aria-valid-attr-value",evaluate:function(a,b,c){b=Array.isArray(b)?b:[];for(var d,e,f=[],g=/^aria-/,h=a.attributes,i=0,j=h.length;i<j;i++)d=h[i],e=d.name,-1===b.indexOf(e)&&g.test(e)&&!axe.commons.aria.validateAttrValue(a,e)&&f.push(e+'="'+d.nodeValue+'"');return!f.length||(this.data(f),!1)},options:[]},{id:"aria-valid-attr",evaluate:function(a,b,c){b=Array.isArray(b)?b:[];for(var d,e=[],f=/^aria-/,g=a.attributes,h=0,i=g.length;h<i;h++)d=g[h].name,-1===b.indexOf(d)&&f.test(d)&&!axe.commons.aria.validateAttr(d)&&e.push(d);return!e.length||(this.data(e),!1)},options:[]},{id:"color-contrast",evaluate:function(a,b,c){if(!axe.commons.dom.isVisible(a,!1))return!0;var d,e=!!(b||{}).noScroll,f=[],g=axe.commons.color.getBackgroundColor(a,f,e),h=axe.commons.color.getForegroundColor(a,e),i=window.getComputedStyle(a),j=parseFloat(i.getPropertyValue("font-size")),k=i.getPropertyValue("font-weight"),l=-1!==["bold","bolder","600","700","800","900"].indexOf(k),m=axe.commons.color.hasValidContrastRatio(g,h,j,l),n=Math.floor(100*m.contrastRatio)/100;null===g&&(d=axe.commons.color.incompleteData.get("bgColor"));var o=!1;1===n&&(o=!0,d=axe.commons.color.incompleteData.set("bgColor","equalRatio"));var p={fgColor:h?h.toHexString():void 0,bgColor:g?g.toHexString():void 0,contrastRatio:m?n:void 0,fontSize:(72*j/96).toFixed(1)+"pt",fontWeight:l?"bold":"normal",missingData:d};return this.data(p),null===h||null===g||o?(d=null,axe.commons.color.incompleteData.clear(),void this.relatedNodes(f)):(m.isValid||this.relatedNodes(f),m.isValid)}},{id:"link-in-text-block",evaluate:function(a,b,c){function d(a,b){var c=a.getRelativeLuminance(),d=b.getRelativeLuminance();return(Math.max(c,d)+.05)/(Math.min(c,d)+.05)}function e(a){var b=window.getComputedStyle(a).getPropertyValue("display");return-1!==i.indexOf(b)||"table-"===b.substr(0,6)}var f=axe.commons,g=f.color,h=f.dom,i=["block","list-item","table","flex","grid","inline-block"];if(e(a))return!1;for(var j=h.getComposedParent(a);1===j.nodeType&&!e(j);)j=h.getComposedParent(j);if(this.relatedNodes([j]),g.elementIsDistinct(a,j))return!0;var k,l;if(k=g.getForegroundColor(a),l=g.getForegroundColor(j),k&&l){var m=d(k,l);if(1===m)return!0;if(m>=3)return axe.commons.color.incompleteData.set("fgColor","bgContrast"),this.data({missingData:axe.commons.color.incompleteData.get("fgColor")}),void axe.commons.color.incompleteData.clear();if(k=g.getBackgroundColor(a),l=g.getBackgroundColor(j),!k||!l||d(k,l)>=3){var n=void 0;return n=k&&l?"bgContrast":axe.commons.color.incompleteData.get("bgColor"),axe.commons.color.incompleteData.set("fgColor",n),this.data({missingData:axe.commons.color.incompleteData.get("fgColor")}),void axe.commons.color.incompleteData.clear()}return!1}}},{id:"fieldset",evaluate:function(a,b,c){function d(a,b){return axe.commons.utils.toArray(a.querySelectorAll('select,textarea,button,input:not([name="'+b+'"]):not([type="hidden"])'))}function e(a,b){var c=a.firstElementChild;if(!c||"LEGEND"!==c.nodeName.toUpperCase())return i.relatedNodes([a]),h="no-legend",!1;if(!axe.commons.text.accessibleText(c))return i.relatedNodes([c]),h="empty-legend",!1;var e=d(a,b);return!e.length||(i.relatedNodes(e),h="mixed-inputs",!1)}function f(a,b){var c=axe.commons.dom.idrefs(a,"aria-labelledby").some(function(a){return a&&axe.commons.text.accessibleText(a)}),e=a.getAttribute("aria-label");if(!(c||e&&axe.commons.text.sanitize(e)))return i.relatedNodes(a),h="no-group-label",!1;var f=d(a,b);return!f.length||(i.relatedNodes(f),h="group-mixed-inputs",!1)}function g(a,b){return axe.commons.utils.toArray(a).filter(function(a){return a!==b})}var h,i=this,j={name:a.getAttribute("name"),type:a.getAttribute("type")},k=function(b){var c=axe.commons.utils.escapeSelector(a.name),d=axe.commons.dom.getRootNode(a),j=d.querySelectorAll('input[type="'+axe.commons.utils.escapeSelector(a.type)+'"][name="'+c+'"]');if(j.length<2)return!0;var k=axe.commons.dom.findUp(b,"fieldset"),l=axe.commons.dom.findUp(b,'[role="group"]'+("radio"===a.type?',[role="radiogroup"]':""));return l||k?k?e(k,c):f(l,c):(h="no-group",i.relatedNodes(g(j,b)),!1)}(a);return k||(j.failureCode=h),this.data(j),k},after:function(a,b){var c={};return a.filter(function(a){if(a.result)return!0;var b=a.data;if(b){if(c[b.type]=c[b.type]||{},!c[b.type][b.name])return c[b.type][b.name]=[b],!0;var d=c[b.type][b.name].some(function(a){return a.failureCode===b.failureCode});return d||c[b.type][b.name].push(b),!d}return!1})}},{id:"group-labelledby",evaluate:function(a,b,c){this.data({name:a.getAttribute("name"),type:a.getAttribute("type")});var d=axe.commons.dom.getRootNode(a),e=d.querySelectorAll('input[type="'+axe.commons.utils.escapeSelector(a.type)+'"][name="'+axe.commons.utils.escapeSelector(a.name)+'"]');return e.length<=1||0!==[].map.call(e,function(a){var b=a.getAttribute("aria-labelledby");return b?b.split(/\s+/):[]}).reduce(function(a,b){return a.filter(function(a){return b.includes(a)})}).filter(function(a){var b=d.getElementById(a);return b&&axe.commons.text.accessibleText(b)}).length},after:function(a,b){var c={};return a.filter(function(a){var b=a.data;return!(!b||(c[b.type]=c[b.type]||{},c[b.type][b.name]))&&(c[b.type][b.name]=!0,!0)})}},{id:"accesskeys",evaluate:function(a,b,c){return axe.commons.dom.isVisible(a,!1)&&(this.data(a.getAttribute("accesskey")),this.relatedNodes([a])),!0},after:function(a,b){var c={};return a.filter(function(a){if(!a.data)return!1;var b=a.data.toUpperCase();return c[b]?(c[b].relatedNodes.push(a.relatedNodes[0]),!1):(c[b]=a,a.relatedNodes=[],!0)}).map(function(a){return a.result=!!a.relatedNodes.length,a})}},{id:"focusable-no-name",evaluate:function(a,b,c){var d=a.getAttribute("tabindex");return!!(axe.commons.dom.isFocusable(a)&&d>-1)&&!axe.commons.text.accessibleText(a)}},{id:"tabindex",evaluate:function(a,b,c){return a.tabIndex<=0}},{id:"duplicate-img-label",evaluate:function(a,b,c){var d=axe.commons.text.visible(c,!0).toLowerCase();return""!==d&&axe.utils.querySelectorAll(c,"img").filter(function(a){var b=a.actualNode;return axe.commons.dom.isVisible(b)&&!["none","presentation"].includes(b.getAttribute("role"))}).some(function(a){return d===axe.commons.text.accessibleText(a).toLowerCase()})}},{id:"explicit-label",evaluate:function(a,b,c){if(a.getAttribute("id")){var d=axe.commons.dom.getRootNode(a),e=axe.commons.utils.escapeSelector(a.getAttribute("id")),f=d.querySelector('label[for="'+e+'"]');if(f)return!!axe.commons.text.accessibleText(f)}return!1}},{id:"help-same-as-label",evaluate:function(a,b,c){var d=axe.commons.text.label(c),e=a.getAttribute("title");if(!d)return!1;if(!e&&(e="",a.getAttribute("aria-describedby"))){e=axe.commons.dom.idrefs(a,"aria-describedby").map(function(a){return a?axe.commons.text.accessibleText(a):""}).join("")}return axe.commons.text.sanitize(e)===axe.commons.text.sanitize(d)},enabled:!1},{id:"implicit-label",evaluate:function(a,b,c){var d=axe.commons.dom.findUp(a,"label");return!!d&&!!axe.commons.text.accessibleText(d)}},{id:"multiple-label",evaluate:function(a,b,c){var d=axe.commons.utils.escapeSelector(a.getAttribute("id")),e=Array.from(document.querySelectorAll('label[for="'+d+'"]')),f=a.parentNode;for(e.length&&(e=e.filter(function(a,b){if(0===b&&!axe.commons.dom.isVisible(a,!0)||axe.commons.dom.isVisible(a,!0))return a}));f;)"LABEL"===f.tagName&&-1===e.indexOf(f)&&e.push(f),f=f.parentNode;return this.relatedNodes(e),e.length>1}},{id:"title-only",evaluate:function(a,b,c){return!(axe.commons.text.label(c)||!a.getAttribute("title")&&!a.getAttribute("aria-describedby"))}},{id:"has-lang",evaluate:function(a,b,c){return!!(a.getAttribute("lang")||a.getAttribute("xml:lang")||"").trim()}},{id:"valid-lang",evaluate:function(a,b,c){function d(a){return a.trim().split("-")[0].toLowerCase()}var e,f;return e=(b||axe.commons.utils.validLangs()).map(d),f=["lang","xml:lang"].reduce(function(b,c){var f=a.getAttribute(c);if("string"!=typeof f)return b;var g=d(f);return""!==g&&-1===e.indexOf(g)&&b.push(c+'="'+a.getAttribute(c)+'"'),b},[]),!!f.length&&(this.data(f),!0)}},{id:"dlitem",evaluate:function(a,b,c){return"DL"===axe.commons.dom.getComposedParent(a).nodeName.toUpperCase()}},{id:"has-listitem",evaluate:function(a,b,c){return c.children.every(function(a){return"LI"!==a.actualNode.nodeName.toUpperCase()})}},{id:"listitem",evaluate:function(a,b,c){var d=axe.commons.dom.getComposedParent(a);return["UL","OL"].includes(d.nodeName.toUpperCase())||"list"===(d.getAttribute("role")||"").toLowerCase()}},{id:"only-dlitems",evaluate:function(a,b,c){var d=[],e=["STYLE","META","LINK","MAP","AREA","SCRIPT","DATALIST","TEMPLATE"],f=!1;return c.children.forEach(function(a){var b=a.actualNode,c=b.nodeName.toUpperCase();1===b.nodeType&&"DT"!==c&&"DD"!==c&&-1===e.indexOf(c)?d.push(b):3===b.nodeType&&""!==b.nodeValue.trim()&&(f=!0)}),d.length&&this.relatedNodes(d),!!d.length||f}},{id:"only-listitems",evaluate:function(a,b,c){var d=[],e=["STYLE","META","LINK","MAP","AREA","SCRIPT","DATALIST","TEMPLATE"],f=!1;return c.children.forEach(function(a){var b=a.actualNode,c=b.nodeName.toUpperCase();1===b.nodeType&&"LI"!==c&&-1===e.indexOf(c)?d.push(b):3===b.nodeType&&""!==b.nodeValue.trim()&&(f=!0)}),d.length&&this.relatedNodes(d),!!d.length||f}},{id:"structured-dlitems",evaluate:function(a,b,c){var d=c.children;if(!d||!d.length)return!1;for(var e,f=!1,g=!1,h=0;h<d.length;h++){if(e=d[h].actualNode.nodeName.toUpperCase(),"DT"===e&&(f=!0),f&&"DD"===e)return!1;"DD"===e&&(g=!0)}return f||g}},{id:"caption",evaluate:function(a,b,c){var d=axe.utils.querySelectorAll(c,"track");if(d.length)return!d.some(function(a){return"captions"===(a.actualNode.getAttribute("kind")||"").toLowerCase()})}},{id:"description",evaluate:function(a,b,c){var d=axe.utils.querySelectorAll(c,"track");if(d.length){var e=!d.some(function(a){return"descriptions"===(a.actualNode.getAttribute("kind")||"").toLowerCase()});return axe.log(d.map(function(a){return a.actualNode.getAttribute("kind")}),e),e}}},{id:"meta-viewport-large",evaluate:function(a,b,c){b=b||{};for(var d,e=a.getAttribute("content")||"",f=e.split(/[;,]/),g={},h=b.scaleMinimum||2,i=b.lowerBound||!1,j=0,k=f.length;j<k;j++){d=f[j].split("=");var l=d.shift().toLowerCase();l&&d.length&&(g[l.trim()]=d.shift().trim().toLowerCase())}return!!(i&&g["maximum-scale"]&&parseFloat(g["maximum-scale"])<i)||!(!i&&"no"===g["user-scalable"])&&!(g["maximum-scale"]&&parseFloat(g["maximum-scale"])<h)},options:{scaleMinimum:5,lowerBound:2}},{id:"meta-viewport",evaluate:function(a,b,c){b=b||{};for(var d,e=a.getAttribute("content")||"",f=e.split(/[;,]/),g={},h=b.scaleMinimum||2,i=b.lowerBound||!1,j=0,k=f.length;j<k;j++){d=f[j].split("=");var l=d.shift().toLowerCase();l&&d.length&&(g[l.trim()]=d.shift().trim().toLowerCase())}return!!(i&&g["maximum-scale"]&&parseFloat(g["maximum-scale"])<i)||!(!i&&"no"===g["user-scalable"])&&!(g["maximum-scale"]&&parseFloat(g["maximum-scale"])<h)},options:{scaleMinimum:2}},{id:"header-present",evaluate:function(a,b,c){return!!a.querySelector('h1, h2, h3, h4, h5, h6, [role="heading"]')}},{id:"heading-order",evaluate:function(a,b,c){var d=a.getAttribute("aria-level");if(null!==d)return this.data(parseInt(d,10)),!0;var e=a.tagName.match(/H(\d)/);return!e||(this.data(parseInt(e[1],10)),!0)},after:function(a,b){if(a.length<2)return a;for(var c=a[0].data,d=1;d<a.length;d++)a[d].result&&a[d].data>c+1&&(a[d].result=!1),c=a[d].data;return a}},{id:"href-no-hash",evaluate:function(a,b,c){return"#"!==a.getAttribute("href")}},{id:"internal-link-present",evaluate:function(a,b,c){return!!a.querySelector('a[href^="#"]')}},{id:"landmark",evaluate:function(a,b,c){return axe.utils.querySelectorAll(c,'main, [role="main"]').length>0}},{id:"meta-refresh",evaluate:function(a,b,c){var d=a.getAttribute("content")||"",e=d.split(/[;,]/);return""===d||"0"===e[0]}},{id:"p-as-heading",evaluate:function(a,b,c){function d(a){for(var b=a,c=a.textContent.trim(),d=c;d===c&&void 0!==b;){var e=-1;if(a=b,0===a.children.length)return a;do{e++,d=a.children[e].textContent.trim()}while(""===d&&e+1<a.children.length);b=a.children[e]}return a}function e(a){switch(a){case"lighter":return 100;case"normal":return 400;case"bold":return 700;case"bolder":return 900}return a=parseInt(a),isNaN(a)?400:a}function f(a){var b=window.getComputedStyle(d(a));return{fontWeight:e(b.getPropertyValue("font-weight")),fontSize:parseInt(b.getPropertyValue("font-size")),isItalic:"italic"===b.getPropertyValue("font-style")}}function g(a,b,c){return c.reduce(function(c,d){return c||(!d.size||a.fontSize/d.size>b.fontSize)&&(!d.weight||a.fontWeight-d.weight>b.fontWeight)&&(!d.italic||a.isItalic&&!b.isItalic)},!1)}var h=Array.from(a.parentNode.children),i=h.indexOf(a);b=b||{};var j=b.margins||[],k=h.slice(i+1).find(function(a){return"P"===a.nodeName.toUpperCase()}),l=h.slice(0,i).reverse().find(function(a){return"P"===a.nodeName.toUpperCase()}),m=f(a),n=k?f(k):null,o=l?f(l):null;if(!n||!g(m,n,j))return!0;var p=axe.commons.dom.findUp(a,"blockquote");return!!(p&&"BLOCKQUOTE"===p.nodeName.toUpperCase()||o&&!g(m,o,j))&&void 0},options:{margins:[{weight:150,italic:!0},{weight:150,size:1.15},{italic:!0,size:1.15},{size:1.4}]}},{id:"region",evaluate:function(a,b,c){function d(a){return j&&j===a}function e(a){return a.hasAttribute("role")?k.includes(a.getAttribute("role").toLowerCase()):l.includes(a.nodeName.toUpperCase())}function f(a){var b=a.actualNode;return e(b)||d(b)||!h.isVisible(b,!0)?[]:h.hasContent(b,!0)?[b]:a.children.filter(function(a){return 1===a.actualNode.nodeType}).map(f).reduce(function(a,b){return a.concat(b)},[])}var g=axe.commons,h=g.dom,i=g.aria,j=function(a){var b=axe.utils.querySelectorAll(a,"a[href]")[0];if(b&&axe.commons.dom.getElementByReference(b.actualNode,"href"))return b.actualNode}(c),k=i.getRolesByType("landmark"),l=k.reduce(function(a,b){return a.concat(i.implicitNodes(b))},[]).filter(function(a){return null!==a}).map(function(a){return a.toUpperCase()}),m=f(c);return this.relatedNodes(m),0===m.length},after:function(a,b){return[a[0]]}},{id:"skip-link",evaluate:function(a,b,c){return axe.commons.dom.isFocusable(axe.commons.dom.getElementByReference(a,"href"))},after:function(a,b){return[a[0]]}},{id:"unique-frame-title",evaluate:function(a,b,c){var d=axe.commons.text.sanitize(a.title).trim().toLowerCase();return this.data(d),!0},after:function(a,b){var c={};return a.forEach(function(a){c[a.data]=void 0!==c[a.data]?++c[a.data]:0}),a.forEach(function(a){a.result=!!c[a.data]}),a}},{id:"aria-label",evaluate:function(a,b,c){var d=a.getAttribute("aria-label");return!!(d?axe.commons.text.sanitize(d).trim():"")}},{id:"aria-labelledby",evaluate:function(a,b,c){return(0,axe.commons.dom.idrefs)(a,"aria-labelledby").some(function(a){return a&&axe.commons.text.accessibleText(a,!0)})}},{id:"button-has-visible-text",evaluate:function(a,b,c){var d=a.nodeName.toUpperCase(),e=a.getAttribute("role"),f=void 0;return("BUTTON"===d||"button"===e&&"INPUT"!==d)&&(f=axe.commons.text.accessibleText(a),this.data(f),!!f)}},{id:"doc-has-title",evaluate:function(a,b,c){var d=document.title;return!!(d?axe.commons.text.sanitize(d).trim():"")}},{id:"duplicate-id",evaluate:function(a,b,c){if(!a.getAttribute("id").trim())return!0;for(var d=axe.commons.utils.escapeSelector(a.getAttribute("id")),e=document.querySelectorAll('[id="'+d+'"]'),f=[],g=0;g<e.length;g++)e[g]!==a&&f.push(e[g]);return f.length&&this.relatedNodes(f),this.data(a.getAttribute("id")),e.length<=1},after:function(a,b){var c=[];return a.filter(function(a){return-1===c.indexOf(a.data)&&(c.push(a.data),!0)})}},{ +id:"exists",evaluate:function(a,b,c){return!0}},{id:"has-alt",evaluate:function(a,b,c){var d=a.nodeName.toLowerCase();return a.hasAttribute("alt")&&("img"===d||"input"===d||"area"===d)}},{id:"has-visible-text",evaluate:function(a,b,c){return axe.commons.text.accessibleText(a).length>0}},{id:"is-on-screen",evaluate:function(a,b,c){return axe.commons.dom.isVisible(a,!1)&&!axe.commons.dom.isOffscreen(a)}},{id:"non-empty-alt",evaluate:function(a,b,c){var d=a.getAttribute("alt");return!!(d?axe.commons.text.sanitize(d).trim():"")}},{id:"non-empty-if-present",evaluate:function(a,b,c){var d=a.nodeName.toUpperCase(),e=(a.getAttribute("type")||"").toLowerCase(),f=a.getAttribute("value");return this.data(f),"INPUT"===d&&-1!==["submit","reset"].indexOf(e)&&null===f}},{id:"non-empty-title",evaluate:function(a,b,c){var d=a.getAttribute("title");return!!(d?axe.commons.text.sanitize(d).trim():"")}},{id:"non-empty-value",evaluate:function(a,b,c){var d=a.getAttribute("value");return!!(d?axe.commons.text.sanitize(d).trim():"")}},{id:"role-none",evaluate:function(a,b,c){return"none"===a.getAttribute("role")}},{id:"role-presentation",evaluate:function(a,b,c){return"presentation"===a.getAttribute("role")}},{id:"caption-faked",evaluate:function(a,b,c){var d=axe.commons.table.toGrid(a),e=d[0];return d.length<=1||e.length<=1||a.rows.length<=1||e.reduce(function(a,b,c){return a||b!==e[c+1]&&void 0!==e[c+1]},!1)}},{id:"has-caption",evaluate:function(a,b,c){return!!a.caption}},{id:"has-summary",evaluate:function(a,b,c){return!!a.summary}},{id:"has-th",evaluate:function(a,b,c){for(var d,e,f=[],g=0,h=a.rows.length;g<h;g++){d=a.rows[g];for(var i=0,j=d.cells.length;i<j;i++)e=d.cells[i],"TH"!==e.nodeName.toUpperCase()&&-1===["rowheader","columnheader"].indexOf(e.getAttribute("role"))||f.push(e)}return!!f.length&&(this.relatedNodes(f),!0)}},{id:"html5-scope",evaluate:function(a,b,c){return!axe.commons.dom.isHTML5(document)||"TH"===a.nodeName.toUpperCase()}},{id:"same-caption-summary",evaluate:function(a,b,c){return!(!a.summary||!a.caption)&&a.summary===axe.commons.text.accessibleText(a.caption)}},{id:"scope-value",evaluate:function(a,b,c){b=b||{};var d=a.getAttribute("scope").toLowerCase();return-1!==(["row","col","rowgroup","colgroup"]||b.values).indexOf(d)}},{id:"td-has-header",evaluate:function(a,b,c){var d=axe.commons.table,e=[];return d.getAllCells(a).forEach(function(a){if(axe.commons.dom.hasContent(a)&&d.isDataCell(a)&&!axe.commons.aria.label(a)){var b=d.getHeaders(a);(b=b.reduce(function(a,b){return a||null!==b&&!!axe.commons.dom.hasContent(b)},!1))||e.push(a)}}),!e.length||(this.relatedNodes(e),!1)}},{id:"td-headers-attr",evaluate:function(a,b,c){for(var d=[],e=0,f=a.rows.length;e<f;e++)for(var g=a.rows[e],h=0,i=g.cells.length;h<i;h++)d.push(g.cells[h]);var j=d.reduce(function(a,b){return b.getAttribute("id")&&a.push(b.getAttribute("id")),a},[]),k=d.reduce(function(a,b){var c,d,e=(b.getAttribute("headers")||"").split(/\s/).reduce(function(a,b){return b=b.trim(),b&&a.push(b),a},[]);return 0!==e.length&&(b.getAttribute("id")&&(c=-1!==e.indexOf(b.getAttribute("id").trim())),d=e.reduce(function(a,b){return a||-1===j.indexOf(b)},!1),(c||d)&&a.push(b)),a},[]);return!(k.length>0)||(this.relatedNodes(k),!1)}},{id:"th-has-data-cells",evaluate:function(a,b,c){var d=axe.commons.table,e=d.getAllCells(a),f=this,g=[];e.forEach(function(a){var b=a.getAttribute("headers");b&&(g=g.concat(b.split(/\s+/)));var c=a.getAttribute("aria-labelledby");c&&(g=g.concat(c.split(/\s+/)))});var h=e.filter(function(a){return""!==axe.commons.text.sanitize(a.textContent)&&("TH"===a.nodeName.toUpperCase()||-1!==["rowheader","columnheader"].indexOf(a.getAttribute("role")))}),i=d.toGrid(a);return!!h.reduce(function(a,b){if(b.getAttribute("id")&&g.includes(b.getAttribute("id")))return!!a||a;var c=!1,e=d.getCellPosition(b,i);return d.isColumnHeader(b)&&(c=d.traverse("down",e,i).reduce(function(a,b){return a||axe.commons.dom.hasContent(b)&&!d.isColumnHeader(b)},!1)),!c&&d.isRowHeader(b)&&(c=d.traverse("right",e,i).reduce(function(a,b){return a||axe.commons.dom.hasContent(b)&&!d.isRowHeader(b)},!1)),c||f.relatedNodes(b),a&&c},!0)||void 0}},{id:"hidden-content",evaluate:function(a,b,c){if(!["SCRIPT","HEAD","TITLE","NOSCRIPT","STYLE","TEMPLATE"].includes(a.tagName.toUpperCase())&&axe.commons.dom.hasContent(c)){var d=window.getComputedStyle(a);if("none"===d.getPropertyValue("display"))return;if("hidden"===d.getPropertyValue("visibility")){var e=axe.commons.dom.getComposedParent(a),f=e&&window.getComputedStyle(e);if(!f||"hidden"!==f.getPropertyValue("visibility"))return}}return!0}}],commons:function(){function a(a){return a.getPropertyValue("font-family").split(/[,;]/g).map(function(a){return a.trim().toLowerCase()})}function b(b,c){var d=window.getComputedStyle(b);if("none"!==d.getPropertyValue("background-image"))return!0;if(["border-bottom","border-top","outline"].reduce(function(a,b){var c=new A.Color;return c.parseRgbString(d.getPropertyValue(b+"-color")),a||"none"!==d.getPropertyValue(b+"-style")&&parseFloat(d.getPropertyValue(b+"-width"))>0&&0!==c.alpha},!1))return!0;var e=window.getComputedStyle(c);if(a(d)[0]!==a(e)[0])return!0;var f=["text-decoration-line","text-decoration-style","font-weight","font-style","font-size"].reduce(function(a,b){return a||d.getPropertyValue(b)!==e.getPropertyValue(b)},!1),g=d.getPropertyValue("text-decoration");return g.split(" ").length<3&&(f=f||g!==e.getPropertyValue("text-decoration")),f}function c(a,b){var c=a.nodeName.toUpperCase();if(E.includes(c))return axe.commons.color.incompleteData.set("bgColor","imgNode"),!0;b=b||window.getComputedStyle(a);var d=b.getPropertyValue("background-image"),e="none"!==d;if(e){var f=/gradient/.test(d);axe.commons.color.incompleteData.set("bgColor",f?"bgGradient":"bgImage")}return e}function d(a,b){b=b||window.getComputedStyle(a);var c=new A.Color;if(c.parseRgbString(b.getPropertyValue("background-color")),0!==c.alpha){var d=b.getPropertyValue("opacity");c.alpha=c.alpha*d}return c}function e(a,b){var c=a.getClientRects()[0],d=document.elementsFromPoint(c.left,c.top);if(d)for(var e=0;e<d.length;e++)if(d[e]!==a&&d[e]===b)return!0;return!1}function f(a,b,c){var f=0;if(a>0)for(var g=a-1;g>=0;g--){var h=b[g],i=window.getComputedStyle(h),j=d(h,i);j.alpha&&e(c,h)?f+=j.alpha:b.splice(g,1)}return f}function g(a,b,c){var d=a!==b&&!B.visuallyContains(a,b)&&0!==c.alpha;return d&&axe.commons.color.incompleteData.set("bgColor","elmPartiallyObscured"),d}function h(a,b){var c={TD:"TR",INPUT:"LABEL"},d=a.map(function(a){return a.tagName}),e=a;for(var f in c)if(c.hasOwnProperty(f)){if(b.tagName===f){var g=axe.commons.dom.findUp(b,c[f]);if(g&&-1===a.indexOf(g)){var h=axe.commons.dom.visuallyOverlaps(b.getBoundingClientRect(),g);h&&e.splice(a.indexOf(b)+1,0,g)}}b.tagName===c[f]&&-1===d.indexOf(b.tagName)&&e.splice(d.indexOf(f)+1,0,b)}return e}function i(a){var b=a.indexOf(document.body),e=a;return b>1&&!c(document.documentElement)&&0===d(document.documentElement).alpha&&(e.splice(b,1),e.splice(a.indexOf(document.documentElement),1),e.push(document.body)),e}function j(a){if(!F.includes(a.actualNode.nodeName.toUpperCase()))return a.children.some(function(a){var b=a.actualNode;return 3===b.nodeType&&b.nodeValue.trim()})}function k(a,b){!1!==b(a.actualNode)&&a.children.forEach(function(a){return k(a,b)})}function l(a){var b=window.getComputedStyle(a).getPropertyValue("display");return G.includes(b)||"table-"===b.substr(0,6)}function m(a){for(var b=B.getComposedParent(a);b&&!l(b);)b=B.getComposedParent(b);return axe.utils.getNodeFromTree(axe._tree[0],b)}function n(a){"use strict";var b=a.match(/rect\s*\(([0-9]+)px,?\s*([0-9]+)px,?\s*([0-9]+)px,?\s*([0-9]+)px\s*\)/);return!(!b||5!==b.length)&&(b[3]-b[1]<=0&&b[2]-b[4]<=0)}function o(a){var b=a.actualNode,c=void 0;return c=b.id?B.findElmsInContext({elm:"label",attr:"for",value:b.id,context:b})[0]:B.findUp(b,"label"),axe.utils.getNodeFromTree(axe._tree[0],c)}function p(a){return["button","reset","submit"].includes(a.actualNode.type.toLowerCase())}function q(a){var b=a.actualNode,c=b.nodeName.toUpperCase();return"TEXTAREA"===c||"SELECT"===c||"INPUT"===c&&"hidden"!==b.type.toLowerCase()}function r(a){return["BUTTON","SUMMARY","A"].includes(a.actualNode.nodeName.toUpperCase())}function s(a){return["TABLE","FIGURE"].includes(a.actualNode.nodeName.toUpperCase())}function t(a){var b=a.actualNode,c=b.nodeName.toUpperCase();if("INPUT"===c)return!b.hasAttribute("type")||J.includes(b.type.toLowerCase())?b.value:"";if("SELECT"===c){var d=b.options;if(d&&d.length){for(var e="",f=0;f<d.length;f++)d[f].selected&&(e+=" "+d[f].text);return D.sanitize(e)}return""}return"TEXTAREA"===c&&b.value?b.value:""}function u(a,b){var c=a.actualNode,d=c.querySelector(b.toLowerCase());return d?D.accessibleText(d):""}function v(a){if(!a)return!1;var b=a.actualNode;switch(b.nodeName.toUpperCase()){case"SELECT":case"TEXTAREA":return!0;case"INPUT":return!b.hasAttribute("type")||J.includes(b.getAttribute("type").toLowerCase());default:return!1}}function w(a){var b=a.actualNode,c=b.nodeName.toUpperCase();return["IMG","APPLET","AREA"].includes(c)||"INPUT"===c&&"image"===b.type.toLowerCase()}function x(a){return!!D.sanitize(a)}var commons={},y=commons.aria={},z=y._lut={};z.attributes={"aria-activedescendant":{type:"idref"},"aria-atomic":{type:"boolean",values:["true","false"]},"aria-autocomplete":{type:"nmtoken",values:["inline","list","both","none"]},"aria-busy":{type:"boolean",values:["true","false"]},"aria-checked":{type:"nmtoken",values:["true","false","mixed","undefined"]},"aria-colcount":{type:"int"},"aria-colindex":{type:"int"},"aria-colspan":{type:"int"},"aria-controls":{type:"idrefs"},"aria-current":{type:"nmtoken",values:["page","step","location","date","time","true","false"]},"aria-describedby":{type:"idrefs"},"aria-disabled":{type:"boolean",values:["true","false"]},"aria-dropeffect":{type:"nmtokens",values:["copy","move","reference","execute","popup","none"]},"aria-expanded":{type:"nmtoken",values:["true","false","undefined"]},"aria-flowto":{type:"idrefs"},"aria-grabbed":{type:"nmtoken",values:["true","false","undefined"]},"aria-haspopup":{type:"boolean",values:["true","false"]},"aria-hidden":{type:"boolean",values:["true","false"]},"aria-invalid":{type:"nmtoken",values:["true","false","spelling","grammar"]},"aria-label":{type:"string"},"aria-labelledby":{type:"idrefs"},"aria-level":{type:"int"},"aria-live":{type:"nmtoken",values:["off","polite","assertive"]},"aria-multiline":{type:"boolean",values:["true","false"]},"aria-multiselectable":{type:"boolean",values:["true","false"]},"aria-orientation":{type:"nmtoken",values:["horizontal","vertical"]},"aria-owns":{type:"idrefs"},"aria-posinset":{type:"int"},"aria-pressed":{type:"nmtoken",values:["true","false","mixed","undefined"]},"aria-readonly":{type:"boolean",values:["true","false"]},"aria-relevant":{type:"nmtokens",values:["additions","removals","text","all"]},"aria-required":{type:"boolean",values:["true","false"]},"aria-rowcount":{type:"int"},"aria-rowindex":{type:"int"},"aria-rowspan":{type:"int"},"aria-selected":{type:"nmtoken",values:["true","false","undefined"]},"aria-setsize":{type:"int"},"aria-sort":{type:"nmtoken",values:["ascending","descending","other","none"]},"aria-valuemax":{type:"decimal"},"aria-valuemin":{type:"decimal"},"aria-valuenow":{type:"decimal"},"aria-valuetext":{type:"string"}},z.globalAttributes=["aria-atomic","aria-busy","aria-controls","aria-current","aria-describedby","aria-disabled","aria-dropeffect","aria-flowto","aria-grabbed","aria-haspopup","aria-hidden","aria-invalid","aria-label","aria-labelledby","aria-live","aria-owns","aria-relevant"],z.role={alert:{type:"widget",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null},alertdialog:{type:"widget",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null},application:{type:"landmark",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null},article:{type:"structure",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null,implicit:["article"]},banner:{type:"landmark",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null,implicit:["header"]},button:{type:"widget",attributes:{allowed:["aria-expanded","aria-pressed"]},owned:null,nameFrom:["author","contents"],context:null,implicit:["button",'input[type="button"]','input[type="image"]','input[type="reset"]','input[type="submit"]',"summary"]},cell:{type:"structure",attributes:{allowed:["aria-colindex","aria-colspan","aria-rowindex","aria-rowspan"]},owned:null,nameFrom:["author","contents"],context:["row"],implicit:["td","th"]},checkbox:{type:"widget",attributes:{required:["aria-checked"]},owned:null,nameFrom:["author","contents"],context:null,implicit:['input[type="checkbox"]']},columnheader:{type:"structure",attributes:{allowed:["aria-expanded","aria-sort","aria-readonly","aria-selected","aria-required"]},owned:null,nameFrom:["author","contents"],context:["row"],implicit:["th"]},combobox:{type:"composite",attributes:{required:["aria-expanded"],allowed:["aria-autocomplete","aria-required","aria-activedescendant"]},owned:{all:["listbox","textbox"]},nameFrom:["author"],context:null},command:{nameFrom:["author"],type:"abstract"},complementary:{type:"landmark",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null,implicit:["aside"]},composite:{nameFrom:["author"],type:"abstract"},contentinfo:{type:"landmark",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null,implicit:["footer"]},definition:{type:"structure",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null,implicit:["dd"]},dialog:{type:"widget",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null,implicit:["dialog"]},directory:{type:"structure",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author","contents"],context:null},document:{type:"structure",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null,implicit:["body"]},form:{type:"landmark",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null,implicit:["form"]},grid:{type:"composite",attributes:{allowed:["aria-level","aria-multiselectable","aria-readonly","aria-activedescendant","aria-expanded"]},owned:{one:["rowgroup","row"]},nameFrom:["author"],context:null,implicit:["table"]},gridcell:{type:"widget",attributes:{allowed:["aria-selected","aria-readonly","aria-expanded","aria-required"]},owned:null,nameFrom:["author","contents"],context:["row"],implicit:["td","th"]},group:{type:"structure",attributes:{allowed:["aria-activedescendant","aria-expanded"]},owned:null,nameFrom:["author"],context:null,implicit:["details","optgroup"]},heading:{type:"structure",attributes:{allowed:["aria-level","aria-expanded"]},owned:null,nameFrom:["author","contents"],context:null,implicit:["h1","h2","h3","h4","h5","h6"]},img:{type:"structure",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null,implicit:["img"]},input:{nameFrom:["author"],type:"abstract"},landmark:{nameFrom:["author"],type:"abstract"},link:{type:"widget",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author","contents"],context:null,implicit:["a[href]"]},list:{type:"structure",attributes:{allowed:["aria-expanded"]},owned:{all:["listitem"]},nameFrom:["author"],context:null,implicit:["ol","ul","dl"]},listbox:{type:"composite",attributes:{allowed:["aria-activedescendant","aria-multiselectable","aria-required","aria-expanded"]},owned:{all:["option"]},nameFrom:["author"],context:null,implicit:["select"]},listitem:{type:"structure",attributes:{allowed:["aria-level","aria-posinset","aria-setsize","aria-expanded"]},owned:null,nameFrom:["author","contents"],context:["list"],implicit:["li","dt"]},log:{type:"widget",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null},main:{type:"landmark",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null,implicit:["main"]},marquee:{type:"widget",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null},math:{type:"structure",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null,implicit:["math"]},menu:{type:"composite",attributes:{allowed:["aria-activedescendant","aria-expanded"]},owned:{one:["menuitem","menuitemradio","menuitemcheckbox"]},nameFrom:["author"],context:null,implicit:['menu[type="context"]']},menubar:{type:"composite",attributes:{allowed:["aria-activedescendant","aria-expanded"]},owned:null,nameFrom:["author"],context:null},menuitem:{type:"widget",attributes:null,owned:null,nameFrom:["author","contents"],context:["menu","menubar"],implicit:['menuitem[type="command"]']},menuitemcheckbox:{type:"widget",attributes:{required:["aria-checked"]},owned:null,nameFrom:["author","contents"],context:["menu","menubar"],implicit:['menuitem[type="checkbox"]']},menuitemradio:{type:"widget",attributes:{allowed:["aria-selected","aria-posinset","aria-setsize"],required:["aria-checked"]},owned:null,nameFrom:["author","contents"],context:["menu","menubar"],implicit:['menuitem[type="radio"]']},navigation:{type:"landmark",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null,implicit:["nav"]},none:{type:"structure",attributes:null,owned:null,nameFrom:["author"],context:null},note:{type:"structure",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null},option:{type:"widget",attributes:{allowed:["aria-selected","aria-posinset","aria-setsize","aria-checked"]},owned:null,nameFrom:["author","contents"],context:["listbox"],implicit:["option"]},presentation:{type:"structure",attributes:null,owned:null,nameFrom:["author"],context:null},progressbar:{type:"widget",attributes:{allowed:["aria-valuetext","aria-valuenow","aria-valuemax","aria-valuemin"]},owned:null,nameFrom:["author"],context:null,implicit:["progress"]},radio:{type:"widget",attributes:{allowed:["aria-selected","aria-posinset","aria-setsize"],required:["aria-checked"]},owned:null,nameFrom:["author","contents"],context:null,implicit:['input[type="radio"]']},radiogroup:{type:"composite",attributes:{allowed:["aria-activedescendant","aria-required","aria-expanded"]},owned:{all:["radio"]},nameFrom:["author"],context:null},range:{nameFrom:["author"],type:"abstract"},region:{type:"structure",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null,implicit:["section"]},roletype:{type:"abstract"},row:{type:"structure",attributes:{allowed:["aria-level","aria-selected","aria-activedescendant","aria-expanded"]},owned:{one:["cell","columnheader","rowheader","gridcell"]},nameFrom:["author","contents"],context:["rowgroup","grid","treegrid","table"],implicit:["tr"]},rowgroup:{type:"structure",attributes:{allowed:["aria-activedescendant","aria-expanded"]},owned:{all:["row"]},nameFrom:["author","contents"],context:["grid","table"],implicit:["tbody","thead","tfoot"]},rowheader:{type:"structure",attributes:{allowed:["aria-sort","aria-required","aria-readonly","aria-expanded","aria-selected"]},owned:null,nameFrom:["author","contents"],context:["row"],implicit:["th"]},scrollbar:{type:"widget",attributes:{required:["aria-controls","aria-orientation","aria-valuenow","aria-valuemax","aria-valuemin"],allowed:["aria-valuetext"]},owned:null,nameFrom:["author"],context:null},search:{type:"landmark",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null},searchbox:{type:"widget",attributes:{allowed:["aria-activedescendant","aria-autocomplete","aria-multiline","aria-readonly","aria-required"]},owned:null,nameFrom:["author"],context:null,implicit:['input[type="search"]']},section:{nameFrom:["author","contents"],type:"abstract"},sectionhead:{nameFrom:["author","contents"],type:"abstract"},select:{nameFrom:["author"],type:"abstract"},separator:{type:"structure",attributes:{allowed:["aria-expanded","aria-orientation"]},owned:null,nameFrom:["author"],context:null,implicit:["hr"]},slider:{type:"widget",attributes:{allowed:["aria-valuetext","aria-orientation"],required:["aria-valuenow","aria-valuemax","aria-valuemin"]},owned:null,nameFrom:["author"],context:null,implicit:['input[type="range"]']},spinbutton:{type:"widget",attributes:{allowed:["aria-valuetext","aria-required"],required:["aria-valuenow","aria-valuemax","aria-valuemin"]},owned:null,nameFrom:["author"],context:null,implicit:['input[type="number"]']},status:{type:"widget",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null,implicit:["output"]},structure:{type:"abstract"},switch:{type:"widget",attributes:{required:["aria-checked"]},owned:null,nameFrom:["author","contents"],context:null},tab:{type:"widget",attributes:{allowed:["aria-selected","aria-expanded"]},owned:null,nameFrom:["author","contents"],context:["tablist"]},table:{type:"structure",attributes:{allowed:["aria-colcount","aria-rowcount"]},owned:{one:["rowgroup","row"]},nameFrom:["author"],context:null,implicit:["table"]},tablist:{type:"composite",attributes:{allowed:["aria-activedescendant","aria-expanded","aria-level","aria-multiselectable"]},owned:{all:["tab"]},nameFrom:["author"],context:null},tabpanel:{type:"widget",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null},text:{type:"structure",owned:null,nameFrom:["author","contents"],context:null},textbox:{type:"widget",attributes:{allowed:["aria-activedescendant","aria-autocomplete","aria-multiline","aria-readonly","aria-required"]},owned:null,nameFrom:["author"],context:null,implicit:['input[type="text"]','input[type="email"]','input[type="password"]','input[type="tel"]','input[type="url"]',"input:not([type])","textarea"]},timer:{type:"widget",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null},toolbar:{type:"structure",attributes:{allowed:["aria-activedescendant","aria-expanded"]},owned:null,nameFrom:["author"],context:null,implicit:['menu[type="toolbar"]']},tooltip:{type:"widget",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author","contents"],context:null},tree:{type:"composite",attributes:{allowed:["aria-activedescendant","aria-multiselectable","aria-required","aria-expanded"]},owned:{all:["treeitem"]},nameFrom:["author"],context:null},treegrid:{type:"composite",attributes:{allowed:["aria-activedescendant","aria-expanded","aria-level","aria-multiselectable","aria-readonly","aria-required"]},owned:{all:["treeitem"]},nameFrom:["author"],context:null},treeitem:{type:"widget",attributes:{allowed:["aria-checked","aria-selected","aria-expanded","aria-level","aria-posinset","aria-setsize"]},owned:null,nameFrom:["author","contents"],context:["treegrid","tree"]},widget:{type:"abstract"},window:{nameFrom:["author"],type:"abstract"}};var A={};commons.color=A;var B=commons.dom={},C=commons.table={},D=commons.text={};commons.utils=axe.utils;y.requiredAttr=function(a){"use strict";var b=z.role[a];return b&&b.attributes&&b.attributes.required||[]},y.allowedAttr=function(a){"use strict";var b=z.role[a],c=b&&b.attributes&&b.attributes.allowed||[],d=b&&b.attributes&&b.attributes.required||[];return c.concat(z.globalAttributes).concat(d)},y.validateAttr=function(a){"use strict";return!!z.attributes[a]},y.validateAttrValue=function(a,b){"use strict";var c,d,e=a.getAttribute(b),f=z.attributes[b],g=B.getRootNode(a);if(!f)return!0;switch(f.type){case"boolean":case"nmtoken":return"string"==typeof e&&-1!==f.values.indexOf(e.toLowerCase());case"nmtokens":return d=axe.utils.tokenList(e),d.reduce(function(a,b){return a&&-1!==f.values.indexOf(b)},0!==d.length);case"idref":return!(!e||!g.getElementById(e));case"idrefs":return d=axe.utils.tokenList(e),d.reduce(function(a,b){return!(!a||!g.getElementById(b))},0!==d.length);case"string":return!0;case"decimal":return!(!(c=e.match(/^[-+]?([0-9]*)\.?([0-9]*)$/))||!c[1]&&!c[2]);case"int":return/^[-+]?[0-9]+$/.test(e)}},y.label=function(a){var b,c;return a.actualNode instanceof Node==!1&&(a=axe.utils.getNodeFromTree(axe._tree[0],a)),a.actualNode.getAttribute("aria-labelledby")&&(b=B.idrefs(a.actualNode,"aria-labelledby"),c=b.map(function(a){var b=axe.utils.getNodeFromTree(axe._tree[0],a);return b?D.visible(b,!0):""}).join(" ").trim())?c:(c=a.actualNode.getAttribute("aria-label"),c&&(c=D.sanitize(c).trim())?c:null)},y.isValidRole=function(a){"use strict";return!!z.role[a]},y.getRolesWithNameFromContents=function(){return Object.keys(z.role).filter(function(a){return z.role[a].nameFrom&&-1!==z.role[a].nameFrom.indexOf("contents")})},y.getRolesByType=function(a){return Object.keys(z.role).filter(function(b){return z.role[b].type===a})},y.getRoleType=function(a){var b=z.role[a];return b&&b.type||null},y.requiredOwned=function(a){"use strict";var b=null,c=z.role[a];return c&&(b=axe.utils.clone(c.owned)),b},y.requiredContext=function(a){"use strict";var b=null,c=z.role[a];return c&&(b=axe.utils.clone(c.context)),b},y.implicitNodes=function(a){"use strict";var b=null,c=z.role[a];return c&&c.implicit&&(b=axe.utils.clone(c.implicit)),b},y.implicitRole=function(a){"use strict";var b=function(b,c){var d=function(b){return axe.utils.matchesSelector(a,b)};return c.implicit&&c.implicit.some(d)&&b.push(c.name),b},c=Object.keys(z.role).map(function(a){var b=z.role[a];return{name:a,implicit:b&&b.implicit}}),d=c.reduce(b,[]);if(!d.length)return null;for(var e=a.attributes,f=[],g=0,h=e.length;g<h;g++){var i=e[g];i.name.match(/^aria-/)&&f.push(i.name)}return function(a,b){var c=function(a){return y.allowedAttr(a).reduce(function(a,c){return a+(b.indexOf(c)>-1?1:0)},0)};return a.map(function(a){return{score:c(a),name:a}}).sort(function(a,b){return b.score-a.score}).map(function(a){return a.name})}(d,f).shift()},A.Color=function(a,b,c,d){this.red=a,this.green=b,this.blue=c,this.alpha=d,this.toHexString=function(){var a=Math.round(this.red).toString(16),b=Math.round(this.green).toString(16),c=Math.round(this.blue).toString(16);return"#"+(this.red>15.5?a:"0"+a)+(this.green>15.5?b:"0"+b)+(this.blue>15.5?c:"0"+c)};var e=/^rgb\((\d+), (\d+), (\d+)\)$/,f=/^rgba\((\d+), (\d+), (\d+), (\d*(\.\d+)?)\)/;this.parseRgbString=function(a){if("transparent"===a)return this.red=0,this.green=0,this.blue=0,void(this.alpha=0);var b=a.match(e);return b?(this.red=parseInt(b[1],10),this.green=parseInt(b[2],10),this.blue=parseInt(b[3],10),void(this.alpha=1)):(b=a.match(f),b?(this.red=parseInt(b[1],10),this.green=parseInt(b[2],10),this.blue=parseInt(b[3],10),void(this.alpha=parseFloat(b[4]))):void 0)},this.getRelativeLuminance=function(){var a=this.red/255,b=this.green/255,c=this.blue/255;return.2126*(a<=.03928?a/12.92:Math.pow((a+.055)/1.055,2.4))+.7152*(b<=.03928?b/12.92:Math.pow((b+.055)/1.055,2.4))+.0722*(c<=.03928?c/12.92:Math.pow((c+.055)/1.055,2.4))}},A.flattenColors=function(a,b){var c=a.alpha,d=(1-c)*b.red+c*a.red,e=(1-c)*b.green+c*a.green,f=(1-c)*b.blue+c*a.blue,g=a.alpha+b.alpha*(1-a.alpha);return new A.Color(d,e,f,g)},A.getContrast=function(a,b){if(!b||!a)return null;b.alpha<1&&(b=A.flattenColors(b,a));var c=a.getRelativeLuminance(),d=b.getRelativeLuminance();return(Math.max(d,c)+.05)/(Math.min(d,c)+.05)},A.hasValidContrastRatio=function(a,b,c,d){var e=A.getContrast(a,b),f=d&&Math.ceil(72*c)/96<14||!d&&Math.ceil(72*c)/96<18;return{isValid:f&&e>=4.5||!f&&e>=3,contrastRatio:e}},A.elementIsDistinct=b;var E=["IMG","CANVAS","OBJECT","IFRAME","VIDEO","SVG"];A.getBackgroundStack=function(a){var b=a.getBoundingClientRect(),c=void 0,d=void 0;if(!(b.left>window.innerWidth||b.top>window.innerHeight)){c=Math.min(Math.ceil(b.left+b.width/2),window.innerWidth-1),d=Math.min(Math.ceil(b.top+b.height/2),window.innerHeight-1);var e=document.elementsFromPoint(c,d);e=h(e,a),e=B.reduceToElementsBelowFloating(e,a),e=i(e);var g=e.indexOf(a);return f(g,e,a)>=.99?(axe.commons.color.incompleteData.set("bgColor","bgOverlap"),null):-1!==g?e:null}},A.getBackgroundColor=function(a){var b=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];if(!0!==(arguments.length>2&&void 0!==arguments[2]&&arguments[2])){var e=a.clientHeight-2>=2*window.innerHeight;a.scrollIntoView(e)}var f=[],h=A.getBackgroundStack(a);if((h||[]).some(function(e){var h=window.getComputedStyle(e),i=d(e,h);return g(a,e,i)||c(e,h)?(f=null,b.push(e),!0):0!==i.alpha&&(b.push(e),f.push(i),1===i.alpha)}),null!==f&&null!==h){f.push(new A.Color(255,255,255,1));return f.reduce(A.flattenColors)}return null},B.isOpaque=function(a){var b=window.getComputedStyle(a);return c(a,b)||1===d(a,b).alpha},A.getForegroundColor=function(a,b){var c=window.getComputedStyle(a),d=new A.Color;d.parseRgbString(c.getPropertyValue("color"));var e=c.getPropertyValue("opacity");if(d.alpha=d.alpha*e,1===d.alpha)return d;var f=A.getBackgroundColor(a,[],b);if(null===f){var g=axe.commons.color.incompleteData.get("bgColor");return axe.commons.color.incompleteData.set("fgColor",g),null}return A.flattenColors(d,f)},A.incompleteData=function(){var a={};return{set:function(b,c){if("string"!=typeof b)throw new Error("Incomplete data: key must be a string");return c&&(a[b]=c),a[b]},get:function(b){return a[b]},clear:function(){a={}}}}(),B.reduceToElementsBelowFloating=function(a,b){var c,d,e,f=["fixed","sticky"],g=[],h=!1;for(c=0;c<a.length;++c)d=a[c],d===b&&(h=!0),e=window.getComputedStyle(d),h||-1===f.indexOf(e.position)?g.push(d):g=[];return g},B.findElmsInContext=function(a){var b=a.context,c=a.value,d=a.attr,e=a.elm,f=void 0===e?"":e,g=void 0;b=b.actualNode||b;var h=axe.utils.escapeSelector(c);return g=9===b.nodeType||11===b.nodeType?b:B.getRootNode(b),Array.from(g.querySelectorAll(f+"["+d+"="+h+"]"))},B.findUp=function(a,b){var c=void 0,d=void 0,e=a;do{if(e=e.assignedSlot?e.assignedSlot:e.parentNode,e&&11===e.nodeType&&(d=null,e=e.host),!d&&(c=axe.commons.dom.getRootNode(e),d=c.querySelectorAll(b),d=axe.utils.toArray(d),c===document&&!d.length))return null}while(e&&!d.includes(e));return e},B.getComposedParent=function a(b){if(b.assignedSlot)return a(b.assignedSlot);if(b.parentNode){var c=b.parentNode;if(1===c.nodeType)return c;if(c.host)return c.host}return null},B.getElementByReference=function(a,b){var c=a.getAttribute(b);if(c&&"#"===c.charAt(0)){c=c.substring(1);var d=document.getElementById(c);if(d)return d;if(d=document.getElementsByName(c),d.length)return d[0]}return null},B.getElementCoordinates=function(a){"use strict";var b=B.getScrollOffset(document),c=b.left,d=b.top,e=a.getBoundingClientRect();return{top:e.top+d,right:e.right+c,bottom:e.bottom+d,left:e.left+c,width:e.right-e.left,height:e.bottom-e.top}},B.getRootNode=function(a){var b=a.getRootNode&&a.getRootNode()||document;return b===a&&(b=document),b},B.getScrollOffset=function(a){"use strict";if(!a.nodeType&&a.document&&(a=a.document),9===a.nodeType){var b=a.documentElement,c=a.body;return{left:b&&b.scrollLeft||c&&c.scrollLeft||0,top:b&&b.scrollTop||c&&c.scrollTop||0}}return{left:a.scrollLeft,top:a.scrollTop}},B.getViewportSize=function(a){"use strict";var b,c=a.document,d=c.documentElement;return a.innerWidth?{width:a.innerWidth,height:a.innerHeight}:d?{width:d.clientWidth,height:d.clientHeight}:(b=c.body,{width:b.clientWidth,height:b.clientHeight})};var F=["HEAD","TITLE","TEMPLATE","SCRIPT","STYLE","IFRAME","OBJECT","VIDEO","AUDIO","NOSCRIPT"];B.hasContent=function(a,b){return a.actualNode||(a=axe.utils.getNodeFromTree(axe._tree[0],a)),j(a)||B.isVisualContent(a.actualNode)||!!y.label(a)||!b&&a.children.some(function(a){return 1===a.actualNode.nodeType&&B.hasContent(a)})},B.idrefs=function(a,b){"use strict";var c,d,e=B.getRootNode(a),f=[],g=a.getAttribute(b);if(g)for(g=axe.utils.tokenList(g),c=0,d=g.length;c<d;c++)f.push(e.getElementById(g[c]));return f},B.isFocusable=function(a){"use strict";if(!a||a.disabled||!B.isVisible(a)&&"AREA"!==a.nodeName.toUpperCase())return!1;switch(a.nodeName.toUpperCase()){case"A":case"AREA":if(a.href)return!0;break;case"INPUT":return"hidden"!==a.type +;case"TEXTAREA":case"SELECT":case"DETAILS":case"BUTTON":return!0}var b=a.getAttribute("tabindex");return!(!b||isNaN(parseInt(b,10)))},B.isHTML5=function(a){var b=a.doctype;return null!==b&&("html"===b.name&&!b.publicId&&!b.systemId)};var G=["block","list-item","table","flex","grid","inline-block"];B.isInTextBlock=function(a){if(l(a))return!1;var b=m(a),c="",d="",e=0;return k(b,function(b){if(2===e)return!1;if(3===b.nodeType&&(c+=b.nodeValue),1===b.nodeType){var f=(b.nodeName||"").toUpperCase();if(["BR","HR"].includes(f))0===e?(c="",d=""):e=2;else{if("none"===b.style.display||"hidden"===b.style.overflow||!["",null,"none"].includes(b.style.float)||!["",null,"relative"].includes(b.style.position))return!1;if("A"===f&&b.href||"link"===(b.getAttribute("role")||"").toLowerCase())return b===a&&(e=1),d+=b.textContent,!1}}}),c=axe.commons.text.sanitize(c),d=axe.commons.text.sanitize(d),c.length>d.length},B.isNode=function(a){"use strict";return a instanceof Node},B.isOffscreen=function(a){"use strict";var b,c=document.documentElement,d=window.getComputedStyle(a),e=window.getComputedStyle(document.body||c).getPropertyValue("direction"),f=B.getElementCoordinates(a);if(f.bottom<0&&(function(a,b){for(a=a.parentNode;"html"!==a.nodeName.toLowerCase();){if(a.scrollTop&&(b+=a.scrollTop)>=0)return!1;a=a.parentNode}return!0}(a,f.bottom)||"absolute"===d.position))return!0;if(0===f.left&&0===f.right)return!1;if("ltr"===e){if(f.right<=0)return!0}else if(b=Math.max(c.scrollWidth,B.getViewportSize(window).width),f.left>=b)return!0;return!1},B.isVisible=function(a,b,c){"use strict";var d,e,f;return 9===a.nodeType||(11===a.nodeType&&(a=a.host),null!==(d=window.getComputedStyle(a,null))&&(e=a.nodeName.toUpperCase(),!("none"===d.getPropertyValue("display")||"STYLE"===e.toUpperCase()||"SCRIPT"===e.toUpperCase()||!b&&n(d.getPropertyValue("clip"))||!c&&("hidden"===d.getPropertyValue("visibility")||!b&&B.isOffscreen(a))||b&&"true"===a.getAttribute("aria-hidden"))&&(!!(f=a.assignedSlot?a.assignedSlot:a.parentNode)&&B.isVisible(f,b,!0))))};var H=["checkbox","img","radio","range","slider","spinbutton","textbox"];B.isVisualContent=function(a){var b=a.getAttribute("role");if(b)return-1!==H.indexOf(b);switch(a.tagName.toUpperCase()){case"IMG":case"IFRAME":case"OBJECT":case"VIDEO":case"AUDIO":case"CANVAS":case"SVG":case"MATH":case"BUTTON":case"SELECT":case"TEXTAREA":case"KEYGEN":case"PROGRESS":case"METER":return!0;case"INPUT":return"hidden"!==a.type;default:return!1}},B.visuallyContains=function(a,b){var c=a.getBoundingClientRect(),d={top:c.top+.01,bottom:c.bottom-.01,left:c.left+.01,right:c.right-.01},e=b.getBoundingClientRect(),f=e.top,g=e.left,h={top:f-b.scrollTop,bottom:f-b.scrollTop+b.scrollHeight,left:g-b.scrollLeft,right:g-b.scrollLeft+b.scrollWidth},i=window.getComputedStyle(b);return"inline"===i.getPropertyValue("display")||!(d.left<h.left&&d.left<e.left||d.top<h.top&&d.top<e.top||d.right>h.right&&d.right>e.right||d.bottom>h.bottom&&d.bottom>e.bottom)&&(!(d.right>e.right||d.bottom>e.bottom)||("scroll"===i.overflow||"auto"===i.overflow||"hidden"===i.overflow||b instanceof HTMLBodyElement||b instanceof HTMLHtmlElement))},B.visuallyOverlaps=function(a,b){var c=b.getBoundingClientRect(),d=c.top,e=c.left,f={top:d-b.scrollTop,bottom:d-b.scrollTop+b.scrollHeight,left:e-b.scrollLeft,right:e-b.scrollLeft+b.scrollWidth};if(a.left>f.right&&a.left>c.right||a.top>f.bottom&&a.top>c.bottom||a.right<f.left&&a.right<c.left||a.bottom<f.top&&a.bottom<c.top)return!1;var g=window.getComputedStyle(b);return!(a.left>c.right||a.top>c.bottom)||("scroll"===g.overflow||"auto"===g.overflow||b instanceof HTMLBodyElement||b instanceof HTMLHtmlElement)},C.getAllCells=function(a){var b,c,d,e,f=[];for(b=0,d=a.rows.length;b<d;b++)for(c=0,e=a.rows[b].cells.length;c<e;c++)f.push(a.rows[b].cells[c]);return f},C.getCellPosition=function(a,b){var c,d;for(b||(b=C.toGrid(B.findUp(a,"table"))),c=0;c<b.length;c++)if(b[c]&&-1!==(d=b[c].indexOf(a)))return{x:d,y:c}},C.getHeaders=function(a){if(a.hasAttribute("headers"))return commons.dom.idrefs(a,"headers");var b=commons.table.toGrid(commons.dom.findUp(a,"table")),c=commons.table.getCellPosition(a,b);return[].concat(C.traverse("left",c,b).filter(function(a){return C.isRowHeader(a)}),C.traverse("up",c,b).filter(function(a){return C.isColumnHeader(a)})).reverse()},C.getScope=function(a){var b=a.getAttribute("scope"),c=a.getAttribute("role");if(a instanceof Element==!1||-1===["TD","TH"].indexOf(a.nodeName.toUpperCase()))throw new TypeError("Expected TD or TH element");if("columnheader"===c)return"col";if("rowheader"===c)return"row";if("col"===b||"row"===b)return b;if("TH"!==a.nodeName.toUpperCase())return!1;var d=C.toGrid(B.findUp(a,"table")),e=C.getCellPosition(a);return d[e.y].reduce(function(a,b){return a&&"TH"===b.nodeName.toUpperCase()},!0)?"col":d.map(function(a){return a[e.x]}).reduce(function(a,b){return a&&"TH"===b.nodeName.toUpperCase()},!0)?"row":"auto"},C.isColumnHeader=function(a){return-1!==["col","auto"].indexOf(C.getScope(a))},C.isDataCell=function(a){return!(!a.children.length&&!a.textContent.trim())&&"TD"===a.nodeName.toUpperCase()},C.isDataTable=function(a){var b=a.getAttribute("role");if(("presentation"===b||"none"===b)&&!B.isFocusable(a))return!1;if("true"===a.getAttribute("contenteditable")||B.findUp(a,'[contenteditable="true"]'))return!0;if("grid"===b||"treegrid"===b||"table"===b)return!0;if("landmark"===commons.aria.getRoleType(b))return!0;if("0"===a.getAttribute("datatable"))return!1;if(a.getAttribute("summary"))return!0;if(a.tHead||a.tFoot||a.caption)return!0;for(var c=0,d=a.children.length;c<d;c++)if("COLGROUP"===a.children[c].nodeName.toUpperCase())return!0;for(var e,f,g=0,h=a.rows.length,i=!1,j=0;j<h;j++){e=a.rows[j];for(var k=0,l=e.cells.length;k<l;k++){if(f=e.cells[k],"TH"===f.nodeName.toUpperCase())return!0;if(i||f.offsetWidth===f.clientWidth&&f.offsetHeight===f.clientHeight||(i=!0),f.getAttribute("scope")||f.getAttribute("headers")||f.getAttribute("abbr"))return!0;if(-1!==["columnheader","rowheader"].indexOf(f.getAttribute("role")))return!0;if(1===f.children.length&&"ABBR"===f.children[0].nodeName.toUpperCase())return!0;g++}}if(a.getElementsByTagName("table").length)return!1;if(h<2)return!1;var m=a.rows[Math.ceil(h/2)];if(1===m.cells.length&&1===m.cells[0].colSpan)return!1;if(m.cells.length>=5)return!0;if(i)return!0;var n,o;for(j=0;j<h;j++){if(e=a.rows[j],n&&n!==window.getComputedStyle(e).getPropertyValue("background-color"))return!0;if(n=window.getComputedStyle(e).getPropertyValue("background-color"),o&&o!==window.getComputedStyle(e).getPropertyValue("background-image"))return!0;o=window.getComputedStyle(e).getPropertyValue("background-image")}return h>=20||!(B.getElementCoordinates(a).width>.95*B.getViewportSize(window).width)&&(!(g<10)&&!a.querySelector("object, embed, iframe, applet"))},C.isHeader=function(a){if(C.isColumnHeader(a)||C.isRowHeader(a))return!0;if(a.getAttribute("id")){var b=axe.utils.escapeSelector(a.getAttribute("id"));return!!document.querySelector('[headers~="'+b+'"]')}return!1},C.isRowHeader=function(a){return-1!==["row","auto"].indexOf(C.getScope(a))},C.toGrid=function(a){for(var b=[],c=a.rows,d=0,e=c.length;d<e;d++){var f=c[d].cells;b[d]=b[d]||[];for(var g=0,h=0,i=f.length;h<i;h++)for(var j=0;j<f[h].colSpan;j++){for(var k=0;k<f[h].rowSpan;k++){for(b[d+k]=b[d+k]||[];b[d+k][g];)g++;b[d+k][g]=f[h]}g++}}return b},C.toArray=C.toGrid,function(a){var b=function a(b,c,d,e){var f,g=d[c.y]?d[c.y][c.x]:void 0;return g?"function"==typeof e&&!0===(f=e(g,c,d))?[g]:(f=a(b,{x:c.x+b.x,y:c.y+b.y},d,e),f.unshift(g),f):[]};a.traverse=function(a,c,d,e){if(Array.isArray(c)&&(e=d,d=c,c={x:0,y:0}),"string"==typeof a)switch(a){case"left":a={x:-1,y:0};break;case"up":a={x:0,y:-1};break;case"right":a={x:1,y:0};break;case"down":a={x:0,y:1}}return b(a,{x:c.x+a.x,y:c.y+a.y},d,e)}}(C);var I={submit:"Submit",reset:"Reset"},J=["text","search","tel","url","email","date","time","number","range","color"],K=["A","EM","STRONG","SMALL","MARK","ABBR","DFN","I","B","S","U","CODE","VAR","SAMP","KBD","SUP","SUB","Q","CITE","SPAN","BDO","BDI","BR","WBR","INS","DEL","IMG","EMBED","OBJECT","IFRAME","MAP","AREA","SCRIPT","NOSCRIPT","RUBY","VIDEO","AUDIO","INPUT","TEXTAREA","SELECT","BUTTON","LABEL","OUTPUT","DATALIST","KEYGEN","PROGRESS","COMMAND","CANVAS","TIME","METER"];D.accessibleText=function(a,b){function c(a,b,c){return a.children.reduce(function(a,d){var e=d.actualNode;return 3===e.nodeType?a+=e.nodeValue:1===e.nodeType&&(K.includes(e.nodeName.toUpperCase())||(a+=" "),a+=f(d,b,c)),a},"")}function d(a,b,d){var e="",g=a.actualNode,h=g.nodeName.toUpperCase();if(r(a)&&(e=c(a,!1,!1)||"",x(e)))return e;if("FIGURE"===h&&(e=u(a,"figcaption"),x(e)))return e;if("TABLE"===h){if(e=u(a,"caption"),x(e))return e;if(e=g.getAttribute("title")||g.getAttribute("summary")||"",x(e))return e}if(w(a))return g.getAttribute("alt")||"";if(q(a)&&!d){if(p(a))return g.value||g.title||I[g.type]||"";var i=o(a);if(i)return f(i,b,!0)}return""}function e(a,b,c){var d="",e=a.actualNode;return!b&&e.hasAttribute("aria-labelledby")&&(d=D.sanitize(B.idrefs(e,"aria-labelledby").map(function(a){if(null!==a){e===a&&g.pop();var b=axe.utils.getNodeFromTree(axe._tree[0],a);return f(b,!0,e!==a)}return""}).join(" "))),d||c&&v(a)||!e.hasAttribute("aria-label")?d:D.sanitize(e.getAttribute("aria-label"))}var f=void 0,g=[];return a instanceof Node&&(a=axe.utils.getNodeFromTree(axe._tree[0],a)),f=function(a,b,f){var h=void 0;if(!a||g.includes(a))return"";if(null!==a&&a.actualNode instanceof Node!=!0)throw new Error("Invalid argument. Virtual Node must be provided");if(!b&&!B.isVisible(a.actualNode,!0))return"";g.push(a);var i=a.actualNode.getAttribute("role");return h=e(a,b,f),x(h)?h:(h=d(a,b,f),x(h)?h:f&&(h=t(a),x(h))?h:s(a)||i&&-1===y.getRolesWithNameFromContents().indexOf(i)||(h=c(a,b,f),!x(h))?a.actualNode.hasAttribute("title")?a.actualNode.getAttribute("title"):"":h)},D.sanitize(f(a,b))},D.label=function(a){var b,c,d;if(c=y.label(a))return c;if(a.actualNode.id){var e=axe.commons.utils.escapeSelector(a.actualNode.getAttribute("id"));if(d=axe.commons.dom.getRootNode(a.actualNode),b=d.querySelector('label[for="'+e+'"]'),b=axe.utils.getNodeFromTree(axe._tree[0],b),c=b&&D.visible(b,!0))return c}return b=B.findUp(a.actualNode,"label"),b=axe.utils.getNodeFromTree(axe._tree[0],b),(c=b&&D.visible(b,!0))||null},D.sanitize=function(a){"use strict";return a.replace(/\r\n/g,"\n").replace(/\u00A0/g," ").replace(/[\s]{2,}/g," ").trim()},D.visible=function(a,b,c){"use strict";var d,e,f,g=a.children,h=g.length,i="";for(d=0;d<h;d++)e=g[d],3===e.actualNode.nodeType?(f=e.actualNode.nodeValue)&&B.isVisible(a.actualNode,b)&&(i+=f):c||(i+=D.visible(e,b));return D.sanitize(i)},axe.utils.toArray=function(a){"use strict";return Array.prototype.slice.call(a)},axe.utils.tokenList=function(a){"use strict";return a.trim().replace(/\s{2,}/g," ").split(" ")} +;var L=["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","in","io","is","it","iu","iw","ja","ji","jv","jw","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mo","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","sh","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu","aaa","aab","aac","aad","aae","aaf","aag","aah","aai","aak","aal","aam","aan","aao","aap","aaq","aas","aat","aau","aav","aaw","aax","aaz","aba","abb","abc","abd","abe","abf","abg","abh","abi","abj","abl","abm","abn","abo","abp","abq","abr","abs","abt","abu","abv","abw","abx","aby","abz","aca","acb","acd","ace","acf","ach","aci","ack","acl","acm","acn","acp","acq","acr","acs","act","acu","acv","acw","acx","acy","acz","ada","adb","add","ade","adf","adg","adh","adi","adj","adl","adn","ado","adp","adq","adr","ads","adt","adu","adw","adx","ady","adz","aea","aeb","aec","aed","aee","aek","ael","aem","aen","aeq","aer","aes","aeu","aew","aey","aez","afa","afb","afd","afe","afg","afh","afi","afk","afn","afo","afp","afs","aft","afu","afz","aga","agb","agc","agd","age","agf","agg","agh","agi","agj","agk","agl","agm","agn","ago","agp","agq","agr","ags","agt","agu","agv","agw","agx","agy","agz","aha","ahb","ahg","ahh","ahi","ahk","ahl","ahm","ahn","aho","ahp","ahr","ahs","aht","aia","aib","aic","aid","aie","aif","aig","aih","aii","aij","aik","ail","aim","ain","aio","aip","aiq","air","ais","ait","aiw","aix","aiy","aja","ajg","aji","ajn","ajp","ajt","aju","ajw","ajz","akb","akc","akd","ake","akf","akg","akh","aki","akj","akk","akl","akm","ako","akp","akq","akr","aks","akt","aku","akv","akw","akx","aky","akz","ala","alc","ald","ale","alf","alg","alh","ali","alj","alk","all","alm","aln","alo","alp","alq","alr","als","alt","alu","alv","alw","alx","aly","alz","ama","amb","amc","ame","amf","amg","ami","amj","amk","aml","amm","amn","amo","amp","amq","amr","ams","amt","amu","amv","amw","amx","amy","amz","ana","anb","anc","and","ane","anf","ang","anh","ani","anj","ank","anl","anm","ann","ano","anp","anq","anr","ans","ant","anu","anv","anw","anx","any","anz","aoa","aob","aoc","aod","aoe","aof","aog","aoh","aoi","aoj","aok","aol","aom","aon","aor","aos","aot","aou","aox","aoz","apa","apb","apc","apd","ape","apf","apg","aph","api","apj","apk","apl","apm","apn","apo","app","apq","apr","aps","apt","apu","apv","apw","apx","apy","apz","aqa","aqc","aqd","aqg","aql","aqm","aqn","aqp","aqr","aqt","aqz","arb","arc","ard","are","arh","ari","arj","ark","arl","arn","aro","arp","arq","arr","ars","art","aru","arv","arw","arx","ary","arz","asa","asb","asc","asd","ase","asf","asg","ash","asi","asj","ask","asl","asn","aso","asp","asq","asr","ass","ast","asu","asv","asw","asx","asy","asz","ata","atb","atc","atd","ate","atg","ath","ati","atj","atk","atl","atm","atn","ato","atp","atq","atr","ats","att","atu","atv","atw","atx","aty","atz","aua","aub","auc","aud","aue","auf","aug","auh","aui","auj","auk","aul","aum","aun","auo","aup","auq","aur","aus","aut","auu","auw","aux","auy","auz","avb","avd","avi","avk","avl","avm","avn","avo","avs","avt","avu","avv","awa","awb","awc","awd","awe","awg","awh","awi","awk","awm","awn","awo","awr","aws","awt","awu","awv","aww","awx","awy","axb","axe","axg","axk","axl","axm","axx","aya","ayb","ayc","ayd","aye","ayg","ayh","ayi","ayk","ayl","ayn","ayo","ayp","ayq","ayr","ays","ayt","ayu","ayx","ayy","ayz","aza","azb","azc","azd","azg","azj","azm","azn","azo","azt","azz","baa","bab","bac","bad","bae","baf","bag","bah","bai","baj","bal","ban","bao","bap","bar","bas","bat","bau","bav","baw","bax","bay","baz","bba","bbb","bbc","bbd","bbe","bbf","bbg","bbh","bbi","bbj","bbk","bbl","bbm","bbn","bbo","bbp","bbq","bbr","bbs","bbt","bbu","bbv","bbw","bbx","bby","bbz","bca","bcb","bcc","bcd","bce","bcf","bcg","bch","bci","bcj","bck","bcl","bcm","bcn","bco","bcp","bcq","bcr","bcs","bct","bcu","bcv","bcw","bcy","bcz","bda","bdb","bdc","bdd","bde","bdf","bdg","bdh","bdi","bdj","bdk","bdl","bdm","bdn","bdo","bdp","bdq","bdr","bds","bdt","bdu","bdv","bdw","bdx","bdy","bdz","bea","beb","bec","bed","bee","bef","beg","beh","bei","bej","bek","bem","beo","bep","beq","ber","bes","bet","beu","bev","bew","bex","bey","bez","bfa","bfb","bfc","bfd","bfe","bff","bfg","bfh","bfi","bfj","bfk","bfl","bfm","bfn","bfo","bfp","bfq","bfr","bfs","bft","bfu","bfw","bfx","bfy","bfz","bga","bgb","bgc","bgd","bge","bgf","bgg","bgi","bgj","bgk","bgl","bgm","bgn","bgo","bgp","bgq","bgr","bgs","bgt","bgu","bgv","bgw","bgx","bgy","bgz","bha","bhb","bhc","bhd","bhe","bhf","bhg","bhh","bhi","bhj","bhk","bhl","bhm","bhn","bho","bhp","bhq","bhr","bhs","bht","bhu","bhv","bhw","bhx","bhy","bhz","bia","bib","bic","bid","bie","bif","big","bij","bik","bil","bim","bin","bio","bip","biq","bir","bit","biu","biv","biw","bix","biy","biz","bja","bjb","bjc","bjd","bje","bjf","bjg","bjh","bji","bjj","bjk","bjl","bjm","bjn","bjo","bjp","bjq","bjr","bjs","bjt","bju","bjv","bjw","bjx","bjy","bjz","bka","bkb","bkc","bkd","bkf","bkg","bkh","bki","bkj","bkk","bkl","bkm","bkn","bko","bkp","bkq","bkr","bks","bkt","bku","bkv","bkw","bkx","bky","bkz","bla","blb","blc","bld","ble","blf","blg","blh","bli","blj","blk","bll","blm","bln","blo","blp","blq","blr","bls","blt","blv","blw","blx","bly","blz","bma","bmb","bmc","bmd","bme","bmf","bmg","bmh","bmi","bmj","bmk","bml","bmm","bmn","bmo","bmp","bmq","bmr","bms","bmt","bmu","bmv","bmw","bmx","bmy","bmz","bna","bnb","bnc","bnd","bne","bnf","bng","bni","bnj","bnk","bnl","bnm","bnn","bno","bnp","bnq","bnr","bns","bnt","bnu","bnv","bnw","bnx","bny","bnz","boa","bob","boe","bof","bog","boh","boi","boj","bok","bol","bom","bon","boo","bop","boq","bor","bot","bou","bov","bow","box","boy","boz","bpa","bpb","bpd","bpg","bph","bpi","bpj","bpk","bpl","bpm","bpn","bpo","bpp","bpq","bpr","bps","bpt","bpu","bpv","bpw","bpx","bpy","bpz","bqa","bqb","bqc","bqd","bqf","bqg","bqh","bqi","bqj","bqk","bql","bqm","bqn","bqo","bqp","bqq","bqr","bqs","bqt","bqu","bqv","bqw","bqx","bqy","bqz","bra","brb","brc","brd","brf","brg","brh","bri","brj","brk","brl","brm","brn","bro","brp","brq","brr","brs","brt","bru","brv","brw","brx","bry","brz","bsa","bsb","bsc","bse","bsf","bsg","bsh","bsi","bsj","bsk","bsl","bsm","bsn","bso","bsp","bsq","bsr","bss","bst","bsu","bsv","bsw","bsx","bsy","bta","btb","btc","btd","bte","btf","btg","bth","bti","btj","btk","btl","btm","btn","bto","btp","btq","btr","bts","btt","btu","btv","btw","btx","bty","btz","bua","bub","buc","bud","bue","buf","bug","buh","bui","buj","buk","bum","bun","buo","bup","buq","bus","but","buu","buv","buw","bux","buy","buz","bva","bvb","bvc","bvd","bve","bvf","bvg","bvh","bvi","bvj","bvk","bvl","bvm","bvn","bvo","bvp","bvq","bvr","bvt","bvu","bvv","bvw","bvx","bvy","bvz","bwa","bwb","bwc","bwd","bwe","bwf","bwg","bwh","bwi","bwj","bwk","bwl","bwm","bwn","bwo","bwp","bwq","bwr","bws","bwt","bwu","bww","bwx","bwy","bwz","bxa","bxb","bxc","bxd","bxe","bxf","bxg","bxh","bxi","bxj","bxk","bxl","bxm","bxn","bxo","bxp","bxq","bxr","bxs","bxu","bxv","bxw","bxx","bxz","bya","byb","byc","byd","bye","byf","byg","byh","byi","byj","byk","byl","bym","byn","byo","byp","byq","byr","bys","byt","byv","byw","byx","byy","byz","bza","bzb","bzc","bzd","bze","bzf","bzg","bzh","bzi","bzj","bzk","bzl","bzm","bzn","bzo","bzp","bzq","bzr","bzs","bzt","bzu","bzv","bzw","bzx","bzy","bzz","caa","cab","cac","cad","cae","caf","cag","cah","cai","caj","cak","cal","cam","can","cao","cap","caq","car","cas","cau","cav","caw","cax","cay","caz","cba","cbb","cbc","cbd","cbe","cbg","cbh","cbi","cbj","cbk","cbl","cbn","cbo","cbq","cbr","cbs","cbt","cbu","cbv","cbw","cby","cca","ccc","ccd","cce","ccg","cch","ccj","ccl","ccm","ccn","cco","ccp","ccq","ccr","ccs","cda","cdc","cdd","cde","cdf","cdg","cdh","cdi","cdj","cdm","cdn","cdo","cdr","cds","cdy","cdz","cea","ceb","ceg","cek","cel","cen","cet","cfa","cfd","cfg","cfm","cga","cgc","cgg","cgk","chb","chc","chd","chf","chg","chh","chj","chk","chl","chm","chn","cho","chp","chq","chr","cht","chw","chx","chy","chz","cia","cib","cic","cid","cie","cih","cik","cim","cin","cip","cir","ciw","ciy","cja","cje","cjh","cji","cjk","cjm","cjn","cjo","cjp","cjr","cjs","cjv","cjy","cka","ckb","ckh","ckl","ckn","cko","ckq","ckr","cks","ckt","cku","ckv","ckx","cky","ckz","cla","clc","cld","cle","clh","cli","clj","clk","cll","clm","clo","clt","clu","clw","cly","cma","cmc","cme","cmg","cmi","cmk","cml","cmm","cmn","cmo","cmr","cms","cmt","cna","cnb","cnc","cng","cnh","cni","cnk","cnl","cno","cns","cnt","cnu","cnw","cnx","coa","cob","coc","cod","coe","cof","cog","coh","coj","cok","col","com","con","coo","cop","coq","cot","cou","cov","cow","cox","coy","coz","cpa","cpb","cpc","cpe","cpf","cpg","cpi","cpn","cpo","cpp","cps","cpu","cpx","cpy","cqd","cqu","cra","crb","crc","crd","crf","crg","crh","cri","crj","crk","crl","crm","crn","cro","crp","crq","crr","crs","crt","crv","crw","crx","cry","crz","csa","csb","csc","csd","cse","csf","csg","csh","csi","csj","csk","csl","csm","csn","cso","csq","csr","css","cst","csu","csv","csw","csy","csz","cta","ctc","ctd","cte","ctg","cth","ctl","ctm","ctn","cto","ctp","cts","ctt","ctu","ctz","cua","cub","cuc","cug","cuh","cui","cuj","cuk","cul","cum","cuo","cup","cuq","cur","cus","cut","cuu","cuv","cuw","cux","cvg","cvn","cwa","cwb","cwd","cwe","cwg","cwt","cya","cyb","cyo","czh","czk","czn","czo","czt","daa","dac","dad","dae","daf","dag","dah","dai","daj","dak","dal","dam","dao","dap","daq","dar","das","dau","dav","daw","dax","day","daz","dba","dbb","dbd","dbe","dbf","dbg","dbi","dbj","dbl","dbm","dbn","dbo","dbp","dbq","dbr","dbt","dbu","dbv","dbw","dby","dcc","dcr","dda","ddd","dde","ddg","ddi","ddj","ddn","ddo","ddr","dds","ddw","dec","ded","dee","def","deg","deh","dei","dek","del","dem","den","dep","deq","der","des","dev","dez","dga","dgb","dgc","dgd","dge","dgg","dgh","dgi","dgk","dgl","dgn","dgo","dgr","dgs","dgt","dgu","dgw","dgx","dgz","dha","dhd","dhg","dhi","dhl","dhm","dhn","dho","dhr","dhs","dhu","dhv","dhw","dhx","dia","dib","dic","did","dif","dig","dih","dii","dij","dik","dil","dim","din","dio","dip","diq","dir","dis","dit","diu","diw","dix","diy","diz","dja","djb","djc","djd","dje","djf","dji","djj","djk","djl","djm","djn","djo","djr","dju","djw","dka","dkk","dkl","dkr","dks","dkx","dlg","dlk","dlm","dln","dma","dmb","dmc","dmd","dme","dmg","dmk","dml","dmm","dmn","dmo","dmr","dms","dmu","dmv","dmw","dmx","dmy","dna","dnd","dne","dng","dni","dnj","dnk","dnn","dnr","dnt","dnu","dnv","dnw","dny","doa","dob","doc","doe","dof","doh","doi","dok","dol","don","doo","dop","doq","dor","dos","dot","dov","dow","dox","doy","doz","dpp","dra","drb","drc","drd","dre","drg","drh","dri","drl","drn","dro","drq","drr","drs","drt","dru","drw","dry","dsb","dse","dsh","dsi","dsl","dsn","dso","dsq","dta","dtb","dtd","dth","dti","dtk","dtm","dtn","dto","dtp","dtr","dts","dtt","dtu","dty","dua","dub","duc","dud","due","duf","dug","duh","dui","duj","duk","dul","dum","dun","duo","dup","duq","dur","dus","duu","duv","duw","dux","duy","duz","dva","dwa","dwl","dwr","dws","dwu","dww","dwy","dya","dyb","dyd","dyg","dyi","dym","dyn","dyo","dyu","dyy","dza","dzd","dze","dzg","dzl","dzn","eaa","ebg","ebk","ebo","ebr","ebu","ecr","ecs","ecy","eee","efa","efe","efi","ega","egl","ego","egx","egy","ehu","eip","eit","eiv","eja","eka","ekc","eke","ekg","eki","ekk","ekl","ekm","eko","ekp","ekr","eky","ele","elh","eli","elk","elm","elo","elp","elu","elx","ema","emb","eme","emg","emi","emk","emm","emn","emo","emp","ems","emu","emw","emx","emy","ena","enb","enc","end","enf","enh","enl","enm","enn","eno","enq","enr","enu","env","enw","enx","eot","epi","era","erg","erh","eri","erk","ero","err","ers","ert","erw","ese","esg","esh","esi","esk","esl","esm","esn","eso","esq","ess","esu","esx","esy","etb","etc","eth","etn","eto","etr","ets","ett","etu","etx","etz","euq","eve","evh","evn","ewo","ext","eya","eyo","eza","eze","faa","fab","fad","faf","fag","fah","fai","faj","fak","fal","fam","fan","fap","far","fat","fau","fax","fay","faz","fbl","fcs","fer","ffi","ffm","fgr","fia","fie","fil","fip","fir","fit","fiu","fiw","fkk","fkv","fla","flh","fli","fll","fln","flr","fly","fmp","fmu","fnb","fng","fni","fod","foi","fom","fon","for","fos","fox","fpe","fqs","frc","frd","frk","frm","fro","frp","frq","frr","frs","frt","fse","fsl","fss","fub","fuc","fud","fue","fuf","fuh","fui","fuj","fum","fun","fuq","fur","fut","fuu","fuv","fuy","fvr","fwa","fwe","gaa","gab","gac","gad","gae","gaf","gag","gah","gai","gaj","gak","gal","gam","gan","gao","gap","gaq","gar","gas","gat","gau","gav","gaw","gax","gay","gaz","gba","gbb","gbc","gbd","gbe","gbf","gbg","gbh","gbi","gbj","gbk","gbl","gbm","gbn","gbo","gbp","gbq","gbr","gbs","gbu","gbv","gbw","gbx","gby","gbz","gcc","gcd","gce","gcf","gcl","gcn","gcr","gct","gda","gdb","gdc","gdd","gde","gdf","gdg","gdh","gdi","gdj","gdk","gdl","gdm","gdn","gdo","gdq","gdr","gds","gdt","gdu","gdx","gea","geb","gec","ged","geg","geh","gei","gej","gek","gel","gem","geq","ges","gev","gew","gex","gey","gez","gfk","gft","gfx","gga","ggb","ggd","gge","ggg","ggk","ggl","ggn","ggo","ggr","ggt","ggu","ggw","gha","ghc","ghe","ghh","ghk","ghl","ghn","gho","ghr","ghs","ght","gia","gib","gic","gid","gie","gig","gih","gil","gim","gin","gio","gip","giq","gir","gis","git","giu","giw","gix","giy","giz","gji","gjk","gjm","gjn","gjr","gju","gka","gke","gkn","gko","gkp","gku","glc","gld","glh","gli","glj","glk","gll","glo","glr","glu","glw","gly","gma","gmb","gmd","gme","gmg","gmh","gml","gmm","gmn","gmq","gmu","gmv","gmw","gmx","gmy","gmz","gna","gnb","gnc","gnd","gne","gng","gnh","gni","gnk","gnl","gnm","gnn","gno","gnq","gnr","gnt","gnu","gnw","gnz","goa","gob","goc","god","goe","gof","gog","goh","goi","goj","gok","gol","gom","gon","goo","gop","goq","gor","gos","got","gou","gow","gox","goy","goz","gpa","gpe","gpn","gqa","gqi","gqn","gqr","gqu","gra","grb","grc","grd","grg","grh","gri","grj","grk","grm","gro","grq","grr","grs","grt","gru","grv","grw","grx","gry","grz","gse","gsg","gsl","gsm","gsn","gso","gsp","gss","gsw","gta","gti","gtu","gua","gub","guc","gud","gue","guf","gug","guh","gui","guk","gul","gum","gun","guo","gup","guq","gur","gus","gut","guu","guv","guw","gux","guz","gva","gvc","gve","gvf","gvj","gvl","gvm","gvn","gvo","gvp","gvr","gvs","gvy","gwa","gwb","gwc","gwd","gwe","gwf","gwg","gwi","gwj","gwm","gwn","gwr","gwt","gwu","gww","gwx","gxx","gya","gyb","gyd","gye","gyf","gyg","gyi","gyl","gym","gyn","gyr","gyy","gza","gzi","gzn","haa","hab","hac","had","hae","haf","hag","hah","hai","haj","hak","hal","ham","han","hao","hap","haq","har","has","hav","haw","hax","hay","haz","hba","hbb","hbn","hbo","hbu","hca","hch","hdn","hds","hdy","hea","hed","heg","heh","hei","hem","hgm","hgw","hhi","hhr","hhy","hia","hib","hid","hif","hig","hih","hii","hij","hik","hil","him","hio","hir","hit","hiw","hix","hji","hka","hke","hkk","hks","hla","hlb","hld","hle","hlt","hlu","hma","hmb","hmc","hmd","hme","hmf","hmg","hmh","hmi","hmj","hmk","hml","hmm","hmn","hmp","hmq","hmr","hms","hmt","hmu","hmv","hmw","hmx","hmy","hmz","hna","hnd","hne","hnh","hni","hnj","hnn","hno","hns","hnu","hoa","hob","hoc","hod","hoe","hoh","hoi","hoj","hok","hol","hom","hoo","hop","hor","hos","hot","hov","how","hoy","hoz","hpo","hps","hra","hrc","hre","hrk","hrm","hro","hrp","hrr","hrt","hru","hrw","hrx","hrz","hsb","hsh","hsl","hsn","hss","hti","hto","hts","htu","htx","hub","huc","hud","hue","huf","hug","huh","hui","huj","huk","hul","hum","huo","hup","huq","hur","hus","hut","huu","huv","huw","hux","huy","huz","hvc","hve","hvk","hvn","hvv","hwa","hwc","hwo","hya","hyx","iai","ian","iap","iar","iba","ibb","ibd","ibe","ibg","ibh","ibi","ibl","ibm","ibn","ibr","ibu","iby","ica","ich","icl","icr","ida","idb","idc","idd","ide","idi","idr","ids","idt","idu","ifa","ifb","ife","iff","ifk","ifm","ifu","ify","igb","ige","igg","igl","igm","ign","igo","igs","igw","ihb","ihi","ihp","ihw","iin","iir","ijc","ije","ijj","ijn","ijo","ijs","ike","iki","ikk","ikl","iko","ikp","ikr","iks","ikt","ikv","ikw","ikx","ikz","ila","ilb","ilg","ili","ilk","ill","ilm","ilo","ilp","ils","ilu","ilv","ilw","ima","ime","imi","iml","imn","imo","imr","ims","imy","inb","inc","ine","ing","inh","inj","inl","inm","inn","ino","inp","ins","int","inz","ior","iou","iow","ipi","ipo","iqu","iqw","ira","ire","irh","iri","irk","irn","iro","irr","iru","irx","iry","isa","isc","isd","ise","isg","ish","isi","isk","ism","isn","iso","isr","ist","isu","itb","itc","itd","ite","iti","itk","itl","itm","ito","itr","its","itt","itv","itw","itx","ity","itz","ium","ivb","ivv","iwk","iwm","iwo","iws","ixc","ixl","iya","iyo","iyx","izh","izi","izr","izz","jaa","jab","jac","jad","jae","jaf","jah","jaj","jak","jal","jam","jan","jao","jaq","jar","jas","jat","jau","jax","jay","jaz","jbe","jbi","jbj","jbk","jbn","jbo","jbr","jbt","jbu","jbw","jcs","jct","jda","jdg","jdt","jeb","jee","jeg","jeh","jei","jek","jel","jen","jer","jet","jeu","jgb","jge","jgk","jgo","jhi","jhs","jia","jib","jic","jid","jie","jig","jih","jii","jil","jim","jio","jiq","jit","jiu","jiv","jiy","jje","jjr","jka","jkm","jko","jkp","jkr","jku","jle","jls","jma","jmb","jmc","jmd","jmi","jml","jmn","jmr","jms","jmw","jmx","jna","jnd","jng","jni","jnj","jnl","jns","job","jod","jog","jor","jos","jow","jpa","jpr","jpx","jqr","jra","jrb","jrr","jrt","jru","jsl","jua","jub","juc","jud","juh","jui","juk","jul","jum","jun","juo","jup","jur","jus","jut","juu","juw","juy","jvd","jvn","jwi","jya","jye","jyy","kaa","kab","kac","kad","kae","kaf","kag","kah","kai","kaj","kak","kam","kao","kap","kaq","kar","kav","kaw","kax","kay","kba","kbb","kbc","kbd","kbe","kbf","kbg","kbh","kbi","kbj","kbk","kbl","kbm","kbn","kbo","kbp","kbq","kbr","kbs","kbt","kbu","kbv","kbw","kbx","kby","kbz","kca","kcb","kcc","kcd","kce","kcf","kcg","kch","kci","kcj","kck","kcl","kcm","kcn","kco","kcp","kcq","kcr","kcs","kct","kcu","kcv","kcw","kcx","kcy","kcz","kda","kdc","kdd","kde","kdf","kdg","kdh","kdi","kdj","kdk","kdl","kdm","kdn","kdo","kdp","kdq","kdr","kdt","kdu","kdv","kdw","kdx","kdy","kdz","kea","keb","kec","ked","kee","kef","keg","keh","kei","kej","kek","kel","kem","ken","keo","kep","keq","ker","kes","ket","keu","kev","kew","kex","key","kez","kfa","kfb","kfc","kfd","kfe","kff","kfg","kfh","kfi","kfj","kfk","kfl","kfm","kfn","kfo","kfp","kfq","kfr","kfs","kft","kfu","kfv","kfw","kfx","kfy","kfz","kga","kgb","kgc","kgd","kge","kgf","kgg","kgh","kgi","kgj","kgk","kgl","kgm","kgn","kgo","kgp","kgq","kgr","kgs","kgt","kgu","kgv","kgw","kgx","kgy","kha","khb","khc","khd","khe","khf","khg","khh","khi","khj","khk","khl","khn","kho","khp","khq","khr","khs","kht","khu","khv","khw","khx","khy","khz","kia","kib","kic","kid","kie","kif","kig","kih","kii","kij","kil","kim","kio","kip","kiq","kis","kit","kiu","kiv","kiw","kix","kiy","kiz","kja","kjb","kjc","kjd","kje","kjf","kjg","kjh","kji","kjj","kjk","kjl","kjm","kjn","kjo","kjp","kjq","kjr","kjs","kjt","kju","kjv","kjx","kjy","kjz","kka","kkb","kkc","kkd","kke","kkf","kkg","kkh","kki","kkj","kkk","kkl","kkm","kkn","kko","kkp","kkq","kkr","kks","kkt","kku","kkv","kkw","kkx","kky","kkz","kla","klb","klc","kld","kle","klf","klg","klh","kli","klj","klk","kll","klm","kln","klo","klp","klq","klr","kls","klt","klu","klv","klw","klx","kly","klz","kma","kmb","kmc","kmd","kme","kmf","kmg","kmh","kmi","kmj","kmk","kml","kmm","kmn","kmo","kmp","kmq","kmr","kms","kmt","kmu","kmv","kmw","kmx","kmy","kmz","kna","knb","knc","knd","kne","knf","kng","kni","knj","knk","knl","knm","knn","kno","knp","knq","knr","kns","knt","knu","knv","knw","knx","kny","knz","koa","koc","kod","koe","kof","kog","koh","koi","koj","kok","kol","koo","kop","koq","kos","kot","kou","kov","kow","kox","koy","koz","kpa","kpb","kpc","kpd","kpe","kpf","kpg","kph","kpi","kpj","kpk","kpl","kpm","kpn","kpo","kpp","kpq","kpr","kps","kpt","kpu","kpv","kpw","kpx","kpy","kpz","kqa","kqb","kqc","kqd","kqe","kqf","kqg","kqh","kqi","kqj","kqk","kql","kqm","kqn","kqo","kqp","kqq","kqr","kqs","kqt","kqu","kqv","kqw","kqx","kqy","kqz","kra","krb","krc","krd","kre","krf","krh","kri","krj","krk","krl","krm","krn","kro","krp","krr","krs","krt","kru","krv","krw","krx","kry","krz","ksa","ksb","ksc","ksd","kse","ksf","ksg","ksh","ksi","ksj","ksk","ksl","ksm","ksn","kso","ksp","ksq","ksr","kss","kst","ksu","ksv","ksw","ksx","ksy","ksz","kta","ktb","ktc","ktd","kte","ktf","ktg","kth","kti","ktj","ktk","ktl","ktm","ktn","kto","ktp","ktq","ktr","kts","ktt","ktu","ktv","ktw","ktx","kty","ktz","kub","kuc","kud","kue","kuf","kug","kuh","kui","kuj","kuk","kul","kum","kun","kuo","kup","kuq","kus","kut","kuu","kuv","kuw","kux","kuy","kuz","kva","kvb","kvc","kvd","kve","kvf","kvg","kvh","kvi","kvj","kvk","kvl","kvm","kvn","kvo","kvp","kvq","kvr","kvs","kvt","kvu","kvv","kvw","kvx","kvy","kvz","kwa","kwb","kwc","kwd","kwe","kwf","kwg","kwh","kwi","kwj","kwk","kwl","kwm","kwn","kwo","kwp","kwq","kwr","kws","kwt","kwu","kwv","kww","kwx","kwy","kwz","kxa","kxb","kxc","kxd","kxe","kxf","kxh","kxi","kxj","kxk","kxl","kxm","kxn","kxo","kxp","kxq","kxr","kxs","kxt","kxu","kxv","kxw","kxx","kxy","kxz","kya","kyb","kyc","kyd","kye","kyf","kyg","kyh","kyi","kyj","kyk","kyl","kym","kyn","kyo","kyp","kyq","kyr","kys","kyt","kyu","kyv","kyw","kyx","kyy","kyz","kza","kzb","kzc","kzd","kze","kzf","kzg","kzh","kzi","kzj","kzk","kzl","kzm","kzn","kzo","kzp","kzq","kzr","kzs","kzt","kzu","kzv","kzw","kzx","kzy","kzz","laa","lab","lac","lad","lae","laf","lag","lah","lai","laj","lak","lal","lam","lan","lap","laq","lar","las","lau","law","lax","lay","laz","lba","lbb","lbc","lbe","lbf","lbg","lbi","lbj","lbk","lbl","lbm","lbn","lbo","lbq","lbr","lbs","lbt","lbu","lbv","lbw","lbx","lby","lbz","lcc","lcd","lce","lcf","lch","lcl","lcm","lcp","lcq","lcs","lda","ldb","ldd","ldg","ldh","ldi","ldj","ldk","ldl","ldm","ldn","ldo","ldp","ldq","lea","leb","lec","led","lee","lef","leg","leh","lei","lej","lek","lel","lem","len","leo","lep","leq","ler","les","let","leu","lev","lew","lex","ley","lez","lfa","lfn","lga","lgb","lgg","lgh","lgi","lgk","lgl","lgm","lgn","lgq","lgr","lgt","lgu","lgz","lha","lhh","lhi","lhl","lhm","lhn","lhp","lhs","lht","lhu","lia","lib","lic","lid","lie","lif","lig","lih","lii","lij","lik","lil","lio","lip","liq","lir","lis","liu","liv","liw","lix","liy","liz","lja","lje","lji","ljl","ljp","ljw","ljx","lka","lkb","lkc","lkd","lke","lkh","lki","lkj","lkl","lkm","lkn","lko","lkr","lks","lkt","lku","lky","lla","llb","llc","lld","lle","llf","llg","llh","lli","llj","llk","lll","llm","lln","llo","llp","llq","lls","llu","llx","lma","lmb","lmc","lmd","lme","lmf","lmg","lmh","lmi","lmj","lmk","lml","lmm","lmn","lmo","lmp","lmq","lmr","lmu","lmv","lmw","lmx","lmy","lmz","lna","lnb","lnd","lng","lnh","lni","lnj","lnl","lnm","lnn","lno","lns","lnu","lnw","lnz","loa","lob","loc","loe","lof","log","loh","loi","loj","lok","lol","lom","lon","loo","lop","loq","lor","los","lot","lou","lov","low","lox","loy","loz","lpa","lpe","lpn","lpo","lpx","lra","lrc","lre","lrg","lri","lrk","lrl","lrm","lrn","lro","lrr","lrt","lrv","lrz","lsa","lsd","lse","lsg","lsh","lsi","lsl","lsm","lso","lsp","lsr","lss","lst","lsy","ltc","ltg","lth","lti","ltn","lto","lts","ltu","lua","luc","lud","lue","luf","lui","luj","luk","lul","lum","lun","luo","lup","luq","lur","lus","lut","luu","luv","luw","luy","luz","lva","lvk","lvs","lvu","lwa","lwe","lwg","lwh","lwl","lwm","lwo","lwt","lwu","lww","lya","lyg","lyn","lzh","lzl","lzn","lzz","maa","mab","mad","mae","maf","mag","mai","maj","mak","mam","man","map","maq","mas","mat","mau","mav","maw","max","maz","mba","mbb","mbc","mbd","mbe","mbf","mbh","mbi","mbj","mbk","mbl","mbm","mbn","mbo","mbp","mbq","mbr","mbs","mbt","mbu","mbv","mbw","mbx","mby","mbz","mca","mcb","mcc","mcd","mce","mcf","mcg","mch","mci","mcj","mck","mcl","mcm","mcn","mco","mcp","mcq","mcr","mcs","mct","mcu","mcv","mcw","mcx","mcy","mcz","mda","mdb","mdc","mdd","mde","mdf","mdg","mdh","mdi","mdj","mdk","mdl","mdm","mdn","mdp","mdq","mdr","mds","mdt","mdu","mdv","mdw","mdx","mdy","mdz","mea","meb","mec","med","mee","mef","meg","meh","mei","mej","mek","mel","mem","men","meo","mep","meq","mer","mes","met","meu","mev","mew","mey","mez","mfa","mfb","mfc","mfd","mfe","mff","mfg","mfh","mfi","mfj","mfk","mfl","mfm","mfn","mfo","mfp","mfq","mfr","mfs","mft","mfu","mfv","mfw","mfx","mfy","mfz","mga","mgb","mgc","mgd","mge","mgf","mgg","mgh","mgi","mgj","mgk","mgl","mgm","mgn","mgo","mgp","mgq","mgr","mgs","mgt","mgu","mgv","mgw","mgx","mgy","mgz","mha","mhb","mhc","mhd","mhe","mhf","mhg","mhh","mhi","mhj","mhk","mhl","mhm","mhn","mho","mhp","mhq","mhr","mhs","mht","mhu","mhw","mhx","mhy","mhz","mia","mib","mic","mid","mie","mif","mig","mih","mii","mij","mik","mil","mim","min","mio","mip","miq","mir","mis","mit","miu","miw","mix","miy","miz","mja","mjb","mjc","mjd","mje","mjg","mjh","mji","mjj","mjk","mjl","mjm","mjn","mjo","mjp","mjq","mjr","mjs","mjt","mju","mjv","mjw","mjx","mjy","mjz","mka","mkb","mkc","mke","mkf","mkg","mkh","mki","mkj","mkk","mkl","mkm","mkn","mko","mkp","mkq","mkr","mks","mkt","mku","mkv","mkw","mkx","mky","mkz","mla","mlb","mlc","mld","mle","mlf","mlh","mli","mlj","mlk","mll","mlm","mln","mlo","mlp","mlq","mlr","mls","mlu","mlv","mlw","mlx","mlz","mma","mmb","mmc","mmd","mme","mmf","mmg","mmh","mmi","mmj","mmk","mml","mmm","mmn","mmo","mmp","mmq","mmr","mmt","mmu","mmv","mmw","mmx","mmy","mmz","mna","mnb","mnc","mnd","mne","mnf","mng","mnh","mni","mnj","mnk","mnl","mnm","mnn","mno","mnp","mnq","mnr","mns","mnt","mnu","mnv","mnw","mnx","mny","mnz","moa","moc","mod","moe","mof","mog","moh","moi","moj","mok","mom","moo","mop","moq","mor","mos","mot","mou","mov","mow","mox","moy","moz","mpa","mpb","mpc","mpd","mpe","mpg","mph","mpi","mpj","mpk","mpl","mpm","mpn","mpo","mpp","mpq","mpr","mps","mpt","mpu","mpv","mpw","mpx","mpy","mpz","mqa","mqb","mqc","mqe","mqf","mqg","mqh","mqi","mqj","mqk","mql","mqm","mqn","mqo","mqp","mqq","mqr","mqs","mqt","mqu","mqv","mqw","mqx","mqy","mqz","mra","mrb","mrc","mrd","mre","mrf","mrg","mrh","mrj","mrk","mrl","mrm","mrn","mro","mrp","mrq","mrr","mrs","mrt","mru","mrv","mrw","mrx","mry","mrz","msb","msc","msd","mse","msf","msg","msh","msi","msj","msk","msl","msm","msn","mso","msp","msq","msr","mss","mst","msu","msv","msw","msx","msy","msz","mta","mtb","mtc","mtd","mte","mtf","mtg","mth","mti","mtj","mtk","mtl","mtm","mtn","mto","mtp","mtq","mtr","mts","mtt","mtu","mtv","mtw","mtx","mty","mua","mub","muc","mud","mue","mug","muh","mui","muj","muk","mul","mum","mun","muo","mup","muq","mur","mus","mut","muu","muv","mux","muy","muz","mva","mvb","mvd","mve","mvf","mvg","mvh","mvi","mvk","mvl","mvm","mvn","mvo","mvp","mvq","mvr","mvs","mvt","mvu","mvv","mvw","mvx","mvy","mvz","mwa","mwb","mwc","mwd","mwe","mwf","mwg","mwh","mwi","mwj","mwk","mwl","mwm","mwn","mwo","mwp","mwq","mwr","mws","mwt","mwu","mwv","mww","mwx","mwy","mwz","mxa","mxb","mxc","mxd","mxe","mxf","mxg","mxh","mxi","mxj","mxk","mxl","mxm","mxn","mxo","mxp","mxq","mxr","mxs","mxt","mxu","mxv","mxw","mxx","mxy","mxz","myb","myc","myd","mye","myf","myg","myh","myi","myj","myk","myl","mym","myn","myo","myp","myq","myr","mys","myt","myu","myv","myw","myx","myy","myz","mza","mzb","mzc","mzd","mze","mzg","mzh","mzi","mzj","mzk","mzl","mzm","mzn","mzo","mzp","mzq","mzr","mzs","mzt","mzu","mzv","mzw","mzx","mzy","mzz","naa","nab","nac","nad","nae","naf","nag","nah","nai","naj","nak","nal","nam","nan","nao","nap","naq","nar","nas","nat","naw","nax","nay","naz","nba","nbb","nbc","nbd","nbe","nbf","nbg","nbh","nbi","nbj","nbk","nbm","nbn","nbo","nbp","nbq","nbr","nbs","nbt","nbu","nbv","nbw","nbx","nby","nca","ncb","ncc","ncd","nce","ncf","ncg","nch","nci","ncj","nck","ncl","ncm","ncn","nco","ncp","ncq","ncr","ncs","nct","ncu","ncx","ncz","nda","ndb","ndc","ndd","ndf","ndg","ndh","ndi","ndj","ndk","ndl","ndm","ndn","ndp","ndq","ndr","nds","ndt","ndu","ndv","ndw","ndx","ndy","ndz","nea","neb","nec","ned","nee","nef","neg","neh","nei","nej","nek","nem","nen","neo","neq","ner","nes","net","neu","nev","new","nex","ney","nez","nfa","nfd","nfl","nfr","nfu","nga","ngb","ngc","ngd","nge","ngf","ngg","ngh","ngi","ngj","ngk","ngl","ngm","ngn","ngo","ngp","ngq","ngr","ngs","ngt","ngu","ngv","ngw","ngx","ngy","ngz","nha","nhb","nhc","nhd","nhe","nhf","nhg","nhh","nhi","nhk","nhm","nhn","nho","nhp","nhq","nhr","nht","nhu","nhv","nhw","nhx","nhy","nhz","nia","nib","nic","nid","nie","nif","nig","nih","nii","nij","nik","nil","nim","nin","nio","niq","nir","nis","nit","niu","niv","niw","nix","niy","niz","nja","njb","njd","njh","nji","njj","njl","njm","njn","njo","njr","njs","njt","nju","njx","njy","njz","nka","nkb","nkc","nkd","nke","nkf","nkg","nkh","nki","nkj","nkk","nkm","nkn","nko","nkp","nkq","nkr","nks","nkt","nku","nkv","nkw","nkx","nkz","nla","nlc","nle","nlg","nli","nlj","nlk","nll","nln","nlo","nlq","nlr","nlu","nlv","nlw","nlx","nly","nlz","nma","nmb","nmc","nmd","nme","nmf","nmg","nmh","nmi","nmj","nmk","nml","nmm","nmn","nmo","nmp","nmq","nmr","nms","nmt","nmu","nmv","nmw","nmx","nmy","nmz","nna","nnb","nnc","nnd","nne","nnf","nng","nnh","nni","nnj","nnk","nnl","nnm","nnn","nnp","nnq","nnr","nns","nnt","nnu","nnv","nnw","nnx","nny","nnz","noa","noc","nod","noe","nof","nog","noh","noi","noj","nok","nol","nom","non","noo","nop","noq","nos","not","nou","nov","now","noy","noz","npa","npb","npg","nph","npi","npl","npn","npo","nps","npu","npx","npy","nqg","nqk","nql","nqm","nqn","nqo","nqq","nqy","nra","nrb","nrc","nre","nrf","nrg","nri","nrk","nrl","nrm","nrn","nrp","nrr","nrt","nru","nrx","nrz","nsa","nsc","nsd","nse","nsf","nsg","nsh","nsi","nsk","nsl","nsm","nsn","nso","nsp","nsq","nsr","nss","nst","nsu","nsv","nsw","nsx","nsy","nsz","ntd","nte","ntg","nti","ntj","ntk","ntm","nto","ntp","ntr","nts","ntu","ntw","ntx","nty","ntz","nua","nub","nuc","nud","nue","nuf","nug","nuh","nui","nuj","nuk","nul","num","nun","nuo","nup","nuq","nur","nus","nut","nuu","nuv","nuw","nux","nuy","nuz","nvh","nvm","nvo","nwa","nwb","nwc","nwe","nwg","nwi","nwm","nwo","nwr","nwx","nwy","nxa","nxd","nxe","nxg","nxi","nxk","nxl","nxm","nxn","nxo","nxq","nxr","nxu","nxx","nyb","nyc","nyd","nye","nyf","nyg","nyh","nyi","nyj","nyk","nyl","nym","nyn","nyo","nyp","nyq","nyr","nys","nyt","nyu","nyv","nyw","nyx","nyy","nza","nzb","nzi","nzk","nzm","nzs","nzu","nzy","nzz","oaa","oac","oar","oav","obi","obk","obl","obm","obo","obr","obt","obu","oca","och","oco","ocu","oda","odk","odt","odu","ofo","ofs","ofu","ogb","ogc","oge","ogg","ogo","ogu","oht","ohu","oia","oin","ojb","ojc","ojg","ojp","ojs","ojv","ojw","oka","okb","okd","oke","okg","okh","oki","okj","okk","okl","okm","okn","oko","okr","oks","oku","okv","okx","ola","old","ole","olk","olm","olo","olr","olt","olu","oma","omb","omc","ome","omg","omi","omk","oml","omn","omo","omp","omq","omr","omt","omu","omv","omw","omx","ona","onb","one","ong","oni","onj","onk","onn","ono","onp","onr","ons","ont","onu","onw","onx","ood","oog","oon","oor","oos","opa","opk","opm","opo","opt","opy","ora","orc","ore","org","orh","orn","oro","orr","ors","ort","oru","orv","orw","orx","ory","orz","osa","osc","osi","oso","osp","ost","osu","osx","ota","otb","otd","ote","oti","otk","otl","otm","otn","oto","otq","otr","ots","ott","otu","otw","otx","oty","otz","oua","oub","oue","oui","oum","oun","ovd","owi","owl","oyb","oyd","oym","oyy","ozm","paa","pab","pac","pad","pae","paf","pag","pah","pai","pak","pal","pam","pao","pap","paq","par","pas","pat","pau","pav","paw","pax","pay","paz","pbb","pbc","pbe","pbf","pbg","pbh","pbi","pbl","pbn","pbo","pbp","pbr","pbs","pbt","pbu","pbv","pby","pbz","pca","pcb","pcc","pcd","pce","pcf","pcg","pch","pci","pcj","pck","pcl","pcm","pcn","pcp","pcr","pcw","pda","pdc","pdi","pdn","pdo","pdt","pdu","pea","peb","ped","pee","pef","peg","peh","pei","pej","pek","pel","pem","peo","pep","peq","pes","pev","pex","pey","pez","pfa","pfe","pfl","pga","pgd","pgg","pgi","pgk","pgl","pgn","pgs","pgu","pgy","pgz","pha","phd","phg","phh","phi","phk","phl","phm","phn","pho","phq","phr","pht","phu","phv","phw","pia","pib","pic","pid","pie","pif","pig","pih","pii","pij","pil","pim","pin","pio","pip","pir","pis","pit","piu","piv","piw","pix","piy","piz","pjt","pka","pkb","pkc","pkg","pkh","pkn","pko","pkp","pkr","pks","pkt","pku","pla","plb","plc","pld","ple","plf","plg","plh","plj","plk","pll","pln","plo","plp","plq","plr","pls","plt","plu","plv","plw","ply","plz","pma","pmb","pmc","pmd","pme","pmf","pmh","pmi","pmj","pmk","pml","pmm","pmn","pmo","pmq","pmr","pms","pmt","pmu","pmw","pmx","pmy","pmz","pna","pnb","pnc","pne","png","pnh","pni","pnj","pnk","pnl","pnm","pnn","pno","pnp","pnq","pnr","pns","pnt","pnu","pnv","pnw","pnx","pny","pnz","poc","pod","poe","pof","pog","poh","poi","pok","pom","pon","poo","pop","poq","pos","pot","pov","pow","pox","poy","poz","ppa","ppe","ppi","ppk","ppl","ppm","ppn","ppo","ppp","ppq","ppr","pps","ppt","ppu","pqa","pqe","pqm","pqw","pra","prb","prc","prd","pre","prf","prg","prh","pri","prk","prl","prm","prn","pro","prp","prq","prr","prs","prt","pru","prw","prx","pry","prz","psa","psc","psd","pse","psg","psh","psi","psl","psm","psn","pso","psp","psq","psr","pss","pst","psu","psw","psy","pta","pth","pti","ptn","pto","ptp","ptq","ptr","ptt","ptu","ptv","ptw","pty","pua","pub","puc","pud","pue","puf","pug","pui","puj","puk","pum","puo","pup","puq","pur","put","puu","puw","pux","puy","puz","pwa","pwb","pwg","pwi","pwm","pwn","pwo","pwr","pww","pxm","pye","pym","pyn","pys","pyu","pyx","pyy","pzn","qaa..qtz","qua","qub","quc","qud","quf","qug","quh","qui","quk","qul","qum","qun","qup","quq","qur","qus","quv","quw","qux","quy","quz","qva","qvc","qve","qvh","qvi","qvj","qvl","qvm","qvn","qvo","qvp","qvs","qvw","qvy","qvz","qwa","qwc","qwe","qwh","qwm","qws","qwt","qxa","qxc","qxh","qxl","qxn","qxo","qxp","qxq","qxr","qxs","qxt","qxu","qxw","qya","qyp","raa","rab","rac","rad","raf","rag","rah","rai","raj","rak","ral","ram","ran","rao","rap","raq","rar","ras","rat","rau","rav","raw","rax","ray","raz","rbb","rbk","rbl","rbp","rcf","rdb","rea","reb","ree","reg","rei","rej","rel","rem","ren","rer","res","ret","rey","rga","rge","rgk","rgn","rgr","rgs","rgu","rhg","rhp","ria","rie","rif","ril","rim","rin","rir","rit","riu","rjg","rji","rjs","rka","rkb","rkh","rki","rkm","rkt","rkw","rma","rmb","rmc","rmd","rme","rmf","rmg","rmh","rmi","rmk","rml","rmm","rmn","rmo","rmp","rmq","rmr","rms","rmt","rmu","rmv","rmw","rmx","rmy","rmz","rna","rnd","rng","rnl","rnn","rnp","rnr","rnw","roa","rob","roc","rod","roe","rof","rog","rol","rom","roo","rop","ror","rou","row","rpn","rpt","rri","rro","rrt","rsb","rsi","rsl","rsm","rtc","rth","rtm","rts","rtw","rub","ruc","rue","ruf","rug","ruh","rui","ruk","ruo","rup","ruq","rut","ruu","ruy","ruz","rwa","rwk","rwm","rwo","rwr","rxd","rxw","ryn","rys","ryu","rzh","saa","sab","sac","sad","sae","saf","sah","sai","saj","sak","sal","sam","sao","sap","saq","sar","sas","sat","sau","sav","saw","sax","say","saz","sba","sbb","sbc","sbd","sbe","sbf","sbg","sbh","sbi","sbj","sbk","sbl","sbm","sbn","sbo","sbp","sbq","sbr","sbs","sbt","sbu","sbv","sbw","sbx","sby","sbz","sca","scb","sce","scf","scg","sch","sci","sck","scl","scn","sco","scp","scq","scs","sct","scu","scv","scw","scx","sda","sdb","sdc","sde","sdf","sdg","sdh","sdj","sdk","sdl","sdm","sdn","sdo","sdp","sdr","sds","sdt","sdu","sdv","sdx","sdz","sea","seb","sec","sed","see","sef","seg","seh","sei","sej","sek","sel","sem","sen","seo","sep","seq","ser","ses","set","seu","sev","sew","sey","sez","sfb","sfe","sfm","sfs","sfw","sga","sgb","sgc","sgd","sge","sgg","sgh","sgi","sgj","sgk","sgl","sgm","sgn","sgo","sgp","sgr","sgs","sgt","sgu","sgw","sgx","sgy","sgz","sha","shb","shc","shd","she","shg","shh","shi","shj","shk","shl","shm","shn","sho","shp","shq","shr","shs","sht","shu","shv","shw","shx","shy","shz","sia","sib","sid","sie","sif","sig","sih","sii","sij","sik","sil","sim","sio","sip","siq","sir","sis","sit","siu","siv","siw","six","siy","siz","sja","sjb","sjd","sje","sjg","sjk","sjl","sjm","sjn","sjo","sjp","sjr","sjs","sjt","sju","sjw","ska","skb","skc","skd","ske","skf","skg","skh","ski","skj","skk","skm","skn","sko","skp","skq","skr","sks","skt","sku","skv","skw","skx","sky","skz","sla","slc","sld","sle","slf","slg","slh","sli","slj","sll","slm","sln","slp","slq","slr","sls","slt","slu","slw","slx","sly","slz","sma","smb","smc","smd","smf","smg","smh","smi","smj","smk","sml","smm","smn","smp","smq","smr","sms","smt","smu","smv","smw","smx","smy","smz","snb","snc","sne","snf","sng","snh","sni","snj","snk","snl","snm","snn","sno","snp","snq","snr","sns","snu","snv","snw","snx","sny","snz","soa","sob","soc","sod","soe","sog","soh","soi","soj","sok","sol","son","soo","sop","soq","sor","sos","sou","sov","sow","sox","soy","soz","spb","spc","spd","spe","spg","spi","spk","spl","spm","spn","spo","spp","spq","spr","sps","spt","spu","spv","spx","spy","sqa","sqh","sqj","sqk","sqm","sqn","sqo","sqq","sqr","sqs","sqt","squ","sra","srb","src","sre","srf","srg","srh","sri","srk","srl","srm","srn","sro","srq","srr","srs","srt","sru","srv","srw","srx","sry","srz","ssa","ssb","ssc","ssd","sse","ssf","ssg","ssh","ssi","ssj","ssk","ssl","ssm","ssn","sso","ssp","ssq","ssr","sss","sst","ssu","ssv","ssx","ssy","ssz","sta","stb","std","ste","stf","stg","sth","sti","stj","stk","stl","stm","stn","sto","stp","stq","str","sts","stt","stu","stv","stw","sty","sua","sub","suc","sue","sug","sui","suj","suk","sul","sum","suq","sur","sus","sut","suv","suw","sux","suy","suz","sva","svb","svc","sve","svk","svm","svr","svs","svx","swb","swc","swf","swg","swh","swi","swj","swk","swl","swm","swn","swo","swp","swq","swr","sws","swt","swu","swv","sww","swx","swy","sxb","sxc","sxe","sxg","sxk","sxl","sxm","sxn","sxo","sxr","sxs","sxu","sxw","sya","syb","syc","syd","syi","syk","syl","sym","syn","syo","syr","sys","syw","syx","syy","sza","szb","szc","szd","sze","szg","szl","szn","szp","szs","szv","szw","taa","tab","tac","tad","tae","taf","tag","tai","taj","tak","tal","tan","tao","tap","taq","tar","tas","tau","tav","taw","tax","tay","taz","tba","tbb","tbc","tbd","tbe","tbf","tbg","tbh","tbi","tbj","tbk","tbl","tbm","tbn","tbo","tbp","tbq","tbr","tbs","tbt","tbu","tbv","tbw","tbx","tby","tbz","tca","tcb","tcc","tcd","tce","tcf","tcg","tch","tci","tck","tcl","tcm","tcn","tco","tcp","tcq","tcs","tct","tcu","tcw","tcx","tcy","tcz","tda","tdb","tdc","tdd","tde","tdf","tdg","tdh","tdi","tdj","tdk","tdl","tdm","tdn","tdo","tdq","tdr","tds","tdt","tdu","tdv","tdx","tdy","tea","teb","tec","ted","tee","tef","teg","teh","tei","tek","tem","ten","teo","tep","teq","ter","tes","tet","teu","tev","tew","tex","tey","tfi","tfn","tfo","tfr","tft","tga","tgb","tgc","tgd","tge","tgf","tgg","tgh","tgi","tgj","tgn","tgo","tgp","tgq","tgr","tgs","tgt","tgu","tgv","tgw","tgx","tgy","tgz","thc","thd","the","thf","thh","thi","thk","thl","thm","thn","thp","thq","thr","ths","tht","thu","thv","thw","thx","thy","thz","tia","tic","tid","tie","tif","tig","tih","tii","tij","tik","til","tim","tin","tio","tip","tiq","tis","tit","tiu","tiv","tiw","tix","tiy","tiz","tja","tjg","tji","tjl","tjm","tjn","tjo","tjs","tju","tjw","tka","tkb","tkd","tke","tkf","tkg","tkk","tkl","tkm","tkn","tkp","tkq","tkr","tks","tkt","tku","tkv","tkw","tkx","tkz","tla","tlb","tlc","tld","tlf","tlg","tlh","tli","tlj","tlk","tll","tlm","tln","tlo","tlp","tlq","tlr","tls","tlt","tlu","tlv","tlw","tlx","tly","tma","tmb","tmc","tmd","tme","tmf","tmg","tmh","tmi","tmj","tmk","tml","tmm","tmn","tmo","tmp","tmq","tmr","tms","tmt","tmu","tmv","tmw","tmy","tmz","tna","tnb","tnc","tnd","tne","tnf","tng","tnh","tni","tnk","tnl","tnm","tnn","tno","tnp","tnq","tnr","tns","tnt","tnu","tnv","tnw","tnx","tny","tnz","tob","toc","tod","toe","tof","tog","toh","toi","toj","tol","tom","too","top","toq","tor","tos","tou","tov","tow","tox","toy","toz","tpa","tpc","tpe","tpf","tpg","tpi","tpj","tpk","tpl","tpm","tpn","tpo","tpp","tpq","tpr","tpt","tpu","tpv","tpw","tpx","tpy","tpz","tqb","tql","tqm","tqn","tqo","tqp","tqq","tqr","tqt","tqu","tqw","tra","trb","trc","trd","tre","trf","trg","trh","tri","trj","trk","trl","trm","trn","tro","trp","trq","trr","trs","trt","tru","trv","trw","trx","try","trz","tsa","tsb","tsc","tsd","tse","tsf","tsg","tsh","tsi","tsj","tsk","tsl","tsm","tsp","tsq","tsr","tss","tst","tsu","tsv","tsw","tsx","tsy","tsz","tta","ttb","ttc","ttd","tte","ttf","ttg","tth","tti","ttj","ttk","ttl","ttm","ttn","tto","ttp","ttq","ttr","tts","ttt","ttu","ttv","ttw","tty","ttz","tua","tub","tuc","tud","tue","tuf","tug","tuh","tui","tuj","tul","tum","tun","tuo","tup","tuq","tus","tut","tuu","tuv","tuw","tux","tuy","tuz","tva","tvd","tve","tvk","tvl","tvm","tvn","tvo","tvs","tvt","tvu","tvw","tvy","twa","twb","twc","twd","twe","twf","twg","twh","twl","twm","twn","two","twp","twq","twr","twt","twu","tww","twx","twy","txa","txb","txc","txe","txg","txh","txi","txj","txm","txn","txo","txq","txr","txs","txt","txu","txx","txy","tya","tye","tyh","tyi","tyj","tyl","tyn","typ","tyr","tys","tyt","tyu","tyv","tyx","tyz","tza","tzh","tzj","tzl","tzm","tzn","tzo","tzx","uam","uan","uar","uba","ubi","ubl","ubr","ubu","uby","uda","ude","udg","udi","udj","udl","udm","udu","ues","ufi","uga","ugb","uge","ugn","ugo","ugy","uha","uhn","uis","uiv","uji","uka","ukg","ukh","ukk","ukl","ukp","ukq","uks","uku","ukw","uky","ula","ulb","ulc","ule","ulf","uli","ulk","ull","ulm","uln","ulu","ulw","uma","umb","umc","umd","umg","umi","umm","umn","umo","ump","umr","ums","umu","una","und","une","ung","unk","unm","unn","unp","unr","unu","unx","unz","uok","upi","upv","ura","urb","urc","ure","urf","urg","urh","uri","urj","urk","url","urm","urn","uro","urp","urr","urt","uru","urv","urw","urx","ury","urz","usa","ush","usi","usk","usp","usu","uta","ute","utp","utr","utu","uum","uun","uur","uuu","uve","uvh","uvl","uwa","uya","uzn","uzs","vaa","vae","vaf","vag","vah","vai","vaj","val","vam","van","vao","vap","var","vas","vau","vav","vay","vbb","vbk","vec","ved","vel","vem","veo","vep","ver","vgr","vgt","vic","vid","vif","vig","vil","vin","vis","vit","viv","vka","vki","vkj","vkk","vkl","vkm","vko","vkp","vkt","vku","vlp","vls","vma","vmb","vmc","vmd","vme","vmf","vmg","vmh","vmi","vmj","vmk","vml","vmm","vmp","vmq","vmr","vms","vmu","vmv","vmw","vmx","vmy","vmz","vnk","vnm","vnp","vor","vot","vra","vro","vrs","vrt","vsi","vsl","vsv","vto","vum","vun","vut","vwa","waa","wab","wac","wad","wae","waf","wag","wah","wai","waj","wak","wal","wam","wan","wao","wap","waq","war","was","wat","wau","wav","waw","wax","way","waz","wba","wbb","wbe","wbf","wbh","wbi","wbj","wbk","wbl","wbm","wbp","wbq","wbr","wbs","wbt","wbv","wbw","wca","wci","wdd","wdg","wdj","wdk","wdu","wdy","wea","wec","wed","weg","weh","wei","wem","wen","weo","wep","wer","wes","wet","weu","wew","wfg","wga","wgb","wgg","wgi","wgo","wgu","wgw","wgy","wha","whg","whk","whu","wib","wic","wie","wif","wig","wih","wii","wij","wik","wil","wim","win","wir","wit","wiu","wiv","wiw","wiy","wja","wji","wka","wkb","wkd","wkl","wku","wkw","wky","wla","wlc","wle","wlg","wli","wlk","wll","wlm","wlo","wlr","wls","wlu","wlv","wlw","wlx","wly","wma","wmb","wmc","wmd","wme","wmh","wmi","wmm","wmn","wmo","wms","wmt","wmw","wmx","wnb","wnc","wnd","wne","wng","wni","wnk","wnm","wnn","wno","wnp","wnu","wnw","wny","woa","wob","woc","wod","woe","wof","wog","woi","wok","wom","won","woo","wor","wos","wow","woy","wpc","wra","wrb","wrd","wrg","wrh","wri","wrk","wrl","wrm","wrn","wro","wrp","wrr","wrs","wru","wrv","wrw","wrx","wry","wrz","wsa","wsg","wsi","wsk","wsr","wss","wsu","wsv","wtf","wth","wti","wtk","wtm","wtw","wua","wub","wud","wuh","wul","wum","wun","wur","wut","wuu","wuv","wux","wuy","wwa","wwb","wwo","wwr","www","wxa","wxw","wya","wyb","wyi","wym","wyr","wyy","xaa","xab","xac","xad","xae","xag","xai","xaj","xak","xal","xam","xan","xao","xap","xaq","xar","xas","xat","xau","xav","xaw","xay","xba","xbb","xbc","xbd","xbe","xbg","xbi","xbj","xbm","xbn","xbo","xbp","xbr","xbw","xbx","xby","xcb","xcc","xce","xcg","xch","xcl","xcm","xcn","xco","xcr","xct","xcu","xcv","xcw","xcy","xda","xdc","xdk","xdm","xdo","xdy","xeb","xed","xeg","xel","xem","xep","xer","xes","xet","xeu","xfa","xga","xgb","xgd","xgf","xgg","xgi","xgl","xgm","xgn","xgr","xgu","xgw","xha","xhc","xhd","xhe","xhr","xht","xhu","xhv","xia","xib","xii","xil","xin","xip","xir","xis","xiv","xiy","xjb","xjt","xka","xkb","xkc","xkd","xke","xkf","xkg","xkh","xki","xkj","xkk","xkl","xkn","xko","xkp","xkq","xkr","xks","xkt","xku","xkv","xkw","xkx","xky","xkz","xla","xlb","xlc","xld","xle","xlg","xli","xln","xlo","xlp","xls","xlu","xly","xma","xmb","xmc","xmd","xme","xmf","xmg","xmh","xmj","xmk","xml","xmm","xmn","xmo","xmp","xmq","xmr","xms","xmt","xmu","xmv","xmw","xmx","xmy","xmz","xna","xnb","xnd","xng","xnh","xni","xnk","xnn","xno","xnr","xns","xnt","xnu","xny","xnz","xoc","xod","xog","xoi","xok","xom","xon","xoo","xop","xor","xow","xpa","xpc","xpe","xpg","xpi","xpj","xpk","xpm","xpn","xpo","xpp","xpq","xpr","xps","xpt","xpu","xpy","xqa","xqt","xra","xrb","xrd","xre","xrg","xri","xrm","xrn","xrq","xrr","xrt","xru","xrw","xsa","xsb","xsc","xsd","xse","xsh","xsi","xsj","xsl","xsm","xsn","xso","xsp","xsq","xsr","xss","xsu","xsv","xsy","xta","xtb","xtc","xtd","xte","xtg","xth","xti","xtj","xtl","xtm","xtn","xto","xtp","xtq","xtr","xts","xtt","xtu","xtv","xtw","xty","xtz","xua","xub","xud","xug","xuj","xul","xum","xun","xuo","xup","xur","xut","xuu","xve","xvi","xvn","xvo","xvs","xwa","xwc","xwd","xwe","xwg","xwj","xwk","xwl","xwo","xwr","xwt","xww","xxb","xxk","xxm","xxr","xxt","xya","xyb","xyj","xyk","xyl","xyt","xyy","xzh","xzm","xzp","yaa","yab","yac","yad","yae","yaf","yag","yah","yai","yaj","yak","yal","yam","yan","yao","yap","yaq","yar","yas","yat","yau","yav","yaw","yax","yay","yaz","yba","ybb","ybd","ybe","ybh","ybi","ybj","ybk","ybl","ybm","ybn","ybo","ybx","yby","ych","ycl","ycn","ycp","yda","ydd","yde","ydg","ydk","yds","yea","yec","yee","yei","yej","yel","yen","yer","yes","yet","yeu","yev","yey","yga","ygi","ygl","ygm","ygp","ygr","ygs","ygu","ygw","yha","yhd","yhl","yhs","yia","yif","yig","yih","yii","yij","yik","yil","yim","yin","yip","yiq","yir","yis","yit","yiu","yiv","yix","yiy","yiz","yka","ykg","yki","ykk","ykl","ykm","ykn","yko","ykr","ykt","yku","yky","yla","ylb","yle","ylg","yli","yll","ylm","yln","ylo","ylr","ylu","yly","yma","ymb","ymc","ymd","yme","ymg","ymh","ymi","ymk","yml","ymm","ymn","ymo","ymp","ymq","ymr","yms","ymt","ymx","ymz","yna","ynd","yne","yng","ynh","ynk","ynl","ynn","yno","ynq","yns","ynu","yob","yog","yoi","yok","yol","yom","yon","yos","yot","yox","yoy","ypa","ypb","ypg","yph","ypk","ypm","ypn","ypo","ypp","ypz","yra","yrb","yre","yri","yrk","yrl","yrm","yrn","yro","yrs","yrw","yry","ysc","ysd","ysg","ysl","ysn","yso","ysp","ysr","yss","ysy","yta","ytl","ytp","ytw","yty","yua","yub","yuc","yud","yue","yuf","yug","yui","yuj","yuk","yul","yum","yun","yup","yuq","yur","yut","yuu","yuw","yux","yuy","yuz","yva","yvt","ywa","ywg","ywl","ywn","ywq","ywr","ywt","ywu","yww","yxa","yxg","yxl","yxm","yxu","yxy","yyr","yyu","yyz","yzg","yzk","zaa","zab","zac","zad","zae","zaf","zag","zah","zai","zaj","zak","zal","zam","zao","zap","zaq","zar","zas","zat","zau","zav","zaw","zax","zay","zaz","zbc","zbe","zbl","zbt","zbw","zca","zch","zdj","zea","zeg","zeh","zen","zga","zgb","zgh","zgm","zgn","zgr","zhb","zhd","zhi","zhn","zhw","zhx","zia","zib","zik","zil","zim","zin","zir","ziw","ziz","zka","zkb","zkd","zkg","zkh","zkk","zkn","zko","zkp","zkr","zkt","zku","zkv","zkz","zle","zlj","zlm","zln","zlq","zls","zlw","zma","zmb","zmc","zmd","zme","zmf","zmg","zmh","zmi","zmj","zmk","zml","zmm","zmn","zmo","zmp","zmq","zmr","zms","zmt","zmu","zmv","zmw","zmx","zmy","zmz","zna","znd","zne","zng","znk","zns","zoc","zoh","zom","zoo","zoq","zor","zos","zpa","zpb","zpc","zpd","zpe","zpf","zpg","zph","zpi","zpj","zpk","zpl","zpm","zpn","zpo","zpp","zpq","zpr","zps","zpt","zpu","zpv","zpw","zpx","zpy","zpz","zqe","zra","zrg","zrn","zro","zrp","zrs","zsa","zsk","zsl","zsm","zsr","zsu","zte","ztg","ztl","ztm","ztn","ztp","ztq","zts","ztt","ztu","ztx","zty","zua","zuh","zum","zun","zuy","zwa","zxx","zyb","zyg","zyj","zyn","zyp","zza","zzj"] +;return axe.utils.validLangs=function(){"use strict";return L},commons}()})}("object"==typeof window?window:this); \ No newline at end of file
diff --git a/third_party/blink/public/web/web_plugin.h b/third_party/blink/public/web/web_plugin.h index 1088264..3f4d2d6 100644 --- a/third_party/blink/public/web/web_plugin.h +++ b/third_party/blink/public/web/web_plugin.h
@@ -143,6 +143,8 @@ virtual bool GetPrintPresetOptionsFromDocument(WebPrintPresetOptions*) { return false; } + // Returns true if the plugin is a PDF plugin. + virtual bool IsPdfPlugin() { return false; } // Sets up printing with the specified printParams. Returns the number of // pages to be printed at these settings.
diff --git a/third_party/blink/renderer/core/core_idl_files.gni b/third_party/blink/renderer/core/core_idl_files.gni index ad9a447..fc23d685 100644 --- a/third_party/blink/renderer/core/core_idl_files.gni +++ b/third_party/blink/renderer/core/core_idl_files.gni
@@ -165,7 +165,6 @@ "events/page_transition_event.idl", "events/pointer_event.idl", "events/pop_state_event.idl", - "events/portal_activate_event.idl", "events/progress_event.idl", "events/promise_rejection_event.idl", "events/resource_progress_event.idl", @@ -292,6 +291,7 @@ "html/media/html_audio_element.idl", "html/media/media_error.idl", "html/portal/html_portal_element.idl", + "html/portal/portal_activate_event.idl", "html/portal/portal_host.idl", "html/track/audio_track_list.idl", "html/track/html_track_element.idl", @@ -643,7 +643,6 @@ "events/page_transition_event_init.idl", "events/pointer_event_init.idl", "events/pop_state_event_init.idl", - "events/portal_activate_event_init.idl", "events/progress_event_init.idl", "events/promise_rejection_event_init.idl", "events/security_policy_violation_event_init.idl", @@ -674,6 +673,7 @@ "html/canvas/image_encode_options.idl", "html/custom/validity_state_flags.idl", "html/forms/form_data_event_init.idl", + "html/portal/portal_activate_event_init.idl", "html/portal/portal_activate_options.idl", "html/track/track_event_init.idl", "imagebitmap/image_bitmap_options.idl",
diff --git a/third_party/blink/renderer/core/css/css_style_sheet.h b/third_party/blink/renderer/core/css/css_style_sheet.h index f773cdf..e6dbe47 100644 --- a/third_party/blink/renderer/core/css/css_style_sheet.h +++ b/third_party/blink/renderer/core/css/css_style_sheet.h
@@ -215,6 +215,9 @@ void SetLoadCompleted(bool); + FRIEND_TEST_ALL_PREFIXES( + CSSStyleSheetTest, + GarbageCollectedShadowRootsRemovedFromAdoptedTreeScopes); FRIEND_TEST_ALL_PREFIXES(CSSStyleSheetTest, CSSStyleSheetConstructionWithEmptyCSSStyleSheetInit); FRIEND_TEST_ALL_PREFIXES( @@ -252,7 +255,7 @@ Member<Node> owner_node_; Member<CSSRule> owner_rule_; - HeapHashSet<Member<TreeScope>> adopted_tree_scopes_; + HeapHashSet<WeakMember<TreeScope>> adopted_tree_scopes_; Member<Document> associated_document_; HashSet<AtomicString> custom_element_tag_names_; Member<ScriptPromiseResolver> resolver_;
diff --git a/third_party/blink/renderer/core/css/css_style_sheet_test.cc b/third_party/blink/renderer/core/css/css_style_sheet_test.cc index 8f786dd..d008ae9 100644 --- a/third_party/blink/renderer/core/css/css_style_sheet_test.cc +++ b/third_party/blink/renderer/core/css/css_style_sheet_test.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/renderer/core/css/css_style_sheet.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/web/web_heap.h" #include "third_party/blink/renderer/bindings/core/v8/media_list_or_string.h" #include "third_party/blink/renderer/bindings/core/v8/script_function.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" @@ -13,6 +14,7 @@ #include "third_party/blink/renderer/core/css/css_rule_list.h" #include "third_party/blink/renderer/core/css/css_style_sheet_init.h" #include "third_party/blink/renderer/core/css/media_list.h" +#include "third_party/blink/renderer/core/dom/shadow_root.h" #include "third_party/blink/renderer/core/testing/page_test_base.h" namespace blink { @@ -70,4 +72,31 @@ ASSERT_FALSE(exception_state.HadException()); } +TEST_F(CSSStyleSheetTest, + GarbageCollectedShadowRootsRemovedFromAdoptedTreeScopes) { + SetBodyInnerHTML("<div id='host_a'></div><div id='host_b'></div>"); + auto* host_a = GetElementById("host_a"); + auto& shadow_a = host_a->AttachShadowRootInternal(ShadowRootType::kOpen); + auto* host_b = GetElementById("host_b"); + auto& shadow_b = host_b->AttachShadowRootInternal(ShadowRootType::kOpen); + DummyExceptionStateForTesting exception_state; + CSSStyleSheetInit* init = CSSStyleSheetInit::Create(); + CSSStyleSheet* sheet = + CSSStyleSheet::Create(GetDocument(), init, exception_state); + + HeapVector<Member<CSSStyleSheet>> adopted_sheets; + adopted_sheets.push_back(sheet); + shadow_a.SetAdoptedStyleSheets(adopted_sheets); + shadow_b.SetAdoptedStyleSheets(adopted_sheets); + + EXPECT_EQ(sheet->adopted_tree_scopes_.size(), 2u); + EXPECT_EQ(shadow_a.AdoptedStyleSheets().size(), 1u); + EXPECT_EQ(shadow_b.AdoptedStyleSheets().size(), 1u); + + host_a->remove(); + WebHeap::CollectAllGarbageForTesting(); + EXPECT_EQ(sheet->adopted_tree_scopes_.size(), 1u); + EXPECT_EQ(shadow_b.AdoptedStyleSheets().size(), 1u); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/css/fullscreen.css b/third_party/blink/renderer/core/css/fullscreen.css index 8023bdb..a0982cad 100644 --- a/third_party/blink/renderer/core/css/fullscreen.css +++ b/third_party/blink/renderer/core/css/fullscreen.css
@@ -1,4 +1,4 @@ -:not(:root):-webkit-full-screen { +:not(:root):fullscreen { position: fixed !important; top: 0 !important; right: 0 !important; @@ -18,14 +18,14 @@ object-fit: contain; } -iframe:-webkit-full-screen { +iframe:fullscreen { border: none !important; padding: 0 !important; } /* TODO(foolip): In the spec, there's a ::backdrop block with the properties shared with dialog::backdrop (see html.css). */ -:not(:root):-webkit-full-screen::backdrop { +:not(:root):fullscreen::backdrop { position: fixed; top: 0; right: 0; @@ -45,7 +45,7 @@ overflow: hidden !important; } -:-webkit-full-screen:-internal-video-persistent-ancestor :not(:-internal-video-persistent-ancestor) { +:fullscreen:-internal-video-persistent-ancestor :not(:-internal-video-persistent-ancestor) { display: none !important; }
diff --git a/third_party/blink/renderer/core/css/fullscreenAndroid.css b/third_party/blink/renderer/core/css/fullscreenAndroid.css index 2466f35..526736d 100644 --- a/third_party/blink/renderer/core/css/fullscreenAndroid.css +++ b/third_party/blink/renderer/core/css/fullscreenAndroid.css
@@ -1,4 +1,4 @@ -video:-webkit-full-screen { +video:fullscreen { /* Fullscreen video on Android does not synchronize correctly when the <video> * element is not rendered in the root render pass. Disable properties that * cause this. (http://crbug.com/618753) */
diff --git a/third_party/blink/renderer/core/css/resolver/font_builder.cc b/third_party/blink/renderer/core/css/resolver/font_builder.cc index e46dfec3..4e22eb67 100644 --- a/third_party/blink/renderer/core/css/resolver/font_builder.cc +++ b/third_party/blink/renderer/core/css/resolver/font_builder.cc
@@ -238,7 +238,8 @@ float specified_size) { DCHECK(document_); float zoom_factor = effective_zoom; - // FIXME: Why is this here!!!!?! + // Apply the text zoom factor preference. The preference is exposed in + // accessibility settings in Chrome for Android to improve readability. if (LocalFrame* frame = document_->GetFrame()) zoom_factor *= frame->TextZoomFactor();
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_context.h b/third_party/blink/renderer/core/display_lock/display_lock_context.h index 518b1620..1a38b2af 100644 --- a/third_party/blink/renderer/core/display_lock/display_lock_context.h +++ b/third_party/blink/renderer/core/display_lock/display_lock_context.h
@@ -66,6 +66,7 @@ enum StyleType { kStyleUpdateNotRequired, kStyleUpdateSelf, + kStyleUpdatePseudoElements, kStyleUpdateChildren, kStyleUpdateDescendants };
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index 3c936fb..566e8333 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -2737,14 +2737,32 @@ // display locking can happen.. display_lock_style_scope.DidUpdateSelfStyle(); + if (!display_lock_style_scope.ShouldUpdateChildStyle()) { + if (child_change.RecalcChildren()) { + // If we should've calculated the style for children but was blocked, + // notify so that we'd come back. + // Note that the if-clause wouldn't catch cases where + // ChildNeedsStyleRecalc() is true but child_change.RecalcChildren() is + // false. Since we are retaining the child dirty bit, that case is + // automatically handled without needing to notify it here. + display_lock_style_scope.NotifyUpdateWasBlocked( + DisplayLockContext::kStyleUpdateDescendants); + + } else if (child_change.TraversePseudoElements(*this)) { + display_lock_style_scope.NotifyUpdateWasBlocked( + DisplayLockContext::kStyleUpdatePseudoElements); + } + if (HasCustomStyleCallbacks()) + DidRecalcStyle(child_change); + return; + } + if (child_change.TraversePseudoElements(*this)) { UpdatePseudoElement(kPseudoIdBackdrop, child_change); UpdatePseudoElement(kPseudoIdBefore, child_change); } - const bool should_update_child_style = - display_lock_style_scope.ShouldUpdateChildStyle(); - if (child_change.TraverseChildren(*this) && should_update_child_style) { + if (child_change.TraverseChildren(*this)) { SelectorFilterParentScope filter_scope(*this); if (ShadowRoot* root = GetShadowRoot()) { if (child_change.TraverseChild(*root)) @@ -2765,20 +2783,9 @@ UpdateFirstLetterPseudoElement(StyleUpdatePhase::kRecalc); } - if (should_update_child_style) { ClearChildNeedsStyleRecalc(); // We've updated all the children that needs an update (might be 0). display_lock_style_scope.DidUpdateChildStyle(); - } else if (child_change.RecalcChildren()) { - // If we should've calculated the style for children but was blocked, - // notify so that we'd come back. - // Note that the if-clause wouldn't catch cases where - // ChildNeedsStyleRecalc() is true but child_change.RecalcChildren() is - // false. Since we are retaining the child dirty bit, that case is - // automatically handled without needing to notify it here. - display_lock_style_scope.NotifyUpdateWasBlocked( - DisplayLockContext::kStyleUpdateDescendants); - } if (HasCustomStyleCallbacks()) DidRecalcStyle(child_change);
diff --git a/third_party/blink/renderer/core/events/BUILD.gn b/third_party/blink/renderer/core/events/BUILD.gn index c831eb37..65e808ff 100644 --- a/third_party/blink/renderer/core/events/BUILD.gn +++ b/third_party/blink/renderer/core/events/BUILD.gn
@@ -58,8 +58,6 @@ "pointer_event_factory.h", "pop_state_event.cc", "pop_state_event.h", - "portal_activate_event.cc", - "portal_activate_event.h", "progress_event.cc", "progress_event.h", "promise_rejection_event.cc",
diff --git a/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc b/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc index 66680b7..31222c6 100644 --- a/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc +++ b/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc
@@ -391,7 +391,7 @@ // PrefixedForCrossProcessDescendant is necessary because: // - The fullscreen element ready check and other checks should be bypassed. // - |ownerElement| will need :-webkit-full-screen-ancestor style in addition - // to :-webkit-full-screen. + // to :fullscreen. // // TODO(alexmos): currently, this assumes prefixed requests, but in the // future, this should plumb in information about which request type
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc index 6a5a39d4..0fccae4 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -171,7 +171,6 @@ #include "third_party/blink/renderer/core/editing/writing_direction.h" #include "third_party/blink/renderer/core/events/after_print_event.h" #include "third_party/blink/renderer/core/events/before_print_event.h" -#include "third_party/blink/renderer/core/events/portal_activate_event.h" #include "third_party/blink/renderer/core/exported/local_frame_client_impl.h" #include "third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.h" #include "third_party/blink/renderer/core/exported/web_document_loader_impl.h" @@ -212,6 +211,7 @@ #include "third_party/blink/renderer/core/html/portal/document_portals.h" #include "third_party/blink/renderer/core/html/portal/dom_window_portal_host.h" #include "third_party/blink/renderer/core/html/portal/html_portal_element.h" +#include "third_party/blink/renderer/core/html/portal/portal_activate_event.h" #include "third_party/blink/renderer/core/html/portal/portal_host.h" #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/input/context_menu_allowed_scope.h"
diff --git a/third_party/blink/renderer/core/html/BUILD.gn b/third_party/blink/renderer/core/html/BUILD.gn index f4b3c6a..da50720 100644 --- a/third_party/blink/renderer/core/html/BUILD.gn +++ b/third_party/blink/renderer/core/html/BUILD.gn
@@ -505,6 +505,8 @@ "portal/dom_window_portal_host.h", "portal/html_portal_element.cc", "portal/html_portal_element.h", + "portal/portal_activate_event.cc", + "portal/portal_activate_event.h", "portal/portal_contents.cc", "portal/portal_contents.h", "portal/portal_host.cc",
diff --git a/third_party/blink/renderer/core/html/media/html_video_element_persistent_test.cc b/third_party/blink/renderer/core/html/media/html_video_element_persistent_test.cc index a62627c5..83f44168c 100644 --- a/third_party/blink/renderer/core/html/media/html_video_element_persistent_test.cc +++ b/third_party/blink/renderer/core/html/media/html_video_element_persistent_test.cc
@@ -194,7 +194,7 @@ DummyExceptionStateForTesting exception_state; - EXPECT_FALSE(DivElement()->matches(":-webkit-full-screen")); + EXPECT_FALSE(DivElement()->matches(":fullscreen")); EXPECT_FALSE(DivElement()->matches(":-internal-video-persistent-ancestor", exception_state)); EXPECT_TRUE(exception_state.HadException()); @@ -220,7 +220,7 @@ EXPECT_TRUE(VideoElement()->ContainsPersistentVideo()); // The :internal-* rules apply only from the UA stylesheet. - EXPECT_TRUE(DivElement()->matches(":-webkit-full-screen")); + EXPECT_TRUE(DivElement()->matches(":fullscreen")); EXPECT_FALSE(DivElement()->matches(":-internal-video-persistent-ancestor", exception_state)); EXPECT_TRUE(exception_state.HadException());
diff --git a/third_party/blink/renderer/core/events/portal_activate_event.cc b/third_party/blink/renderer/core/html/portal/portal_activate_event.cc similarity index 96% rename from third_party/blink/renderer/core/events/portal_activate_event.cc rename to third_party/blink/renderer/core/html/portal/portal_activate_event.cc index 1b34ff4c..1b442bd 100644 --- a/third_party/blink/renderer/core/events/portal_activate_event.cc +++ b/third_party/blink/renderer/core/html/portal/portal_activate_event.cc
@@ -2,15 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "third_party/blink/renderer/core/events/portal_activate_event.h" +#include "third_party/blink/renderer/core/html/portal/portal_activate_event.h" #include <utility> #include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/event_type_names.h" -#include "third_party/blink/renderer/core/events/portal_activate_event_init.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/html/portal/html_portal_element.h" +#include "third_party/blink/renderer/core/html/portal/portal_activate_event_init.h" #include "third_party/blink/renderer/core/messaging/message_port.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
diff --git a/third_party/blink/renderer/core/events/portal_activate_event.h b/third_party/blink/renderer/core/html/portal/portal_activate_event.h similarity index 94% rename from third_party/blink/renderer/core/events/portal_activate_event.h rename to third_party/blink/renderer/core/html/portal/portal_activate_event.h index 51cff48..2b3feb0 100644 --- a/third_party/blink/renderer/core/events/portal_activate_event.h +++ b/third_party/blink/renderer/core/html/portal/portal_activate_event.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_PORTAL_ACTIVATE_EVENT_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_PORTAL_ACTIVATE_EVENT_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_PORTAL_PORTAL_ACTIVATE_EVENT_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_PORTAL_PORTAL_ACTIVATE_EVENT_H_ #include "base/unguessable_token.h" #include "mojo/public/cpp/bindings/associated_remote.h" @@ -101,4 +101,4 @@ } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_PORTAL_ACTIVATE_EVENT_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_PORTAL_PORTAL_ACTIVATE_EVENT_H_
diff --git a/third_party/blink/renderer/core/events/portal_activate_event.idl b/third_party/blink/renderer/core/html/portal/portal_activate_event.idl similarity index 100% rename from third_party/blink/renderer/core/events/portal_activate_event.idl rename to third_party/blink/renderer/core/html/portal/portal_activate_event.idl
diff --git a/third_party/blink/renderer/core/events/portal_activate_event_init.idl b/third_party/blink/renderer/core/html/portal/portal_activate_event_init.idl similarity index 100% rename from third_party/blink/renderer/core/events/portal_activate_event_init.idl rename to third_party/blink/renderer/core/html/portal/portal_activate_event_init.idl
diff --git a/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc b/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc index fc21269..13bad13 100644 --- a/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc +++ b/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc
@@ -911,9 +911,9 @@ void ImageBitmap::ResolvePromiseOnOriginalThread( ScriptPromiseResolver* resolver, - sk_sp<SkImage> skia_image, bool origin_clean, - std::unique_ptr<ParsedOptions> parsed_options) { + std::unique_ptr<ParsedOptions> parsed_options, + sk_sp<SkImage> skia_image) { if (!skia_image) { resolver->Reject( ScriptValue(resolver->GetScriptState(), @@ -945,11 +945,10 @@ } void ImageBitmap::RasterizeImageOnBackgroundThread( - ScriptPromiseResolver* resolver, sk_sp<PaintRecord> paint_record, const IntRect& dst_rect, - bool origin_clean, - std::unique_ptr<ParsedOptions> parsed_options) { + scoped_refptr<base::SequencedTaskRunner> task_runner, + WTF::CrossThreadOnceFunction<void(sk_sp<SkImage>)> callback) { DCHECK(!IsMainThread()); SkImageInfo info = SkImageInfo::MakeN32Premul(dst_rect.Width(), dst_rect.Height()); @@ -959,14 +958,9 @@ paint_record->Playback(surface->getCanvas()); skia_image = surface->makeImageSnapshot(); } - scoped_refptr<base::SingleThreadTaskRunner> task_runner = - Thread::MainThread()->GetTaskRunner(); PostCrossThreadTask( *task_runner, FROM_HERE, - CrossThreadBindOnce(&ResolvePromiseOnOriginalThread, - WrapCrossThreadPersistent(resolver), - std::move(skia_image), origin_clean, - WTF::Passed(std::move(parsed_options)))); + CrossThreadBindOnce(std::move(callback), std::move(skia_image))); } ScriptPromise ImageBitmap::CreateAsync(ImageElementBase* image, @@ -1017,11 +1011,13 @@ std::make_unique<ParsedOptions>(parsed_options); worker_pool::PostTask( FROM_HERE, - CrossThreadBindOnce(&RasterizeImageOnBackgroundThread, - WrapCrossThreadPersistent(resolver), - std::move(paint_record), draw_dst_rect, - !image->WouldTaintOrigin(), - WTF::Passed(std::move(passed_parsed_options)))); + CrossThreadBindOnce( + &RasterizeImageOnBackgroundThread, std::move(paint_record), + draw_dst_rect, Thread::MainThread()->GetTaskRunner(), + CrossThreadBindOnce(&ResolvePromiseOnOriginalThread, + WrapCrossThreadPersistent(resolver), + !image->WouldTaintOrigin(), + WTF::Passed(std::move(passed_parsed_options))))); return promise; }
diff --git a/third_party/blink/renderer/core/imagebitmap/image_bitmap.h b/third_party/blink/renderer/core/imagebitmap/image_bitmap.h index bea78c0d..62ffad0 100644 --- a/third_party/blink/renderer/core/imagebitmap/image_bitmap.h +++ b/third_party/blink/renderer/core/imagebitmap/image_bitmap.h
@@ -7,6 +7,7 @@ #include <memory> #include "base/memory/scoped_refptr.h" +#include "base/sequenced_task_runner.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/html/canvas/canvas_image_source.h" #include "third_party/blink/renderer/core/html/canvas/image_element_base.h" @@ -17,6 +18,7 @@ #include "third_party/blink/renderer/platform/graphics/image.h" #include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h" #include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/skia/include/core/SkRefCnt.h" namespace blink { @@ -172,14 +174,14 @@ private: void UpdateImageBitmapMemoryUsage(); static void ResolvePromiseOnOriginalThread(ScriptPromiseResolver*, - sk_sp<SkImage>, bool origin_clean, - std::unique_ptr<ParsedOptions>); - static void RasterizeImageOnBackgroundThread(ScriptPromiseResolver*, - sk_sp<PaintRecord>, - const IntRect&, - bool origin_clean, - std::unique_ptr<ParsedOptions>); + std::unique_ptr<ParsedOptions>, + sk_sp<SkImage>); + static void RasterizeImageOnBackgroundThread( + sk_sp<PaintRecord>, + const IntRect&, + scoped_refptr<base::SequencedTaskRunner>, + WTF::CrossThreadOnceFunction<void(sk_sp<SkImage>)> callback); scoped_refptr<StaticBitmapImage> image_; bool is_neutered_ = false; int32_t memory_usage_ = 0;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc index 41819c4..678ecb82 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
@@ -523,7 +523,6 @@ if (NGLayoutInputNode next = child.NextSibling()) { container_builder_.AddBreakBeforeChild(next, /* is_forced_break */ true); - container_builder_.SetDidBreak(); } break; } else { @@ -1645,7 +1644,6 @@ if (NGLayoutInputNode next = child.NextSibling()) { container_builder_.AddBreakBeforeChild(next, /* is_forced_break */ true); - container_builder_.SetDidBreak(); } } } @@ -2057,7 +2055,6 @@ // Drop the fragment on the floor and retry at the start of the next // fragmentainer. container_builder_.AddBreakBeforeChild(child, break_type == ForcedBreak); - container_builder_.SetDidBreak(); if (break_type == ForcedBreak) { container_builder_.SetHasForcedBreak(); } else {
diff --git a/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc b/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc index b82787b6..c3fe64c 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc
@@ -82,6 +82,7 @@ void NGBoxFragmentBuilder::AddBreakBeforeChild(NGLayoutInputNode child, bool is_forced_break) { DCHECK(has_block_fragmentation_); + SetDidBreak(); if (auto* child_inline_node = DynamicTo<NGInlineNode>(child)) { if (inline_break_tokens_.IsEmpty()) { // In some cases we may want to break before the first line, as a last @@ -103,6 +104,7 @@ DCHECK(has_block_fragmentation_); DCHECK_GT(line_number, 0); DCHECK_LE(unsigned(line_number), inline_break_tokens_.size()); + SetDidBreak(); int lines_to_remove = inline_break_tokens_.size() - line_number; if (lines_to_remove > 0) { // Remove widows that should be pushed to the next fragment. We'll also
diff --git a/third_party/blink/renderer/core/svg/animation/smil_animation_sandwich.cc b/third_party/blink/renderer/core/svg/animation/smil_animation_sandwich.cc index 250faaf2..506fb69e8 100644 --- a/third_party/blink/renderer/core/svg/animation/smil_animation_sandwich.cc +++ b/third_party/blink/renderer/core/svg/animation/smil_animation_sandwich.cc
@@ -85,6 +85,8 @@ for (const auto& animation : sandwich_) { earliest_progress_time = std::min( earliest_progress_time, animation->NextProgressTime(presentation_time)); + if (earliest_progress_time <= presentation_time) + break; } return earliest_progress_time; }
diff --git a/third_party/blink/renderer/core/svg/animation/smil_time_container.cc b/third_party/blink/renderer/core/svg/animation/smil_time_container.cc index 1cc397e..059052a89 100644 --- a/third_party/blink/renderer/core/svg/animation/smil_time_container.cc +++ b/third_party/blink/renderer/core/svg/animation/smil_time_container.cc
@@ -424,9 +424,11 @@ ApplyAnimationValues(elapsed); SMILTime next_progress_time = SMILTime::Unresolved(); - for (auto& sandwich : scheduled_animations_) { + for (auto& sandwich : scheduled_animations_.Values()) { next_progress_time = - std::min(next_progress_time, sandwich.value->NextProgressTime(elapsed)); + std::min(next_progress_time, sandwich->NextProgressTime(elapsed)); + if (next_progress_time <= elapsed) + break; } if (!CanScheduleFrame(next_progress_time)) @@ -461,23 +463,15 @@ } void SMILTimeContainer::UpdateIntervals(SMILTime document_time) { - // This Shrink should free up the memory from the previous - // run in this loop. Otherwise it won't do anything. DCHECK(document_time.IsFinite()); DCHECK(document_time >= 0.0); do { intervals_dirty_ = false; - active_sandwiches_.Shrink(0); - for (auto& entry : scheduled_animations_) { - auto* sandwich = entry.value.Get(); + + for (auto& sandwich : scheduled_animations_.Values()) sandwich->UpdateTiming(document_time.Value()); - if (!sandwich->IsEmpty()) { - active_sandwiches_.push_back(sandwich); - } - } - - for (auto& sandwich : active_sandwiches_) + for (auto& sandwich : scheduled_animations_.Values()) sandwich->UpdateSyncBases(document_time.Value()); } while (intervals_dirty_); } @@ -502,7 +496,6 @@ if (intervals_dirty_) UpdateIntervals(latest_update_time_); - active_sandwiches_.ReserveCapacity(scheduled_animations_.size()); while (latest_update_time_ < presentation_time) { const SMILTime interesting_time = NextInterestingTime(latest_update_time_); latest_update_time_ = @@ -517,12 +510,11 @@ prevent_scheduled_animations_changes_ = true; #endif HeapVector<Member<SVGSMILElement>> animations_to_apply; - for (auto& sandwich : active_sandwiches_) { + for (auto& sandwich : scheduled_animations_.Values()) { sandwich->UpdateActiveAnimationStack(elapsed); if (SVGSMILElement* animation = sandwich->ApplyAnimationValues()) animations_to_apply.push_back(animation); } - active_sandwiches_.Shrink(0); if (animations_to_apply.IsEmpty()) { #if DCHECK_IS_ON() @@ -568,7 +560,6 @@ void SMILTimeContainer::Trace(blink::Visitor* visitor) { visitor->Trace(scheduled_animations_); visitor->Trace(owner_svg_element_); - visitor->Trace(active_sandwiches_); } } // namespace blink
diff --git a/third_party/blink/renderer/core/svg/animation/smil_time_container.h b/third_party/blink/renderer/core/svg/animation/smil_time_container.h index eb7e28d..14b97fd 100644 --- a/third_party/blink/renderer/core/svg/animation/smil_time_container.h +++ b/third_party/blink/renderer/core/svg/animation/smil_time_container.h
@@ -147,7 +147,6 @@ TaskRunnerTimer<SMILTimeContainer> animation_policy_once_timer_; AnimationsMap scheduled_animations_; - HeapVector<Member<SMILAnimationSandwich>> active_sandwiches_; Member<SVGSVGElement> owner_svg_element_;
diff --git a/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc b/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc index 021e0c3..fde9c0a 100644 --- a/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc +++ b/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc
@@ -1057,7 +1057,7 @@ return repeating_duration_end; return interval_.end; } - return presentation_time + 0.025; + return presentation_time; } return interval_.begin >= presentation_time ? interval_.begin : SMILTime::Unresolved(); @@ -1109,17 +1109,6 @@ return true; } -void SVGSMILElement::TriggerPendingEvents(double elapsed) { - if (GetActiveState() == kInactive) - ScheduleEvent(event_type_names::kBeginEvent); - - if (CalculateAnimationRepeat(elapsed)) - ScheduleEvent(event_type_names::kRepeatEvent); - - if (GetActiveState() == kInactive || GetActiveState() == kFrozen) - ScheduleEvent(event_type_names::kEndEvent); -} - void SVGSMILElement::UpdateSyncBases() { if (!interval_has_changed_) return;
diff --git a/third_party/blink/renderer/core/svg/animation/svg_smil_element.h b/third_party/blink/renderer/core/svg/animation/svg_smil_element.h index 001c9fd..6ad9f03 100644 --- a/third_party/blink/renderer/core/svg/animation/svg_smil_element.h +++ b/third_party/blink/renderer/core/svg/animation/svg_smil_element.h
@@ -89,7 +89,6 @@ // next interval. Returns true if the interval was restarted. bool CheckAndUpdateInterval(double elapsed); void UpdateActiveState(double elapsed, bool interval_restart); - void TriggerPendingEvents(double elapsed); void UpdateSyncBases(); SMILTime NextInterestingTime(double elapsed) const; @@ -291,8 +290,6 @@ Member<SMILTimeContainer> time_container_; unsigned document_order_index_; - Vector<unsigned> repeat_event_count_list_; - mutable SMILTime cached_dur_; mutable SMILTime cached_repeat_dur_; mutable SMILTime cached_repeat_count_;
diff --git a/third_party/blink/renderer/core/testing/data/fullscreen_style.html b/third_party/blink/renderer/core/testing/data/fullscreen_style.html index a1c95d0c..126feb5 100644 --- a/third_party/blink/renderer/core/testing/data/fullscreen_style.html +++ b/third_party/blink/renderer/core/testing/data/fullscreen_style.html
@@ -10,7 +10,7 @@ margin: 0px; } - body:-webkit-full-screen-ancestor > :not(:-webkit-full-screen-ancestor):not(:-webkit-full-screen) { + body:-webkit-full-screen-ancestor > :not(:-webkit-full-screen-ancestor):not(:fullscreen) { display: none!important }
diff --git a/third_party/blink/renderer/core/trustedtypes/trusted_types_util.cc b/third_party/blink/renderer/core/trustedtypes/trusted_types_util.cc index 78113b8..8791c6b4 100644 --- a/third_party/blink/renderer/core/trustedtypes/trusted_types_util.cc +++ b/third_party/blink/renderer/core/trustedtypes/trusted_types_util.cc
@@ -290,9 +290,12 @@ } if (result->toString().IsNull()) { - TrustedTypeFail(kTrustedHTMLAssignmentAndDefaultPolicyFailed, - execution_context, exception_state, string); - return g_empty_string; + if (TrustedTypeFail(kTrustedHTMLAssignmentAndDefaultPolicyFailed, + execution_context, exception_state, string)) { + return g_empty_string; + } else { + return string; + } } return result->toString(); @@ -346,9 +349,12 @@ } if (result->toString().IsNull()) { - TrustedTypeFail(kTrustedScriptAssignmentAndDefaultPolicyFailed, - execution_context, exception_state, potential_script); - return g_empty_string; + if (TrustedTypeFail(kTrustedScriptAssignmentAndDefaultPolicyFailed, + execution_context, exception_state, potential_script)) { + return g_empty_string; + } else { + return potential_script; + } } return result->toString(); @@ -390,9 +396,12 @@ } if (result->toString().IsNull()) { - TrustedTypeFail(kTrustedScriptURLAssignmentAndDefaultPolicyFailed, - execution_context, exception_state, string); - return g_empty_string; + if (TrustedTypeFail(kTrustedScriptURLAssignmentAndDefaultPolicyFailed, + execution_context, exception_state, string)) { + return g_empty_string; + } else { + return string; + } } return result->toString(); @@ -430,9 +439,12 @@ } if (result->toString().IsNull()) { - TrustedTypeFail(kTrustedURLAssignmentAndDefaultPolicyFailed, - execution_context, exception_state, string); - return g_empty_string; + if (TrustedTypeFail(kTrustedURLAssignmentAndDefaultPolicyFailed, + execution_context, exception_state, string)) { + return g_empty_string; + } else { + return string; + } } return result->toString();
diff --git a/third_party/blink/renderer/core/workers/worker_global_scope.h b/third_party/blink/renderer/core/workers/worker_global_scope.h index 1b8d92d..2180559 100644 --- a/third_party/blink/renderer/core/workers/worker_global_scope.h +++ b/third_party/blink/renderer/core/workers/worker_global_scope.h
@@ -228,21 +228,6 @@ mojom::ScriptType GetScriptType() const { return script_type_; } - // State transition about worker top-level script evaluation. - enum class ScriptEvalState { - // Initial state: ReadyToRunWorkerScript() was not yet called. - // Worker top-level script fetch might or might not be completed, and even - // when the fetch completes in this state, script evaluation will be - // deferred to when ReadyToRunWorkerScript() is called later. - kPauseAfterFetch, - // ReadyToRunWorkerScript() was already called. - kReadyToEvaluate, - // The worker top-level script was evaluated. - kEvaluated, - }; - - ScriptEvalState GetScriptEvalState() const { return script_eval_state_; } - private: void SetWorkerSettings(std::unique_ptr<WorkerSettings>); @@ -287,7 +272,20 @@ blink::BrowserInterfaceBrokerProxy browser_interface_broker_proxy_; + // State transition about worker top-level script evaluation. + enum class ScriptEvalState { + // Initial state: ReadyToRunWorkerScript() was not yet called. + // Worker top-level script fetch might or might not be completed, and even + // when the fetch completes in this state, script evaluation will be + // deferred to when ReadyToRunWorkerScript() is called later. + kPauseAfterFetch, + // ReadyToRunWorkerScript() was already called. + kReadyToEvaluate, + // The worker top-level script was evaluated. + kEvaluated, + }; ScriptEvalState script_eval_state_; + Member<Script> worker_script_; base::Optional<v8_inspector::V8StackTraceId> stack_id_;
diff --git a/third_party/blink/renderer/core/workers/worker_thread_test.cc b/third_party/blink/renderer/core/workers/worker_thread_test.cc index f2830066..69dc5968 100644 --- a/third_party/blink/renderer/core/workers/worker_thread_test.cc +++ b/third_party/blink/renderer/core/workers/worker_thread_test.cc
@@ -296,7 +296,16 @@ EXPECT_EQ(ExitCode::kGracefullyTerminated, GetExitCode()); } -TEST_F(WorkerThreadTest, SyncTerminate_ImmediatelyAfterStart) { +// Disabled due to flakiness: https://crbug.com/1003217. +#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \ + defined(THREAD_SANITIZER) || defined(OS_WIN) +#define MAYBE_SyncTerminate_ImmediatelyAfterStart \ + DISABLED_SyncTerminate_ImmediatelyAfterStart +#else +#define MAYBE_SyncTerminate_ImmediatelyAfterStart \ + SyncTerminate_ImmediatelyAfterStart +#endif +TEST_F(WorkerThreadTest, MAYBE_SyncTerminate_ImmediatelyAfterStart) { ExpectReportingCallsForWorkerPossiblyTerminatedBeforeInitialization(); Start();
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc index 1a1b395..7869370 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc +++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
@@ -1426,6 +1426,7 @@ mojom::blink::ServiceWorkerRegistrationObjectInfoPtr registration_info, mojom::blink::FetchHandlerExistence fetch_hander_existence) { DCHECK(IsContextThread()); + DCHECK(!global_scope_initialized_); DCHECK(service_worker_host.is_valid()); DCHECK(!service_worker_host_); @@ -1442,21 +1443,24 @@ SetFetchHandlerExistence(fetch_hander_existence); + global_scope_initialized_ = true; if (!pause_evaluation_) ReadyToRunWorkerScript(); } void ServiceWorkerGlobalScope::PauseEvaluation() { DCHECK(IsContextThread()); + DCHECK(!global_scope_initialized_); + DCHECK(!pause_evaluation_); pause_evaluation_ = true; } void ServiceWorkerGlobalScope::ResumeEvaluation() { DCHECK(IsContextThread()); DCHECK(pause_evaluation_); - DCHECK_EQ(ScriptEvalState::kReadyToEvaluate, ScriptEvalState()); pause_evaluation_ = false; - ReadyToRunWorkerScript(); + if (global_scope_initialized_) + ReadyToRunWorkerScript(); } void ServiceWorkerGlobalScope::DispatchInstallEvent(
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h index d26c49b..13e7e46c 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h +++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h
@@ -542,10 +542,11 @@ // an event should be aborted. std::unique_ptr<ServiceWorkerTimeoutTimer> timeout_timer_; - // InitializeGlobalScope() doesn't run the script when this flag is true. - // TODO(bashi): Consider merging this flag into - // WorkerGlobalScope::ScriptEvalState + // InitializeGlobalScope() pauses the top level script evaluation when this + // flag is true. bool pause_evaluation_ = false; + // ResumeEvaluation() evaluates the top level script when this flag is true. + bool global_scope_initialized_ = false; // Connected by the ServiceWorkerProviderHost in the browser process and by // the controllees. |controller_bindings_| should be destroyed before
diff --git a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc index ad09429..eb86194 100644 --- a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc +++ b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc
@@ -66,6 +66,8 @@ #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/shared_buffer.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" +#include "third_party/blink/renderer/platform/wtf/text/ascii_ctype.h" +#include "third_party/blink/renderer/platform/wtf/text/string_impl.h" namespace blink { @@ -887,12 +889,22 @@ return; } + // TODO(yoichio): Do this after EndReadData by reading |message_chunks_| + // instead. + if (receiving_message_type_is_text_ && received_text_is_all_ascii_) { + for (size_t i = 0; i < size; i++) { + if (!IsASCII(data[i])) { + received_text_is_all_ascii_ = false; + break; + } + } + } + if (!fin) { message_chunks_.Append(base::make_span(data, size)); return; } - const wtf_size_t message_size = static_cast<wtf_size_t>(message_size_so_far); Vector<base::span<const char>> chunks = message_chunks_.GetView(); if (size > 0) { chunks.push_back(base::make_span(data, size)); @@ -904,20 +916,8 @@ false, chunks); if (receiving_message_type_is_text_) { - Vector<char> flatten; - base::span<const char> span; - if (chunks.size() > 1) { - flatten.ReserveCapacity(message_size); - for (const auto& chunk : chunks) { - flatten.Append(chunk.data(), static_cast<wtf_size_t>(chunk.size())); - } - span = base::make_span(flatten.data(), flatten.size()); - } else if (chunks.size() == 1) { - span = chunks[0]; - } - String message = span.size() > 0 - ? String::FromUTF8(span.data(), span.size()) - : g_empty_string; + String message = GetTextMessage( + chunks, static_cast<wtf_size_t>(message_size_so_far + size)); if (message.IsNull()) { FailAsError("Could not decode a text frame as UTF-8."); } else { @@ -927,6 +927,47 @@ client_->DidReceiveBinaryMessage(chunks); } message_chunks_.Clear(); + received_text_is_all_ascii_ = true; +} + +String WebSocketChannelImpl::GetTextMessage( + const Vector<base::span<const char>>& chunks, + wtf_size_t size) { + DCHECK(receiving_message_type_is_text_); + + if (size == 0) { + return g_empty_string; + } + + // We can skip UTF8 encoding if received text contains only ASCII. + // We do this in order to avoid constructing a temporary buffer. + if (received_text_is_all_ascii_) { + LChar* buffer; + scoped_refptr<StringImpl> string_impl = + StringImpl::CreateUninitialized(size, buffer); + size_t index = 0; + for (const auto& chunk : chunks) { + DCHECK_LE(index + chunk.size(), size); + memcpy(buffer + index, chunk.data(), chunk.size()); + index += chunk.size(); + } + DCHECK_EQ(index, size); + return String(std::move(string_impl)); + } + + Vector<char> flatten; + base::span<const char> span; + if (chunks.size() > 1) { + flatten.ReserveCapacity(size); + for (const auto& chunk : chunks) { + flatten.Append(chunk.data(), static_cast<wtf_size_t>(chunk.size())); + } + span = base::make_span(flatten.data(), flatten.size()); + } else if (chunks.size() == 1) { + span = chunks[0]; + } + DCHECK_EQ(span.size(), size); + return String::FromUTF8(span.data(), span.size()); } void WebSocketChannelImpl::OnConnectionError(const base::Location& set_from,
diff --git a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h index c5f5b5b4..317ddb5a 100644 --- a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h +++ b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h
@@ -228,6 +228,8 @@ network::mojom::blink::WebSocketMessageType type, const char* data, size_t data_size); + String GetTextMessage(const Vector<base::span<const char>>& chunks, + wtf_size_t size); void OnConnectionError(const base::Location& set_from, uint32_t custom_reason, const std::string& description); @@ -243,6 +245,7 @@ bool backpressure_ = false; bool receiving_message_type_is_text_ = false; + bool received_text_is_all_ascii_ = true; bool throttle_passed_ = false; bool has_initiated_opening_handshake_ = false; uint64_t sending_quota_ = 0;
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.cc b/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.cc index 2059816..db10ff1 100644 --- a/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.cc +++ b/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.cc
@@ -33,7 +33,9 @@ } // namespace DarkModeImageClassifier::DarkModeImageClassifier() - : pixels_to_sample_(kPixelsToSample) {} + : pixels_to_sample_(kPixelsToSample), + blocks_count_horizontal_(kBlocksCount1D), + blocks_count_vertical_(kBlocksCount1D) {} DarkModeClassification DarkModeImageClassifier::Classify( Image* image, @@ -42,15 +44,6 @@ if (result != DarkModeClassification::kNotClassified) return result; - // TODO(v.paturi): This is a limitation that arises because of the way - // GetSamples() is implemented. Try to get rid of this limitation. - if (src_rect.Width() <= kBlocksCount1D || - src_rect.Height() <= kBlocksCount1D) { - result = DarkModeClassification::kDoNotApplyFilter; - image->AddDarkModeClassification(src_rect, result); - return result; - } - result = image->CheckTypeSpecificConditionsForDarkMode(src_rect, this); if (result != DarkModeClassification::kNotClassified) { image->AddDarkModeClassification(src_rect, result); @@ -77,6 +70,12 @@ if (pixels_to_sample_ > src_rect.Width() * src_rect.Height()) pixels_to_sample_ = src_rect.Width() * src_rect.Height(); + if (blocks_count_horizontal_ > src_rect.Width()) + blocks_count_horizontal_ = floor(src_rect.Width()); + + if (blocks_count_vertical_ > src_rect.Height()) + blocks_count_vertical_ = floor(src_rect.Height()); + float transparency_ratio; float background_ratio; Vector<SkColor> sampled_pixels; @@ -97,26 +96,30 @@ Vector<SkColor>* sampled_pixels, float* transparency_ratio, float* background_ratio) { - int pixels_per_block = pixels_to_sample_ / (kBlocksCount1D * kBlocksCount1D); + int pixels_per_block = + pixels_to_sample_ / (blocks_count_horizontal_ * blocks_count_vertical_); int transparent_pixels = 0; int opaque_pixels = 0; int blocks_count = 0; - Vector<int> horizontal_grid(kBlocksCount1D + 1); - Vector<int> vertical_grid(kBlocksCount1D + 1); - for (int block = 0; block <= kBlocksCount1D; block++) { - horizontal_grid[block] = static_cast<int>( - round(block * bitmap.width() / static_cast<float>(kBlocksCount1D))); - vertical_grid[block] = static_cast<int>( - round(block * bitmap.height() / static_cast<float>(kBlocksCount1D))); + Vector<int> horizontal_grid(blocks_count_horizontal_ + 1); + Vector<int> vertical_grid(blocks_count_vertical_ + 1); + + for (int block = 0; block <= blocks_count_horizontal_; block++) { + horizontal_grid[block] = static_cast<int>(round( + block * bitmap.width() / static_cast<float>(blocks_count_horizontal_))); + } + for (int block = 0; block <= blocks_count_vertical_; block++) { + vertical_grid[block] = static_cast<int>(round( + block * bitmap.height() / static_cast<float>(blocks_count_vertical_))); } sampled_pixels->clear(); Vector<IntRect> foreground_blocks; - for (int y = 0; y < kBlocksCount1D; y++) { - for (int x = 0; x < kBlocksCount1D; x++) { + for (int y = 0; y < blocks_count_vertical_; y++) { + for (int x = 0; x < blocks_count_horizontal_; x++) { IntRect block(horizontal_grid[x], vertical_grid[y], horizontal_grid[x + 1] - horizontal_grid[x], vertical_grid[y + 1] - vertical_grid[y]); @@ -239,4 +242,10 @@ max_buckets[color_mode == ColorMode::kColor]; } +void DarkModeImageClassifier::ResetDataMembersToDefaults() { + pixels_to_sample_ = kPixelsToSample; + blocks_count_horizontal_ = kBlocksCount1D; + blocks_count_vertical_ = kBlocksCount1D; +} + } // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.h b/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.h index 259a1df7..445379c 100644 --- a/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.h +++ b/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.h
@@ -54,6 +54,24 @@ void SetImageType(ImageType image_type) { image_type_ = image_type; } + // Functions for testing. + + void SetHorizontalBlocksCount(int horizontal_blocks) { + blocks_count_horizontal_ = horizontal_blocks; + } + + void SetVerticalBlocksCount(int vertical_blocks) { + blocks_count_vertical_ = vertical_blocks; + } + + int HorizontalBlocksCount() { return blocks_count_horizontal_; } + + int VerticalBlocksCount() { return blocks_count_vertical_; } + + void ResetDataMembersToDefaults(); + + // End of Functions for testing. + private: enum class ColorMode { kColor = 0, kGrayscale = 1 }; @@ -86,6 +104,12 @@ const ColorMode color_mode); int pixels_to_sample_; + // Holds the number of blocks in the horizontal direction when the image is + // divided into a grid of blocks. + int blocks_count_horizontal_; + // Holds the number of blocks in the vertical direction when the image is + // divided into a grid of blocks. + int blocks_count_vertical_; ImageType image_type_; };
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier_test.cc b/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier_test.cc index 8d30e9c..9a38e0dd 100644 --- a/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier_test.cc +++ b/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier_test.cc
@@ -54,32 +54,9 @@ class DarkModeImageClassifierTest : public testing::Test { public: - // Loads the image from |file_name|, computes features into |features|, - // and returns the classification result. - bool GetFeaturesAndClassification( - const String& file_name, - DarkModeImageClassifier::Features* features) { - CHECK(features); + // Loads the image from |file_name|. + scoped_refptr<BitmapImage> GetImage(const String& file_name) { SCOPED_TRACE(file_name); - scoped_refptr<BitmapImage> image = LoadImage(file_name); - DarkModeImageClassifier dark_mode_image_classifier; - dark_mode_image_classifier.SetImageType( - DarkModeImageClassifier::ImageType::kBitmap); - auto features_or_null = dark_mode_image_classifier.GetFeatures( - image.get(), FloatRect(0, 0, image->width(), image->height())); - CHECK(features_or_null.has_value()); - (*features) = features_or_null.value(); - DarkModeClassification result = - dark_mode_generic_classifier_.ClassifyWithFeatures(*features); - return result == DarkModeClassification::kApplyFilter; - } - - DarkModeGenericClassifier* classifier() { - return &dark_mode_generic_classifier_; - } - - protected: - scoped_refptr<BitmapImage> LoadImage(const String& file_name) { String file_path = test::BlinkWebTestsDir() + file_name; scoped_refptr<SharedBuffer> image_data = test::ReadFromFile(file_path); EXPECT_TRUE(image_data.get() && image_data.get()->size()); @@ -89,8 +66,37 @@ return image; } + // Computes features into |features|. + void GetFeatures(scoped_refptr<BitmapImage> image, + DarkModeImageClassifier::Features* features) { + CHECK(features); + dark_mode_image_classifier_.SetImageType( + DarkModeImageClassifier::ImageType::kBitmap); + auto features_or_null = dark_mode_image_classifier_.GetFeatures( + image.get(), FloatRect(0, 0, image->width(), image->height())); + CHECK(features_or_null.has_value()); + (*features) = features_or_null.value(); + } + + // Returns the classification result. + bool GetClassification(const DarkModeImageClassifier::Features features) { + DarkModeClassification result = + dark_mode_generic_classifier_.ClassifyWithFeatures(features); + return result == DarkModeClassification::kApplyFilter; + } + + DarkModeImageClassifier* image_classifier() { + return &dark_mode_image_classifier_; + } + + DarkModeGenericClassifier* generic_classifier() { + return &dark_mode_generic_classifier_; + } + + protected: ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler> platform_; + DarkModeImageClassifier dark_mode_image_classifier_; DarkModeGenericClassifier dark_mode_generic_classifier_; }; @@ -102,9 +108,13 @@ // Color Buckets Ratio: Low // Decision Tree: Apply // Neural Network: NA - EXPECT_TRUE(GetFeaturesAndClassification("/images/resources/grid-large.png", - &features)); - EXPECT_EQ(classifier()->ClassifyUsingDecisionTreeForTesting(features), + + // The data members of DarkModeImageClassifier have to be reset for every + // image as the same classifier object is used for all the tests. + image_classifier()->ResetDataMembersToDefaults(); + GetFeatures(GetImage("/images/resources/grid-large.png"), &features); + EXPECT_TRUE(GetClassification(features)); + EXPECT_EQ(generic_classifier()->ClassifyUsingDecisionTreeForTesting(features), DarkModeClassification::kApplyFilter); EXPECT_FALSE(features.is_colorful); EXPECT_FALSE(features.is_svg); @@ -117,9 +127,10 @@ // Color Buckets Ratio: Medium // Decision Tree: Can't Decide // Neural Network: Apply - EXPECT_FALSE(GetFeaturesAndClassification("/images/resources/apng08-ref.png", - &features)); - EXPECT_EQ(classifier()->ClassifyUsingDecisionTreeForTesting(features), + image_classifier()->ResetDataMembersToDefaults(); + GetFeatures(GetImage("/images/resources/apng08-ref.png"), &features); + EXPECT_FALSE(GetClassification(features)); + EXPECT_EQ(generic_classifier()->ClassifyUsingDecisionTreeForTesting(features), DarkModeClassification::kNotClassified); EXPECT_FALSE(features.is_colorful); EXPECT_FALSE(features.is_svg); @@ -132,9 +143,10 @@ // Color Buckets Ratio: Low // Decision Tree: Apply // Neural Network: NA. - EXPECT_TRUE(GetFeaturesAndClassification( - "/images/resources/twitter_favicon.ico", &features)); - EXPECT_EQ(classifier()->ClassifyUsingDecisionTreeForTesting(features), + image_classifier()->ResetDataMembersToDefaults(); + GetFeatures(GetImage("/images/resources/twitter_favicon.ico"), &features); + EXPECT_TRUE(GetClassification(features)); + EXPECT_EQ(generic_classifier()->ClassifyUsingDecisionTreeForTesting(features), DarkModeClassification::kApplyFilter); EXPECT_TRUE(features.is_colorful); EXPECT_FALSE(features.is_svg); @@ -147,9 +159,11 @@ // Color Buckets Ratio: High // Decision Tree: Do Not Apply // Neural Network: NA. - EXPECT_FALSE(GetFeaturesAndClassification( - "/images/resources/blue-wheel-srgb-color-profile.png", &features)); - EXPECT_EQ(classifier()->ClassifyUsingDecisionTreeForTesting(features), + image_classifier()->ResetDataMembersToDefaults(); + GetFeatures(GetImage("/images/resources/blue-wheel-srgb-color-profile.png"), + &features); + EXPECT_FALSE(GetClassification(features)); + EXPECT_EQ(generic_classifier()->ClassifyUsingDecisionTreeForTesting(features), DarkModeClassification::kDoNotApplyFilter); EXPECT_TRUE(features.is_colorful); EXPECT_FALSE(features.is_svg); @@ -162,9 +176,10 @@ // Color Buckets Ratio: Medium // Decision Tree: Apply // Neural Network: NA. - EXPECT_TRUE(GetFeaturesAndClassification( - "/images/resources/ycbcr-444-float.jpg", &features)); - EXPECT_EQ(classifier()->ClassifyUsingDecisionTreeForTesting(features), + image_classifier()->ResetDataMembersToDefaults(); + GetFeatures(GetImage("/images/resources/ycbcr-444-float.jpg"), &features); + EXPECT_TRUE(GetClassification(features)); + EXPECT_EQ(generic_classifier()->ClassifyUsingDecisionTreeForTesting(features), DarkModeClassification::kApplyFilter); EXPECT_TRUE(features.is_colorful); EXPECT_FALSE(features.is_svg); @@ -201,4 +216,41 @@ EXPECT_EQ(image->GetMapSize(), 3); } +TEST_F(DarkModeImageClassifierTest, BlocksCount) { + scoped_refptr<BitmapImage> image = + GetImage("/images/resources/grid-large.png"); + DarkModeImageClassifier::Features features; + image_classifier()->ResetDataMembersToDefaults(); + + // When the horizontal and vertical blocks counts are lesser than the + // image dimensions, they should remain unaltered. + image_classifier()->SetHorizontalBlocksCount((int)(image->width() - 1)); + image_classifier()->SetVerticalBlocksCount((int)(image->height() - 1)); + GetFeatures(image, &features); + EXPECT_EQ(image_classifier()->HorizontalBlocksCount(), + (int)(image->width() - 1)); + EXPECT_EQ(image_classifier()->VerticalBlocksCount(), + (int)(image->height() - 1)); + + // When the horizontal and vertical blocks counts are lesser than the + // image dimensions, they should remain unaltered. + image_classifier()->SetHorizontalBlocksCount((int)(image->width())); + image_classifier()->SetVerticalBlocksCount((int)(image->height())); + GetFeatures(image, &features); + EXPECT_EQ(image_classifier()->HorizontalBlocksCount(), + (int)(image->width())); + EXPECT_EQ(image_classifier()->VerticalBlocksCount(), + (int)(image->height())); + + // When the horizontal and vertical blocks counts are greater than the + // image dimensions, they should be reduced. + image_classifier()->SetHorizontalBlocksCount((int)(image->width() + 1)); + image_classifier()->SetVerticalBlocksCount((int)(image->height() + 1)); + GetFeatures(image, &features); + EXPECT_EQ(image_classifier()->HorizontalBlocksCount(), + floor(image->width())); + EXPECT_EQ(image_classifier()->VerticalBlocksCount(), + floor(image->height())); +} + } // namespace blink
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader_test.cc b/third_party/blink/renderer/platform/loader/fetch/resource_loader_test.cc index b0e56e3..aeb5d25 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_loader_test.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader_test.cc
@@ -10,7 +10,6 @@ #include "mojo/public/c/system/data_pipe.h" #include "services/network/public/mojom/fetch_api.mojom-blink.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/public/platform/web_runtime_features.h" #include "third_party/blink/public/platform/web_url_loader.h" #include "third_party/blink/public/platform/web_url_loader_factory.h" #include "third_party/blink/renderer/platform/exported/wrapped_resource_response.h" @@ -117,9 +116,6 @@ } TEST_F(ResourceLoaderTest, ResponseType) { - // This test will be trivial if EnableOutOfBlinkCors is enabled. - WebRuntimeFeatures::EnableOutOfBlinkCors(false); - const scoped_refptr<const SecurityOrigin> origin = SecurityOrigin::Create(foo_url_); const scoped_refptr<const SecurityOrigin> no_origin = nullptr;
diff --git a/third_party/blink/web_tests/LeakExpectations b/third_party/blink/web_tests/LeakExpectations index 9a55f9d2..1d97ec5 100644 --- a/third_party/blink/web_tests/LeakExpectations +++ b/third_party/blink/web_tests/LeakExpectations
@@ -24,6 +24,8 @@ crbug.com/755625 external/wpt/beacon/beacon-error.window.html [ Leak ] crbug.com/651742 external/wpt/content-security-policy/connect-src/connect-src-beacon-allowed.sub.html [ Leak ] +crbug.com/1003224 http/tests/clipboard/async-write-image-read-image.html [ Leak ] + # ----------------------------------------------------------------- # Flakily leaks # -----------------------------------------------------------------
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests index 15a5e85..84c2aed5 100644 --- a/third_party/blink/web_tests/NeverFixTests +++ b/third_party/blink/web_tests/NeverFixTests
@@ -1666,7 +1666,6 @@ external/wpt/FileAPI/FileReader/test_notreadableerrors-manual.html [ WontFix ] external/wpt/FileAPI/FileReader/test_securityerrors-manual.html [ WontFix ] external/wpt/FileAPI/url/url_createobjecturl_file_img-manual.html [ WontFix ] -external/wpt/accelerometer/Accelerometer_onerror-manual.https.html [ WontFix ] external/wpt/accelerometer/LinearAccelerationSensor-shake-threshold-manual.https.html [ WontFix ] external/wpt/audio-output/setSinkId-manual.https.html [ WontFix ] external/wpt/battery-status/battery-charging-manual.https.html [ WontFix ] @@ -1849,8 +1848,6 @@ external/wpt/geolocation-API/getCurrentPosition_permission_allow-manual.html [ WontFix ] external/wpt/geolocation-API/getCurrentPosition_permission_deny-manual.html [ WontFix ] external/wpt/geolocation-API/watchPosition_permission-manual.html [ WontFix ] -external/wpt/geolocation-sensor/GeolocationSensor_onerror-manual.https.html [ WontFix ] -external/wpt/gyroscope/Gyroscope_onerror-manual.https.html [ WontFix ] external/wpt/hr-time/unload-manual.html [ WontFix ] external/wpt/html-media-capture/capture_audio-manual.html [ WontFix ] external/wpt/html-media-capture/capture_audio_cancel-manual.html [ WontFix ] @@ -1977,7 +1974,6 @@ external/wpt/html/semantics/selectors/pseudo-classes/checked-001-manual.html [ WontFix ] external/wpt/html/webappapis/scripting/events/contextmenu-event-manual.htm [ WontFix ] external/wpt/html/webappapis/scripting/events/event-handler-processing-algorithm-manual.html [ WontFix ] -external/wpt/magnetometer/Magnetometer_onerror-manual.https.html [ WontFix ] external/wpt/mediacapture-streams/MediaStream-MediaElement-preload-none-manual.https.html [ WontFix ] external/wpt/mediacapture-streams/MediaStreamTrack-end-manual.https.html [ WontFix ] external/wpt/notifications/body-basic-manual.html [ WontFix ] @@ -2009,7 +2005,6 @@ external/wpt/orientation-event/t023-manual.https.html [ WontFix ] external/wpt/orientation-event/t025-manual.https.html [ WontFix ] external/wpt/orientation-event/t028-manual.https.html [ WontFix ] -external/wpt/orientation-sensor/OrientationSensor_onerror-manual.https.html [ WontFix ] external/wpt/page-visibility/test_minimize-manual.html [ WontFix ] external/wpt/page-visibility/test_tab_state_change-manual.html [ WontFix ] external/wpt/payment-method-basic-card/empty-data-manual.https.html [ WontFix ]
diff --git a/third_party/blink/web_tests/SlowTests b/third_party/blink/web_tests/SlowTests index e930830..59b0391d 100644 --- a/third_party/blink/web_tests/SlowTests +++ b/third_party/blink/web_tests/SlowTests
@@ -525,7 +525,6 @@ crbug.com/874695 plugins/plugin-document-back-forward.html [ Slow ] crbug.com/874695 pointer-lock/locked-element-iframe-removed-from-dom.html [ Slow ] crbug.com/874695 printing/webgl-oversized-printing.html [ Slow ] -crbug.com/874695 sensor/magnetometer.html [ Slow ] crbug.com/874695 storage/websql/change-version.html [ Slow ] crbug.com/874695 storage/websql/executesql-accepts-only-one-statement.html [ Slow ] crbug.com/874695 storage/websql/open-database-creation-callback.html [ Slow ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index f137c3c..3a7ae1f0 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -244,8 +244,7 @@ # Display locking failures crbug.com/955533 wpt_internal/display-lock/sizing/overflow-auto-with-overflow.html [ Failure ] -# Skip some tests for rendersubtree -crbug.com/991095 wpt_internal/display-lock/rendersubtree/sizing [ Skip ] +crbug.com/1000702 wpt_internal/display-lock/rendersubtree/sizing/get-bounding-client-rect-block-layout.html [ Failure ] # MSAN failure crbug.com/996625 inspector-protocol/accessibility/accessibility-getFullAXTree-display-locked.js [ Skip ] @@ -535,7 +534,6 @@ crbug.com/174167 external/wpt/css/css-tables/visibility-collapse-colspan-003.html [ Failure ] crbug.com/174167 external/wpt/css/css-tables/visibility-collapse-rowcol-001.html [ Failure ] crbug.com/174167 external/wpt/css/css-tables/visibility-collapse-rowcol-002.html [ Failure ] -crbug.com/377847 external/wpt/css/css-tables/subpixel-collapsed-borders-002.html [ Failure ] crbug.com/377847 external/wpt/css/css-tables/subpixel-collapsed-borders-003.html [ Failure ] crbug.com/377847 external/wpt/css/css-tables/subpixel-table-cell-height-001.html [ Failure ] crbug.com/377847 external/wpt/css/css-tables/subpixel-table-cell-width-001.html [ Failure ] @@ -672,9 +670,6 @@ # Layout team disagrees with the spec for this particular test. crbug.com/591099 external/wpt/css/css-ui/text-overflow-015.html [ Failure ] -# Fails only on Linux bots. Pass on all other bots and on local Linux. -crbug.com/985620 [ Linux ] fast/text/zwnj-disables-kerning.html [ Failure ] - # ====== Layout team owned tests to here ====== # ====== LayoutNG-only failures from here ====== @@ -731,7 +726,7 @@ crbug.com/591099 fast/multicol/vertical-lr/float-paginate.html [ Failure ] crbug.com/591099 fast/multicol/vertical-lr/nested-columns.html [ Failure ] crbug.com/591099 fast/multicol/vertical-lr/unsplittable-inline-block.html [ Failure ] -crbug.com/591099 fast/text/ellipsis-with-self-painting-layer.html [ Failure ] +crbug.com/591099 [ Win ] fast/text/ellipsis-with-self-painting-layer.html [ Failure ] # LayoutNG failures that needs to be triaged crbug.com/591099 fast/text/selection/selection-rect-line-height-too-small.html [ Failure ] @@ -742,7 +737,6 @@ crbug.com/591099 external/wpt/css/css-text/hyphens/hyphens-out-of-flow-002.html [ Failure ] crbug.com/591099 external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-vertical.html [ Failure ] crbug.com/591099 fast/css-intrinsic-dimensions/width-avoid-floats.html [ Failure ] -crbug.com/591099 fast/multicol/span/overflow-on-multicol.html [ Failure ] crbug.com/591099 fast/selectors/shadow-host-div-with-span.html [ Failure ] crbug.com/591099 fast/selectors/shadow-host-div-with-text.html [ Failure ] crbug.com/591099 fast/text/selection/inline-block-in-selection-root.html [ Failure ] @@ -760,8 +754,10 @@ crbug.com/591099 external/wpt/dom/ranges/Range-compareBoundaryPoints.html [ Timeout Failure Pass ] crbug.com/591099 external/wpt/dom/ranges/Range-set.html [ Failure Timeout ] crbug.com/591099 external/wpt/encoding/legacy-mb-korean/euc-kr/euckr-decode-ksc_5601.html [ Timeout Failure Pass ] -crbug.com/591099 fast/text/international/shape-across-elements-simple.html [ Failure ] -crbug.com/591099 fast/text/word-space-monospace.html [ Failure ] +crbug.com/591099 [ Mac ] fast/text/international/shape-across-elements-simple.html [ Failure ] +crbug.com/591099 [ Win ] fast/text/international/shape-across-elements-simple.html [ Failure ] +crbug.com/591099 [ Mac ] fast/text/word-space-monospace.html [ Failure ] +crbug.com/591099 [ Win ] fast/text/word-space-monospace.html [ Failure ] crbug.com/591099 [ Fuchsia ] editing/selection/4402375.html [ Failure ] crbug.com/591099 [ Fuchsia ] fast/block/float/centered-float-avoidance-complexity.html [ Failure Timeout ] crbug.com/591099 [ Fuchsia ] fast/block/float/float-in-float-painting.html [ Failure ] @@ -1349,7 +1345,6 @@ crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-multicol/multicol-breaking-nobackground-003.html [ Failure ] crbug.com/829028 virtual/layout_ng_experimental/external/wpt/css/css-multicol/multicol-breaking-nobackground-004.html [ Failure ] crbug.com/829028 virtual/layout_ng_experimental/external/wpt/css/css-multicol/multicol-breaking-nobackground-005.html [ Failure ] -crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-multicol/multicol-br-inside-avoidcolumn-001.xht [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-multicol/multicol-clip-001.xht [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-multicol/multicol-clip-002.xht [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-multicol/multicol-collapsing-001.xht [ Failure ] @@ -2082,7 +2077,6 @@ ## https://test-results.appspot.com/data/layout_results/linux-blink-rel/1237/webkit_layout_tests%20%28with%20patch%29/layout-test-results/results.html crbug.com/891427 virtual/threaded/animations/responsive/viewport-unit-transform-responsive.html [ Timeout ] crbug.com/891427 virtual/threaded/animations/responsive/viewport-unit-translate-responsive.html [ Timeout ] -crbug.com/891427 fast/replaced/replaced-breaking.html [ Failure ] crbug.com/891427 virtual/android/fullscreen/rendering/backdrop-video.html [ Failure ] crbug.com/891427 virtual/android/url-bar/bottom-and-top-fixed-sticks-to-top.html [ Failure ] ## Next 4 here: https://ci.chromium.org/p/chromium/builders/luci.chromium.try/linux_chromium_rel_ng/216317 @@ -3025,8 +3019,6 @@ #crbug.com/626703 [ Win ] external/wpt/css/css-flexbox/flex-minimum-width-flex-items-003.xht [ Failure ] #crbug.com/626703 [ Win ] external/wpt/css/css-flexbox/flexbox_flex-natural-mixed-basis-auto.html [ Failure ] #crbug.com/626703 external/wpt/css/css-cascade/revert-val-001.html [ Failure ] -crbug.com/626703 external/wpt/css/css-writing-modes/sizing-orthog-htb-in-vrl-001.xht [ Failure ] -crbug.com/626703 external/wpt/css/css-writing-modes/sizing-orthog-htb-in-vrl-004.xht [ Failure ] crbug.com/626703 external/wpt/css/css-writing-modes/sizing-orthog-htb-in-vrl-013.xht [ Failure ] crbug.com/626703 external/wpt/css/css-writing-modes/sizing-orthog-vlr-in-htb-008.xht [ Failure ] crbug.com/626703 external/wpt/css/css-writing-modes/sizing-orthog-vlr-in-htb-020.xht [ Failure ] @@ -3568,8 +3560,6 @@ crbug.com/626703 external/wpt/svg/interact/manual/event-attribute-001-manual.svg [ Skip ] crbug.com/626703 external/wpt/css/css-values/vh-support-atviewport.html [ Failure ] crbug.com/626703 external/wpt/css/CSS2/text/white-space-nowrap-attribute-001.xht [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/css/CSS2/text/white-space-bidirectionality-001.xht [ Failure ] -crbug.com/626703 [ Win ] external/wpt/css/CSS2/text/white-space-bidirectionality-001.xht [ Failure ] crbug.com/626703 external/wpt/css/css-text/white-space/pre-wrap-012.html [ Failure ] crbug.com/626703 external/wpt/css/css-text/white-space/pre-wrap-014.html [ Failure ] @@ -4791,12 +4781,6 @@ crbug.com/746128 [ Mac ] media/controls/video-enter-exit-fullscreen-without-hovering-doesnt-show-controls.html [ Failure Pass ] crbug.com/746128 [ Mac ] virtual/audio-service/media/controls/video-enter-exit-fullscreen-without-hovering-doesnt-show-controls.html [ Failure Pass ] -crbug.com/731018 [ Mac ] sensor/accelerometer.html [ Failure Pass Crash ] -crbug.com/731018 [ Mac ] sensor/ambient-light-sensor.html [ Failure Pass Crash ] -crbug.com/731018 [ Mac ] sensor/gyroscope.html [ Failure Pass Crash ] -crbug.com/731018 [ Mac ] sensor/magnetometer.html [ Failure Pass Crash ] -crbug.com/731018 [ Mac ] sensor/orientation-sensor.html [ Failure Pass Crash ] - # Tests failing when enabling new modern media controls crbug.com/831942 media/webkit-media-controls-webkit-appearance.html [ Failure Pass ] crbug.com/831942 virtual/audio-service/media/webkit-media-controls-webkit-appearance.html [ Failure Pass ] @@ -5667,9 +5651,6 @@ # Sheriff 2019-02-13 crbug.com/931646 [ Win7 ] http/tests/preload/meta-viewport-link-headers-imagesrcset.html [ Failure Pass ] -# Sheriff 2019-02-19 -crbug.com/933346 [ Debug ] external/wpt/orientation-sensor/RelativeOrientationSensor.https.html [ Failure Timeout Pass ] - # These started failing when network service was enabled by default. crbug.com/933880 external/wpt/service-workers/service-worker/request-end-to-end.https.html [ Failure ] crbug.com/933880 virtual/omt-service-worker-startup/external/wpt/service-workers/service-worker/request-end-to-end.https.html [ Failure ] @@ -5720,7 +5701,6 @@ crbug.com/937811 [ Linux Release ] http/tests/devtools/elements/shadow/elements-panel-shadow-selection-on-refresh-3.js [ Pass Failure ] crbug.com/937811 [ Win Release ] http/tests/devtools/elements/shadow/elements-panel-shadow-selection-on-refresh-2.js [ Pass Failure ] crbug.com/935689 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/symbols-function.html [ Failure Pass ] -crbug.com/937858 [ Debug ] external/wpt/ambient-light/AmbientLightSensor.https.html [ Pass Failure ] # Sheriff 2019-03-05 crbug.com/938200 http/tests/devtools/network/network-blocked-reason.js [ Timeout Pass ] @@ -5815,8 +5795,6 @@ # Sheriff 2019-04-03 crbug.com/949167 external/wpt/html/semantics/links/links-created-by-a-and-area-elements/target_blank_implicit_noopener.html [ Pass Timeout ] crbug.com/949207 external/wpt/html/semantics/links/links-created-by-a-and-area-elements/target_blank_implicit_noopener_base.html [ Pass Timeout ] -crbug.com/949442 [ Mac10.13 Debug ] external/wpt/accelerometer/Accelerometer.https.html [ Pass Failure ] -crbug.com/949442 [ Mac10.13 Debug ] external/wpt/orientation-sensor/AbsoluteOrientationSensor.https.html [ Pass Failure ] crbug.com/949445 [ Mac ] fast/forms/text/input-text-scroll-left-on-blur.html [ Failure ] # Sheriff 2019-04-09 @@ -6167,12 +6145,6 @@ crbug.com/999209 virtual/lazyload-image/http/tests/lazyload/style-dimension.html [ Timeout ] -# Disable tests with expectation mismatch -crbug.com/999473 external/wpt/streams/writable-streams/properties.any.sharedworker.html [ Pass Failure ] -crbug.com/999473 external/wpt/streams/writable-streams/properties.any.serviceworker.html [ Pass Failure ] -crbug.com/999473 external/wpt/streams/writable-streams/properties.any.html [ Pass Failure ] -crbug.com/999473 external/wpt/streams/writable-streams/properties.any.worker.html [ Pass Failure ] - crbug.com/1000051 [ Mac ] virtual/audio-service/media/controls/volume-slider.html [ Failure Timeout Pass ] # Sheriff 2019-09-03 @@ -6241,3 +6213,6 @@ crbug.com/1003055 virtual/threaded/external/wpt/css/css-scroll-snap/scroll-target-snap-001.html [ Failure ] crbug.com/1003055 virtual/threaded/external/wpt/css/css-scroll-snap/scroll-target-snap-002.html [ Failure ] crbug.com/1003055 virtual/threaded/external/wpt/css/css-scroll-snap/scroll-target-snap-003.html [ Failure ] + +# Sheriff 2019-09-12 +crbug.com/1003268 [ Win10 ] fast/harness/internals-observe-gc.html [ Failure ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json index 5470100..2719586e 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
@@ -73,24 +73,12 @@ {} ] ], - "accelerometer/Accelerometer_onerror-manual.https.html": [ - [ - "accelerometer/Accelerometer_onerror-manual.https.html", - {} - ] - ], "accelerometer/LinearAccelerationSensor-shake-threshold-manual.https.html": [ [ "accelerometer/LinearAccelerationSensor-shake-threshold-manual.https.html", {} ] ], - "ambient-light/AmbientLightSensor_onerror-manual.https.html": [ - [ - "ambient-light/AmbientLightSensor_onerror-manual.https.html", - {} - ] - ], "audio-output/setSinkId-manual.https.html": [ [ "audio-output/setSinkId-manual.https.html", @@ -4861,12 +4849,6 @@ {} ] ], - "geolocation-sensor/GeolocationSensor_onerror-manual.https.html": [ - [ - "geolocation-sensor/GeolocationSensor_onerror-manual.https.html", - {} - ] - ], "graphics-aam/graphics-document_on_html_element-manual.html": [ [ "graphics-aam/graphics-document_on_html_element-manual.html", @@ -4903,12 +4885,6 @@ {} ] ], - "gyroscope/Gyroscope_onerror-manual.https.html": [ - [ - "gyroscope/Gyroscope_onerror-manual.https.html", - {} - ] - ], "hr-time/unload-manual.html": [ [ "hr-time/unload-manual.html", @@ -5947,12 +5923,6 @@ {} ] ], - "magnetometer/Magnetometer_onerror-manual.https.html": [ - [ - "magnetometer/Magnetometer_onerror-manual.https.html", - {} - ] - ], "mediacapture-depth/dictionary-manual.https.html": [ [ "mediacapture-depth/dictionary-manual.https.html", @@ -6205,12 +6175,6 @@ {} ] ], - "orientation-sensor/OrientationSensor_onerror-manual.https.html": [ - [ - "orientation-sensor/OrientationSensor_onerror-manual.https.html", - {} - ] - ], "page-visibility/test_minimize-manual.html": [ [ "page-visibility/test_minimize-manual.html", @@ -65081,6 +65045,18 @@ {} ] ], + "css/css-tables/percent-height-replaced-in-percent-cell.tentative.html": [ + [ + "css/css-tables/percent-height-replaced-in-percent-cell.tentative.html", + [ + [ + "/css/reference/ref-filled-green-100px-square-only.html", + "==" + ] + ], + {} + ] + ], "css/css-tables/percent-width-cell-dynamic.html": [ [ "css/css-tables/percent-width-cell-dynamic.html", @@ -126430,6 +126406,9 @@ "accelerometer/Accelerometer.https-expected.txt": [ [] ], + "accelerometer/LinearAccelerationSensor-shake-threshold-manual.https-expected.txt": [ + [] + ], "accelerometer/META.yml": [ [] ], @@ -156031,6 +156010,9 @@ "generic-sensor/generic-sensor-tests.js": [ [] ], + "generic-sensor/resources/generic-sensor-helpers.js": [ + [] + ], "generic-sensor/resources/iframe_sensor_handler.html": [ [] ], @@ -161767,15 +161749,6 @@ "html/semantics/forms/attributes-common-to-form-controls/dirname-ltr-iframe.html": [ [] ], - "html/semantics/forms/autofocus/first-reconnected-expected.txt": [ - [] - ], - "html/semantics/forms/autofocus/first-when-later-but-before-expected.txt": [ - [] - ], - "html/semantics/forms/autofocus/focusable-area-in-top-document-expected.txt": [ - [] - ], "html/semantics/forms/autofocus/resources/child-autofocus.html": [ [] ], @@ -161791,18 +161764,9 @@ "html/semantics/forms/autofocus/resources/utils.js": [ [] ], - "html/semantics/forms/autofocus/skip-document-with-fragment-expected.txt": [ - [] - ], - "html/semantics/forms/autofocus/skip-non-focusable-expected.txt": [ - [] - ], "html/semantics/forms/autofocus/supported-elements-expected.txt": [ [] ], - "html/semantics/forms/autofocus/update-the-rendering-expected.txt": [ - [] - ], "html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt": [ [] ], @@ -166648,6 +166612,9 @@ "portals/resources/postmessage-referrer.sub.html": [ [] ], + "portals/resources/simple-portal-adopts-predecessor.html": [ + [] + ], "portals/resources/simple-portal.html": [ [] ], @@ -256196,6 +256163,21 @@ {} ] ], + "mathml/relations/html5-tree/tabindex-001.html": [ + [ + "mathml/relations/html5-tree/tabindex-001.html", + {} + ] + ], + "mathml/relations/html5-tree/tabindex-002.html": [ + [ + "mathml/relations/html5-tree/tabindex-002.html", + { + "testdriver": true, + "timeout": "long" + } + ] + ], "mathml/relations/html5-tree/unique-identifier-2.html": [ [ "mathml/relations/html5-tree/unique-identifier-2.html", @@ -272348,6 +272330,12 @@ {} ] ], + "portals/portals-set-src-after-activate.html": [ + [ + "portals/portals-set-src-after-activate.html", + {} + ] + ], "preload/avoid-delaying-onload-link-preload.html": [ [ "preload/avoid-delaying-onload-link-preload.html", @@ -328873,7 +328861,7 @@ "support" ], "accelerometer/Accelerometer-iframe-access.https.html": [ - "f5a79f07536f85e4f78c5c1b96532c9b583515dc", + "bec1705780f53e795949729a19bf8f3e4f03b432", "testharness" ], "accelerometer/Accelerometer-supported-by-feature-policy.html": [ @@ -328881,20 +328869,20 @@ "testharness" ], "accelerometer/Accelerometer.https-expected.txt": [ - "8597e2aef1f79cb6318f0c118a30466d6aece71e", + "f974e469b92356b90baa341085a4bf70e71db893", "support" ], "accelerometer/Accelerometer.https.html": [ - "c68e9854b0d16a989bd66bd0f42201fc9202711a", + "e8af0393fc5691b486df43bb32fbc4942a3ad9bb", "testharness" ], "accelerometer/Accelerometer_insecure_context.html": [ "ff1f0832c31088bd0a85c99f9ad158f7c62d62a6", "testharness" ], - "accelerometer/Accelerometer_onerror-manual.https.html": [ - "dec21881b63101a96dcb8e19e963867eb0cb664c", - "manual" + "accelerometer/LinearAccelerationSensor-shake-threshold-manual.https-expected.txt": [ + "6cc9b56e286762e783b30cde06b49c3899892f77", + "support" ], "accelerometer/LinearAccelerationSensor-shake-threshold-manual.https.html": [ "c0746e5ebd54439ff9ad085d103aab5adbfec0bf", @@ -329077,7 +329065,7 @@ "support" ], "ambient-light/AmbientLightSensor-iframe-access.https.html": [ - "9600843145cd2771629fea765bc853467a5d5bf9", + "5fedd5fb7a9b18ac36b75802667814097c23121e", "testharness" ], "ambient-light/AmbientLightSensor-supported-by-feature-policy.html": [ @@ -329085,17 +329073,13 @@ "testharness" ], "ambient-light/AmbientLightSensor.https.html": [ - "8fcc4c7cd227fee26907b7f0e0798ba6cd8f1a5d", + "2383a2de2187f863c0299688a2f6ad80972648b6", "testharness" ], "ambient-light/AmbientLightSensor_insecure_context.html": [ "9a7c91492b58d82d8f51478d7a6a98136184180b", "testharness" ], - "ambient-light/AmbientLightSensor_onerror-manual.https.html": [ - "139e76fe1f927c2d766bb6f94019f753d766ceef", - "manual" - ], "ambient-light/META.yml": [ "c3f69ba181e69906ebeb1fe42f1e4255f17c47c5", "support" @@ -330933,7 +330917,7 @@ "support" ], "common/security-features/resources/common.sub.js": [ - "c7f94e806f94da494580de2f25c676815ca9464e", + "64d2b9ffb4e3b2231f3b90313c4376ba2f4d867a", "support" ], "common/security-features/resources/common.sub.js.headers": [ @@ -330997,7 +330981,7 @@ "support" ], "common/security-features/subresource/subresource.py": [ - "850ca5e8147e659d803e33dd098e573676bbef02", + "582378d41fa38a29da1bbda9a3065d4585a36875", "support" ], "common/security-features/subresource/svg.py": [ @@ -331057,7 +331041,7 @@ "support" ], "common/security-features/tools/spec_validator.py": [ - "fff4c5dd6f688a733c1a48c5fe818f7f2979c8dd", + "dae5c6e35a3fe978571e9976c6aaaf1c5d3c1076", "support" ], "common/security-features/tools/template/disclaimer.template": [ @@ -340993,7 +340977,7 @@ "reftest" ], "css/CSS2/linebox/vertical-align-top-bottom-001.html": [ - "c08674da4b359800ce7f1821dd36277a74a780f3", + "2e03bc0d2fbed51589545b0b62d0ccb3d161556d", "testharness" ], "css/CSS2/linebox/vertical-align-top-bottom-padding-ref.html": [ @@ -384776,6 +384760,10 @@ "ffbb796b6afe0fe9fa93e15de3586bef96174d8b", "reftest" ], + "css/css-tables/percent-height-replaced-in-percent-cell.tentative.html": [ + "ed5effa8a755d9533054e0b6005900305735b3d6", + "reftest" + ], "css/css-tables/percent-width-cell-dynamic.html": [ "5c7ef3bf8a2b7eac7371c7d86594f52cfb42815d", "reftest" @@ -431545,7 +431533,7 @@ "manual" ], "fullscreen/rendering/fullscreen-css-transition.html": [ - "1d50502ee3bdb9b58eab3b516f1f743fa4e3a2f2", + "b494dc04e6d900ce3fcb6ece31dd987095f4cfdb", "testharness" ], "fullscreen/rendering/fullscreen-pseudo-class-manual-expected.txt": [ @@ -431601,7 +431589,7 @@ "support" ], "generic-sensor/README.md": [ - "28227b0ba40d9075351d0a7a0003f30b5995118f", + "250300b51ed406d5353b63c596295a48502481e7", "support" ], "generic-sensor/SensorErrorEvent-constructor.https.html": [ @@ -431617,15 +431605,19 @@ "support" ], "generic-sensor/generic-sensor-tests.js": [ - "a48b4c59aa89d0f1a0c7855f93bd80ce0f33fbf0", + "1779fd6bb59235ff14f0c5ec3d67a134b74be4a2", "support" ], "generic-sensor/idlharness.https.window.js": [ "f591d755209e386f34610a429e5bdcd85e9c0ac0", "testharness" ], + "generic-sensor/resources/generic-sensor-helpers.js": [ + "8302f6f6cfbc77ebda6ab92f5a1269fb209416c1", + "support" + ], "generic-sensor/resources/iframe_sensor_handler.html": [ - "12ab1d47b99f65344bceb1194452b94832066d66", + "ec594abd4c726e008700597ca50a971056404c0e", "support" ], "geolocation-API/META.yml": [ @@ -431761,7 +431753,7 @@ "support" ], "geolocation-sensor/GeolocationSensor-iframe-access.https.html": [ - "68a99029f63b04d3ce44f2564f39f31062376dfd", + "bb0541de32c374c0028de72c90cc195f02979d61", "testharness" ], "geolocation-sensor/GeolocationSensor-supported-by-feature-policy.html": [ @@ -431769,21 +431761,17 @@ "testharness" ], "geolocation-sensor/GeolocationSensor.https-expected.txt": [ - "88659b68f2e9a3462da607f3e4a035da5a9a73ff", + "aa70d5a307908f785908cda8d43804f4d0fc94a4", "support" ], "geolocation-sensor/GeolocationSensor.https.html": [ - "ef198438fdee21bb667f9e23795caea4dc23e833", + "b71f964b1297f39257c1e80ce50a145c5283228f", "testharness" ], "geolocation-sensor/GeolocationSensor_insecure_context.html": [ "6a3a126c7850f42486680266c4901d7c84b867c8", "testharness" ], - "geolocation-sensor/GeolocationSensor_onerror-manual.https.html": [ - "2e6d45f2ede501dc32cc2c6870849c59a72eb00d", - "manual" - ], "geolocation-sensor/GeolocationSensor_read.https-expected.txt": [ "ed51f10b26c45da3d8940874eb7005aa575b8ca2", "support" @@ -431889,7 +431877,7 @@ "support" ], "gyroscope/Gyroscope-iframe-access.https.html": [ - "02edf4bd232ec2878b3d9f5ff7a0bc976eb41e39", + "ed0183bef9ad414b451acc87712acd7b7b55a347", "testharness" ], "gyroscope/Gyroscope-supported-by-feature-policy.html": [ @@ -431897,17 +431885,13 @@ "testharness" ], "gyroscope/Gyroscope.https.html": [ - "f4ae28acf01f8a1c0a11bf8bc9f9ea5eaef0c49f", + "f85349f5315a27bdb06a3b6b4b0fa2c40612a15a", "testharness" ], "gyroscope/Gyroscope_insecure_context.html": [ "2ae8117d70877871a706cce48ebc6b2f10e0412d", "testharness" ], - "gyroscope/Gyroscope_onerror-manual.https.html": [ - "b63448bfc88cc61011fa16681d36be6f9384f462", - "manual" - ], "gyroscope/META.yml": [ "6a48535e3c7416eb1d54b1a6e6837230ba498b39", "support" @@ -445604,18 +445588,10 @@ "47e3e3fd0abdc93e8447c099314935f8cdc31c42", "testharness" ], - "html/semantics/forms/autofocus/first-reconnected-expected.txt": [ - "b056ed018821f61c2360ca260264f0fb08eef458", - "support" - ], "html/semantics/forms/autofocus/first-reconnected.html": [ "99ee9198d1b0a39605ee7115ba71b1178e815943", "testharness" ], - "html/semantics/forms/autofocus/first-when-later-but-before-expected.txt": [ - "535ad230cc676aef3b046fee9c022610b657a6cb", - "support" - ], "html/semantics/forms/autofocus/first-when-later-but-before.html": [ "f361463401b555f4c90cc25f195dd8b6c7e03b0b", "testharness" @@ -445628,10 +445604,6 @@ "02ebb79a3e9dff0f1b0211eb187b7a91f7de8c17", "testharness" ], - "html/semantics/forms/autofocus/focusable-area-in-top-document-expected.txt": [ - "f8760c98f9030e0670d9b790f5a9d4e4b4781f32", - "support" - ], "html/semantics/forms/autofocus/focusable-area-in-top-document.html": [ "327040eeeeb7da9bf134cb7120b60c7d1e76d5c7", "testharness" @@ -445676,18 +445648,10 @@ "d392b903f075276a03189207e57d789608523de1", "testharness" ], - "html/semantics/forms/autofocus/skip-document-with-fragment-expected.txt": [ - "699bc679602616f62cd4ca43d65c93855fee2034", - "support" - ], "html/semantics/forms/autofocus/skip-document-with-fragment.html": [ "a4301e13516634e9fc09d1b8084091a2697b1f24", "testharness" ], - "html/semantics/forms/autofocus/skip-non-focusable-expected.txt": [ - "eaeff36ab1187f7997cb01fd5f8fbb60c6d215a8", - "support" - ], "html/semantics/forms/autofocus/skip-non-focusable.html": [ "008371d8e163fbdec937e29435fe61dffd520cde", "testharness" @@ -445708,10 +445672,6 @@ "398577e7d51edf10ea2571ec4e220394208f6931", "testharness" ], - "html/semantics/forms/autofocus/update-the-rendering-expected.txt": [ - "5f907cc883352c0fe1b48523da2c440f2c31a22f", - "support" - ], "html/semantics/forms/autofocus/update-the-rendering.html": [ "afaf0926f5b55e4f1925010c7262ed26a616d3be", "testharness" @@ -453893,7 +453853,7 @@ "support" ], "interfaces/wasm-js-api.idl": [ - "62bc0b7a839cce5308a85b162585bd387efb1163", + "828729071e4b5e77978bce021a8b5c36c3b9cd85", "support" ], "interfaces/wasm-web-api.idl": [ @@ -454813,7 +454773,7 @@ "support" ], "magnetometer/Magnetometer-iframe-access.https.html": [ - "04c9800fc018dcb51584e204f453d74bd2647c2c", + "3dc90e3dd7f5ac52364f02712ad7083cc373ec6b", "testharness" ], "magnetometer/Magnetometer-supported-by-feature-policy.html": [ @@ -454821,21 +454781,17 @@ "testharness" ], "magnetometer/Magnetometer.https-expected.txt": [ - "2a48ea4e8101f9958f2cbbda4fa6456cd6851ac8", + "f918d3af72f13b49fd14722d768beb507c92005e", "support" ], "magnetometer/Magnetometer.https.html": [ - "c93d9a415f3b2662a477b25eb82384dcfa8bca3a", + "0cc443784bebb38fce406b7efe934dc10aa7f966", "testharness" ], "magnetometer/Magnetometer_insecure_context.html": [ "45ff584b425d991f73419751381bdc61ec279817", "testharness" ], - "magnetometer/Magnetometer_onerror-manual.https.html": [ - "dbdcf1d5f7c5247ea4b5b1d8b6293173dd190eba", - "manual" - ], "magnetometer/OWNERS": [ "614fe922a78ff13495733a48ce10b06d008416d4", "support" @@ -455832,6 +455788,14 @@ "e1d7a853704ce5f9edf2f2d6d6a414be51fe4e4b", "reftest" ], + "mathml/relations/html5-tree/tabindex-001.html": [ + "aaf82f77caa87cadd4dfa4706a2bc15192006a6a", + "testharness" + ], + "mathml/relations/html5-tree/tabindex-002.html": [ + "a1788d562e3e20e7160d27ff2fd940e6d3851ca3", + "testharness" + ], "mathml/relations/html5-tree/unique-identifier-1-iframe-1.html": [ "6b3ab07f1aa1dcf7edefd39a3e5f5bc4724ff960", "support" @@ -466917,11 +466881,11 @@ "support" ], "orientation-sensor/AbsoluteOrientationSensor-iframe-access.https.html": [ - "5fe1e528590a76d2c09d3d168811c5ae1ace1d6d", + "e99b5c6365d3031b24aef5281c31da1f43d2eaa7", "testharness" ], "orientation-sensor/AbsoluteOrientationSensor.https.html": [ - "424d59b6e5bb3f479a0a00af351b2321e2c4607f", + "7c5adc63d2916f0d88ccff7f3fdb344f03aa0352", "testharness" ], "orientation-sensor/META.yml": [ @@ -466936,10 +466900,6 @@ "18d41cec9eef52effab445e6d695063e3a958a0a", "testharness" ], - "orientation-sensor/OrientationSensor_onerror-manual.https.html": [ - "415a63c1edf6fa6cee1d3fdc3726e6c974bee9e3", - "manual" - ], "orientation-sensor/RelativeOrientationSensor-disabled-by-feature-policy.https.html": [ "d97d40b6ca3c470e03009772889a07c0dfb935b9", "testharness" @@ -466973,11 +466933,11 @@ "support" ], "orientation-sensor/RelativeOrientationSensor-iframe-access.https.html": [ - "95b57647ddb1438628594fd578c0de17dcb0f1a3", + "5d30534841bfc45573a5720f411636533a37cb65", "testharness" ], "orientation-sensor/RelativeOrientationSensor.https.html": [ - "3fa618b26eb2d1a79287ea4a175f2c37bcda87c8", + "75983793cd8adbcca1b8b490e2d21d77684b37fb", "testharness" ], "orientation-sensor/idlharness.https.window.js": [ @@ -466985,7 +466945,7 @@ "testharness" ], "orientation-sensor/orientation-sensor-tests.js": [ - "d6754b3188908dda945354962d95d4d18094d2c4", + "fb6d83faa8bec709724777aa3fe5caaada5daf11", "support" ], "origin-policy/origin-policy-features.https.tentative.html": [ @@ -468572,6 +468532,10 @@ "0eae0ddfd6ef1e9de2251f50914a855f4142b9d5", "reftest" ], + "portals/portals-set-src-after-activate.html": [ + "8da6b341840162dc7348b95cfed060c075a75135", + "testharness" + ], "portals/references/portals-rendering.html": [ "4a8414ab5656593811772c3728e4ee83eb034457", "support" @@ -468676,6 +468640,10 @@ "92aef00380ae4a6180039ad0b10169c81a190441", "support" ], + "portals/resources/simple-portal-adopts-predecessor.html": [ + "b199bdd93b3a03437ebde7abaef9b14ac61b1f76", + "support" + ], "portals/resources/simple-portal.html": [ "29380099af1a3b9bf0990990ecefd8fa632d30c4", "support" @@ -480385,7 +480353,7 @@ "support" ], "resources/chromium/generic_sensor_mocks.js": [ - "531c3b8fe0542b280806b82658acc0ff888f6c5b", + "572c0deced61d04b113f025c3b8c23e4be544998", "support" ], "resources/chromium/generic_sensor_mocks.js.headers": [ @@ -494661,7 +494629,7 @@ "testharness" ], "trusted-types/default-policy-report-only.tentative.html": [ - "aa13e4252c4cbcd7c26d62e52b04e9dbe90773db", + "1170655c5f53088e6ff0815c98175af81f5bd1d2", "testharness" ], "trusted-types/default-policy-report-only.tentative.html.headers": [ @@ -494669,7 +494637,7 @@ "support" ], "trusted-types/default-policy.tentative.html": [ - "aa13e4252c4cbcd7c26d62e52b04e9dbe90773db", + "68e05c1305b0a55b73871cb3ab72f1b534a37c5e", "testharness" ], "trusted-types/default-policy.tentative.html.headers": [
diff --git a/third_party/blink/web_tests/external/wpt/accelerometer/Accelerometer-iframe-access.https.html b/third_party/blink/web_tests/external/wpt/accelerometer/Accelerometer-iframe-access.https.html index f5a79f07..bec17057 100644 --- a/third_party/blink/web_tests/external/wpt/accelerometer/Accelerometer-iframe-access.https.html +++ b/third_party/blink/web_tests/external/wpt/accelerometer/Accelerometer-iframe-access.https.html
@@ -6,7 +6,7 @@ <link rel="help" href="https://www.w3.org/TR/accelerometer/"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<script src="/generic-sensor/generic-sensor-tests.js"></script> +<script src="/generic-sensor/resources/generic-sensor-helpers.js"></script> <script src="/generic-sensor/generic-sensor-iframe-tests.sub.js"></script> <script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script> <div id="log"></div>
diff --git a/third_party/blink/web_tests/external/wpt/accelerometer/Accelerometer.https-expected.txt b/third_party/blink/web_tests/external/wpt/accelerometer/Accelerometer.https-expected.txt index 8597e2a..f974e469 100644 --- a/third_party/blink/web_tests/external/wpt/accelerometer/Accelerometer.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/accelerometer/Accelerometer.https-expected.txt
@@ -1,45 +1,70 @@ This is a testharness.js-based test. -PASS Accelerometer: Test that 'onreading' is called and sensor reading is valid -PASS Accelerometer: sensor reading is correct -PASS Accelerometer: sensor timestamp is updated when time passes +Found 66 tests; 44 PASS, 22 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS Accelerometer: Test that onerror is sent when sensor is not supported. +PASS Accelerometer: Test that onerror is sent when permissions are not granted. +PASS Accelerometer: Test that onerror is send when start() call has failed. +PASS Accelerometer: Test that frequency is capped to allowed maximum. +PASS Accelerometer: Test that frequency is capped to the maximum supported frequency. +PASS Accelerometer: Test that frequency is limited to the minimum supported frequency. +PASS Accelerometer: Test that sensor cannot be constructed within iframe disallowed to use feature policy. +PASS Accelerometer: Test that sensor can be constructed within an iframe allowed to use feature policy. +PASS Accelerometer: Test that 'onreading' is called and sensor reading is valid. +PASS Accelerometer: sensor reading is correct. +PASS Accelerometer: sensor timestamp is updated when time passes. PASS Accelerometer: Test that sensor can be successfully created and its states are correct. -PASS Accelerometer: sensor.start() returns undefined -PASS Accelerometer: no exception is thrown when calling start() on already started sensor -PASS Accelerometer: sensor.stop() returns undefined -PASS Accelerometer: no exception is thrown when calling stop() on already stopped sensor -PASS Accelerometer: Test that fresh reading is fetched on start() -PASS Accelerometer: frequency hint works -PASS Accelerometer: sensor receives suspend / resume notifications when cross-origin subframe is focused -PASS Accelerometer: throw 'TypeError' if frequency is invalid -PASS Accelerometer: sensor reading is correct when options.referenceFrame is 'screen' -PASS Accelerometer: throw 'TypeError' if referenceFrame is not one of enumeration values -FAIL GravitySensor: Test that 'onreading' is called and sensor reading is valid assert_true: expected true got false -FAIL GravitySensor: sensor reading is correct assert_true: expected true got false -FAIL GravitySensor: sensor timestamp is updated when time passes assert_true: expected true got false +PASS Accelerometer: sensor.start() returns undefined. +PASS Accelerometer: no exception is thrown when calling start() on already started sensor. +PASS Accelerometer: sensor.stop() returns undefined. +PASS Accelerometer: no exception is thrown when calling stop() on already stopped sensor. +PASS Accelerometer: Test that fresh reading is fetched on start(). +PASS Accelerometer: frequency hint works. +PASS Accelerometer: sensor receives suspend / resume notifications when cross-origin subframe is focused. +PASS Accelerometer: throw 'TypeError' if frequency is invalid. +PASS Accelerometer: sensor reading is correct when options.referenceFrame is 'screen'. +PASS Accelerometer: throw 'TypeError' if referenceFrame is not one of enumeration values. +FAIL GravitySensor: Test that onerror is sent when sensor is not supported. assert_true: expected true got false +FAIL GravitySensor: Test that onerror is sent when permissions are not granted. assert_true: expected true got false +FAIL GravitySensor: Test that onerror is send when start() call has failed. assert_true: expected true got false +FAIL GravitySensor: Test that frequency is capped to allowed maximum. assert_true: expected true got false +FAIL GravitySensor: Test that frequency is capped to the maximum supported frequency. assert_true: expected true got false +FAIL GravitySensor: Test that frequency is limited to the minimum supported frequency. assert_true: expected true got false +FAIL GravitySensor: Test that sensor cannot be constructed within iframe disallowed to use feature policy. assert_true: expected true got false +FAIL GravitySensor: Test that sensor can be constructed within an iframe allowed to use feature policy. assert_true: expected true got false +FAIL GravitySensor: Test that 'onreading' is called and sensor reading is valid. assert_true: expected true got false +FAIL GravitySensor: sensor reading is correct. assert_true: expected true got false +FAIL GravitySensor: sensor timestamp is updated when time passes. assert_true: expected true got false FAIL GravitySensor: Test that sensor can be successfully created and its states are correct. assert_true: expected true got false -FAIL GravitySensor: sensor.start() returns undefined assert_true: expected true got false -FAIL GravitySensor: no exception is thrown when calling start() on already started sensor assert_true: expected true got false -FAIL GravitySensor: sensor.stop() returns undefined assert_true: expected true got false -FAIL GravitySensor: no exception is thrown when calling stop() on already stopped sensor assert_true: expected true got false -FAIL GravitySensor: Test that fresh reading is fetched on start() assert_true: expected true got false -FAIL GravitySensor: frequency hint works assert_true: expected true got false -FAIL GravitySensor: sensor receives suspend / resume notifications when cross-origin subframe is focused assert_true: expected true got false -FAIL GravitySensor: throw 'TypeError' if frequency is invalid assert_true: expected true got false -FAIL GravitySensor: sensor reading is correct when options.referenceFrame is 'screen' assert_true: expected true got false -FAIL GravitySensor: throw 'TypeError' if referenceFrame is not one of enumeration values assert_true: expected true got false -PASS LinearAccelerationSensor: Test that 'onreading' is called and sensor reading is valid -PASS LinearAccelerationSensor: sensor reading is correct -PASS LinearAccelerationSensor: sensor timestamp is updated when time passes +FAIL GravitySensor: sensor.start() returns undefined. assert_true: expected true got false +FAIL GravitySensor: no exception is thrown when calling start() on already started sensor. assert_true: expected true got false +FAIL GravitySensor: sensor.stop() returns undefined. assert_true: expected true got false +FAIL GravitySensor: no exception is thrown when calling stop() on already stopped sensor. assert_true: expected true got false +FAIL GravitySensor: Test that fresh reading is fetched on start(). assert_true: expected true got false +FAIL GravitySensor: frequency hint works. assert_true: expected true got false +FAIL GravitySensor: sensor receives suspend / resume notifications when cross-origin subframe is focused. assert_true: expected true got false +FAIL GravitySensor: throw 'TypeError' if frequency is invalid. assert_true: expected true got false +FAIL GravitySensor: sensor reading is correct when options.referenceFrame is 'screen'. assert_true: expected true got false +FAIL GravitySensor: throw 'TypeError' if referenceFrame is not one of enumeration values. assert_true: expected true got false +PASS LinearAccelerationSensor: Test that onerror is sent when sensor is not supported. +PASS LinearAccelerationSensor: Test that onerror is sent when permissions are not granted. +PASS LinearAccelerationSensor: Test that onerror is send when start() call has failed. +PASS LinearAccelerationSensor: Test that frequency is capped to allowed maximum. +PASS LinearAccelerationSensor: Test that frequency is capped to the maximum supported frequency. +PASS LinearAccelerationSensor: Test that frequency is limited to the minimum supported frequency. +PASS LinearAccelerationSensor: Test that sensor cannot be constructed within iframe disallowed to use feature policy. +PASS LinearAccelerationSensor: Test that sensor can be constructed within an iframe allowed to use feature policy. +PASS LinearAccelerationSensor: Test that 'onreading' is called and sensor reading is valid. +PASS LinearAccelerationSensor: sensor reading is correct. +PASS LinearAccelerationSensor: sensor timestamp is updated when time passes. PASS LinearAccelerationSensor: Test that sensor can be successfully created and its states are correct. -PASS LinearAccelerationSensor: sensor.start() returns undefined -PASS LinearAccelerationSensor: no exception is thrown when calling start() on already started sensor -PASS LinearAccelerationSensor: sensor.stop() returns undefined -PASS LinearAccelerationSensor: no exception is thrown when calling stop() on already stopped sensor -PASS LinearAccelerationSensor: Test that fresh reading is fetched on start() -PASS LinearAccelerationSensor: frequency hint works -PASS LinearAccelerationSensor: sensor receives suspend / resume notifications when cross-origin subframe is focused -PASS LinearAccelerationSensor: throw 'TypeError' if frequency is invalid -PASS LinearAccelerationSensor: sensor reading is correct when options.referenceFrame is 'screen' -PASS LinearAccelerationSensor: throw 'TypeError' if referenceFrame is not one of enumeration values +PASS LinearAccelerationSensor: sensor.start() returns undefined. +PASS LinearAccelerationSensor: no exception is thrown when calling start() on already started sensor. +PASS LinearAccelerationSensor: sensor.stop() returns undefined. +PASS LinearAccelerationSensor: no exception is thrown when calling stop() on already stopped sensor. +PASS LinearAccelerationSensor: Test that fresh reading is fetched on start(). +PASS LinearAccelerationSensor: frequency hint works. +PASS LinearAccelerationSensor: sensor receives suspend / resume notifications when cross-origin subframe is focused. +PASS LinearAccelerationSensor: throw 'TypeError' if frequency is invalid. +PASS LinearAccelerationSensor: sensor reading is correct when options.referenceFrame is 'screen'. +PASS LinearAccelerationSensor: throw 'TypeError' if referenceFrame is not one of enumeration values. Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/accelerometer/Accelerometer.https.html b/third_party/blink/web_tests/external/wpt/accelerometer/Accelerometer.https.html index c68e9854..e8af039 100644 --- a/third_party/blink/web_tests/external/wpt/accelerometer/Accelerometer.https.html +++ b/third_party/blink/web_tests/external/wpt/accelerometer/Accelerometer.https.html
@@ -6,12 +6,40 @@ <link rel="help" href="https://www.w3.org/TR/accelerometer/"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="/generic-sensor/resources/generic-sensor-helpers.js"></script> <script src="/generic-sensor/generic-sensor-tests.js"></script> -<div id="log"></div> <script> -runGenericSensorTests('Accelerometer'); -runGenericSensorTests('GravitySensor'); -runGenericSensorTests('LinearAccelerationSensor'); +'use strict'; + +const kReadings = { + readings: [ + [1.12345, 2.12345, 3.12345] + ], + expectedReadings: [ + [1.12345, 2.12345, 3.12345] + ], + expectedRemappedReadings: [ + [-2.12345, 1.12345, 3.12345] + ] +}; + +runGenericSensorTests( + 'Accelerometer', + kReadings, + verifyXyzSensorReading, + ['accelerometer']); + +runGenericSensorTests( + 'GravitySensor', + kReadings, + verifyXyzSensorReading, + ['accelerometer']); + +runGenericSensorTests( + 'LinearAccelerationSensor', + kReadings, + verifyXyzSensorReading, + ['accelerometer']); </script>
diff --git a/third_party/blink/web_tests/external/wpt/accelerometer/Accelerometer_onerror-manual.https.html b/third_party/blink/web_tests/external/wpt/accelerometer/Accelerometer_onerror-manual.https.html deleted file mode 100644 index dec2188..0000000 --- a/third_party/blink/web_tests/external/wpt/accelerometer/Accelerometer_onerror-manual.https.html +++ /dev/null
@@ -1,22 +0,0 @@ -<!DOCTYPE html> -<meta charset="utf-8"> -<title>Accelerometer Test: onerror</title> -<link rel="author" title="Intel" href="http://www.intel.com"> -<link rel="help" href="https://www.w3.org/TR/accelerometer/"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/generic-sensor/generic-sensor-tests.js"></script> -<div id="log"></div> -<h2>Precondition</h2> -<ol> - <li> - Disable the Accelerometer Sensor or run test on a device without Accelerometer Sensor. - </li> -</ol> -<script> - -runGenericSensorOnerror('Accelerometer'); -runGenericSensorOnerror('GravitySensor'); -runGenericSensorOnerror('LinearAccelerationSensor'); - -</script>
diff --git a/third_party/blink/web_tests/external/wpt/accelerometer/LinearAccelerationSensor-shake-threshold-manual.https-expected.txt b/third_party/blink/web_tests/external/wpt/accelerometer/LinearAccelerationSensor-shake-threshold-manual.https-expected.txt new file mode 100644 index 0000000..6cc9b56e --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/accelerometer/LinearAccelerationSensor-shake-threshold-manual.https-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Test that when shaking gesture along x axis of the device, the shake threshold can be greater than 25 assert_unreached: NotAllowedError:Permissions to access sensor are not granted Reached unreachable code +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/ambient-light/AmbientLightSensor-iframe-access.https.html b/third_party/blink/web_tests/external/wpt/ambient-light/AmbientLightSensor-iframe-access.https.html index 9600843..5fedd5f 100644 --- a/third_party/blink/web_tests/external/wpt/ambient-light/AmbientLightSensor-iframe-access.https.html +++ b/third_party/blink/web_tests/external/wpt/ambient-light/AmbientLightSensor-iframe-access.https.html
@@ -5,7 +5,7 @@ <link rel="help" href="https://w3c.github.io/ambient-light/"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<script src="/generic-sensor/generic-sensor-tests.js"></script> +<script src="/generic-sensor/resources/generic-sensor-helpers.js"></script> <script src="/generic-sensor/generic-sensor-iframe-tests.sub.js"></script> <script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script> <div id="log"></div>
diff --git a/third_party/blink/web_tests/external/wpt/ambient-light/AmbientLightSensor.https.html b/third_party/blink/web_tests/external/wpt/ambient-light/AmbientLightSensor.https.html index 8fcc4c7c..2383a2d 100644 --- a/third_party/blink/web_tests/external/wpt/ambient-light/AmbientLightSensor.https.html +++ b/third_party/blink/web_tests/external/wpt/ambient-light/AmbientLightSensor.https.html
@@ -5,10 +5,25 @@ <link rel="help" href="https://www.w3.org/TR/ambient-light/"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="/generic-sensor/resources/generic-sensor-helpers.js"></script> <script src="/generic-sensor/generic-sensor-tests.js"></script> -<div id="log"></div> <script> -runGenericSensorTests('AmbientLightSensor'); +'use strict'; + +const kReadings = { + readings: [ + [3.1415] + ], + expectedReadings: [ + [3.1415] + ] +}; + +runGenericSensorTests( + 'AmbientLightSensor', + kReadings, + verifyAlsSensorReading, + ['ambient-light-sensor']); </script>
diff --git a/third_party/blink/web_tests/external/wpt/ambient-light/AmbientLightSensor_onerror-manual.https.html b/third_party/blink/web_tests/external/wpt/ambient-light/AmbientLightSensor_onerror-manual.https.html deleted file mode 100644 index 139e76f..0000000 --- a/third_party/blink/web_tests/external/wpt/ambient-light/AmbientLightSensor_onerror-manual.https.html +++ /dev/null
@@ -1,20 +0,0 @@ -<!DOCTYPE html> -<meta charset="utf-8"> -<title>AmbientLightSensor Test: onerror</title> -<link rel="author" title="Intel" href="http://www.intel.com"> -<link rel="help" href="https://www.w3.org/TR/ambient-light/"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/generic-sensor/generic-sensor-tests.js"></script> -<div id="log"></div> -<h2>Precondition</h2> -<ol> - <li> - Disable the Ambient Light Sensor or run test on a device without Amibent Light Sensor. - </li> -</ol> -<script> - -runGenericSensorOnerror('AmbientLightSensor'); - -</script>
diff --git a/third_party/blink/web_tests/external/wpt/common/security-features/resources/common.sub.js b/third_party/blink/web_tests/external/wpt/common/security-features/resources/common.sub.js index c7f94e80..64d2b9f 100644 --- a/third_party/blink/web_tests/external/wpt/common/security-features/resources/common.sub.js +++ b/third_party/blink/web_tests/external/wpt/common/security-features/resources/common.sub.js
@@ -968,9 +968,11 @@ // These values can evaluate to either empty strings or a ":port" string. const httpPort = getNormalizedPort(parseInt("{{ports[http][0]}}", 10)); - const httpsPort = getNormalizedPort(parseInt("{{ports[https][0]}}", 10)); + const httpsRawPort = parseInt("{{ports[https][0]}}", 10); + const httpsPort = getNormalizedPort(httpsRawPort); const wsPort = getNormalizedPort(parseInt("{{ports[ws][0]}}", 10)); - const wssPort = getNormalizedPort(parseInt("{{ports[wss][0]}}", 10)); + const wssRawPort = parseInt("{{ports[wss][0]}}", 10); + const wssPort = getNormalizedPort(wssRawPort); /** @typedef OriginType @@ -992,6 +994,22 @@ "same-ws": wsProtocol + "://" + sameOriginHost + wsPort, "cross-wss": wssProtocol + "://" + crossOriginHost + wssPort, "cross-ws": wsProtocol + "://" + crossOriginHost + wsPort, + + // The following origin types are used for upgrade-insecure-requests tests: + // These rely on some unintuitive cleverness due to WPT's test setup: + // 'Upgrade-Insecure-Requests' does not upgrade the port number, + // so we use URLs in the form `http://[domain]:[https-port]`, + // which will be upgraded to `https://[domain]:[https-port]`. + // If the upgrade fails, the load will fail, as we don't serve HTTP over + // the secure port. + "same-http-downgrade": + httpProtocol + "://" + sameOriginHost + ":" + httpsRawPort, + "cross-http-downgrade": + httpProtocol + "://" + crossOriginHost + ":" + httpsRawPort, + "same-ws-downgrade": + wsProtocol + "://" + sameOriginHost + ":" + wssRawPort, + "cross-ws-downgrade": + wsProtocol + "://" + crossOriginHost + ":" + wssRawPort, }; return originMap[originType];
diff --git a/third_party/blink/web_tests/external/wpt/common/security-features/subresource/subresource.py b/third_party/blink/web_tests/external/wpt/common/security-features/subresource/subresource.py index 850ca5e8..582378d 100644 --- a/third_party/blink/web_tests/external/wpt/common/security-features/subresource/subresource.py +++ b/third_party/blink/web_tests/external/wpt/common/security-features/subresource/subresource.py
@@ -32,10 +32,15 @@ # current request URL `request.url`, except for: # - When `swap_scheme` or `swap_origin` is True, its scheme/origin is changed # to the other one. (http <-> https, ws <-> wss, etc.) +# - For `downgrade`, we redirect to a URL that would be successfully loaded +# if and only if upgrade-insecure-request is applied. # - `query_parameter_to_remove` parameter is removed from query part. # Its default is "redirection" to avoid redirect loops. -def create_url(request, swap_scheme = False, swap_origin = False, - query_parameter_to_remove = "redirection"): +def create_url(request, + swap_scheme=False, + swap_origin=False, + downgrade=False, + query_parameter_to_remove="redirection"): parsed = urlparse.urlsplit(request.url) destination_netloc = parsed.netloc @@ -46,6 +51,24 @@ port = request.server.config["ports"][scheme][0] destination_netloc = ":".join([hostname, str(port)]) + if downgrade: + # These rely on some unintuitive cleverness due to WPT's test setup: + # 'Upgrade-Insecure-Requests' does not upgrade the port number, + # so we use URLs in the form `http://[domain]:[https-port]`, + # which will be upgraded to `https://[domain]:[https-port]`. + # If the upgrade fails, the load will fail, as we don't serve HTTP over + # the secure port. + if parsed.scheme == "https": + scheme = "http" + elif parsed.scheme == "wss": + scheme = "ws" + else: + raise ValueError("Downgrade redirection: Invalid scheme '%s'" % + parsed.scheme) + hostname = parsed.netloc.split(':')[0] + port = request.server.config["ports"][parsed.scheme][0] + destination_netloc = ":".join([hostname, str(port)]) + if swap_origin: destination_netloc = __get_swapped_origin_netloc(destination_netloc) @@ -75,6 +98,8 @@ redirect_url = create_url(request, swap_scheme=False) elif redirection == "swap-scheme": redirect_url = create_url(request, swap_scheme=True) + elif redirection == "downgrade": + redirect_url = create_url(request, downgrade=True) elif redirection == "keep-origin": redirect_url = create_url(request, swap_origin=False) elif redirection == "swap-origin":
diff --git a/third_party/blink/web_tests/external/wpt/common/security-features/tools/spec_validator.py b/third_party/blink/web_tests/external/wpt/common/security-features/tools/spec_validator.py index fff4c5dd..dae5c6e 100755 --- a/third_party/blink/web_tests/external/wpt/common/security-features/tools/spec_validator.py +++ b/third_party/blink/web_tests/external/wpt/common/security-features/tools/spec_validator.py
@@ -205,15 +205,20 @@ test_expansion_schema, 'source_context_list', spec_json['source_context_list_schema'].keys()) + # Should be consistent with `preprocess_redirection` in + # `/common/security-features/subresource/subresource.py`. assert_atom_or_list_items_from(test_expansion_schema, 'redirection', [ 'no-redirect', 'keep-origin', 'swap-origin', 'keep-scheme', - 'swap-scheme' + 'swap-scheme', 'downgrade' ]) for subresource in leaf_values(test_expansion_schema['subresource']): assert subresource in valid_subresource_names, "Invalid subresource %s" % subresource + # Should be consistent with getSubresourceOrigin() in + # `/common/security-features/resources/common.sub.js`. assert_atom_or_list_items_from(test_expansion_schema, 'origin', [ 'same-http', 'same-https', 'same-ws', 'same-wss', 'cross-http', - 'cross-https', 'cross-ws', 'cross-wss' + 'cross-https', 'cross-ws', 'cross-wss', 'same-http-downgrade', + 'cross-http-downgrade', 'same-ws-downgrade', 'cross-ws-downgrade' ]) # Validate excluded tests.
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/linebox/vertical-align-top-bottom-001.html b/third_party/blink/web_tests/external/wpt/css/CSS2/linebox/vertical-align-top-bottom-001.html index c08674d..2e03bc0 100644 --- a/third_party/blink/web_tests/external/wpt/css/CSS2/linebox/vertical-align-top-bottom-001.html +++ b/third_party/blink/web_tests/external/wpt/css/CSS2/linebox/vertical-align-top-bottom-001.html
@@ -3,6 +3,7 @@ <link rel="author" href="mailto:kojii@chromium.org"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> <style> section.test { display: inline-block; @@ -65,18 +66,22 @@ <div><div class="filler text-bottom"></div><div class="target" data-y="45"></div></div> </section> <script> -for (let target of document.getElementsByClassName('target')) { - let container = target.parentElement; - let filler = container.firstElementChild; - let section = container.parentElement; - let pass = false; - test(() => { - let y = target.offsetTop - container.offsetTop; - assert_approx_equals(y, target.dataset.y, 0); - pass = true; - }, `${section.className.substr(5)}+${filler.className.substr(7)}`); - if (!pass) - container.classList.add('fail'); -} +setup({explicit_done: true}); +document.fonts.ready.then(()=> { + for (let target of document.getElementsByClassName('target')) { + let container = target.parentElement; + let filler = container.firstElementChild; + let section = container.parentElement; + let pass = false; + test(() => { + let y = target.offsetTop - container.offsetTop; + assert_approx_equals(y, target.dataset.y, 0); + pass = true; + }, `${section.className.substr(5)}+${filler.className.substr(7)}`); + if (!pass) + container.classList.add('fail'); + } + done(); +}); </script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/fullscreen/rendering/fullscreen-css-transition.html b/third_party/blink/web_tests/external/wpt/fullscreen/rendering/fullscreen-css-transition.html index 1d50502..b494dc0 100644 --- a/third_party/blink/web_tests/external/wpt/fullscreen/rendering/fullscreen-css-transition.html +++ b/third_party/blink/web_tests/external/wpt/fullscreen/rendering/fullscreen-css-transition.html
@@ -17,11 +17,11 @@ assert_equals(document.fullscreenElement, trans); assert_equals(getComputedStyle(trans).color, "rgb(0, 128, 0)", "Transition is in progress - still green"); }); - trans.addEventListener('click', e => { + trans.addEventListener('click', t.step_func(() => { trans.style.color = "red"; trans.offsetTop; trans.requestFullscreen(); - }, {once: true}); + }), {once: true}); test_driver.click(trans); }); </script>
diff --git a/third_party/blink/web_tests/external/wpt/generic-sensor/README.md b/third_party/blink/web_tests/external/wpt/generic-sensor/README.md index 28227b0..250300b5 100644 --- a/third_party/blink/web_tests/external/wpt/generic-sensor/README.md +++ b/third_party/blink/web_tests/external/wpt/generic-sensor/README.md
@@ -1,11 +1,31 @@ -The `generic-sensor-tests.js` tests require an implementation of +The `resources/generic-sensor-helpers.js` tests require an implementation of the `GenericSensorTest` interface, which should emulate platform sensor backends. The `GenericSensorTest` interface is defined as: ``` + class MockSensor { + // Sets fake data that is used to deliver sensor reading updates. + async setSensorReading(FrozenArray<double> readingData); + setStartShouldFail(boolean shouldFail); // Sets flag that forces sensor to fail. + getSamplingFrequency(); // Return the sampling frequency. + }; + + class MockSensorProvider { + // Sets flag that forces mock SensorProvider to fail when getSensor() is + // invoked. + setGetSensorShouldFail(DOMString sensorType, boolean shouldFail); + // Sets flag that forces mock SensorProvider to permissions denied when + // getSensor() is invoked. + setPermissionsDenied(DOMString sensorType, boolean permissionsDenied); + getCreatedSensor(DOMString sensorType); // Return `MockSensor` interface. + setMaximumSupportedFrequency(double frequency); // Sets the maximum frequency. + setMinimumSupportedFrequency(double frequency); // Sets the minimum frequency. + } + class GenericSensorTest { - async initialize(); // Sets up the testing enviroment. + initialize(); // Sets up the testing environment. async reset(); // Frees the resources. + getSensorProvider(); // Returns `MockSensorProvider` interface. }; ```
diff --git a/third_party/blink/web_tests/external/wpt/generic-sensor/generic-sensor-tests.js b/third_party/blink/web_tests/external/wpt/generic-sensor/generic-sensor-tests.js index a48b4c5..1779fd6 100644 --- a/third_party/blink/web_tests/external/wpt/generic-sensor/generic-sensor-tests.js +++ b/third_party/blink/web_tests/external/wpt/generic-sensor/generic-sensor-tests.js
@@ -1,148 +1,250 @@ -// These tests rely on the User Agent providing an implementation of -// platform sensor backends. -// -// In Chromium-based browsers this implementation is provided by a polyfill -// in order to reduce the amount of test-only code shipped to users. To enable -// these tests the browser must be run with these options: -// -// --enable-blink-features=MojoJS,MojoJSTest -let loadChromiumResources = Promise.resolve().then(() => { - if (!window.MojoInterfaceInterceptor) { - // Do nothing on non-Chromium-based browsers or when the Mojo bindings are - // not present in the global namespace. - return; - } +'use strict'; - let chain = Promise.resolve(); - [ - '/resources/chromium/mojo_bindings.js', - '/resources/chromium/string16.mojom.js', - '/resources/chromium/sensor.mojom.js', - '/resources/chromium/sensor_provider.mojom.js', - '/resources/chromium/generic_sensor_mocks.js', - ].forEach(path => { - let script = document.createElement('script'); - script.src = path; - script.async = false; - chain = chain.then(() => new Promise(resolve => { - script.onload = resolve; - })); - document.head.appendChild(script); - }); +// Run a set of tests for a given |sensorName|. +// |readingData| is an object with 3 keys, all of which are arrays of arrays: +// 1. "readings". Each value corresponds to one raw reading that will be +// processed by a sensor. +// 2. "expectedReadings". Each value corresponds to the processed value a +// sensor will make available to users (i.e. a capped or rounded value). +// Its length must match |readings|'. +// 3. "expectedRemappedReadings" (optional). Similar to |expectedReadings|, but +// used only by spatial sensors, whose reference frame can change the values +// returned by a sensor. +// Its length should match |readings|'. +// |verificationFunction| is called to verify that a given reading matches a +// value in |expectedReadings|. +// |featurePolicies| represents |sensorName|'s associated sensor feature name. - return chain; -}); - -async function initialize_generic_sensor_tests() { - if (typeof GenericSensorTest === 'undefined') { - await loadChromiumResources; - } - assert_true( - typeof GenericSensorTest !== 'undefined', - 'Mojo testing interface is not available.' - ); - let sensorTest = new GenericSensorTest(); - await sensorTest.initialize(); - return sensorTest; -} - -function sensor_test(func, name, properties) { - promise_test(async (t) => { - let sensorTest = await initialize_generic_sensor_tests(); - try { - await func(t); - } finally { - await sensorTest.reset(); - }; - }, name, properties); -} - -const properties = { - 'AmbientLightSensor' : ['timestamp', 'illuminance'], - 'Accelerometer' : ['timestamp', 'x', 'y', 'z'], - 'LinearAccelerationSensor' : ['timestamp', 'x', 'y', 'z'], - "GravitySensor" : ['timestamp', 'x', 'y', 'z'], - 'Gyroscope' : ['timestamp', 'x', 'y', 'z'], - 'Magnetometer' : ['timestamp', 'x', 'y', 'z'], - "UncalibratedMagnetometer" : ['timestamp', 'x', 'y', 'z', - 'xBias', 'yBias', 'zBias'], - 'AbsoluteOrientationSensor' : ['timestamp', 'quaternion'], - 'RelativeOrientationSensor' : ['timestamp', 'quaternion'], - 'GeolocationSensor' : ['timestamp', 'latitude', 'longitude', 'altitude', - 'accuracy', 'altitudeAccuracy', 'heading', 'speed'], - 'ProximitySensor' : ['timestamp', 'max'] -}; -const spatialSensors = ['Accelerometer', - 'LinearAccelerationSensor', - 'GravitySensor', - 'Gyroscope', - 'Magnetometer', - 'UncalibratedMagnetometer', - 'AbsoluteOrientationSensor', - 'RelativeOrientationSensor']; - -function assert_reading_not_null(sensor) { - for (let property in properties[sensor.constructor.name]) { - let propertyName = properties[sensor.constructor.name][property]; - assert_not_equals(sensor[propertyName], null); - } -} - -function assert_reading_null(sensor) { - for (let property in properties[sensor.constructor.name]) { - let propertyName = properties[sensor.constructor.name][property]; - assert_equals(sensor[propertyName], null); - } -} - -function reading_to_array(sensor) { - const arr = new Array(); - for (let property in properties[sensor.constructor.name]) { - let propertyName = properties[sensor.constructor.name][property]; - arr[property] = sensor[propertyName]; - } - return arr; -} - -function runGenericSensorTests(sensorName) { +function runGenericSensorTests(sensorName, + readingData, + verificationFunction, + featurePolicies) { const sensorType = self[sensorName]; - sensor_test(async t => { + function validateReadingFormat(data) { + return Array.isArray(data) && data.every(element => Array.isArray(element)); + } + + const { readings, expectedReadings, expectedRemappedReadings } = readingData; + if (!validateReadingFormat(readings)) { + throw new TypeError('readingData.readings must be an array of arrays.'); + } + if (!validateReadingFormat(expectedReadings)) { + throw new TypeError('readingData.expectedReadings must be an array of ' + + 'arrays.'); + } + if (readings.length != expectedReadings.length) { + throw new TypeError('readingData.readings and ' + + 'readingData.expectedReadings must have the same ' + + 'length.'); + } + if (expectedRemappedReadings && + !validateReadingFormat(expectedRemappedReadings)) { + throw new TypeError('readingData.expectedRemappedReadings must be an ' + + 'array of arrays.'); + } + if (expectedRemappedReadings && + readings.length != expectedRemappedReadings.length) { + throw new TypeError('readingData.readings and ' + + 'readingData.expectedRemappedReadings must have the same ' + + 'length.'); + } + + sensor_test(async (t, sensorProvider) => { + assert_true(sensorName in self); + sensorProvider.setGetSensorShouldFail(sensorName, true); + const sensor = new sensorType; + const sensorWatcher = new EventWatcher(t, sensor, ["reading", "error"]); + sensor.start(); + + const event = await sensorWatcher.wait_for("error"); + + assert_false(sensor.activated); + assert_equals(event.error.name, 'NotReadableError'); + }, `${sensorName}: Test that onerror is sent when sensor is not supported.`); + + sensor_test(async (t, sensorProvider) => { + assert_true(sensorName in self); + sensorProvider.setPermissionsDenied(sensorName, true); + const sensor = new sensorType; + const sensorWatcher = new EventWatcher(t, sensor, ["reading", "error"]); + sensor.start(); + + const event = await sensorWatcher.wait_for("error"); + + assert_false(sensor.activated); + assert_equals(event.error.name, 'NotAllowedError'); + }, `${sensorName}: Test that onerror is sent when permissions are not\ + granted.`); + + sensor_test(async (t, sensorProvider) => { + assert_true(sensorName in self); + const sensor = new sensorType({frequency: 560}); + const sensorWatcher = new EventWatcher(t, sensor, ["reading", "error"]); + sensor.start(); + + const mockSensor = await sensorProvider.getCreatedSensor(sensorName); + mockSensor.setStartShouldFail(true); + + const event = await sensorWatcher.wait_for("error"); + + assert_false(sensor.activated); + assert_equals(event.error.name, 'NotReadableError'); + }, `${sensorName}: Test that onerror is send when start() call has failed.`); + + sensor_test(async (t, sensorProvider) => { + assert_true(sensorName in self); + const sensor = new sensorType({frequency: 560}); + const sensorWatcher = new EventWatcher(t, sensor, ["activate", "error"]); + sensor.start(); + + const mockSensor = await sensorProvider.getCreatedSensor(sensorName); + + await sensorWatcher.wait_for("activate"); + + assert_less_than_equal(mockSensor.getSamplingFrequency(), 60); + sensor.stop(); + assert_false(sensor.activated); + }, `${sensorName}: Test that frequency is capped to allowed maximum.`); + + sensor_test(async (t, sensorProvider) => { + assert_true(sensorName in self); + const maxSupportedFrequency = 5; + sensorProvider.setMaximumSupportedFrequency(maxSupportedFrequency); + const sensor = new sensorType({frequency: 50}); + const sensorWatcher = new EventWatcher(t, sensor, ["activate", "error"]); + sensor.start(); + + const mockSensor = await sensorProvider.getCreatedSensor(sensorName); + + await sensorWatcher.wait_for("activate"); + + assert_equals(mockSensor.getSamplingFrequency(), maxSupportedFrequency); + sensor.stop(); + assert_false(sensor.activated); + }, `${sensorName}: Test that frequency is capped to the maximum supported\ + frequency.`); + + sensor_test(async (t, sensorProvider) => { + assert_true(sensorName in self); + const minSupportedFrequency = 2; + sensorProvider.setMinimumSupportedFrequency(minSupportedFrequency); + const sensor = new sensorType({frequency: -1}); + const sensorWatcher = new EventWatcher(t, sensor, ["activate", "error"]); + sensor.start(); + + const mockSensor = await sensorProvider.getCreatedSensor(sensorName); + + await sensorWatcher.wait_for("activate"); + + assert_equals(mockSensor.getSamplingFrequency(), minSupportedFrequency); + sensor.stop(); + assert_false(sensor.activated); + }, `${sensorName}: Test that frequency is limited to the minimum supported\ + frequency.`); + + promise_test(async t => { + assert_true(sensorName in self); + const iframe = document.createElement('iframe'); + iframe.allow = featurePolicies.join(' \'none\'; ') + ' \'none\';'; + iframe.srcdoc = '<script>' + + ' window.onmessage = message => {' + + ' if (message.data === "LOADED") {' + + ' try {' + + ' new ' + sensorName + '();' + + ' parent.postMessage("FAIL", "*");' + + ' } catch (e) {' + + ' parent.postMessage("PASS", "*");' + + ' }' + + ' }' + + ' };' + + '<\/script>'; + const iframeWatcher = new EventWatcher(t, iframe, "load"); + document.body.appendChild(iframe); + await iframeWatcher.wait_for("load"); + iframe.contentWindow.postMessage('LOADED', '*'); + + const windowWatcher = new EventWatcher(t, window, "message"); + const message = await windowWatcher.wait_for("message"); + assert_equals(message.data, 'PASS'); + }, `${sensorName}: Test that sensor cannot be constructed within iframe\ + disallowed to use feature policy.`); + + promise_test(async t => { + assert_true(sensorName in self); + const iframe = document.createElement('iframe'); + iframe.allow = featurePolicies.join(';') + ';'; + iframe.srcdoc = '<script>' + + ' window.onmessage = message => {' + + ' if (message.data === "LOADED") {' + + ' try {' + + ' new ' + sensorName + '();' + + ' parent.postMessage("PASS", "*");' + + ' } catch (e) {' + + ' parent.postMessage("FAIL", "*");' + + ' }' + + ' }' + + ' };' + + '<\/script>'; + const iframeWatcher = new EventWatcher(t, iframe, "load"); + document.body.appendChild(iframe); + await iframeWatcher.wait_for("load"); + iframe.contentWindow.postMessage('LOADED', '*'); + + const windowWatcher = new EventWatcher(t, window, "message"); + const message = await windowWatcher.wait_for("message"); + assert_equals(message.data, 'PASS'); + }, `${sensorName}: Test that sensor can be constructed within an iframe\ + allowed to use feature policy.`); + + sensor_test(async (t, sensorProvider) => { assert_true(sensorName in self); const sensor = new sensorType(); const sensorWatcher = new EventWatcher(t, sensor, ["reading", "error"]); sensor.start(); + assert_false(sensor.hasReading); + + const mockSensor = await sensorProvider.getCreatedSensor(sensorName); + await mockSensor.setSensorReading(readings); await sensorWatcher.wait_for("reading"); - assert_reading_not_null(sensor); + const expected = new RingBuffer(expectedReadings).next().value; + assert_true(verificationFunction(expected, sensor)); assert_true(sensor.hasReading); sensor.stop(); - assert_reading_null(sensor); + assert_true(verificationFunction(expected, sensor, /*isNull=*/true)); assert_false(sensor.hasReading); - }, `${sensorName}: Test that 'onreading' is called and sensor reading is valid`); + }, `${sensorName}: Test that 'onreading' is called and sensor reading is\ + valid.`); - sensor_test(async t => { + sensor_test(async (t, sensorProvider) => { assert_true(sensorName in self); const sensor1 = new sensorType(); - const sensor2 = new sensorType(); const sensorWatcher = new EventWatcher(t, sensor1, ["reading", "error"]); - sensor2.start(); sensor1.start(); - await sensorWatcher.wait_for("reading"); - // Reading values are correct for both sensors. - assert_reading_not_null(sensor1); - assert_reading_not_null(sensor2); + const sensor2 = new sensorType(); + sensor2.start(); - //After first sensor stops its reading values are null, - //reading values for the second sensor remains + const mockSensor = await sensorProvider.getCreatedSensor(sensorName); + await mockSensor.setSensorReading(readings); + + await sensorWatcher.wait_for("reading"); + const expected = new RingBuffer(expectedReadings).next().value; + // Reading values are correct for both sensors. + assert_true(verificationFunction(expected, sensor1)); + assert_true(verificationFunction(expected, sensor2)); + + // After first sensor stops its reading values are null, + // reading values for the second sensor sensor remain. sensor1.stop(); - assert_reading_null(sensor1); - assert_reading_not_null(sensor2); + assert_true(verificationFunction(expected, sensor1, /*isNull=*/true)); + assert_true(verificationFunction(expected, sensor2)); + sensor2.stop(); - assert_reading_null(sensor2); - }, `${sensorName}: sensor reading is correct`); + assert_true(verificationFunction(expected, sensor2, /*isNull=*/true)); + }, `${sensorName}: sensor reading is correct.`); sensor_test(async t => { assert_true(sensorName in self); @@ -158,7 +260,7 @@ assert_greater_than(cachedTimeStamp2, cachedTimeStamp1); sensor.stop(); - }, `${sensorName}: sensor timestamp is updated when time passes`); + }, `${sensorName}: sensor timestamp is updated when time passes.`); sensor_test(async t => { assert_true(sensorName in self); @@ -173,7 +275,8 @@ sensor.stop(); assert_false(sensor.activated); - }, `${sensorName}: Test that sensor can be successfully created and its states are correct.`); + }, `${sensorName}: Test that sensor can be successfully created and its\ + states are correct.`); sensor_test(async t => { assert_true(sensorName in self); @@ -184,7 +287,7 @@ await sensorWatcher.wait_for("activate"); assert_equals(start_return, undefined); sensor.stop(); - }, `${sensorName}: sensor.start() returns undefined`); + }, `${sensorName}: sensor.start() returns undefined.`); sensor_test(async t => { assert_true(sensorName in self); @@ -196,7 +299,8 @@ await sensorWatcher.wait_for("activate"); assert_true(sensor.activated); sensor.stop(); - }, `${sensorName}: no exception is thrown when calling start() on already started sensor`); + }, `${sensorName}: no exception is thrown when calling start() on already\ + started sensor.`); sensor_test(async t => { assert_true(sensorName in self); @@ -207,7 +311,7 @@ await sensorWatcher.wait_for("activate"); const stop_return = sensor.stop(); assert_equals(stop_return, undefined); - }, `${sensorName}: sensor.stop() returns undefined`); + }, `${sensorName}: sensor.stop() returns undefined.`); sensor_test(async t => { assert_true(sensorName in self); @@ -219,16 +323,23 @@ sensor.stop(); sensor.stop(); assert_false(sensor.activated); - }, `${sensorName}: no exception is thrown when calling stop() on already stopped sensor`); + }, `${sensorName}: no exception is thrown when calling stop() on already\ + stopped sensor.`); - sensor_test(async t => { + sensor_test(async (t, sensorProvider) => { assert_true(sensorName in self); const sensor = new sensorType(); const sensorWatcher = new EventWatcher(t, sensor, ["reading", "error"]); sensor.start(); + const mockSensor = await sensorProvider.getCreatedSensor(sensorName); + await mockSensor.setSensorReading(readings); + + const expectedBuffer = new RingBuffer(expectedReadings); await sensorWatcher.wait_for("reading"); + const expected1 = expectedBuffer.next().value; assert_true(sensor.hasReading); + assert_true(verificationFunction(expected1, sensor)); const timestamp = sensor.timestamp; sensor.stop(); assert_false(sensor.hasReading); @@ -236,62 +347,84 @@ sensor.start(); await sensorWatcher.wait_for("reading"); assert_true(sensor.hasReading); + // |readingData| may have a single reading/expectation value, and this + // is the second reading we are getting. For that case, make sure we + // also wrap around as if we had the same RingBuffer used in + // generic_sensor_mocks.js. + const expected2 = expectedBuffer.next().value; + assert_true(verificationFunction(expected2, sensor)); + // Make sure that 'timestamp' is already initialized. assert_greater_than(timestamp, 0); + // Check that the reading is updated. assert_greater_than(sensor.timestamp, timestamp); sensor.stop(); - }, `${sensorName}: Test that fresh reading is fetched on start()`); + }, `${sensorName}: Test that fresh reading is fetched on start().`); // TBD file a WPT issue: visibilityChangeWatcher times out. -// sensor_test(async t => { +// sensor_test(async (t, sensorProvider) => { +// assert_true(sensorName in self); // const sensor = new sensorType(); // const sensorWatcher = new EventWatcher(t, sensor, ["reading", "error"]); -// const visibilityChangeWatcher = new EventWatcher(t, document, "visibilitychange"); +// const visibilityChangeWatcher = new EventWatcher(t, document, +// "visibilitychange"); // sensor.start(); +// const mockSensor = await sensorProvider.getCreatedSensor(sensorName); +// await mockSensor.setSensorReading(readings); + // await sensorWatcher.wait_for("reading"); -// assert_reading_not_null(sensor); -// const cachedSensor1 = reading_to_array(sensor); +// const expected = new RingBuffer(expectedReadings).next().value; +// assert_true(verificationFunction(expected, sensor)); +// const cachedTimestamp1 = sensor.timestamp; // const win = window.open('', '_blank'); // await visibilityChangeWatcher.wait_for("visibilitychange"); -// const cachedSensor2 = reading_to_array(sensor); +// const cachedTimestamp2 = sensor.timestamp; // win.close(); // sensor.stop(); -// assert_object_equals(cachedSensor1, cachedSensor2); -// }, `${sensorName}: sensor readings can not be fired on the background tab`); +// assert_equals(cachedTimestamp1, cachedTimestamp2); +// }, `${sensorName}: sensor readings can not be fired on the background tab.`); - sensor_test(async t => { + sensor_test(async (t, sensorProvider) => { assert_true(sensorName in self); - const fastSensor = new sensorType({frequency: 30}); - const slowSensor = new sensorType({frequency: 5}); - slowSensor.start(); + const fastSensor = new sensorType({frequency: 60}); + fastSensor.start(); + + const mockSensor = await sensorProvider.getCreatedSensor(sensorName); const fastCounter = await new Promise((resolve, reject) => { - let fastCounter = 0; - let slowCounter = 0; + let fastSensorNotifiedCounter = 0; + let slowSensorNotifiedCounter = 0; fastSensor.onreading = () => { - fastCounter++; - } - slowSensor.onreading = () => { - slowCounter++; - if (slowCounter == 1) { - fastSensor.start(); - } else if (slowCounter == 3) { - fastSensor.stop(); - slowSensor.stop(); - resolve(fastCounter); + if (fastSensorNotifiedCounter === 0) { + // For Magnetometer and ALS, the maximum frequency is less than 60Hz + // we make "slow" sensor 4 times slower than the actual applied + // frequency, so that the "fast" sensor will immediately overtake it + // despite the notification adjustments. + const slowFrequency = mockSensor.getSamplingFrequency() * 0.25; + const slowSensor = new sensorType({frequency: slowFrequency}); + slowSensor.onreading = () => { + // Skip the initial notification that always comes immediately. + if (slowSensorNotifiedCounter === 1) { + fastSensor.stop(); + slowSensor.stop(); + resolve(fastSensorNotifiedCounter); + } + slowSensorNotifiedCounter++; + } + slowSensor.onerror = reject; + slowSensor.start(); } + fastSensorNotifiedCounter++; } fastSensor.onerror = reject; - slowSensor.onerror = reject; }); - assert_greater_than(fastCounter, 2, - "Fast sensor overtakes the slow one"); - }, `${sensorName}: frequency hint works`); + assert_greater_than(fastCounter, 2, "Fast sensor overtakes the slow one"); + }, `${sensorName}: frequency hint works.`); - sensor_test(async t => { + sensor_test(async (t, sensorProvider) => { assert_true(sensorName in self); // Create a focused editbox inside a cross-origin iframe, // sensor notification must suspend. @@ -304,34 +437,40 @@ const sensorWatcher = new EventWatcher(t, sensor, ["reading", "error"]); sensor.start(); + const mockSensor = await sensorProvider.getCreatedSensor(sensorName); + await mockSensor.setSensorReading(readings); + await sensorWatcher.wait_for("reading"); - assert_reading_not_null(sensor); - const cachedTimestamp = sensor.timestamp; - const cachedSensor1 = reading_to_array(sensor); + const expected = new RingBuffer(expectedReadings).next().value; + assert_true(verificationFunction(expected, sensor)); + const cachedTimestamp1 = sensor.timestamp; const iframeWatcher = new EventWatcher(t, iframe, "load"); document.body.appendChild(iframe); await iframeWatcher.wait_for("load"); - const cachedSensor2 = reading_to_array(sensor); - assert_array_equals(cachedSensor1, cachedSensor2); + const cachedTimestamp2 = sensor.timestamp; + assert_equals(cachedTimestamp1, cachedTimestamp2); iframe.remove(); await sensorWatcher.wait_for("reading"); - const cachedSensor3 = reading_to_array(sensor); - assert_greater_than(sensor.timestamp, cachedTimestamp); + assert_greater_than(sensor.timestamp, cachedTimestamp1); sensor.stop(); }, `${sensorName}: sensor receives suspend / resume notifications when\ - cross-origin subframe is focused`); + cross-origin subframe is focused.`); // Re-enable after https://github.com/w3c/sensors/issues/361 is fixed. // test(() => { -// assert_throws("NotSupportedError", () => { new sensorType({invalid: 1}) }); -// assert_throws("NotSupportedError", () => { new sensorType({frequency: 60, invalid: 1}) }); -// if (spatialSensors.indexOf(sensorName) == -1) { -// assert_throws("NotSupportedError", () => { new sensorType({referenceFrame: "screen"}) }); +// assert_throws("NotSupportedError", +// () => { new sensorType({invalid: 1}) }); +// assert_throws("NotSupportedError", +// () => { new sensorType({frequency: 60, invalid: 1}) }); +// if (!expectedRemappedReadings) { +// assert_throws("NotSupportedError", +// () => { new sensorType({referenceFrame: "screen"}) }); // } -// }, `${sensorName}: throw 'NotSupportedError' for an unsupported sensor option`); +// }, `${sensorName}: throw 'NotSupportedError' for an unsupported sensor\ +// option.`); test(() => { assert_true(sensorName in self); @@ -347,26 +486,42 @@ () => { new sensorType({frequency: freq}) }, `when freq is ${freq}`); }); - }, `${sensorName}: throw 'TypeError' if frequency is invalid`); + }, `${sensorName}: throw 'TypeError' if frequency is invalid.`); - if (spatialSensors.indexOf(sensorName) == -1) { + if (!expectedRemappedReadings) { // The sensorType does not represent a spatial sensor. return; } - sensor_test(async t => { + sensor_test(async (t, sensorProvider) => { assert_true(sensorName in self); - const sensor = new sensorType({referenceFrame: "screen"}); - const sensorWatcher = new EventWatcher(t, sensor, ["reading", "error"]); - sensor.start(); + const sensor1 = new sensorType({frequency: 60}); + const sensor2 = new sensorType({frequency: 60, referenceFrame: "screen"}); + const sensorWatcher = new EventWatcher(t, sensor1, ["reading", "error"]); + + sensor1.start(); + sensor2.start(); + + const mockSensor = await sensorProvider.getCreatedSensor(sensorName); + await mockSensor.setSensorReading(readings); await sensorWatcher.wait_for("reading"); - //TODO use mock data to verify sensor readings, blocked by issue: - // https://github.com/web-platform-tests/wpt/issues/9686 - assert_reading_not_null(sensor); - sensor.stop(); - }, `${sensorName}: sensor reading is correct when options.referenceFrame is 'screen'`); + const expected = new RingBuffer(expectedReadings).next().value; + const expectedRemapped = + new RingBuffer(expectedRemappedReadings).next().value; + assert_true(verificationFunction(expected, sensor1)); + assert_true(verificationFunction(expectedRemapped, sensor2)); + + sensor1.stop(); + assert_true(verificationFunction(expected, sensor1, /*isNull=*/true)); + assert_true(verificationFunction(expectedRemapped, sensor2)); + + sensor2.stop(); + assert_true(verificationFunction(expectedRemapped, sensor2, + /*isNull=*/true)); + }, `${sensorName}: sensor reading is correct when options.referenceFrame\ + is 'screen'.`); test(() => { assert_true(sensorName in self); @@ -383,27 +538,12 @@ () => { new sensorType({referenceFrame: refFrame}) }, `when refFrame is ${refFrame}`); }); - }, `${sensorName}: throw 'TypeError' if referenceFrame is not one of enumeration values`); + }, `${sensorName}: throw 'TypeError' if referenceFrame is not one of\ + enumeration values.`); } function runGenericSensorInsecureContext(sensorName) { test(() => { assert_false(sensorName in window, `${sensorName} must not be exposed`); - }, `${sensorName} is not exposed in an insecure context`); -} - -function runGenericSensorOnerror(sensorName) { - const sensorType = self[sensorName]; - - promise_test(async t => { - assert_true(sensorName in self); - const sensor = new sensorType(); - const sensorWatcher = new EventWatcher(t, sensor, ["error", "activate"]); - sensor.start(); - - const event = await sensorWatcher.wait_for("error"); - assert_false(sensor.activated); - assert_true(event.error.name == 'NotReadableError' || - event.error.name == 'NotAllowedError'); - }, `${sensorName}: 'onerror' event is fired when sensor is not supported`); + }, `${sensorName} is not exposed in an insecure context.`); }
diff --git a/third_party/blink/web_tests/external/wpt/generic-sensor/resources/generic-sensor-helpers.js b/third_party/blink/web_tests/external/wpt/generic-sensor/resources/generic-sensor-helpers.js new file mode 100644 index 0000000..8302f6f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/generic-sensor/resources/generic-sensor-helpers.js
@@ -0,0 +1,119 @@ +'use strict'; + +// These tests rely on the User Agent providing an implementation of +// platform sensor backends. +// +// In Chromium-based browsers this implementation is provided by a polyfill +// in order to reduce the amount of test-only code shipped to users. To enable +// these tests the browser must be run with these options: +// +// --enable-blink-features=MojoJS,MojoJSTest +const loadChromiumResources = async () => { + if (!('MojoInterfaceInterceptor' in self)) { + // Do nothing on non-Chromium-based browsers or when the Mojo bindings are + // not present in the global namespace. + return; + } + + const resources = [ + '/gen/layout_test_data/mojo/public/js/mojo_bindings.js', + '/gen/mojo/public/mojom/base/string16.mojom.js', + '/gen/services/device/public/mojom/sensor.mojom.js', + '/gen/services/device/public/mojom/sensor_provider.mojom.js', + '/resources/chromium/generic_sensor_mocks.js', + ]; + + await Promise.all(resources.map(path => { + const script = document.createElement('script'); + script.src = path; + script.async = false; + const promise = new Promise((resolve, reject) => { + script.onload = resolve; + script.onerror = reject; + }); + document.head.appendChild(script); + return promise; + })); +}; + +async function initialize_generic_sensor_tests() { + if (typeof GenericSensorTest === 'undefined') { + await loadChromiumResources(); + } + assert_true( + typeof GenericSensorTest !== 'undefined', + 'Mojo testing interface is not available.' + ); + let sensorTest = new GenericSensorTest(); + await sensorTest.initialize(); + return sensorTest; +} + +function sensor_test(func, name, properties) { + promise_test(async (t) => { + let sensorTest = await initialize_generic_sensor_tests(); + try { + await func(t, sensorTest.getSensorProvider()); + } finally { + await sensorTest.reset(); + }; + }, name, properties); +} + +function verifySensorReading(pattern, values, timestamp, isNull) { + function round(val) { + return Number.parseFloat(val).toPrecision(6); + } + + if (isNull) { + return (values === null || values.every(r => r === null)) && + timestamp === null; + } + + return values.every((r, i) => round(r) === round(pattern[i])) && + timestamp !== null; +} + +function verifyXyzSensorReading(pattern, {x, y, z, timestamp}, isNull) { + return verifySensorReading(pattern, [x, y, z], timestamp, isNull); +} + +function verifyQuatSensorReading(pattern, {quaternion, timestamp}, isNull) { + return verifySensorReading(pattern, quaternion, timestamp, isNull); +} + +function verifyAlsSensorReading(pattern, {illuminance, timestamp}, isNull) { + return verifySensorReading(pattern, [illuminance], timestamp, isNull); +} + +function verifyGeoSensorReading(pattern, {latitude, longitude, altitude, + accuracy, altitudeAccuracy, heading, speed, timestamp}, isNull) { + return verifySensorReading(pattern, [latitude, longitude, altitude, + accuracy, altitudeAccuracy, heading, speed], timestamp, isNull); +} + +// A "sliding window" that iterates over |data| and returns one item at a +// time, advancing and wrapping around as needed. |data| must be an array of +// arrays. +class RingBuffer { + constructor(data) { + this.bufferPosition_ = 0; + // Validate |data|'s format and deep-copy every element. + this.data_ = Array.from(data, element => { + if (!Array.isArray(element)) { + throw new TypeError('Every |data| element must be an array.'); + } + return Array.from(element); + }) + } + + next() { + const value = this.data_[this.bufferPosition_]; + this.bufferPosition_ = (this.bufferPosition_ + 1) % this.data_.length; + return { done: false, value: value }; + } + + [Symbol.iterator]() { + return this; + } +}
diff --git a/third_party/blink/web_tests/external/wpt/generic-sensor/resources/iframe_sensor_handler.html b/third_party/blink/web_tests/external/wpt/generic-sensor/resources/iframe_sensor_handler.html index 12ab1d4..ec594ab 100644 --- a/third_party/blink/web_tests/external/wpt/generic-sensor/resources/iframe_sensor_handler.html +++ b/third_party/blink/web_tests/external/wpt/generic-sensor/resources/iframe_sensor_handler.html
@@ -2,7 +2,7 @@ <meta charset="utf-8"> <title>iframe sensor tester</title> <script src="/resources/testharness.js"></script> -<script src="/generic-sensor/generic-sensor-tests.js"></script> +<script src="/generic-sensor/resources/generic-sensor-helpers.js"></script> <script> let mockBackend = null; // Minimum frequency supported by the mock backend is 5Hz. Using 200ms @@ -60,4 +60,4 @@ }); } } -</script> \ No newline at end of file +</script>
diff --git a/third_party/blink/web_tests/external/wpt/geolocation-sensor/GeolocationSensor-iframe-access.https.html b/third_party/blink/web_tests/external/wpt/geolocation-sensor/GeolocationSensor-iframe-access.https.html index 68a9902..bb0541d 100644 --- a/third_party/blink/web_tests/external/wpt/geolocation-sensor/GeolocationSensor-iframe-access.https.html +++ b/third_party/blink/web_tests/external/wpt/geolocation-sensor/GeolocationSensor-iframe-access.https.html
@@ -5,7 +5,7 @@ <link rel="help" href="https://wicg.github.io/geolocation-sensor/"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<script src="/generic-sensor/generic-sensor-tests.js"></script> +<script src="/generic-sensor/resources/generic-sensor-helpers.js"></script> <script src="/generic-sensor/generic-sensor-iframe-tests.sub.js"></script> <script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script> <div id="log"></div>
diff --git a/third_party/blink/web_tests/external/wpt/geolocation-sensor/GeolocationSensor.https-expected.txt b/third_party/blink/web_tests/external/wpt/geolocation-sensor/GeolocationSensor.https-expected.txt index 88659b6..aa70d5a 100644 --- a/third_party/blink/web_tests/external/wpt/geolocation-sensor/GeolocationSensor.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/geolocation-sensor/GeolocationSensor.https-expected.txt
@@ -1,15 +1,23 @@ This is a testharness.js-based test. -FAIL GeolocationSensor: Test that 'onreading' is called and sensor reading is valid assert_true: expected true got false -FAIL GeolocationSensor: sensor reading is correct assert_true: expected true got false -FAIL GeolocationSensor: sensor timestamp is updated when time passes assert_true: expected true got false +FAIL GeolocationSensor: Test that onerror is sent when sensor is not supported. assert_true: expected true got false +FAIL GeolocationSensor: Test that onerror is sent when permissions are not granted. assert_true: expected true got false +FAIL GeolocationSensor: Test that onerror is send when start() call has failed. assert_true: expected true got false +FAIL GeolocationSensor: Test that frequency is capped to allowed maximum. assert_true: expected true got false +FAIL GeolocationSensor: Test that frequency is capped to the maximum supported frequency. assert_true: expected true got false +FAIL GeolocationSensor: Test that frequency is limited to the minimum supported frequency. assert_true: expected true got false +FAIL GeolocationSensor: Test that sensor cannot be constructed within iframe disallowed to use feature policy. assert_true: expected true got false +FAIL GeolocationSensor: Test that sensor can be constructed within an iframe allowed to use feature policy. assert_true: expected true got false +FAIL GeolocationSensor: Test that 'onreading' is called and sensor reading is valid. assert_true: expected true got false +FAIL GeolocationSensor: sensor reading is correct. assert_true: expected true got false +FAIL GeolocationSensor: sensor timestamp is updated when time passes. assert_true: expected true got false FAIL GeolocationSensor: Test that sensor can be successfully created and its states are correct. assert_true: expected true got false -FAIL GeolocationSensor: sensor.start() returns undefined assert_true: expected true got false -FAIL GeolocationSensor: no exception is thrown when calling start() on already started sensor assert_true: expected true got false -FAIL GeolocationSensor: sensor.stop() returns undefined assert_true: expected true got false -FAIL GeolocationSensor: no exception is thrown when calling stop() on already stopped sensor assert_true: expected true got false -FAIL GeolocationSensor: Test that fresh reading is fetched on start() assert_true: expected true got false -FAIL GeolocationSensor: frequency hint works assert_true: expected true got false -FAIL GeolocationSensor: sensor receives suspend / resume notifications when cross-origin subframe is focused assert_true: expected true got false -FAIL GeolocationSensor: throw 'TypeError' if frequency is invalid assert_true: expected true got false +FAIL GeolocationSensor: sensor.start() returns undefined. assert_true: expected true got false +FAIL GeolocationSensor: no exception is thrown when calling start() on already started sensor. assert_true: expected true got false +FAIL GeolocationSensor: sensor.stop() returns undefined. assert_true: expected true got false +FAIL GeolocationSensor: no exception is thrown when calling stop() on already stopped sensor. assert_true: expected true got false +FAIL GeolocationSensor: Test that fresh reading is fetched on start(). assert_true: expected true got false +FAIL GeolocationSensor: frequency hint works. assert_true: expected true got false +FAIL GeolocationSensor: sensor receives suspend / resume notifications when cross-origin subframe is focused. assert_true: expected true got false +FAIL GeolocationSensor: throw 'TypeError' if frequency is invalid. assert_true: expected true got false Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/geolocation-sensor/GeolocationSensor.https.html b/third_party/blink/web_tests/external/wpt/geolocation-sensor/GeolocationSensor.https.html index ef19843..b71f964 100644 --- a/third_party/blink/web_tests/external/wpt/geolocation-sensor/GeolocationSensor.https.html +++ b/third_party/blink/web_tests/external/wpt/geolocation-sensor/GeolocationSensor.https.html
@@ -5,9 +5,25 @@ <link rel="help" href="https://wicg.github.io/geolocation-sensor/"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="/generic-sensor/resources/generic-sensor-helpers.js"></script> <script src="/generic-sensor/generic-sensor-tests.js"></script> <script> -runGenericSensorTests('GeolocationSensor'); +'use strict'; + +const kReadings = { + readings: [ + [1.12345, 2.12345, 3.12345, 0.95, 0.96, 4.12345, 5.123] + ], + expectedReadings: [ + [1.12345, 2.12345, 3.12345, 0.95, 0.96, 4.12345, 5.123] + ] +}; + +runGenericSensorTests( + 'GeolocationSensor', + kReadings, + verifyXyzSensorReading, + ['geolocation']); </script>
diff --git a/third_party/blink/web_tests/external/wpt/geolocation-sensor/GeolocationSensor_onerror-manual.https.html b/third_party/blink/web_tests/external/wpt/geolocation-sensor/GeolocationSensor_onerror-manual.https.html deleted file mode 100644 index 2e6d45f2..0000000 --- a/third_party/blink/web_tests/external/wpt/geolocation-sensor/GeolocationSensor_onerror-manual.https.html +++ /dev/null
@@ -1,19 +0,0 @@ -<!DOCTYPE html> -<meta charset="utf-8"> -<title>GeolocationSensor Test: onerror</title> -<link rel="author" title="Intel" href="http://www.intel.com"> -<link rel="help" href="https://wicg.github.io/geolocation-sensor/"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/generic-sensor/generic-sensor-tests.js"></script> -<h2>Precondition</h2> -<ol> - <li> - Disable the Geolocation sensor or run test on a device without Geolocation sensor. - </li> -</ol> -<script> - -runGenericSensorOnerror('GeolocationSensor'); - -</script>
diff --git a/third_party/blink/web_tests/external/wpt/gyroscope/Gyroscope-iframe-access.https.html b/third_party/blink/web_tests/external/wpt/gyroscope/Gyroscope-iframe-access.https.html index 02edf4bd..ed0183b 100644 --- a/third_party/blink/web_tests/external/wpt/gyroscope/Gyroscope-iframe-access.https.html +++ b/third_party/blink/web_tests/external/wpt/gyroscope/Gyroscope-iframe-access.https.html
@@ -5,7 +5,7 @@ <link rel="help" href="https://www.w3.org/TR/gyroscope/"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<script src="/generic-sensor/generic-sensor-tests.js"></script> +<script src="/generic-sensor/resources/generic-sensor-helpers.js"></script> <script src="/generic-sensor/generic-sensor-iframe-tests.sub.js"></script> <script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script> <div id="log"></div>
diff --git a/third_party/blink/web_tests/external/wpt/gyroscope/Gyroscope.https.html b/third_party/blink/web_tests/external/wpt/gyroscope/Gyroscope.https.html index f4ae28a..f85349f5 100644 --- a/third_party/blink/web_tests/external/wpt/gyroscope/Gyroscope.https.html +++ b/third_party/blink/web_tests/external/wpt/gyroscope/Gyroscope.https.html
@@ -6,10 +6,28 @@ <link rel="help" href="https://www.w3.org/TR/gyroscope/"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="/generic-sensor/resources/generic-sensor-helpers.js"></script> <script src="/generic-sensor/generic-sensor-tests.js"></script> -<div id="log"></div> <script> -runGenericSensorTests('Gyroscope'); +'use strict'; + +const kReadings = { + readings: [ + [1.12345, 2.12345, 3.12345] + ], + expectedReadings: [ + [1.12345, 2.12345, 3.12345] + ], + expectedRemappedReadings: [ + [-2.12345, 1.12345, 3.12345] + ] +}; + +runGenericSensorTests( + 'Gyroscope', + kReadings, + verifyXyzSensorReading, + ['gyroscope']); </script>
diff --git a/third_party/blink/web_tests/external/wpt/gyroscope/Gyroscope_onerror-manual.https.html b/third_party/blink/web_tests/external/wpt/gyroscope/Gyroscope_onerror-manual.https.html deleted file mode 100644 index b63448b..0000000 --- a/third_party/blink/web_tests/external/wpt/gyroscope/Gyroscope_onerror-manual.https.html +++ /dev/null
@@ -1,20 +0,0 @@ -<!DOCTYPE html> -<meta charset="utf-8"> -<title>Gyroscope Test: onerror</title> -<link rel="author" title="Intel" href="http://www.intel.com"> -<link rel="help" href="https://www.w3.org/TR/gyroscope/"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/generic-sensor/generic-sensor-tests.js"></script> -<div id="log"></div> -<h2>Precondition</h2> -<ol> - <li> - Disable the Gyroscope Sensor or run test on a device without Gyroscope Sensor. - </li> -</ol> -<script> - -runGenericSensorOnerror('Gyroscope'); - -</script>
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/wasm-js-api.idl b/third_party/blink/web_tests/external/wpt/interfaces/wasm-js-api.idl index 62bc0b7..8287290 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/wasm-js-api.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/wasm-js-api.idl
@@ -99,12 +99,3 @@ any valueOf(); attribute any value; }; - -[LegacyNamespace=WebAssembly] -interface CompileError { }; - -[LegacyNamespace=WebAssembly] -interface LinkError { }; - -[LegacyNamespace=WebAssembly] -interface RuntimeError { };
diff --git a/third_party/blink/web_tests/external/wpt/magnetometer/Magnetometer-iframe-access.https.html b/third_party/blink/web_tests/external/wpt/magnetometer/Magnetometer-iframe-access.https.html index 04c9800..3dc90e3 100644 --- a/third_party/blink/web_tests/external/wpt/magnetometer/Magnetometer-iframe-access.https.html +++ b/third_party/blink/web_tests/external/wpt/magnetometer/Magnetometer-iframe-access.https.html
@@ -5,7 +5,7 @@ <link rel="help" href="https://www.w3.org/TR/magnetometer/"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<script src="/generic-sensor/generic-sensor-tests.js"></script> +<script src="/generic-sensor/resources/generic-sensor-helpers.js"></script> <script src="/generic-sensor/generic-sensor-iframe-tests.sub.js"></script> <script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script> <div id="log"></div>
diff --git a/third_party/blink/web_tests/external/wpt/magnetometer/Magnetometer.https-expected.txt b/third_party/blink/web_tests/external/wpt/magnetometer/Magnetometer.https-expected.txt index 2a48ea4..f918d3a 100644 --- a/third_party/blink/web_tests/external/wpt/magnetometer/Magnetometer.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/magnetometer/Magnetometer.https-expected.txt
@@ -1,31 +1,47 @@ This is a testharness.js-based test. -PASS Magnetometer: Test that 'onreading' is called and sensor reading is valid -PASS Magnetometer: sensor reading is correct -PASS Magnetometer: sensor timestamp is updated when time passes +PASS Magnetometer: Test that onerror is sent when sensor is not supported. +PASS Magnetometer: Test that onerror is sent when permissions are not granted. +PASS Magnetometer: Test that onerror is send when start() call has failed. +PASS Magnetometer: Test that frequency is capped to allowed maximum. +PASS Magnetometer: Test that frequency is capped to the maximum supported frequency. +PASS Magnetometer: Test that frequency is limited to the minimum supported frequency. +PASS Magnetometer: Test that sensor cannot be constructed within iframe disallowed to use feature policy. +PASS Magnetometer: Test that sensor can be constructed within an iframe allowed to use feature policy. +PASS Magnetometer: Test that 'onreading' is called and sensor reading is valid. +PASS Magnetometer: sensor reading is correct. +PASS Magnetometer: sensor timestamp is updated when time passes. PASS Magnetometer: Test that sensor can be successfully created and its states are correct. -PASS Magnetometer: sensor.start() returns undefined -PASS Magnetometer: no exception is thrown when calling start() on already started sensor -PASS Magnetometer: sensor.stop() returns undefined -PASS Magnetometer: no exception is thrown when calling stop() on already stopped sensor -PASS Magnetometer: Test that fresh reading is fetched on start() -PASS Magnetometer: frequency hint works -PASS Magnetometer: sensor receives suspend / resume notifications when cross-origin subframe is focused -PASS Magnetometer: throw 'TypeError' if frequency is invalid -PASS Magnetometer: sensor reading is correct when options.referenceFrame is 'screen' -PASS Magnetometer: throw 'TypeError' if referenceFrame is not one of enumeration values -FAIL UncalibratedMagnetometer: Test that 'onreading' is called and sensor reading is valid assert_true: expected true got false -FAIL UncalibratedMagnetometer: sensor reading is correct assert_true: expected true got false -FAIL UncalibratedMagnetometer: sensor timestamp is updated when time passes assert_true: expected true got false +PASS Magnetometer: sensor.start() returns undefined. +PASS Magnetometer: no exception is thrown when calling start() on already started sensor. +PASS Magnetometer: sensor.stop() returns undefined. +PASS Magnetometer: no exception is thrown when calling stop() on already stopped sensor. +PASS Magnetometer: Test that fresh reading is fetched on start(). +PASS Magnetometer: frequency hint works. +PASS Magnetometer: sensor receives suspend / resume notifications when cross-origin subframe is focused. +PASS Magnetometer: throw 'TypeError' if frequency is invalid. +PASS Magnetometer: sensor reading is correct when options.referenceFrame is 'screen'. +PASS Magnetometer: throw 'TypeError' if referenceFrame is not one of enumeration values. +FAIL UncalibratedMagnetometer: Test that onerror is sent when sensor is not supported. assert_true: expected true got false +FAIL UncalibratedMagnetometer: Test that onerror is sent when permissions are not granted. assert_true: expected true got false +FAIL UncalibratedMagnetometer: Test that onerror is send when start() call has failed. assert_true: expected true got false +FAIL UncalibratedMagnetometer: Test that frequency is capped to allowed maximum. assert_true: expected true got false +FAIL UncalibratedMagnetometer: Test that frequency is capped to the maximum supported frequency. assert_true: expected true got false +FAIL UncalibratedMagnetometer: Test that frequency is limited to the minimum supported frequency. assert_true: expected true got false +FAIL UncalibratedMagnetometer: Test that sensor cannot be constructed within iframe disallowed to use feature policy. assert_true: expected true got false +FAIL UncalibratedMagnetometer: Test that sensor can be constructed within an iframe allowed to use feature policy. assert_true: expected true got false +FAIL UncalibratedMagnetometer: Test that 'onreading' is called and sensor reading is valid. assert_true: expected true got false +FAIL UncalibratedMagnetometer: sensor reading is correct. assert_true: expected true got false +FAIL UncalibratedMagnetometer: sensor timestamp is updated when time passes. assert_true: expected true got false FAIL UncalibratedMagnetometer: Test that sensor can be successfully created and its states are correct. assert_true: expected true got false -FAIL UncalibratedMagnetometer: sensor.start() returns undefined assert_true: expected true got false -FAIL UncalibratedMagnetometer: no exception is thrown when calling start() on already started sensor assert_true: expected true got false -FAIL UncalibratedMagnetometer: sensor.stop() returns undefined assert_true: expected true got false -FAIL UncalibratedMagnetometer: no exception is thrown when calling stop() on already stopped sensor assert_true: expected true got false -FAIL UncalibratedMagnetometer: Test that fresh reading is fetched on start() assert_true: expected true got false -FAIL UncalibratedMagnetometer: frequency hint works assert_true: expected true got false -FAIL UncalibratedMagnetometer: sensor receives suspend / resume notifications when cross-origin subframe is focused assert_true: expected true got false -FAIL UncalibratedMagnetometer: throw 'TypeError' if frequency is invalid assert_true: expected true got false -FAIL UncalibratedMagnetometer: sensor reading is correct when options.referenceFrame is 'screen' assert_true: expected true got false -FAIL UncalibratedMagnetometer: throw 'TypeError' if referenceFrame is not one of enumeration values assert_true: expected true got false +FAIL UncalibratedMagnetometer: sensor.start() returns undefined. assert_true: expected true got false +FAIL UncalibratedMagnetometer: no exception is thrown when calling start() on already started sensor. assert_true: expected true got false +FAIL UncalibratedMagnetometer: sensor.stop() returns undefined. assert_true: expected true got false +FAIL UncalibratedMagnetometer: no exception is thrown when calling stop() on already stopped sensor. assert_true: expected true got false +FAIL UncalibratedMagnetometer: Test that fresh reading is fetched on start(). assert_true: expected true got false +FAIL UncalibratedMagnetometer: frequency hint works. assert_true: expected true got false +FAIL UncalibratedMagnetometer: sensor receives suspend / resume notifications when cross-origin subframe is focused. assert_true: expected true got false +FAIL UncalibratedMagnetometer: throw 'TypeError' if frequency is invalid. assert_true: expected true got false +FAIL UncalibratedMagnetometer: sensor reading is correct when options.referenceFrame is 'screen'. assert_true: expected true got false +FAIL UncalibratedMagnetometer: throw 'TypeError' if referenceFrame is not one of enumeration values. assert_true: expected true got false Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/magnetometer/Magnetometer.https.html b/third_party/blink/web_tests/external/wpt/magnetometer/Magnetometer.https.html index c93d9a41..0cc44378 100644 --- a/third_party/blink/web_tests/external/wpt/magnetometer/Magnetometer.https.html +++ b/third_party/blink/web_tests/external/wpt/magnetometer/Magnetometer.https.html
@@ -6,11 +6,34 @@ <link rel="help" href="https://www.w3.org/TR/magnetometer/"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="/generic-sensor/resources/generic-sensor-helpers.js"></script> <script src="/generic-sensor/generic-sensor-tests.js"></script> -<div id="log"></div> <script> -runGenericSensorTests('Magnetometer'); -runGenericSensorTests('UncalibratedMagnetometer'); +'use strict'; + +const kReadings = { + readings: [ + [-19.2, 12.1, -44.3] + ], + expectedReadings: [ + [-19.2, 12.1, -44.3] + ], + expectedRemappedReadings: [ + [-12.1, -19.2, -44.3] + ] +}; + +runGenericSensorTests( + 'Magnetometer', + kReadings, + verifyXyzSensorReading, + ['magnetometer']); + +runGenericSensorTests( + 'UncalibratedMagnetometer', + kReadings, + verifyXyzSensorReading, + ['magnetometer']); </script>
diff --git a/third_party/blink/web_tests/external/wpt/magnetometer/Magnetometer_onerror-manual.https.html b/third_party/blink/web_tests/external/wpt/magnetometer/Magnetometer_onerror-manual.https.html deleted file mode 100644 index dbdcf1d5..0000000 --- a/third_party/blink/web_tests/external/wpt/magnetometer/Magnetometer_onerror-manual.https.html +++ /dev/null
@@ -1,21 +0,0 @@ -<!DOCTYPE html> -<meta charset="utf-8"> -<title>Magnetometer Test: onerror</title> -<link rel="author" title="Intel" href="http://www.intel.com"> -<link rel="help" href="https://www.w3.org/TR/magnetometer/"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/generic-sensor/generic-sensor-tests.js"></script> -<div id="log"></div> -<h2>Precondition</h2> -<ol> - <li> - Disable the Magnetometer Sensor or run test on a device without Magnetometer Sensor. - </li> -</ol> -<script> - -runGenericSensorOnerror('Magnetometer'); -runGenericSensorOnerror('UncalibratedMagnetometer'); - -</script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/tabindex-001.html b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/tabindex-001.html new file mode 100644 index 0000000..aaf82f7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/tabindex-001.html
@@ -0,0 +1,39 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>MathML tabIndex attribute</title> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-top-level-math-element"> +<meta name="assert" content="Verify default values for the tabIndex attribute"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + window.addEventListener("load", function() { + test(() => { + const mrow = document.getElementById('mrow'); + assert_equals(mrow.tabIndex, -1, "no attribute"); + mrow.setAttribute("tabindex", "invalid"); + assert_equals(mrow.tabIndex, -1, "invalid"); + mrow.setAttribute("tabindex", "9999999999"); + assert_equals(mrow.tabIndex, -1, "too large integer"); + }, "default and invalid values on mrow"); + test(() => { + const mrowLink = document.getElementById('mrow-link'); + assert_equals(mrow.tabIndex, 0, "no attribute"); + mrow.setAttribute("tabindex", "invalid"); + assert_equals(mrow.tabIndex, 0, "invalid"); + mrow.setAttribute("tabindex", "9999999999"); + assert_equals(mrow.tabIndex, 0, "too large integer"); + }, "default and invalid values on MathML link"); + }); +</script> +</head> +<body> + <div id="log"></div> + <math> + <mrow id="mrow" onfocus="alert('fail')"></mrow> + <mrow id="mrow-link" href="javascript:alert('fail')" onfocus="alert('fail')"></mrow> + </math> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/tabindex-002.html b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/tabindex-002.html new file mode 100644 index 0000000..a1788d5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/tabindex-002.html
@@ -0,0 +1,63 @@ +<!DOCTYPE html> +<meta charset="utf-8"/> +<title>MathML tabindex attribute</title> +<meta name="timeout" content="long"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> +<meta assert="flag" content="interact"> +<meta assert="assert" content="Check the sequential focus navigation order for MathML"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<div id="log"></div> +<math> + <mtext id="text1">tabindex(omitted)</mtext> + <mtext id="text2" tabindex="">tabindex(empty)</mtext> + <mtext id="text3" tabindex="a">tabindex(a)</mtext> + <mtext id="text4" tabindex="-1">tabindex(-1)</mtext> + <mtext id="text5" tabindex="0">tabindex(0)</mtext> + <mtext id="text6" href="#link">tabindex(href)</mtext> + <mtext id="text7" tabindex="3">tabindex(3)</mtext> + <mtext id="text8" tabindex="2">tabindex(2)</mtext> + <mtext id="text9" tabindex="2">tabindex(2)</mtext> + <mtext id="text10" tabindex="2">tabindex(2)</mtext> + <mtext id="text11" tabindex="1">tabindex(1)</mtext> +</math> +<script> + +var i = 0, + expectation = ["text11", "text8", "text9", "text10", "text7", "text5", "text6"], + results = [], + t = async_test("Elements with different tabindex must be focused sequentially when pressing 'Tab' keys"); + +setup(function () { + document.body.focus(); +}); + +document.querySelector("math").addEventListener("focus", function (evt) { + results.push(evt.target.id); + i++; + if (i >= expectation.length) { + t.step(function () { + assert_array_equals(results, expectation); + }); + t.done(); + } else { + t.step(function () { + // TAB = '\ue004' + test_driver.send_keys(document.body, "\ue004"); + }); + } +}, true); + +document.addEventListener("keydown", function (evt) { + t.step(function () { + assert_equals(evt.keyCode, 9, "Please press 'Tab' key."); + }); +}, true); + +t.step(function () { + // TAB = '\ue004' + test_driver.send_keys(document.body, "\ue004"); +}); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/orientation-sensor/AbsoluteOrientationSensor-iframe-access.https.html b/third_party/blink/web_tests/external/wpt/orientation-sensor/AbsoluteOrientationSensor-iframe-access.https.html index 5fe1e528..e99b5c63 100644 --- a/third_party/blink/web_tests/external/wpt/orientation-sensor/AbsoluteOrientationSensor-iframe-access.https.html +++ b/third_party/blink/web_tests/external/wpt/orientation-sensor/AbsoluteOrientationSensor-iframe-access.https.html
@@ -5,7 +5,7 @@ <link rel="help" href="https://www.w3.org/TR/orientation-sensor/"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<script src="/generic-sensor/generic-sensor-tests.js"></script> +<script src="/generic-sensor/resources/generic-sensor-helpers.js"></script> <script src="/generic-sensor/generic-sensor-iframe-tests.sub.js"></script> <script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script> <div id="log"></div>
diff --git a/third_party/blink/web_tests/external/wpt/orientation-sensor/AbsoluteOrientationSensor.https.html b/third_party/blink/web_tests/external/wpt/orientation-sensor/AbsoluteOrientationSensor.https.html index 424d59b..7c5adc63d 100644 --- a/third_party/blink/web_tests/external/wpt/orientation-sensor/AbsoluteOrientationSensor.https.html +++ b/third_party/blink/web_tests/external/wpt/orientation-sensor/AbsoluteOrientationSensor.https.html
@@ -7,11 +7,17 @@ <link rel="help" href="https://w3c.github.io/sensors/"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="/generic-sensor/resources/generic-sensor-helpers.js"></script> <script src="/generic-sensor/generic-sensor-tests.js"></script> <script src="/orientation-sensor/orientation-sensor-tests.js"></script> -<div id="log"></div> - <script> + +runGenericSensorTests( + 'AbsoluteOrientationSensor', + kReadings, + verifyQuatSensorReading, + ['accelerometer', 'gyroscope', 'magnetometer']); + runOrienationSensorTests('AbsoluteOrientationSensor'); -runGenericSensorTests('AbsoluteOrientationSensor'); + </script>
diff --git a/third_party/blink/web_tests/external/wpt/orientation-sensor/OrientationSensor_onerror-manual.https.html b/third_party/blink/web_tests/external/wpt/orientation-sensor/OrientationSensor_onerror-manual.https.html deleted file mode 100644 index 415a63c..0000000 --- a/third_party/blink/web_tests/external/wpt/orientation-sensor/OrientationSensor_onerror-manual.https.html +++ /dev/null
@@ -1,22 +0,0 @@ -<!DOCTYPE html> -<meta charset="utf-8"> -<title>AbsoluteOrientationSensor Test: onerror</title> -<link rel="author" title="Intel" href="http://www.intel.com"> -<link rel="help" href="https://w3c.github.io/orientation-sensor/"> -<link rel="help" href="https://w3c.github.io/sensors/"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/generic-sensor/generic-sensor-tests.js"></script> -<div id="log"></div> -<h2>Precondition</h2> -<ol> - <li> - Disable the motion sensors which the underlying physical sensors include Accelerometer, Magnetometer, and (when present) Gyroscope or run test on a device without the motion sensors. - </li> -</ol> -<script> - -runGenericSensorOnerror('AbsoluteOrientationSensor'); -runGenericSensorOnerror('RelativeOrientationSensor'); - -</script>
diff --git a/third_party/blink/web_tests/external/wpt/orientation-sensor/RelativeOrientationSensor-iframe-access.https.html b/third_party/blink/web_tests/external/wpt/orientation-sensor/RelativeOrientationSensor-iframe-access.https.html index 95b57647..5d30534 100644 --- a/third_party/blink/web_tests/external/wpt/orientation-sensor/RelativeOrientationSensor-iframe-access.https.html +++ b/third_party/blink/web_tests/external/wpt/orientation-sensor/RelativeOrientationSensor-iframe-access.https.html
@@ -5,7 +5,7 @@ <link rel="help" href="https://www.w3.org/TR/orientation-sensor/"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<script src="/generic-sensor/generic-sensor-tests.js"></script> +<script src="/generic-sensor/resources/generic-sensor-helpers.js"></script> <script src="/generic-sensor/generic-sensor-iframe-tests.sub.js"></script> <script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script> <div id="log"></div>
diff --git a/third_party/blink/web_tests/external/wpt/orientation-sensor/RelativeOrientationSensor.https.html b/third_party/blink/web_tests/external/wpt/orientation-sensor/RelativeOrientationSensor.https.html index 3fa618b2..7598379 100644 --- a/third_party/blink/web_tests/external/wpt/orientation-sensor/RelativeOrientationSensor.https.html +++ b/third_party/blink/web_tests/external/wpt/orientation-sensor/RelativeOrientationSensor.https.html
@@ -7,11 +7,17 @@ <link rel="help" href="https://w3c.github.io/sensors/"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="/generic-sensor/resources/generic-sensor-helpers.js"></script> <script src="/generic-sensor/generic-sensor-tests.js"></script> <script src="/orientation-sensor/orientation-sensor-tests.js"></script> -<div id="log"></div> - <script> + +runGenericSensorTests( + 'RelativeOrientationSensor', + kReadings, + verifyQuatSensorReading, + ['accelerometer', 'gyroscope']); + runOrienationSensorTests('RelativeOrientationSensor'); -runGenericSensorTests('RelativeOrientationSensor'); + </script>
diff --git a/third_party/blink/web_tests/external/wpt/orientation-sensor/orientation-sensor-tests.js b/third_party/blink/web_tests/external/wpt/orientation-sensor/orientation-sensor-tests.js index d6754b31..fb6d83f 100644 --- a/third_party/blink/web_tests/external/wpt/orientation-sensor/orientation-sensor-tests.js +++ b/third_party/blink/web_tests/external/wpt/orientation-sensor/orientation-sensor-tests.js
@@ -1,19 +1,21 @@ -//IEEE 754: single precision retricts to 7 decimal digits -const float_precision = 1e-7; +'use strict'; -function create_matrix(quat) { - const X = quat[0]; - const Y = quat[1]; - const Z = quat[2]; - const W = quat[3]; - const mat = new Array( - 1-2*Y*Y-2*Z*Z, 2*X*Y-2*Z*W, 2*X*Z+2*Y*W, 0, - 2*X*Y+2*Z*W, 1-2*X*X-2*Z*Z, 2*Y*Z-2*X*W, 0, - 2*X*Z-2*Y*W, 2*Y*Z+2*W*X, 1-2*X*X-2*Y*Y, 0, - 0, 0, 0, 1 - ); - return mat; -} +const kDefaultReading = [ + [ 1, 0, 0, 0 ] // 180 degrees around X axis. +]; +const kRotationMatrix = [1, 0, 0, 0, + 0, -1, 0, 0, + 0, 0, -1, 0, + 0, 0, 0, 1]; +const kReadings = { + readings: kDefaultReading, + expectedReadings: kDefaultReading, + expectedRemappedReadings: [ + // For 'orientation.angle == 270', which is set for tests at + // at SensorProxy::GetScreenOrientationAngle(). + [-0.707107, 0.707107, 0, 0] + ] +}; async function checkQuaternion(t, sensorType) { const sensor = new sensorType(); @@ -26,41 +28,46 @@ sensor.stop(); }; -async function checkPopulateMatrix(t, sensorType) { +async function checkPopulateMatrix(t, sensorProvider, sensorType) { const sensor = new sensorType(); const eventWatcher = new EventWatcher(t, sensor, ["reading", "error"]); - //Throws with insufficient buffer space. - assert_throws({ name: 'TypeError' }, () => sensor.populateMatrix(new Float32Array(15))); + // Throws with insufficient buffer space. + assert_throws({ name: 'TypeError' }, + () => sensor.populateMatrix(new Float32Array(15))); - //Throws if no orientation data available. - assert_throws({ name: 'NotReadableError' }, () => sensor.populateMatrix(new Float32Array(16))); + // Throws if no orientation data available. + assert_throws({ name: 'NotReadableError' }, + () => sensor.populateMatrix(new Float32Array(16))); // Throws if passed SharedArrayBuffer view. - assert_throws({ name: 'TypeError' }, () => sensor.populateMatrix(new Float32Array(new SharedArrayBuffer(16)))); + assert_throws({ name: 'TypeError' }, + () => sensor.populateMatrix(new Float32Array(new SharedArrayBuffer(16)))); sensor.start(); + + const mockSensor = await sensorProvider.getCreatedSensor(sensorType.name); + await mockSensor.setSensorReading(kDefaultReading); + await eventWatcher.wait_for("reading"); - const quat = sensor.quaternion; - const mat_expect = create_matrix(quat); // Works for all supported types. - const mat_32 = new Float32Array(16); - sensor.populateMatrix(mat_32); - assert_array_approx_equals(mat_32, mat_expect, float_precision); + const rotationMatrix32 = new Float32Array(16); + sensor.populateMatrix(rotationMatrix32); + assert_array_equals(rotationMatrix32, kRotationMatrix); - const mat_64 = new Float64Array(16); - sensor.populateMatrix(mat_64); - assert_array_equals(mat_64, mat_expect); + let rotationMatrix64 = new Float64Array(16); + sensor.populateMatrix(rotationMatrix64); + assert_array_equals(rotationMatrix64, kRotationMatrix); - const mat_dom = new DOMMatrix(); - sensor.populateMatrix(mat_dom); - assert_array_equals(mat_dom.toFloat64Array(), mat_expect); + let rotationDOMMatrix = new DOMMatrix(); + sensor.populateMatrix(rotationDOMMatrix); + assert_array_equals(rotationDOMMatrix.toFloat64Array(), kRotationMatrix); // Sets every matrix element. - mat_64.fill(123); - sensor.populateMatrix(mat_64); - assert_array_equals(mat_64, mat_expect); + rotationMatrix64.fill(123); + sensor.populateMatrix(rotationMatrix64); + assert_array_equals(rotationMatrix64, kRotationMatrix); sensor.stop(); } @@ -73,9 +80,8 @@ return checkQuaternion(t, sensorType); }, `${sensorName}.quaternion return a four-element FrozenArray.`); - sensor_test(async t => { + sensor_test(async (t, sensorProvider) => { assert_true(sensorName in self); - return checkPopulateMatrix(t, sensorType); + return checkPopulateMatrix(t, sensorProvider, sensorType); }, `${sensorName}.populateMatrix() method works correctly.`); } -
diff --git a/third_party/blink/web_tests/external/wpt/resources/chromium/generic_sensor_mocks.js b/third_party/blink/web_tests/external/wpt/resources/chromium/generic_sensor_mocks.js index 531c3b8f..572c0de 100644 --- a/third_party/blink/web_tests/external/wpt/resources/chromium/generic_sensor_mocks.js +++ b/third_party/blink/web_tests/external/wpt/resources/chromium/generic_sensor_mocks.js
@@ -1,13 +1,18 @@ 'use strict'; var GenericSensorTest = (() => { + // Default sensor frequency in default configurations. + const DEFAULT_FREQUENCY = 5; + // Class that mocks Sensor interface defined in // https://cs.chromium.org/chromium/src/services/device/public/mojom/sensor.mojom class MockSensor { constructor(sensorRequest, handle, offset, size, reportingMode) { this.client_ = null; + this.startShouldFail_ = false; this.reportingMode_ = reportingMode; this.sensorReadingTimerId_ = null; + this.readingData_ = null; this.requestedFrequencies_ = []; let rv = handle.mapBuffer(offset, size); assert_equals(rv.result, Mojo.RESULT_OK, "Failed to map shared buffer"); @@ -20,11 +25,14 @@ }); } - getDefaultConfiguration() { - return Promise.resolve({frequency: 5}); + // Returns default configuration. + async getDefaultConfiguration() { + return { frequency: DEFAULT_FREQUENCY }; } - addConfiguration(configuration) { + // Adds configuration for the sensor and starts reporting fake data + // through setSensorReading function. + async addConfiguration(configuration) { assert_not_equals(configuration, null, "Invalid sensor configuration."); this.requestedFrequencies_.push(configuration.frequency); @@ -32,74 +40,83 @@ this.requestedFrequencies_.sort( (first, second) => { return second - first }); - this.startReading(); + if (!this.startShouldFail_ ) + this.startReading(); - return Promise.resolve({success: true}); + return { success: !this.startShouldFail_ }; } + // Removes sensor configuration from the list of active configurations and + // stops notification about sensor reading changes if + // requestedFrequencies_ is empty. removeConfiguration(configuration) { - let index = this.requestedFrequencies_.indexOf(configuration.frequency); + const index = this.requestedFrequencies_.indexOf(configuration.frequency); if (index == -1) return; this.requestedFrequencies_.splice(index, 1); - - if (this.isReading) { + if (this.requestedFrequencies_.length === 0) this.stopReading(); - if (this.requestedFrequencies_.length !== 0) - this.startReading(); - } } - suspend() { - this.stopReading(); - } + // Mock functions - resume() { - this.startReading(); - } - + // Resets mock Sensor state. reset() { this.stopReading(); + this.startShouldFail_ = false; this.requestedFrequencies_ = []; + this.readingData_ = null; this.buffer_.fill(0); this.binding_.close(); } + // Sets fake data that is used to deliver sensor reading updates. + async setSensorReading(readingData) { + this.readingData_ = new RingBuffer(readingData); + return this; + } + + // Sets flag that forces sensor to fail when addConfiguration is invoked. + setStartShouldFail(shouldFail) { + this.startShouldFail_ = shouldFail; + } + startReading() { - if (this.isReading) { - console.warn("Sensor reading is already started."); - return; + if (this.readingData_ != null) { + this.stopReading(); } - - if (this.requestedFrequencies_.length == 0) { - console.warn("Sensor reading cannot be started as" + - "there are no configurations added."); - return; - } - - const maxFrequencyHz = this.requestedFrequencies_[0]; - const timeoutMs = (1 / maxFrequencyHz) * 1000; + let maxFrequencyUsed = this.requestedFrequencies_[0]; + let timeout = (1 / maxFrequencyUsed) * 1000; this.sensorReadingTimerId_ = window.setInterval(() => { + if (this.readingData_) { + // |buffer_| is a TypedArray, so we need to make sure pass an + // array to set(). + const reading = this.readingData_.next().value; + assert_true(Array.isArray(reading), "The readings passed to " + + "setSensorReading() must be arrays."); + this.buffer_.set(reading, 2); + } // For all tests sensor reading should have monotonically // increasing timestamp in seconds. this.buffer_[1] = window.performance.now() * 0.001; if (this.reportingMode_ === device.mojom.ReportingMode.ON_CHANGE) { this.client_.sensorReadingChanged(); } - }, timeoutMs); + }, timeout); } stopReading() { - if (this.isReading) { + if (this.sensorReadingTimerId_ != null) { window.clearInterval(this.sensorReadingTimerId_); this.sensorReadingTimerId_ = null; } } - get isReading() { - this.sensorReadingTimerId_ !== null; - } + getSamplingFrequency() { + assert_true(this.requestedFrequencies_.length > 0); + return this.requestedFrequencies_[0]; + } } // Class that mocks SensorProvider interface defined in @@ -110,70 +127,162 @@ device.mojom.SensorInitParams.kReadBufferSizeForTests; this.sharedBufferSizeInBytes_ = this.readingSizeInBytes_ * (device.mojom.SensorType.MAX_VALUE + 1); - let rv = Mojo.createSharedBuffer(this.sharedBufferSizeInBytes_); + const rv = Mojo.createSharedBuffer(this.sharedBufferSizeInBytes_); assert_equals(rv.result, Mojo.RESULT_OK, "Failed to create buffer"); this.sharedBufferHandle_ = rv.handle; - this.activeSensor_ = null; - this.isContinuous_ = false; + this.activeSensors_ = new Map(); + this.resolveFuncs_ = new Map(); + this.getSensorShouldFail_ = new Map(); + this.permissionsDenied_ = new Map(); + this.maxFrequency_ = 60; + this.minFrequency_ = 1; + this.mojomSensorType_ = new Map([ + ['Accelerometer', device.mojom.SensorType.ACCELEROMETER], + ['LinearAccelerationSensor', + device.mojom.SensorType.LINEAR_ACCELERATION], + ['AmbientLightSensor', device.mojom.SensorType.AMBIENT_LIGHT], + ['Gyroscope', device.mojom.SensorType.GYROSCOPE], + ['Magnetometer', device.mojom.SensorType.MAGNETOMETER], + ['AbsoluteOrientationSensor', + device.mojom.SensorType.ABSOLUTE_ORIENTATION_QUATERNION], + ['AbsoluteOrientationEulerAngles', + device.mojom.SensorType.ABSOLUTE_ORIENTATION_EULER_ANGLES], + ['RelativeOrientationSensor', + device.mojom.SensorType.RELATIVE_ORIENTATION_QUATERNION], + ['RelativeOrientationEulerAngles', + device.mojom.SensorType.RELATIVE_ORIENTATION_EULER_ANGLES] + ]); this.binding_ = new mojo.Binding(device.mojom.SensorProvider, this); this.interceptor_ = new MojoInterfaceInterceptor( device.mojom.SensorProvider.name); this.interceptor_.oninterfacerequest = e => { - this.binding_.bind(e.handle); - this.binding_.setConnectionErrorHandler(() => { - console.error("Mojo connection error"); - this.reset(); - }); + this.bindToPipe(e.handle); }; this.interceptor_.start(); } + // Returns initialized Sensor proxy to the client. async getSensor(type) { + if (this.getSensorShouldFail_.get(type)) { + return {result: device.mojom.SensorCreationResult.ERROR_NOT_AVAILABLE, + initParams: null}; + } + if (this.permissionsDenied_.get(type)) { + return {result: device.mojom.SensorCreationResult.ERROR_NOT_ALLOWED, + initParams: null}; + } + const offset = type * this.readingSizeInBytes_; const reportingMode = device.mojom.ReportingMode.ON_CHANGE; - let sensorPtr = new device.mojom.SensorPtr(); - if (this.activeSensor_ == null) { - let mockSensor = new MockSensor( + const sensorPtr = new device.mojom.SensorPtr(); + if (!this.activeSensors_.has(type)) { + const mockSensor = new MockSensor( mojo.makeRequest(sensorPtr), this.sharedBufferHandle_, offset, this.readingSizeInBytes_, reportingMode); - this.activeSensor_ = mockSensor; - this.activeSensor_.client_ = new device.mojom.SensorClientPtr(); + this.activeSensors_.set(type, mockSensor); + this.activeSensors_.get(type).client_ = + new device.mojom.SensorClientPtr(); } - let rv = this.sharedBufferHandle_.duplicateBufferHandle(); + const rv = this.sharedBufferHandle_.duplicateBufferHandle(); assert_equals(rv.result, Mojo.RESULT_OK); - let maxAllowedFrequencyHz = 60; + + const defaultConfig = { frequency: DEFAULT_FREQUENCY }; + // Consider sensor traits to meet assertions in C++ code (see + // services/device/public/cpp/generic_sensor/sensor_traits.h) if (type == device.mojom.SensorType.AMBIENT_LIGHT || type == device.mojom.SensorType.MAGNETOMETER) { - maxAllowedFrequencyHz = 10; + this.maxFrequency_ = Math.min(10, this.maxFrequency_); } - let initParams = new device.mojom.SensorInitParams({ + const initParams = new device.mojom.SensorInitParams({ sensor: sensorPtr, - clientRequest: mojo.makeRequest(this.activeSensor_.client_), + clientRequest: mojo.makeRequest(this.activeSensors_.get(type).client_), memory: rv.handle, bufferOffset: offset, mode: reportingMode, - defaultConfiguration: {frequency: 5}, - minimumFrequency: 1, - maximumFrequency: maxAllowedFrequencyHz + defaultConfiguration: defaultConfig, + minimumFrequency: this.minFrequency_, + maximumFrequency: this.maxFrequency_ }); + if (this.resolveFuncs_.has(type)) { + for (let resolveFunc of this.resolveFuncs_.get(type)) { + resolveFunc(this.activeSensors_.get(type)); + } + this.resolveFuncs_.delete(type); + } + return {result: device.mojom.SensorCreationResult.SUCCESS, initParams: initParams}; } + // Binds object to mojo message pipe + bindToPipe(pipe) { + this.binding_.bind(pipe); + this.binding_.setConnectionErrorHandler(() => { + this.reset(); + }); + } + + // Mock functions + + // Resets state of mock SensorProvider between test runs. reset() { - if (this.activeSensor_ !== null) { - this.activeSensor_.reset(); - this.activeSensor_ = null; + for (const sensor of this.activeSensors_.values()) { + sensor.reset(); } + this.activeSensors_.clear(); + this.resolveFuncs_.clear(); + this.getSensorShouldFail_.clear(); + this.permissionsDenied_.clear(); + this.maxFrequency_ = 60; + this.minFrequency_ = 1; this.binding_.close(); this.interceptor_.stop(); } + + // Sets flag that forces mock SensorProvider to fail when getSensor() is + // invoked. + setGetSensorShouldFail(sensorType, shouldFail) { + this.getSensorShouldFail_.set(this.mojomSensorType_.get(sensorType), + shouldFail); + } + + setPermissionsDenied(sensorType, permissionsDenied) { + this.permissionsDenied_.set(this.mojomSensorType_.get(sensorType), + permissionsDenied); + } + + // Returns mock sensor that was created in getSensor to the layout test. + getCreatedSensor(sensorType) { + const type = this.mojomSensorType_.get(sensorType); + assert_equals(typeof type, "number", "A sensor type must be specified."); + + if (this.activeSensors_.has(type)) { + return Promise.resolve(this.activeSensors_.get(type)); + } + + return new Promise(resolve => { + if (!this.resolveFuncs_.has(type)) { + this.resolveFuncs_.set(type, []); + } + this.resolveFuncs_.get(type).push(resolve); + }); + } + + // Sets the maximum frequency for a concrete sensor. + setMaximumSupportedFrequency(frequency) { + this.maxFrequency_ = frequency; + } + + // Sets the minimum frequency for a concrete sensor. + setMinimumSupportedFrequency(frequency) { + this.minFrequency_ = frequency; + } } let testInternal = { @@ -190,7 +299,8 @@ if (testInternal.initialized) throw new Error('Call reset() before initialize().'); - if (window.testRunner) { // Grant sensor permissions for Chromium testrunner. + if (window.testRunner) { + // Grant sensor permissions for Chromium testrunner. ['accelerometer', 'gyroscope', 'magnetometer', 'ambient-light-sensor'].forEach((entry) => { window.testRunner.setPermission(entry, 'granted', @@ -213,6 +323,10 @@ // the sensor provider finish. await new Promise(resolve => setTimeout(resolve, 0)); } + + getSensorProvider() { + return testInternal.sensorProvider; + } } return GenericSensorTestChromium;
diff --git a/third_party/blink/web_tests/external/wpt/streams/writable-streams/properties.any-expected.txt b/third_party/blink/web_tests/external/wpt/streams/writable-streams/properties.any-expected.txt index ff1f36737..8a7f4cb 100644 --- a/third_party/blink/web_tests/external/wpt/streams/writable-streams/properties.any-expected.txt +++ b/third_party/blink/web_tests/external/wpt/streams/writable-streams/properties.any-expected.txt
@@ -7,7 +7,7 @@ PASS WritableStream.prototype.locked should be a getter PASS WritableStream.prototype.abort should have standard properties FAIL WritableStream.prototype.abort should be a method assert_equals: abort should take 1 arguments expected 1 but got 0 -FAIL WritableStream.prototype.close should have standard properties Cannot destructure property `configurable` of 'undefined' or 'null'. +FAIL WritableStream.prototype.close should have standard properties Cannot destructure property 'configurable' of 'descriptor' as it is undefined. FAIL WritableStream.prototype.close should be a method Cannot read property 'writable' of undefined PASS WritableStream.prototype.getWriter should have standard properties PASS WritableStream.prototype.getWriter should be a method
diff --git a/third_party/blink/web_tests/external/wpt/streams/writable-streams/properties.any.serviceworker-expected.txt b/third_party/blink/web_tests/external/wpt/streams/writable-streams/properties.any.serviceworker-expected.txt index ff1f36737..8a7f4cb 100644 --- a/third_party/blink/web_tests/external/wpt/streams/writable-streams/properties.any.serviceworker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/streams/writable-streams/properties.any.serviceworker-expected.txt
@@ -7,7 +7,7 @@ PASS WritableStream.prototype.locked should be a getter PASS WritableStream.prototype.abort should have standard properties FAIL WritableStream.prototype.abort should be a method assert_equals: abort should take 1 arguments expected 1 but got 0 -FAIL WritableStream.prototype.close should have standard properties Cannot destructure property `configurable` of 'undefined' or 'null'. +FAIL WritableStream.prototype.close should have standard properties Cannot destructure property 'configurable' of 'descriptor' as it is undefined. FAIL WritableStream.prototype.close should be a method Cannot read property 'writable' of undefined PASS WritableStream.prototype.getWriter should have standard properties PASS WritableStream.prototype.getWriter should be a method
diff --git a/third_party/blink/web_tests/external/wpt/streams/writable-streams/properties.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/streams/writable-streams/properties.any.sharedworker-expected.txt index ff1f36737..8a7f4cb 100644 --- a/third_party/blink/web_tests/external/wpt/streams/writable-streams/properties.any.sharedworker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/streams/writable-streams/properties.any.sharedworker-expected.txt
@@ -7,7 +7,7 @@ PASS WritableStream.prototype.locked should be a getter PASS WritableStream.prototype.abort should have standard properties FAIL WritableStream.prototype.abort should be a method assert_equals: abort should take 1 arguments expected 1 but got 0 -FAIL WritableStream.prototype.close should have standard properties Cannot destructure property `configurable` of 'undefined' or 'null'. +FAIL WritableStream.prototype.close should have standard properties Cannot destructure property 'configurable' of 'descriptor' as it is undefined. FAIL WritableStream.prototype.close should be a method Cannot read property 'writable' of undefined PASS WritableStream.prototype.getWriter should have standard properties PASS WritableStream.prototype.getWriter should be a method
diff --git a/third_party/blink/web_tests/external/wpt/streams/writable-streams/properties.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/streams/writable-streams/properties.any.worker-expected.txt index ff1f36737..8a7f4cb 100644 --- a/third_party/blink/web_tests/external/wpt/streams/writable-streams/properties.any.worker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/streams/writable-streams/properties.any.worker-expected.txt
@@ -7,7 +7,7 @@ PASS WritableStream.prototype.locked should be a getter PASS WritableStream.prototype.abort should have standard properties FAIL WritableStream.prototype.abort should be a method assert_equals: abort should take 1 arguments expected 1 but got 0 -FAIL WritableStream.prototype.close should have standard properties Cannot destructure property `configurable` of 'undefined' or 'null'. +FAIL WritableStream.prototype.close should have standard properties Cannot destructure property 'configurable' of 'descriptor' as it is undefined. FAIL WritableStream.prototype.close should be a method Cannot read property 'writable' of undefined PASS WritableStream.prototype.getWriter should have standard properties PASS WritableStream.prototype.getWriter should be a method
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/default-policy-report-only.tentative.html b/third_party/blink/web_tests/external/wpt/trusted-types/default-policy-report-only.tentative.html index aa13e42..1170655 100644 --- a/third_party/blink/web_tests/external/wpt/trusted-types/default-policy-report-only.tentative.html +++ b/third_party/blink/web_tests/external/wpt/trusted-types/default-policy-report-only.tentative.html
@@ -7,26 +7,6 @@ </head> <body> <script> - -// We expect to run this test in two instances, enforcing and report-only -// Trusted Type policies. We'll infer from our URL which one we are. -// -// The expected file names/headers are: -// - default-policy.tentative.html: -// Content-Security-Policy: trusted-types * -// - default-policy-report-only.tentative.html: -// Content-Security-Policy-Report-Only: trusted-types * -// -// The behaviour of the tests should be _mostly_ identical, except that -// Trusted Types relevant assignments should only throw in the enforced -// case. We will use assert_throws for things that should always throw -// (i.e., regular exceptions), and maybe_throws for tests that should only -// throw in TT-enforcing mode. -const is_report_only = document.location.pathname.includes("report-only"); -const maybe_throws = (is_report_only - ? (error, fn, message) => fn() - : assert_throws); - // Ensure that only the right events trigger violation reports. // The Promise will resolve, when an event including the string "done" is // received. The last line of this test file will cause this trigger. @@ -69,7 +49,8 @@ testCases.forEach(c => { test(t => { const element = document.createElement(c[0]); - maybe_throws(TypeError(), _ => element[c[1]] = "nodefault"); + element[c[1]] = "nodefault"; + assert_true(element[c[1]].includes("nodefault")); }, `${c[0]}.${c[1]} no default policy`); }); @@ -105,7 +86,8 @@ }, name + "default"); test(t => { const element = document.createElement(c[0]); - maybe_throws(TypeError(), _ => element[c[1]] = "null"); + element[c[1]] = "null"; + assert_true(element[c[1]].includes("null")); }, name + "null"); test(t => { const element = document.createElement(c[0]); @@ -113,7 +95,8 @@ }, name + "throw"); test(t => { const element = document.createElement(c[0]); - maybe_throws(TypeError(), _ => element[c[1]] = "undefined"); + element[c[1]] = "undefined"; + assert_true(element[c[1]].includes("undefined")); }, name + "undefined"); test(t => { const element = document.createElement(c[0]);
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/default-policy.tentative.html b/third_party/blink/web_tests/external/wpt/trusted-types/default-policy.tentative.html index aa13e42..68e05c130 100644 --- a/third_party/blink/web_tests/external/wpt/trusted-types/default-policy.tentative.html +++ b/third_party/blink/web_tests/external/wpt/trusted-types/default-policy.tentative.html
@@ -7,26 +7,6 @@ </head> <body> <script> - -// We expect to run this test in two instances, enforcing and report-only -// Trusted Type policies. We'll infer from our URL which one we are. -// -// The expected file names/headers are: -// - default-policy.tentative.html: -// Content-Security-Policy: trusted-types * -// - default-policy-report-only.tentative.html: -// Content-Security-Policy-Report-Only: trusted-types * -// -// The behaviour of the tests should be _mostly_ identical, except that -// Trusted Types relevant assignments should only throw in the enforced -// case. We will use assert_throws for things that should always throw -// (i.e., regular exceptions), and maybe_throws for tests that should only -// throw in TT-enforcing mode. -const is_report_only = document.location.pathname.includes("report-only"); -const maybe_throws = (is_report_only - ? (error, fn, message) => fn() - : assert_throws); - // Ensure that only the right events trigger violation reports. // The Promise will resolve, when an event including the string "done" is // received. The last line of this test file will cause this trigger. @@ -69,7 +49,8 @@ testCases.forEach(c => { test(t => { const element = document.createElement(c[0]); - maybe_throws(TypeError(), _ => element[c[1]] = "nodefault"); + assert_throws(TypeError(), _ => element[c[1]] = "nodefault"); + assert_equals(element[c[1]], ""); }, `${c[0]}.${c[1]} no default policy`); }); @@ -105,7 +86,8 @@ }, name + "default"); test(t => { const element = document.createElement(c[0]); - maybe_throws(TypeError(), _ => element[c[1]] = "null"); + assert_throws(TypeError(), _ => element[c[1]] = "null"); + assert_equals(element[c[1]], ""); }, name + "null"); test(t => { const element = document.createElement(c[0]); @@ -113,7 +95,8 @@ }, name + "throw"); test(t => { const element = document.createElement(c[0]); - maybe_throws(TypeError(), _ => element[c[1]] = "undefined"); + assert_throws(TypeError(), _ => element[c[1]] = "undefined"); + assert_equals(element[c[1]], ""); }, name + "undefined"); test(t => { const element = document.createElement(c[0]);
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/fast/replaced/replaced-breaking-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/fast/replaced/replaced-breaking-expected.png index a7fe529..e07ba946 100644 --- a/third_party/blink/web_tests/platform/mac-mac10.10/fast/replaced/replaced-breaking-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac10.10/fast/replaced/replaced-breaking-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.11/fast/replaced/replaced-breaking-expected.png b/third_party/blink/web_tests/platform/mac-mac10.11/fast/replaced/replaced-breaking-expected.png index 02c7379..090cb62 100644 --- a/third_party/blink/web_tests/platform/mac-mac10.11/fast/replaced/replaced-breaking-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac10.11/fast/replaced/replaced-breaking-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/replaced/replaced-breaking-expected.png b/third_party/blink/web_tests/platform/mac/fast/replaced/replaced-breaking-expected.png index 9efc766..4c81edd 100644 --- a/third_party/blink/web_tests/platform/mac/fast/replaced/replaced-breaking-expected.png +++ b/third_party/blink/web_tests/platform/mac/fast/replaced/replaced-breaking-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/replaced/replaced-breaking-expected.png b/third_party/blink/web_tests/platform/win/fast/replaced/replaced-breaking-expected.png index 7807cd2..3049b11 100644 --- a/third_party/blink/web_tests/platform/win/fast/replaced/replaced-breaking-expected.png +++ b/third_party/blink/web_tests/platform/win/fast/replaced/replaced-breaking-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/sensor/OWNERS b/third_party/blink/web_tests/sensor/OWNERS deleted file mode 100644 index 8f04c5d..0000000 --- a/third_party/blink/web_tests/sensor/OWNERS +++ /dev/null
@@ -1,2 +0,0 @@ -# TEAM: device-dev@chromium.org -# COMPONENT: Blink>Sensor
diff --git a/third_party/blink/web_tests/sensor/accelerometer.html b/third_party/blink/web_tests/sensor/accelerometer.html deleted file mode 100644 index 081e9b5..0000000 --- a/third_party/blink/web_tests/sensor/accelerometer.html +++ /dev/null
@@ -1,39 +0,0 @@ -<!DOCTYPE html> -<script src="../resources/testharness.js"></script> -<script src="../resources/testharnessreport.js"></script> -<script src="../http/tests/resources/sensor-helpers.js"></script> -<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> -<script src="file:///gen/services/device/public/mojom/sensor_provider.mojom.js"></script> -<script src="resources/generic-sensor-utils.js"></script> -<script src="resources/generic-sensor-tests.js"></script> -<script> - -'use strict'; - -if (!window.testRunner) - debug('This test cannot be run without the TestRunner'); - -const kReadings = { - readings: [ - [1.12345, 2.12345, 3.12345] - ], - expectedReadings: [ - [1.12345, 2.12345, 3.12345] - ], - expectedRemappedReadings: [ - [-2.12345, 1.12345, 3.12345] - ] -} - -runGenericSensorTests( - Accelerometer, - kReadings, - verifyXyzSensorReading, - ['accelerometer']); - -runGenericSensorTests( - LinearAccelerationSensor, - kReadings, - verifyXyzSensorReading, - ['accelerometer']); -</script>
diff --git a/third_party/blink/web_tests/sensor/ambient-light-sensor.html b/third_party/blink/web_tests/sensor/ambient-light-sensor.html deleted file mode 100644 index 9476ffcc..0000000 --- a/third_party/blink/web_tests/sensor/ambient-light-sensor.html +++ /dev/null
@@ -1,30 +0,0 @@ -<!DOCTYPE html> -<script src="../resources/testharness.js"></script> -<script src="../resources/testharnessreport.js"></script> -<script src="../http/tests/resources/sensor-helpers.js"></script> -<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> -<script src="file:///gen/services/device/public/mojom/sensor_provider.mojom.js"></script> -<script src="resources/generic-sensor-utils.js"></script> -<script src="resources/generic-sensor-tests.js"></script> -<script> - -'use strict'; - -if (!window.testRunner) - debug('This test cannot be run without the TestRunner'); - -const kReadings = { - readings: [ - [3.1415] - ], - expectedReadings: [ - [3.1415] - ] -}; - -runGenericSensorTests( - AmbientLightSensor, - kReadings, - verifyAlsSensorReading, - ['ambient-light-sensor']); -</script>
diff --git a/third_party/blink/web_tests/sensor/gyroscope.html b/third_party/blink/web_tests/sensor/gyroscope.html deleted file mode 100644 index c52cf85..0000000 --- a/third_party/blink/web_tests/sensor/gyroscope.html +++ /dev/null
@@ -1,33 +0,0 @@ -<!DOCTYPE html> -<script src="../resources/testharness.js"></script> -<script src="../resources/testharnessreport.js"></script> -<script src="../http/tests/resources/sensor-helpers.js"></script> -<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> -<script src="file:///gen/services/device/public/mojom/sensor_provider.mojom.js"></script> -<script src="resources/generic-sensor-utils.js"></script> -<script src="resources/generic-sensor-tests.js"></script> -<script> - -'use strict'; - -if (!window.testRunner) - debug('This test cannot be run without the TestRunner'); - -const kReadings = { - readings: [ - [1.12345, 2.12345, 3.12345] - ], - expectedReadings: [ - [1.12345, 2.12345, 3.12345] - ], - expectedRemappedReadings: [ - [-2.12345, 1.12345, 3.12345] - ] -} - -runGenericSensorTests( - Gyroscope, - kReadings, - verifyXyzSensorReading, - ['gyroscope']); -</script>
diff --git a/third_party/blink/web_tests/sensor/magnetometer.html b/third_party/blink/web_tests/sensor/magnetometer.html deleted file mode 100644 index 117dca4..0000000 --- a/third_party/blink/web_tests/sensor/magnetometer.html +++ /dev/null
@@ -1,33 +0,0 @@ -<!DOCTYPE html> -<script src="../resources/testharness.js"></script> -<script src="../resources/testharnessreport.js"></script> -<script src="../http/tests/resources/sensor-helpers.js"></script> -<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> -<script src="file:///gen/services/device/public/mojom/sensor_provider.mojom.js"></script> -<script src="resources/generic-sensor-utils.js"></script> -<script src="resources/generic-sensor-tests.js"></script> -<script> - -'use strict'; - -if (!window.testRunner) - debug('This test cannot be run without the TestRunner'); - -const kReadings = { - readings: [ - [-19.2, 12.1, -44.3] - ], - expectedReadings: [ - [-19.2, 12.1, -44.3] - ], - expectedRemappedReadings: [ - [-12.1, -19.2, -44.3] - ] -} - -runGenericSensorTests( - Magnetometer, - kReadings, - verifyXyzSensorReading, - ['magnetometer']); -</script>
diff --git a/third_party/blink/web_tests/sensor/mock-sensor.html b/third_party/blink/web_tests/sensor/mock-sensor.html deleted file mode 100644 index 47d7dcb9..0000000 --- a/third_party/blink/web_tests/sensor/mock-sensor.html +++ /dev/null
@@ -1,14 +0,0 @@ -<!DOCTYPE html> -<script src="../resources/testharness.js"></script> -<script src="../resources/testharnessreport.js"></script> -<script src="../http/tests/resources/sensor-helpers.js"></script> -<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> -<script src="file:///gen/services/device/public/mojom/sensor_provider.mojom.js"></script> -<script> - -'use strict'; - -sensor_test(sensorProvider => { - assert_true(sensorProvider instanceof Object); -}, 'Sensor Mojo bindings and mock interfaces are available to tests.') -</script>
diff --git a/third_party/blink/web_tests/sensor/orientation-sensor.html b/third_party/blink/web_tests/sensor/orientation-sensor.html deleted file mode 100644 index ef7cd83..0000000 --- a/third_party/blink/web_tests/sensor/orientation-sensor.html +++ /dev/null
@@ -1,108 +0,0 @@ -<!DOCTYPE html> -<script src="../resources/testharness.js"></script> -<script src="../resources/testharnessreport.js"></script> -<script src="../http/tests/resources/sensor-helpers.js"></script> -<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> -<script src="file:///gen/services/device/public/mojom/sensor_provider.mojom.js"></script> -<script src="resources/generic-sensor-utils.js"></script> -<script src="resources/generic-sensor-tests.js"></script> -<script> - -'use strict'; - -if (!window.testRunner) - debug('This test cannot be run without the TestRunner'); - -const kDefaultReading = [ - [ 1, 0, 0, 0 ] // 180 degrees around X axis. -]; -const kRotationMatrix = [1, 0, 0, 0, - 0, -1, 0, 0, - 0, 0, -1, 0, - 0, 0, 0, 1]; - -async function checkPopulateMatrix(sensorProvider, sensorType) { - let sensorObject = new sensorType(); - - // Throws with insufficient buffer space. - assert_throws({ name: 'TypeError' }, () => sensorObject.populateMatrix(new Float32Array(15))); - - // Throws if no orientation data available. - assert_throws({ name: 'NotReadableError' }, () => sensorObject.populateMatrix(new Float32Array(16))); - - if (window.SharedArrayBuffer) { - // Throws if passed SharedArrayBuffer view. - assert_throws({ name: 'TypeError' }, () => sensorObject.populateMatrix(new Float32Array(new SharedArrayBuffer(16)))); - } - - sensorObject.start(); - - let mockSensor = await sensorProvider.getCreatedSensor(sensorType.name); - await mockSensor.setSensorReading(kDefaultReading); - await new Promise((resolve, reject) => { - sensorObject.onreading = () => { - try { - // Works for all supported types. - let rotationMatrix32 = new Float32Array(16); - sensorObject.populateMatrix(rotationMatrix32); - assert_array_equals(rotationMatrix32, kRotationMatrix); - - let rotationMatrix64 = new Float64Array(16); - sensorObject.populateMatrix(rotationMatrix64); - assert_array_equals(rotationMatrix64, kRotationMatrix); - - let rotationDOMMatrix = new DOMMatrix(); - sensorObject.populateMatrix(rotationDOMMatrix); - assert_array_equals(rotationDOMMatrix.toFloat64Array(), - kRotationMatrix); - - // Sets every matrix element. - rotationMatrix64.fill(123); - sensorObject.populateMatrix(rotationMatrix64); - assert_array_equals(rotationMatrix64, kRotationMatrix); - - sensorObject.stop(); - resolve(mockSensor); - } catch (e) { - reject(e); - }; - } - sensorObject.onerror = reject; - }); - return mockSensor.removeConfigurationCalled(); -} - -const kReadings = { - readings: kDefaultReading, - expectedReadings: kDefaultReading, - expectedRemappedReadings: [ - // For 'orientation.angle == 270', which is set for tests at - // at SensorProxy::GetScreenOrientationAngle(). - [-0.707107, 0.707107, 0, 0] - ] -} - -runGenericSensorTests( - AbsoluteOrientationSensor, - kReadings, - verifyQuatSensorReading, - ['accelerometer', 'gyroscope', 'magnetometer']); - -sensor_test((t, sensorProvider) => { - return checkPopulateMatrix( - sensorProvider, - AbsoluteOrientationSensor); -}, 'Test AbsoluteOrientationSensor.populateMatrix() method works correctly.'); - -runGenericSensorTests( - RelativeOrientationSensor, - kReadings, - verifyQuatSensorReading, - ['accelerometer', 'gyroscope']); - -sensor_test((t, sensorProvider) => { - return checkPopulateMatrix( - sensorProvider, - RelativeOrientationSensor); -}, 'Test RelativeOrientationSensor.populateMatrix() method works correctly.'); -</script>
diff --git a/third_party/blink/web_tests/sensor/resources/generic-sensor-tests.js b/third_party/blink/web_tests/sensor/resources/generic-sensor-tests.js deleted file mode 100644 index b079f3c..0000000 --- a/third_party/blink/web_tests/sensor/resources/generic-sensor-tests.js +++ /dev/null
@@ -1,597 +0,0 @@ -'use strict'; - -// Run a set of tests for a given |sensorType|. -// |readingData| is an object with 3 keys, all of which are arrays of arrays: -// 1. "readings". Each value corresponds to one raw reading that will be -// processed by a sensor. -// 2. "expectedReadings". Each value corresponds to the processed value a -// sensor will make available to users (i.e. a capped or rounded value). -// Its length must match |readings|'. -// 3. "expectedRemappedReadings" (optional). Similar to |expectedReadings|, but -// used only by spatial sensors, whose reference frame can change the values -// returned by a sensor. -// Its length should match |readings|'. -// |verificationFunction| is called to verify that a given reading matches a -// value in |expectedReadings|. -// |featurePolicies| represents |sensorType|’s associated sensor feature name. -function runGenericSensorTests(sensorType, - readingData, - verificationFunction, - featurePolicies) { - function validateReadingFormat(data) { - return Array.isArray(data) && data.every(element => Array.isArray(element)); - } - - const { readings, expectedReadings, expectedRemappedReadings } = readingData; - if (!validateReadingFormat(readings)) { - throw new TypeError('readingData.readings must be an array of arrays.'); - } - if (!validateReadingFormat(expectedReadings)) { - throw new TypeError('readingData.expectedReadings must be an array of ' + - 'arrays.'); - } - if (readings.length != expectedReadings.length) { - throw new TypeError('readingData.readings and ' + - 'readingData.expectedReadings must have the same ' + - 'length.'); - } - if (expectedRemappedReadings && - !validateReadingFormat(expectedRemappedReadings)) { - throw new TypeError('readingData.expectedRemappedReadings must be an ' + - 'array of arrays.'); - } - if (expectedRemappedReadings && - readings.length != expectedRemappedReadings.length) { - throw new TypeError('readingData.readings and ' + - 'readingData.expectedRemappedReadings must have the same ' + - 'length.'); - } - - // Wraps callback and calls rejectFunc if callback throws an error. - class CallbackWrapper { - constructor(callback, rejectFunc) { - this.wrapperFunc_ = (args) => { - try { - callback(args); - } catch (e) { - rejectFunc(e); - } - } - } - - get callback() { - return this.wrapperFunc_; - } - } - - sensor_test((t, sensorProvider) => { - sensorProvider.getSensorTypeSettings(sensorType.name).unavailable = true; - let sensorObject = new sensorType; - sensorObject.start(); - return new Promise((resolve, reject) => { - let wrapper = new CallbackWrapper(event => { - assert_false(sensorObject.activated); - assert_equals(event.error.name, 'NotReadableError'); - sensorObject.onerror = null; - resolve(); - }, reject); - - sensorObject.onerror = wrapper.callback; - }); - }, `${sensorType.name}: Test that onerror is sent when sensor is not supported.`); - - sensor_test((t, sensorProvider) => { - sensorProvider.getSensorTypeSettings(sensorType.name).shouldDenyRequests = true; - let sensorObject = new sensorType; - sensorObject.start(); - return new Promise((resolve, reject) => { - let wrapper = new CallbackWrapper(event => { - assert_false(sensorObject.activated); - assert_equals(event.error.name, 'NotAllowedError'); - sensorObject.onerror = null; - resolve(); - }, reject); - - sensorObject.onerror = wrapper.callback; - }); - }, `${sensorType.name}: Test that onerror is sent when permissions are not granted.`); - - sensor_test(async (t, sensorProvider) => { - let sensorObject = new sensorType({frequency: 560}); - sensorObject.start(); - - let mockSensor = await sensorProvider.getCreatedSensor(sensorType.name); - mockSensor.setStartShouldFail(true); - await mockSensor.addConfigurationCalled(); - await new Promise((resolve, reject) => { - let wrapper = new CallbackWrapper(event => { - assert_false(sensorObject.activated); - assert_equals(event.error.name, 'NotReadableError'); - sensorObject.onerror = null; - resolve(); - }, reject); - - sensorObject.onerror = wrapper.callback; - }); - }, `${sensorType.name}: Test that onerror is send when start() call has failed.`); - - sensor_test(async (t, sensorProvider) => { - let sensorObject = new sensorType(); - sensorObject.start(); - - let mockSensor = await sensorProvider.getCreatedSensor(sensorType.name); - mockSensor.setStartShouldFail(true); - await mockSensor.addConfigurationCalled(); - return mockSensor.removeConfigurationCalled(); - }, `${sensorType.name}: Test that no pending configuration left after start() failure.`); - - sensor_test(async (t, sensorProvider) => { - let sensorObject = new sensorType({frequency: 560}); - sensorObject.start(); - - let mockSensor = await sensorProvider.getCreatedSensor(sensorType.name); - await mockSensor.addConfigurationCalled(); - await new Promise((resolve, reject) => { - let wrapper = new CallbackWrapper(() => { - assert_less_than_equal(mockSensor.getSamplingFrequency(), 60); - sensorObject.stop(); - assert_false(sensorObject.activated); - resolve(mockSensor); - }, reject); - sensorObject.onactivate = wrapper.callback; - sensorObject.onerror = reject; - }); - return mockSensor.removeConfigurationCalled(); - }, `${sensorType.name}: Test that frequency is capped to allowed maximum.`); - - sensor_test(async (t, sensorProvider) => { - let sensorObject = new sensorType(); - sensorObject.start(); - let mockSensor = await sensorProvider.getCreatedSensor(sensorType.name); - await mockSensor.addConfigurationCalled(); - await new Promise((resolve, reject) => { - sensorObject.onactivate = () => { - // Now sensor proxy is initialized. - let anotherSensor = new sensorType({frequency: 21}); - anotherSensor.start(); - anotherSensor.stop(); - resolve(mockSensor); - } - }); - await mockSensor.removeConfigurationCalled(); - sensorObject.stop(); - return mockSensor.removeConfigurationCalled(); - }, `${sensorType.name}: Test that configuration is removed for a stopped sensor.`); - - sensor_test(async (t, sensorProvider) => { - const maxSupportedFrequency = 5; - sensorProvider.setMaximumSupportedFrequency(maxSupportedFrequency); - let sensorObject = new sensorType({frequency: 50}); - sensorObject.start(); - - let mockSensor = await sensorProvider.getCreatedSensor(sensorType.name); - await mockSensor.addConfigurationCalled(); - await new Promise((resolve, reject) => { - let wrapper = new CallbackWrapper(() => { - assert_equals(mockSensor.getSamplingFrequency(), maxSupportedFrequency); - sensorObject.stop(); - assert_false(sensorObject.activated); - resolve(mockSensor); - }, reject); - sensorObject.onactivate = wrapper.callback; - sensorObject.onerror = reject; - }); - return mockSensor.removeConfigurationCalled(); - }, `${sensorType.name}: Test that frequency is capped to the maximum supported from frequency.`); - - sensor_test(async (t, sensorProvider) => { - const minSupportedFrequency = 2; - sensorProvider.setMinimumSupportedFrequency(minSupportedFrequency); - let sensorObject = new sensorType({frequency: -1}); - sensorObject.start(); - - let mockSensor = await sensorProvider.getCreatedSensor(sensorType.name); - await mockSensor.addConfigurationCalled(); - await new Promise((resolve, reject) => { - let wrapper = new CallbackWrapper(() => { - assert_equals(mockSensor.getSamplingFrequency(), minSupportedFrequency); - sensorObject.stop(); - assert_false(sensorObject.activated); - resolve(mockSensor); - }, reject); - sensorObject.onactivate = wrapper.callback; - sensorObject.onerror = reject; - }); - return mockSensor.removeConfigurationCalled(); - }, `${sensorType.name}: Test that frequency is limited to the minimum supported from frequency.`); - - sensor_test(async (t, sensorProvider) => { - let sensorObject = new sensorType({frequency: 60}); - assert_false(sensorObject.activated); - sensorObject.start(); - assert_false(sensorObject.activated); - - let mockSensor = await sensorProvider.getCreatedSensor(sensorType.name); - await new Promise((resolve, reject) => { - let wrapper = new CallbackWrapper(() => { - assert_true(sensorObject.activated); - sensorObject.stop(); - assert_false(sensorObject.activated); - resolve(mockSensor); - }, reject); - sensorObject.onactivate = wrapper.callback; - sensorObject.onerror = reject; - }); - return mockSensor.removeConfigurationCalled(); - }, `${sensorType.name}: Test that sensor can be successfully created and its states are correct.`); - - sensor_test(async (t, sensorProvider) => { - let sensorObject = new sensorType(); - sensorObject.start(); - - let mockSensor = await sensorProvider.getCreatedSensor(sensorType.name); - await new Promise((resolve, reject) => { - let wrapper = new CallbackWrapper(() => { - assert_true(sensorObject.activated); - sensorObject.stop(); - assert_false(sensorObject.activated); - resolve(mockSensor); - }, reject); - - sensorObject.onactivate = wrapper.callback; - sensorObject.onerror = reject; - }); - return mockSensor.removeConfigurationCalled(); - }, `${sensorType.name}: Test that sensor can be constructed with default configuration.`); - - sensor_test(async (t, sensorProvider) => { - let sensorObject = new sensorType({frequency: 60}); - sensorObject.start(); - - let mockSensor = await sensorProvider.getCreatedSensor(sensorType.name); - await mockSensor.addConfigurationCalled(); - await new Promise((resolve, reject) => { - let wrapper = new CallbackWrapper(() => { - assert_true(sensorObject.activated); - sensorObject.stop(); - assert_false(sensorObject.activated); - resolve(mockSensor); - }, reject); - sensorObject.onactivate = wrapper.callback; - sensorObject.onerror = reject; - }); - return mockSensor.removeConfigurationCalled(); - }, `${sensorType.name}: Test that addConfiguration and removeConfiguration is called.`); - - async function checkOnReadingIsCalledAndReadingIsValid(sensorProvider) { - let sensorObject = new sensorType({frequency: 60}); - sensorObject.start(); - assert_false(sensorObject.hasReading); - - let mockSensor = await sensorProvider.getCreatedSensor(sensorType.name); - await mockSensor.setSensorReading(readings); - await new Promise((resolve, reject) => { - let wrapper = new CallbackWrapper(() => { - const expected = new RingBuffer(expectedReadings).next().value; - assert_true(verificationFunction(expected, sensorObject)) - assert_true(sensorObject.hasReading); - sensorObject.stop(); - assert_true(verificationFunction(expected, sensorObject, - /*isNull=*/true)) - assert_false(sensorObject.hasReading); - resolve(mockSensor); - }, reject); - - sensorObject.onreading = wrapper.callback; - sensorObject.onerror = reject; - }); - return mockSensor.removeConfigurationCalled(); - } - - sensor_test((t, sensorProvider) => checkOnReadingIsCalledAndReadingIsValid(sensorProvider), - `${sensorType.name}: Test that onreading is called and sensor reading is valid (onchange reporting).`); - - sensor_test((t, sensorProvider) => { - sensorProvider.setContinuousReportingMode(); - return checkOnReadingIsCalledAndReadingIsValid(sensorProvider); - }, `${sensorType.name}: Test that onreading is called and sensor reading is valid (continuous reporting).`); - - sensor_test(async (t, sensorProvider) => { - let sensorObject = new sensorType({frequency: 60}); - sensorObject.start(); - - let mockSensor = await sensorProvider.getCreatedSensor(sensorType.name); - await mockSensor.setSensorReading(readings); - await new Promise((resolve, reject) => { - let wrapper = new CallbackWrapper(() => { - const expected = new RingBuffer(expectedReadings).next().value; - assert_true(verificationFunction(expected, sensorObject)); - resolve(mockSensor); - }, reject); - - sensorObject.onreading = wrapper.callback; - sensorObject.onerror = reject; - }); - testRunner.setPageVisibility('hidden'); - await mockSensor.suspendCalled(); - - testRunner.setPageVisibility('visible'); - await mockSensor.resumeCalled(); - - sensorObject.stop(); - await mockSensor.removeConfigurationCalled(); - }, `${sensorType.name}: Test that sensor receives suspend / resume notifications when page\ - visibility changes.`); - - sensor_test(async (t, sensorProvider) => { - let sensorObject = new sensorType({frequency: 60}); - sensorObject.start(); - - // Create a focused editbox inside a cross-origin iframe, sensor notification must suspend. - const iframeSrc = 'data:text/html;charset=utf-8,<html><body><input id="edit" type="text"><script>document.getElementById("edit").focus();</script></body></html>'; - let iframe = document.createElement('iframe'); - iframe.src = encodeURI(iframeSrc); - iframe.allow = "focus-without-user-activation"; - - let mockSensor = await sensorProvider.getCreatedSensor(sensorType.name); - await mockSensor.setSensorReading(readings); - await new Promise((resolve, reject) => { - let wrapper = new CallbackWrapper(() => { - const expected = new RingBuffer(expectedReadings).next().value; - assert_true(verificationFunction(expected, sensorObject)); - resolve(mockSensor); - }, reject); - - sensorObject.onreading = wrapper.callback; - sensorObject.onerror = reject; - }); - - document.body.appendChild(iframe); - await mockSensor.suspendCalled(); - - window.focus(); - await mockSensor.resumeCalled(); - - sensorObject.stop(); - document.body.removeChild(iframe); - return mockSensor.removeConfigurationCalled(); - }, `${sensorType.name}: Test that sensor receives suspend / resume notifications when\ - cross-origin subframe is focused`); - - sensor_test(async (t, sensorProvider) => { - let sensor1 = new sensorType({frequency: 60}); - sensor1.start(); - - let sensor2 = new sensorType({frequency: 20}); - sensor2.start(); - - let mockSensor = await sensorProvider.getCreatedSensor(sensorType.name); - await mockSensor.setSensorReading(readings); - await new Promise((resolve, reject) => { - let wrapper = new CallbackWrapper(() => { - const expected = new RingBuffer(expectedReadings).next().value; - - // Reading values are correct for both sensors. - assert_true(verificationFunction(expected, sensor1)); - assert_true(verificationFunction(expected, sensor2)); - - // After first sensor stops its reading values are null, - // reading values for the second sensor sensor remain. - sensor1.stop(); - - assert_true(verificationFunction(expected, sensor1, - /*isNull=*/true)); - assert_true(verificationFunction(expected, sensor2)); - - sensor2.stop(); - assert_true(verificationFunction(expected, sensor2, - /*isNull=*/true)); - - resolve(mockSensor); - }, reject); - - sensor1.onreading = wrapper.callback; - sensor1.onerror = reject; - sensor2.onerror = reject; - }); - return mockSensor.removeConfigurationCalled(); - }, `${sensorType.name}: Test that sensor reading is correct.`); - - async function checkFrequencyHintWorks(sensorProvider) { - let fastSensor = new sensorType({frequency: 60}); - fastSensor.start(); - - let slowSensor; // To be initialized later. - - let mockSensor = await sensorProvider.getCreatedSensor(sensorType.name); - await mockSensor.setSensorReading(readings); - - await new Promise((resolve, reject) => { - let fastSensorNotifiedCounter = 0; - let slowSensorNotifiedCounter = 0; - - let slowSensorWrapper = new CallbackWrapper(() => { - // Skip the initial notification that always comes immediately. - if (slowSensorNotifiedCounter === 1) { - assert_true(fastSensorNotifiedCounter > 2, - "Fast sensor overtakes the slow one"); - fastSensor.stop(); - slowSensor.stop(); - resolve(mockSensor); - } - - slowSensorNotifiedCounter++; - }, reject); - - let fastSensorWrapper = new CallbackWrapper(() => { - if (fastSensorNotifiedCounter === 0) { - // For Magnetometer and ALS, the maximum frequency is less than 60Hz - // we make "slow" sensor 4 times slower than the actual applied - // frequency, so that the "fast" sensor will immediately overtake it - // despite the notification adjustments. - const slowFrequency = mockSensor.getSamplingFrequency() * 0.25; - slowSensor = new sensorType({frequency: slowFrequency}); - slowSensor.onreading = slowSensorWrapper.callback; - slowSensor.onerror = reject; - slowSensor.start(); - } - - fastSensorNotifiedCounter++; - }, reject); - - fastSensor.onreading = fastSensorWrapper.callback; - fastSensor.onerror = reject; - }); - return mockSensor.removeConfigurationCalled(); - } - - sensor_test((t, sensorProvider) => checkFrequencyHintWorks(sensorProvider), - `${sensorType.name}: Test that frequency hint works (onchange reporting).`); - - sensor_test((t, sensorProvider) => { - sensorProvider.setContinuousReportingMode(); - return checkFrequencyHintWorks(sensorProvider); - }, `${sensorType.name}: Test that frequency hint works (continuous reporting).`); - - promise_test(t => { - return new Promise((resolve,reject) => { - let iframe = document.createElement('iframe'); - iframe.allow = featurePolicies.join(' \'none\'; ') + ' \'none\';'; - iframe.srcdoc = '<script>' + - ' window.onmessage = message => {' + - ' if (message.data === "LOADED") {' + - ' try {' + - ' new ' + sensorType.name + '();' + - ' parent.postMessage("FAIL", "*");' + - ' } catch (e) {' + - ' parent.postMessage("PASS", "*");' + - ' }' + - ' }' + - ' };' + - '<\/script>'; - iframe.onload = () => iframe.contentWindow.postMessage('LOADED', '*'); - document.body.appendChild(iframe); - window.onmessage = message => { - if (message.data == 'PASS') { - resolve(); - } else if (message.data == 'FAIL') { - reject(); - } - } - }); - }, `${sensorType.name}: Test that sensor cannot be constructed within iframe disallowed to use feature policy.`); - - promise_test(t => { - return new Promise((resolve,reject) => { - let iframe = document.createElement('iframe'); - iframe.allow = featurePolicies.join(';') + ';'; - iframe.srcdoc = '<script>' + - ' window.onmessage = message => {' + - ' if (message.data === "LOADED") {' + - ' try {' + - ' new ' + sensorType.name + '();' + - ' parent.postMessage("PASS", "*");' + - ' } catch (e) {' + - ' parent.postMessage("FAIL", "*");' + - ' }' + - ' }' + - ' };' + - '<\/script>'; - iframe.onload = () => iframe.contentWindow.postMessage('LOADED', '*'); - document.body.appendChild(iframe); - window.onmessage = message => { - if (message.data == 'PASS') { - resolve(); - } else if (message.data == 'FAIL') { - reject(); - } - } - }); - }, `${sensorType.name}: Test that sensor can be constructed within an iframe allowed to use feature policy.`); - - sensor_test(async (t, sensorProvider) => { - let sensorObject = new sensorType({frequency: 60}); - let timestamp = 0; - sensorObject.start(); - - let mockSensor = await sensorProvider.getCreatedSensor(sensorType.name); - await mockSensor.setSensorReading(readings); - await new Promise((resolve, reject) => { - const expectedBuffer = new RingBuffer(expectedReadings); - - let wrapper1 = new CallbackWrapper(() => { - assert_true(sensorObject.hasReading); - const expected = expectedBuffer.next().value; - assert_true(verificationFunction(expected, sensorObject)); - timestamp = sensorObject.timestamp; - sensorObject.stop(); - - assert_false(sensorObject.hasReading); - sensorObject.onreading = wrapper2.callback; - sensorObject.start(); - }, reject); - - let wrapper2 = new CallbackWrapper(() => { - assert_true(sensorObject.hasReading); - // |readingData| may have a single reading/expectation value, and this - // is the second reading we are getting. For that case, make sure we - // also wrap around as if we had the same RingBuffer used in - // sensor-helpers.js. - const expected = expectedBuffer.next().value; - assert_true(verificationFunction(expected, sensorObject)); - // Make sure that 'timestamp' is already initialized. - assert_greater_than(timestamp, 0); - // Check that the reading is updated. - assert_greater_than(sensorObject.timestamp, timestamp); - sensorObject.stop(); - resolve(mockSensor); - }, reject); - - sensorObject.onreading = wrapper1.callback; - sensorObject.onerror = reject; - }); - return mockSensor.removeConfigurationCalled(); - }, `${sensorType.name}: Test that fresh reading is fetched on start().`); - - sensor_test(async (t, sensorProvider) => { - if (!expectedRemappedReadings) { - // The sensorType does not represent a spatial sensor. - return; - } - - let sensor1 = new sensorType({frequency: 60}); - let sensor2 = new sensorType({frequency: 60, referenceFrame: "screen"}); - - sensor1.start(); - sensor2.start(); - - let mockSensor = await sensorProvider.getCreatedSensor(sensorType.name); - await mockSensor.setSensorReading(readings); - await new Promise((resolve, reject) => { - let wrapper = new CallbackWrapper(() => { - const expected = new RingBuffer(expectedReadings).next().value; - const expectedRemapped = - new RingBuffer(expectedRemappedReadings).next().value; - - assert_true(verificationFunction(expected, sensor1)); - assert_true(verificationFunction(expectedRemapped, sensor2)); - - sensor1.stop(); - assert_true(verificationFunction(expected, sensor1, - /*isNull=*/true)); - assert_true(verificationFunction(expectedRemapped, sensor2)); - - sensor2.stop(); - assert_true(verificationFunction(expectedRemapped, sensor2, - /*isNull=*/true)); - - resolve(mockSensor); - }, reject); - - sensor1.onreading = wrapper.callback; - sensor1.onerror = reject; - sensor2.onerror = reject; - }); - return mockSensor.removeConfigurationCalled(); - }, `${sensorType.name}: Test that reading is mapped to the screen coordinates`); -}
diff --git a/third_party/blink/web_tests/sensor/resources/generic-sensor-utils.js b/third_party/blink/web_tests/sensor/resources/generic-sensor-utils.js deleted file mode 100644 index 8cad13b..0000000 --- a/third_party/blink/web_tests/sensor/resources/generic-sensor-utils.js +++ /dev/null
@@ -1,27 +0,0 @@ -'use strict'; - -function verifySensorReading(pattern, values, timestamp, isNull) { - function round(val) { - return Number.parseFloat(val).toPrecision(6); - } - - if (isNull) { - return (values === null || values.every(r => r === null)) && - timestamp === null; - } - - return values.every((r, i) => round(r) === round(pattern[i])) && - timestamp !== null; -} - -function verifyXyzSensorReading(pattern, {x, y, z, timestamp}, isNull) { - return verifySensorReading(pattern, [x, y, z], timestamp, isNull); -} - -function verifyQuatSensorReading(pattern, {quaternion, timestamp}, isNull) { - return verifySensorReading(pattern, quaternion, timestamp, isNull); -} - -function verifyAlsSensorReading(pattern, {illuminance, timestamp}, isNull) { - return verifySensorReading(pattern, [illuminance], timestamp, isNull); -}
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/pseudo-elements-visible-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/pseudo-elements-visible-ref.html new file mode 100644 index 0000000..f3357c75 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/pseudo-elements-visible-ref.html
@@ -0,0 +1,21 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: pseudo elements</title> +<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<style> + #container::before { + content: "a"; + color: blue; + } + #container::after { + content: "b"; + color: green; + } +</style> +<div id="log">PASS</div> +<div id="container"></div> +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/pseudo-elements-visible.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/pseudo-elements-visible.html new file mode 100644 index 0000000..441c4b4 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/pseudo-elements-visible.html
@@ -0,0 +1,41 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: pseudo elements</title> +<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="pseudo-elements-visible-ref.html"> +<script src="/common/reftest-wait.js"></script> +<script src="resources/utils.js"></script> + +<style> + #container::before { + content: "a"; + color: blue; + } + .hasAfter::after { + content: "b"; + color: green; + } +</style> +<div id="log"></div> +<div id="container" style="display:none;"></div> + +<script> + +function finishTest(status_string) { + if (document.getElementById("log").innerHTML === "") + document.getElementById("log").innerHTML = status_string; + takeScreenshot(); +} + +async function runTest() { + // Trigger reattachment in #container and the ::after pseudo element. + container.classList.add("hasAfter"); + container.style = ""; + setInvisible(container).then(() => { setVisible(container).then(() => {finishTest("PASS");}); }); +} + +window.onload = runTest; +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/pseudo-elements.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/pseudo-elements.html new file mode 100644 index 0000000..5f0962d41 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/pseudo-elements.html
@@ -0,0 +1,41 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: pseudo elements</title> +<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="pass-ref.html"> +<script src="/common/reftest-wait.js"></script> +<script src="resources/utils.js"></script> + +<style> + #container::before { + content: "a"; + color: blue; + } + .hasAfter::after { + content: "b"; + color: green; + } +</style> +<div id="log"></div> +<div id="container" style="display:none;"></div> + +<script> + +function finishTest(status_string) { + if (document.getElementById("log").innerHTML === "") + document.getElementById("log").innerHTML = status_string; + takeScreenshot(); +} + +async function runTest() { + // Trigger reattachment in #container and the ::after pseudo element. + container.classList.add("hasAfter"); + container.style = ""; + setInvisible(container).then(() => { finishTest("PASS");} ); +} + +window.onload = runTest; +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/selection-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/selection-ref.html index 7f0fd4c..4095552 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/selection-ref.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/selection-ref.html
@@ -15,11 +15,8 @@ width: 30px; height: 30px; } </style> -<div id="neighbor"> - neighbor -</div> <div id="container"> - <div> + <div id="notLocked"> not locked! </div> <div id="nonActivatable"> @@ -33,7 +30,7 @@ <script> window.getSelection().removeAllRanges(); const selectionRange = document.createRange(); - selectionRange.setStart(neighbor.firstChild, 4); + selectionRange.setStart(notLocked.firstChild, 4); selectionRange.setEnd(nested.firstChild, 7); window.getSelection().addRange(selectionRange); </script>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/selection-shadow.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/selection-shadow.html index 0e5f387..f2aafec 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/selection-shadow.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/selection-shadow.html
@@ -6,11 +6,7 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="selection-shadow-ref.html"> <script src="/common/reftest-wait.js"></script> -<style> - div { - contain: style layout; - } -</style> +<script src="resources/utils.js"></script> <div id="host"> <div id="slottedToFirst" slot="first"> @@ -39,8 +35,6 @@ async function runTest() { const shadowRoot = host.attachShadow({ mode: "open" }); - shadowRoot.innerHTML = "<style> div { contain: style layout; } </style>"; - const firstSlot = document.createElement("slot"); firstSlot.name = "first"; shadowRoot.appendChild(firstSlot); @@ -52,10 +46,13 @@ secondSlot.name = "second"; shadowRoot.appendChild(secondSlot); - // TODO(rakina): make this use rendersubtree once sizing is implemented. - await host.displayLock.acquire({ timeout: Infinity, activatable: true, size: [100, 100] }); - await nonActivatable.displayLock.acquire({ timeout: Infinity, activatable: false, size: [20, 20] }); - await slottedToFirst.displayLock.acquire({ timeout: Infinity, activatable: true, size: [40, 40] }); + host.style = "content-size: 100px 100px;" + nonActivatable.style = "content-size: 20px 20px;" + slottedToFirst.style = "content-size: 40px 40px;" + await setInvisibleActivatable(host); + await setInvisible(nonActivatable); + await setInvisibleActivatable(slottedToFirst); + window.getSelection().removeAllRanges(); const selectionRange = document.createRange(); selectionRange.setStart(slottedToFirst.firstChild, 8);
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/selection.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/selection.html index f06f7e4a..b1b68b0 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/selection.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/selection.html
@@ -6,19 +6,15 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="selection-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="resources/utils.js"></script> + <style> - div { - contain: style layout; - } #userSelectNone { user-select: none; } </style> -<div id="neighbor"> - neighbor -</div> <div id="container"> - <div> + <div id="notLocked"> not locked! </div> <div id="nonActivatable"> @@ -33,14 +29,18 @@ </div> <script> async function runTest() { - // TODO(rakina): make this use rendersubtree once sizing is implemented. - await container.displayLock.acquire({ timeout: Infinity, activatable: true, size: [100, 100] }); - await nonActivatable.displayLock.acquire({ timeout: Infinity, activatable: false, size: [20, 20] }); - await userSelectNone.displayLock.acquire({ timeout: Infinity, activatable: true, size: [30, 30] }); - await nested.displayLock.acquire({ timeout: Infinity, activatable: true, size: [40, 40] }); + container.style = "content-size: 100px 100px;" + nonActivatable.style = "content-size: 20px 20px;" + userSelectNone.style = "content-size: 30px 30px;" + nested.style = "content-size: 40px 40px;" + await setInvisibleActivatable(container); + await setInvisible(nonActivatable); + await setInvisibleActivatable(userSelectNone); + await setInvisibleActivatable(nested); + window.getSelection().removeAllRanges(); const selectionRange = document.createRange(); - selectionRange.setStart(neighbor.firstChild, 4); + selectionRange.setStart(notLocked.firstChild, 4); selectionRange.setEnd(nested.firstChild, 7); window.getSelection().addRange(selectionRange); requestAnimationFrame(takeScreenshot);
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/acquire-after-resize.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/acquire-after-resize.html index 04d5dab4..fceb7b6b3 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/acquire-after-resize.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/acquire-after-resize.html
@@ -6,16 +6,17 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="acquire-after-resize-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="../resources/utils.js"></script> <style> -.contained { - contain: style layout; -} #spacer { width: 50px; height: 50px; background: lightgreen; } +#small { + content-size: 150px 150px; +} </style> <div id="log"></div> @@ -31,7 +32,7 @@ function runTest() { const container = document.getElementById("small"); - container.displayLock.acquire({ timeout: Infinity, size: [150, 150] }).then( + setInvisible(container).then( () => { finishTest("PASS"); }, (e) => { finishTest("FAIL " + e.message); }); }
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/acquire-size-used-when-auto-size-border-and-scrollbars.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/acquire-size-used-when-auto-size-border-and-scrollbars.html index c87084b..ecb03a4 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/acquire-size-used-when-auto-size-border-and-scrollbars.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/acquire-size-used-when-auto-size-border-and-scrollbars.html
@@ -6,6 +6,7 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="acquire-size-used-when-auto-size-border-and-scrollbars-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="../resources/utils.js"></script> <style> #border { @@ -13,10 +14,10 @@ border: 1px solid green; } #container { - contain: style layout; background: lightblue; overflow: scroll; border: 10px solid black; + content-size: 123px 456px; } #child { width: 500px; @@ -35,7 +36,7 @@ <script> async function runTest() { const container = document.getElementById("container"); - await container.displayLock.acquire({ timeout: Infinity, size: [123, 456] }); + await setInvisible(container); takeScreenshot(); }
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/acquire-size-used-when-auto-size-border-min-content.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/acquire-size-used-when-auto-size-border-min-content.html index 22c76246..fbad481 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/acquire-size-used-when-auto-size-border-min-content.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/acquire-size-used-when-auto-size-border-min-content.html
@@ -6,6 +6,7 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="acquire-size-used-when-auto-size-border-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="../resources/utils.js"></script> <style> #border { @@ -13,8 +14,8 @@ border: 1px solid green; } #container { - contain: style layout; border: 10px solid black; + content-size: 123px 456px; } #child { width: 500px; @@ -40,7 +41,7 @@ function runTest() { let container = document.getElementById("container"); - container.displayLock.acquire({ timeout: Infinity, size: [123, 456] }).then(finishTest); + setInvisible(container).then(finishTest); } window.onload = runTest;
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/acquire-size-used-when-auto-size-border.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/acquire-size-used-when-auto-size-border.html index 9d83a769..05ba535a 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/acquire-size-used-when-auto-size-border.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/acquire-size-used-when-auto-size-border.html
@@ -6,6 +6,7 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="acquire-size-used-when-auto-size-border-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="../resources/utils.js"></script> <style> #border { @@ -13,8 +14,8 @@ border: 1px solid green; } #container { - contain: style layout; border: 10px solid black; + content-size: 123px 456px; } #child { width: 500px; @@ -32,7 +33,7 @@ <script> async function runTest() { const container = document.getElementById("container"); - await container.displayLock.acquire({ timeout: Infinity, size: [123, 456] }); + await setInvisible(container); takeScreenshot(); }
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/acquire-size-used-when-auto-size-scrollbars.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/acquire-size-used-when-auto-size-scrollbars.html index 5463e13..661f28e1 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/acquire-size-used-when-auto-size-scrollbars.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/acquire-size-used-when-auto-size-scrollbars.html
@@ -6,6 +6,7 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="acquire-size-used-when-auto-size-scrollbars-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="../resources/utils.js"></script> <style> #border { @@ -13,8 +14,8 @@ border: 1px solid green; } #container { - contain: style layout; overflow: scroll; + content-size: 123px 456px; } #child { width: 500px; @@ -32,7 +33,7 @@ <script> async function runTest() { const container = document.getElementById("container"); - await container.displayLock.acquire({ timeout: Infinity, size: [123, 456] }); + await setInvisible(container); takeScreenshot(); }
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/acquire-size-used-when-auto-size.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/acquire-size-used-when-auto-size.html index 15a460be..266e2a1 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/acquire-size-used-when-auto-size.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/acquire-size-used-when-auto-size.html
@@ -6,6 +6,7 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="acquire-size-used-when-auto-size-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="../resources/utils.js"></script> <style> #border { @@ -13,7 +14,7 @@ border: 1px solid green; } #container { - contain: style layout; + content-size: 123px 456px; } #child { width: 500px; @@ -31,7 +32,7 @@ <script> async function runTest() { const container = document.getElementById("container"); - await container.displayLock.acquire({ timeout: Infinity, size: [123, 456] }); + await setInvisible(container); takeScreenshot(); }
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/reacquire-different-size.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/change-content-size.html similarity index 68% rename from third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/reacquire-different-size.html rename to third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/change-content-size.html index e95a8b2..5e8a83be 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/reacquire-different-size.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/change-content-size.html
@@ -6,10 +6,11 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="acquire-after-resize-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="../resources/utils.js"></script> <style> .contained { - contain: style layout; + content-size: 123px 456px; } #spacer { width: 50px; @@ -31,17 +32,13 @@ function runTest() { const container = document.getElementById("small"); - container.displayLock.acquire({ timeout: Infinity, size: [123, 456] }).then( - () => { - // Re-acquire with a different size. - container.displayLock.acquire({ timeout: Infinity, size: [150, 150] }).then( - () => { finishTest("PASS"); }, - (e) => { finishTest("FAIL " + e.message); }); - }, - (e) => { finishTest("FAIL " + e.message); } - ); + setInvisible(container).then(() => { + container.style = "content-size: 150px 150px"; + requestAnimationFrame(() => finishTest("PASS")); + }); } window.onload = runTest; </script> </html> +
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/contain-size-block-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/contain-size-block-ref.html index 31998cb..0f74b4b 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/contain-size-block-ref.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/contain-size-block-ref.html
@@ -11,5 +11,6 @@ width: min-content; } </style> -<div id="border"></div> +<div id="border"> +</div> </html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/contain-size-block.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/contain-size-block.html index d5d6562..0c0fe70 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/contain-size-block.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/contain-size-block.html
@@ -6,6 +6,7 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="contain-size-block-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="../resources/utils.js"></script> <style> #border { @@ -14,6 +15,7 @@ } #container { contain: style layout size; + content-size: none; } </style> @@ -24,7 +26,7 @@ <script> function runTest() { const container = document.getElementById("container"); - container.displayLock.acquire({ timeout: Infinity, size: [123, 345] }).then(() => { + setInvisible(container).then(() => { takeScreenshot(); }); }
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/contain-size-fieldset-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/contain-size-fieldset-ref.html new file mode 100644 index 0000000..8867824 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/contain-size-fieldset-ref.html
@@ -0,0 +1,24 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: fieldset with legend and size containment, sized by display lock</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<style> +#border { + border: 1px solid black; + width: min-content; +} +#container { + width: 123px; + height: 234px; +} +</style> + +<div id="border"> + <fieldset id="container"> + </fieldset> +</div> + +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/contain-size-fieldset.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/contain-size-fieldset.html index 2d653cc7..58bd9dd 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/contain-size-fieldset.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/contain-size-fieldset.html
@@ -4,8 +4,9 @@ <title>Display Locking: fieldset with legend and size containment, sized by display lock</title> <link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> <link rel="help" href="https://github.com/WICG/display-locking"> -<link rel="match" href="fieldset-empty-ref.html"> +<link rel="match" href="contain-size-fieldset-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="../resources/utils.js"></script> <style> #border { @@ -13,7 +14,7 @@ width: min-content; } #container { - contain: style layout size; + content-size: 123px 234px; } </style> @@ -27,7 +28,7 @@ <script> async function runTest() { const container = document.getElementById("container"); - await container.displayLock.acquire({ timeout: Infinity, size: [123, 234] }); + await setInvisible(container); takeScreenshot(); }
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/contain-size-flex-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/contain-size-flex-ref.html index 4b5ac45..0a421444 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/contain-size-flex-ref.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/contain-size-flex-ref.html
@@ -16,6 +16,8 @@ } #container { contain: style layout size; + width: 12px; + height: 34px; } .item { width: 50px;
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/contain-size-flex.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/contain-size-flex.html index d8d9076d..5220b2e 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/contain-size-flex.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/contain-size-flex.html
@@ -6,6 +6,8 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="contain-size-flex-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="../resources/utils.js"></script> + <style> #flexer { @@ -17,7 +19,7 @@ background: lightgreen; } #container { - contain: style layout size; + content-size: 12px 34px; } .item { width: 50px; @@ -35,7 +37,7 @@ <script> async function runTest() { const container = document.getElementById("container"); - await container.displayLock.acquire({ timeout: Infinity, size: [12, 34] }); + await setInvisible(container); takeScreenshot(); }
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/contain-size-replaced.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/contain-size-replaced.html index 66645358..91bbcef 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/contain-size-replaced.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/contain-size-replaced.html
@@ -6,6 +6,7 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="contain-size-replaced-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="../resources/utils.js"></script> <style> #border { @@ -13,7 +14,7 @@ width: max-content; } img { - contain: style layout size; + content-size: none; } </style> @@ -24,7 +25,7 @@ <script> async function runTest() { const element = document.getElementById("element"); - await element.displayLock.acquire({ timeout: Infinity, size: [12, 34] }); + await setInvisible(element); takeScreenshot(); }
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/fieldset-empty.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/fieldset-empty.html index a2edd61..edb09522 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/fieldset-empty.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/fieldset-empty.html
@@ -6,6 +6,7 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="fieldset-empty-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="../resources/utils.js"></script> <style> #border { @@ -13,7 +14,7 @@ width: min-content; } #container { - contain: style layout; + content-size: 0px 0px; } </style> @@ -24,7 +25,7 @@ <script> async function runTest() { const container = document.getElementById("container"); - await container.displayLock.acquire({ timeout: Infinity, size: [0, 0] }); + await setInvisible(container); takeScreenshot(); }
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/fieldset-with-legend-sized.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/fieldset-with-legend-sized.html index 9b28cb7..622ad4cbf 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/fieldset-with-legend-sized.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/fieldset-with-legend-sized.html
@@ -6,6 +6,7 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="fieldset-with-legend-sized-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="../resources/utils.js"></script> <style> #border { @@ -13,7 +14,7 @@ width: min-content; } #container { - contain: style layout; + content-size: 123px 234px; } </style> @@ -27,7 +28,7 @@ <script> async function runTest() { const container = document.getElementById("container"); - await container.displayLock.acquire({ timeout: Infinity, size: [123, 234] }); + await setInvisible(container); takeScreenshot(); }
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/fieldset-with-legend.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/fieldset-with-legend.html index b0faa5ae..d1f40f9 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/fieldset-with-legend.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/fieldset-with-legend.html
@@ -6,6 +6,7 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="fieldset-empty-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="../resources/utils.js"></script> <style> #border { @@ -13,7 +14,7 @@ width: min-content; } #container { - contain: style layout; + content-size: 0px 0px; } </style> @@ -26,7 +27,7 @@ <script> async function runTest() { const container = document.getElementById("container"); - await container.displayLock.acquire({ timeout: Infinity, size: [0, 0] }); + await setInvisible(container); takeScreenshot(); }
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-column-horizontal-with-grow.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-column-horizontal-with-grow.html index 90413e994..8e34ec7 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-column-horizontal-with-grow.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-column-horizontal-with-grow.html
@@ -6,6 +6,7 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="flex-column-horizontal-with-grow-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="../resources/utils.js"></script> <style> #flexer { @@ -18,7 +19,7 @@ writing-mode: horizontal-tb; } #container { - contain: style layout; + content-size: 12px 34px; flex-grow: 3; } .item { @@ -38,7 +39,7 @@ <script> async function runTest() { const container = document.getElementById("container"); - await container.displayLock.acquire({ timeout: Infinity, size: [12, 34] }); + await setInvisible(container); takeScreenshot(); }
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-column-horizontal.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-column-horizontal.html index bea81a8..0fda2de 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-column-horizontal.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-column-horizontal.html
@@ -6,6 +6,7 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="flex-column-horizontal-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="../resources/utils.js"></script> <style> #flexer { @@ -18,7 +19,7 @@ writing-mode: horizontal-tb; } #container { - contain: style layout; + content-size: 12px 34px; } .item { width: 50px; @@ -36,7 +37,7 @@ <script> async function runTest() { const container = document.getElementById("container"); - await container.displayLock.acquire({ timeout: Infinity, size: [12, 34] }); + await setInvisible(container); takeScreenshot(); }
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-column-vertical-with-grow.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-column-vertical-with-grow.html index 35a481b..ee6409a 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-column-vertical-with-grow.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-column-vertical-with-grow.html
@@ -6,6 +6,7 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="flex-column-vertical-with-grow-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="../resources/utils.js"></script> <style> #flexer { @@ -18,7 +19,7 @@ writing-mode: vertical-rl; } #container { - contain: style layout; + content-size: 12px 34px; flex-grow: 3; } .item { @@ -38,7 +39,7 @@ <script> async function runTest() { const container = document.getElementById("container"); - await container.displayLock.acquire({ timeout: Infinity, size: [12, 34] }); + await setInvisible(container); takeScreenshot(); }
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-column-vertical.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-column-vertical.html index 3269fde..7d4ea745 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-column-vertical.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-column-vertical.html
@@ -6,6 +6,7 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="flex-column-vertical-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="../resources/utils.js"></script> <style> #flexer { @@ -18,6 +19,7 @@ writing-mode: vertical-rl; } #container { + content-size: 12px 34px; contain: style layout; } .item { @@ -36,7 +38,7 @@ <script> async function runTest() { const container = document.getElementById("container"); - await container.displayLock.acquire({ timeout: Infinity, size: [12, 34] }); + await setInvisible(container); takeScreenshot(); }
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-row-horizontal-with-grow.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-row-horizontal-with-grow.html index 42a0ebe..2983948 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-row-horizontal-with-grow.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-row-horizontal-with-grow.html
@@ -6,6 +6,7 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="flex-row-horizontal-with-grow-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="../resources/utils.js"></script> <style> #flexer { @@ -18,7 +19,7 @@ writing-mode: horizontal-tb; } #container { - contain: style layout; + content-size: 12px 34px; flex-grow: 3; } .item { @@ -38,7 +39,7 @@ <script> async function runTest() { const container = document.getElementById("container"); - await container.displayLock.acquire({ timeout: Infinity, size: [12, 34] }); + await setInvisible(container); takeScreenshot(); }
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-row-horizontal.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-row-horizontal.html index ca328918..028ab10 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-row-horizontal.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-row-horizontal.html
@@ -6,6 +6,7 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="flex-row-horizontal-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="../resources/utils.js"></script> <style> #flexer { @@ -18,7 +19,7 @@ writing-mode: horizontal-tb; } #container { - contain: style layout; + content-size: 12px 34px; } .item { width: 50px; @@ -36,7 +37,7 @@ <script> async function runTest() { const container = document.getElementById("container"); - await container.displayLock.acquire({ timeout: Infinity, size: [12, 34] }); + await setInvisible(container); takeScreenshot(); }
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-row-vertical-with-grow.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-row-vertical-with-grow.html index a886c57..700fa523 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-row-vertical-with-grow.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-row-vertical-with-grow.html
@@ -6,6 +6,7 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="flex-row-vertical-with-grow-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="../resources/utils.js"></script> <style> #flexer { @@ -18,7 +19,7 @@ writing-mode: vertical-rl; } #container { - contain: style layout; + content-size: 12px 34px; flex-grow: 3; } .item { @@ -38,7 +39,7 @@ <script> async function runTest() { const container = document.getElementById("container"); - await container.displayLock.acquire({ timeout: Infinity, size: [12, 34] }); + await setInvisible(container); takeScreenshot(); }
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-row-vertical.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-row-vertical.html index 3080430e..cac60d88 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-row-vertical.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-row-vertical.html
@@ -6,6 +6,7 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="flex-row-vertical-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="../resources/utils.js"></script> <style> #flexer { @@ -18,7 +19,7 @@ writing-mode: vertical-rl; } #container { - contain: style layout; + content-size: 12px 34px; } .item { width: 50px; @@ -36,7 +37,7 @@ <script> async function runTest() { const container = document.getElementById("container"); - await container.displayLock.acquire({ timeout: Infinity, size: [12, 34] }); + await setInvisible(container); takeScreenshot(); }
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-with-child-lock.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-with-child-lock.html index 0a9af37..dd12ec2 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-with-child-lock.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-with-child-lock.html
@@ -6,6 +6,7 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="flex-with-child-lock-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="../resources/utils.js"></script> <style> #flexer { @@ -15,7 +16,7 @@ background: lightgreen; } #container { - contain: style layout; + content-size: 123px 234px; background: lightblue; } </style> @@ -29,7 +30,7 @@ <script> async function runTest() { const container = document.getElementById("container"); - await container.displayLock.acquire({ timeout: Infinity, size: [123, 234] }); + await setInvisible(container); takeScreenshot(); }
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-with-descendant-lock.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-with-descendant-lock.html index 471d9df..96801ffc 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-with-descendant-lock.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-with-descendant-lock.html
@@ -6,6 +6,7 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="flex-with-descendant-lock-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="../resources/utils.js"></script> <style> #flexer { @@ -15,7 +16,7 @@ background: lightgreen; } #container { - contain: style layout; + content-size: 123px 234px; background: lightblue; } </style> @@ -31,7 +32,7 @@ <script> async function runTest() { const container = document.getElementById("container"); - await container.displayLock.acquire({ timeout: Infinity, size: [123, 234] }); + await setInvisible(container); takeScreenshot(); }
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/float-left.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/float-left.html index 884ac89..4a46f137 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/float-left.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/float-left.html
@@ -6,6 +6,7 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="float-left-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="../resources/utils.js"></script> <style> #border { @@ -13,8 +14,8 @@ border: 1px solid green; } #container { - contain: style layout; float: left; + content-size: 123px 456px; } #child { width: 500px; @@ -33,7 +34,7 @@ <script> async function runTest() { const container = document.getElementById("container"); - await container.displayLock.acquire({ timeout: Infinity, size: [123, 456] }); + await setInvisible(container); takeScreenshot(); }
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/get-bounding-client-rect-block-layout-in-iframe.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/get-bounding-client-rect-block-layout-in-iframe.html index bdab4eb6..770e62e2 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/get-bounding-client-rect-block-layout-in-iframe.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/get-bounding-client-rect-block-layout-in-iframe.html
@@ -7,12 +7,11 @@ <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="../resources/utils.js"></script> <style> #container { - contain: style layout; - width: 123px; - height: 234px; + content-size: 123px 234px; } #frame { padding: 0; @@ -48,7 +47,7 @@ await load_promise; const container = document.getElementById("container"); - await container.displayLock.acquire({ timeout: Infinity }); + await setInvisible(container); const frame = document.getElementById("frame"); frame.style.width = "224px";
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/get-bounding-client-rect-block-layout.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/get-bounding-client-rect-block-layout.html index bbe152d5..e389b0e 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/get-bounding-client-rect-block-layout.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/get-bounding-client-rect-block-layout.html
@@ -7,44 +7,75 @@ <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="../resources/utils.js"></script> -<style> -div { - contain: style layout; -} -</style> <body> <script> const BODY_WIDTH = document.body.getBoundingClientRect().width; -const ACQUIRE_WIDTH = 33; -const ACQUIRE_HEIGHT = 44; +const CONTENT_WIDTH = 33; +const CONTENT_HEIGHT = 44; async_test(async(t) => { let container = document.createElement("div"); - container.style = "width: min-content;"; let child = document.createElement("div"); container.appendChild(child); document.body.appendChild(container); - await container.displayLock.acquire({ timeout: Infinity, size: [ACQUIRE_WIDTH, ACQUIRE_HEIGHT] }); + container.style = "content-size: ${CONTENT_WIDTH}px ${CONTENT_HEIGHT}px;"; + await setInvisible(container); let rect = container.getBoundingClientRect(); - t.step(() => assert_equals(rect.width, ACQUIRE_WIDTH, - "Locked element with min-content uses width from acquire()")); - t.step(() => assert_equals(rect.height, ACQUIRE_HEIGHT, - "Locked element with min-content uses height from acquire()")); + t.step(() => assert_equals(rect.width, CONTENT_WIDTH, + "Locked element uses width from content-size")); + t.step(() => assert_equals(rect.height, CONTENT_HEIGHT, + "Locked element uses height from content-size")); rect = child.getBoundingClientRect(); - t.step(() => assert_equals(rect.width, ACQUIRE_WIDTH, - "Child of locked element with min-content uses width from acquire()")); + t.step(() => assert_equals(rect.width, CONTENT_WIDTH, + "Child of locked element with no content uses width from content-size")); + t.step(() => assert_equals(rect.height, 0, + "Child of locked element with no content has zero height")); + + child.style = "width: 100px; height: 200px;"; + rect = container.getBoundingClientRect(); + t.step(() => assert_equals(rect.width, CONTENT_WIDTH, + "Locked element with sized child uses width from content-size")); + t.step(() => assert_equals(rect.height, CONTENT_HEIGHT, + "Locked element with sized child uses height from content-size")); + rect = child.getBoundingClientRect(); + t.step(() => assert_equals(rect.width, 100, + "Child of locked element uses width from style")); + t.step(() => assert_equals(rect.height, 200, + "Child of locked element uses height from style")); + + t.done(); +}, "getBoundingClientRect"); + +async_test(async(t) => { + let container = document.createElement("div"); + let child = document.createElement("div"); + container.appendChild(child); + document.body.appendChild(container); + container.style = "width: min-content; content-size: ${CONTENT_WIDTH}px ${CONTENT_HEIGHT}px;"; + await setInvisible(container); + + let rect = container.getBoundingClientRect(); + t.step(() => assert_equals(rect.width, CONTENT_WIDTH, + "Locked element with min-content uses width from content-size")); + t.step(() => assert_equals(rect.height, CONTENT_HEIGHT, + "Locked element with min-content uses height from content-size")); + + rect = child.getBoundingClientRect(); + t.step(() => assert_equals(rect.width, CONTENT_WIDTH, + "Child of locked element with min-content & no content uses width from content-size")); t.step(() => assert_equals(rect.height, 0, "Child of locked element with min-content & no content has zero height")); child.style = "width: 100px; height: 200px;"; rect = container.getBoundingClientRect(); - t.step(() => assert_equals(rect.width, ACQUIRE_WIDTH, - "Locked element with min-content and sized child uses width from acquire()")); - t.step(() => assert_equals(rect.height, ACQUIRE_HEIGHT, - "Locked element with min-content and sized child uses height from acquire()")); + t.step(() => assert_equals(rect.width, CONTENT_WIDTH, + "Locked element with min-content and sized child uses width from content-size")); + t.step(() => assert_equals(rect.height, CONTENT_HEIGHT, + "Locked element with min-content and sized child uses height from content-size")); rect = child.getBoundingClientRect(); t.step(() => assert_equals(rect.width, 100, "Child of locked element with min-content uses width from style")); @@ -56,58 +87,40 @@ async_test(async(t) => { let container = document.createElement("div"); - document.body.appendChild(container); - await container.displayLock.acquire({ timeout: Infinity, size: [ACQUIRE_WIDTH, ACQUIRE_HEIGHT] }); - let rect = container.getBoundingClientRect(); - - t.step(() => assert_equals(rect.width, BODY_WIDTH, - "Locked element uses width from body")); - t.step(() => assert_equals(rect.height, ACQUIRE_HEIGHT, - "Locked element uses height from acquire()")); - - await container.displayLock.acquire({ timeout: Infinity, size: [55, 66] }); - rect = container.getBoundingClientRect(); - t.step(() => assert_equals(rect.width, BODY_WIDTH, - "After re-acquire, locked element still uses width from body")); - t.step(() => assert_equals(rect.height, 66, - "After re-acquire, locked element uses height from the last acquire()")); - t.done(); -}, "getBoundingClientRect with re-acquire"); - -async_test(async (t) => { - let container = document.createElement("div"); - container.style = "width: 11px; height: 22px;"; let child = document.createElement("div"); container.appendChild(child); document.body.appendChild(container); - - await container.displayLock.acquire({ timeout: Infinity, size: [ACQUIRE_WIDTH, ACQUIRE_HEIGHT] }); - + container.style = "content-size: ${CONTENT_WIDTH}px ${CONTENT_HEIGHT}px;"; + await setInvisible(container); let rect = container.getBoundingClientRect(); - t.step(() => assert_equals(rect.width, 11, - "Styled locked element uses width from style")); - t.step(() => assert_equals(rect.height, 22, - "Styled locked element uses height from style")); - rect = child.getBoundingClientRect(); - t.step(() => assert_equals(rect.width, 11, - "Child of styled locked element uses width from locked element's style")); - t.step(() => assert_equals(rect.height, 0, - "Child of styled locked element with no content has zero height")); - container.style = ""; + t.step(() => assert_equals(rect.width, CONTENT_WIDTH, + "Locked element uses width from content-size")); + t.step(() => assert_equals(rect.height, CONTENT_HEIGHT, + "Locked element uses height from content-size")); + + rect = child.getBoundingClientRect(); + t.step(() => assert_equals(rect.width, CONTENT_WIDTH, + "Child of locked element with no content uses width from content-size")); + t.step(() => assert_equals(rect.height, 0, + "Child of locked element with no content has zero height")); + + container.style = "content-size: 55px 66px;"; rect = container.getBoundingClientRect(); - t.step(() => assert_equals(rect.width, BODY_WIDTH, - "Unstyled locked element uses width from body")); - t.step(() => assert_equals(rect.height, ACQUIRE_HEIGHT, - "Unstyled locked element uses height given in acquire()")); + t.step(() => assert_equals(rect.width, 55, + "After content-size change, locked element usese width from newest content-size")); + t.step(() => assert_equals(rect.height, 66, + "After content-sizechange , locked element uses height from newest content-size")); rect = child.getBoundingClientRect(); - t.step(() => assert_equals(rect.width, BODY_WIDTH, - "Child of unstyled locked element uses width from locked element's width")); + t.step(() => assert_equals(rect.width, 55, + "Child of locked element with no content uses width from neweest content-size")); t.step(() => assert_equals(rect.height, 0, - "Child of unstyled locked element with no content has zero height")); + "Child of locked element with no content has zero height")); + + t.done(); -}, "getBoundingClientRect with styled width & height"); +}, "getBoundingClientRect with changed content-size"); </script> </body> </html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/layout-replaced.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/layout-replaced.html index c2ef7627..90b1c76 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/layout-replaced.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/layout-replaced.html
@@ -6,14 +6,15 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="layout-replaced-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="../resources/utils.js"></script> <style> #border { border: 1px solid blue; width: max-content; } -img { - contain: style layout; +#element { + content-size: 12px 34px; } </style> @@ -24,7 +25,7 @@ <script> async function runTest() { const element = document.getElementById("element"); - await element.displayLock.acquire({ timeout: Infinity, size: [12, 34] }); + await setInvisible(element); takeScreenshot(); }
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/max-content-size-ignored.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/max-content-size-ignored.html index 4e05a42..1a1ee282 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/max-content-size-ignored.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/max-content-size-ignored.html
@@ -6,6 +6,8 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="max-content-size-ignored-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="../resources/utils.js"></script> + <style> #border { @@ -13,8 +15,8 @@ border: 1px solid green; } #container { - contain: style layout; width: max-content; + content-size: 123px 456px; } #child { width: 500px; @@ -32,7 +34,7 @@ <script> async function runTest() { const container = document.getElementById("container"); - await container.displayLock.acquire({ timeout: Infinity, size: [123, 456] }); + await setInvisible(container); takeScreenshot(); }
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/measure-forced-layout-after-commit.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/measure-forced-layout-after-commit.html index 0cb1d21..512d346 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/measure-forced-layout-after-commit.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/measure-forced-layout-after-commit.html
@@ -4,10 +4,11 @@ <title>Display Locking: measure forced layout after commit</title> <link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> <link rel="help" href="https://github.com/WICG/display-locking"> +<script src="../resources/utils.js"></script> <style> .contained { - contain: style layout; + content-size: 100px 100px; background: lightgreen; } #large { @@ -73,12 +74,12 @@ async function runTest() { const container = document.getElementById("small"); - await container.displayLock.acquire({ timeout: Infinity, size: [100, 100] }); + await setInvisible(container); construct(document.getElementById("large")); measureForced(); - container.displayLock.commit(); + await setVisible(container); forcedMeasureAfterCommit(); t.done(); }
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/measure-forced-layout.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/measure-forced-layout.html index ef16011..0b44fba 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/measure-forced-layout.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/measure-forced-layout.html
@@ -4,10 +4,11 @@ <title>Display Locking: measure forced layout</title> <link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> <link rel="help" href="https://github.com/WICG/display-locking"> +<script src="../resources/utils.js"></script> <style> .contained { - contain: style layout; + content-size: 100px 100px; background: lightgreen; } #large { @@ -73,12 +74,12 @@ async function runTest() { const container = document.getElementById("small"); - await container.displayLock.acquire({ timeout: Infinity, size: [100, 100] }); + await setInvisible(container); construct(document.getElementById("large")); measureForced(); - container.displayLock.commit().then(() => { + setVisible(container).then(() => { measureInCommit(); t.done(); });
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/measure-updated-layout.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/measure-updated-layout.html index 3d2d94a..47ab110 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/measure-updated-layout.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/measure-updated-layout.html
@@ -4,10 +4,11 @@ <title>Display Locking: measure updated layout</title> <link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> <link rel="help" href="https://github.com/WICG/display-locking"> +<script src="../resources/utils.js"></script> <style> .contained { - contain: style layout; + content-size: 100px 100px; background: lightgreen; } #large { @@ -73,13 +74,13 @@ async function runTest() { const container = document.getElementById("small"); - await container.displayLock.acquire({ timeout: Infinity, size: [100, 100] }); + await setInvisible(container); construct(document.getElementById("large")); container.displayLock.update().then(() => { measureInUpdate(); - container.displayLock.commit().then(() => { + setVisible(container).then(() => { measureInCommit(); t.done(); });
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/min-width-respected.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/min-width-respected.html index 1b5f869..8581848 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/min-width-respected.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/min-width-respected.html
@@ -6,6 +6,7 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="min-width-respected-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="../resources/utils.js"></script> <style> #border { @@ -13,7 +14,7 @@ border: 1px solid green; } #container { - contain: style layout; + content-size: 123px 456px; min-width: 157px; } #child { @@ -32,7 +33,7 @@ <script> async function runTest() { const container = document.getElementById("container"); - await container.displayLock.acquire({ timeout: Infinity, size: [123, 456] }); + await setInvisible(container); takeScreenshot(); }
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/overflow-auto-with-overflow.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/overflow-auto-with-overflow.html index d98b251..3356927 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/overflow-auto-with-overflow.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/overflow-auto-with-overflow.html
@@ -6,6 +6,7 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="overflow-auto-with-overflow-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="../resources/utils.js"></script> <style> #border { @@ -13,7 +14,7 @@ width: max-content; } #container { - contain: style layout; + content-size: 12px 34px; height: 100px; overflow: auto; } @@ -37,7 +38,7 @@ <script> async function runTest() { const container = document.getElementById("container"); - await container.displayLock.acquire({ timeout: Infinity, size: [12, 34] }); + await setInvisible(container); takeScreenshot(); }
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/writing-modes-inherited-after-append.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/writing-modes-inherited-after-append.html index d2f87276..99a4ac5aa 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/writing-modes-inherited-after-append.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/writing-modes-inherited-after-append.html
@@ -6,6 +6,7 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="writing-modes-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="../resources/utils.js"></script> <style> .verticalrl { @@ -23,7 +24,7 @@ } .box { background: lightblue; - contain: style layout; + content-size: 12px 34px; border-color: blue; border-style: solid; border-width: 1px 2px 3px 4px; @@ -57,7 +58,7 @@ let promises = [] for (let i = 0; i < items.length; ++i) { let clone = template_element.cloneNode(true); - promises.push(clone.displayLock.acquire({ timeout: Infinity, size: [12, 34] })); + promises.push(setInvisible(clone)); items[i].appendChild(clone); } await Promise.all(promises);
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/writing-modes-switch.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/writing-modes-switch.html index 57a0657..9de07503 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/writing-modes-switch.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/writing-modes-switch.html
@@ -6,6 +6,7 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="writing-modes-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="../resources/utils.js"></script> <style> .verticalrl { @@ -23,7 +24,7 @@ } .box { background: lightblue; - contain: style layout; + content-size: 12px 34px; border-color: blue; border-style: solid; border-width: 1px 2px 3px 4px; @@ -67,7 +68,7 @@ let items = document.getElementsByClassName("box"); let promises = [] for (let i = 0; i < items.length; ++i) { - promises.push(items[i].displayLock.acquire({ timeout: Infinity, size: [12, 34] })); + promises.push(setInvisible(items[i])); } await Promise.all(promises);
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/writing-modes.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/writing-modes.html index 69ce11d..18586a67 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/writing-modes.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/writing-modes.html
@@ -6,6 +6,7 @@ <link rel="help" href="https://github.com/WICG/display-locking"> <link rel="match" href="writing-modes-ref.html"> <script src="/common/reftest-wait.js"></script> +<script src="../resources/utils.js"></script> <style> .verticalrl { @@ -23,7 +24,7 @@ } .box { background: lightblue; - contain: style layout; + content-size: 12px 34px; border-color: blue; border-style: solid; border-width: 1px 2px 3px 4px; @@ -67,7 +68,7 @@ const items = document.getElementsByClassName("box"); const promises = [] for (let i = 0; i < items.length; ++i) { - promises.push(items[i].displayLock.acquire({ timeout: Infinity, size: [12, 34] })); + promises.push(setInvisible(items[i])); } await Promise.all(promises); takeScreenshot();
diff --git a/tools/android/elf_compression/compress_section.py b/tools/android/elf_compression/compress_section.py index 8980f6c2..52ad04d 100755 --- a/tools/android/elf_compression/compress_section.py +++ b/tools/android/elf_compression/compress_section.py
@@ -43,6 +43,48 @@ 'third_party/llvm-build/Release+Asserts/bin/llvm-objcopy') +def AlignUp(addr, page_size=ADDRESS_ALIGN): + """Rounds up given address to be aligned to page_size. + + Args: + addr: int. Virtual address to be aligned. + page_size: int. Page size to be used for the alignment. + """ + if addr % page_size != 0: + addr += page_size - (addr % page_size) + return addr + + +def AlignDown(addr, page_size=ADDRESS_ALIGN): + """Round down given address to be aligned to page_size. + + Args: + addr: int. Virtual address to be aligned. + page_size: int. Page size to be used for the alignment. + """ + return addr - addr % page_size + + +def MatchVaddrAlignment(vaddr, offset, align=ADDRESS_ALIGN): + """Align vaddr to comply with ELF standard binary alignment. + + Increases vaddr until the following is true: + vaddr % align == offset % align + + Args: + vaddr: virtual address to be aligned. + offset: file offset to be aligned. + align: alignment value. + + Returns: + Aligned virtual address, bigger or equal than the vaddr. + """ + delta = offset % align - vaddr % align + if delta < 0: + delta += align + return vaddr + delta + + def _SetupLogging(): logging.basicConfig( format='%(asctime)s %(filename)s:%(lineno)s %(levelname)s] %(message)s', @@ -79,7 +121,7 @@ """ elf = elf_headers.ElfHeader(data) for phdr in elf.GetPhdrs(): - if phdr.p_type == elf_headers.ProgramHeader.Type.PT_LOAD.value: + if phdr.p_type == elf_headers.ProgramHeader.Type.PT_LOAD: # Current version of the prototype only supports ranges which are fully # contained inside one LOAD segment. It should cover most of the common # cases. @@ -100,9 +142,8 @@ virtual_l, virtual_r = _FileRangeToVirtualAddressRange(data, l, r) # LOAD segments borders are being rounded to the page size so we have to # shrink [l, r) so corresponding virtual addresses are aligned. - if virtual_l % ADDRESS_ALIGN != 0: - l += ADDRESS_ALIGN - (virtual_l % ADDRESS_ALIGN) - r -= virtual_r % ADDRESS_ALIGN + l += AlignUp(virtual_l) - virtual_l + r -= virtual_r - AlignDown(virtual_r) if l >= r: raise RuntimeError('Range collapsed after aligning by page size') @@ -134,6 +175,68 @@ data[:] = bytearray(f.read()) +def _FindNewVaddr(phdrs): + """Returns the virt address that is safe to use for insertion of new data.""" + max_vaddr = 0 + # Strictly speaking it should be sufficient to look through only LOAD + # segments, but better be safe than sorry. + for phdr in phdrs: + max_vaddr = max(max_vaddr, phdr.p_vaddr + phdr.p_memsz) + # When the mapping occurs end address is increased to be a multiple + # of page size. To ensure compatibility with anything relying on this + # behaviour we take this increase into account. + max_vaddr = AlignUp(max_vaddr) + return max_vaddr + + +def _MovePhdrToTheEnd(data): + """Moves Phdrs to the end of the file and adjusts all references to it.""" + elf_hdr = elf_headers.ElfHeader(data) + + # If program headers are already in the end of the file, nothing to do. + if elf_hdr.e_phoff + elf_hdr.e_phnum * elf_hdr.e_phentsize == len(data): + return + + new_phoff = len(data) + unaligned_new_vaddr = _FindNewVaddr(elf_hdr.GetPhdrs()) + new_vaddr = MatchVaddrAlignment(unaligned_new_vaddr, new_phoff) + # Since we moved the PHDR section to the end of the file, we need to create a + # new LOAD segment to load it in. + new_filesz = (elf_hdr.e_phnum + 1) * elf_hdr.e_phentsize + elf_hdr.AddPhdr( + elf_headers.ProgramHeader.Create( + elf_hdr.byte_order, + p_type=elf_headers.ProgramHeader.Type.PT_LOAD, + p_flags=elf_headers.ProgramHeader.Flags.PF_R, + p_offset=new_phoff, + p_vaddr=new_vaddr, + p_paddr=new_vaddr, + p_filesz=new_filesz, + p_memsz=new_filesz, + p_align=ADDRESS_ALIGN, + )) + + # PHDR segment if it exists should point to the new location. + for phdr in elf_hdr.GetPhdrs(): + if phdr.p_type == elf_headers.ProgramHeader.Type.PT_PHDR: + phdr.p_offset = new_phoff + phdr.p_vaddr = new_vaddr + phdr.p_paddr = new_vaddr + phdr.p_filesz = new_filesz + phdr.p_memsz = new_filesz + phdr.p_align = ADDRESS_ALIGN + + # We need to replace the previous phdr placement with zero bytes to fail + # fast if dynamic linker doesn't like the new program header. + previous_phdr_size = (elf_hdr.e_phnum - 1) * elf_hdr.e_phentsize + data[elf_hdr.e_phoff:elf_hdr.e_phoff + + previous_phdr_size] = [0] * previous_phdr_size + + # Updating ELF header to point to the new location. + elf_hdr.e_phoff = new_phoff + elf_hdr.PatchData(data) + + def main(): _SetupLogging() args = _ParseArguments() @@ -143,6 +246,7 @@ data = bytearray(data) _CopyRangeIntoCompressedSection(data, args.left_range, args.right_range) + _MovePhdrToTheEnd(data) with open(args.output, 'wb') as f: f.write(data)
diff --git a/tools/android/elf_compression/elf_headers.py b/tools/android/elf_compression/elf_headers.py index f8ab8dad..597adf0 100644 --- a/tools/android/elf_compression/elf_headers.py +++ b/tools/android/elf_compression/elf_headers.py
@@ -66,6 +66,28 @@ continue setattr(self, field_name, kwargs[field_name]) + def ToBytes(self): + """Returns byte representation of ELF entry.""" + bytearr = bytearray() + for field_name, field_size in self._fields: + field_bytes = getattr(self, field_name).to_bytes( + field_size, byteorder=self.byte_order) + bytearr.extend(field_bytes) + return bytearr + + @classmethod + def Create(cls, byte_order, **kwargs): + """Static wrapper around ApplyKwargs method. + + Args: + byte_order: str. Either 'little' for little endian or 'big' for big + endian. + **kwargs: will be passed directly to the ApplyKwargs method. + """ + obj = cls(byte_order) + obj.ApplyKwargs(**kwargs) + return obj + @classmethod def FromBytes(cls, byte_order, data, offset): """Static wrapper around ParseBytes method. @@ -93,6 +115,11 @@ PT_SHLIB = 5 PT_PHDR = 6 + class Flags(enum.IntFlag): + PF_X = 1 + PF_W = 2 + PF_R = 4 + def __init__(self, byte_order): """ProgramHeader constructor. @@ -238,3 +265,36 @@ def GetPhdrs(self): """Returns the list of file's program headers.""" return self.phdrs + + def AddPhdr(self, phdr): + """Adds a new ProgramHeader entry correcting the e_phnum variable. + + Args: + phdr: ProgramHeader. Instance of ProgramHeader to add. + """ + self.phdrs.append(phdr) + self.e_phnum += 1 + + def PatchData(self, data): + """Patches the given data array to reflect all changes made to the header. + + This method doesn't completely rewrite the data, instead it patches + inplace. Not only the ElfHeader is patched but all of its ProgramHeader + as well. + + The important limitation is that this method doesn't take changes of sizes + and offsets into account. As example, if new ProgramHeader is added, this + method will override whatever data is located under its placement so the + user has to move the headers to the end beforehand or the user mustn't + change header's size. + + Args: + data: bytearray. The data array to be patched. + """ + elf_bytes = self.ToBytes() + data[:len(elf_bytes)] = elf_bytes + current_offset = self.e_phoff + for phdr in self.GetPhdrs(): + phdr_bytes = phdr.ToBytes() + data[current_offset:current_offset + len(phdr_bytes)] = phdr_bytes + current_offset += self.e_phentsize
diff --git a/tools/android/elf_compression/test/compression_script_test.py b/tools/android/elf_compression/test/compression_script_test.py index 61e9fe4..dee43eb0e 100755 --- a/tools/android/elf_compression/test/compression_script_test.py +++ b/tools/android/elf_compression/test/compression_script_test.py
@@ -2,17 +2,18 @@ # Copyright 2019 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Basic test for the compress_section script. - -Runs the script on a sample library and verifies that it still works. -""" +"""Tests for the compress_section script.""" import os import pathlib import subprocess +import sys import tempfile import unittest +sys.path.append(str(pathlib.Path(__file__).resolve().parents[1])) +import compress_section + LIBRARY_CC_NAME = 'libtest.cc' OPENER_CC_NAME = 'library_opener.cc' @@ -118,6 +119,28 @@ opener_output = self._RunOpener(opener_path, patched_library_path) self.assertEqual(opener_output, '1046506\n') + def testAlignUp(self): + """Tests for AlignUp method of the script.""" + self.assertEqual(compress_section.AlignUp(1024, 1024), 1024) + self.assertEqual(compress_section.AlignUp(1023, 1024), 1024) + self.assertEqual(compress_section.AlignUp(1025, 1024), 2048) + self.assertEqual(compress_section.AlignUp(5555, 4096), 8192) + + def testAlignDown(self): + """Tests for AlignDown method of the script.""" + self.assertEqual(compress_section.AlignDown(1024, 1024), 1024) + self.assertEqual(compress_section.AlignDown(1023, 1024), 0) + self.assertEqual(compress_section.AlignDown(1025, 1024), 1024) + self.assertEqual(compress_section.AlignDown(5555, 4096), 4096) + + def testMatchVaddrAlignment(self): + """Tests for MatchVaddrAlignment method of the script.""" + self.assertEqual(compress_section.MatchVaddrAlignment(100, 100, 1024), 100) + self.assertEqual(compress_section.MatchVaddrAlignment(99, 100, 1024), 100) + self.assertEqual(compress_section.MatchVaddrAlignment(101, 100, 1024), 1124) + self.assertEqual( + compress_section.MatchVaddrAlignment(1024, 2049, 1024), 1025) + if __name__ == '__main__': unittest.main()
diff --git a/tools/android/elf_compression/test/elf_headers_test.py b/tools/android/elf_compression/test/elf_headers_test.py index b75a3a0b..ced8154 100755 --- a/tools/android/elf_compression/test/elf_headers_test.py +++ b/tools/android/elf_compression/test/elf_headers_test.py
@@ -69,6 +69,52 @@ self.assertEqual(load_phdr.p_vaddr, 0x1000) self.assertEqual(load_phdr.p_paddr, 0x1000) + def testElfHeaderNoopPatching(self): + """Patching the ELF without any changes.""" + with open(self.library_path, 'rb') as f: + data = bytearray(f.read()) + data_copy = data[:] + elf = elf_headers.ElfHeader(data) + elf.PatchData(data) + self.assertEqual(data, data_copy) + + def testElfHeaderPatchingAndParsing(self): + """Patching the ELF and validating that it worked.""" + with open(self.library_path, 'rb') as f: + data = bytearray(f.read()) + elf = elf_headers.ElfHeader(data) + # Changing some values. + elf.e_ehsize = 42 + elf.GetPhdrs()[0].p_align = 1 + elf.GetPhdrs()[0].p_filesz = 10 + elf.PatchData(data) + + updated_elf = elf_headers.ElfHeader(data) + # Validating all of the ELF header fields. + self.assertEqual(updated_elf.e_type, elf.e_type) + self.assertEqual(updated_elf.e_entry, elf.e_entry) + self.assertEqual(updated_elf.e_phoff, elf.e_phoff) + self.assertEqual(updated_elf.e_shoff, elf.e_shoff) + self.assertEqual(updated_elf.e_flags, elf.e_flags) + self.assertEqual(updated_elf.e_ehsize, 42) + self.assertEqual(updated_elf.e_phentsize, elf.e_phentsize) + self.assertEqual(updated_elf.e_phnum, elf.e_phnum) + self.assertEqual(updated_elf.e_shentsize, elf.e_shentsize) + self.assertEqual(updated_elf.e_shnum, elf.e_shnum) + self.assertEqual(updated_elf.e_shstrndx, elf.e_shstrndx) + + # Validating all of the fields of the first segment. + load_phdr = elf.GetPhdrs()[0] + updated_load_phdr = updated_elf.GetPhdrs()[0] + + self.assertEqual(updated_load_phdr.p_offset, load_phdr.p_offset) + self.assertEqual(updated_load_phdr.p_vaddr, load_phdr.p_vaddr) + self.assertEqual(updated_load_phdr.p_paddr, load_phdr.p_paddr) + self.assertEqual(updated_load_phdr.p_filesz, 10) + self.assertEqual(updated_load_phdr.p_memsz, load_phdr.p_memsz) + self.assertEqual(updated_load_phdr.p_flags, load_phdr.p_flags) + self.assertEqual(updated_load_phdr.p_align, 1) + if __name__ == '__main__': unittest.main()
diff --git a/tools/diagnosis/.style.yapf b/tools/diagnosis/.style.yapf new file mode 100644 index 0000000..ef24bfc6 --- /dev/null +++ b/tools/diagnosis/.style.yapf
@@ -0,0 +1,6 @@ +[style] +based_on_style = pep8 +column_limit = 80 +blank_line_before_nested_class_or_def = true +blank_line_before_module_docstring = true +indent_width = 2
diff --git a/tools/diagnosis/crbug_1001171.py b/tools/diagnosis/crbug_1001171.py new file mode 100644 index 0000000..478fb8c --- /dev/null +++ b/tools/diagnosis/crbug_1001171.py
@@ -0,0 +1,51 @@ +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Helper context wrapper for diagnosing crbug.com/1001171. + +This module and all uses thereof can and should be removed once +crbug.com/1001171 has been resolved. +""" + +from __future__ import print_function + +import contextlib +import os +import sys + + +@contextlib.contextmanager +def DumpStateOnLookupError(): + """Prints potentially useful state info in the event of a LookupError.""" + try: + yield + except LookupError: + print('LookupError diagnosis for crbug.com/1001171:') + for path_index, path_entry in enumerate(sys.path): + desc = 'unknown' + if not os.path.exists(path_entry): + desc = 'missing' + elif os.path.islink(path_entry): + desc = 'link -> %s' % os.path.realpath(path_entry) + elif os.path.isfile(path_entry): + desc = 'file' + elif os.path.isdir(path_entry): + desc = 'dir' + print(' sys.path[%d]: %s (%s)' % (path_index, path_entry, desc)) + + real_path_entry = os.path.realpath(path_entry) + if (path_entry.endswith(os.path.join('lib', 'python2.7')) + and os.path.isdir(real_path_entry)): + encodings_dir = os.path.realpath( + os.path.join(real_path_entry, 'encodings')) + if os.path.exists(encodings_dir): + if os.path.isdir(encodings_dir): + print(' %s contents: %s' % (encodings_dir, + str(os.listdir(encodings_dir)))) + else: + print(' %s exists but is not a directory' % encodings_dir) + else: + print(' %s missing' % encodings_dir) + + raise
diff --git a/tools/grit/grit/grit_runner.py b/tools/grit/grit/grit_runner.py index ea59c44..7b2b500c 100755 --- a/tools/grit/grit/grit_runner.py +++ b/tools/grit/grit/grit_runner.py
@@ -111,7 +111,8 @@ tool_list = '' for (tool, info) in _TOOLS: if not _HIDDEN in info: - tool_list += ' %-12s %s\n' % (tool, info[_FACTORY]().ShortDescription()) + tool_list += ' %-12s %s\n' % ( + tool, info[_FACTORY]().ShortDescription()) print("""GRIT - the Google Resource and Internationalization Tool @@ -263,4 +264,9 @@ if __name__ == '__main__': - sys.exit(Main(sys.argv[1:])) + sys.path.append(os.path.abspath( + os.path.join(os.path.dirname(__file__), '..', '..', 'diagnosis'))) + import crbug_1001171 + + with crbug_1001171.DumpStateOnLookupError(): + sys.exit(Main(sys.argv[1:]))
diff --git a/tools/perf/benchmarks/blink_perf.py b/tools/perf/benchmarks/blink_perf.py index 68c8994..09b9082 100644 --- a/tools/perf/benchmarks/blink_perf.py +++ b/tools/perf/benchmarks/blink_perf.py
@@ -19,8 +19,6 @@ from telemetry.timeline import model as model_module from telemetry.timeline import tracing_config -from telemetry.value import list_of_scalar_values - BLINK_PERF_BASE_DIR = os.path.join(path_util.GetChromiumSrcDir(), 'third_party', 'blink', 'perf_tests') @@ -309,9 +307,7 @@ if cpu_times: avg = sum(cpu_times)/len(cpu_times) print 'avg', '{0:.10f}'.format(avg), unit - results.AddValue(list_of_scalar_values.ListOfScalarValues( - results.current_page, name=trace_event_name, units=unit, - values=cpu_times)) + results.AddMeasurement(trace_event_name, unit, cpu_times) print print '\n' @@ -342,8 +338,7 @@ units = parts[-1] metric = page.name.split('.')[0].replace('/', '_') if values: - results.AddValue(list_of_scalar_values.ListOfScalarValues( - results.current_page, metric, units, values)) + results.AddMeasurement(metric, units, values) else: raise legacy_page_test.MeasurementFailure('Empty test results')
diff --git a/tools/perf/metrics/__init__.py b/tools/perf/metrics/__init__.py index b2e7a3ed..c137187e 100644 --- a/tools/perf/metrics/__init__.py +++ b/tools/perf/metrics/__init__.py
@@ -25,6 +25,6 @@ Metrics may implement AddResults to provide a common way to add results to the PageTestResults in PageTest.ValidateOrMeasurePage -- - results should be added with results.AddValue(...). + results should be added with results.AddMeasurement(...). """ raise NotImplementedError()
diff --git a/ui/base/clipboard/clipboard_ozone.cc b/ui/base/clipboard/clipboard_ozone.cc index 18e383c..fbde9b72 100644 --- a/ui/base/clipboard/clipboard_ozone.cc +++ b/ui/base/clipboard/clipboard_ozone.cc
@@ -8,6 +8,7 @@ #include <utility> #include "base/bind.h" +#include "base/containers/flat_map.h" #include "base/containers/span.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" @@ -26,18 +27,51 @@ namespace { // The amount of time to wait for a request to complete before aborting it. -constexpr base::TimeDelta kRequestTimeoutMs = - base::TimeDelta::FromMilliseconds(10000); +constexpr base::TimeDelta kRequestTimeout = base::TimeDelta::FromSeconds(10); + +// Depending on the backend, the platform clipboard may or may not be +// available. Should it be absent, we provide a dummy one. It always calls +// back immediately with empty data, and denies ownership of any buffer. +class StubPlatformClipboard : public PlatformClipboard { + public: + StubPlatformClipboard() = default; + ~StubPlatformClipboard() override = default; + + // PlatformClipboard: + void OfferClipboardData( + ClipboardBuffer buffer, + const PlatformClipboard::DataMap& data_map, + PlatformClipboard::OfferDataClosure callback) override { + std::move(callback).Run(); + } + void RequestClipboardData( + ClipboardBuffer buffer, + const std::string& mime_type, + PlatformClipboard::DataMap* data_map, + PlatformClipboard::RequestDataClosure callback) override { + std::move(callback).Run({}); + } + void GetAvailableMimeTypes( + ClipboardBuffer buffer, + PlatformClipboard::GetMimeTypesClosure callback) override { + std::move(callback).Run({}); + } + bool IsSelectionOwner(ClipboardBuffer buffer) override { return false; } + void SetSequenceNumberUpdateCb( + PlatformClipboard::SequenceNumberUpdateCb cb) override {} +}; } // namespace -// A helper class, which uses a request pattern to asynchronously communicate -// with the ozone::PlatformClipboard and fetch clipboard data with mimes -// specified. +// A helper class that uses a request pattern to asynchronously communicate +// with the ozone::PlatformClipboard and fetch clipboard data with the +// specified MIME types. class ClipboardOzone::AsyncClipboardOzone { public: explicit AsyncClipboardOzone(PlatformClipboard* platform_clipboard) : platform_clipboard_(platform_clipboard), weak_factory_(this) { + DCHECK(platform_clipboard_); + // Set a callback to listen to requests to increase the clipboard sequence // number. auto update_sequence_cb = @@ -51,12 +85,8 @@ base::span<uint8_t> ReadClipboardDataAndWait(ClipboardBuffer buffer, const std::string& mime_type) { - // TODO(tonikitoo): add selection support. - if (buffer == ClipboardBuffer::kSelection) - return base::span<uint8_t>(); - // We can use a fastpath if we are the owner of the selection. - if (platform_clipboard_->IsSelectionOwner()) { + if (platform_clipboard_->IsSelectionOwner(buffer)) { auto it = offered_data_.find(mime_type); if (it == offered_data_.end()) return {}; @@ -65,7 +95,7 @@ Request request(RequestType::kRead); request.requested_mime_type = mime_type; - PerformRequestAndWaitForResult(&request); + PerformRequestAndWaitForResult(buffer, &request); offered_data_ = std::move(request.data_map); auto it = offered_data_.find(mime_type); @@ -74,9 +104,9 @@ return base::make_span(it->second.data(), it->second.size()); } - std::vector<std::string> RequestMimeTypes() { + std::vector<std::string> RequestMimeTypes(ClipboardBuffer buffer) { // We can use a fastpath if we are the owner of the selection. - if (platform_clipboard_->IsSelectionOwner()) { + if (platform_clipboard_->IsSelectionOwner(buffer)) { std::vector<std::string> mime_types; for (const auto& item : offered_data_) mime_types.push_back(item.first); @@ -84,30 +114,31 @@ } Request request(RequestType::kGetMime); - PerformRequestAndWaitForResult(&request); + PerformRequestAndWaitForResult(buffer, &request); return request.mime_types; } - void OfferData() { + void OfferData(ClipboardBuffer buffer) { Request request(RequestType::kOffer); - request.data_map = offered_data_; - PerformRequestAndWaitForResult(&request); + request.data_map = data_to_offer_; + offered_data_ = std::move(data_to_offer_); + PerformRequestAndWaitForResult(buffer, &request); - UpdateClipboardSequenceNumber(); + UpdateClipboardSequenceNumber(buffer); + } + + void Clear(ClipboardBuffer buffer) { + data_to_offer_.clear(); + OfferData(buffer); } void InsertData(std::vector<uint8_t> data, const std::string& mime_type) { - DCHECK(!base::Contains(offered_data_, mime_type)); - offered_data_[mime_type] = std::move(data); + DCHECK_EQ(data_to_offer_.count(mime_type), 0U); + data_to_offer_[mime_type] = std::move(data); } - void ClearOfferedData() { offered_data_.clear(); } - uint64_t GetSequenceNumber(ClipboardBuffer buffer) { - if (buffer == ClipboardBuffer::kCopyPaste) - return clipboard_sequence_number_; - // TODO(tonikitoo): add sequence number for the selection clipboard buffer. - return 0; + return clipboard_sequence_number_[buffer]; } private: @@ -117,8 +148,7 @@ kGetMime = 2, }; - // A structure, which holds request data to process inquiries from - // the ClipboardOzone. + // Holds request data to process inquiries from the ClipboardOzone. struct Request { explicit Request(RequestType request_type) : type(request_type) {} ~Request() = default; @@ -143,7 +173,8 @@ std::vector<std::string> mime_types; }; - void PerformRequestAndWaitForResult(Request* request) { + void PerformRequestAndWaitForResult(ClipboardBuffer buffer, + Request* request) { DCHECK(request); DCHECK(!abort_timer_.IsRunning()); DCHECK(!pending_request_); @@ -151,13 +182,13 @@ pending_request_ = request; switch (pending_request_->type) { case (RequestType::kRead): - DispatchReadRequest(request); + DispatchReadRequest(buffer, request); break; case (RequestType::kOffer): - DispatchOfferRequest(request); + DispatchOfferRequest(buffer, request); break; case (RequestType::kGetMime): - DispatchGetMimeRequest(request); + DispatchGetMimeRequest(buffer, request); break; } @@ -172,7 +203,7 @@ request->finish_closure = run_loop.QuitClosure(); // Set a timeout timer after which the request will be aborted. - abort_timer_.Start(FROM_HERE, kRequestTimeoutMs, this, + abort_timer_.Start(FROM_HERE, kRequestTimeout, this, &AsyncClipboardOzone::AbortStalledRequest); run_loop.Run(); } @@ -182,27 +213,25 @@ std::move(pending_request_->finish_closure).Run(); } - void DispatchReadRequest(Request* request) { + void DispatchReadRequest(ClipboardBuffer buffer, Request* request) { auto callback = base::BindOnce(&AsyncClipboardOzone::OnTextRead, weak_factory_.GetWeakPtr()); - DCHECK(platform_clipboard_); platform_clipboard_->RequestClipboardData( - request->requested_mime_type, &request->data_map, std::move(callback)); + buffer, request->requested_mime_type, &request->data_map, + std::move(callback)); } - void DispatchOfferRequest(Request* request) { + void DispatchOfferRequest(ClipboardBuffer buffer, Request* request) { auto callback = base::BindOnce(&AsyncClipboardOzone::OnOfferDone, weak_factory_.GetWeakPtr()); - DCHECK(platform_clipboard_); - platform_clipboard_->OfferClipboardData(request->data_map, + platform_clipboard_->OfferClipboardData(buffer, request->data_map, std::move(callback)); } - void DispatchGetMimeRequest(Request* request) { + void DispatchGetMimeRequest(ClipboardBuffer buffer, Request* request) { auto callback = base::BindOnce(&AsyncClipboardOzone::OnGotMimeTypes, weak_factory_.GetWeakPtr()); - DCHECK(platform_clipboard_); - platform_clipboard_->GetAvailableMimeTypes(std::move(callback)); + platform_clipboard_->GetAvailableMimeTypes(buffer, std::move(callback)); } void OnTextRead(const base::Optional<std::vector<uint8_t>>& data) { @@ -227,10 +256,15 @@ pending_request_ = nullptr; } - void UpdateClipboardSequenceNumber() { ++clipboard_sequence_number_; } + void UpdateClipboardSequenceNumber(ClipboardBuffer buffer) { + ++clipboard_sequence_number_[buffer]; + } - // Cached clipboard data, which is pending to be written. Must be cleared on - // every new write to the |platform_clipboard_|. + // Clipboard data accumulated for writing. + PlatformClipboard::DataMap data_to_offer_; + + // Clipboard data that had been offered most recently. Used as a cache to + // read data if we still own it. PlatformClipboard::DataMap offered_data_; // A current pending request being processed. @@ -242,7 +276,7 @@ // Provides communication to a system clipboard under ozone level. PlatformClipboard* platform_clipboard_ = nullptr; - uint64_t clipboard_sequence_number_ = 0; + base::flat_map<ClipboardBuffer, uint64_t> clipboard_sequence_number_; base::WeakPtrFactory<AsyncClipboardOzone> weak_factory_; @@ -256,9 +290,18 @@ // ClipboardOzone implementation. ClipboardOzone::ClipboardOzone() { - async_clipboard_ozone_ = - std::make_unique<ClipboardOzone::AsyncClipboardOzone>( - OzonePlatform::GetInstance()->GetPlatformClipboard()); + auto* platform_clipboard = + OzonePlatform::GetInstance()->GetPlatformClipboard(); + if (platform_clipboard) { + async_clipboard_ozone_ = + std::make_unique<ClipboardOzone::AsyncClipboardOzone>( + platform_clipboard); + } else { + static base::NoDestructor<StubPlatformClipboard> stub_platform_clipboard; + async_clipboard_ozone_ = + std::make_unique<ClipboardOzone::AsyncClipboardOzone>( + stub_platform_clipboard.get()); + } } ClipboardOzone::~ClipboardOzone() = default; @@ -272,11 +315,8 @@ bool ClipboardOzone::IsFormatAvailable(const ClipboardFormatType& format, ClipboardBuffer buffer) const { DCHECK(CalledOnValidThread()); - // TODO(tonikitoo): add selection support. - if (buffer == ClipboardBuffer::kSelection) - return false; - auto available_types = async_clipboard_ozone_->RequestMimeTypes(); + auto available_types = async_clipboard_ozone_->RequestMimeTypes(buffer); for (auto mime_type : available_types) { if (format.ToString() == mime_type) { return true; @@ -286,21 +326,17 @@ } void ClipboardOzone::Clear(ClipboardBuffer buffer) { - async_clipboard_ozone_->ClearOfferedData(); - async_clipboard_ozone_->OfferData(); + async_clipboard_ozone_->Clear(buffer); } void ClipboardOzone::ReadAvailableTypes(ClipboardBuffer buffer, std::vector<base::string16>* types, bool* contains_filenames) const { DCHECK(CalledOnValidThread()); + types->clear(); - // TODO(tonikitoo): add selection support. - if (buffer == ClipboardBuffer::kSelection) - return; - - auto available_types = async_clipboard_ozone_->RequestMimeTypes(); + auto available_types = async_clipboard_ozone_->RequestMimeTypes(buffer); for (auto mime_type : available_types) types->push_back(base::UTF8ToUTF16(mime_type)); } @@ -318,6 +354,7 @@ void ClipboardOzone::ReadAsciiText(ClipboardBuffer buffer, std::string* result) const { DCHECK(CalledOnValidThread()); + auto clipboard_data = async_clipboard_ozone_->ReadClipboardDataAndWait(buffer, kMimeTypeText); result->assign(clipboard_data.begin(), clipboard_data.end()); @@ -329,6 +366,7 @@ uint32_t* fragment_start, uint32_t* fragment_end) const { DCHECK(CalledOnValidThread()); + markup->clear(); if (src_url) src_url->clear(); @@ -346,6 +384,7 @@ void ClipboardOzone::ReadRTF(ClipboardBuffer buffer, std::string* result) const { DCHECK(CalledOnValidThread()); + auto clipboard_data = async_clipboard_ozone_->ReadClipboardDataAndWait(buffer, kMimeTypeRTF); result->assign(clipboard_data.begin(), clipboard_data.end()); @@ -353,19 +392,21 @@ SkBitmap ClipboardOzone::ReadImage(ClipboardBuffer buffer) const { DCHECK(CalledOnValidThread()); + auto clipboard_data = async_clipboard_ozone_->ReadClipboardDataAndWait(buffer, kMimeTypePNG); SkBitmap bitmap; - if (gfx::PNGCodec::Decode(clipboard_data.data(), clipboard_data.size(), - &bitmap)) - return SkBitmap(bitmap); - return SkBitmap(); + if (!gfx::PNGCodec::Decode(clipboard_data.data(), clipboard_data.size(), + &bitmap)) + return {}; + return SkBitmap(bitmap); } void ClipboardOzone::ReadCustomData(ClipboardBuffer buffer, const base::string16& type, base::string16* result) const { DCHECK(CalledOnValidThread()); + auto custom_data = async_clipboard_ozone_->ReadClipboardDataAndWait( buffer, kMimeTypeWebCustomData); ui::ReadCustomDataForType(custom_data.data(), custom_data.size(), type, @@ -382,6 +423,7 @@ void ClipboardOzone::ReadData(const ClipboardFormatType& format, std::string* result) const { DCHECK(CalledOnValidThread()); + auto clipboard_data = async_clipboard_ozone_->ReadClipboardDataAndWait( ClipboardBuffer::kCopyPaste, format.ToString()); result->assign(clipboard_data.begin(), clipboard_data.end()); @@ -390,13 +432,30 @@ void ClipboardOzone::WriteObjects(ClipboardBuffer buffer, const ObjectMap& objects) { DCHECK(CalledOnValidThread()); + + for (const auto& object : objects) + DispatchObject(static_cast<ObjectType>(object.first), object.second); + + async_clipboard_ozone_->OfferData(buffer); + + // Just like Aura/X11 implementation does, copy text data from the copy/paste + // selection to the primary selection. if (buffer == ClipboardBuffer::kCopyPaste) { - async_clipboard_ozone_->ClearOfferedData(); - - for (const auto& object : objects) - DispatchObject(object.first, object.second); - - async_clipboard_ozone_->OfferData(); + auto text_iter = objects.find(ObjectType::kText); + if (text_iter != objects.end()) { + const ObjectMapParams& params_vector = text_iter->second; + if (params_vector.size()) { + const ObjectMapParam& char_vector = params_vector[0]; + const uint8_t* uint8_data = + reinterpret_cast<const uint8_t*>(char_vector.data()); + if (char_vector.size()) { + std::vector<uint8_t> data(uint8_data, + uint8_data + char_vector.size()); + async_clipboard_ozone_->InsertData(std::move(data), kMimeTypeText); + } + } + async_clipboard_ozone_->OfferData(ClipboardBuffer::kSelection); + } } }
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_table_list.js b/ui/file_manager/file_manager/foreground/js/ui/file_table_list.js index 8bed1cf..58f5eca8 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/file_table_list.js +++ b/ui/file_manager/file_manager/foreground/js/ui/file_table_list.js
@@ -80,7 +80,7 @@ FileTableList.decorate = self => { self.__proto__ = FileTableList.prototype; self.setAttribute('aria-multiselectable', true); - self.onMergeItems_ = null; + /** @type {FileTableList} */ (self).onMergeItems_ = null; }; /**
diff --git a/ui/file_manager/file_manager/foreground/js/ui/table/table_list.js b/ui/file_manager/file_manager/foreground/js/ui/table/table_list.js index 0c6c28f..cc9835b 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/table/table_list.js +++ b/ui/file_manager/file_manager/foreground/js/ui/table/table_list.js
@@ -8,33 +8,37 @@ cr.define('cr.ui.table', function() { /** @const */ const List = cr.ui.List; - /** @const */ const ListItem = cr.ui.ListItem; /** * Creates a new table list element. - * @param {Object=} opt_propertyBag Optional properties. - * @constructor - * @extends {cr.ui.List} */ - const TableList = cr.ui.define('list'); - - TableList.prototype = { - __proto__: List.prototype, - - table_: null, - + class TableList extends cr.ui.List { /** - * Initializes the element. + * @param {Object=} opt_propertyBag Optional properties. */ - decorate: function() { - List.prototype.decorate.apply(this); - this.className = 'list'; - }, + constructor(opt_propertyBag) { + super(opt_propertyBag); + + /** @private {cr.ui.Table} */ + this.table_ = null; + + /** + * Actually defined and managed by cr.ui.List. + * @private {HTMLElement} + * */ + this.afterFiller_; + } + + static decorate(el) { + cr.ui.List.decorate(el); + el.__proto__ = TableList.prototype; + el.className = 'list'; + } /** * Resizes columns. Called when column width changed. */ - resize: function() { + resize() { if (this.needsFullRedraw_()) { this.redraw(); return; @@ -43,12 +47,12 @@ List.prototype.redraw.call(this); } // Redraw items only. this.resizeCells_(); - }, + } /** * Updates width of cells. */ - resizeCells_: function() { + resizeCells_() { const cm = this.table_.columnModel; for (let row = this.firstElementChild; row; row = row.nextElementSibling) { @@ -62,12 +66,12 @@ row.style.width = cm.totalWidth + 'px'; } this.afterFiller_.style.width = cm.totalWidth + 'px'; - }, + } /** * Redraws the viewport. */ - redraw: function() { + redraw() { if (this.batchCount_ != 0) { return; } @@ -75,7 +79,7 @@ List.prototype.redraw.call(this); this.resizeCells_(); - }, + } /** * Returns the height of after filler in the list. @@ -83,19 +87,19 @@ * @return {number} The height of after filler. * @override */ - getAfterFillerHeight: function(lastIndex) { + getAfterFillerHeight(lastIndex) { // If the list is empty set height to 1 to show horizontal // scroll bar. return lastIndex == 0 ? 1 : cr.ui.List.prototype.getAfterFillerHeight.call(this, lastIndex); - }, + } /** * Shows or hides vertical and horizontal scroll bars in the list. * @return {boolean} True if horizontal scroll bar changed. */ - updateScrollbars_: function() { + updateScrollbars_() { const cm = this.table_.columnModel; const style = this.style; if (!cm || cm.size == 0) { @@ -131,14 +135,14 @@ } } return changed; - }, + } /** * Shows or hides vertical scroll bar. * @param {boolean} show True to show. * @return {boolean} True if visibility changed. */ - showVerticalScrollBar_: function(show) { + showVerticalScrollBar_(show) { const style = this.style; if (show && style.overflowY == 'scroll') { return false; @@ -148,34 +152,35 @@ } style.overflowY = show ? 'scroll' : 'hidden'; return true; - }, + } /** * @param {number} visibleHeight Height in pixels. * @return {boolean} True if all rows could be accomodiated in * visibleHeight pixels. */ - areAllItemsVisible_: function(visibleHeight) { + areAllItemsVisible_(visibleHeight) { if (!this.dataModel || this.dataModel.length == 0) { return true; } return this.getItemTop(this.dataModel.length) <= visibleHeight; - }, + } /** * Creates a new list item. * @param {*} dataItem The value to use for the item. * @return {!cr.ui.ListItem} The newly created list item. */ - createItem: function(dataItem) { - return this.table_.getRenderFunction().call(null, dataItem, this.table_); - }, + createItem(dataItem) { + return /** @type {!cr.ui.ListItem} */ ( + this.table_.getRenderFunction().call(null, dataItem, this.table_)); + } /** * Determines whether a full redraw is required. * @return {boolean} */ - needsFullRedraw_: function() { + needsFullRedraw_() { const cm = this.table_.columnModel; const row = this.firstElementChild; // If the number of columns in the model has changed, a full redraw is @@ -190,8 +195,8 @@ } } return false; - }, - }; + } + } /** * The table associated with the list. @@ -199,5 +204,7 @@ */ cr.defineProperty(TableList, 'table'); - return {TableList: TableList}; + return { + TableList: TableList, + }; });
diff --git a/ui/file_manager/integration_tests/file_manager/drive_specific.js b/ui/file_manager/integration_tests/file_manager/drive_specific.js index d3014d3..f81b9a95 100644 --- a/ui/file_manager/integration_tests/file_manager/drive_specific.js +++ b/ui/file_manager/integration_tests/file_manager/drive_specific.js
@@ -81,9 +81,6 @@ * "shared-with-me" should be shown. */ testcase.driveOpenSidebarSharedWithMe = async () => { - const isDriveFsEnabled = - await sendTestMessage({name: 'getDriveFsEnabled'}) === 'true'; - // Open Files app on Drive containing "Shared with me" file entries. const appId = await setupAndWaitUntilReady( RootPath.DRIVE, [], BASIC_DRIVE_ENTRY_SET.concat([ @@ -111,9 +108,7 @@ // Wait until the breadcrumb path is updated. await remoteCall.waitUntilCurrentDirectoryIsChanged( - appId, - isDriveFsEnabled ? '/Shared with me/Shared Directory' : - '/My Drive/Shared Directory'); + appId, '/Shared with me/Shared Directory'); // Verify the file list. await remoteCall.waitForFiles( @@ -280,50 +275,6 @@ await remoteCall.waitForElement(appId, ['body:not(.check-select)']); }; -/** - * Pin hello.txt in the old Drive client. - */ -testcase.PRE_driveMigratePinnedFile = async () => { - const appId = await setupAndWaitUntilReady(RootPath.DRIVE); - await remoteCall.callRemoteTestUtil('selectFile', appId, ['hello.txt']); - await remoteCall.waitForElement(appId, ['.table-row[selected]']); - chrome.test.assertTrue(await remoteCall.callRemoteTestUtil( - 'fakeMouseRightClick', appId, ['.table-row[selected]'])); - - // Wait menu to appear and click on toggle pinned. - await remoteCall.waitForElement(appId, '#file-context-menu:not([hidden])'); - await remoteCall.waitAndClickElement( - appId, '[command="#toggle-pinned"]:not([hidden]):not([disabled])'); - - // Wait the toggle pinned async action to finish, so the next call to display - // context menu is after the action has finished. - await remoteCall.waitForElement(appId, '#file-context-menu[hidden]'); - // TODO(crbug.com/953616): Change wait for a deterministic option. - await wait(100); - - // Open context menu again. - chrome.test.assertTrue(await remoteCall.callRemoteTestUtil( - 'fakeEvent', appId, ['#file-list', 'contextmenu'])); - - // Check: File is pinned. - await remoteCall.waitForElement(appId, '[command="#toggle-pinned"][checked]'); -}; - -/** - * Verify hello.txt is still pinned after migrating to DriveFS. - */ -testcase.driveMigratePinnedFile = async () => { - // After enabling DriveFS, ensure the file is still pinned. - const appId = await setupAndWaitUntilReady(RootPath.DRIVE); - await remoteCall.callRemoteTestUtil('selectFile', appId, ['hello.txt']); - await remoteCall.waitForElement(appId, ['.table-row[selected]']); - chrome.test.assertTrue(await remoteCall.callRemoteTestUtil( - 'fakeMouseRightClick', appId, ['.table-row[selected]'])); - - await remoteCall.waitForElement(appId, '#file-context-menu:not([hidden])'); - await remoteCall.waitForElement(appId, '[command="#toggle-pinned"][checked]'); -}; - // Match the way the production version formats dates. function formatDate(date) { const padAndConvert = i => { @@ -385,100 +336,6 @@ }; /** - * Create some dirty files in Drive. - * - * Create /root/never-sync.txt and /root/A/never-sync.txt. These files will - * never complete syncing to the fake drive service so will remain dirty - * forever. - */ -testcase.PRE_driveRecoverDirtyFiles = async () => { - // Open Files app on downloads. - const appId = await setupAndWaitUntilReady( - RootPath.DOWNLOADS, [ENTRIES.neverSync], [ENTRIES.directoryA]); - - // Select never-sync.txt. - chrome.test.assertTrue( - await remoteCall.callRemoteTestUtil( - 'selectFile', appId, ['never-sync.txt']), - 'selectFile failed'); - - // Copy it. - chrome.test.assertTrue( - await remoteCall.callRemoteTestUtil( - 'fakeKeyDown', appId, ['#file-list', 'c', true, false, false]), - 'copy failed'); - - // Navigate to My Drive. - await remoteCall.navigateWithDirectoryTree( - appId, '/root', 'My Drive', 'drive'); - - // Paste. - chrome.test.assertTrue( - await remoteCall.callRemoteTestUtil( - 'fakeKeyDown', appId, ['#file-list', 'v', true, false, false]), - 'paste failed'); - - // Wait for the paste to complete. - let expectedEntryRows = [ - ENTRIES.neverSync.getExpectedRow(), - ENTRIES.directoryA.getExpectedRow(), - ]; - await remoteCall.waitForFiles( - appId, expectedEntryRows, {ignoreLastModifiedTime: true}); - - // Navigate to My Drive/A. - await remoteCall.navigateWithDirectoryTree( - appId, '/root/A', 'My Drive', 'drive'); - - // Paste. - chrome.test.assertTrue( - await remoteCall.callRemoteTestUtil( - 'fakeKeyDown', appId, ['#file-list', 'v', true, false, false]), - 'paste failed'); - - // Wait for the paste to complete. - expectedEntryRows = [ENTRIES.neverSync.getExpectedRow()]; - await remoteCall.waitForFiles( - appId, expectedEntryRows, {ignoreLastModifiedTime: true}); -}; - -/** - * Verify that when enabling DriveFS, the dirty files are recovered to - * Downloads/Recovered files from Google Drive. The directory structure should - * be flattened with uniquified names: - * - never-sync.txt - * - never-sync (1).txt - */ -testcase.driveRecoverDirtyFiles = async () => { - // After enabling DriveFS, ensure the dirty files have been - // recovered into Downloads. - const appId = await setupAndWaitUntilReady(RootPath.DOWNLOADS, [], []); - - // Wait for the Recovered files directory to be in Downloads. - let expectedEntryRows = [ - ENTRIES.neverSync.getExpectedRow(), - ['Recovered files from Google Drive', '--', 'Folder'], - ]; - await remoteCall.waitForFiles( - appId, expectedEntryRows, {ignoreLastModifiedTime: true}); - - // Navigate to the recovered files directory. - await remoteCall.navigateWithDirectoryTree( - appId, '/Downloads/Recovered files from Google Drive', - 'My files/Downloads'); - - // Ensure it contains never-sync.txt and never-sync (1).txt. - const uniquifiedNeverSync = ENTRIES.neverSync.getExpectedRow(); - uniquifiedNeverSync[0] = 'never-sync (1).txt'; - expectedEntryRows = [ - ENTRIES.neverSync.getExpectedRow(), - uniquifiedNeverSync, - ]; - await remoteCall.waitForFiles( - appId, expectedEntryRows, {ignoreLastModifiedTime: true}); -}; - -/** * Verify that "Available Offline" is available from the gear menu for a drive * file before the context menu has been opened. */
diff --git a/ui/file_manager/integration_tests/file_manager/file_dialog.js b/ui/file_manager/integration_tests/file_manager/file_dialog.js index 30ae7495..72e531c 100644 --- a/ui/file_manager/integration_tests/file_manager/file_dialog.js +++ b/ui/file_manager/integration_tests/file_manager/file_dialog.js
@@ -84,11 +84,8 @@ async function openFileDialogClickOkButton( volume, name, useBrowserOpen = false) { const okButton = '.button-panel button.ok:enabled'; - if (volume !== 'drive' || - await sendTestMessage({name: 'getDriveFsEnabled'}) === 'true') { - await sendTestMessage( - {name: 'expectFileTask', fileNames: [name], openType: 'open'}); - } + await sendTestMessage( + {name: 'expectFileTask', fileNames: [name], openType: 'open'}); let closer = clickOpenFileDialogButton.bind(null, name, okButton); const entrySet = await setUpFileEntrySet(volume); @@ -114,11 +111,8 @@ async function saveFileDialogClickOkButton(volume, name) { const caller = getCaller(); - if (volume !== 'drive' || - await sendTestMessage({name: 'getDriveFsEnabled'}) === 'true') { - await sendTestMessage( - {name: 'expectFileTask', fileNames: [name], openType: 'saveAs'}); - } + await sendTestMessage( + {name: 'expectFileTask', fileNames: [name], openType: 'saveAs'}); let closer = async (appId) => { const okButton = '.button-panel button.ok:enabled'; @@ -375,11 +369,7 @@ const url = new URL( await openFileDialogClickOkButton('drive', TEST_DRIVE_FILE, true)); - const isDriveFsEnabled = - await sendTestMessage({name: 'getDriveFsEnabled'}) === 'true'; - - chrome.test.assertEq( - url.protocol, isDriveFsEnabled ? 'file:' : 'externalfile:'); + chrome.test.assertEq(url.protocol, 'file:'); chrome.test.assertTrue( url.pathname.endsWith(`/root/${TEST_DRIVE_FILE}`), url.pathname); };
diff --git a/ui/file_manager/integration_tests/file_manager/keyboard_operations.js b/ui/file_manager/integration_tests/file_manager/keyboard_operations.js index 9f7f2d9..c7844bd 100644 --- a/ui/file_manager/integration_tests/file_manager/keyboard_operations.js +++ b/ui/file_manager/integration_tests/file_manager/keyboard_operations.js
@@ -89,8 +89,7 @@ await remoteCall.waitForFiles( appId, expectedEntryRows, {ignoreLastModifiedTime: true}); const files = await remoteCall.callRemoteTestUtil('getFileList', appId, []); - if (path == RootPath.DRIVE && - await sendTestMessage({name: 'getDriveFsEnabled'}) === 'true') { + if (path == RootPath.DRIVE) { // DriveFs doesn't preserve mtimes so they shouldn't match. chrome.test.assertTrue(files[0][3] != files[1][3], files[0][3]); } else {
diff --git a/ui/file_manager/integration_tests/file_manager/open_audio_files.js b/ui/file_manager/integration_tests/file_manager/open_audio_files.js index 61dab88..701c799 100644 --- a/ui/file_manager/integration_tests/file_manager/open_audio_files.js +++ b/ui/file_manager/integration_tests/file_manager/open_audio_files.js
@@ -159,15 +159,11 @@ async function audioOpenMultipleTracksDrive() { const tracks = [ENTRIES.beautiful, ENTRIES.newlyAdded]; - // File open events are not reported for legacy Drive. - if (await sendTestMessage({name: 'getDriveFsEnabled'}) === 'true') { - await sendTestMessage({ - name: 'expectFileTask', - fileNames: - [ENTRIES.beautiful.targetPath, ENTRIES.newlyAdded.targetPath], - openType: 'launch' - }); - } + await sendTestMessage({ + name: 'expectFileTask', + fileNames: [ENTRIES.beautiful.targetPath, ENTRIES.newlyAdded.targetPath], + openType: 'launch' + }); // Open Files.App on Drive, add the audio files to Drive. const appId = await setupAndWaitUntilReady(RootPath.DRIVE, [], tracks);
diff --git a/ui/file_manager/integration_tests/file_manager/open_image_files.js b/ui/file_manager/integration_tests/file_manager/open_image_files.js index c6112f83..65a2d84 100644 --- a/ui/file_manager/integration_tests/file_manager/open_image_files.js +++ b/ui/file_manager/integration_tests/file_manager/open_image_files.js
@@ -11,15 +11,11 @@ * @param {string} path Directory path (Downloads or Drive). */ async function imageOpen(path) { - // File open events are not reported for legacy Drive. - if (path !== RootPath.DRIVE || - await sendTestMessage({name: 'getDriveFsEnabled'}) === 'true') { - await sendTestMessage({ - name: 'expectFileTask', - fileNames: [ENTRIES.image3.targetPath], - openType: 'launch' - }); - } + await sendTestMessage({ + name: 'expectFileTask', + fileNames: [ENTRIES.image3.targetPath], + openType: 'launch' + }); // Open Files.App on |path|, add image3 to Downloads and Drive. const appId = @@ -48,15 +44,11 @@ * @param {string} path Directory path (Downloads or Drive). */ async function imageOpenGalleryOpen(path) { - // File open events are not reported for legacy Drive. - if (path !== RootPath.DRIVE || - await sendTestMessage({name: 'getDriveFsEnabled'}) === 'true') { - await sendTestMessage({ - name: 'expectFileTask', - fileNames: [ENTRIES.image3.targetPath, ENTRIES.desktop.targetPath], - openType: 'launch' - }); - } + await sendTestMessage({ + name: 'expectFileTask', + fileNames: [ENTRIES.image3.targetPath, ENTRIES.desktop.targetPath], + openType: 'launch' + }); const testImages = [ENTRIES.image3, ENTRIES.desktop];
diff --git a/ui/file_manager/integration_tests/file_manager/open_video_files.js b/ui/file_manager/integration_tests/file_manager/open_video_files.js index d0f5d508..2a3456e 100644 --- a/ui/file_manager/integration_tests/file_manager/open_video_files.js +++ b/ui/file_manager/integration_tests/file_manager/open_video_files.js
@@ -28,15 +28,11 @@ * @param {string} path Directory path to be tested. */ async function videoOpen(path) { - // File open events are not reported for legacy Drive. - if (path !== RootPath.DRIVE || - await sendTestMessage({name: 'getDriveFsEnabled'}) === 'true') { - await sendTestMessage({ - name: 'expectFileTask', - fileNames: ['world.ogv'], - openType: 'launch' - }); - } + await sendTestMessage({ + name: 'expectFileTask', + fileNames: ['world.ogv'], + openType: 'launch', + }); const appId = await setupAndWaitUntilReady(path);
diff --git a/ui/file_manager/integration_tests/file_manager/zip_files.js b/ui/file_manager/integration_tests/file_manager/zip_files.js index 914a98d..e3df0eb 100644 --- a/ui/file_manager/integration_tests/file_manager/zip_files.js +++ b/ui/file_manager/integration_tests/file_manager/zip_files.js
@@ -302,13 +302,11 @@ * Tests zip file open (aka unzip) from Google Drive. */ testcase.zipFileOpenDrive = async () => { - if (await sendTestMessage({name: 'getDriveFsEnabled'}) === 'true') { - await sendTestMessage({ - name: 'expectFileTask', - fileNames: [ENTRIES.zipArchive.targetPath], - openType: 'launch' - }); - } + await sendTestMessage({ + name: 'expectFileTask', + fileNames: [ENTRIES.zipArchive.targetPath], + openType: 'launch' + }); // Open Files app on Drive containing a zip file. const appId = @@ -435,13 +433,11 @@ * Tests creating a zip file on Drive. */ testcase.zipCreateFileDrive = async () => { - if (await sendTestMessage({name: 'getDriveFsEnabled'}) === 'true') { - await sendTestMessage({ - name: 'expectFileTask', - fileNames: [ENTRIES.photos.targetPath], - openType: 'launch' - }); - } + await sendTestMessage({ + name: 'expectFileTask', + fileNames: [ENTRIES.photos.targetPath], + openType: 'launch' + }); // Open Files app on Drive containing ENTRIES.photos. const appId =
diff --git a/ui/ozone/BUILD.gn b/ui/ozone/BUILD.gn index 7955a926..b7883e6 100644 --- a/ui/ozone/BUILD.gn +++ b/ui/ozone/BUILD.gn
@@ -100,6 +100,7 @@ "//gpu/vulkan:buildflags", "//ipc", "//skia", + "//ui/base/clipboard:clipboard_types", "//ui/display", "//ui/display/types", "//ui/display/util",
diff --git a/ui/ozone/DEPS b/ui/ozone/DEPS index 281c592..9511491 100644 --- a/ui/ozone/DEPS +++ b/ui/ozone/DEPS
@@ -8,6 +8,7 @@ "-ui/base/ime/init", "+ui/display", "+ui/events", + "+ui/base/clipboard/clipboard_buffer.h", "+ui/base/cursor", "+ui/gfx", "+ui/gl",
diff --git a/ui/ozone/platform/wayland/host/wayland_clipboard.cc b/ui/ozone/platform/wayland/host/wayland_clipboard.cc index ae4fb06..d56445d0 100644 --- a/ui/ozone/platform/wayland/host/wayland_clipboard.cc +++ b/ui/ozone/platform/wayland/host/wayland_clipboard.cc
@@ -19,8 +19,15 @@ WaylandClipboard::~WaylandClipboard() = default; void WaylandClipboard::OfferClipboardData( + ClipboardBuffer buffer, const PlatformClipboard::DataMap& data_map, PlatformClipboard::OfferDataClosure callback) { + // TODO(https://crbug.com/921950): Implement primary selection. + if (buffer != ClipboardBuffer::kCopyPaste) { + std::move(callback).Run(); + return; + } + if (!clipboard_data_source_) { clipboard_data_source_ = data_device_manager_->CreateSource(); clipboard_data_source_->WriteToClipboard(data_map); @@ -30,9 +37,16 @@ } void WaylandClipboard::RequestClipboardData( + ClipboardBuffer buffer, const std::string& mime_type, PlatformClipboard::DataMap* data_map, PlatformClipboard::RequestDataClosure callback) { + // TODO(https://crbug.com/921950): Implement primary selection. + if (buffer != ClipboardBuffer::kCopyPaste) { + std::move(callback).Run({}); + return; + } + read_clipboard_closure_ = std::move(callback); DCHECK(data_map); @@ -41,7 +55,11 @@ SetData({}, mime_type); } -bool WaylandClipboard::IsSelectionOwner() { +bool WaylandClipboard::IsSelectionOwner(ClipboardBuffer buffer) { + // TODO(https://crbug.com/921950): Implement primary selection. + if (buffer != ClipboardBuffer::kCopyPaste) + return false; + return !!clipboard_data_source_; } @@ -53,7 +71,14 @@ } void WaylandClipboard::GetAvailableMimeTypes( + ClipboardBuffer buffer, PlatformClipboard::GetMimeTypesClosure callback) { + // TODO(https://crbug.com/921950): Implement primary selection. + if (buffer != ClipboardBuffer::kCopyPaste) { + std::move(callback).Run({}); + return; + } + std::move(callback).Run(data_device_->GetAvailableMimeTypes()); } @@ -79,9 +104,13 @@ data_map_ = nullptr; } -void WaylandClipboard::UpdateSequenceNumber() { +void WaylandClipboard::UpdateSequenceNumber(ClipboardBuffer buffer) { + // TODO(https://crbug.com/921950): Implement primary selection. + if (buffer != ClipboardBuffer::kCopyPaste) + return; + if (!update_sequence_cb_.is_null()) - update_sequence_cb_.Run(); + update_sequence_cb_.Run(buffer); } } // namespace ui
diff --git a/ui/ozone/platform/wayland/host/wayland_clipboard.h b/ui/ozone/platform/wayland/host/wayland_clipboard.h index 8fcbfae..c808bba 100644 --- a/ui/ozone/platform/wayland/host/wayland_clipboard.h +++ b/ui/ozone/platform/wayland/host/wayland_clipboard.h
@@ -26,21 +26,24 @@ // PlatformClipboard. void OfferClipboardData( + ClipboardBuffer buffer, const PlatformClipboard::DataMap& data_map, PlatformClipboard::OfferDataClosure callback) override; void RequestClipboardData( + ClipboardBuffer buffer, const std::string& mime_type, PlatformClipboard::DataMap* data_map, PlatformClipboard::RequestDataClosure callback) override; void GetAvailableMimeTypes( + ClipboardBuffer buffer, PlatformClipboard::GetMimeTypesClosure callback) override; - bool IsSelectionOwner() override; + bool IsSelectionOwner(ClipboardBuffer buffer) override; void SetSequenceNumberUpdateCb( PlatformClipboard::SequenceNumberUpdateCb cb) override; void DataSourceCancelled(); void SetData(const std::string& contents, const std::string& mime_type); - void UpdateSequenceNumber(); + void UpdateSequenceNumber(ClipboardBuffer buffer); private: // Holds a temporary instance of the client's clipboard content
diff --git a/ui/ozone/platform/wayland/host/wayland_data_device.cc b/ui/ozone/platform/wayland/host/wayland_data_device.cc index 02debda..81a2a73 100644 --- a/ui/ozone/platform/wayland/host/wayland_data_device.cc +++ b/ui/ozone/platform/wayland/host/wayland_data_device.cc
@@ -210,7 +210,8 @@ wl_data_offer* offer) { auto* self = static_cast<WaylandDataDevice*>(data); - self->connection_->clipboard()->UpdateSequenceNumber(); + self->connection_->clipboard()->UpdateSequenceNumber( + ClipboardBuffer::kCopyPaste); DCHECK(!self->new_offer_); self->new_offer_ = std::make_unique<WaylandDataOffer>(offer);
diff --git a/ui/ozone/platform/wayland/host/wayland_data_device_unittest.cc b/ui/ozone/platform/wayland/host/wayland_data_device_unittest.cc index 133cd04..8ab31d7 100644 --- a/ui/ozone/platform/wayland/host/wayland_data_device_unittest.cc +++ b/ui/ozone/platform/wayland/host/wayland_data_device_unittest.cc
@@ -51,16 +51,19 @@ data_types_[mime_type] = std::vector<uint8_t>(object_data, object_data + object_map.size()); - delegate_->OfferClipboardData(data_types_, std::move(callback)); + delegate_->OfferClipboardData(ClipboardBuffer::kCopyPaste, data_types_, + std::move(callback)); } void ReadData(const std::string& mime_type, PlatformClipboard::RequestDataClosure callback) { - delegate_->RequestClipboardData(mime_type, &data_types_, - std::move(callback)); + delegate_->RequestClipboardData(ClipboardBuffer::kCopyPaste, mime_type, + &data_types_, std::move(callback)); } - bool IsSelectionOwner() { return delegate_->IsSelectionOwner(); } + bool IsSelectionOwner() { + return delegate_->IsSelectionOwner(ClipboardBuffer::kCopyPaste); + } private: PlatformClipboard* delegate_ = nullptr;
diff --git a/ui/ozone/platform/x11/x11_clipboard_ozone.cc b/ui/ozone/platform/x11/x11_clipboard_ozone.cc index 7797f50..2d10fa24 100644 --- a/ui/ozone/platform/x11/x11_clipboard_ozone.cc +++ b/ui/ozone/platform/x11/x11_clipboard_ozone.cc
@@ -52,6 +52,37 @@ } // namespace +// Maintains state of a single selection (aka system clipboard buffer). +struct X11ClipboardOzone::SelectionState { + SelectionState() = default; + ~SelectionState() = default; + + // DataMap we keep from |OfferClipboardData| to service remote requests for + // the clipboard. + PlatformClipboard::DataMap offer_data_map; + + // DataMap from |RequestClipboardData| that we write remote clipboard + // contents to before calling the completion callback. + PlatformClipboard::DataMap* request_data_map = nullptr; + + // Mime types supported by remote clipboard. + std::vector<std::string> mime_types; + + // Data most recently read from remote clipboard. + std::vector<unsigned char> data; + + // Mime type of most recently read data from remote clipboard. + std::string data_mime_type; + + // Callbacks are stored when we haven't already prefetched the remote + // clipboard. + PlatformClipboard::GetMimeTypesClosure get_available_mime_types_callback; + PlatformClipboard::RequestDataClosure request_clipboard_data_callback; + + // The time that this instance took ownership of the clipboard. + Time acquired_selection_timestamp; +}; + X11ClipboardOzone::X11ClipboardOzone() : atom_clipboard_(gfx::GetAtom(kClipboard)), atom_targets_(gfx::GetAtom(kTargets)), @@ -77,12 +108,15 @@ // Register to receive standard X11 events. X11EventSource::GetInstance()->AddXEventDispatcher(this); - // Register to receive XFixes notification when selection owner changes. - XFixesSelectSelectionInput(x_display_, x_window_, atom_clipboard_, - XFixesSetSelectionOwnerNotifyMask); - - // Prefetch the current remote clipboard contents. - QueryTargets(); + for (auto atom : {atom_clipboard_, XA_PRIMARY}) { + // Register the selection state. + selection_state_.emplace(atom, std::make_unique<SelectionState>()); + // Register to receive XFixes notification when selection owner changes. + XFixesSelectSelectionInput(x_display_, x_window_, atom, + XFixesSetSelectionOwnerNotifyMask); + // Prefetch the current remote clipboard contents. + QueryTargets(atom); + } } X11ClipboardOzone::~X11ClipboardOzone() { @@ -95,9 +129,9 @@ switch (xev->type) { case SelectionRequest: - return OnSelectionRequest(xev); + return OnSelectionRequest(xev->xselectionrequest); case SelectionNotify: - return OnSelectionNotify(xev); + return OnSelectionNotify(xev->xselection); } if (using_xfixes_ && @@ -112,30 +146,20 @@ // TARGETS: List of mime types that we support for the clipboard. // TIMESTAMP: Time when we took ownership of the clipboard. // <mime-type>: Mime type to receive clipboard as. -bool X11ClipboardOzone::OnSelectionRequest(XEvent* xev) { - // We only support selection=CLIPBOARD, and property must be set. - if (xev->xselectionrequest.selection != atom_clipboard_ || - xev->xselectionrequest.property == x11::None) { +bool X11ClipboardOzone::OnSelectionRequest( + const XSelectionRequestEvent& event) { + // The property must be set. + if (event.property == x11::None) return false; - } - - XSelectionEvent selection_event; - selection_event.type = SelectionNotify; - selection_event.display = xev->xselectionrequest.display; - selection_event.requestor = xev->xselectionrequest.requestor; - selection_event.selection = xev->xselectionrequest.selection; - selection_event.target = xev->xselectionrequest.target; - selection_event.property = xev->xselectionrequest.property; - selection_event.time = xev->xselectionrequest.time; - - selection_event.property = xev->xselectionrequest.property; // target=TARGETS. - if (selection_event.target == atom_targets_) { + auto& selection_state = GetSelectionState(event.selection); + PlatformClipboard::DataMap& offer_data_map = selection_state.offer_data_map; + if (event.target == atom_targets_) { std::vector<std::string> targets; // Add TIMESTAMP. targets.push_back(kTimestamp); - for (auto& entry : offer_data_map_) { + for (auto& entry : offer_data_map) { targets.push_back(entry.first); } // Expand types, then convert from string to atom. @@ -144,40 +168,49 @@ for (auto& entry : targets) { atoms.push_back(gfx::GetAtom(entry.c_str())); } - XChangeProperty( - x_display_, selection_event.requestor, selection_event.property, - XA_ATOM, /*format=*/32, PropModeReplace, - reinterpret_cast<unsigned char*>(atoms.data()), atoms.size()); + XChangeProperty(x_display_, event.requestor, event.property, XA_ATOM, + /*format=*/32, PropModeReplace, + reinterpret_cast<unsigned char*>(atoms.data()), + atoms.size()); - } else if (selection_event.target == atom_timestamp_) { + } else if (event.target == atom_timestamp_) { // target=TIMESTAMP. - XChangeProperty( - x_display_, selection_event.requestor, selection_event.property, - XA_INTEGER, /*format=*/32, PropModeReplace, - reinterpret_cast<unsigned char*>(&acquired_selection_timestamp_), 1); + XChangeProperty(x_display_, event.requestor, event.property, XA_INTEGER, + /*format=*/32, PropModeReplace, + reinterpret_cast<unsigned char*>( + &selection_state.acquired_selection_timestamp), + 1); } else { // Send clipboard data. - char* target_name = XGetAtomName(x_display_, selection_event.target); + char* target_name = XGetAtomName(x_display_, event.target); std::string key = target_name; // Allow conversions for text/plain[;charset=utf-8] <=> [UTF8_]STRING. - if (key == kUtf8String && !Contains(offer_data_map_, kUtf8String)) { + if (key == kUtf8String && !Contains(offer_data_map, kUtf8String)) { key = kMimeTypeUtf8; - } else if (key == kString && !Contains(offer_data_map_, kString)) { + } else if (key == kString && !Contains(offer_data_map, kString)) { key = kMimeTypeText; } - auto it = offer_data_map_.find(key); - if (it != offer_data_map_.end()) { - XChangeProperty( - x_display_, selection_event.requestor, selection_event.property, - selection_event.target, /*format=*/8, PropModeReplace, - const_cast<unsigned char*>(it->second.data()), it->second.size()); + auto it = offer_data_map.find(key); + if (it != offer_data_map.end()) { + XChangeProperty(x_display_, event.requestor, event.property, event.target, + /*format=*/8, PropModeReplace, + const_cast<unsigned char*>(it->second.data()), + it->second.size()); } XFree(target_name); } // Notify remote peer that clipboard has been sent. + XSelectionEvent selection_event; + selection_event.type = SelectionNotify; + selection_event.display = event.display; + selection_event.requestor = event.requestor; + selection_event.selection = event.selection; + selection_event.target = event.target; + selection_event.property = event.property; + selection_event.time = event.time; XSendEvent(x_display_, selection_event.requestor, /*propagate=*/x11::False, /*event_mask=*/0, reinterpret_cast<XEvent*>(&selection_event)); return true; @@ -186,9 +219,10 @@ // A remote peer owns the clipboard. This event is received in response to // our request for TARGETS (GetAvailableMimeTypes), or a specific mime type // (RequestClipboardData). -bool X11ClipboardOzone::OnSelectionNotify(XEvent* xev) { +bool X11ClipboardOzone::OnSelectionNotify(const XSelectionEvent& event) { // GetAvailableMimeTypes. - if (xev->xselection.target == atom_targets_) { + auto& selection_state = GetSelectionState(event.selection); + if (event.target == atom_targets_) { XAtom type; int format; unsigned long item_count, after; @@ -202,12 +236,12 @@ return false; } - mime_types_.clear(); + selection_state.mime_types.clear(); base::span<XAtom> targets(reinterpret_cast<XAtom*>(data), item_count); for (auto target : targets) { char* atom_name = XGetAtomName(x_display_, target); if (atom_name) { - mime_types_.push_back(atom_name); + selection_state.mime_types.push_back(atom_name); XFree(atom_name); } } @@ -215,20 +249,21 @@ // If we have a saved callback, invoke it now with expanded types, otherwise // guess that we will want 'text/plain' and fetch it now. - if (get_available_mime_types_callback_) { - std::vector<std::string> result(mime_types_); + if (selection_state.get_available_mime_types_callback) { + std::vector<std::string> result(selection_state.mime_types); ExpandTypes(&result); - std::move(get_available_mime_types_callback_).Run(std::move(result)); + std::move(selection_state.get_available_mime_types_callback) + .Run(std::move(result)); } else { - data_mime_type_ = kMimeTypeText; - ReadRemoteClipboard(); + selection_state.data_mime_type = kMimeTypeText; + ReadRemoteClipboard(event.selection); } return true; } // RequestClipboardData. - if (xev->xselection.property == x_property_) { + if (event.property == x_property_) { XAtom type; int format; unsigned long item_count, after; @@ -239,16 +274,18 @@ &item_count, &after, &data); if (type != x11::None && format == 8) { std::vector<unsigned char> tmp(data, data + item_count); - data_ = tmp; + selection_state.data = tmp; } XFree(data); // If we have a saved callback, invoke it now, otherwise this was a prefetch // and we have already saved |data_| for the next call to // |RequestClipboardData|. - if (request_clipboard_data_callback_) { - request_data_map_->emplace(data_mime_type_, data_); - std::move(request_clipboard_data_callback_).Run(data_); + if (selection_state.request_clipboard_data_callback) { + selection_state.request_data_map->emplace(selection_state.data_mime_type, + selection_state.data); + std::move(selection_state.request_clipboard_data_callback) + .Run(selection_state.data); } return true; } @@ -257,27 +294,64 @@ } bool X11ClipboardOzone::OnSetSelectionOwnerNotify(XEvent* xev) { + XFixesSelectionNotifyEvent* event = + reinterpret_cast<XFixesSelectionNotifyEvent*>(xev); + // Reset state and fetch remote clipboard if there is a new remote owner. - if (!IsSelectionOwner()) { - mime_types_.clear(); - data_mime_type_.clear(); - data_.clear(); - QueryTargets(); + if (!IsSelectionOwner(BufferForSelectionAtom(event->selection))) { + auto& selection_state = GetSelectionState(event->selection); + selection_state.mime_types.clear(); + selection_state.data_mime_type.clear(); + selection_state.data.clear(); + QueryTargets(event->selection); } + + // Increase the sequence number always. + update_sequence_cb_.Run(BufferForSelectionAtom(event->selection)); + return true; } -void X11ClipboardOzone::QueryTargets() { - mime_types_.clear(); - XConvertSelection(x_display_, atom_clipboard_, atom_targets_, x_property_, +XAtom X11ClipboardOzone::SelectionAtomForBuffer(ClipboardBuffer buffer) const { + switch (buffer) { + case ClipboardBuffer::kCopyPaste: + return atom_clipboard_; + case ClipboardBuffer::kSelection: + return XA_PRIMARY; + default: + NOTREACHED(); + return x11::None; + } +} + +ClipboardBuffer X11ClipboardOzone::BufferForSelectionAtom( + XAtom selection) const { + if (selection == XA_PRIMARY) + return ClipboardBuffer::kSelection; + if (selection == atom_clipboard_) + return ClipboardBuffer::kCopyPaste; + NOTREACHED(); + return ClipboardBuffer::kCopyPaste; +} + +X11ClipboardOzone::SelectionState& X11ClipboardOzone::GetSelectionState( + XAtom selection) { + DCHECK(Contains(selection_state_, selection)); + return *selection_state_[selection]; +} + +void X11ClipboardOzone::QueryTargets(XAtom selection) { + GetSelectionState(selection).mime_types.clear(); + XConvertSelection(x_display_, selection, atom_targets_, x_property_, x_window_, x11::CurrentTime); } -void X11ClipboardOzone::ReadRemoteClipboard() { - data_.clear(); +void X11ClipboardOzone::ReadRemoteClipboard(XAtom selection) { + auto& selection_state = GetSelectionState(selection); + selection_state.data.clear(); // Allow conversions for text/plain[;charset=utf-8] <=> [UTF8_]STRING. - std::string target = data_mime_type_; - if (!Contains(mime_types_, target)) { + std::string target = selection_state.data_mime_type; + if (!Contains(selection_state.mime_types, target)) { if (target == kMimeTypeText) { target = kString; } else if (target == kMimeTypeUtf8) { @@ -285,68 +359,79 @@ } } - XConvertSelection(x_display_, atom_clipboard_, gfx::GetAtom(target.c_str()), + XConvertSelection(x_display_, selection, gfx::GetAtom(target.c_str()), x_property_, x_window_, x11::CurrentTime); } void X11ClipboardOzone::OfferClipboardData( + ClipboardBuffer buffer, const PlatformClipboard::DataMap& data_map, PlatformClipboard::OfferDataClosure callback) { - acquired_selection_timestamp_ = X11EventSource::GetInstance()->GetTimestamp(); - offer_data_map_ = data_map; + const XAtom selection = SelectionAtomForBuffer(buffer); + auto& selection_state = GetSelectionState(selection); + const auto timestamp = X11EventSource::GetInstance()->GetTimestamp(); + selection_state.acquired_selection_timestamp = timestamp; + selection_state.offer_data_map = data_map; // Only take ownership if we are using xfixes. // TODO(joelhockey): Make clipboard work without xfixes. if (using_xfixes_) { - XSetSelectionOwner(x_display_, atom_clipboard_, x_window_, - acquired_selection_timestamp_); + XSetSelectionOwner(x_display_, selection, x_window_, timestamp); } std::move(callback).Run(); } void X11ClipboardOzone::RequestClipboardData( + ClipboardBuffer buffer, const std::string& mime_type, PlatformClipboard::DataMap* data_map, PlatformClipboard::RequestDataClosure callback) { + const XAtom selection = SelectionAtomForBuffer(buffer); + auto& selection_state = GetSelectionState(selection); // If we are not using xfixes, return empty data. // TODO(joelhockey): Make clipboard work without xfixes. // If we have already prefetched the clipboard for the correct mime type, // then send it right away, otherwise save the callback and attempt to get the // requested mime type from the remote clipboard. - if (!using_xfixes_ || (data_mime_type_ == mime_type && !data_.empty())) { - data_map->emplace(mime_type, data_); - std::move(callback).Run(data_); + if (!using_xfixes_ || (selection_state.data_mime_type == mime_type && + !selection_state.data.empty())) { + data_map->emplace(mime_type, selection_state.data); + std::move(callback).Run(selection_state.data); return; } - data_mime_type_ = mime_type; - request_data_map_ = data_map; - DCHECK(request_clipboard_data_callback_.is_null()); - request_clipboard_data_callback_ = std::move(callback); - ReadRemoteClipboard(); + selection_state.data_mime_type = mime_type; + selection_state.request_data_map = data_map; + DCHECK(selection_state.request_clipboard_data_callback.is_null()); + selection_state.request_clipboard_data_callback = std::move(callback); + ReadRemoteClipboard(selection); } void X11ClipboardOzone::GetAvailableMimeTypes( + ClipboardBuffer buffer, PlatformClipboard::GetMimeTypesClosure callback) { + const XAtom selection = SelectionAtomForBuffer(buffer); + auto& selection_state = GetSelectionState(selection); // If we are not using xfixes, return empty data. // TODO(joelhockey): Make clipboard work without xfixes. // If we already have the list of supported mime types, send the expanded list // of types right away, otherwise save the callback and get the list of // TARGETS from the remote clipboard. - if (!using_xfixes_ || !mime_types_.empty()) { - std::vector<std::string> result(mime_types_); + if (!using_xfixes_ || !selection_state.mime_types.empty()) { + std::vector<std::string> result(selection_state.mime_types); ExpandTypes(&result); std::move(callback).Run(std::move(result)); return; } - DCHECK(get_available_mime_types_callback_.is_null()); - get_available_mime_types_callback_ = std::move(callback); - QueryTargets(); + DCHECK(selection_state.get_available_mime_types_callback.is_null()); + selection_state.get_available_mime_types_callback = std::move(callback); + QueryTargets(selection); } -bool X11ClipboardOzone::IsSelectionOwner() { +bool X11ClipboardOzone::IsSelectionOwner(ClipboardBuffer buffer) { // If we are not using xfixes, then we are always the owner. // TODO(joelhockey): Make clipboard work without xfixes. return !using_xfixes_ || - XGetSelectionOwner(x_display_, atom_clipboard_) == x_window_; + XGetSelectionOwner(x_display_, SelectionAtomForBuffer(buffer)) == + x_window_; } void X11ClipboardOzone::SetSequenceNumberUpdateCb(
diff --git a/ui/ozone/platform/x11/x11_clipboard_ozone.h b/ui/ozone/platform/x11/x11_clipboard_ozone.h index eb0424f9b..8743c6c 100644 --- a/ui/ozone/platform/x11/x11_clipboard_ozone.h +++ b/ui/ozone/platform/x11/x11_clipboard_ozone.h
@@ -9,6 +9,7 @@ #include <vector> #include "base/callback.h" +#include "base/containers/flat_map.h" #include "ui/events/platform/x11/x11_event_source.h" #include "ui/gfx/x/x11.h" #include "ui/gfx/x/x11_types.h" @@ -31,70 +32,52 @@ // PlatformClipboard: void OfferClipboardData( + ClipboardBuffer buffer, const PlatformClipboard::DataMap& data_map, PlatformClipboard::OfferDataClosure callback) override; void RequestClipboardData( + ClipboardBuffer buffer, const std::string& mime_type, PlatformClipboard::DataMap* data_map, PlatformClipboard::RequestDataClosure callback) override; void GetAvailableMimeTypes( + ClipboardBuffer buffer, PlatformClipboard::GetMimeTypesClosure callback) override; - bool IsSelectionOwner() override; + bool IsSelectionOwner(ClipboardBuffer buffer) override; void SetSequenceNumberUpdateCb( PlatformClipboard::SequenceNumberUpdateCb cb) override; private: + struct SelectionState; + // XEventDispatcher: bool DispatchXEvent(XEvent* xev) override; - bool OnSelectionRequest(XEvent* xev); - bool OnSelectionNotify(XEvent* xev); + bool OnSelectionRequest(const XSelectionRequestEvent& event); + bool OnSelectionNotify(const XSelectionEvent& event); bool OnSetSelectionOwnerNotify(XEvent* xev); + // Returns an X atom for a clipboard buffer type. + XAtom SelectionAtomForBuffer(ClipboardBuffer buffer) const; + + // Returns a clipboard buffer type for an X atom for a selection name of the + // system clipboard buffer. + ClipboardBuffer BufferForSelectionAtom(XAtom selection) const; + + // Returns the state for the given selection; + SelectionState& GetSelectionState(XAtom selection); + // Queries the current clipboard owner for what mime types are available by // sending XConvertSelection with target=TARGETS. After sending this, we // will receive a SelectionNotify event with xselection.target=TARGETS which // is processed in |OnSelectionNotify|. - void QueryTargets(); + void QueryTargets(XAtom selection); // Reads the contents of the remote clipboard by sending XConvertSelection // with target=<mime-type>. After sending this, we will receive a // SelectionNotify event with xselection.target=<mime-type> which is processed // in |OnSelectionNotify|. - void ReadRemoteClipboard(); - - // Notifies whenever clipboard sequence number is changed. - PlatformClipboard::SequenceNumberUpdateCb update_sequence_cb_; - - // DataMap we keep from |OfferClipboardData| to service remote requests for - // the clipboard. - PlatformClipboard::DataMap offer_data_map_; - - // DataMap from |RequestClipboardData| that we write remote clipboard contents - // to before calling the completion callback. - PlatformClipboard::DataMap* request_data_map_ = nullptr; - - // Mime types supported by remote clipboard. - std::vector<std::string> mime_types_; - - // Data most recently read from remote clipboard. - std::vector<unsigned char> data_; - - // Mime type of most recently read data from remote clipboard. - std::string data_mime_type_; - - // If XFixes is unavailable, this clipboard window will not register to - // receive events and no processing will take place. - // TODO(joelhockey): Make clipboard work without xfixes. - bool using_xfixes_ = false; - - // The event base returned by XFixesQueryExtension(). - int xfixes_event_base_; - - // Callbacks are stored when we haven't already prefetched the remote - // clipboard. - PlatformClipboard::GetMimeTypesClosure get_available_mime_types_callback_; - PlatformClipboard::RequestDataClosure request_clipboard_data_callback_; + void ReadRemoteClipboard(XAtom selection); // Local cache of atoms. const XAtom atom_clipboard_; @@ -110,8 +93,19 @@ // Input-only window used as a selection owner. const XID x_window_; - // The time that this instance took ownership of the clipboard. - Time acquired_selection_timestamp_; + // If XFixes is unavailable, this clipboard window will not register to + // receive events and no processing will take place. + // TODO(joelhockey): Make clipboard work without xfixes. + bool using_xfixes_ = false; + + // The event base returned by XFixesQueryExtension(). + int xfixes_event_base_; + + // Notifies whenever clipboard sequence number is changed. + PlatformClipboard::SequenceNumberUpdateCb update_sequence_cb_; + + // State of selections served by this instance. + base::flat_map<XAtom, std::unique_ptr<SelectionState>> selection_state_; DISALLOW_COPY_AND_ASSIGN(X11ClipboardOzone); };
diff --git a/ui/ozone/public/platform_clipboard.h b/ui/ozone/public/platform_clipboard.h index 377ba00..0962bc9 100644 --- a/ui/ozone/public/platform_clipboard.h +++ b/ui/ozone/public/platform_clipboard.h
@@ -12,13 +12,17 @@ #include "base/component_export.h" #include "base/macros.h" #include "base/optional.h" +#include "ui/base/clipboard/clipboard_buffer.h" namespace ui { -// PlatformClipboard is an interface that allows Ozone backends to exchange -// data with other applications on the host system. The most familiar use for -// it is handling copy and paste operations. +// Allows Chrome controls and windows to exchange data with each other and other +// applications, e.g., to copy and paste. // +// In environments that have multiple clipboards (like Linux X11 or OS X, see +// ui::ClipboardBuffer), the implementation should provide a separate data +// buffer for each system clipboard. When data is requested or offered, the +// caller specifies which buffer to use by providing the |buffer| parameter. class COMPONENT_EXPORT(OZONE_BASE) PlatformClipboard { public: virtual ~PlatformClipboard() {} @@ -30,7 +34,8 @@ // SequenceNumberUpdateCb is a repeating callback, which can be used to tell // a client of the PlatformClipboard to increment clipboard's sequence number - using SequenceNumberUpdateCb = base::RepeatingCallback<void()>; + using SequenceNumberUpdateCb = + base::RepeatingCallback<void(ClipboardBuffer buffer)>; // Offers a given clipboard data 'data_map' to the host system clipboard. // @@ -47,7 +52,8 @@ // OfferDataClosure should be invoked when the host clipboard implementation // acknowledges that the "offer to clipboard" operation is performed. using OfferDataClosure = base::OnceCallback<void()>; - virtual void OfferClipboardData(const DataMap& data_map, + virtual void OfferClipboardData(ClipboardBuffer buffer, + const DataMap& data_map, OfferDataClosure callback) = 0; // Reads data from host system clipboard given mime type. The data is @@ -57,7 +63,8 @@ // data has been read and stored into 'data_map'. using RequestDataClosure = base::OnceCallback<void(const base::Optional<std::vector<uint8_t>>&)>; - virtual void RequestClipboardData(const std::string& mime_type, + virtual void RequestClipboardData(ClipboardBuffer buffer, + const std::string& mime_type, DataMap* data_map, RequestDataClosure callback) = 0; @@ -68,7 +75,8 @@ // operations are known. using GetMimeTypesClosure = base::OnceCallback<void(const std::vector<std::string>&)>; - virtual void GetAvailableMimeTypes(GetMimeTypesClosure callback) = 0; + virtual void GetAvailableMimeTypes(ClipboardBuffer buffer, + GetMimeTypesClosure callback) = 0; // Returns true if the current application writing data to the host clipboard // data is this one; false otherwise. @@ -76,7 +84,7 @@ // It can be relevant to know this information in case the client wants to // caches the clipboard data, and wants to know if it is possible to use // the cached data in order to reply faster to read-clipboard operations. - virtual bool IsSelectionOwner() = 0; + virtual bool IsSelectionOwner(ClipboardBuffer buffer) = 0; // See comment above SequenceNumberUpdateCb. Can be called once. virtual void SetSequenceNumberUpdateCb(SequenceNumberUpdateCb cb) = 0;
diff --git a/ui/webui/resources/cr_elements/BUILD.gn b/ui/webui/resources/cr_elements/BUILD.gn index 23c694e..a9a9475 100644 --- a/ui/webui/resources/cr_elements/BUILD.gn +++ b/ui/webui/resources/cr_elements/BUILD.gn
@@ -85,6 +85,12 @@ # Targets for auto-generating Polymer 3 JS Modules. +polymer_modulizer("action_link_css") { + js_file = "action_link_css.m.js" + html_file = "action_link_css.html" + html_type = "style-module" +} + polymer_modulizer("shared_vars_css") { js_file = "shared_vars_css.m.js" html_file = "shared_vars_css.html" @@ -128,6 +134,7 @@ group("polymer3_elements") { deps = [ + ":action_link_css_module", ":cr_icons_css_module", ":hidden_style_css_module", ":icons_module",
diff --git a/ui/webui/resources/cr_elements_resources_v3.grdp b/ui/webui/resources/cr_elements_resources_v3.grdp index 979a065..fcc98b9 100644 --- a/ui/webui/resources/cr_elements_resources_v3.grdp +++ b/ui/webui/resources/cr_elements_resources_v3.grdp
@@ -1,6 +1,11 @@ <?xml version="1.0" encoding="utf-8"?> <grit-part> <!-- Polymer 3.0 Elements --> + <include name="IDR_CR_ELEMENTS_ACTION_LINK_CSS_M_JS" + file="${root_gen_dir}/ui/webui/resources/cr_elements/action_link_css.m.js" + use_base_dir="false" + type="BINDATA" + compress="gzip" /> <include name="IDR_CR_ELEMENTS_CR_ACTION_MENU_ANCHOR_ALIGNMENT_M_JS" file="${root_gen_dir}/ui/webui/resources/cr_elements/cr_action_menu/anchor_alignment.m.js" use_base_dir="false"