diff --git a/DEPS b/DEPS index d6011c92..2c8d360 100644 --- a/DEPS +++ b/DEPS
@@ -167,11 +167,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': '2638f3d44b021eb9a03e7bafb22f68852a65d575', + 'skia_revision': '915b779f9cfd5a885154bf4cb6b65230ed3ef5de', # 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': 'b8b45f95d46ba556184b321dc47643252d72ea20', + 'v8_revision': 'e9c6aa2428d01a7adcfbccc3132443ee309e9568', # 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. @@ -179,7 +179,7 @@ # 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': '9122bec28506ddefc46974c0d210382a9881aaf0', + 'angle_revision': 'be1fa7d8cddfe0ccc05d1458678b93eaab1afa43', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -187,7 +187,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '44d038359f4ee991e42da983a15c012c2b13b638', + 'pdfium_revision': 'c0e6e7a631e75288270e52520455b84744bfcb94', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -230,7 +230,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': 'bfdfc7ac4118354794ef65bd45bf686949830ec2', + 'catapult_revision': 'bef344f7017fc9e04f7049d0f58af6d9ce9f4ab6', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -445,7 +445,7 @@ 'packages': [ { 'package': 'chromium/chrome/test/data/autofill/captured_sites', - 'version': 'qXyuiSemC7BA9Rtoa77IjWhCD8arKt968jVmHDt34hQC', + 'version': '23EuJes_tRa4KkcqAuvDc48MlYCQwVKmjv64tpGllr8C', } ], 'condition': 'checkout_chromium_autofill_test_dependencies', @@ -866,7 +866,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '8017a6a7fc260ec47bbf2b7fac188bc30afc6c6e', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '6e9cdb62e782d2432b3bf0d509e7236823f2ff6d', 'condition': 'checkout_linux', }, @@ -891,7 +891,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '53f9e0979a583470e6504e73a1789b23ff0b0464', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '67fccdf0c90e11031f9e6f3043b7d0f6cc7c664f', 'src/third_party/devtools-node-modules': Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'), @@ -1054,7 +1054,7 @@ Var('chromium_git') + '/chromium/deps/hunspell_dictionaries.git' + '@' + '681ca92480ecc11d35feae8c1c00e4e035630f43', 'src/third_party/icu': - Var('chromium_git') + '/chromium/deps/icu.git' + '@' + '5005010d694e16571b8dfbf07d70817841f80a69', + Var('chromium_git') + '/chromium/deps/icu.git' + '@' + 'b51014b96251d1a0194db61a2aa36eb216daf43c', 'src/third_party/icu4j': { 'packages': [ @@ -1477,7 +1477,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '2701c130839edbeb226735b0775966b6423d9e83', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'a043b2ba46b9f81f1a679f36e1945fc7802f8201', + Var('webrtc_git') + '/src.git' + '@' + '05691ddbd2bcf0fc31a64d7714b5ea05d2492820', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1539,7 +1539,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@2ba136292e50c1cb99abde0260cc8e5cdbb64bc5', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@8e8e4f75129b01e20ae96560fb5aba566d837be4', 'condition': 'checkout_src_internal', },
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 9bbb4f6b..e67a8c2 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -3123,11 +3123,9 @@ # Extract the tag from lines like `Log.d(TAG, "*");` or `Log.d("TAG", "*");` log_call_pattern = input_api.re.compile(r'^\s*Log\.\w\((?P<tag>\"?\w+\"?)\,') log_decl_pattern = input_api.re.compile( - r'^\s*private static final String TAG = "(?P<name>(.*))";', - input_api.re.MULTILINE) + r'static final String TAG = "(?P<name>(.*))"') - REF_MSG = ('See docs/android_logging.md ' - 'or contact dgn@chromium.org for more info.') + REF_MSG = ('See docs/android_logging.md for more info.') sources = lambda x: input_api.FilterSourceFile(x, white_list=[r'.*\.java$'], black_list=cr_log_check_excluded_paths)
diff --git a/PRESUBMIT_test.py b/PRESUBMIT_test.py index 772d241..209560f9 100755 --- a/PRESUBMIT_test.py +++ b/PRESUBMIT_test.py
@@ -1267,6 +1267,12 @@ 'private static final String TAG = "cr_foo.bar";', 'Log.d(TAG, "foo");', ]), + MockAffectedFile('HasDottedTagPublic.java', [ + 'import org.chromium.base.Log;', + 'some random stuff', + 'public static final String TAG = "cr_foo.bar";', + 'Log.d(TAG, "foo");', + ]), MockAffectedFile('HasNoTagDecl.java', [ 'import org.chromium.base.Log;', 'some random stuff', @@ -1332,9 +1338,10 @@ # Tag must not contain nb = len(msgs[4].items) - self.assertEqual(2, nb, + self.assertEqual(3, nb, 'Expected %d items, found %d: %s' % (2, nb, msgs[4].items)) self.assertTrue('HasDottedTag.java' in msgs[4].items) + self.assertTrue('HasDottedTagPublic.java' in msgs[4].items) self.assertTrue('HasOldTag.java' in msgs[4].items)
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index b877416..e26d377b 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -163,8 +163,14 @@ "ambient/model/photo_model.cc", "ambient/model/photo_model.h", "ambient/model/photo_model_observer.h", + "ambient/ui/ambient_assistant_container_view.cc", + "ambient/ui/ambient_assistant_container_view.h", + "ambient/ui/ambient_assistant_dialog_plate.cc", + "ambient/ui/ambient_assistant_dialog_plate.h", "ambient/ui/ambient_container_view.cc", "ambient/ui/ambient_container_view.h", + "ambient/ui/assistant_response_container_view.cc", + "ambient/ui/assistant_response_container_view.h", "ambient/ui/photo_view.cc", "ambient/ui/photo_view.h", "ambient/util/ambient_util.cc",
diff --git a/ash/ambient/ambient_controller.cc b/ash/ambient/ambient_controller.cc index 6dbb54a..cd4da08 100644 --- a/ash/ambient/ambient_controller.cc +++ b/ash/ambient/ambient_controller.cc
@@ -8,6 +8,7 @@ #include "ash/ambient/model/photo_model_observer.h" #include "ash/ambient/ui/ambient_container_view.h" #include "ash/ambient/util/ambient_util.h" +#include "ash/assistant/assistant_controller.h" #include "ash/login/ui/lock_screen.h" #include "ash/public/cpp/ambient/photo_controller.h" #include "chromeos/constants/chromeos_features.h" @@ -24,7 +25,8 @@ } // namespace -AmbientController::AmbientController() = default; +AmbientController::AmbientController(AssistantController* assistant_controller) + : assistant_controller_(assistant_controller) {} AmbientController::~AmbientController() { DestroyContainerView(); @@ -34,6 +36,11 @@ refresh_timer_.Stop(); container_view_->GetWidget()->RemoveObserver(this); container_view_ = nullptr; + + // If our widget is being destroyed, Assistant UI is no longer visible. + // If Assistant UI was already closed, this is a no-op. + assistant_controller_->ui_controller()->CloseUi( + AssistantExitPoint::kUnspecified); } void AmbientController::Toggle() { @@ -57,6 +64,13 @@ return; } + // CloseUi to ensure standalone Assistant Ui doesn't exist when entering + // Ambient mode to avoid strange behavior caused by standalone Ui was + // only hidden at that time. This will be a no-op if Ui was already closed. + // TODO(meilinw): Handle embedded Ui. + assistant_controller_->ui_controller()->CloseUi( + AssistantExitPoint::kUnspecified); + CreateContainerView(); container_view_->GetWidget()->Show(); RefreshImage();
diff --git a/ash/ambient/ambient_controller.h b/ash/ambient/ambient_controller.h index aa95084..2bdbce9 100644 --- a/ash/ambient/ambient_controller.h +++ b/ash/ambient/ambient_controller.h
@@ -19,12 +19,13 @@ namespace ash { class AmbientContainerView; +class AssistantController; class PhotoModelObserver; // Class to handle all ambient mode functionalities. class ASH_EXPORT AmbientController : views::WidgetObserver { public: - AmbientController(); + explicit AmbientController(AssistantController* assistant_controller); ~AmbientController() override; // views::WidgetObserver: @@ -46,6 +47,10 @@ return refresh_timer_; } + AssistantController* assistant_controller() { return assistant_controller_; } + + bool is_showing() const { return !!container_view_; } + private: void Start(); void Stop(); @@ -56,7 +61,8 @@ void GetNextImage(); void OnPhotoDownloaded(const gfx::ImageSkia& image); - AmbientContainerView* container_view_ = nullptr; + AssistantController* const assistant_controller_; // Owned by Shell. + AmbientContainerView* container_view_ = nullptr; // Owned by view hierarchy. PhotoModel model_; base::OneShotTimer refresh_timer_; base::WeakPtrFactory<AmbientController> weak_factory_{this};
diff --git a/ash/ambient/ui/ambient_assistant_container_view.cc b/ash/ambient/ui/ambient_assistant_container_view.cc new file mode 100644 index 0000000..cba7a89 --- /dev/null +++ b/ash/ambient/ui/ambient_assistant_container_view.cc
@@ -0,0 +1,129 @@ +// 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. + +#include "ash/ambient/ui/ambient_assistant_container_view.h" + +#include <memory> +#include <string> + +#include "ash/ambient/ui/ambient_assistant_dialog_plate.h" +#include "ash/ambient/ui/assistant_response_container_view.h" +#include "ash/assistant/ui/assistant_ui_constants.h" +#include "ash/assistant/ui/assistant_view_delegate.h" +#include "ash/assistant/util/assistant_util.h" +#include "ash/session/session_controller_impl.h" +#include "ash/shell.h" +#include "ash/strings/grit/ash_strings.h" +#include "base/strings/utf_string_conversions.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/views/background.h" +#include "ui/views/controls/image_view.h" +#include "ui/views/controls/label.h" +#include "ui/views/layout/box_layout.h" + +namespace ash { + +namespace { + +// Appearance. +constexpr int kAvatarImageSizeDip = 32; + +// Greeting message. +base::string16 GetGreetingMessage(const UserSession* user_session) { + const std::string& username = user_session->user_info.display_name; + return l10n_util::GetStringFUTF16(IDS_ASSISTANT_AMBIENT_GREETING_MESSAGE, + base::UTF8ToUTF16(username)); +} + +} // namespace + +AmbientAssistantContainerView::AmbientAssistantContainerView( + AssistantViewDelegate* delegate) + : delegate_(delegate) { + InitLayout(); + + // The AssistantViewDelegate should outlive AmbientAssistantContainerView. + delegate_->AddUiModelObserver(this); +} + +AmbientAssistantContainerView::~AmbientAssistantContainerView() { + delegate_->RemoveUiModelObserver(this); +} + +const char* AmbientAssistantContainerView::GetClassName() const { + return "AmbientAssistantContainerView"; +} + +void AmbientAssistantContainerView::OnUiVisibilityChanged( + AssistantVisibility new_visibility, + AssistantVisibility old_visibility, + base::Optional<AssistantEntryPoint> entry_point, + base::Optional<AssistantExitPoint> exit_point) { + // TODO(meilinw): Define the expected behavior where multiple Assistant UIs + // could exist at the same time (e.g. launcher embedded UI and ambient UI + // for in-session Ambient Mode), but only one that is currently active + // should be responding to Assistant events. + if (assistant::util::IsStartingSession(new_visibility, old_visibility)) + SetVisible(true); + else if (assistant::util::IsFinishingSession(new_visibility)) + SetVisible(false); +} + +void AmbientAssistantContainerView::InitLayout() { + SetPaintToLayer(); + SetBackground(views::CreateSolidBackground(SK_ColorWHITE)); + + constexpr int kRightPaddingDip = 8; + views::BoxLayout* layout_manager = + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal, + gfx::Insets(0, 0, 0, kRightPaddingDip))); + + layout_manager->set_cross_axis_alignment( + views::BoxLayout::CrossAxisAlignment::kCenter); + + // Mic button and input query view. + ambient_assistant_dialog_plate_ = + AddChildView(std::make_unique<AmbientAssistantDialogPlate>(delegate_)); + + // Response container view. + assistant_response_container_view_ = + AddChildView(std::make_unique<AssistantResponseContainerView>(delegate_)); + + // Greeting label. + const UserSession* active_user_session = + Shell::Get()->session_controller()->GetUserSession(0); + greeting_label_ = AddChildView( + std::make_unique<views::Label>(GetGreetingMessage(active_user_session))); + greeting_label_->SetEnabledColor(kTextColorSecondary); + greeting_label_->SetFontList( + ash::assistant::ui::GetDefaultFontList() + .DeriveWithSizeDelta(8) + .DeriveWithWeight(gfx::Font::Weight::NORMAL)); + greeting_label_->SetHorizontalAlignment( + gfx::HorizontalAlignment::ALIGN_CENTER); + + // Spacer. + views::View* spacer = AddChildView(std::make_unique<views::View>()); + // Sets the flex weight to be 1 so the spacer view can be resized. + layout_manager->SetFlexForView(spacer, 1); + + // Rounded avatar image view. + avatar_view_ = AddChildView(std::make_unique<views::ImageView>()); + avatar_view_->SetImageSize( + gfx::Size(kAvatarImageSizeDip, kAvatarImageSizeDip)); + avatar_view_->SetPreferredSize( + gfx::Size(kAvatarImageSizeDip, kAvatarImageSizeDip)); + gfx::ImageSkia avatar = active_user_session->user_info.avatar.image; + if (!avatar.isNull()) + avatar_view_->SetImage(avatar); + + SkPath circular_mask; + constexpr int kClipCircleRadius = kAvatarImageSizeDip / 2; + circular_mask.addCircle(kClipCircleRadius, kClipCircleRadius, + kClipCircleRadius); + avatar_view_->set_clip_path(circular_mask); +} + +} // namespace ash
diff --git a/ash/ambient/ui/ambient_assistant_container_view.h b/ash/ambient/ui/ambient_assistant_container_view.h new file mode 100644 index 0000000..a0183fe --- /dev/null +++ b/ash/ambient/ui/ambient_assistant_container_view.h
@@ -0,0 +1,55 @@ +// 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 ASH_AMBIENT_UI_AMBIENT_ASSISTANT_CONTAINER_VIEW_H_ +#define ASH_AMBIENT_UI_AMBIENT_ASSISTANT_CONTAINER_VIEW_H_ + +#include "ash/assistant/model/assistant_ui_model_observer.h" +#include "base/macros.h" +#include "ui/views/view.h" + +namespace views { +class ImageView; +class Label; +} // namespace views + +namespace ash { + +class AssistantResponseContainerView; +class AssistantViewDelegate; +class AmbientAssistantDialogPlate; + +class AmbientAssistantContainerView : public views::View, + public AssistantUiModelObserver { + public: + explicit AmbientAssistantContainerView(AssistantViewDelegate* delegate); + ~AmbientAssistantContainerView() override; + + // views::View: + const char* GetClassName() const override; + + // AssistantUiModelObserver: + void OnUiVisibilityChanged( + AssistantVisibility new_visibility, + AssistantVisibility old_visibility, + base::Optional<AssistantEntryPoint> entry_point, + base::Optional<AssistantExitPoint> exit_point) override; + + private: + void InitLayout(); + + AssistantViewDelegate* const delegate_; // Owned by AssistantController. + + // Owned by view hierarchy. + AmbientAssistantDialogPlate* ambient_assistant_dialog_plate_ = nullptr; + AssistantResponseContainerView* assistant_response_container_view_ = nullptr; + views::ImageView* avatar_view_ = nullptr; + views::Label* greeting_label_ = nullptr; + + DISALLOW_COPY_AND_ASSIGN(AmbientAssistantContainerView); +}; + +} // namespace ash + +#endif // ASH_AMBIENT_UI_AMBIENT_ASSISTANT_CONTAINER_VIEW_H_
diff --git a/ash/ambient/ui/ambient_assistant_dialog_plate.cc b/ash/ambient/ui/ambient_assistant_dialog_plate.cc new file mode 100644 index 0000000..9dadf560 --- /dev/null +++ b/ash/ambient/ui/ambient_assistant_dialog_plate.cc
@@ -0,0 +1,68 @@ +// 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. + +#include "ash/ambient/ui/ambient_assistant_dialog_plate.h" + +#include <memory> + +#include "ash/assistant/ui/assistant_view_delegate.h" +#include "ash/assistant/ui/dialog_plate/mic_view.h" +#include "ash/assistant/ui/main_stage/assistant_query_view.h" +#include "ash/strings/grit/ash_strings.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/views/layout/box_layout.h" + +namespace ash { + +AmbientAssistantDialogPlate::AmbientAssistantDialogPlate( + AssistantViewDelegate* delegate) + : delegate_(delegate) { + InitLayout(); + + // The AssistantViewDelegate should outlive AmbientAssistantDialogPlate. + delegate_->AddInteractionModelObserver(this); +} + +AmbientAssistantDialogPlate::~AmbientAssistantDialogPlate() { + delegate_->RemoveInteractionModelObserver(this); +} + +const char* AmbientAssistantDialogPlate::GetClassName() const { + return "AmbientAssistantDialogPlate"; +} + +void AmbientAssistantDialogPlate::ButtonPressed(views::Button* sender, + const ui::Event& event) { + delegate_->OnDialogPlateButtonPressed( + static_cast<AssistantButtonId>(sender->GetID())); +} + +void AmbientAssistantDialogPlate::OnCommittedQueryChanged( + const AssistantQuery& query) { + voice_query_view_->SetQuery(query); +} + +void AmbientAssistantDialogPlate::OnPendingQueryChanged( + const AssistantQuery& query) { + voice_query_view_->SetQuery(query); +} + +void AmbientAssistantDialogPlate::InitLayout() { + views::BoxLayout* layout_manager = + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal)); + layout_manager->set_main_axis_alignment( + views::BoxLayout::MainAxisAlignment::kStart); + + // Animated voice input toggle button. + animated_voice_input_toggle_ = AddChildView(std::make_unique<MicView>( + this, delegate_, AssistantButtonId::kVoiceInputToggle)); + animated_voice_input_toggle_->SetAccessibleName( + l10n_util::GetStringUTF16(IDS_ASH_ASSISTANT_DIALOG_PLATE_MIC_ACCNAME)); + + // Voice input query view. + voice_query_view_ = AddChildView(std::make_unique<AssistantQueryView>()); +} + +} // namespace ash
diff --git a/ash/ambient/ui/ambient_assistant_dialog_plate.h b/ash/ambient/ui/ambient_assistant_dialog_plate.h new file mode 100644 index 0000000..eb6154f --- /dev/null +++ b/ash/ambient/ui/ambient_assistant_dialog_plate.h
@@ -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. + +#ifndef ASH_AMBIENT_UI_AMBIENT_ASSISTANT_DIALOG_PLATE_H_ +#define ASH_AMBIENT_UI_AMBIENT_ASSISTANT_DIALOG_PLATE_H_ + +#include "ash/assistant/model/assistant_interaction_model_observer.h" +#include "base/macros.h" +#include "ui/views/controls/button/button.h" +#include "ui/views/view.h" + +namespace ash { + +class AssistantQueryView; +class AssistantViewDelegate; +class MicView; +enum class AssistantButtonId; + +class AmbientAssistantDialogPlate : public views::View, + public views::ButtonListener, + public AssistantInteractionModelObserver { + public: + explicit AmbientAssistantDialogPlate(AssistantViewDelegate* delegate); + ~AmbientAssistantDialogPlate() override; + + // views::View: + const char* GetClassName() const override; + + // views::ButtonListener: + void ButtonPressed(views::Button* sender, const ui::Event& event) override; + + // AssistantInteractionModelObserver: + void OnCommittedQueryChanged(const AssistantQuery& query) override; + void OnPendingQueryChanged(const AssistantQuery& query) override; + + private: + void InitLayout(); + + AssistantViewDelegate* const delegate_; + + // Owned by view hierarchy. + MicView* animated_voice_input_toggle_ = nullptr; + AssistantQueryView* voice_query_view_ = nullptr; + + DISALLOW_COPY_AND_ASSIGN(AmbientAssistantDialogPlate); +}; + +} // namespace ash + +#endif // ASH_AMBIENT_UI_AMBIENT_ASSISTANT_DIALOG_PLATE_H_
diff --git a/ash/ambient/ui/ambient_container_view.cc b/ash/ambient/ui/ambient_container_view.cc index e522649..e5b5ba88 100644 --- a/ash/ambient/ui/ambient_container_view.cc +++ b/ash/ambient/ui/ambient_container_view.cc
@@ -4,10 +4,14 @@ #include "ash/ambient/ui/ambient_container_view.h" +#include <memory> +#include <utility> + #include "ash/ambient/ambient_controller.h" -#include "ash/ambient/ui/ambient_container_view.h" +#include "ash/ambient/ui/ambient_assistant_container_view.h" #include "ash/ambient/ui/photo_view.h" #include "ash/ambient/util/ambient_util.h" +#include "ash/assistant/assistant_controller.h" #include "ash/login/ui/lock_screen.h" #include "ash/public/cpp/shell_window_ids.h" #include "ash/shell.h" @@ -20,6 +24,9 @@ namespace { +// Ambient Assistant container view appearance. +constexpr int kAmbientAssistantContainerViewPreferredHeightDip = 128; + aura::Window* GetContainer() { aura::Window* container = nullptr; if (ambient::util::IsShowing(LockScreen::ScreenType::kLock)) @@ -60,6 +67,16 @@ return GetWidget()->GetNativeWindow()->GetRootWindow()->bounds().size(); } +void AmbientContainerView::Layout() { + if (!ambient_assistant_container_view_) + return; + + // Set bounds for the ambient Assistant container view. + ambient_assistant_container_view_->SetBoundsRect( + gfx::Rect(0, 0, GetWidget()->GetRootView()->size().width(), + kAmbientAssistantContainerViewPreferredHeightDip)); +} + void AmbientContainerView::OnMouseEvent(ui::MouseEvent* event) { if (event->type() == ui::ET_MOUSE_PRESSED) { event->SetHandled(); @@ -79,8 +96,12 @@ // TODO(b/139954108): Choose a better dark mode theme color. SetBackground(views::CreateSolidBackground(SK_ColorBLACK)); - photo_view_ = new PhotoView(ambient_controller_); - AddChildView(photo_view_); + photo_view_ = AddChildView(std::make_unique<PhotoView>(ambient_controller_)); + + ambient_assistant_container_view_ = + AddChildView(std::make_unique<AmbientAssistantContainerView>( + ambient_controller_->assistant_controller()->view_delegate())); + ambient_assistant_container_view_->SetVisible(false); } } // namespace ash
diff --git a/ash/ambient/ui/ambient_container_view.h b/ash/ambient/ui/ambient_container_view.h index 2f499d65..26f8cfa9 100644 --- a/ash/ambient/ui/ambient_container_view.h +++ b/ash/ambient/ui/ambient_container_view.h
@@ -11,6 +11,7 @@ namespace ash { +class AmbientAssistantContainerView; class AmbientController; class PhotoView; @@ -23,6 +24,7 @@ // views::View: const char* GetClassName() const override; gfx::Size CalculatePreferredSize() const override; + void Layout() override; void OnMouseEvent(ui::MouseEvent* event) override; void OnGestureEvent(ui::GestureEvent* event) override; @@ -30,7 +32,10 @@ void Init(); AmbientController* ambient_controller_ = nullptr; - PhotoView* photo_view_ = nullptr; // Owned by view hierarchy. + + // Owned by view hierarchy. + PhotoView* photo_view_ = nullptr; + AmbientAssistantContainerView* ambient_assistant_container_view_ = nullptr; DISALLOW_COPY_AND_ASSIGN(AmbientContainerView); };
diff --git a/ash/ambient/ui/assistant_response_container_view.cc b/ash/ambient/ui/assistant_response_container_view.cc new file mode 100644 index 0000000..e93c5456 --- /dev/null +++ b/ash/ambient/ui/assistant_response_container_view.cc
@@ -0,0 +1,77 @@ +// 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. + +#include "ash/ambient/ui/assistant_response_container_view.h" + +#include <memory> + +#include "ash/assistant/model/assistant_interaction_model_observer.h" +#include "ash/assistant/model/assistant_response.h" +#include "ash/assistant/model/assistant_ui_element.h" +#include "ash/assistant/ui/assistant_view_delegate.h" +#include "ash/assistant/ui/main_stage/assistant_text_element_view.h" +#include "ui/views/layout/box_layout.h" + +namespace ash { + +namespace { + +// Appearance. +constexpr int kPreferredWidthDip = 600; + +} // namespace + +AssistantResponseContainerView::AssistantResponseContainerView( + AssistantViewDelegate* delegate) + : AnimatedContainerView(delegate) { + InitLayout(); +} + +AssistantResponseContainerView::~AssistantResponseContainerView() = default; + +const char* AssistantResponseContainerView::GetClassName() const { + return "AssistantResponseContainerView"; +} + +gfx::Size AssistantResponseContainerView::CalculatePreferredSize() const { + return gfx::Size(kPreferredWidthDip, + content_view()->GetHeightForWidth(kPreferredWidthDip)); +} + +void AssistantResponseContainerView::OnContentsPreferredSizeChanged( + views::View* content_view) { + content_view->SetSize(CalculatePreferredSize()); +} + +void AssistantResponseContainerView::InitLayout() { + content_view()->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); +} + +void AssistantResponseContainerView::HandleResponse( + const AssistantResponse& response) { + for (const auto& ui_element : response.GetUiElements()) { + switch (ui_element->GetType()) { + case AssistantUiElementType::kCard: + // For card elements, we instead use the "fallback" message for HTML + // card rendering as the text response. + AddTextElementView(new AssistantTextElement( + static_cast<const AssistantCardElement*>(ui_element.get()) + ->fallback())); + break; + case AssistantUiElementType::kText: + AddTextElementView( + static_cast<const AssistantTextElement*>(ui_element.get())); + break; + } + } +} + +void AssistantResponseContainerView::AddTextElementView( + const AssistantTextElement* text_element) { + content_view()->AddChildView( + std::make_unique<AssistantTextElementView>(text_element)); +} + +} // namespace ash
diff --git a/ash/ambient/ui/assistant_response_container_view.h b/ash/ambient/ui/assistant_response_container_view.h new file mode 100644 index 0000000..9143eb1 --- /dev/null +++ b/ash/ambient/ui/assistant_response_container_view.h
@@ -0,0 +1,39 @@ +// 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 ASH_AMBIENT_UI_ASSISTANT_RESPONSE_CONTAINER_VIEW_H_ +#define ASH_AMBIENT_UI_ASSISTANT_RESPONSE_CONTAINER_VIEW_H_ + +#include "ash/assistant/ui/main_stage/animated_container_view.h" +#include "base/macros.h" + +namespace ash { + +class AssistantResponse; +class AssistantTextElement; +class AssistantViewDelegate; + +class AssistantResponseContainerView : public AnimatedContainerView { + public: + explicit AssistantResponseContainerView(AssistantViewDelegate* delegate); + ~AssistantResponseContainerView() override; + + // AnimatedContainerView: + const char* GetClassName() const override; + gfx::Size CalculatePreferredSize() const override; + void OnContentsPreferredSizeChanged(views::View* content_view) override; + + private: + void InitLayout(); + void AddTextElementView(const AssistantTextElement* text_element); + + // AnimatedContainerView: + void HandleResponse(const AssistantResponse& response) override; + + DISALLOW_COPY_AND_ASSIGN(AssistantResponseContainerView); +}; + +} // namespace ash + +#endif // ASH_AMBIENT_UI_ASSISTANT_RESPONSE_CONTAINER_VIEW_H_
diff --git a/ash/app_list/app_list_controller_impl_unittest.cc b/ash/app_list/app_list_controller_impl_unittest.cc index 0b87bab..0baefc18 100644 --- a/ash/app_list/app_list_controller_impl_unittest.cc +++ b/ash/app_list/app_list_controller_impl_unittest.cc
@@ -35,9 +35,13 @@ #include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ash/wm/window_state.h" #include "ash/wm/window_util.h" +#include "base/macros.h" #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" #include "base/test/metrics/histogram_tester.h" +#include "base/test/scoped_feature_list.h" +#include "chromeos/constants/chromeos_features.h" +#include "chromeos/constants/chromeos_switches.h" #include "ui/compositor/scoped_animation_duration_scale_mode.h" #include "ui/events/test/event_generator.h" #include "ui/message_center/message_center.h" @@ -435,10 +439,34 @@ GetAppListView()->app_list_state()); } +class HotseatAppListControllerImplTest + : public AppListControllerImplTest, + public testing::WithParamInterface<bool> { + public: + HotseatAppListControllerImplTest() = default; + ~HotseatAppListControllerImplTest() override = default; + + // AshTestBase: + void SetUp() override { + if (GetParam()) { + feature_list_.InitAndEnableFeature(chromeos::features::kShelfHotseat); + } else { + feature_list_.InitAndDisableFeature(chromeos::features::kShelfHotseat); + } + AppListControllerImplTest::SetUp(); + } + + private: + base::test::ScopedFeatureList feature_list_; + DISALLOW_COPY_AND_ASSIGN(HotseatAppListControllerImplTest); +}; + +// Tests with both hotseat disabled and enabled. +INSTANTIATE_TEST_SUITE_P(, HotseatAppListControllerImplTest, testing::Bool()); + // Tests for HomeScreenDelegate::GetInitialAppListItemScreenBoundsForWindow // implemtenation. -// Disabled due to crbug.com/1016843 -TEST_F(AppListControllerImplTest, DISABLED_GetItemBoundsForWindow) { +TEST_P(HotseatAppListControllerImplTest, GetItemBoundsForWindow) { // Populate app list model with 25 items, of which items at indices in // |folders| are folders containing a single item. const std::set<int> folders = {5, 23}; @@ -485,14 +513,18 @@ {"", base::nullopt}, {"fake_id_22", base::nullopt}}; + // Tests the case app ID property is not set on the window. + std::unique_ptr<aura::Window> window_without_app_id(CreateTestWindow()); + HomeScreenDelegate* const home_screen_delegate = Shell::Get()->home_screen_controller()->delegate(); + // NOTE: Calculate the apps grid bounds after test window is shown, as showing + // the window can change the app list layout (due to the change in the shelf + // height). const gfx::Rect apps_grid_bounds = apps_grid_view->GetBoundsInScreen(); const gfx::Rect apps_grid_center = gfx::Rect(apps_grid_bounds.CenterPoint(), gfx::Size(1, 1)); - // Tests the case app ID property is not set on the window. - std::unique_ptr<aura::Window> window_without_app_id(CreateTestWindow()); EXPECT_EQ(apps_grid_center, home_screen_delegate->GetInitialAppListItemScreenBoundsForWindow( window_without_app_id.get()));
diff --git a/ash/app_list/views/apps_grid_view.cc b/ash/app_list/views/apps_grid_view.cc index 66d851d..559ddb5b 100644 --- a/ash/app_list/views/apps_grid_view.cc +++ b/ash/app_list/views/apps_grid_view.cc
@@ -2905,6 +2905,9 @@ return gfx::Rect(GetContentsBounds().CenterPoint(), gfx::Size(1, 1)); const int model_index = GetModelIndexOfItem(item); + if (model_index >= view_model_.view_size()) + return gfx::Rect(GetContentsBounds().CenterPoint(), gfx::Size(1, 1)); + const GridIndex grid_index = GetIndexFromModelIndex(model_index); if (grid_index.page != 0) return gfx::Rect(GetContentsBounds().CenterPoint(), gfx::Size(1, 1));
diff --git a/ash/app_list/views/assistant/assistant_page_view.cc b/ash/app_list/views/assistant/assistant_page_view.cc index 9775355..34fff9b 100644 --- a/ash/app_list/views/assistant/assistant_page_view.cc +++ b/ash/app_list/views/assistant/assistant_page_view.cc
@@ -4,6 +4,7 @@ #include "ash/app_list/views/assistant/assistant_page_view.h" +#include <algorithm> #include <memory> #include <utility> @@ -139,6 +140,7 @@ } NOTREACHED(); break; + case AssistantUiMode::kAmbientUi: case AssistantUiMode::kMainUi: case AssistantUiMode::kMiniUi: NOTREACHED(); @@ -259,6 +261,7 @@ } NOTREACHED(); break; + case AssistantUiMode::kAmbientUi: case AssistantUiMode::kMainUi: case AssistantUiMode::kMiniUi: NOTREACHED(); @@ -310,6 +313,7 @@ } NOTREACHED(); break; + case AssistantUiMode::kAmbientUi: case AssistantUiMode::kMainUi: case AssistantUiMode::kMiniUi: NOTREACHED();
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index d324a87..c911af5 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -2023,6 +2023,9 @@ <message name="IDS_ASSISTANT_EDIT_REMINDER_QUERY" desc="Query to issue to edit reminder."> Edit reminder </message> + <message name="IDS_ASSISTANT_AMBIENT_GREETING_MESSAGE" desc="Greetings message shown on Ambient Mode UI."> + Hi, <ph name="USERNAME">$1</ph> + </message> <message name="IDS_ASH_MESSAGE_CENTER_UNLOCK_TO_PERFORM_ACTION" desc="The short message to encourage user to unlock the device so that Chrome OS can perform the notification action selected by user after unlocking."> Unlock device to perform the notification action
diff --git a/ash/assistant/assistant_ui_controller.cc b/ash/assistant/assistant_ui_controller.cc index 2a47bd2..86a5934 100644 --- a/ash/assistant/assistant_ui_controller.cc +++ b/ash/assistant/assistant_ui_controller.cc
@@ -4,6 +4,7 @@ #include "ash/assistant/assistant_ui_controller.h" +#include "ash/ambient/ambient_controller.h" #include "ash/assistant/assistant_controller.h" #include "ash/assistant/assistant_interaction_controller.h" #include "ash/assistant/assistant_screen_context_controller.h" @@ -26,6 +27,7 @@ #include "ash/system/toast/toast_manager_impl.h" #include "base/bind.h" #include "base/optional.h" +#include "chromeos/constants/chromeos_features.h" #include "chromeos/services/assistant/public/features.h" #include "chromeos/services/assistant/public/mojom/assistant.mojom.h" #include "ui/aura/client/aura_constants.h" @@ -468,7 +470,8 @@ assistant::util::RecordAssistantEntryPoint(entry_point.value()); if (!container_view_) { - DCHECK_EQ(AssistantUiMode::kLauncherEmbeddedUi, model_.ui_mode()); + DCHECK(model_.ui_mode() == AssistantUiMode::kAmbientUi || + model_.ui_mode() == AssistantUiMode::kLauncherEmbeddedUi); event_monitor_.reset(); break; } @@ -534,6 +537,13 @@ return; } + if (chromeos::features::IsAmbientModeEnabled() && + Shell::Get()->ambient_controller()->is_showing()) { + model_.SetUiMode(AssistantUiMode::kAmbientUi); + model_.SetVisible(entry_point); + return; + } + if (app_list_features::IsEmbeddedAssistantUIEnabled()) { model_.SetUiMode(AssistantUiMode::kLauncherEmbeddedUi); model_.SetVisible(entry_point); @@ -541,6 +551,7 @@ } DCHECK_NE(AssistantUiMode::kLauncherEmbeddedUi, model_.ui_mode()); + DCHECK_NE(AssistantUiMode::kAmbientUi, model_.ui_mode()); if (model_.visibility() == AssistantVisibility::kVisible) { // If Assistant window is already visible, we just try to retake focus.
diff --git a/ash/assistant/model/assistant_ui_model.h b/ash/assistant/model/assistant_ui_model.h index ccd9f2e..55546c9 100644 --- a/ash/assistant/model/assistant_ui_model.h +++ b/ash/assistant/model/assistant_ui_model.h
@@ -57,10 +57,11 @@ // Enumeration of Assistant UI modes. enum class AssistantUiMode { + kAmbientUi, + kLauncherEmbeddedUi, kMainUi, kMiniUi, kWebUi, - kLauncherEmbeddedUi, }; // Enumeration of Assistant visibility states.
diff --git a/ash/assistant/ui/assistant_container_view.cc b/ash/assistant/ui/assistant_container_view.cc index 7994f7b5..bd21a0f7 100644 --- a/ash/assistant/ui/assistant_container_view.cc +++ b/ash/assistant/ui/assistant_container_view.cc
@@ -365,6 +365,7 @@ if (assistant_web_view_) assistant_web_view_->RequestFocus(); break; + case AssistantUiMode::kAmbientUi: case AssistantUiMode::kLauncherEmbeddedUi: NOTREACHED(); break; @@ -397,6 +398,7 @@ case AssistantUiMode::kWebUi: assistant_web_view_->SetVisible(true); break; + case AssistantUiMode::kAmbientUi: case AssistantUiMode::kLauncherEmbeddedUi: NOTREACHED(); break; @@ -430,6 +432,7 @@ case AssistantUiMode::kWebUi: // Default views::FocusSearch behavior is acceptable. return nullptr; + case AssistantUiMode::kAmbientUi: case AssistantUiMode::kLauncherEmbeddedUi: NOTREACHED(); return nullptr;
diff --git a/ash/assistant/ui/main_stage/animated_container_view.h b/ash/assistant/ui/main_stage/animated_container_view.h index 9da4dc77d..4156a96 100644 --- a/ash/assistant/ui/main_stage/animated_container_view.h +++ b/ash/assistant/ui/main_stage/animated_container_view.h
@@ -6,6 +6,7 @@ #define ASH_ASSISTANT_UI_MAIN_STAGE_ANIMATED_CONTAINER_VIEW_H_ #include <memory> +#include <vector> #include "ash/assistant/model/assistant_interaction_model_observer.h" #include "ash/assistant/ui/base/assistant_scroll_view.h" @@ -46,8 +47,9 @@ // all |ElementAnimator| instances. // 8) Finally when this animation is complete the derived class is informed // through |AnimatedContainerView::OnAllViewsAnimatedIn|. -class AnimatedContainerView : public AssistantScrollView, - public AssistantInteractionModelObserver { +class COMPONENT_EXPORT(ASSISTANT_UI) AnimatedContainerView + : public AssistantScrollView, + public AssistantInteractionModelObserver { public: explicit AnimatedContainerView(AssistantViewDelegate* delegate); ~AnimatedContainerView() override;
diff --git a/ash/assistant/ui/main_stage/ui_element_container_view.cc b/ash/assistant/ui/main_stage/ui_element_container_view.cc index 5179e3f..68a5767 100644 --- a/ash/assistant/ui/main_stage/ui_element_container_view.cc +++ b/ash/assistant/ui/main_stage/ui_element_container_view.cc
@@ -237,9 +237,7 @@ InitLayout(); } -UiElementContainerView::~UiElementContainerView() { - delegate()->RemoveInteractionModelObserver(this); -} +UiElementContainerView::~UiElementContainerView() = default; const char* UiElementContainerView::GetClassName() const { return "UiElementContainerView";
diff --git a/ash/public/cpp/ash_features.cc b/ash/public/cpp/ash_features.cc index ef89b97..b48f6876 100644 --- a/ash/public/cpp/ash_features.cc +++ b/ash/public/cpp/ash_features.cc
@@ -97,7 +97,7 @@ base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kSwipingFromLeftEdgeToGoBack{ - "SwipingFromLeftEdgeToGoBack", base::FEATURE_DISABLED_BY_DEFAULT}; + "SwipingFromLeftEdgeToGoBack", base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kDragFromShelfToHomeOrOverview{ "DragFromShelfToHomeOrOverview", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/ash/shelf/shelf_config.cc b/ash/shelf/shelf_config.cc index ad10689..3205a43 100644 --- a/ash/shelf/shelf_config.cc +++ b/ash/shelf/shelf_config.cc
@@ -26,7 +26,8 @@ // Returns whether tablet mode is currently active. bool IsTabletMode() { - return Shell::Get()->tablet_mode_controller()->InTabletMode(); + return Shell::Get()->tablet_mode_controller() && + Shell::Get()->tablet_mode_controller()->InTabletMode(); } } // namespace @@ -173,7 +174,7 @@ int ShelfConfig::control_border_radius() const { return (chromeos::switches::ShouldShowShelfHotseat() && is_in_app() && - Shell::Get()->tablet_mode_controller()->InTabletMode()) + IsTabletMode()) ? 0 : control_size() / 2; } @@ -219,8 +220,9 @@ SkColor ShelfConfig::GetShelfControlButtonColor() const { if (chromeos::switches::ShouldShowShelfHotseat() && IsTabletMode() && Shell::Get()->session_controller()->GetSessionState() == - session_manager::SessionState::ACTIVE) + session_manager::SessionState::ACTIVE) { return is_in_app() ? SK_ColorTRANSPARENT : GetDefaultShelfColor(); + } return shelf_control_permanent_highlight_background_; }
diff --git a/ash/shelf/shelf_view_unittest.cc b/ash/shelf/shelf_view_unittest.cc index a7e81c3..48145fa 100644 --- a/ash/shelf/shelf_view_unittest.cc +++ b/ash/shelf/shelf_view_unittest.cc
@@ -1440,7 +1440,35 @@ EXPECT_FALSE(tooltip_manager->IsVisible()); } -TEST_F(ShelfViewTest, ShouldHideTooltipTest) { +class HotseatShelfViewTest : public ShelfViewTest, + public testing::WithParamInterface<bool> { + public: + HotseatShelfViewTest() = default; + ~HotseatShelfViewTest() override = default; + + // AshTestBase: + void SetUp() override { + if (GetParam()) { + feature_list_.InitAndEnableFeature(chromeos::features::kShelfHotseat); + } else { + feature_list_.InitAndDisableFeature(chromeos::features::kShelfHotseat); + } + ShelfViewTest::SetUp(); + } + + private: + base::test::ScopedFeatureList feature_list_; + DISALLOW_COPY_AND_ASSIGN(HotseatShelfViewTest); +}; + +// Tests with both hotseat enabled and disabled. +INSTANTIATE_TEST_SUITE_P(, HotseatShelfViewTest, testing::Bool()); + +TEST_P(HotseatShelfViewTest, ShouldHideTooltipTest) { + // TODO(https://crbug.com/1016823): Fix this test for the hotseat. + if (chromeos::switches::ShouldShowShelfHotseat()) + return; + ShelfID app_button_id = AddAppShortcut(); ShelfID platform_button_id = AddApp(); // TODO(manucornet): It should not be necessary to call this manually. The @@ -1538,7 +1566,9 @@ // Test that by moving the mouse cursor off the button onto the bubble it closes // the bubble. -TEST_F(ShelfViewTest, ShouldHideTooltipWhenHoveringOnTooltip) { +TEST_P(HotseatShelfViewTest, ShouldHideTooltipWhenHoveringOnTooltip) { + if (chromeos::switches::ShouldShowShelfHotseat()) + return; ShelfTooltipManager* tooltip_manager = test_api_->tooltip_manager(); tooltip_manager->set_timer_delay_for_test(0); ui::test::EventGenerator* generator = GetEventGenerator();
diff --git a/ash/shell.cc b/ash/shell.cc index 5d61872f..bc5d640 100644 --- a/ash/shell.cc +++ b/ash/shell.cc
@@ -1044,8 +1044,10 @@ // |assistant_controller_| is put before |ambient_controller_| as it will be // used by the latter. - if (chromeos::features::IsAmbientModeEnabled()) - ambient_controller_ = std::make_unique<AmbientController>(); + if (chromeos::features::IsAmbientModeEnabled()) { + ambient_controller_ = + std::make_unique<AmbientController>(assistant_controller_.get()); + } home_screen_controller_ = std::make_unique<HomeScreenController>();
diff --git a/ash/system/network/auto_connect_notifier.cc b/ash/system/network/auto_connect_notifier.cc index 9bd3c8f..76fe8521 100644 --- a/ash/system/network/auto_connect_notifier.cc +++ b/ash/system/network/auto_connect_notifier.cc
@@ -13,8 +13,10 @@ #include "base/time/time.h" #include "base/timer/timer.h" #include "chromeos/network/network_connection_handler.h" +#include "chromeos/network/network_event_log.h" #include "chromeos/network/network_state.h" #include "chromeos/network/network_state_handler.h" +#include "chromeos/network/network_type_pattern.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/image/canvas_image_source.h" @@ -79,18 +81,35 @@ void AutoConnectNotifier::NetworkConnectionStateChanged( const chromeos::NetworkState* network) { - // No notification should be shown unless an auto-connection is underway. - if (!timer_->IsRunning()) + // Ignore non WiFi networks completely. + if (!network->Matches(chromeos::NetworkTypePattern::WiFi())) return; // The notification is only shown when a connection has succeeded; if // |network| is not connected, there is nothing to do. - if (!network->IsConnectedState()) + if (!network->IsConnectedState()) { + // Clear the tracked network if it is no longer connected or connecting. + if (!network->IsConnectingState() && + network->guid() == connected_network_guid_) { + connected_network_guid_.clear(); + } + return; + } + + // No notification should be shown unless an auto-connection is underway. + if (!timer_->IsRunning()) { + // Track the currently connected network. + connected_network_guid_ = network->guid(); + return; + } + + // Ignore NetworkConnectionStateChanged for a previously connected network. + if (network->guid() == connected_network_guid_) return; // An auto-connected network has connected successfully. Display a // notification alerting the user that this has occurred. - DisplayNotification(); + DisplayNotification(network); has_user_explicitly_requested_connection_ = false; } @@ -125,7 +144,9 @@ timer_->Start(FROM_HERE, kNetworkConnectionTimeout, base::DoNothing()); } -void AutoConnectNotifier::DisplayNotification() { +void AutoConnectNotifier::DisplayNotification( + const chromeos::NetworkState* network) { + NET_LOG(EVENT) << "Show AutoConnect Notification for: " << network->name(); auto notification = ash::CreateSystemNotification( message_center::NotificationType::NOTIFICATION_TYPE_SIMPLE, kAutoConnectNotificationId,
diff --git a/ash/system/network/auto_connect_notifier.h b/ash/system/network/auto_connect_notifier.h index 8e7b4d5..6d8da384 100644 --- a/ash/system/network/auto_connect_notifier.h +++ b/ash/system/network/auto_connect_notifier.h
@@ -48,9 +48,10 @@ static const char kAutoConnectNotificationId[]; private: - void DisplayNotification(); + void DisplayNotification(const chromeos::NetworkState* network); bool has_user_explicitly_requested_connection_ = false; + std::string connected_network_guid_; std::unique_ptr<base::OneShotTimer> timer_; DISALLOW_COPY_AND_ASSIGN(AutoConnectNotifier);
diff --git a/ash/system/network/auto_connect_notifier_unittest.cc b/ash/system/network/auto_connect_notifier_unittest.cc index 717b231c..736efd5 100644 --- a/ash/system/network/auto_connect_notifier_unittest.cc +++ b/ash/system/network/auto_connect_notifier_unittest.cc
@@ -18,6 +18,7 @@ #include "chromeos/network/auto_connect_handler.h" #include "chromeos/network/network_cert_loader.h" #include "chromeos/network/network_handler.h" +#include "chromeos/services/network_config/public/cpp/cros_network_config_test_helper.h" #include "dbus/object_path.h" #include "third_party/cros_system_api/dbus/shill/dbus-constants.h" #include "ui/message_center/message_center.h" @@ -44,6 +45,9 @@ chromeos::shill_clients::InitializeFakes(); chromeos::NetworkHandler::Initialize(); CHECK(chromeos::NetworkHandler::Get()->auto_connect_handler()); + network_config_helper_ = std::make_unique< + chromeos::network_config::CrosNetworkConfigTestHelper>(); + AshTestBase::SetUp(); mock_notification_timer_ = new base::MockOneShotTimer(); @@ -54,13 +58,14 @@ chromeos::ShillServiceClient::Get()->GetTestInterface()->AddService( kTestServicePath, kTestServiceGuid, kTestServiceName, shill::kTypeWifi, - shill::kStateOnline, true /* visible*/); + shill::kStateIdle, true /* visible*/); // Ensure fake DBus service initialization completes. base::RunLoop().RunUntilIdle(); } void TearDown() override { AshTestBase::TearDown(); + network_config_helper_.reset(); chromeos::NetworkHandler::Shutdown(); chromeos::shill_clients::Shutdown(); chromeos::NetworkCertLoader::Shutdown(); @@ -88,6 +93,9 @@ base::MockOneShotTimer* mock_notification_timer_; private: + std::unique_ptr<chromeos::network_config::CrosNetworkConfigTestHelper> + network_config_helper_; + DISALLOW_COPY_AND_ASSIGN(AutoConnectNotifierTest); }; @@ -139,6 +147,22 @@ EXPECT_FALSE(notification); } +TEST_F(AutoConnectNotifierTest, ConnectToConnectedNetwork) { + SuccessfullyJoinWifiNetwork(); + + NotifyConnectToNetworkRequested(); + chromeos::NetworkHandler::Get() + ->auto_connect_handler() + ->NotifyAutoConnectInitiatedForTest( + chromeos::AutoConnectHandler::AUTO_CONNECT_REASON_POLICY_APPLIED); + SuccessfullyJoinWifiNetwork(); + + message_center::Notification* notification = + message_center::MessageCenter::Get()->FindVisibleNotificationById( + GetNotificationId()); + ASSERT_FALSE(notification); +} + TEST_F(AutoConnectNotifierTest, NotificationDisplayed) { NotifyConnectToNetworkRequested(); chromeos::NetworkHandler::Get()
diff --git a/ash/system/overview/overview_button_tray_unittest.cc b/ash/system/overview/overview_button_tray_unittest.cc index 1d5b1f4b..4c6593a 100644 --- a/ash/system/overview/overview_button_tray_unittest.cc +++ b/ash/system/overview/overview_button_tray_unittest.cc
@@ -425,4 +425,37 @@ EXPECT_TRUE(GetTray()->GetVisible()); } +// Using the developers keyboard shortcut to enable tablet mode should force the +// overview tray button visible, even though the events are not blocked. +TEST_F(OverviewButtonTrayTest, ForDevTabletModeForcesTheButtonShown) { + Shell::Get()->tablet_mode_controller()->SetEnabledForDev(true); + EXPECT_TRUE(TabletModeControllerTestApi().IsTabletModeStarted()); + EXPECT_FALSE(TabletModeControllerTestApi().AreEventsBlocked()); + EXPECT_TRUE(GetTray()->GetVisible()); + + Shell::Get()->tablet_mode_controller()->SetEnabledForDev(false); + EXPECT_FALSE(TabletModeControllerTestApi().IsTabletModeStarted()); + EXPECT_FALSE(GetTray()->GetVisible()); + + // When there is a window, a screenshot will be taken and entering tablet mode + // becomes asynchronous. + std::unique_ptr<aura::Window> window( + CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20))); + + EXPECT_FALSE(GetTray()->GetVisible()); + TabletMode::Waiter waiter(/*enable=*/true); + Shell::Get()->tablet_mode_controller()->SetEnabledForDev(true); + EXPECT_FALSE(GetTray()->GetVisible()); + + waiter.Wait(); + + EXPECT_TRUE(TabletModeControllerTestApi().IsTabletModeStarted()); + EXPECT_TRUE(GetTray()->GetVisible()); + + // However, disabling tablet mode is always synchronous. + Shell::Get()->tablet_mode_controller()->SetEnabledForDev(false); + EXPECT_FALSE(TabletModeControllerTestApi().IsTabletModeStarted()); + EXPECT_FALSE(GetTray()->GetVisible()); +} + } // namespace ash
diff --git a/ash/test/ash_test_helper.cc b/ash/test/ash_test_helper.cc index 435183f..f953a33 100644 --- a/ash/test/ash_test_helper.cc +++ b/ash/test/ash_test_helper.cc
@@ -41,7 +41,6 @@ #include "chromeos/audio/cras_audio_handler.h" #include "chromeos/dbus/audio/cras_audio_client.h" #include "chromeos/dbus/power/power_policy_controller.h" -#include "chromeos/network/network_handler.h" #include "chromeos/system/fake_statistics_provider.h" #include "components/discardable_memory/public/mojom/discardable_shared_memory_manager.mojom.h" #include "components/prefs/testing_pref_service.h"
diff --git a/ash/wm/overview/overview_session_unittest.cc b/ash/wm/overview/overview_session_unittest.cc index 0a5e1650..94dabc8b 100644 --- a/ash/wm/overview/overview_session_unittest.cc +++ b/ash/wm/overview/overview_session_unittest.cc
@@ -61,12 +61,15 @@ #include "ash/wm/window_util.h" #include "ash/wm/wm_event.h" #include "ash/wm/workspace/workspace_window_resizer.h" +#include "base/macros.h" #include "base/run_loop.h" #include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/metrics/user_action_tester.h" #include "base/test/scoped_feature_list.h" +#include "chromeos/constants/chromeos_features.h" +#include "chromeos/constants/chromeos_switches.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/client/window_types.h" #include "ui/aura/test/test_window_delegate.h" @@ -1631,7 +1634,64 @@ no_windows_widget->GetWindowBoundsInScreen().CenterPoint()); } +class HotseatDisabledOverviewSessionTest : public OverviewSessionTest { + public: + HotseatDisabledOverviewSessionTest() = default; + ~HotseatDisabledOverviewSessionTest() override = default; + + // AshTestBase: + void SetUp() override { + feature_list_.InitAndDisableFeature(chromeos::features::kShelfHotseat); + OverviewSessionTest::SetUp(); + } + + private: + base::test::ScopedFeatureList feature_list_; + DISALLOW_COPY_AND_ASSIGN(HotseatDisabledOverviewSessionTest); +}; + +INSTANTIATE_TEST_SUITE_P(, HotseatDisabledOverviewSessionTest, testing::Bool()); + +TEST_P(HotseatDisabledOverviewSessionTest, + NoWindowsIndicatorPositionSplitview) { + UpdateDisplay("400x300"); + EnterTabletMode(); + std::unique_ptr<aura::Window> window(CreateTestWindow()); + + ToggleOverview(); + ASSERT_TRUE(overview_session()); + RoundedLabelWidget* no_windows_widget = + overview_session()->no_windows_widget_for_testing(); + EXPECT_FALSE(no_windows_widget); + + // Tests that when snapping a window to the left in splitview, the no windows + // indicator shows up in the middle of the right side of the screen. + split_view_controller()->SnapWindow(window.get(), SplitViewController::LEFT); + no_windows_widget = overview_session()->no_windows_widget_for_testing(); + ASSERT_TRUE(no_windows_widget); + + // There is a 8dp divider in splitview, the indicator should take that into + // account. + const int bounds_left = 200 + 4; + int expected_x = bounds_left + (400 - (bounds_left)) / 2; + const int expected_y = (300 - ShelfConfig::Get()->shelf_size()) / 2; + EXPECT_EQ(gfx::Point(expected_x, expected_y), + no_windows_widget->GetWindowBoundsInScreen().CenterPoint()); + + // Tests that when snapping a window to the right in splitview, the no windows + // indicator shows up in the middle of the left side of the screen. + split_view_controller()->SnapWindow(window.get(), SplitViewController::RIGHT); + expected_x = /*bounds_right=*/(200 - 4) / 2; + EXPECT_EQ(gfx::Point(expected_x, expected_y), + no_windows_widget->GetWindowBoundsInScreen().CenterPoint()); +} + TEST_P(OverviewSessionTest, NoWindowsIndicatorPositionSplitview) { + // TODO(https://crbug.com/1009550): Make the shelf in-app for split view and + // overview. + if (chromeos::switches::ShouldShowShelfHotseat()) + return; + UpdateDisplay("400x300"); EnterTabletMode(); std::unique_ptr<aura::Window> window(CreateTestWindow()); @@ -5206,6 +5266,36 @@ // representations of bounds rects rather than individual components of // origins and sizes. Those string representations of bounds rects are most // readable when hard-coded. + if (chromeos::switches::ShouldShowShelfHotseat()) { + ASSERT_EQ( + "0,0 800x552", + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( + root_windows[0]) + .ToString()); + ASSERT_EQ( + "800,0 800x552", + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( + root_windows[1]) + .ToString()); + + EXPECT_EQ("0,0 400x552", + SplitViewController::Get(root_windows[0]) + ->GetSnappedWindowBoundsInScreen(SplitViewController::LEFT) + .ToString()); + EXPECT_EQ("400,0 400x552", + SplitViewController::Get(root_windows[0]) + ->GetSnappedWindowBoundsInScreen(SplitViewController::RIGHT) + .ToString()); + EXPECT_EQ("800,0 400x552", + SplitViewController::Get(root_windows[1]) + ->GetSnappedWindowBoundsInScreen(SplitViewController::LEFT) + .ToString()); + EXPECT_EQ("1200,0 400x552", + SplitViewController::Get(root_windows[1]) + ->GetSnappedWindowBoundsInScreen(SplitViewController::RIGHT) + .ToString()); + return; + } ASSERT_EQ("0,0 800x544", screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( root_windows[0])
diff --git a/ash/wm/splitview/split_view_controller_unittest.cc b/ash/wm/splitview/split_view_controller_unittest.cc index 4b6a852e..f0571de 100644 --- a/ash/wm/splitview/split_view_controller_unittest.cc +++ b/ash/wm/splitview/split_view_controller_unittest.cc
@@ -18,6 +18,7 @@ #include "ash/public/cpp/ash_features.h" #include "ash/public/cpp/fps_counter.h" #include "ash/public/cpp/presentation_time_recorder.h" +#include "ash/public/cpp/shelf_config.h" #include "ash/public/cpp/window_properties.h" #include "ash/root_window_controller.h" #include "ash/screen_util.h" @@ -3596,6 +3597,7 @@ const gfx::Rect bounds(0, 0, 400, 400); std::unique_ptr<aura::Window> window1( CreateWindowWithType(bounds, AppType::BROWSER)); + wm::ActivateWindow(window1.get()); gfx::Rect tablet_mode_bounds = window1->bounds(); EXPECT_NE(bounds, tablet_mode_bounds);
diff --git a/ash/wm/tablet_mode/tablet_mode_controller.cc b/ash/wm/tablet_mode/tablet_mode_controller.cc index c4badf1..8585a2b 100644 --- a/ash/wm/tablet_mode/tablet_mode_controller.cc +++ b/ash/wm/tablet_mode/tablet_mode_controller.cc
@@ -184,9 +184,9 @@ /*force_physical_tablet_state=*/false, }; -// Defines the behavior that sticks to the current mode. Used to -// implement --force-tablet-mode flag. -constexpr TabletModeController::TabletModeBehavior kLockInCurrentMode{ +// Defines the behavior that sticks to tablet mode. Used to implement the +// --force-tablet-mode=touch_view flag. +constexpr TabletModeController::TabletModeBehavior kLockInTabletMode{ /*use_sensor=*/false, /*observe_display_events=*/false, /*observe_external_pointer_device_events=*/false, @@ -195,6 +195,17 @@ /*force_physical_tablet_state=*/false, }; +// Defines the behavior that sticks to tablet mode. Used to implement the +// --force-tablet-mode=clamshell flag. +constexpr TabletModeController::TabletModeBehavior kLockInClamshellMode{ + /*use_sensor=*/false, + /*observe_display_events=*/false, + /*observe_external_pointer_device_events=*/false, + /*block_internal_input_device=*/false, + /*always_show_overview_button=*/false, + /*force_physical_tablet_state=*/false, +}; + // Defines the behavior used for testing. It prevents the device from // switching the mode due to sensor events during the test. constexpr TabletModeController::TabletModeBehavior kOnForTest{ @@ -434,8 +445,12 @@ forced_ui_mode_ = GetUiMode(); switch (forced_ui_mode_) { case UiMode::kTabletMode: + tablet_mode_behavior_ = kLockInTabletMode; + UpdateUiTabletState(); + break; + case UiMode::kClamshell: - tablet_mode_behavior_ = kLockInCurrentMode; + tablet_mode_behavior_ = kLockInClamshellMode; UpdateUiTabletState(); break; @@ -630,6 +645,7 @@ void TabletModeController::SetEnabledForDev(bool enabled) { tablet_mode_behavior_ = enabled ? kOnForDev : kDefault; + force_notify_events_blocking_changed_ = true; SetIsInTabletPhysicalState(enabled); } @@ -906,8 +922,15 @@ tablet_mode_behavior_.block_internal_input_device && (InTabletMode() || is_in_tablet_physical_state_); - if (should_block_internal_events == AreInternalInputDeviceEventsBlocked()) + if (should_block_internal_events == AreInternalInputDeviceEventsBlocked()) { + if (force_notify_events_blocking_changed_) { + for (auto& observer : tablet_mode_observers_) + observer.OnTabletModeEventsBlockingChanged(); + force_notify_events_blocking_changed_ = false; + } + return; + } event_blocker_->UpdateInternalInputDevices(should_block_internal_events); for (auto& observer : tablet_mode_observers_)
diff --git a/ash/wm/tablet_mode/tablet_mode_controller.h b/ash/wm/tablet_mode/tablet_mode_controller.h index 2e1c0ef..a574b2b2 100644 --- a/ash/wm/tablet_mode/tablet_mode_controller.h +++ b/ash/wm/tablet_mode/tablet_mode_controller.h
@@ -363,6 +363,11 @@ // not enter tablet mode if this is true. bool has_external_pointing_device_ = false; + // Set to true temporarily when the tablet mode is enabled/disabled via the + // developer's keyboard shortcut in order to update the visibility of the + // overview tray button, even though internal events are not blocked. + bool force_notify_events_blocking_changed_ = false; + // Counts the app window drag from top in tablet mode. int app_window_drag_count_ = 0;
diff --git a/ash/wm/toplevel_window_event_handler_unittest.cc b/ash/wm/toplevel_window_event_handler_unittest.cc index 048e24c..a7db7c0 100644 --- a/ash/wm/toplevel_window_event_handler_unittest.cc +++ b/ash/wm/toplevel_window_event_handler_unittest.cc
@@ -1368,10 +1368,10 @@ TapWindowInOverviewGridDuringWindowDrag) { TabletModeControllerTestApi().EnterTabletMode(); - SendGestureEvent(gfx::Point(0, 0), 0, 5, ui::ET_GESTURE_SCROLL_BEGIN); + SendGestureEvent(gfx::Point(100, 0), 0, 5, ui::ET_GESTURE_SCROLL_BEGIN); // Drag the window to the right corner to avoid overlap with // |non_dragged_window_| in overview grid. - SendGestureEvent(gfx::Point(700, 500), 700, 500, + SendGestureEvent(gfx::Point(600, 500), 600, 500, ui::ET_GESTURE_SCROLL_UPDATE); EXPECT_TRUE(WindowState::Get(dragged_window_.get())->is_dragged()); @@ -1403,8 +1403,8 @@ dragged_window_->SetProperty(aura::client::kResizeBehaviorKey, aura::client::kResizeBehaviorNone); - SendGestureEvent(gfx::Point(0, 0), 0, 5, ui::ET_GESTURE_SCROLL_BEGIN); - SendGestureEvent(gfx::Point(700, 500), 700, 500, + SendGestureEvent(gfx::Point(100, 0), 0, 5, ui::ET_GESTURE_SCROLL_BEGIN); + SendGestureEvent(gfx::Point(600, 500), 600, 500, ui::ET_GESTURE_SCROLL_UPDATE); EXPECT_TRUE(WindowState::Get(dragged_window_.get())->is_dragged()); @@ -1450,10 +1450,10 @@ ASSERT_TRUE(TabletModeControllerTestApi().IsTabletModeStarted()); - SendGestureEvent(gfx::Point(0, 0), 0, 5, ui::ET_GESTURE_SCROLL_BEGIN); + SendGestureEvent(gfx::Point(100, 0), 0, 5, ui::ET_GESTURE_SCROLL_BEGIN); // Drag the window to the right corner to avoid overlap with // |non_dragged_window_| in overview grid. - SendGestureEvent(gfx::Point(700, 500), 700, 500, + SendGestureEvent(gfx::Point(600, 500), 600, 500, ui::ET_GESTURE_SCROLL_UPDATE); EXPECT_TRUE(WindowState::Get(dragged_window_.get())->is_dragged());
diff --git a/base/profiler/stack_copier_suspend_unittest.cc b/base/profiler/stack_copier_suspend_unittest.cc index a496ade..9115d57 100644 --- a/base/profiler/stack_copier_suspend_unittest.cc +++ b/base/profiler/stack_copier_suspend_unittest.cc
@@ -63,6 +63,8 @@ return true; } + PlatformThreadId GetThreadId() const override { return PlatformThreadId(); } + uintptr_t GetStackBaseAddress() const override { return reinterpret_cast<uintptr_t>(&fake_stack_[0] + fake_stack_.size()); }
diff --git a/base/profiler/suspendable_thread_delegate_mac.cc b/base/profiler/suspendable_thread_delegate_mac.cc index 81323969..14c059ac 100644 --- a/base/profiler/suspendable_thread_delegate_mac.cc +++ b/base/profiler/suspendable_thread_delegate_mac.cc
@@ -78,6 +78,10 @@ return std::make_unique<ScopedSuspendThread>(thread_port_); } +PlatformThreadId SuspendableThreadDelegateMac::GetThreadId() const { + return thread_port_; +} + // NO HEAP ALLOCATIONS. bool SuspendableThreadDelegateMac::GetThreadContext( x86_thread_state64_t* thread_context) {
diff --git a/base/profiler/suspendable_thread_delegate_mac.h b/base/profiler/suspendable_thread_delegate_mac.h index de3f3066..a7d3477e 100644 --- a/base/profiler/suspendable_thread_delegate_mac.h +++ b/base/profiler/suspendable_thread_delegate_mac.h
@@ -46,6 +46,7 @@ std::unique_ptr<SuspendableThreadDelegate::ScopedSuspendThread> CreateScopedSuspendThread() override; bool GetThreadContext(x86_thread_state64_t* thread_context) override; + PlatformThreadId GetThreadId() const override; uintptr_t GetStackBaseAddress() const override; bool CanCopyStack(uintptr_t stack_pointer) override; std::vector<uintptr_t*> GetRegistersToRewrite( @@ -53,7 +54,7 @@ private: // Weak reference: Mach port for thread being profiled. - mach_port_t thread_port_; + const mach_port_t thread_port_; // The stack base address corresponding to |thread_port_|. const uintptr_t thread_stack_base_address_;
diff --git a/base/profiler/suspendable_thread_delegate_win.cc b/base/profiler/suspendable_thread_delegate_win.cc index d7369e5..267623d 100644 --- a/base/profiler/suspendable_thread_delegate_win.cc +++ b/base/profiler/suspendable_thread_delegate_win.cc
@@ -173,7 +173,8 @@ SuspendableThreadDelegateWin::SuspendableThreadDelegateWin( PlatformThreadId thread_id) - : thread_handle_(GetThreadHandle(thread_id)), + : thread_id_(thread_id), + thread_handle_(GetThreadHandle(thread_id)), thread_stack_base_address_(reinterpret_cast<uintptr_t>( GetThreadEnvironmentBlock(thread_handle_.Get())->Tib.StackBase)) {} @@ -184,6 +185,10 @@ return std::make_unique<ScopedSuspendThread>(thread_handle_.Get()); } +PlatformThreadId SuspendableThreadDelegateWin::GetThreadId() const { + return thread_id_; +} + // NO HEAP ALLOCATIONS. bool SuspendableThreadDelegateWin::GetThreadContext(CONTEXT* thread_context) { *thread_context = {0};
diff --git a/base/profiler/suspendable_thread_delegate_win.h b/base/profiler/suspendable_thread_delegate_win.h index 2452dbe..48c880f 100644 --- a/base/profiler/suspendable_thread_delegate_win.h +++ b/base/profiler/suspendable_thread_delegate_win.h
@@ -45,12 +45,14 @@ std::unique_ptr<SuspendableThreadDelegate::ScopedSuspendThread> CreateScopedSuspendThread() override; bool GetThreadContext(CONTEXT* thread_context) override; + PlatformThreadId GetThreadId() const override; uintptr_t GetStackBaseAddress() const override; bool CanCopyStack(uintptr_t stack_pointer) override; std::vector<uintptr_t*> GetRegistersToRewrite( CONTEXT* thread_context) override; private: + const PlatformThreadId thread_id_; win::ScopedHandle thread_handle_; const uintptr_t thread_stack_base_address_; };
diff --git a/base/profiler/thread_delegate.h b/base/profiler/thread_delegate.h index bb8b50b..88bf516 100644 --- a/base/profiler/thread_delegate.h +++ b/base/profiler/thread_delegate.h
@@ -9,6 +9,7 @@ #include "base/base_export.h" #include "base/profiler/register_context.h" +#include "base/threading/platform_thread.h" namespace base { @@ -24,6 +25,9 @@ ThreadDelegate(const ThreadDelegate&) = delete; ThreadDelegate& operator=(const ThreadDelegate&) = delete; + // Gets the platform-specific id for the thread. + virtual PlatformThreadId GetThreadId() const = 0; + // Gets the base address of the thread's stack. virtual uintptr_t GetStackBaseAddress() const = 0;
diff --git a/base/profiler/thread_delegate_posix.cc b/base/profiler/thread_delegate_posix.cc index 76934dc0..242fd6a 100644 --- a/base/profiler/thread_delegate_posix.cc +++ b/base/profiler/thread_delegate_posix.cc
@@ -24,7 +24,12 @@ } // namespace ThreadDelegatePosix::ThreadDelegatePosix(PlatformThreadId thread_id) - : thread_stack_base_address_(GetThreadStackBaseAddress(thread_id)) {} + : thread_id_(thread_id), + thread_stack_base_address_(GetThreadStackBaseAddress(thread_id)) {} + +PlatformThreadId ThreadDelegatePosix::GetThreadId() const { + return thread_id_; +} uintptr_t ThreadDelegatePosix::GetStackBaseAddress() const { return thread_stack_base_address_;
diff --git a/base/profiler/thread_delegate_posix.h b/base/profiler/thread_delegate_posix.h index 60830d21..e88fc3d 100644 --- a/base/profiler/thread_delegate_posix.h +++ b/base/profiler/thread_delegate_posix.h
@@ -21,11 +21,13 @@ ThreadDelegatePosix& operator=(const ThreadDelegatePosix&) = delete; // ThreadDelegate + PlatformThreadId GetThreadId() const override; uintptr_t GetStackBaseAddress() const override; std::vector<uintptr_t*> GetRegistersToRewrite( RegisterContext* thread_context) override; private: + const PlatformThreadId thread_id_; const uintptr_t thread_stack_base_address_; };
diff --git a/base/trace_event/cfi_backtrace_android.cc b/base/trace_event/cfi_backtrace_android.cc index 567b2de2..593c5550 100644 --- a/base/trace_event/cfi_backtrace_android.cc +++ b/base/trace_event/cfi_backtrace_android.cc
@@ -164,16 +164,13 @@ } void CFIBacktraceAndroid::ParseCFITables() { - // The first 4 bytes in the file is the size of UNW_INDEX table. - static constexpr size_t kUnwIndexRowSize = - sizeof(*unw_index_function_col_) + sizeof(*unw_index_indices_col_); + // The first 4 bytes in the file is the number of entries in UNW_INDEX table. size_t unw_index_size = 0; memcpy(&unw_index_size, cfi_mmap_->data(), sizeof(unw_index_size)); - DCHECK_EQ(0u, unw_index_size % kUnwIndexRowSize); // UNW_INDEX table starts after 4 bytes. unw_index_function_col_ = reinterpret_cast<const uintptr_t*>(cfi_mmap_->data()) + 1; - unw_index_row_count_ = unw_index_size / kUnwIndexRowSize; + unw_index_row_count_ = unw_index_size; unw_index_indices_col_ = reinterpret_cast<const uint16_t*>( unw_index_function_col_ + unw_index_row_count_);
diff --git a/base/trace_event/cfi_backtrace_android_unittest.cc b/base/trace_event/cfi_backtrace_android_unittest.cc index 4f21091d..e60fa808 100644 --- a/base/trace_event/cfi_backtrace_android_unittest.cc +++ b/base/trace_event/cfi_backtrace_android_unittest.cc
@@ -68,10 +68,10 @@ STACK CFI 2204 .cfa: sp 44 + .ra: .cfa -8 + ^ r4: .cfa -16 + ^ */ uint16_t input[] = {// UNW_INDEX size - 0x2A, + 0x07, 0x0, // UNW_INDEX address column (4 byte rows). - 0x0, 0x1000, 0x0, 0x1502, 0x0, 0x2000, 0x0, 0x2024, 0x0, + 0x1000, 0x0, 0x1502, 0x0, 0x2000, 0x0, 0x2024, 0x0, 0x2126, 0x0, 0x2200, 0x0, 0x2212, 0x0, // UNW_INDEX index column (2 byte rows).
diff --git a/build/android/gyp/extract_unwind_tables.py b/build/android/gyp/extract_unwind_tables.py index 37a8421..ea13c6a 100755 --- a/build/android/gyp/extract_unwind_tables.py +++ b/build/android/gyp/extract_unwind_tables.py
@@ -20,7 +20,7 @@ UNW_DATA table. The second table contains one or more rows for the function unwind information. -The output file starts with 4 bytes counting the size of UNW_INDEX in bytes. +The output file starts with 4 bytes counting the number of entries in UNW_INDEX. Then UNW_INDEX table and UNW_DATA table. UNW_INDEX contains two columns of N rows each, where N is the number of @@ -240,7 +240,7 @@ func_addr_to_index[previous_func_end + 2] = _CANT_UNWIND # Write the size of UNW_INDEX file in bytes. - _Write4Bytes(out_file, len(func_addr_to_index) * 6) + _Write4Bytes(out_file, len(func_addr_to_index)) # Write the UNW_INDEX table. First list of addresses and then indices. sorted_unw_index = sorted(func_addr_to_index.iteritems())
diff --git a/build/android/gyp/extract_unwind_tables_tests.py b/build/android/gyp/extract_unwind_tables_tests.py index 02c70eb..e686607 100755 --- a/build/android/gyp/extract_unwind_tables_tests.py +++ b/build/android/gyp/extract_unwind_tables_tests.py
@@ -87,8 +87,8 @@ # First value is size of unw_index table. unw_index_size = actual_output[1] << 16 | actual_output[0] - # Each function index is 6 bytes data. - self.assertEqual(expected_function_count * 6, unw_index_size) + # |unw_index_size| should match entry count. + self.assertEqual(expected_function_count, unw_index_size) # |actual_output| is in blocks of 2 bytes. Skip first 4 bytes representing # size. unw_index_start = 2
diff --git a/build/android/incremental_install/README.md b/build/android/incremental_install/README.md index 53a6d20..1af672a 100644 --- a/build/android/incremental_install/README.md +++ b/build/android/incremental_install/README.md
@@ -25,7 +25,7 @@ ## Overview -The basic idea is to side-load .dex and .so files to `/data/local/tmp` rather +The basic idea is to sideload .dex and .so files to `/data/local/tmp` rather than bundling them in the .apk. Then, when making a change, only the changed .dex / .so needs to be pushed to the device. @@ -54,9 +54,14 @@ Caveats: * Isolated processes (on L+) are incompatible with incremental install. As a work-around, isolated processes are disabled when building incremental apks. - * Android resources, assets, and `loadable_modules` are not side-loaded (they + * Android resources, assets, and `loadable_modules` are not sideloaded (they remain in the apk), so builds & installs that modify any of these are not as fast as those that modify only .java / .cc. + * Since files are sideloaded to `/data/local/tmp`, you need to use the wrapper + scripts to uninstall them fully. E.g.: + ```shell + out/Default/bin/chrome_public_apk uninstall + ``` ## The Code
diff --git a/cc/input/scrollbar_controller.cc b/cc/input/scrollbar_controller.cc index 7018ba1d..e8e9d63a 100644 --- a/cc/input/scrollbar_controller.cc +++ b/cc/input/scrollbar_controller.cc
@@ -354,7 +354,6 @@ // - scrollbar_thumb_length // - scroll_layer_length // - viewport_length - // - device_scale_factor // - position_in_widget // // When a thumb drag is in progress, for every pixel that the pointer moves, @@ -364,6 +363,8 @@ // (scroll_layer_length - viewport_length) / // (scrollbar_track_length - scrollbar_thumb_length) // + // PS: Note that since this is a "ratio", it need not be scaled by the DSF. + // // |<--------------------- scroll_layer_length -------------------------->| // // +------------------------------------------------+...................... @@ -403,17 +404,8 @@ ? owner_scroll_layer->scroll_container_bounds().height() : (owner_scroll_layer->scroll_container_bounds().width()); - // For platforms which have use_zoom_for_dsf set to false (like Mac), the - // device_scale_factor should not be used while determining the - // scaled_scroller_to_scrollbar_ratio as thumb drag would appear jittery due - // to constant over and under corrections. - // (See ScrollbarController::ScreenSpaceScaleFactor()). - float scaled_scroller_to_scrollbar_ratio = - ((scroll_layer_length - viewport_length) / - (scrollbar_track_length - scrollbar_thumb_length)) * - ScreenSpaceScaleFactor(); - - return scaled_scroller_to_scrollbar_ratio; + return ((scroll_layer_length - viewport_length) / + (scrollbar_track_length - scrollbar_thumb_length)); } void ScrollbarController::ResetState() { @@ -608,7 +600,7 @@ switch (scrollbar_part) { case ScrollbarPart::BACK_BUTTON: case ScrollbarPart::FORWARD_BUTTON: - scroll_delta = kPixelsPerLineStep; + scroll_delta = kPixelsPerLineStep * ScreenSpaceScaleFactor(); break; case ScrollbarPart::BACK_TRACK: case ScrollbarPart::FORWARD_TRACK: @@ -629,7 +621,7 @@ scroll_delta = 0; } - return scroll_delta * ScreenSpaceScaleFactor(); + return scroll_delta; } float ScrollbarController::ScreenSpaceScaleFactor() const { @@ -640,7 +632,8 @@ // on arrows would be incorrectly calculated as 80px instead of 40px. This is // also necessary to ensure that hit testing works as intended. return layer_tree_host_impl_->settings().use_zoom_for_dsf - ? layer_tree_host_impl_->active_tree()->device_scale_factor() + ? layer_tree_host_impl_->active_tree() + ->painted_device_scale_factor() : 1.f; }
diff --git a/cc/paint/image_transfer_cache_entry.cc b/cc/paint/image_transfer_cache_entry.cc index 5939e78..599d0c2 100644 --- a/cc/paint/image_transfer_cache_entry.cc +++ b/cc/paint/image_transfer_cache_entry.cc
@@ -250,7 +250,6 @@ DCHECK_GT(plane->width(), 0); DCHECK_GT(plane->height(), 0); } - DCHECK(yuv_color_space_); } bool ClientImageTransferCacheEntry::Serialize(base::span<uint8_t> data) const {
diff --git a/cc/paint/paint_image.cc b/cc/paint/paint_image.cc index c601c01..f9b3d0e 100644 --- a/cc/paint/paint_image.cc +++ b/cc/paint/paint_image.cc
@@ -193,19 +193,17 @@ client_id); } -bool PaintImage::DecodeYuv(void* planes[SkYUVASizeInfo::kMaxCount], - size_t frame_index, - GeneratorClientId client_id, - const SkYUVASizeInfo& yuva_size_info) const { - SkYUVAIndex indices[SkYUVAIndex::kIndexCount]; - // Passing nullptr for the SkYUVASizeInfo forces IsYuv to create and fill out - // a temporary object instead because |yuva_size_info| is const. - bool is_yuv = IsYuv(nullptr, indices); - DCHECK(is_yuv); +bool PaintImage::DecodeYuv( + void* planes[SkYUVASizeInfo::kMaxCount], + size_t frame_index, + GeneratorClientId client_id, + const SkYUVASizeInfo& yuva_size_info, + SkYUVAIndex plane_indices[SkYUVAIndex::kIndexCount]) const { + DCHECK(plane_indices != nullptr); DCHECK(CanDecodeFromGenerator()); const uint32_t lazy_pixel_ref = unique_id(); - return paint_image_generator_->GetYUVA8Planes(yuva_size_info, indices, planes, - frame_index, lazy_pixel_ref); + return paint_image_generator_->GetYUVA8Planes( + yuva_size_info, plane_indices, planes, frame_index, lazy_pixel_ref); } bool PaintImage::DecodeFromGenerator(void* memory,
diff --git a/cc/paint/paint_image.h b/cc/paint/paint_image.h index df01c108..84e64fd 100644 --- a/cc/paint/paint_image.h +++ b/cc/paint/paint_image.h
@@ -218,10 +218,14 @@ // - The |frame_index| parameter will be passed along to // ImageDecoder::DecodeToYUV but for multi-frame YUV support, ImageDecoder // needs a separate YUV frame buffer cache. + // - The mapping of source planes to channels is tracked by |plane_indices|. + // This struct is initialized by QueryYUVA8 in calls to + // PaintImage::IsYuv(), including within this method. bool DecodeYuv(void* planes[SkYUVASizeInfo::kMaxCount], size_t frame_index, GeneratorClientId client_id, - const SkYUVASizeInfo& yuva_size_info) const; + const SkYUVASizeInfo& yuva_size_info, + SkYUVAIndex* plane_indices) const; Id stable_id() const { return id_; } const sk_sp<SkImage>& GetSkImage() const;
diff --git a/cc/paint/paint_image_unittest.cc b/cc/paint/paint_image_unittest.cc index bc1a06d..3837d80e 100644 --- a/cc/paint/paint_image_unittest.cc +++ b/cc/paint/paint_image_unittest.cc
@@ -150,8 +150,10 @@ ASSERT_TRUE(image.IsYuv(&image_yuv_size_info, image_plane_indices)); ASSERT_EQ(yuva_size_info, image_yuv_size_info); + SkYUVAIndex plane_indices[SkYUVAIndex::kIndexCount]; image.DecodeYuv(planes, 1u /* frame_index */, - PaintImage::kDefaultGeneratorClientId, yuva_size_info); + PaintImage::kDefaultGeneratorClientId, yuva_size_info, + plane_indices); ASSERT_EQ(yuv_generator->frames_decoded().size(), 1u); EXPECT_EQ(yuv_generator->frames_decoded().count(1u), 1u); yuv_generator->reset_frames_decoded();
diff --git a/cc/tiles/gpu_image_decode_cache.cc b/cc/tiles/gpu_image_decode_cache.cc index 198f910..d0dd588 100644 --- a/cc/tiles/gpu_image_decode_cache.cc +++ b/cc/tiles/gpu_image_decode_cache.cc
@@ -186,23 +186,26 @@ DCHECK(pixmap_y); DCHECK(pixmap_u); DCHECK(pixmap_v); - const size_t y_width = yuva_size_info.fWidthBytes[SkYUVAIndex::kY_Index]; + const size_t y_width_bytes = + yuva_size_info.fWidthBytes[SkYUVAIndex::kY_Index]; + const size_t y_width = yuva_size_info.fSizes[SkYUVAIndex::kY_Index].width(); const size_t y_height = yuva_size_info.fSizes[SkYUVAIndex::kY_Index].height(); - const size_t u_width = yuva_size_info.fWidthBytes[SkYUVAIndex::kU_Index]; + const size_t u_width_bytes = + yuva_size_info.fWidthBytes[SkYUVAIndex::kU_Index]; + const size_t u_width = yuva_size_info.fSizes[SkYUVAIndex::kU_Index].width(); const size_t u_height = yuva_size_info.fSizes[SkYUVAIndex::kU_Index].height(); - const size_t v_width = yuva_size_info.fWidthBytes[SkYUVAIndex::kV_Index]; + const size_t v_width_bytes = + yuva_size_info.fWidthBytes[SkYUVAIndex::kV_Index]; + const size_t v_width = yuva_size_info.fSizes[SkYUVAIndex::kV_Index].width(); const size_t v_height = yuva_size_info.fSizes[SkYUVAIndex::kV_Index].height(); const SkImageInfo y_decode_info = info.makeColorType(kGray_8_SkColorType).makeWH(y_width, y_height); const SkImageInfo u_decode_info = y_decode_info.makeWH(u_width, u_height); const SkImageInfo v_decode_info = y_decode_info.makeWH(v_width, v_height); yuva_size_info.computePlanes(memory_ptr, planes); - pixmap_y->reset(y_decode_info, planes[SkYUVAIndex::kY_Index], - y_decode_info.minRowBytes()); - pixmap_u->reset(u_decode_info, planes[SkYUVAIndex::kU_Index], - u_decode_info.minRowBytes()); - pixmap_v->reset(v_decode_info, planes[SkYUVAIndex::kV_Index], - v_decode_info.minRowBytes()); + pixmap_y->reset(y_decode_info, planes[SkYUVAIndex::kY_Index], y_width_bytes); + pixmap_u->reset(u_decode_info, planes[SkYUVAIndex::kU_Index], u_width_bytes); + pixmap_v->reset(v_decode_info, planes[SkYUVAIndex::kV_Index], v_width_bytes); } // Helper method to fill in |scaled_u_size| and |scaled_v_size| by computing @@ -280,8 +283,10 @@ draw_image.filter_quality() == kNone_SkFilterQuality; SkImageInfo info = pixmap.info(); SkYUVASizeInfo yuva_size_info; + SkYUVAIndex plane_indices[SkYUVAIndex::kIndexCount]; if (do_yuv_decode) { - const bool yuva_info_initialized = paint_image.IsYuv(&yuva_size_info); + const bool yuva_info_initialized = + paint_image.IsYuv(&yuva_size_info, plane_indices); DCHECK(yuva_info_initialized); } SkISize supported_size = @@ -298,7 +303,7 @@ SetYuvPixmapsFromSizeInfo(pixmap_y, pixmap_u, pixmap_v, yuva_size_info, planes, info, pixmap.writable_addr()); return paint_image.DecodeYuv(planes, draw_image.frame_index(), client_id, - yuva_size_info); + yuva_size_info, plane_indices); } return paint_image.Decode(pixmap.writable_addr(), &info, color_space, draw_image.frame_index(), client_id); @@ -346,11 +351,12 @@ yuva_size_info.computePlanes(decode_pixmap.writable_addr(), planes); } bool initial_decode_failed = - do_yuv_decode ? !paint_image.DecodeYuv(planes, draw_image.frame_index(), - client_id, yuva_size_info) - : !paint_image.Decode(decode_pixmap.writable_addr(), - &decode_info, color_space, - draw_image.frame_index(), client_id); + do_yuv_decode + ? !paint_image.DecodeYuv(planes, draw_image.frame_index(), client_id, + yuva_size_info, plane_indices) + : !paint_image.Decode(decode_pixmap.writable_addr(), &decode_info, + color_space, draw_image.frame_index(), + client_id); if (initial_decode_failed) return false; @@ -2301,7 +2307,6 @@ mode != DecodedDataMode::kCpu && !image_larger_than_max_texture; // TODO(crbug.com/910276): Change after alpha support. if (is_yuv) { - size_t y_size_bytes = image_info.width() * image_info.height(); const gfx::Size target_raster_size(image_info.width(), image_info.height()); gfx::Size unscaled_u_size( target_yuva_size_info.fSizes[SkYUVAIndex::kU_Index].width(), @@ -2314,8 +2319,16 @@ ComputeMippedUVPlaneSizes(target_raster_size, unscaled_u_size, unscaled_v_size, draw_image, &scaled_u_size, &scaled_v_size); - size_t u_size_bytes = base::checked_cast<size_t>(scaled_u_size.GetArea()); - size_t v_size_bytes = base::checked_cast<size_t>(scaled_v_size.GetArea()); + + size_t y_size_bytes = + target_yuva_size_info.fWidthBytes[SkYUVAIndex::kY_Index] * + target_yuva_size_info.fSizes[SkYUVAIndex::kY_Index].height(); + size_t u_size_bytes = + target_yuva_size_info.fWidthBytes[SkYUVAIndex::kU_Index] * + target_yuva_size_info.fSizes[SkYUVAIndex::kU_Index].height(); + size_t v_size_bytes = + target_yuva_size_info.fWidthBytes[SkYUVAIndex::kV_Index] * + target_yuva_size_info.fSizes[SkYUVAIndex::kV_Index].height(); data_size = y_size_bytes + u_size_bytes + v_size_bytes; }
diff --git a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java index 93a9f676..57a34065 100644 --- a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java +++ b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java
@@ -249,6 +249,8 @@ : "HomeSurface"; RecordUserAction.record( "StartSurface.TwoPanes.DefaultOn" + defaultOnUserActionString); + } else if (mSurfaceMode == SurfaceMode.TASKS_ONLY) { + RecordUserAction.record("StartSurface.TasksOnly"); } // Make sure FeedSurfaceCoordinator is built before the explore surface is showing by
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionProcessor.java index bfe5add..1208c92 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionProcessor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionProcessor.java
@@ -232,6 +232,6 @@ assert suggestion.getType() == OmniboxSuggestionType.CALCULATOR; return R.drawable.ic_equals_sign_round; } - return 0; + return R.drawable.ic_google_round; } }
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index 10f0127..cad48385 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -653,6 +653,30 @@ <message name="IDS_SETTINGS_CROSTINI_SHARED_USB_DEVICES_EXTRA_DESCRIPTION" desc="Extra description for managing shared USB devices."> Only Android devices are currently supported. </message> + <message name="IDS_SETTINGS_CROSTINI_ARC_ADB_TITLE" desc="Title of ARC ADB sideloading section."> + Develop Android apps + </message> + <message name="IDS_SETTINGS_CROSTINI_ARC_ADB_DESCRIPTION" desc="Description of ARC ADB sideloading in Settings."> + To create and test your apps, enable the Android Debug Bridge (ADB). Note that this action allows installation of Android apps that haven't been verified by Google, and requires a factory reset to disable. + </message> + <message name="IDS_SETTINGS_CROSTINI_ARC_ADB_LABEL" desc="Label for enabling ADB in ARC."> + Enable on this device + </message> + <message name="IDS_SETTINGS_CROSTINI_ARC_ADB_CONFIRMATION_TITLE_ENABLE" desc="Confirmation dialog title to restart for enabling ADB."> + Enable ADB? + </message> + <message name="IDS_SETTINGS_CROSTINI_ARC_ADB_CONFIRMATION_TITLE_DISABLE" desc="Confirmation dialog title to restart for disabling ADB."> + Disable ADB? + </message> + <message name="IDS_SETTINGS_CROSTINI_ARC_ADB_CONFIRMATION_MESSAGE_ENABLE" desc="Describes what will happen if the user enables ADB Sideloading."> + To enable the Android Debug Bridge, first restart your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph>. Disabling ADB requires a reset to factory settings. + </message> + <message name="IDS_SETTINGS_CROSTINI_ARC_ADB_CONFIRMATION_MESSAGE_DISABLE" desc="Describes what will happen if the user disables ADB Sideloading."> + To disable ADB, restart your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph>. It will be reset to factory settings, and all user accounts and local data will be erased. + </message> + <message name="IDS_SETTINGS_CROSTINI_ARC_ADB_RESTART_BUTTON" desc="Label for the button that initiates the ADB enabling flow by restarting the device."> + Restart + </message> <!-- Plugin VM Page --> <message name="IDS_SETTINGS_PLUGIN_VM_PAGE_TITLE" desc="The title of Plugin VM section.">
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index dacb510..c0ba9ac 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -4193,7 +4193,7 @@ FEATURE_VALUE_TYPE( autofill::features::kAutofillDoNotMigrateUnsupportedLocalCards)}, {"enable-unsafe-webgpu", flag_descriptions::kUnsafeWebGPUName, - flag_descriptions::kUnsafeWebGPUDescription, kOsMac, + flag_descriptions::kUnsafeWebGPUDescription, kOsMac | kOsWin, SINGLE_VALUE_TYPE(switches::kEnableUnsafeWebGPU)}, #if defined(OS_ANDROID)
diff --git a/chrome/browser/autofill/autofill_interactive_uitest.cc b/chrome/browser/autofill/autofill_interactive_uitest.cc index d34ef52..f81f2d81 100644 --- a/chrome/browser/autofill/autofill_interactive_uitest.cc +++ b/chrome/browser/autofill/autofill_interactive_uitest.cc
@@ -21,6 +21,7 @@ #include "base/strings/string_split.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/bind_test_util.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/mock_entropy_provider.h" #include "base/test/scoped_feature_list.h" @@ -68,6 +69,7 @@ #include "content/public/test/content_mock_cert_verifier.h" #include "content/public/test/test_renderer_host.h" #include "content/public/test/test_utils.h" +#include "content/public/test/url_loader_interceptor.h" #include "net/base/net_errors.h" #include "net/cert/mock_cert_verifier.h" #include "net/dns/mock_host_resolver.h" @@ -82,6 +84,7 @@ #include "ui/events/keycodes/keyboard_codes.h" using base::ASCIIToUTF16; +using content::URLLoaderInterceptor; namespace autofill { @@ -721,8 +724,43 @@ } }; +class AutofillInteractiveTestWithHistogramTester + : public AutofillInteractiveTest { + public: + void SetUp() override { + // Only allow requests to be loaded that are necessary for the test. This + // allows a histogram to test properties of some specific requests. + std::vector<std::string> allowlist = { + "/internal/test_url_path", "https://clients1.google.com/tbproxy"}; + url_loader_interceptor_ = + std::make_unique<URLLoaderInterceptor>(base::BindLambdaForTesting( + [&](URLLoaderInterceptor::RequestParams* params) { + for (const auto& s : allowlist) { + const bool is_match = + params->url_request.url.spec().find(s) != std::string::npos; + if (is_match) + return false; // Do not intercept. + } + return true; // Intercept + })); + AutofillInteractiveTest::SetUp(); + } + + void TearDownOnMainThread() override { + url_loader_interceptor_.reset(); + AutofillInteractiveTest::TearDownOnMainThread(); + } + + base::HistogramTester& histogram_tester() { return histogram_tester_; } + + private: + base::HistogramTester histogram_tester_; + std::unique_ptr<URLLoaderInterceptor> url_loader_interceptor_; +}; + // Test that basic form fill is working. -IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest, BasicFormFill) { +IN_PROC_BROWSER_TEST_F(AutofillInteractiveTestWithHistogramTester, + BasicFormFill) { LOG(ERROR) << "crbug/967588: In case of flakes, report log statements to " "crbug.com/967588"; CreateTestProfile(); @@ -737,6 +775,13 @@ // Invoke Autofill. TryBasicFormFill(); LOG(ERROR) << "crbug/967588: Basic form filling completed"; + + SubprocessMetricsProvider::MergeHistogramDeltasForTesting(); + // Assert that the network isolation key is populated for 2 requests: + // - Navigation: /internal/test_url_path + // - Autofill query: https://clients1.google.com/tbproxy/af/query?... + histogram_tester().ExpectBucketCount("HttpCache.NetworkIsolationKeyPresent2", + 2 /*kPresent*/, 2 /*count*/); } IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest, BasicClear) {
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.cc b/chrome/browser/chromeos/accessibility/accessibility_manager.cc index ab5fb357..fb09891 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_manager.cc +++ b/chrome/browser/chromeos/accessibility/accessibility_manager.cc
@@ -48,7 +48,6 @@ #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/extensions/api/braille_display_private/stub_braille_controller.h" #include "chrome/browser/extensions/extension_service.h" -#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/ash/multi_user/multi_user_util.h" #include "chrome/browser/ui/singleton_tabs.h" @@ -241,8 +240,6 @@ notification_registrar_.Add(this, chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE, content::NotificationService::AllSources()); - notification_registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, - content::NotificationService::AllSources()); notification_registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, content::NotificationService::AllSources()); notification_registrar_.Add(this, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE, @@ -1052,10 +1049,19 @@ } } +void AccessibilityManager::OnProfileWillBeDestroyed(Profile* profile) { + DCHECK_EQ(profile_, profile); + SetProfile(nullptr); +} + void AccessibilityManager::SetProfile(Profile* profile) { if (profile_ == profile) return; + if (profile_) + profile_observer_.Remove(profile_); + DCHECK(!profile_observer_.IsObservingSources()); + pref_change_registrar_.reset(); local_state_pref_change_registrar_.reset(); @@ -1141,6 +1147,8 @@ extensions::ExtensionRegistry::Get(profile); if (!extension_registry_observer_.IsObserving(registry)) extension_registry_observer_.Add(registry); + + profile_observer_.Add(profile); } bool had_profile = (profile_ != NULL); @@ -1278,13 +1286,6 @@ SetProfile(profile); break; } - case chrome::NOTIFICATION_PROFILE_DESTROYED: { - // Update |profile_| when exiting a session or shutting down. - Profile* profile = content::Source<Profile>(source).ptr(); - if (profile_ == profile) - SetProfile(nullptr); - break; - } case chrome::NOTIFICATION_APP_TERMINATING: { app_terminating_ = true; break;
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.h b/chrome/browser/chromeos/accessibility/accessibility_manager.h index 243b260..23d91d6b 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_manager.h +++ b/chrome/browser/chromeos/accessibility/accessibility_manager.h
@@ -20,6 +20,8 @@ #include "chrome/browser/chromeos/accessibility/chromevox_panel.h" #include "chrome/browser/chromeos/accessibility/switch_access_panel.h" #include "chrome/browser/extensions/api/braille_display_private/braille_controller.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_observer.h" #include "chromeos/audio/cras_audio_handler.h" #include "components/prefs/pref_change_registrar.h" #include "components/user_manager/user_manager.h" @@ -35,7 +37,6 @@ #include "ui/base/ime/chromeos/input_method_manager.h" class Browser; -class Profile; class SwitchAccessEventHandlerDelegate; namespace ash { @@ -109,7 +110,8 @@ public extensions::ExtensionRegistryObserver, public user_manager::UserManager::UserSessionStateObserver, public input_method::InputMethodManager::Observer, - public CrasAudioHandler::AudioObserver { + public CrasAudioHandler::AudioObserver, + public ProfileObserver { public: // Creates an instance of AccessibilityManager, this should be called once, // because only one instance should exist at the same time. @@ -429,8 +431,12 @@ // CrasAudioHandler::AudioObserver: void OnActiveOutputNodeChanged() override; + // ProfileObserver: + void OnProfileWillBeDestroyed(Profile* profile) override; + // Profile which has the current a11y context. Profile* profile_ = nullptr; + ScopedObserver<Profile, ProfileObserver> profile_observer_{this}; content::NotificationRegistrar notification_registrar_; std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_;
diff --git a/chrome/browser/chromeos/accessibility/magnification_manager.cc b/chrome/browser/chromeos/accessibility/magnification_manager.cc index 97ce57d..d0e337a7 100644 --- a/chrome/browser/chromeos/accessibility/magnification_manager.cc +++ b/chrome/browser/chromeos/accessibility/magnification_manager.cc
@@ -15,7 +15,6 @@ #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" -#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" #include "components/prefs/pref_change_registrar.h" #include "components/prefs/pref_service.h" @@ -95,6 +94,11 @@ ash::prefs::kAccessibilityScreenMagnifierScale); } +void MagnificationManager::OnProfileWillBeDestroyed(Profile* profile) { + DCHECK_EQ(profile_, profile); + SetProfile(nullptr); +} + void MagnificationManager::OnViewEvent(views::View* view, ax::mojom::Event event_type) { if (!fullscreen_magnifier_enabled_ && !IsDockedMagnifierEnabled()) @@ -114,8 +118,6 @@ MagnificationManager::MagnificationManager() { registrar_.Add(this, chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE, content::NotificationService::AllSources()); - registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, - content::NotificationService::AllSources()); // TODO(warx): observe focus changed in page notification when either // fullscreen magnifier or docked magnifier is enabled. registrar_.Add(this, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE, @@ -142,13 +144,6 @@ SetProfile(profile); break; } - case chrome::NOTIFICATION_PROFILE_DESTROYED: { - // Update |profile_| when exiting a session or shutting down. - Profile* profile = content::Source<Profile>(source).ptr(); - if (profile_ == profile) - SetProfile(NULL); - break; - } case content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE: { HandleFocusChangedInPage(details); break; @@ -170,6 +165,10 @@ } void MagnificationManager::SetProfile(Profile* profile) { + if (profile_) + profile_observer_.Remove(profile_); + DCHECK(!profile_observer_.IsObservingSources()); + pref_change_registrar_.reset(); if (profile) { @@ -193,6 +192,8 @@ base::BindRepeating( &MagnificationManager::UpdateDockedMagnifierFromPrefs, base::Unretained(this))); + + profile_observer_.Add(profile); } profile_ = profile;
diff --git a/chrome/browser/chromeos/accessibility/magnification_manager.h b/chrome/browser/chromeos/accessibility/magnification_manager.h index 68cd4ba..36508be2 100644 --- a/chrome/browser/chromeos/accessibility/magnification_manager.h +++ b/chrome/browser/chromeos/accessibility/magnification_manager.h
@@ -7,13 +7,15 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "base/scoped_observer.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_observer.h" #include "components/user_manager/user_manager.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" #include "ui/views/accessibility/ax_event_observer.h" class PrefChangeRegistrar; -class Profile; namespace chromeos { @@ -32,6 +34,7 @@ class MagnificationManager : public content::NotificationObserver, public user_manager::UserManager::UserSessionStateObserver, + public ProfileObserver, public views::AXEventObserver { public: // Creates an instance of MagnificationManager. This should be called once. @@ -61,6 +64,9 @@ // Loads the Fullscreen magnifier scale from the pref. double GetSavedScreenMagnifierScale() const; + // ProfileObserver: + void OnProfileWillBeDestroyed(Profile* profile) override; + // views::AXEventObserver: void OnViewEvent(views::View* view, ax::mojom::Event event_type) override; @@ -94,6 +100,7 @@ void HandleFocusChanged(const gfx::Rect& bounds_in_screen, bool is_editable); Profile* profile_ = nullptr; + ScopedObserver<Profile, ProfileObserver> profile_observer_{this}; bool fullscreen_magnifier_enabled_ = false; bool keep_focus_centered_ = false;
diff --git a/chrome/browser/chromeos/note_taking_controller_client.cc b/chrome/browser/chromeos/note_taking_controller_client.cc index b5872945..8fe7fe9 100644 --- a/chrome/browser/chromeos/note_taking_controller_client.cc +++ b/chrome/browser/chromeos/note_taking_controller_client.cc
@@ -4,18 +4,12 @@ #include "chrome/browser/chromeos/note_taking_controller_client.h" -#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" -#include "chrome/browser/profiles/profile_manager.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_source.h" namespace chromeos { NoteTakingControllerClient::NoteTakingControllerClient(NoteTakingHelper* helper) : helper_(helper) { - registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, - content::NotificationService::AllSources()); user_manager::UserManager::Get()->AddSessionStateObserver(this); } @@ -41,20 +35,18 @@ weak_ptr_factory_.GetWeakPtr(), active_user)); } -void NoteTakingControllerClient::Observe( - int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - DCHECK_EQ(type, chrome::NOTIFICATION_PROFILE_DESTROYED); +void NoteTakingControllerClient::OnProfileWillBeDestroyed(Profile* profile) { // Update |profile_| when exiting a session or shutting down. - Profile* profile = content::Source<Profile>(source).ptr(); - if (profile_ == profile) - profile_ = nullptr; + DCHECK_EQ(profile_, profile); + profile_observer_.Remove(profile_); + profile_ = nullptr; } void NoteTakingControllerClient::SetProfileByUser( const user_manager::User* user) { profile_ = ProfileHelper::Get()->GetProfileByUser(user); + profile_observer_.RemoveAll(); + profile_observer_.Add(profile_); } } // namespace chromeos
diff --git a/chrome/browser/chromeos/note_taking_controller_client.h b/chrome/browser/chromeos/note_taking_controller_client.h index a80e87b..4fcc074d 100644 --- a/chrome/browser/chromeos/note_taking_controller_client.h +++ b/chrome/browser/chromeos/note_taking_controller_client.h
@@ -9,18 +9,16 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "chrome/browser/chromeos/note_taking_helper.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_observer.h" #include "components/user_manager/user_manager.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" - -class Profile; namespace chromeos { class NoteTakingControllerClient : public ash::NoteTakingClient, public user_manager::UserManager::UserSessionStateObserver, - public content::NotificationObserver { + public ProfileObserver { public: explicit NoteTakingControllerClient(NoteTakingHelper* helper); ~NoteTakingControllerClient() override; @@ -32,10 +30,8 @@ // user_manager::UserManager::UserSessionStateObserver: void ActiveUserChanged(user_manager::User* active_user) override; - // content::NotificationObserver: - void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; + // ProfileObserver: + void OnProfileWillBeDestroyed(Profile* profile) override; void SetProfileForTesting(Profile* profile) { profile_ = profile; } @@ -47,8 +43,8 @@ // Unowned pointer to the active profile. Profile* profile_ = nullptr; + ScopedObserver<Profile, ProfileObserver> profile_observer_{this}; - content::NotificationRegistrar registrar_; base::WeakPtrFactory<NoteTakingControllerClient> weak_ptr_factory_{this}; DISALLOW_COPY_AND_ASSIGN(NoteTakingControllerClient);
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_token_forwarder_unittest.cc b/chrome/browser/chromeos/policy/user_cloud_policy_token_forwarder_unittest.cc index 877649ee..f6f5234 100644 --- a/chrome/browser/chromeos/policy/user_cloud_policy_token_forwarder_unittest.cc +++ b/chrome/browser/chromeos/policy/user_cloud_policy_token_forwarder_unittest.cc
@@ -115,6 +115,8 @@ void TearDown() override { user_policy_manager_->core()->Disconnect(); + // Must be torn down before |profile_manager_|. + user_policy_manager_.reset(); chromeos::DBusThreadManager::Shutdown(); }
diff --git a/chrome/browser/chromeos/system/system_clock.cc b/chrome/browser/chromeos/system/system_clock.cc index c9cd100..8e8a9e5810 100644 --- a/chrome/browser/chromeos/system/system_clock.cc +++ b/chrome/browser/chromeos/system/system_clock.cc
@@ -14,8 +14,6 @@ #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/chromeos/system/system_clock_observer.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/profiles/profile_manager.h" #include "chrome/common/pref_names.h" #include "chromeos/login/login_state/login_state.h" #include "chromeos/settings/cros_settings_names.h" @@ -54,8 +52,6 @@ if (LoginState::IsInitialized()) LoginState::Get()->AddObserver(this); - registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, - content::NotificationService::AllSources()); user_manager::UserManager::Get()->AddSessionStateObserver(this); } @@ -67,7 +63,6 @@ user_manager::UserManager::Get()->RemoveSessionStateObserver(this); } -// LoginState::Observer overrides. void SystemClock::LoggedInStateChanged() { // It apparently sometimes takes a while after login before the current user // is recognized as the owner. Make sure that the system-wide clock setting @@ -76,15 +71,11 @@ SetShouldUse24HourClock(ShouldUse24HourClock()); } -// content::NotificationObserver implementation. -void SystemClock::Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - DCHECK_EQ(type, chrome::NOTIFICATION_PROFILE_DESTROYED); - if (OnProfileDestroyed(content::Source<Profile>(source).ptr())) { - registrar_.Remove(this, chrome::NOTIFICATION_PROFILE_DESTROYED, - content::NotificationService::AllSources()); - } +void SystemClock::OnProfileWillBeDestroyed(Profile* profile) { + DCHECK_EQ(profile, user_profile_); + profile_observer_.Remove(profile); + user_pref_registrar_.reset(); + user_profile_ = nullptr; } void SystemClock::ActiveUserChanged(user_manager::User* active_user) { @@ -110,6 +101,8 @@ void SystemClock::SetProfile(Profile* profile) { user_profile_ = profile; + profile_observer_.RemoveAll(); + profile_observer_.Add(profile); PrefService* prefs = profile->GetPrefs(); user_pref_registrar_.reset(new PrefChangeRegistrar); user_pref_registrar_->Init(prefs); @@ -119,14 +112,6 @@ UpdateClockType(); } -bool SystemClock::OnProfileDestroyed(Profile* profile) { - if (profile != user_profile_) - return false; - user_pref_registrar_.reset(); - user_profile_ = NULL; - return true; -} - void SystemClock::SetLastFocusedPodHourClockType( base::HourClockType hour_clock_type) { user_pod_was_focused_ = true;
diff --git a/chrome/browser/chromeos/system/system_clock.h b/chrome/browser/chromeos/system/system_clock.h index 635941a2..76a8e687 100644 --- a/chrome/browser/chromeos/system/system_clock.h +++ b/chrome/browser/chromeos/system/system_clock.h
@@ -11,12 +11,12 @@ #include "base/i18n/time_formatting.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "base/scoped_observer.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_observer.h" #include "chromeos/login/login_state/login_state.h" #include "components/user_manager/user_manager.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" -class Profile; class PrefChangeRegistrar; namespace user_manager { @@ -33,7 +33,7 @@ // modify on-screen time representation (like ActiveUserChanged) and notifies // observers. class SystemClock : public chromeos::LoginState::Observer, - public content::NotificationObserver, + public ProfileObserver, public user_manager::UserManager::UserSessionStateObserver { public: SystemClock(); @@ -46,12 +46,10 @@ bool ShouldUse24HourClock() const; - // content::NotificationObserver implementation. - void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; + // ProfileObserver: + void OnProfileWillBeDestroyed(Profile* profile) override; - // user_manager::UserManager::UserSessionStateObserver overrides + // user_manager::UserManager::UserSessionStateObserver: void ActiveUserChanged(user_manager::User* active_user) override; private: @@ -61,7 +59,6 @@ void SetProfileByUser(const user_manager::User* user); void SetProfile(Profile* profile); - bool OnProfileDestroyed(Profile* profile); // LoginState::Observer overrides. void LoggedInStateChanged() override; @@ -74,7 +71,7 @@ base::HourClockType last_focused_pod_hour_clock_type_ = base::k12HourClock; Profile* user_profile_ = nullptr; - content::NotificationRegistrar registrar_; + ScopedObserver<Profile, ProfileObserver> profile_observer_{this}; std::unique_ptr<PrefChangeRegistrar> user_pref_registrar_; base::ObserverList<SystemClockObserver>::Unchecked observer_list_;
diff --git a/chrome/browser/extensions/api/input_ime/input_ime_api.cc b/chrome/browser/extensions/api/input_ime/input_ime_api.cc index 573d7eb..61bb8af 100644 --- a/chrome/browser/extensions/api/input_ime/input_ime_api.cc +++ b/chrome/browser/extensions/api/input_ime/input_ime_api.cc
@@ -8,9 +8,6 @@ #include <utility> #include "base/lazy_instance.h" -#include "chrome/browser/chrome_notification_types.h" -#include "content/public/browser/notification_registrar.h" -#include "content/public/browser/notification_service.h" #include "extensions/browser/extension_registry.h" #include "ui/base/ime/ime_bridge.h" @@ -268,7 +265,6 @@ } InputImeEventRouterFactory::InputImeEventRouterFactory() = default; - InputImeEventRouterFactory::~InputImeEventRouterFactory() = default; InputImeEventRouter* InputImeEventRouterFactory::GetRouter(Profile* profile) { @@ -426,23 +422,15 @@ EventRouter* event_router = EventRouter::Get(browser_context_); event_router->RegisterObserver(this, input_ime::OnFocus::kEventName); - registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, - content::NotificationService::AllSources()); -} - -void InputImeAPI::Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - DCHECK_EQ(chrome::NOTIFICATION_PROFILE_DESTROYED, type); - extensions::InputImeEventRouterFactory::GetInstance()->RemoveProfile( - content::Source<Profile>(source).ptr()); } InputImeAPI::~InputImeAPI() = default; void InputImeAPI::Shutdown() { + extension_registry_observer_.RemoveAll(); + InputImeEventRouterFactory::GetInstance()->RemoveProfile( + Profile::FromBrowserContext(browser_context_)); EventRouter::Get(browser_context_)->UnregisterObserver(this); - registrar_.RemoveAll(); if (observer_ && ui::IMEBridge::Get()) { ui::IMEBridge::Get()->RemoveObserver(observer_.get()); } @@ -459,8 +447,7 @@ InputImeEventRouter* GetInputImeEventRouter(Profile* profile) { if (!profile) return nullptr; - return extensions::InputImeEventRouterFactory::GetInstance()->GetRouter( - profile); + return InputImeEventRouterFactory::GetInstance()->GetRouter(profile); } } // namespace extensions
diff --git a/chrome/browser/extensions/api/input_ime/input_ime_api.h b/chrome/browser/extensions/api/input_ime/input_ime_api.h index 30e8382..d208be1 100644 --- a/chrome/browser/extensions/api/input_ime/input_ime_api.h +++ b/chrome/browser/extensions/api/input_ime/input_ime_api.h
@@ -18,11 +18,11 @@ #include "chrome/browser/ui/input_method/input_method_engine_base.h" #include "chrome/common/extensions/api/input_ime.h" #include "components/keyed_service/core/keyed_service.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" #include "extensions/browser/browser_context_keyed_api_factory.h" #include "extensions/browser/event_router.h" +#include "extensions/browser/event_router_factory.h" #include "extensions/browser/extension_function.h" +#include "extensions/browser/extension_registry_factory.h" #include "extensions/browser/extension_registry_observer.h" #include "extensions/common/extension.h" #include "ui/base/ime/ime_bridge_observer.h" @@ -177,15 +177,14 @@ class InputImeAPI : public BrowserContextKeyedAPI, public ExtensionRegistryObserver, - public EventRouter::Observer, - public content::NotificationObserver { + public EventRouter::Observer { public: explicit InputImeAPI(content::BrowserContext* context); ~InputImeAPI() override; - // BrowserContextKeyedAPI implementation. static BrowserContextKeyedAPIFactory<InputImeAPI>* GetFactoryInstance(); + // BrowserContextKeyedAPI implementation. void Shutdown() override; // ExtensionRegistryObserver implementation. @@ -198,11 +197,6 @@ // EventRouter::Observer implementation. void OnListenerAdded(const EventListenerInfo& details) override; - // content::NotificationObserver: - void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; - private: friend class BrowserContextKeyedAPIFactory<InputImeAPI>; InputImeEventRouter* input_ime_event_router(); @@ -219,11 +213,18 @@ ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> extension_registry_observer_{this}; - content::NotificationRegistrar registrar_; - std::unique_ptr<ui::IMEBridgeObserver> observer_; }; +template <> +struct BrowserContextFactoryDependencies<InputImeAPI> { + static void DeclareFactoryDependencies( + BrowserContextKeyedAPIFactory<InputImeAPI>* factory) { + factory->DependsOn(EventRouterFactory::GetInstance()); + factory->DependsOn(ExtensionRegistryFactory::GetInstance()); + } +}; + InputImeEventRouter* GetInputImeEventRouter(Profile* profile); } // namespace extensions
diff --git a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc index f0ccf81..3c98d3e1 100644 --- a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc +++ b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc
@@ -421,8 +421,7 @@ // policy::BrowserDMTokenStorage::Get()->RetrieveDMToken() doesn't return a // valid token either. Once these are fixed the #if !defined can be removed. - if (!policy::ChromeBrowserCloudManagementController:: - IsMachineLevelUserCloudPolicyEnabled()) { + if (!policy::ChromeBrowserCloudManagementController::IsEnabled()) { return; }
diff --git a/chrome/browser/extensions/error_console/error_console.cc b/chrome/browser/extensions/error_console/error_console.cc index 6cabcac..76d7799 100644 --- a/chrome/browser/extensions/error_console/error_console.cc +++ b/chrome/browser/extensions/error_console/error_console.cc
@@ -12,16 +12,11 @@ #include "base/lazy_instance.h" #include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" -#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/extensions/error_console/error_console_factory.h" -#include "chrome/browser/profiles/profile.h" #include "chrome/common/pref_names.h" #include "components/crx_file/id_util.h" #include "components/prefs/pref_service.h" #include "components/version_info/version_info.h" -#include "content/public/browser/notification_details.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_source.h" #include "extensions/browser/extension_prefs.h" #include "extensions/browser/extension_system.h" #include "extensions/common/constants.h" @@ -198,10 +193,9 @@ // also create an ExtensionPrefs object. prefs_ = ExtensionPrefs::Get(profile_); - notification_registrar_.Add( - this, - chrome::NOTIFICATION_PROFILE_DESTROYED, - content::NotificationService::AllBrowserContextsAndSources()); + profile_observer_.Add(profile_); + if (profile_->HasOffTheRecordProfile()) + profile_observer_.Add(profile_->GetOffTheRecordProfile()); const ExtensionSet& extensions = ExtensionRegistry::Get(profile_)->enabled_extensions(); @@ -213,7 +207,7 @@ } void ErrorConsole::Disable() { - notification_registrar_.RemoveAll(); + profile_observer_.RemoveAll(); errors_.RemoveAllErrors(); enabled_ = false; } @@ -264,11 +258,12 @@ } } -void ErrorConsole::Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - DCHECK_EQ(chrome::NOTIFICATION_PROFILE_DESTROYED, type); - Profile* profile = content::Source<Profile>(source).ptr(); +void ErrorConsole::OnOffTheRecordProfileCreated(Profile* off_the_record) { + profile_observer_.Add(off_the_record); +} + +void ErrorConsole::OnProfileWillBeDestroyed(Profile* profile) { + profile_observer_.Remove(profile); // If incognito profile which we are associated with is destroyed, also // destroy all incognito errors. if (profile->IsOffTheRecord() && profile_->IsSameProfile(profile))
diff --git a/chrome/browser/extensions/error_console/error_console.h b/chrome/browser/extensions/error_console/error_console.h index dc628b5..7686f20c 100644 --- a/chrome/browser/extensions/error_console/error_console.h +++ b/chrome/browser/extensions/error_console/error_console.h
@@ -16,10 +16,10 @@ #include "base/observer_list.h" #include "base/scoped_observer.h" #include "base/threading/thread_checker.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_observer.h" #include "components/keyed_service/core/keyed_service.h" #include "components/prefs/pref_change_registrar.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" #include "extensions/browser/error_map.h" #include "extensions/browser/extension_error.h" #include "extensions/browser/extension_registry.h" @@ -27,12 +27,8 @@ namespace content { class BrowserContext; -class NotificationDetails; -class NotificationSource; } -class Profile; - namespace extensions { class Extension; class ExtensionPrefs; @@ -44,7 +40,7 @@ // This class is owned by ExtensionSystem, making it, in effect, a // BrowserContext-keyed service. class ErrorConsole : public KeyedService, - public content::NotificationObserver, + public ProfileObserver, public ExtensionRegistryObserver { public: class Observer { @@ -159,10 +155,9 @@ // Add manifest errors from an extension's install warnings. void AddManifestErrorsForExtension(const Extension* extension); - // content::NotificationObserver implementation. - void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; + // ProfileObserver: + void OnOffTheRecordProfileCreated(Profile* off_the_record) override; + void OnProfileWillBeDestroyed(Profile* profile) override; // Returns the applicable bit mask of reporting preferences for the extension. int GetMaskForExtension(const std::string& extension_id) const; @@ -196,7 +191,7 @@ // is dependent on ExtensionPrefs. ExtensionPrefs* prefs_; - content::NotificationRegistrar notification_registrar_; + ScopedObserver<Profile, ProfileObserver> profile_observer_{this}; PrefChangeRegistrar pref_registrar_; ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
diff --git a/chrome/browser/extensions/menu_manager.cc b/chrome/browser/extensions/menu_manager.cc index d70d392f..1cc13387 100644 --- a/chrome/browser/extensions/menu_manager.cc +++ b/chrome/browser/extensions/menu_manager.cc
@@ -16,7 +16,6 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" -#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/extensions/extension_tab_util.h" #include "chrome/browser/extensions/menu_manager_factory.h" #include "chrome/browser/extensions/tab_helper.h" @@ -24,9 +23,6 @@ #include "chrome/common/extensions/api/chrome_web_view_internal.h" #include "chrome/common/extensions/api/context_menus.h" #include "chrome/common/extensions/api/url_handlers/url_handlers_parser.h" -#include "content/public/browser/notification_details.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_source.h" #include "content/public/browser/web_contents.h" #include "content/public/common/child_process_host.h" #include "content/public/common/context_menu_params.h" @@ -317,14 +313,15 @@ MenuManager::MenuManager(content::BrowserContext* context, StateStore* store) : browser_context_(context), store_(store) { extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_)); - registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, - content::NotificationService::AllSources()); + Profile* profile = Profile::FromBrowserContext(context); + observed_profiles_.Add(profile); + if (profile->HasOffTheRecordProfile()) + observed_profiles_.Add(profile->GetOffTheRecordProfile()); if (store_) store_->RegisterKey(kContextMenusKey); } -MenuManager::~MenuManager() { -} +MenuManager::~MenuManager() = default; // static MenuManager* MenuManager::Get(content::BrowserContext* context) { @@ -883,18 +880,14 @@ } } -void MenuManager::Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - DCHECK_EQ(chrome::NOTIFICATION_PROFILE_DESTROYED, type); - Profile* profile = content::Source<Profile>(source).ptr(); - // We cannot use profile_->HasOffTheRecordProfile as it may already be - // false at this point, if for example the incognito profile was destroyed - // using DestroyOffTheRecordProfile. - if (profile->GetOriginalProfile() == browser_context_ && - profile->GetOriginalProfile() != profile) { +void MenuManager::OnOffTheRecordProfileCreated(Profile* off_the_record) { + observed_profiles_.Add(off_the_record); +} + +void MenuManager::OnProfileWillBeDestroyed(Profile* profile) { + observed_profiles_.Remove(profile); + if (profile->IsOffTheRecord()) RemoveAllIncognitoContextItems(); - } } gfx::Image MenuManager::GetIconForExtension(const std::string& extension_id) {
diff --git a/chrome/browser/extensions/menu_manager.h b/chrome/browser/extensions/menu_manager.h index e44d27e..a4c6594 100644 --- a/chrome/browser/extensions/menu_manager.h +++ b/chrome/browser/extensions/menu_manager.h
@@ -22,9 +22,9 @@ #include "base/strings/string16.h" #include "base/values.h" #include "chrome/browser/extensions/extension_icon_manager.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_observer.h" #include "components/keyed_service/core/keyed_service.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_registry_observer.h" #include "extensions/common/url_pattern_set.h" @@ -282,7 +282,7 @@ }; // This class keeps track of menu items added by extensions. -class MenuManager : public content::NotificationObserver, +class MenuManager : public ProfileObserver, public base::SupportsWeakPtr<MenuManager>, public KeyedService, public ExtensionRegistryObserver { @@ -355,10 +355,9 @@ // default extension icon. gfx::Image GetIconForExtension(const std::string& extension_id); - // content::NotificationObserver implementation. - void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; + // ProfileObserver: + void OnOffTheRecordProfileCreated(Profile* off_the_record) override; + void OnProfileWillBeDestroyed(Profile* profile) override; // ExtensionRegistryObserver implementation. void OnExtensionLoaded(content::BrowserContext* browser_context, @@ -404,12 +403,12 @@ // items. std::map<MenuItem::Id, MenuItem*> items_by_id_; - content::NotificationRegistrar registrar_; - - // Listen to extension load, unloaded notifications. + // Listen to extension load, unloaded events. ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> extension_registry_observer_{this}; + ScopedObserver<Profile, ProfileObserver> observed_profiles_{this}; + ExtensionIconManager icon_manager_; content::BrowserContext* browser_context_;
diff --git a/chrome/browser/file_select_helper.cc b/chrome/browser/file_select_helper.cc index c775e4f..e54d28f 100644 --- a/chrome/browser/file_select_helper.cc +++ b/chrome/browser/file_select_helper.cc
@@ -69,17 +69,6 @@ constexpr char kContactsMimeType[] = "text/json+contacts"; #endif -// Converts a list of FilePaths to a list of ui::SelectedFileInfo. -std::vector<ui::SelectedFileInfo> FilePathListToSelectedFileInfoList( - const std::vector<base::FilePath>& paths) { - std::vector<ui::SelectedFileInfo> selected_files; - for (size_t i = 0; i < paths.size(); ++i) { - selected_files.push_back( - ui::SelectedFileInfo(paths[i], paths[i])); - } - return selected_files; -} - void DeleteFiles(std::vector<base::FilePath> paths) { for (auto& file_path : paths) base::DeleteFile(file_path, false); @@ -207,7 +196,7 @@ const std::vector<base::FilePath>& files, void* params) { std::vector<ui::SelectedFileInfo> selected_files = - FilePathListToSelectedFileInfoList(files); + ui::FilePathListToSelectedFileInfoList(files); MultiFilesSelectedWithExtraInfo(selected_files, params); } @@ -281,7 +270,7 @@ } std::vector<ui::SelectedFileInfo> selected_files = - FilePathListToSelectedFileInfoList(entry->results_); + ui::FilePathListToSelectedFileInfoList(entry->results_); if (dialog_type_ == ui::SelectFileDialog::SELECT_UPLOAD_FOLDER) { LaunchConfirmationDialog(entry->path_, std::move(selected_files));
diff --git a/chrome/browser/importer/importer_list.cc b/chrome/browser/importer/importer_list.cc index da4c6f6..7065785 100644 --- a/chrome/browser/importer/importer_list.cc +++ b/chrome/browser/importer/importer_list.cc
@@ -94,8 +94,13 @@ std::vector<importer::SourceProfile>* profiles) { base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, base::BlockingType::MAY_BLOCK); - - base::FilePath profile_path = GetFirefoxProfilePath(); +#if defined(OS_WIN) + const std::string firefox_install_id = + shell_integration::GetFirefoxProgIdSuffix(); +#else + const std::string firefox_install_id; +#endif // defined(OS_WIN) + base::FilePath profile_path = GetFirefoxProfilePath(firefox_install_id); if (profile_path.empty()) return;
diff --git a/chrome/browser/navigation_predictor/navigation_predictor_preconnect_client.cc b/chrome/browser/navigation_predictor/navigation_predictor_preconnect_client.cc index 3e12b74..0143534 100644 --- a/chrome/browser/navigation_predictor/navigation_predictor_preconnect_client.cc +++ b/chrome/browser/navigation_predictor/navigation_predictor_preconnect_client.cc
@@ -7,6 +7,7 @@ #include <memory> #include "base/bind.h" +#include "base/feature_list.h" #include "base/metrics/field_trial_params.h" #include "base/time/time.h" #include "build/build_config.h" @@ -33,11 +34,16 @@ #endif }; +// Experiment with which event triggers the preconnect after commit. +const base::Feature kPreconnectOnDidFinishNavigation{ + "PreconnectOnDidFinishNavigation", base::FEATURE_DISABLED_BY_DEFAULT}; + } // namespace NavigationPredictorPreconnectClient::NavigationPredictorPreconnectClient( content::WebContents* web_contents) - : browser_context_(web_contents->GetBrowserContext()), + : content::WebContentsObserver(web_contents), + browser_context_(web_contents->GetBrowserContext()), current_visibility_(web_contents->GetVisibility()) {} NavigationPredictorPreconnectClient::~NavigationPredictorPreconnectClient() = @@ -51,6 +57,20 @@ // New page, so stop the preconnect timer. timer_.Stop(); + + if (base::FeatureList::IsEnabled(kPreconnectOnDidFinishNavigation)) { + int delay_ms = base::GetFieldTrialParamByFeatureAsInt( + kPreconnectOnDidFinishNavigation, "delay_after_commit_in_ms", 3000); + if (delay_ms <= 0) { + MaybePreconnectNow(); + return; + } + + timer_.Start( + FROM_HERE, base::TimeDelta::FromMilliseconds(delay_ms), + base::BindOnce(&NavigationPredictorPreconnectClient::MaybePreconnectNow, + base::Unretained(this))); + } } void NavigationPredictorPreconnectClient::OnVisibilityChanged(
diff --git a/chrome/browser/navigation_predictor/navigation_predictor_preconnect_client_browsertest.cc b/chrome/browser/navigation_predictor/navigation_predictor_preconnect_client_browsertest.cc index f416600..392229d5 100644 --- a/chrome/browser/navigation_predictor/navigation_predictor_preconnect_client_browsertest.cc +++ b/chrome/browser/navigation_predictor/navigation_predictor_preconnect_client_browsertest.cc
@@ -5,9 +5,10 @@ #include "base/macros.h" #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" -#include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" -#include "chrome/browser/metrics/subprocess_metrics_provider.h" +#include "chrome/browser/predictors/loading_predictor.h" +#include "chrome/browser/predictors/loading_predictor_factory.h" +#include "chrome/browser/predictors/preconnect_manager.h" #include "chrome/browser/search_engines/template_url_service_factory.h" #include "chrome/browser/subresource_filter/subresource_filter_browser_test_harness.h" #include "chrome/browser/ui/browser.h" @@ -24,7 +25,8 @@ namespace { class NavigationPredictorPreconnectClientBrowserTest - : public subresource_filter::SubresourceFilterBrowserTest { + : public subresource_filter::SubresourceFilterBrowserTest, + public predictors::PreconnectManager::Observer { public: NavigationPredictorPreconnectClientBrowserTest() : subresource_filter::SubresourceFilterBrowserTest() { @@ -45,36 +47,40 @@ void SetUpOnMainThread() override { subresource_filter::SubresourceFilterBrowserTest::SetUpOnMainThread(); host_resolver()->ClearRules(); + + auto* loading_predictor = + predictors::LoadingPredictorFactory::GetForProfile( + browser()->profile()); + ASSERT_TRUE(loading_predictor); + loading_predictor->preconnect_manager()->SetObserverForTesting(this); } const GURL GetTestURL(const char* file) const { return https_server_->GetURL(file); } - // Retries fetching |histogram_name| until it contains at least |count| - // samples. - void RetryForHistogramUntilCountReached( - const base::HistogramTester& histogram_tester, - const std::string& histogram_name, - size_t count) { - base::RunLoop().RunUntilIdle(); - for (size_t attempt = 0; attempt < 50; ++attempt) { - const std::vector<base::Bucket> buckets = - histogram_tester.GetAllSamples(histogram_name); - size_t total_count = 0; - for (const auto& bucket : buckets) - total_count += bucket.count; - if (total_count >= count) - return; - content::FetchHistogramsFromChildProcesses(); - SubprocessMetricsProvider::MergeHistogramDeltasForTesting(); - base::RunLoop().RunUntilIdle(); + void OnPreresolveFinished(const GURL& url, bool success) override { + EXPECT_TRUE(success); + preresolve_done_count_++; + if (run_loop_) + run_loop_->Quit(); + } + + void WaitForPreresolveCount(int expected_count) { + while (preresolve_done_count_ < expected_count) { + run_loop_ = std::make_unique<base::RunLoop>(); + run_loop_->Run(); + run_loop_.reset(); } } + protected: + int preresolve_done_count_ = 0; + private: std::unique_ptr<net::EmbeddedTestServer> https_server_; base::test::ScopedFeatureList feature_list_; + std::unique_ptr<base::RunLoop> run_loop_; DISALLOW_COPY_AND_ASSIGN(NavigationPredictorPreconnectClientBrowserTest); }; @@ -100,26 +106,20 @@ model->SetUserSelectedDefaultSearchProvider(template_url); const GURL& url = GetTestURL("/anchors_different_area.html?q=cats"); - base::HistogramTester histogram_tester; ui_test_utils::NavigateToURL(browser(), url); // There should be preconnect from navigation, but not preconnect client. - histogram_tester.ExpectTotalCount("LoadingPredictor.PreconnectCount", 1); - - ui_test_utils::NavigateToURL(browser(), url); - // There should be 2 preconnects from navigation, but not any from preconnect - // client. - histogram_tester.ExpectTotalCount("LoadingPredictor.PreconnectCount", 2); + EXPECT_EQ(1, preresolve_done_count_); } IN_PROC_BROWSER_TEST_F(NavigationPredictorPreconnectClientBrowserTest, PreconnectNotSearch) { const GURL& url = GetTestURL("/anchors_different_area.html"); - base::HistogramTester histogram_tester; ui_test_utils::NavigateToURL(browser(), url); - // There should be preconnect from navigation and one from preconnect client. - RetryForHistogramUntilCountReached(histogram_tester, - "LoadingPredictor.PreconnectCount", 2); + // There should be one preconnect from navigation and one from preconnect + // client. + WaitForPreresolveCount(2); + EXPECT_EQ(2, preresolve_done_count_); } IN_PROC_BROWSER_TEST_F(NavigationPredictorPreconnectClientBrowserTest, @@ -127,26 +127,26 @@ const GURL& url = GetTestURL("/anchors_different_area.html"); browser()->tab_strip_model()->GetActiveWebContents()->WasHidden(); - base::HistogramTester histogram_tester; + ui_test_utils::NavigateToURL(browser(), url); // There should be a navigational preconnect. - histogram_tester.ExpectTotalCount("LoadingPredictor.PreconnectCount", 1); + EXPECT_EQ(1, preresolve_done_count_); // Change to visible. browser()->tab_strip_model()->GetActiveWebContents()->WasShown(); // After showing the contents, there should be a preconnect client preconnect. - RetryForHistogramUntilCountReached(histogram_tester, - "LoadingPredictor.PreconnectCount", 2); + WaitForPreresolveCount(2); + EXPECT_EQ(2, preresolve_done_count_); browser()->tab_strip_model()->GetActiveWebContents()->WasHidden(); browser()->tab_strip_model()->GetActiveWebContents()->WasShown(); // After showing the contents again, there should be another preconnect client // preconnect. - RetryForHistogramUntilCountReached(histogram_tester, - "LoadingPredictor.PreconnectCount", 3); + WaitForPreresolveCount(3); + EXPECT_EQ(3, preresolve_done_count_); } class NavigationPredictorPreconnectClientBrowserTestWithUnusedIdleSocketTimeout @@ -167,12 +167,16 @@ IN_PROC_BROWSER_TEST_F( NavigationPredictorPreconnectClientBrowserTestWithUnusedIdleSocketTimeout, ActionAccuracy_timeout) { - base::HistogramTester histogram_tester; const GURL& url = GetTestURL("/page_with_same_host_anchor_element.html"); ui_test_utils::NavigateToURL(browser(), url); - histogram_tester.ExpectTotalCount("LoadingPredictor.PreconnectCount", 1); + WaitForPreresolveCount(3); + EXPECT_EQ(3, preresolve_done_count_); + + // Expect another one. + WaitForPreresolveCount(4); + EXPECT_EQ(4, preresolve_done_count_); } class NavigationPredictorPreconnectClientBrowserTestWithHoldback @@ -193,15 +197,69 @@ NoPreconnectHoldback) { const GURL& url = GetTestURL("/anchors_different_area.html"); - base::HistogramTester histogram_tester; ui_test_utils::NavigateToURL(browser(), url); // There should be preconnect from navigation, but not preconnect client. - histogram_tester.ExpectTotalCount("LoadingPredictor.PreconnectCount", 1); + EXPECT_EQ(1, preresolve_done_count_); ui_test_utils::NavigateToURL(browser(), url); // There should be 2 preconnects from navigation, but not any from preconnect // client. - histogram_tester.ExpectTotalCount("LoadingPredictor.PreconnectCount", 2); + EXPECT_EQ(2, preresolve_done_count_); +} + +const base::Feature kPreconnectOnDidFinishNavigation{ + "PreconnectOnDidFinishNavigation", base::FEATURE_DISABLED_BY_DEFAULT}; + +class + NavigationPredictorPreconnectClientBrowserTestPreconnectOnDidFinishNavigationSecondDelay + : public NavigationPredictorPreconnectClientBrowserTest { + public: + NavigationPredictorPreconnectClientBrowserTestPreconnectOnDidFinishNavigationSecondDelay() + : NavigationPredictorPreconnectClientBrowserTest() { + feature_list_.InitAndEnableFeatureWithParameters( + kPreconnectOnDidFinishNavigation, + {{"delay_after_commit_in_ms", "1000"}}); + } + + private: + base::test::ScopedFeatureList feature_list_; +}; + +IN_PROC_BROWSER_TEST_F( + NavigationPredictorPreconnectClientBrowserTestPreconnectOnDidFinishNavigationSecondDelay, + PreconnectNotSearch) { + const GURL& url = GetTestURL("/anchors_different_area.html"); + + ui_test_utils::NavigateToURL(browser(), url); + // There should be preconnect from navigation and one from OnLoad client. + WaitForPreresolveCount(2); + EXPECT_EQ(2, preresolve_done_count_); +} + +class + NavigationPredictorPreconnectClientBrowserTestPreconnectOnDidFinishNavigationNoDelay + : public NavigationPredictorPreconnectClientBrowserTest { + public: + NavigationPredictorPreconnectClientBrowserTestPreconnectOnDidFinishNavigationNoDelay() + : NavigationPredictorPreconnectClientBrowserTest() { + feature_list_.InitAndEnableFeatureWithParameters( + kPreconnectOnDidFinishNavigation, {{"delay_after_commit_in_ms", "0"}}); + } + + private: + base::test::ScopedFeatureList feature_list_; +}; + +IN_PROC_BROWSER_TEST_F( + NavigationPredictorPreconnectClientBrowserTestPreconnectOnDidFinishNavigationNoDelay, + PreconnectNotSearch) { + const GURL& url = GetTestURL("/anchors_different_area.html"); + + ui_test_utils::NavigateToURL(browser(), url); + // There should be a navigation preconnect, a commit preconnect, and an OnLoad + // preconnect. + WaitForPreresolveCount(3); + EXPECT_EQ(3, preresolve_done_count_); } } // namespace
diff --git a/chrome/browser/net/system_network_context_manager.cc b/chrome/browser/net/system_network_context_manager.cc index da04738f..cb0bf49 100644 --- a/chrome/browser/net/system_network_context_manager.cc +++ b/chrome/browser/net/system_network_context_manager.cc
@@ -87,6 +87,10 @@ #include "ui/base/l10n/l10n_util.h" #endif // defined(OS_LINUX) && !defined(OS_CHROMEOS) +#if defined(OS_WIN) || defined(OS_MACOSX) +#include "content/public/common/network_service_util.h" +#endif + #if BUILDFLAG(ENABLE_EXTENSIONS) #include "extensions/common/constants.h" #endif // BUILDFLAG(ENABLE_EXTENSIONS) @@ -669,9 +673,13 @@ content::GetNetworkService()->SetCryptConfig(std::move(config)); #endif #if defined(OS_WIN) || defined(OS_MACOSX) - std::string key = OSCrypt::GetRawEncryptionKey(); - DCHECK(!key.empty()); - content::GetNetworkService()->SetEncryptionKey(key); + // The OSCrypt keys are process bound, so if network service is out of + // process, send it the required key. + if (content::IsOutOfProcessNetworkService()) { + std::string key = OSCrypt::GetRawEncryptionKey(); + DCHECK(!key.empty()); + content::GetNetworkService()->SetEncryptionKey(key); + } #endif // Asynchronously reapply the most recently received CRLSet (if any).
diff --git a/chrome/browser/policy/chrome_browser_cloud_management_controller.cc b/chrome/browser/policy/chrome_browser_cloud_management_controller.cc index 8c10689c..5e6b671 100644 --- a/chrome/browser/policy/chrome_browser_cloud_management_controller.cc +++ b/chrome/browser/policy/chrome_browser_cloud_management_controller.cc
@@ -86,8 +86,7 @@ ChromeBrowserCloudManagementController::kPolicyDir[] = FILE_PATH_LITERAL("Policy"); -bool ChromeBrowserCloudManagementController:: - IsMachineLevelUserCloudPolicyEnabled() { +bool ChromeBrowserCloudManagementController::IsEnabled() { #if BUILDFLAG(GOOGLE_CHROME_BRANDING) return true; #else @@ -105,7 +104,7 @@ std::unique_ptr<MachineLevelUserCloudPolicyManager> ChromeBrowserCloudManagementController::CreatePolicyManager( ConfigurationPolicyProvider* platform_provider) { - if (!IsMachineLevelUserCloudPolicyEnabled()) + if (!IsEnabled()) return nullptr; std::string enrollment_token = @@ -153,7 +152,7 @@ void ChromeBrowserCloudManagementController::Init( PrefService* local_state, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) { - if (!IsMachineLevelUserCloudPolicyEnabled()) + if (!IsEnabled()) return; base::PostTask(
diff --git a/chrome/browser/policy/chrome_browser_cloud_management_controller.h b/chrome/browser/policy/chrome_browser_cloud_management_controller.h index e53cf94..9686e0a 100644 --- a/chrome/browser/policy/chrome_browser_cloud_management_controller.h +++ b/chrome/browser/policy/chrome_browser_cloud_management_controller.h
@@ -69,7 +69,7 @@ // The Chrome browser cloud management is only enabled on Chrome by default. // However, it can be enabled on Chromium by command line switch for test and // development purpose. - static bool IsMachineLevelUserCloudPolicyEnabled(); + static bool IsEnabled(); ChromeBrowserCloudManagementController(); virtual ~ChromeBrowserCloudManagementController();
diff --git a/chrome/browser/resources/local_ntp/local_ntp.css b/chrome/browser/resources/local_ntp/local_ntp.css index 1abacac..47f0790 100644 --- a/chrome/browser/resources/local_ntp/local_ntp.css +++ b/chrome/browser/resources/local_ntp/local_ntp.css
@@ -264,7 +264,7 @@ -webkit-mask-size: 20px; } -html[dir=rtl] #realbox-matches :-webkit-any(.clock-icon, .search-icon) { +html[dir=rtl] :-webkit-any(.clock-icon, .search-icon) { right: 16px; }
diff --git a/chrome/browser/resources/pdf/BUILD.gn b/chrome/browser/resources/pdf/BUILD.gn index 88ac35c..0acf118 100644 --- a/chrome/browser/resources/pdf/BUILD.gn +++ b/chrome/browser/resources/pdf/BUILD.gn
@@ -19,7 +19,7 @@ js_library("browser_api") { deps = [ - "//ui/webui/resources/js:assert", + "//ui/webui/resources/js:assert.m", ] externs_list = [ "$externs_path/chrome_extensions.js", @@ -40,9 +40,6 @@ } js_library("pdf_scripting_api") { - deps = [ - "//ui/webui/resources/js:assert", - ] } js_library("viewport_scroller") { @@ -53,8 +50,9 @@ ":gesture_detector", ":pdf_fitting_type", ":zoom_manager", - "//ui/webui/resources/js:event_tracker", - "//ui/webui/resources/js:util", + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:event_tracker.m", + "//ui/webui/resources/js:util.m", ] externs_list = [ "$externs_path/pending.js" ] } @@ -62,7 +60,7 @@ js_library("zoom_manager") { deps = [ ":browser_api", - "//ui/webui/resources/js/cr:event_target", + "//ui/webui/resources/js/cr:event_target.m", ] } @@ -84,7 +82,7 @@ deps = [ "elements:viewer-pdf-toolbar", "elements:viewer-zoom-toolbar", - "//ui/webui/resources/js:util", + "//ui/webui/resources/js:util.m", ] } @@ -93,8 +91,11 @@ ":annotation_tool", ":viewport", "elements:viewer-pdf-toolbar", - "//ui/webui/resources/js:load_time_data", - "//ui/webui/resources/js/cr:event_target", + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:load_time_data.m", + "//ui/webui/resources/js:promise_resolver.m", + "//ui/webui/resources/js:util.m", + "//ui/webui/resources/js/cr:event_target.m", ] } @@ -113,8 +114,11 @@ "elements:viewer-password-screen", "elements:viewer-pdf-toolbar", "elements:viewer-zoom-toolbar", - "//ui/webui/resources/js:event_tracker", - "//ui/webui/resources/js:load_time_data", + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:event_tracker.m", + "//ui/webui/resources/js:load_time_data.m", + "//ui/webui/resources/js:promise_resolver.m", + "//ui/webui/resources/js:util.m", ] externs_list = [ "$externs_path/resources_private.js" ] }
diff --git a/chrome/browser/resources/pdf/browser_api.js b/chrome/browser/resources/pdf/browser_api.js index e44d9b4..98b3739 100644 --- a/chrome/browser/resources/pdf/browser_api.js +++ b/chrome/browser/resources/pdf/browser_api.js
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -'use strict'; +import {assert} from 'chrome://resources/js/assert.m.js'; /** * @param {!Object} streamInfo The stream object pointing to the data contained @@ -49,7 +49,7 @@ /** * A class providing an interface to the browser. */ -class BrowserApi { +export class BrowserApi { /** * @param {!Object} streamInfo The stream object which points to the data * contained in the PDF. @@ -230,7 +230,7 @@ * @return {!Promise<!BrowserApi>} A promise to a BrowserApi instance for the * current environment. */ -function createBrowserApi() { +export function createBrowserApi() { if (location.origin === 'chrome://print') { return createBrowserApiForPrintPreview(); }
diff --git a/chrome/browser/resources/pdf/controller.js b/chrome/browser/resources/pdf/controller.js index ea790f3..e607c688 100644 --- a/chrome/browser/resources/pdf/controller.js +++ b/chrome/browser/resources/pdf/controller.js
@@ -2,10 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -'use strict'; +import {assert} from 'chrome://resources/js/assert.m.js'; +import {NativeEventTarget as EventTarget} from 'chrome://resources/js/cr/event_target.m.js'; +import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; +import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js'; +import {$} from 'chrome://resources/js/util.m.js'; + +import {PartialPoint, Point, Viewport} from './viewport.js'; /** @typedef {{ type: string }} */ -let MessageData; +export let MessageData; /** * @typedef {{ @@ -37,7 +43,7 @@ * pageNumbers: !Array<number> * }} */ -let PrintPreviewParams; +export let PrintPreviewParams; // Note: Redefining this type here, to work around the fact that ink externs // are only available on Chrome OS, so the targets that contain them cannot be @@ -70,7 +76,7 @@ } /** @abstract */ -class ContentController { +export class ContentController { constructor() {} beforeZoom() {} @@ -127,7 +133,7 @@ * set-annotation-undo-state: Contains information about whether undo or redo * options are available. */ -class InkController extends ContentController { +export class InkController extends ContentController { /** @param {!Viewport} viewport */ constructor(viewport) { super(); @@ -139,7 +145,7 @@ this.inkHost_ = null; /** @private {!EventTarget} */ - this.eventTarget_ = new cr.EventTarget(); + this.eventTarget_ = new EventTarget(); /** @type {?AnnotationTool} */ this.tool_ = null; @@ -218,7 +224,7 @@ * element. Dispatches a 'plugin-message' event containing the message from the * plugin, if a message type not handled by this controller is received. */ -class PluginController extends ContentController { +export class PluginController extends ContentController { /** * @param {!HTMLEmbedElement} plugin * @param {!Viewport} viewport @@ -246,7 +252,7 @@ 'message', e => this.handlePluginMessage_(e), false); /** @private {!EventTarget} */ - this.eventTarget_ = new cr.EventTarget(); + this.eventTarget_ = new EventTarget(); } /** @return {!EventTarget} */
diff --git a/chrome/browser/resources/pdf/elements/viewer-ink-host.js b/chrome/browser/resources/pdf/elements/viewer-ink-host.js index a9b474d..1de273f 100644 --- a/chrome/browser/resources/pdf/elements/viewer-ink-host.js +++ b/chrome/browser/resources/pdf/elements/viewer-ink-host.js
@@ -3,6 +3,8 @@ // found in the LICENSE file. import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {PDFMetrics} from '../metrics.js'; +import {Viewport} from '../viewport.js'; /** @enum {string} */ const State = {
diff --git a/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown.js b/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown.js index ceb2774..15c8b4e 100644 --- a/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown.js +++ b/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown.js
@@ -5,6 +5,7 @@ import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js'; import 'chrome://resources/cr_elements/icons.m.js'; import 'chrome://resources/cr_elements/shared_vars_css.m.js'; +import 'chrome://resources/polymer/v3_0/paper-styles/shadow.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
diff --git a/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar.js b/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar.js index 0b53527..4322f79 100644 --- a/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar.js +++ b/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar.js
@@ -9,6 +9,7 @@ import {assert} from 'chrome://resources/js/assert.m.js'; import {isRTL} from 'chrome://resources/js/util.m.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {FittingType} from '../pdf_fitting_type.js'; /** * @typedef {{
diff --git a/chrome/browser/resources/pdf/gesture_detector.js b/chrome/browser/resources/pdf/gesture_detector.js index 7c56d75..f149d80 100644 --- a/chrome/browser/resources/pdf/gesture_detector.js +++ b/chrome/browser/resources/pdf/gesture_detector.js
@@ -2,13 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -'use strict'; - /** * A class that listens for touch events and produces events when these * touches form gestures (e.g. pinching). */ -class GestureDetector { +export class GestureDetector { /** * @param {!Element} element The element to monitor for touch gestures. */ @@ -260,3 +258,7 @@ }; } } + +// Export on |window| such that scripts injected from pdf_extension_test.cc can +// access it. +window.GestureDetector = GestureDetector;
diff --git a/chrome/browser/resources/pdf/index.html b/chrome/browser/resources/pdf/index.html index a32f4d4..8a5ff5d 100644 --- a/chrome/browser/resources/pdf/index.html +++ b/chrome/browser/resources/pdf/index.html
@@ -2,13 +2,6 @@ <html> <head> <meta charset="utf-8"> - <script src="chrome://resources/js/assert.js"></script> - <script src="chrome://resources/js/promise_resolver.js"></script> - <script src="chrome://resources/js/load_time_data.js"></script> - <script src="chrome://resources/js/util.js"></script> - <script src="chrome://resources/js/cr.js"></script> - <script src="chrome://resources/js/cr/event_target.js"></script> - <script src="chrome://resources/js/event_tracker.js"></script> <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> <link rel="stylesheet" href="index.css"> @@ -33,17 +26,8 @@ <div id="content"></div> </body> -<script src="pdf_fitting_type.js"></script> -<script src="toolbar_manager.js"></script> -<script src="viewport.js"></script> -<script src="open_pdf_params_parser.js"></script> -<script src="navigator.js"></script> -<script src="viewport_scroller.js"></script> -<script src="zoom_manager.js"></script> -<script src="gesture_detector.js"></script> +<!-- TODO(crbug.com/1012574): Convert pdf_scripting_api.js to a JS module once + Print Preview has been migrated to JS modules as well --> <script src="pdf_scripting_api.js"></script> -<script src="browser_api.js"></script> -<script src="metrics.js"></script> -<script src="controller.js"></script> <script type="module" src="main.js"></script> </html>
diff --git a/chrome/browser/resources/pdf/main.js b/chrome/browser/resources/pdf/main.js index 427a1d5..0ea634e 100644 --- a/chrome/browser/resources/pdf/main.js +++ b/chrome/browser/resources/pdf/main.js
@@ -12,6 +12,8 @@ import './elements/viewer-ink-host.js'; import './elements/viewer-form-warning.js'; // </if> + +import {BrowserApi, createBrowserApi} from './browser_api.js'; import {PDFViewer} from './pdf_viewer.js'; /**
diff --git a/chrome/browser/resources/pdf/metrics.js b/chrome/browser/resources/pdf/metrics.js index d55c0d1..dc7f62a 100644 --- a/chrome/browser/resources/pdf/metrics.js +++ b/chrome/browser/resources/pdf/metrics.js
@@ -2,11 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {FittingType} from './pdf_fitting_type.js'; /** * Handles events specific to the PDF viewer and logs the corresponding metrics. */ -class PDFMetrics { +export class PDFMetrics { /** * Records when the zoom mode is changed to fit a FittingType. *
diff --git a/chrome/browser/resources/pdf/navigator.js b/chrome/browser/resources/pdf/navigator.js index d2e21dd..df4762a 100644 --- a/chrome/browser/resources/pdf/navigator.js +++ b/chrome/browser/resources/pdf/navigator.js
@@ -2,13 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -'use strict'; +import {OpenPdfParamsParser} from './open_pdf_params_parser.js'; +import {Viewport} from './viewport.js'; /** * NavigatorDelegate for calling browser-specific functions to do the actual * navigating. */ -class NavigatorDelegate { +export class NavigatorDelegate { /** * @param {number} tabId The tab ID of the PDF viewer or -1 if the viewer is * not displayed in a tab. @@ -63,7 +64,7 @@ } /** Navigator for navigating to links inside or outside the PDF. */ -class PdfNavigator { +export class PdfNavigator { /** * @param {string} originalUrl The original page URL. * @param {!Viewport} viewport The viewport info of the page. @@ -261,3 +262,7 @@ NEW_WINDOW: 6, SAVE_TO_DISK: 7 }; + +// Export on |window| such that scripts injected from pdf_extension_test.cc can +// access it. +window.PdfNavigator = PdfNavigator;
diff --git a/chrome/browser/resources/pdf/open_pdf_params_parser.js b/chrome/browser/resources/pdf/open_pdf_params_parser.js index c33c46b..941d9a3 100644 --- a/chrome/browser/resources/pdf/open_pdf_params_parser.js +++ b/chrome/browser/resources/pdf/open_pdf_params_parser.js
@@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -'use strict'; +import {FittingType} from './pdf_fitting_type.js'; /** * Parses the open pdf parameters passed in the url to set initial viewport * settings for opening the pdf. */ -class OpenPdfParamsParser { +export class OpenPdfParamsParser { /** * @param {function(string):void} getNamedDestinationCallback * Function called to fetch information for a named destination.
diff --git a/chrome/browser/resources/pdf/pdf_fitting_type.js b/chrome/browser/resources/pdf/pdf_fitting_type.js index f2d4eb63..7ff9bdb 100644 --- a/chrome/browser/resources/pdf/pdf_fitting_type.js +++ b/chrome/browser/resources/pdf/pdf_fitting_type.js
@@ -2,13 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -'use strict'; - /** * Enumeration of page fitting types. * @enum {string} */ -const FittingType = { +export const FittingType = { NONE: 'none', FIT_TO_PAGE: 'fit-to-page', FIT_TO_WIDTH: 'fit-to-width',
diff --git a/chrome/browser/resources/pdf/pdf_scripting_api.js b/chrome/browser/resources/pdf/pdf_scripting_api.js index 5957e13c..49c333d 100644 --- a/chrome/browser/resources/pdf/pdf_scripting_api.js +++ b/chrome/browser/resources/pdf/pdf_scripting_api.js
@@ -296,12 +296,12 @@ * * @param {string} src the source URL of the PDF to load initially. * @param {string} baseUrl the base URL of the PDF viewer - * @return {HTMLIFrameElement} the iframe element containing the PDF viewer. + * @return {!HTMLIFrameElement} the iframe element containing the PDF viewer. */ function PDFCreateOutOfProcessPlugin(src, baseUrl) { const client = new PDFScriptingAPI(window, null); - const iframe = assertInstanceof( - window.document.createElement('iframe'), HTMLIFrameElement); + const iframe = /** @type {!HTMLIFrameElement} */ ( + window.document.createElement('iframe')); iframe.setAttribute('src', baseUrl + '/index.html?' + src); iframe.onload = function() {
diff --git a/chrome/browser/resources/pdf/pdf_viewer.js b/chrome/browser/resources/pdf/pdf_viewer.js index dfc0e97..32083cc 100644 --- a/chrome/browser/resources/pdf/pdf_viewer.js +++ b/chrome/browser/resources/pdf/pdf_viewer.js
@@ -2,8 +2,25 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {assert, assertNotReached} from 'chrome://resources/js/assert.m.js'; +import {EventTracker} from 'chrome://resources/js/event_tracker.m.js'; +import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; +import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js'; +import {$, hasKeyModifiers, isRTL} from 'chrome://resources/js/util.m.js'; + +import {BrowserApi} from './browser_api.js'; +import {ContentController, InkController, MessageData, PluginController, PrintPreviewParams} from './controller.js'; import {Bookmark} from './elements/viewer-bookmark.js'; import {FitToChangedEvent} from './elements/viewer-zoom-toolbar.js'; +import {GestureDetector} from './gesture_detector.js'; +import {PDFMetrics} from './metrics.js'; +import {NavigatorDelegate, PdfNavigator} from './navigator.js'; +import {OpenPdfParamsParser} from './open_pdf_params_parser.js'; +import {FittingType} from './pdf_fitting_type.js'; +import {ToolbarManager} from './toolbar_manager.js'; +import {LayoutOptions, Point, Viewport} from './viewport.js'; +import {ViewportScroller} from './viewport_scroller.js'; +import {ZoomManager} from './zoom_manager.js'; /** * @typedef {{ @@ -1489,8 +1506,8 @@ } } -// Export PDFViewer on |window| such that scripts injected from -// pdf_extension_test.cc can access it. +// Export on |window| such that scripts injected from pdf_extension_test.cc can +// access it. window.PDFViewer = PDFViewer; /**
diff --git a/chrome/browser/resources/pdf/toolbar_manager.js b/chrome/browser/resources/pdf/toolbar_manager.js index bc9f905..f5ce7423 100644 --- a/chrome/browser/resources/pdf/toolbar_manager.js +++ b/chrome/browser/resources/pdf/toolbar_manager.js
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -'use strict'; +import {isRTL} from 'chrome://resources/js/util.m.js'; /** Idle time in ms before the UI is hidden. */ const HIDE_TIMEOUT = 2000; @@ -46,7 +46,7 @@ } /** Responsible for co-ordinating between multiple toolbar elements. */ -class ToolbarManager { +export class ToolbarManager { /** * @param {!Window} window The window containing the UI. * @param {?ViewerPdfToolbarElement} toolbar
diff --git a/chrome/browser/resources/pdf/viewport.js b/chrome/browser/resources/pdf/viewport.js index 17986ae5..0e76ca4 100644 --- a/chrome/browser/resources/pdf/viewport.js +++ b/chrome/browser/resources/pdf/viewport.js
@@ -2,6 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {assert} from 'chrome://resources/js/assert.m.js'; +import {EventTracker} from 'chrome://resources/js/event_tracker.m.js'; +import {$} from 'chrome://resources/js/util.m.js'; + +import {FittingType} from './pdf_fitting_type.js'; +import {InactiveZoomManager, ZoomManager} from './zoom_manager.js'; + /** * @typedef {{ * width: number, @@ -13,13 +20,13 @@ let DocumentDimensions; /** @typedef {{defaultPageOrientation: number}} */ -let LayoutOptions; +export let LayoutOptions; /** @typedef {{x: number, y: number}} */ -let Point; +export let Point; /** @typedef {{x: (number|undefined), y: (number|undefined)}} */ -let PartialPoint; +export let PartialPoint; /** @typedef {{width: number, height: number}} */ let Size; @@ -77,7 +84,7 @@ }; } -class Viewport { +export class Viewport { /** * @param {!Window} window * @param {!HTMLDivElement} sizer The element which represents the size of the
diff --git a/chrome/browser/resources/pdf/viewport_scroller.js b/chrome/browser/resources/pdf/viewport_scroller.js index ca16c9c..c0d8fe4 100644 --- a/chrome/browser/resources/pdf/viewport_scroller.js +++ b/chrome/browser/resources/pdf/viewport_scroller.js
@@ -2,15 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -'use strict'; - /** * Creates a new ViewportScroller. * A ViewportScroller scrolls the page in response to drag selection with the * mouse. * */ -class ViewportScroller { +export class ViewportScroller { /** * @param {Object} viewport The viewport info of the page. * @param {Object} plugin The PDF plugin element.
diff --git a/chrome/browser/resources/pdf/zoom_manager.js b/chrome/browser/resources/pdf/zoom_manager.js index db2878d..bb4e687e 100644 --- a/chrome/browser/resources/pdf/zoom_manager.js +++ b/chrome/browser/resources/pdf/zoom_manager.js
@@ -2,14 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -'use strict'; +import {NativeEventTarget as EventTarget} from 'chrome://resources/js/cr/event_target.m.js'; + +import {BrowserApi} from './browser_api.js'; /** * Abstract parent of classes that manage updating the browser * with zoom changes and/or updating the viewer's zoom when * the browser zoom changes. */ -class ZoomManager { +export class ZoomManager { /** * @param {function():number} getViewportZoom Callback to get the viewport's * current zoom level. @@ -27,7 +29,7 @@ this.getViewportZoom_ = getViewportZoom; /** @private {!EventTarget} */ - this.eventTarget_ = new cr.EventTarget(); + this.eventTarget_ = new EventTarget(); } /** @return {!EventTarget} */ @@ -111,7 +113,7 @@ * InactiveZoomManager has no control over the browser's zoom * and does not respond to browser zoom changes. */ -class InactiveZoomManager extends ZoomManager {} +export class InactiveZoomManager extends ZoomManager {} /** * ActiveZoomManager controls the browser's zoom.
diff --git a/chrome/browser/resources/settings/crostini_page/BUILD.gn b/chrome/browser/resources/settings/crostini_page/BUILD.gn index 2e4035e..1bd08b223 100644 --- a/chrome/browser/resources/settings/crostini_page/BUILD.gn +++ b/chrome/browser/resources/settings/crostini_page/BUILD.gn
@@ -6,6 +6,7 @@ js_type_check("closure_compile") { deps = [ + ":crostini_arc_adb", ":crostini_browser_proxy", ":crostini_export_import", ":crostini_page", @@ -15,6 +16,15 @@ ] } +js_library("crostini_arc_adb") { + deps = [ + ":crostini_browser_proxy", + "..:route", + "//ui/webui/resources/cr_elements/policy:cr_policy_indicator", + "//ui/webui/resources/js:web_ui_listener_behavior", + ] +} + js_library("crostini_browser_proxy") { deps = [ "//ui/webui/resources/js:cr",
diff --git a/chrome/browser/resources/settings/crostini_page/crostini_arc_adb.html b/chrome/browser/resources/settings/crostini_page/crostini_arc_adb.html new file mode 100644 index 0000000..3b4cd5b --- /dev/null +++ b/chrome/browser/resources/settings/crostini_page/crostini_arc_adb.html
@@ -0,0 +1,39 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> + +<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> +<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_indicator.html"> +<link rel="import" href="chrome://resources/html/i18n_behavior.html"> +<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> +<link rel="import" href="crostini_browser_proxy.html"> +<link rel="import" href="crostini_arc_adb_confirmation_dialog.html"> +<link rel="import" href="../i18n_setup.html"> +<link rel="import" href="../settings_shared_css.html"> + +<dom-module id="settings-crostini-arc-adb"> + <template> + <style include="settings-shared"></style> + <div class="settings-box first"> + <span>$i18n{crostiniArcAdbDescription}</span> + </div> + <div class="settings-box"> + <div id="enableArcAdbLabel" class="start"> + $i18n{crostiniArcAdbLabel} + </div> + <cr-policy-indicator indicator-type="[[getPolicyIndicatorType_( + isOwnerProfile_, isEnterpriseManaged_)]]"></cr-policy-indicator> + <cr-toggle id="arcAdbEnabledButton" aria-labelledby="enableArcAdbLabel" + checked$="[[arcAdbEnabled_]]" + disabled="[[shouldDisable_(isOwnerProfile_, isEnterpriseManaged_)]]" + on-change="onArcAdbToggleChanged_"> + </cr-toggle> + </div> + + <template is="dom-if" if="[[showConfirmationDialog_]]" restamp> + <settings-crostini-arc-adb-confirmation-dialog + action="[[getToggleAction_(arcAdbEnabled_)]]" + on-close="onConfirmationDialogClose_"> + </settings-crostini-arc-adb-confirmation-dialog> + </template> + </template> + <script src="crostini_arc_adb.js"></script> +</dom-module>
diff --git a/chrome/browser/resources/settings/crostini_page/crostini_arc_adb.js b/chrome/browser/resources/settings/crostini_page/crostini_arc_adb.js new file mode 100644 index 0000000..3665e26 --- /dev/null +++ b/chrome/browser/resources/settings/crostini_page/crostini_arc_adb.js
@@ -0,0 +1,91 @@ +// 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. + +/** + * @fileoverview + * 'crostini-arc-adb' is the ARC adb sideloading subpage for Crostini. + */ + +Polymer({ + is: 'settings-crostini-arc-adb', + + behaviors: [WebUIListenerBehavior], + + properties: { + /** @private {boolean} */ + arcAdbEnabled_: { + type: Boolean, + value: false, + }, + + /** @private {boolean} */ + isOwnerProfile_: { + type: Boolean, + value: function() { + return loadTimeData.getBoolean('isOwnerProfile'); + }, + }, + + /** @private {boolean} */ + isEnterpriseManaged_: { + type: Boolean, + value: function() { + return loadTimeData.getBoolean('isEnterpriseManaged'); + }, + }, + + /** @private {boolean} */ + showConfirmationDialog_: { + type: Boolean, + value: false, + }, + }, + + attached: function() { + this.addWebUIListener( + 'crostini-arc-adb-sideload-status-changed', (enabled) => { + this.arcAdbEnabled_ = enabled; + }); + settings.CrostiniBrowserProxyImpl.getInstance() + .requestArcAdbSideloadStatus(); + }, + + /** + * Returns whether the toggle is changeable to the user. Only the device owner + * is able to change it. Note that the actual guard should be in browser, + * otherwise a user may bypass this check by inspecting Settings with + * developer tool. + * @private + */ + shouldDisable_: function(isOwnerProfile, isEnterpriseManaged) { + return !isOwnerProfile || isEnterpriseManaged; + }, + + /** @private */ + getPolicyIndicatorType_: function(isOwnerProfile, isEnterpriseManaged) { + if (isEnterpriseManaged) { + return CrPolicyIndicatorType.DEVICE_POLICY; + } else if (!isOwnerProfile) { + return CrPolicyIndicatorType.OWNER; + } else { + return CrPolicyIndicatorType.NONE; + } + }, + + /** @private */ + getToggleAction_: function(arcAdbEnabled) { + return arcAdbEnabled ? 'disable' : 'enable'; + }, + + /** @private */ + onArcAdbToggleChanged_: function(event) { + this.showConfirmationDialog_ = true; + }, + + /** @private */ + onConfirmationDialogClose_: function() { + this.showConfirmationDialog_ = false; + this.$.arcAdbEnabledButton.checked = this.arcAdbEnabled_; + }, +});
diff --git a/chrome/browser/resources/settings/crostini_page/crostini_arc_adb_confirmation_dialog.html b/chrome/browser/resources/settings/crostini_page/crostini_arc_adb_confirmation_dialog.html new file mode 100644 index 0000000..664f85c --- /dev/null +++ b/chrome/browser/resources/settings/crostini_page/crostini_arc_adb_confirmation_dialog.html
@@ -0,0 +1,36 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> + +<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> +<link rel="import" href="chrome://resources/html/i18n_behavior.html"> +<link rel="import" href="crostini_browser_proxy.html"> +<link rel="import" href="../settings_shared_css.html"> + +<dom-module id="settings-crostini-arc-adb-confirmation-dialog"> + <template> + <style include="settings-shared"></style> + <cr-dialog id="dialog" close-text="$i18n{close}"> + <div slot="title" hidden="[[!isEnabling_(action)]]"> + $i18n{crostiniArcAdbConfirmationTitleEnable} + </div> + <div slot="title" hidden="[[!isDisabling_(action)]]"> + $i18n{crostiniArcAdbConfirmationTitleDisable} + </div> + <div slot="body" hidden="[[!isEnabling_(action)]]"> + $i18n{crostiniArcAdbConfirmationMessageEnable} + </div> + <div slot="body" hidden="[[!isDisabling_(action)]]"> + $i18n{crostiniArcAdbConfirmationMessageDisable} + </div> + <div slot="button-container"> + <cr-button id="cancel" class="cancel-button" on-click="onCancelTap_"> + $i18n{cancel} + </cr-button> + <cr-button id="continue" class="action-button" on-click="onRestartTap_"> + $i18n{crostiniArcAdbRestartButton} + </cr-button> + </div> + </cr-dialog> + </template> + <script src="crostini_arc_adb_confirmation_dialog.js"></script> +</dom-module>
diff --git a/chrome/browser/resources/settings/crostini_page/crostini_arc_adb_confirmation_dialog.js b/chrome/browser/resources/settings/crostini_page/crostini_arc_adb_confirmation_dialog.js new file mode 100644 index 0000000..6b64eb55 --- /dev/null +++ b/chrome/browser/resources/settings/crostini_page/crostini_arc_adb_confirmation_dialog.js
@@ -0,0 +1,50 @@ +// 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. + +/** + * @fileoverview 'settings-crostini-arc-adb-confirmation-dialog' is a component + * to confirm for enabling or disabling adb sideloading. After the confirmation, + * reboot will happens. + */ +Polymer({ + is: 'settings-crostini-arc-adb-confirmation-dialog', + + properties: { + /** An attribute that indicates the action for the confirmation */ + action: { + type: String, + }, + }, + + /** @override */ + attached: function() { + this.$.dialog.showModal(); + }, + + /** @override */ + isEnabling_: function() { + return this.action === 'enable'; + }, + + /** @override */ + isDisabling_: function() { + return this.action === 'disable'; + }, + + /** @private */ + onCancelTap_: function() { + this.$.dialog.close(); + }, + + /** @private */ + onRestartTap_: function() { + if (this.isEnabling_()) { + settings.CrostiniBrowserProxyImpl.getInstance().enableArcAdbSideload(); + } else if (this.isDisabling_()) { + settings.CrostiniBrowserProxyImpl.getInstance().disableArcAdbSideload(); + } else { + assertNotReached(); + } + }, +});
diff --git a/chrome/browser/resources/settings/crostini_page/crostini_browser_proxy.js b/chrome/browser/resources/settings/crostini_page/crostini_browser_proxy.js index f9b965ea..3bd9508e 100644 --- a/chrome/browser/resources/settings/crostini_page/crostini_browser_proxy.js +++ b/chrome/browser/resources/settings/crostini_page/crostini_browser_proxy.js
@@ -72,6 +72,15 @@ * Import crostini container. */ importCrostiniContainer() {} + + /** Queries the current status of ARC ADB Sideloading. */ + requestArcAdbSideloadStatus() {} + + /** Initiates the flow to enable ARC ADB Sideloading. */ + enableArcAdbSideload() {} + + /** Initiates the flow to disable ARC ADB Sideloading. */ + disableArcAdbSideload() {} } /** @implements {settings.CrostiniBrowserProxy} */ @@ -125,6 +134,21 @@ importCrostiniContainer() { chrome.send('importCrostiniContainer'); } + + /** @override */ + requestArcAdbSideloadStatus() { + chrome.send('requestArcAdbSideloadStatus'); + } + + /** @override */ + enableArcAdbSideload() { + chrome.send('enableArcAdbSideload'); + } + + /** @override */ + disableArcAdbSideload() { + chrome.send('disableArcAdbSideload'); + } } // The singleton instance_ can be replaced with a test version of this wrapper
diff --git a/chrome/browser/resources/settings/crostini_page/crostini_page.html b/chrome/browser/resources/settings/crostini_page/crostini_page.html index d241d5ba..85004114 100644 --- a/chrome/browser/resources/settings/crostini_page/crostini_page.html +++ b/chrome/browser/resources/settings/crostini_page/crostini_page.html
@@ -9,6 +9,7 @@ <link rel="import" href="../settings_page/settings_animated_pages.html"> <link rel="import" href="../settings_page/settings_subpage.html"> <link rel="import" href="../settings_shared_css.html"> +<link rel="import" href="crostini_arc_adb.html"> <link rel="import" href="crostini_browser_proxy.html"> <link rel="import" href="crostini_export_import.html"> <link rel="import" href="crostini_shared_paths.html"> @@ -62,6 +63,15 @@ </settings-subpage> </template> + <template is="dom-if" route-path="/crostini/androidAdb"> + <settings-subpage + associated-control="[[$$('#crostini')]]" + page-title="$i18n{crostiniArcAdbTitle}"> + <settings-crostini-arc-adb prefs="{{prefs}}"> + </settings-crostini-arc-adb> + </settings-subpage> + </template> + <template is="dom-if" route-path="/crostini/exportImport"> <settings-subpage associated-control="[[$$('#crostini')]]"
diff --git a/chrome/browser/resources/settings/crostini_page/crostini_subpage.html b/chrome/browser/resources/settings/crostini_page/crostini_subpage.html index c77f616..5465713 100644 --- a/chrome/browser/resources/settings/crostini_page/crostini_subpage.html +++ b/chrome/browser/resources/settings/crostini_page/crostini_subpage.html
@@ -31,6 +31,14 @@ on-click="onExportImportClick_"> </cr-link-row> </template> + <template is="dom-if" if="[[showArcAdbSideloading_]]"> + <cr-link-row + class="hr" + label="$i18n{crostiniArcAdbTitle}" + id="crostini-enable-arc-adb" + on-click="onEnableArcAdbClick_"> + </cr-link-row> + </template> <template is="dom-if" if="[[!hideCrostiniUninstall_]]"> <div id="remove" class="settings-box"> <div id="removeCrostiniLabel" class="start">$i18n{crostiniRemove}</div>
diff --git a/chrome/browser/resources/settings/crostini_page/crostini_subpage.js b/chrome/browser/resources/settings/crostini_page/crostini_subpage.js index 66d8ca13f..16a18df7 100644 --- a/chrome/browser/resources/settings/crostini_page/crostini_subpage.js +++ b/chrome/browser/resources/settings/crostini_page/crostini_subpage.js
@@ -30,6 +30,25 @@ }, }, + /** @private {boolean} */ + showArcAdbSideloading_: { + type: Boolean, + computed: 'and_(isArcAdbSideloadingSupported_, isAndroidEnabled_)', + }, + + /** @private {boolean} */ + isArcAdbSideloadingSupported_: { + type: Boolean, + value: function() { + return loadTimeData.getBoolean('ArcAdbSideloadingSupported'); + }, + }, + + /** @private {boolean} */ + isAndroidEnabled_: { + type: Boolean, + }, + /** * Whether the uninstall options should be displayed. * @private {boolean} @@ -39,7 +58,10 @@ }, }, - observers: ['onCrostiniEnabledChanged_(prefs.crostini.enabled.value)'], + observers: [ + 'onCrostiniEnabledChanged_(prefs.crostini.enabled.value)', + 'onArcEnabledChanged_(prefs.arc.enabled.value)' + ], attached: function() { const callback = (status) => { @@ -59,10 +81,20 @@ }, /** @private */ + onArcEnabledChanged_: function(enabled) { + this.isAndroidEnabled_ = enabled; + }, + + /** @private */ onExportImportClick_: function() { settings.navigateTo(settings.routes.CROSTINI_EXPORT_IMPORT); }, + /** @private */ + onEnableArcAdbClick_: function() { + settings.navigateTo(settings.routes.CROSTINI_ANDROID_ADB); + }, + /** * Shows a confirmation dialog when removing crostini. * @private @@ -80,4 +112,9 @@ onSharedUsbDevicesClick_: function() { settings.navigateTo(settings.routes.CROSTINI_SHARED_USB_DEVICES); }, + + /** @private */ + and_: function(a, b) { + return a && b; + }, });
diff --git a/chrome/browser/resources/settings/os_settings_resources.grd b/chrome/browser/resources/settings/os_settings_resources.grd index 9d683c7..776139a 100644 --- a/chrome/browser/resources/settings/os_settings_resources.grd +++ b/chrome/browser/resources/settings/os_settings_resources.grd
@@ -1147,6 +1147,18 @@ <structure name="IDR_OS_SETTINGS_CROSTINI_SUBPAGE_JS" file="crostini_page/crostini_subpage.js" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_CROSTINI_ARC_ADB_HTML" + file="crostini_page/crostini_arc_adb.html" + type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_CROSTINI_ARC_ADB_JS" + file="crostini_page/crostini_arc_adb.js" + type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_CROSTINI_ARC_ADB_CONFIRMATION_DIALOG_HTML" + file="crostini_page/crostini_arc_adb_confirmation_dialog.html" + type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_CROSTINI_ARC_ADB_CONFIRMATION_DIALOG_JS" + file="crostini_page/crostini_arc_adb_confirmation_dialog.js" + type="chrome_html" /> <structure name="IDR_OS_SETTINGS_CROSTINI_EXPORT_IMPORT_HTML" file="crostini_page/crostini_export_import.html" type="chrome_html" />
diff --git a/chrome/browser/resources/settings/route.js b/chrome/browser/resources/settings/route.js index 4084819..9c6b8150 100644 --- a/chrome/browser/resources/settings/route.js +++ b/chrome/browser/resources/settings/route.js
@@ -19,6 +19,7 @@ * ANDROID_APPS: (undefined|!settings.Route), * ANDROID_APPS_DETAILS: (undefined|!settings.Route), * CROSTINI: (undefined|!settings.Route), + * CROSTINI_ANDROID_ADB: (undefined|!settings.Route), * CROSTINI_DETAILS: (undefined|!settings.Route), * CROSTINI_EXPORT_IMPORT: (undefined|!settings.Route), * CROSTINI_SHARED_PATHS: (undefined|!settings.Route), @@ -471,6 +472,7 @@ if (loadTimeData.valueExists('showCrostini') && loadTimeData.getBoolean('showCrostini')) { r.CROSTINI = r.BASIC.createSection('/crostini', 'crostini'); + r.CROSTINI_ANDROID_ADB = r.CROSTINI.createChild('/crostini/androidAdb'); r.CROSTINI_DETAILS = r.CROSTINI.createChild('/crostini/details'); if (loadTimeData.valueExists('showCrostiniExportImport') && loadTimeData.getBoolean('showCrostiniExportImport')) {
diff --git a/chrome/browser/resources/settings/settings_resources.grd b/chrome/browser/resources/settings/settings_resources.grd index ea0b1a10..42e999f 100644 --- a/chrome/browser/resources/settings/settings_resources.grd +++ b/chrome/browser/resources/settings/settings_resources.grd
@@ -1362,6 +1362,18 @@ <structure name="IDR_SETTINGS_CROSTINI_SUBPAGE_JS" file="crostini_page/crostini_subpage.js" type="chrome_html" /> + <structure name="IDR_SETTINGS_CROSTINI_ARC_ADB_HTML" + file="crostini_page/crostini_arc_adb.html" + type="chrome_html" /> + <structure name="IDR_SETTINGS_CROSTINI_ARC_ADB_JS" + file="crostini_page/crostini_arc_adb.js" + type="chrome_html" /> + <structure name="IDR_SETTINGS_CROSTINI_ARC_ADB_CONFIRMATION_DIALOG_HTML" + file="crostini_page/crostini_arc_adb_confirmation_dialog.html" + type="chrome_html" /> + <structure name="IDR_SETTINGS_CROSTINI_ARC_ADB_CONFIRMATION_DIALOG_JS" + file="crostini_page/crostini_arc_adb_confirmation_dialog.js" + type="chrome_html" /> <structure name="IDR_SETTINGS_CROSTINI_EXPORT_IMPORT_HTML" file="crostini_page/crostini_export_import.html" type="chrome_html" />
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate.cc b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate.cc index e681532..9ef146d 100644 --- a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate.cc +++ b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate.cc
@@ -434,8 +434,8 @@ // policy::BrowserDMTokenStorage::Get()->RetrieveDMToken() does not return a // valid token either. Once these are fixed the #if !defined can be removed. - if (dm_token.empty() && policy::ChromeBrowserCloudManagementController:: - IsMachineLevelUserCloudPolicyEnabled()) { + if (dm_token.empty() && + policy::ChromeBrowserCloudManagementController::IsEnabled()) { dm_token = policy::BrowserDMTokenStorage::Get()->RetrieveDMToken(); } #endif
diff --git a/chrome/browser/safe_browsing/download_protection/binary_upload_service.cc b/chrome/browser/safe_browsing/download_protection/binary_upload_service.cc index 8545ac1..a815dec8 100644 --- a/chrome/browser/safe_browsing/download_protection/binary_upload_service.cc +++ b/chrome/browser/safe_browsing/download_protection/binary_upload_service.cc
@@ -20,6 +20,7 @@ #include "components/prefs/pref_service.h" #include "components/safe_browsing/common/safe_browsing_prefs.h" #include "components/safe_browsing/proto/webprotect.pb.h" +#include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "net/http/http_status_code.h" @@ -56,8 +57,11 @@ active_requests_[raw_request] = std::move(request); if (!binary_fcm_service_) { - FinishRequest(raw_request, Result::FAILED_TO_GET_TOKEN, - DeepScanningClientResponse()); + base::PostTask(FROM_HERE, {content::BrowserThread::UI}, + base::BindOnce(&BinaryUploadService::FinishRequest, + weakptr_factory_.GetWeakPtr(), raw_request, + Result::FAILED_TO_GET_TOKEN, + DeepScanningClientResponse())); return; }
diff --git a/chrome/browser/safe_browsing/download_protection/binary_upload_service_unittest.cc b/chrome/browser/safe_browsing/download_protection/binary_upload_service_unittest.cc index 668514c..21629f4 100644 --- a/chrome/browser/safe_browsing/download_protection/binary_upload_service_unittest.cc +++ b/chrome/browser/safe_browsing/download_protection/binary_upload_service_unittest.cc
@@ -359,4 +359,26 @@ EXPECT_EQ(scanning_result, BinaryUploadService::Result::SUCCESS); } +TEST_F(BinaryUploadServiceTest, ReturnsAsynchronouslyWithNoFCM) { + // Instantiate a BinaryUploadService with no FCM connection. + BinaryUploadService service(nullptr, + std::unique_ptr<BinaryFCMService>(nullptr)); + + BinaryUploadService::Result scanning_result = + BinaryUploadService::Result::UNKNOWN; + DeepScanningClientResponse scanning_response; + std::unique_ptr<MockRequest> request = + MakeRequest(&scanning_result, &scanning_response); + request->set_request_dlp_scan(DlpDeepScanningClientRequest()); + request->set_request_malware_scan(MalwareDeepScanningClientRequest()); + + service.UploadForDeepScanning(std::move(request)); + + EXPECT_EQ(scanning_result, BinaryUploadService::Result::UNKNOWN); + + content::RunAllTasksUntilIdle(); + + EXPECT_EQ(scanning_result, BinaryUploadService::Result::FAILED_TO_GET_TOKEN); +} + } // namespace safe_browsing
diff --git a/chrome/browser/shell_integration.h b/chrome/browser/shell_integration.h index fdb4c9d..c4e6687 100644 --- a/chrome/browser/shell_integration.h +++ b/chrome/browser/shell_integration.h
@@ -96,6 +96,13 @@ // Returns true if IE is likely to be the default browser for the current // user. This method is very fast so it can be invoked in the UI thread. bool IsIEDefaultBrowser(); + +// Returns the install id of the installation set as default browser. If no +// installation of Firefox is set as the default browser, returns an empty +// string. +// TODO(crbug/1011830): This should return the install id of the stable +// version if no version of Firefox is set as default browser. +std::string GetFirefoxProgIdSuffix(); #endif // Attempt to determine if this instance of Chrome is the default client
diff --git a/chrome/browser/shell_integration_win.cc b/chrome/browser/shell_integration_win.cc index 23dd8287..94069792 100644 --- a/chrome/browser/shell_integration_win.cc +++ b/chrome/browser/shell_integration_win.cc
@@ -502,6 +502,15 @@ win::MigrateShortcutsInPathInternal(chrome_proxy_path, shortcut_path); } +base::string16 GetHttpProtocolUserChoiceProgId() { + base::string16 prog_id; + base::win::RegKey key(HKEY_CURRENT_USER, ShellUtil::kRegVistaUrlPrefs, + KEY_QUERY_VALUE); + if (key.Valid()) + key.ReadValue(L"ProgId", &prog_id); + return prog_id; +} + } // namespace bool SetAsDefaultBrowser() { @@ -579,31 +588,28 @@ ShellUtil::GetChromeDefaultState()); } -// There is no reliable way to say which browser is default on a machine (each -// browser can have some of the protocols/shortcuts). So we look for only HTTP -// protocol handler. Even this handler is located at different places in -// registry on XP and Vista: -// - HKCR\http\shell\open\command (XP) -// - HKCU\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\ -// http\UserChoice (Vista) -// This method checks if Firefox is default browser by checking these -// locations and returns true if Firefox traces are found there. In case of -// error (or if Firefox is not found)it returns the default value which -// is false. +// This method checks if Firefox is default browser by checking for the default +// HTTP protocol handler. Returns false in case of error or if Firefox is not +// the user's default http protocol client. bool IsFirefoxDefaultBrowser() { - base::string16 app_cmd; - base::win::RegKey key(HKEY_CURRENT_USER, ShellUtil::kRegVistaUrlPrefs, - KEY_READ); - return key.Valid() && key.ReadValue(L"Progid", &app_cmd) == ERROR_SUCCESS && - app_cmd == L"FirefoxURL"; + return base::StartsWith(GetHttpProtocolUserChoiceProgId(), L"FirefoxURL", + base::CompareCase::SENSITIVE); +} + +std::string GetFirefoxProgIdSuffix() { + const base::string16 app_cmd = GetHttpProtocolUserChoiceProgId(); + static constexpr base::StringPiece16 kFirefoxProgIdPrefix(L"FirefoxURL-"); + if (base::StartsWith(app_cmd, kFirefoxProgIdPrefix, + base::CompareCase::SENSITIVE)) { + // Returns the id that appears after the prefix "FirefoxURL-". + return std::string(app_cmd.begin() + kFirefoxProgIdPrefix.size(), + app_cmd.end()); + } + return std::string(); } bool IsIEDefaultBrowser() { - base::string16 app_cmd; - base::win::RegKey key(HKEY_CURRENT_USER, ShellUtil::kRegVistaUrlPrefs, - KEY_READ); - return key.Valid() && key.ReadValue(L"Progid", &app_cmd) == ERROR_SUCCESS && - app_cmd == L"IE.HTTP"; + return GetHttpProtocolUserChoiceProgId() == L"IE.HTTP"; } DefaultWebClientState IsDefaultProtocolClient(const std::string& protocol) {
diff --git a/chrome/browser/site_isolation/site_per_process_text_input_browsertest.cc b/chrome/browser/site_isolation/site_per_process_text_input_browsertest.cc index 8c4c64e..facccc7 100644 --- a/chrome/browser/site_isolation/site_per_process_text_input_browsertest.cc +++ b/chrome/browser/site_isolation/site_per_process_text_input_browsertest.cc
@@ -1134,6 +1134,14 @@ // |TextInputState.show_ime_if_needed| is true. This should happen even when // the TextInputState has not changed (according to the platform), e.g., in // aura when receiving two consecutive updates with same |TextInputState.type|. + +// This test is disabled on Windows because we have removed TryShow/TryHide API +// calls and replaced it with TSF input pane policy which is a policy applied by +// text service framework on Windows based on whether TSF edit control has focus +// or not. On Windows we have implemented TSF1 on Chromium that takes care of +// IME compositions, handwriting panels, SIP visibility etc. Please see +// (https://crbug.com/1007958) for more details. +#if !defined(OS_WIN) IN_PROC_BROWSER_TEST_F(SitePerProcessTextInputManagerTest, CorrectlyShowVirtualKeyboardIfEnabled) { // We only need the <iframe> page to create RWHV. @@ -1159,9 +1167,6 @@ // Set |TextInputState.show_ime_if_needed| to true. Expect IME. sender.SetShowVirtualKeyboardIfEnabled(true); -#if defined(OS_WIN) - sender.SetLastPointerType(ui::EventPointerType::POINTER_TYPE_TOUCH); -#endif EXPECT_TRUE(send_and_check_show_ime()); // Send the same message. Expect IME (no change). @@ -1179,16 +1184,12 @@ sender.SetShowVirtualKeyboardIfEnabled(true); EXPECT_TRUE(send_and_check_show_ime()); -#if defined(OS_WIN) - // Set input type to mouse. Expect no IME. - sender.SetLastPointerType(ui::EventPointerType::POINTER_TYPE_MOUSE); - EXPECT_FALSE(send_and_check_show_ime()); -#endif - // Set |TextInputState.type| to ui::TEXT_INPUT_TYPE_NONE. Expect no IME. sender.SetType(ui::TEXT_INPUT_TYPE_NONE); EXPECT_FALSE(send_and_check_show_ime()); } +#endif // OS_WIN + #endif // USE_AURA // Ensure that a cross-process subframe can utilize keyboard edit commands.
diff --git a/chrome/browser/ssl/security_state_tab_helper.cc b/chrome/browser/ssl/security_state_tab_helper.cc index 9759e20..2018203 100644 --- a/chrome/browser/ssl/security_state_tab_helper.cc +++ b/chrome/browser/ssl/security_state_tab_helper.cc
@@ -179,6 +179,9 @@ UMA_HISTOGRAM_ENUMERATION( "Security.SafetyTips.FormSubmission", GetVisibleSecurityState()->safety_tip_info.status); + UMA_HISTOGRAM_BOOLEAN( + "Security.LegacyTLS.FormSubmission", + GetLegacyTLSWarningStatus(*GetVisibleSecurityState())); } }
diff --git a/chrome/browser/ssl/security_state_tab_helper_unittest.cc b/chrome/browser/ssl/security_state_tab_helper_unittest.cc index a305b64..9ffc27a 100644 --- a/chrome/browser/ssl/security_state_tab_helper_unittest.cc +++ b/chrome/browser/ssl/security_state_tab_helper_unittest.cc
@@ -8,10 +8,12 @@ #include "base/command_line.h" #include "base/test/metrics/histogram_tester.h" +#include "chrome/browser/ssl/tls_deprecation_test_utils.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "components/security_state/content/ssl_status_input_event_data.h" #include "content/public/browser/navigation_entry.h" #include "content/public/test/mock_navigation_handle.h" +#include "content/public/test/navigation_simulator.h" #include "testing/gtest/include/gtest/gtest.h" namespace { @@ -80,4 +82,52 @@ security_state::WARNING, 1); } +// Tests that form submission histograms are recorded correctly on a page that +// uses legacy TLS (TLS 1.0/1.1). +TEST_F(SecurityStateTabHelperHistogramTest, LegacyTLSFormSubmissionHistogram) { + base::HistogramTester histograms; + InitializeEmptyLegacyTLSConfig(); + + auto navigation = + CreateLegacyTLSNavigation(GURL(kLegacyTLSDefaultURL), web_contents()); + navigation->Commit(); + + StartFormSubmissionNavigation(); + + histograms.ExpectUniqueSample("Security.LegacyTLS.FormSubmission", true, 1); +} + +// Tests that form submission histograms are recorded as not coming from a page +// that triggered legacy TLS warnings for a page that uses legacy TLS but is +// marked as a control site that should suppress legacy TLS warnings. +TEST_F(SecurityStateTabHelperHistogramTest, + LegacyTLSControlSiteFormSubmissionHistogram) { + base::HistogramTester histograms; + InitializeLegacyTLSConfigWithControl(); + + auto navigation = + CreateLegacyTLSNavigation(GURL(kLegacyTLSControlURL), web_contents()); + navigation->Commit(); + + StartFormSubmissionNavigation(); + + histograms.ExpectUniqueSample("Security.LegacyTLS.FormSubmission", false, 1); +} + +// Tests that form submission histograms are recorded as not coming from a page +// that triggered legacy TLS warnings for a page that uses modern TLS. +TEST_F(SecurityStateTabHelperHistogramTest, + LegacyTLSGoodSiteFormSubmissionHistogram) { + base::HistogramTester histograms; + InitializeEmptyLegacyTLSConfig(); + + auto navigation = + CreateNonlegacyTLSNavigation(GURL("https://good.test"), web_contents()); + navigation->Commit(); + + StartFormSubmissionNavigation(); + + histograms.ExpectUniqueSample("Security.LegacyTLS.FormSubmission", false, 1); +} + } // namespace
diff --git a/chrome/browser/ui/app_list/test/chrome_app_list_test_support.cc b/chrome/browser/ui/app_list/test/chrome_app_list_test_support.cc index 28ccb7f6..81525eec 100644 --- a/chrome/browser/ui/app_list/test/chrome_app_list_test_support.cc +++ b/chrome/browser/ui/app_list/test/chrome_app_list_test_support.cc
@@ -26,38 +26,6 @@ namespace { -class CreateProfileHelper { - public: - CreateProfileHelper() : profile_(NULL) {} - - Profile* CreateAsync() { - ProfileManager* profile_manager = g_browser_process->profile_manager(); - base::FilePath temp_profile_dir = - profile_manager->user_data_dir().AppendASCII("Profile 1"); - profile_manager->CreateProfileAsync( - temp_profile_dir, - base::Bind(&CreateProfileHelper::OnProfileCreated, - base::Unretained(this)), - base::string16(), - std::string()); - run_loop_.Run(); - return profile_; - } - - private: - void OnProfileCreated(Profile* profile, Profile::CreateStatus status) { - if (status == Profile::CREATE_STATUS_INITIALIZED) { - profile_ = profile; - run_loop_.Quit(); - } - } - - base::RunLoop run_loop_; - Profile* profile_; - - DISALLOW_COPY_AND_ASSIGN(CreateProfileHelper); -}; - // Create the icon image for the app-item with |id|. // TODO(mukai): consolidate the implementation with // ash/app_list/test/app_list_test_model.cc. @@ -84,11 +52,6 @@ return client; } -Profile* CreateSecondProfileAsync() { - CreateProfileHelper helper; - return helper.CreateAsync(); -} - void PopulateDummyAppListItems(int n) { AppListClientImpl* client = GetAppListClient(); Profile* profile = client->GetCurrentAppListProfile();
diff --git a/chrome/browser/ui/ash/app_list/OWNERS b/chrome/browser/ui/ash/app_list/OWNERS deleted file mode 100644 index 403dd3f..0000000 --- a/chrome/browser/ui/ash/app_list/OWNERS +++ /dev/null
@@ -1,3 +0,0 @@ -calamity@chromium.org -khmel@chromium.org -xiyuan@chromium.org
diff --git a/chrome/browser/ui/ash/assistant/proactive_suggestions_client_impl.cc b/chrome/browser/ui/ash/assistant/proactive_suggestions_client_impl.cc index 73d799c3..1d7bd8f 100644 --- a/chrome/browser/ui/ash/assistant/proactive_suggestions_client_impl.cc +++ b/chrome/browser/ui/ash/assistant/proactive_suggestions_client_impl.cc
@@ -174,7 +174,8 @@ // The previous set of proactive suggestions is no longer valid. SetActiveProactiveSuggestions(nullptr); - if (active_url_.is_empty()) { + // We only load proactive suggestions for http/https schemes. + if (!url.is_valid() || !url.SchemeIsHTTPOrHTTPS()) { loader_.reset(); return; }
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc index 115727a..e8e7fb8 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc
@@ -111,16 +111,6 @@ return SelectShelfItem(id, event_type, display_id); } -class TestEvent : public ui::Event { - public: - explicit TestEvent(ui::EventType type) - : ui::Event(type, base::TimeTicks(), 0) {} - ~TestEvent() override {} - - private: - DISALLOW_COPY_AND_ASSIGN(TestEvent); -}; - // Find the browser that associated with |app_name|. Browser* FindBrowserForApp(const std::string& app_name) { for (auto* browser : *BrowserList::GetInstance()) { @@ -219,17 +209,6 @@ DISALLOW_COPY_AND_ASSIGN(LauncherPlatformAppBrowserTest); }; -enum RipOffCommand { - // Drag the item off the shelf and let the mouse go. - RIP_OFF_ITEM, - // Drag the item off the shelf, move the mouse back and then let go. - RIP_OFF_ITEM_AND_RETURN, - // Drag the item off the shelf and then issue a cancel command. - RIP_OFF_ITEM_AND_CANCEL, - // Drag the item off the shelf and do not release the mouse. - RIP_OFF_ITEM_AND_DONT_RELEASE_MOUSE, -}; - class ShelfAppBrowserTest : public extensions::ExtensionBrowserTest { protected: ShelfAppBrowserTest() {} @@ -286,10 +265,6 @@ return item.id; } - ash::ShelfID PinFakeApp(const std::string& app_id) { - return controller_->CreateAppShortcutLauncherItem( - ash::ShelfID(app_id), shelf_model()->item_count()); - } // Get the index of an item which has the given type. int GetIndexOfShelfItemType(ash::ShelfItemType type) {
diff --git a/chrome/browser/ui/page_info/page_info.cc b/chrome/browser/ui/page_info/page_info.cc index 6bd0665..44b18cf 100644 --- a/chrome/browser/ui/page_info/page_info.cc +++ b/chrome/browser/ui/page_info/page_info.cc
@@ -343,6 +343,7 @@ did_revoke_user_ssl_decisions_(false), profile_(profile), security_level_(security_state::NONE), + visible_security_state_for_metrics_(visible_security_state), #if BUILDFLAG(FULL_SAFE_BROWSING) password_protection_service_( safe_browsing::ChromePasswordProtectionService:: @@ -390,6 +391,11 @@ safety_tip_info_.status), base::TimeTicks::Now() - start_time_, base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromHours(1), 100); + base::UmaHistogramCustomTimes( + security_state::GetLegacyTLSHistogramName( + kPageInfoTimePrefix, visible_security_state_for_metrics_), + base::TimeTicks::Now() - start_time_, + base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromHours(1), 100); if (did_perform_action_) { base::UmaHistogramCustomTimes( @@ -404,6 +410,12 @@ base::TimeTicks::Now() - start_time_, base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromHours(1), 100); + base::UmaHistogramCustomTimes( + security_state::GetLegacyTLSHistogramName( + kPageInfoTimeActionPrefix, visible_security_state_for_metrics_), + base::TimeTicks::Now() - start_time_, + base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromHours(1), + 100); } else { base::UmaHistogramCustomTimes( security_state::GetSecurityLevelHistogramName( @@ -417,12 +429,19 @@ base::TimeTicks::Now() - start_time_, base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromHours(1), 100); + base::UmaHistogramCustomTimes( + security_state::GetLegacyTLSHistogramName( + kPageInfoTimeNoActionPrefix, visible_security_state_for_metrics_), + base::TimeTicks::Now() - start_time_, + base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromHours(1), + 100); } } void PageInfo::UpdateSecurityState( security_state::SecurityLevel security_level, const security_state::VisibleSecurityState& visible_security_state) { + visible_security_state_for_metrics_ = visible_security_state; ComputeUIInputs(site_url_, security_level, visible_security_state); PresentSiteIdentity(); } @@ -438,6 +457,11 @@ "Security.SafetyTips.PageInfo.Action", safety_tip_info_.status), action, PAGE_INFO_COUNT); + base::UmaHistogramEnumeration(security_state::GetLegacyTLSHistogramName( + "Security.LegacyTLS.PageInfo.Action", + visible_security_state_for_metrics_), + action, PAGE_INFO_COUNT); + std::string histogram_name; if (site_url_.SchemeIsCryptographic()) { if (security_level_ == security_state::SECURE) {
diff --git a/chrome/browser/ui/page_info/page_info.h b/chrome/browser/ui/page_info/page_info.h index 96d6d6d..2cafe15 100644 --- a/chrome/browser/ui/page_info/page_info.h +++ b/chrome/browser/ui/page_info/page_info.h
@@ -329,6 +329,8 @@ security_state::SecurityLevel security_level_; + security_state::VisibleSecurityState visible_security_state_for_metrics_; + #if BUILDFLAG(FULL_SAFE_BROWSING) // Used to handle changing password, and whitelisting site. safe_browsing::ChromePasswordProtectionService* password_protection_service_;
diff --git a/chrome/browser/ui/page_info/page_info_unittest.cc b/chrome/browser/ui/page_info/page_info_unittest.cc index 31199e0..8f2416f 100644 --- a/chrome/browser/ui/page_info/page_info_unittest.cc +++ b/chrome/browser/ui/page_info/page_info_unittest.cc
@@ -21,6 +21,7 @@ #include "chrome/browser/infobars/mock_infobar_service.h" #include "chrome/browser/ssl/chrome_ssl_host_state_delegate.h" #include "chrome/browser/ssl/chrome_ssl_host_state_delegate_factory.h" +#include "chrome/browser/ssl/tls_deprecation_test_utils.h" #include "chrome/browser/ui/page_info/page_info_ui.h" #include "chrome/browser/usb/usb_chooser_context.h" #include "chrome/browser/usb/usb_chooser_context_factory.h" @@ -1262,6 +1263,122 @@ page_info(); } +// Tests that metrics are recorded on a PageInfo for pages with +// various Legacy TLS statuses. +TEST_F(PageInfoTest, LegacyTLSMetrics) { + const struct TestCase { + const bool connection_used_legacy_tls; + const bool should_suppress_legacy_tls_warning; + const std::string histogram_suffix; + } kTestCases[] = { + {true, false, "LegacyTLS_Triggered"}, + {true, true, "LegacyTLS_NotTriggered"}, + {false, false, "LegacyTLS_NotTriggered"}, + }; + + const std::string kHistogramPrefix("Security.LegacyTLS.PageInfo.Action"); + const char kGenericHistogram[] = "WebsiteSettings.Action"; + + InitializeEmptyLegacyTLSConfig(); + + for (const auto& test : kTestCases) { + base::HistogramTester histograms; + SetURL("https://example.test"); + visible_security_state_.connection_used_legacy_tls = + test.connection_used_legacy_tls; + visible_security_state_.should_suppress_legacy_tls_warning = + test.should_suppress_legacy_tls_warning; + ResetMockUI(); + ClearPageInfo(); + SetDefaultUIExpectations(mock_ui()); + + histograms.ExpectTotalCount(kGenericHistogram, 0); + histograms.ExpectTotalCount(kHistogramPrefix + "." + test.histogram_suffix, + 0); + + page_info()->RecordPageInfoAction( + PageInfo::PageInfoAction::PAGE_INFO_OPENED); + + // RecordPageInfoAction() is called during PageInfo creation in addition to + // the explicit RecordPageInfoAction() call, so it is called twice in total. + histograms.ExpectTotalCount(kGenericHistogram, 2); + histograms.ExpectBucketCount(kGenericHistogram, + PageInfo::PageInfoAction::PAGE_INFO_OPENED, 2); + + histograms.ExpectTotalCount(kHistogramPrefix + "." + test.histogram_suffix, + 2); + histograms.ExpectBucketCount(kHistogramPrefix + "." + test.histogram_suffix, + PageInfo::PageInfoAction::PAGE_INFO_OPENED, 2); + } +} + +// Tests that the duration of time the PageInfo is open is recorded for pages +// with various Legacy TLS statuses. +TEST_F(PageInfoTest, LegacyTLSTimeOpenMetrics) { + const struct TestCase { + const bool connection_used_legacy_tls; + const bool should_suppress_legacy_tls_warning; + const std::string legacy_tls_status_name; + const PageInfo::PageInfoAction action; + } kTestCases[] = { + // PAGE_INFO_COUNT used as shorthand for "take no action". + {true, false, "LegacyTLS_Triggered", PageInfo::PAGE_INFO_COUNT}, + {true, true, "LegacyTLS_NotTriggered", PageInfo::PAGE_INFO_COUNT}, + {false, false, "LegacyTLS_NotTriggered", PageInfo::PAGE_INFO_COUNT}, + {true, false, "LegacyTLS_Triggered", + PageInfo::PAGE_INFO_SITE_SETTINGS_OPENED}, + {true, true, "LegacyTLS_NotTriggered", + PageInfo::PAGE_INFO_SITE_SETTINGS_OPENED}, + {false, false, "LegacyTLS_NotTriggered", + PageInfo::PAGE_INFO_SITE_SETTINGS_OPENED}, + }; + + const std::string kHistogramPrefix("Security.PageInfo.TimeOpen."); + + InitializeEmptyLegacyTLSConfig(); + + for (const auto& test : kTestCases) { + base::HistogramTester histograms; + SetURL("https://example.test"); + visible_security_state_.connection_used_legacy_tls = + test.connection_used_legacy_tls; + visible_security_state_.should_suppress_legacy_tls_warning = + test.should_suppress_legacy_tls_warning; + ResetMockUI(); + ClearPageInfo(); + SetDefaultUIExpectations(mock_ui()); + + histograms.ExpectTotalCount(kHistogramPrefix + test.legacy_tls_status_name, + 0); + histograms.ExpectTotalCount( + kHistogramPrefix + "Action." + test.legacy_tls_status_name, 0); + histograms.ExpectTotalCount( + kHistogramPrefix + "NoAction." + test.legacy_tls_status_name, 0); + + PageInfo* test_page_info = page_info(); + if (test.action != PageInfo::PAGE_INFO_COUNT) { + test_page_info->RecordPageInfoAction(test.action); + } + ClearPageInfo(); + + histograms.ExpectTotalCount(kHistogramPrefix + test.legacy_tls_status_name, + 1); + + if (test.action != PageInfo::PAGE_INFO_COUNT) { + histograms.ExpectTotalCount( + kHistogramPrefix + "Action." + test.legacy_tls_status_name, 1); + } else { + histograms.ExpectTotalCount( + kHistogramPrefix + "NoAction." + test.legacy_tls_status_name, 1); + } + } + + // PageInfoTest expects a valid PageInfo instance to exist at end of test. + ResetMockUI(); + SetDefaultUIExpectations(mock_ui()); + page_info(); +} + // Tests that the SubresourceFilter setting is omitted correctly. TEST_F(PageInfoTest, SubresourceFilterSetting_MatchesActivation) { auto showing_setting = [](const PermissionInfoList& permissions) {
diff --git a/chrome/browser/ui/views/autofill/autofill_bubble_handler_impl.cc b/chrome/browser/ui/views/autofill/autofill_bubble_handler_impl.cc index 2e77a40e9..7b5b7e9 100644 --- a/chrome/browser/ui/views/autofill/autofill_bubble_handler_impl.cc +++ b/chrome/browser/ui/views/autofill/autofill_bubble_handler_impl.cc
@@ -136,7 +136,10 @@ } void AutofillBubbleHandlerImpl::OnPasswordSaved() { - ShowAvatarHighlightAnimation(); + if (base::FeatureList::IsEnabled( + features::kAutofillCreditCardUploadFeedback)) { + ShowAvatarHighlightAnimation(); + } } void AutofillBubbleHandlerImpl::HideSignInPromo() {
diff --git a/chrome/browser/ui/views/global_media_controls/media_dialog_view.cc b/chrome/browser/ui/views/global_media_controls/media_dialog_view.cc index 4a4bbfb0..d59f6b12 100644 --- a/chrome/browser/ui/views/global_media_controls/media_dialog_view.cc +++ b/chrome/browser/ui/views/global_media_controls/media_dialog_view.cc
@@ -70,7 +70,7 @@ observed_containers_[id] = container_ptr; active_sessions_view_->ShowNotification(id, std::move(container)); - OnAnchorBoundsChanged(); + SizeToContents(); for (auto& observer : observers_) observer.OnMediaSessionShown(); @@ -84,7 +84,7 @@ if (active_sessions_view_->empty()) HideDialog(); else - OnAnchorBoundsChanged(); + SizeToContents(); for (auto& observer : observers_) observer.OnMediaSessionHidden(); @@ -125,7 +125,7 @@ } void MediaDialogView::OnContainerExpanded(bool expanded) { - OnAnchorBoundsChanged(); + SizeToContents(); } void MediaDialogView::OnContainerMetadataChanged() {
diff --git a/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc b/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc index 2a4d10f..88e4f94 100644 --- a/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc +++ b/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc
@@ -9,10 +9,19 @@ #include "base/bind.h" #include "base/bind_helpers.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/browser_process_platform_part.h" #include "chrome/browser/chromeos/crostini/crostini_util.h" #include "chrome/browser/chromeos/file_manager/path_util.h" #include "chrome/browser/chromeos/guest_os/guest_os_share_path.h" +#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" +#include "chrome/browser/chromeos/profiles/profile_helper.h" +#include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/common/pref_names.h" +#include "chromeos/dbus/session_manager/session_manager_client.h" +#include "components/prefs/pref_service.h" +#include "components/user_manager/user_manager.h" #include "content/public/browser/browser_thread.h" namespace chromeos { @@ -68,6 +77,18 @@ base::BindRepeating( &CrostiniHandler::HandleCrostiniExportImportOperationStatusRequest, weak_ptr_factory_.GetWeakPtr())); + web_ui()->RegisterMessageCallback( + "requestArcAdbSideloadStatus", + base::BindRepeating(&CrostiniHandler::HandleQueryArcAdbRequest, + weak_ptr_factory_.GetWeakPtr())); + web_ui()->RegisterMessageCallback( + "enableArcAdbSideload", + base::BindRepeating(&CrostiniHandler::HandleEnableArcAdbRequest, + weak_ptr_factory_.GetWeakPtr())); + web_ui()->RegisterMessageCallback( + "disableArcAdbSideload", + base::BindRepeating(&CrostiniHandler::HandleDisableArcAdbRequest, + weak_ptr_factory_.GetWeakPtr())); } void CrostiniHandler::OnJavascriptAllowed() { @@ -254,5 +275,70 @@ base::Value(in_progress)); } +void CrostiniHandler::HandleQueryArcAdbRequest(const base::ListValue* args) { + AllowJavascript(); + CHECK_EQ(0U, args->GetSize()); + + chromeos::SessionManagerClient* client = + chromeos::SessionManagerClient::Get(); + client->QueryAdbSideload(base::Bind(&CrostiniHandler::OnQueryAdbSideload, + weak_ptr_factory_.GetWeakPtr())); +} + +void CrostiniHandler::OnQueryAdbSideload(bool success, bool enabled) { + if (!success) { + LOG(ERROR) << "Failed to query adb sideload status"; + enabled = false; + } + // Other side listens with cr.addWebUIListener + FireWebUIListener("crostini-arc-adb-sideload-status-changed", + base::Value(enabled)); +} + +void CrostiniHandler::HandleEnableArcAdbRequest(const base::ListValue* args) { + CHECK_EQ(0U, args->GetSize()); + if (!CheckEligibilityToChangeArcAdbSideloading()) + return; + + PrefService* prefs = g_browser_process->local_state(); + prefs->SetBoolean(prefs::kEnableAdbSideloadingRequested, true); + prefs->CommitPendingWrite(); + + chrome::AttemptRelaunch(); +} + +void CrostiniHandler::HandleDisableArcAdbRequest(const base::ListValue* args) { + CHECK_EQ(0U, args->GetSize()); + if (!CheckEligibilityToChangeArcAdbSideloading()) + return; + + PrefService* prefs = g_browser_process->local_state(); + prefs->SetBoolean(prefs::kFactoryResetRequested, true); + prefs->CommitPendingWrite(); + + chromeos::PowerManagerClient::Get()->RequestRestart( + power_manager::REQUEST_RESTART_FOR_USER, "disable adb sideloading"); +} + +bool CrostiniHandler::CheckEligibilityToChangeArcAdbSideloading() const { + if (!chromeos::ProfileHelper::IsOwnerProfile(profile_)) { + DVLOG(1) << "Only the owner can change adb sideloading status"; + return false; + } + + if (user_manager::UserManager::Get()->IsLoggedInAsChildUser()) { + DVLOG(1) << "Child account is currently unsupported"; + return false; + } + + policy::BrowserPolicyConnectorChromeOS* connector = + g_browser_process->platform_part()->browser_policy_connector_chromeos(); + if (connector->IsEnterpriseManaged()) { + DVLOG(1) << "adb sideloading is currently unsupported on managed device"; + return false; + } + return true; +} + } // namespace settings } // namespace chromeos
diff --git a/chrome/browser/ui/webui/settings/chromeos/crostini_handler.h b/chrome/browser/ui/webui/settings/chromeos/crostini_handler.h index c5d4a353..1141963 100644 --- a/chrome/browser/ui/webui/settings/chromeos/crostini_handler.h +++ b/chrome/browser/ui/webui/settings/chromeos/crostini_handler.h
@@ -63,6 +63,17 @@ const base::ListValue* args); // CrostiniExportImport::Observer: void OnCrostiniExportImportOperationStatusChanged(bool in_progress) override; + // Handle a request for querying status of ARC adb sideloading. + void HandleQueryArcAdbRequest(const base::ListValue* args); + // Handle a request for enabling adb sideloading in ARC. + void HandleEnableArcAdbRequest(const base::ListValue* args); + // Handle a request for disabling adb sideloading in ARC. + void HandleDisableArcAdbRequest(const base::ListValue* args); + // Callback of HandleQueryArcAdbRequest. + void OnQueryAdbSideload(bool success, bool enabled); + // Returns whether the current user can change adb sideloading configuration + // on current device. + bool CheckEligibilityToChangeArcAdbSideloading() const; Profile* profile_; // weak_ptr_factory_ should always be last member.
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc index 465410f..4bcb7f14 100644 --- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -19,6 +19,7 @@ #include "chrome/browser/autofill/personal_data_manager_factory.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h" +#include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_shortcut_manager.h" @@ -137,6 +138,12 @@ return base::ASCIIToUTF16(original_url + "&b=" + base::SysInfo::GetLsbReleaseBoard()); } + +bool IsEnterpriseManaged() { + policy::BrowserPolicyConnectorChromeOS* connector = + g_browser_process->platform_part()->browser_policy_connector_chromeos(); + return connector->IsEnterpriseManaged(); +} #endif void AddCommonStrings(content::WebUIDataSource* html_source, Profile* profile) { @@ -566,6 +573,15 @@ IDS_SETTINGS_CROSTINI_SHARED_USB_DEVICES_EXTRA_DESCRIPTION}, {"crostiniSharedUsbDevicesListEmptyMessage", IDS_SETTINGS_CROSTINI_SHARED_USB_DEVICES_LIST_EMPTY_MESSAGE}, + {"crostiniArcAdbTitle", IDS_SETTINGS_CROSTINI_ARC_ADB_TITLE}, + {"crostiniArcAdbDescription", IDS_SETTINGS_CROSTINI_ARC_ADB_DESCRIPTION}, + {"crostiniArcAdbLabel", IDS_SETTINGS_CROSTINI_ARC_ADB_LABEL}, + {"crostiniArcAdbRestartButton", + IDS_SETTINGS_CROSTINI_ARC_ADB_RESTART_BUTTON}, + {"crostiniArcAdbConfirmationTitleEnable", + IDS_SETTINGS_CROSTINI_ARC_ADB_CONFIRMATION_TITLE_ENABLE}, + {"crostiniArcAdbConfirmationTitleDisable", + IDS_SETTINGS_CROSTINI_ARC_ADB_CONFIRMATION_TITLE_DISABLE}, }; AddLocalizedStringsBulk(html_source, kLocalizedStrings, base::size(kLocalizedStrings)); @@ -578,6 +594,16 @@ IDS_SETTINGS_CROSTINI_REMOVE, ui::GetChromeOSDeviceName())); html_source->AddString( + "crostiniArcAdbConfirmationMessageEnable", + l10n_util::GetStringFUTF16( + IDS_SETTINGS_CROSTINI_ARC_ADB_CONFIRMATION_MESSAGE_ENABLE, + ui::GetChromeOSDeviceName())); + html_source->AddString( + "crostiniArcAdbConfirmationMessageDisable", + l10n_util::GetStringFUTF16( + IDS_SETTINGS_CROSTINI_ARC_ADB_CONFIRMATION_MESSAGE_DISABLE, + ui::GetChromeOSDeviceName())); + html_source->AddString( "crostiniSharedPathsInstructionsLocate", l10n_util::GetStringFUTF16( IDS_SETTINGS_CROSTINI_SHARED_PATHS_INSTRUCTIONS_LOCATE, @@ -586,6 +612,12 @@ html_source->AddBoolean( "showCrostiniExportImport", crostini::CrostiniFeatures::Get()->IsExportImportUIAllowed(profile)); + html_source->AddBoolean("ArcAdbSideloadingSupported", + base::FeatureList::IsEnabled( + chromeos::features::kArcAdbSideloadingFeature)); + html_source->AddBoolean("isOwnerProfile", + chromeos::ProfileHelper::IsOwnerProfile(profile)); + html_source->AddBoolean("isEnterpriseManaged", IsEnterpriseManaged()); } void AddPluginVmStrings(content::WebUIDataSource* html_source, @@ -1670,10 +1702,7 @@ html_source->AddBoolean("isActiveDirectoryUser", user && user->IsActiveDirectoryUser()); - policy::BrowserPolicyConnectorChromeOS* connector = - g_browser_process->platform_part()->browser_policy_connector_chromeos(); - if (!connector->IsEnterpriseManaged() && - !user_manager->IsCurrentUserOwner()) { + if (!IsEnterpriseManaged() && !user_manager->IsCurrentUserOwner()) { html_source->AddString("ownerEmail", user_manager->GetOwnerAccountId().GetUserEmail()); }
diff --git a/chrome/browser/vr/service/browser_xr_runtime.cc b/chrome/browser/vr/service/browser_xr_runtime.cc index 13562206..a2f92738 100644 --- a/chrome/browser/vr/service/browser_xr_runtime.cc +++ b/chrome/browser/vr/service/browser_xr_runtime.cc
@@ -236,8 +236,8 @@ BrowserXRRuntime::~BrowserXRRuntime() = default; -void BrowserXRRuntime::ExitVrFromPresentingService() { - auto* service = GetPresentingVRService(); +void BrowserXRRuntime::ExitActiveImmersiveSession() { + auto* service = GetServiceWithActiveImmersiveSession(); if (service) { service->ExitPresent(); }
diff --git a/chrome/browser/vr/service/browser_xr_runtime.h b/chrome/browser/vr/service/browser_xr_runtime.h index b9d9e3b..07253feb 100644 --- a/chrome/browser/vr/service/browser_xr_runtime.h +++ b/chrome/browser/vr/service/browser_xr_runtime.h
@@ -58,7 +58,7 @@ device::mojom::VRDisplayInfoPtr info); ~BrowserXRRuntime() override; - void ExitVrFromPresentingService(); + void ExitActiveImmersiveSession(); bool SupportsFeature(device::mojom::XRSessionFeature feature) const; bool SupportsAllFeatures( const std::vector<device::mojom::XRSessionFeature>& features) const; @@ -76,7 +76,9 @@ void RequestSession(VRServiceImpl* service, const device::mojom::XRRuntimeSessionOptionsPtr& options, RequestSessionCallback callback); - VRServiceImpl* GetPresentingVRService() { return presenting_service_; } + VRServiceImpl* GetServiceWithActiveImmersiveSession() { + return presenting_service_; + } void UpdateListeningForActivate(VRServiceImpl* service); device::mojom::VRDisplayInfoPtr GetVRDisplayInfo() {
diff --git a/chrome/browser/vr/service/vr_service_impl.cc b/chrome/browser/vr/service/vr_service_impl.cc index 20ac7b3c..77f54b5b 100644 --- a/chrome/browser/vr/service/vr_service_impl.cc +++ b/chrome/browser/vr/service/vr_service_impl.cc
@@ -208,7 +208,7 @@ in_focused_frame_ = focused; if (ListeningForActivate()) { BrowserXRRuntime* immersive_runtime = - runtime_manager_->GetImmersiveRuntime(); + runtime_manager_->GetImmersiveVrRuntime(); if (immersive_runtime) immersive_runtime->UpdateListeningForActivate(this); } @@ -536,7 +536,9 @@ } void VRServiceImpl::ExitPresent() { - BrowserXRRuntime* immersive_runtime = runtime_manager_->GetImmersiveRuntime(); + BrowserXRRuntime* immersive_runtime = + runtime_manager_->GetCurrentlyPresentingImmersiveRuntime(); + DVLOG(2) << __func__ << ": !!immersive_runtime=" << !!immersive_runtime; if (immersive_runtime) immersive_runtime->ExitPresent(this); } @@ -545,7 +547,7 @@ if (throttled != frames_throttled_) { frames_throttled_ = throttled; BrowserXRRuntime* immersive_runtime = - runtime_manager_->GetImmersiveRuntime(); + runtime_manager_->GetCurrentlyPresentingImmersiveRuntime(); if (immersive_runtime) { immersive_runtime->SetFramesThrottled(this, frames_throttled_); } @@ -560,7 +562,8 @@ display_client_.Bind(std::move(display_client)); else display_client_.reset(); - BrowserXRRuntime* immersive_runtime = runtime_manager_->GetImmersiveRuntime(); + BrowserXRRuntime* immersive_runtime = + runtime_manager_->GetImmersiveVrRuntime(); if (immersive_runtime && display_client_) { immersive_runtime->UpdateListeningForActivate(this); } @@ -575,7 +578,8 @@ return; } - BrowserXRRuntime* immersive_runtime = runtime_manager_->GetImmersiveRuntime(); + BrowserXRRuntime* immersive_runtime = + runtime_manager_->GetImmersiveVrRuntime(); if (immersive_runtime) { immersive_runtime->InitializeAndGetDisplayInfo(render_frame_host_, std::move(callback));
diff --git a/chrome/browser/vr/service/xr_runtime_manager.cc b/chrome/browser/vr/service/xr_runtime_manager.cc index 7f2b611..4bc73b2a 100644 --- a/chrome/browser/vr/service/xr_runtime_manager.cc +++ b/chrome/browser/vr/service/xr_runtime_manager.cc
@@ -106,12 +106,13 @@ return; } - auto* browser_xr_runtime = g_xr_runtime_manager->GetImmersiveRuntime(); + auto* browser_xr_runtime = + g_xr_runtime_manager->GetCurrentlyPresentingImmersiveRuntime(); if (!browser_xr_runtime) { return; } - browser_xr_runtime->ExitVrFromPresentingService(); + browser_xr_runtime->ExitActiveImmersiveSession(); } void XRRuntimeManager::AddService(VRServiceImpl* service) { @@ -163,7 +164,7 @@ } if (options->immersive) { - auto* runtime = GetImmersiveRuntime(); + auto* runtime = GetImmersiveVrRuntime(); return runtime && runtime->SupportsAllFeatures(options->required_features) ? runtime : nullptr; @@ -182,7 +183,7 @@ } } -BrowserXRRuntime* XRRuntimeManager::GetImmersiveRuntime() { +BrowserXRRuntime* XRRuntimeManager::GetImmersiveVrRuntime() { #if defined(OS_ANDROID) auto* gvr = GetRuntime(device::mojom::XRDeviceId::GVR_DEVICE_ID); if (gvr) @@ -216,11 +217,18 @@ return nullptr; } +BrowserXRRuntime* XRRuntimeManager::GetImmersiveArRuntime() { + device::mojom::XRSessionOptions options = {}; + options.immersive = true; + options.environment_integration = true; + return GetRuntimeForOptions(&options); +} + device::mojom::VRDisplayInfoPtr XRRuntimeManager::GetCurrentVRDisplayInfo( VRServiceImpl* service) { DVLOG(1) << __func__; - // Get an immersive runtime if there is one. - auto* immersive_runtime = GetImmersiveRuntime(); + // Get an immersive VR runtime if there is one. + auto* immersive_runtime = GetImmersiveVrRuntime(); if (immersive_runtime) { // Listen to changes for this runtime. immersive_runtime->OnServiceAdded(service); @@ -233,9 +241,7 @@ } // Get an AR runtime if there is one. - device::mojom::XRSessionOptions options = {}; - options.environment_integration = true; - auto* ar_runtime = GetRuntimeForOptions(&options); + auto* ar_runtime = GetImmersiveArRuntime(); if (ar_runtime) { // Listen to changes for this runtime. ar_runtime->OnServiceAdded(service); @@ -264,16 +270,28 @@ return device_info; } +BrowserXRRuntime* XRRuntimeManager::GetCurrentlyPresentingImmersiveRuntime() { + auto* vr_runtime = GetImmersiveVrRuntime(); + if (vr_runtime && vr_runtime->GetServiceWithActiveImmersiveSession()) { + return vr_runtime; + } + + auto* ar_runtime = GetImmersiveArRuntime(); + if (ar_runtime && ar_runtime->GetServiceWithActiveImmersiveSession()) { + return ar_runtime; + } + + return nullptr; +} + bool XRRuntimeManager::IsOtherClientPresenting(VRServiceImpl* service) { DCHECK(service); - auto* runtime = GetImmersiveRuntime(); + auto* runtime = GetCurrentlyPresentingImmersiveRuntime(); if (!runtime) return false; // No immersive runtime to be presenting. - VRServiceImpl* presenting_service = runtime->GetPresentingVRService(); - if (!presenting_service) - return false; // No VRServiceImpl is presenting. + auto* presenting_service = runtime->GetServiceWithActiveImmersiveSession(); // True if some other VRServiceImpl is presenting. return (presenting_service != service);
diff --git a/chrome/browser/vr/service/xr_runtime_manager.h b/chrome/browser/vr/service/xr_runtime_manager.h index d6e468c..194b717b 100644 --- a/chrome/browser/vr/service/xr_runtime_manager.h +++ b/chrome/browser/vr/service/xr_runtime_manager.h
@@ -76,7 +76,18 @@ bool HasRuntime(device::mojom::XRDeviceId id); BrowserXRRuntime* GetRuntimeForOptions( device::mojom::XRSessionOptions* options); - BrowserXRRuntime* GetImmersiveRuntime(); + + // Gets the system default immersive-vr runtime if available. + BrowserXRRuntime* GetImmersiveVrRuntime(); + + // Gets the system default immersive-ar runtime if available. + BrowserXRRuntime* GetImmersiveArRuntime(); + + // Gets the runtime matching a currently-active immersive session, if any. + // This is either the VR or AR runtime, or null if there's no matching + // runtime or if there's no active immersive session. + BrowserXRRuntime* GetCurrentlyPresentingImmersiveRuntime(); + device::mojom::VRDisplayInfoPtr GetCurrentVRDisplayInfo( VRServiceImpl* service);
diff --git a/chrome/browser/web_applications/components/app_shortcut_manager.cc b/chrome/browser/web_applications/components/app_shortcut_manager.cc index 9bf38989..4ba3de5 100644 --- a/chrome/browser/web_applications/components/app_shortcut_manager.cc +++ b/chrome/browser/web_applications/components/app_shortcut_manager.cc
@@ -38,6 +38,11 @@ registrar_ = registrar; } +void AppShortcutManager::Shutdown() { + for (auto& observer : observers_) + observer.OnShortcutManagerDestroyed(); +} + void AppShortcutManager::AddObserver(AppShortcutObserver* observer) { observers_.AddObserver(observer); }
diff --git a/chrome/browser/web_applications/components/app_shortcut_manager.h b/chrome/browser/web_applications/components/app_shortcut_manager.h index 4b6cfda..52522b69 100644 --- a/chrome/browser/web_applications/components/app_shortcut_manager.h +++ b/chrome/browser/web_applications/components/app_shortcut_manager.h
@@ -33,6 +33,7 @@ virtual ~AppShortcutManager(); void SetSubsystems(AppRegistrar* registrar); + void Shutdown(); void AddObserver(AppShortcutObserver* observer); void RemoveObserver(AppShortcutObserver* observer);
diff --git a/chrome/browser/web_applications/components/app_shortcut_observer.h b/chrome/browser/web_applications/components/app_shortcut_observer.h index d9075e3d..36264ad 100644 --- a/chrome/browser/web_applications/components/app_shortcut_observer.h +++ b/chrome/browser/web_applications/components/app_shortcut_observer.h
@@ -13,6 +13,7 @@ class AppShortcutObserver : public base::CheckedObserver { public: virtual void OnShortcutsCreated(const AppId& app_id) {} + virtual void OnShortcutManagerDestroyed() {} }; } // namespace web_app
diff --git a/chrome/browser/web_applications/web_app_provider.cc b/chrome/browser/web_applications/web_app_provider.cc index 86545bf..20243b0 100644 --- a/chrome/browser/web_applications/web_app_provider.cc +++ b/chrome/browser/web_applications/web_app_provider.cc
@@ -149,6 +149,7 @@ pending_app_manager_->Shutdown(); install_manager_->Shutdown(); manifest_update_manager_->Shutdown(); + shortcut_manager_->Shutdown(); } void WebAppProvider::StartImpl() {
diff --git a/chrome/common/importer/firefox_importer_utils.cc b/chrome/common/importer/firefox_importer_utils.cc index e1f5ada..7360ca4 100644 --- a/chrome/common/importer/firefox_importer_utils.cc +++ b/chrome/common/importer/firefox_importer_utils.cc
@@ -50,51 +50,107 @@ return path; } -// Checks if the named profile is the default profile. -bool IsDefaultProfile(const base::DictionaryValue& root, - const std::string& profile_name) { - std::string is_default; - root.GetStringASCII(profile_name + ".Default", &is_default); - return is_default == "1"; +// Returns a map from Firefox profiles to their corresponding installation ids. +// The keys are file system paths for Firefox profiles that are the default +// profile in their installation. The values are the registry keys for the +// corresponding installation. +std::map<std::string, std::string> GetDefaultProfilesPerInstall( + const base::DictionaryValue& root) { + std::map<std::string, std::string> default_profile_to_install_id; + static constexpr base::StringPiece kInstallPrefix("Install"); + // Find the default profiles for each Firefox installation. + for (const auto& data : root) { + const std::string& dict_key = data.first; + if (base::StartsWith(dict_key, kInstallPrefix, + base::CompareCase::SENSITIVE)) { + std::string path; + if (root.GetStringASCII(dict_key + ".Default", &path)) { + default_profile_to_install_id.emplace( + std::move(path), dict_key.substr(kInstallPrefix.size())); + } + } + } + return default_profile_to_install_id; +} + +base::FilePath GetLegacyDefaultProfilePath( + const base::DictionaryValue& root, + const std::vector<std::string>& profile_names) { + if (profile_names.empty()) + return base::FilePath(); + + // When multiple profiles exist, the path to the default profile is returned. + for (const auto& profile_name : profile_names) { + // Checks if the named profile is the default profile using the legacy + // format of profiles.ini (Firefox version < 67). + std::string is_default; + if (root.GetStringASCII(profile_name + ".Default", &is_default) && + is_default == "1") { + return GetProfilePath(root, profile_name); + } + } + + // If no default profile is found, the path to Profile0 will be returned. + return GetProfilePath(root, profile_names.front()); } } // namespace -base::FilePath GetFirefoxProfilePath() { +base::FilePath GetFirefoxProfilePath(const std::string& firefox_install_id) { base::FilePath ini_file = GetProfilesINI(); std::string content; base::ReadFileToString(ini_file, &content); DictionaryValueINIParser ini_parser; ini_parser.Parse(content); - return GetFirefoxProfilePathFromDictionary(ini_parser.root()); + return GetFirefoxProfilePathFromDictionary(ini_parser.root(), + firefox_install_id); } base::FilePath GetFirefoxProfilePathFromDictionary( - const base::DictionaryValue& root) { - std::vector<std::string> profiles; + const base::DictionaryValue& root, + const std::string& firefox_install_id) { + // List of profiles linked to a Firefox installation. This will be empty for + // Firefox versions older than 67. + std::map<std::string, std::string> default_profile_to_install_id = + GetDefaultProfilesPerInstall(root); + // First profile linked to a Firefox installation (version >= 67). + base::Optional<std::string> first_modern_profile; + + // Profiles not linked to a Firefox installation (version < 67). + std::vector<std::string> legacy_profiles; + for (int i = 0; ; ++i) { std::string current_profile = base::StringPrintf("Profile%d", i); - if (root.HasKey(current_profile)) { - profiles.push_back(current_profile); - } else { - // Profiles are continuously numbered. So we exit when we can't + if (!root.HasKey(current_profile)) { + // Profiles are contiguously numbered. So we exit when we can't // find the i-th one. break; } + + std::string path; + if (!root.GetStringASCII(current_profile + ".Path", &path)) + continue; + + auto install_id_it = default_profile_to_install_id.find(path); + if (install_id_it != default_profile_to_install_id.end()) { + // If this installation is the default browser, use the associated + // profile as default profile. + if (install_id_it->second == firefox_install_id) + return GetProfilePath(root, current_profile); + if (!first_modern_profile) + first_modern_profile.emplace(std::move(current_profile)); + } else { + // If no Firefox installation found in profiles.ini, legacy profiles + // (Firefox version < 67) are being used. + legacy_profiles.push_back(std::move(current_profile)); + } } - if (profiles.empty()) - return base::FilePath(); + // Take the first install found as the default install. + if (first_modern_profile) + return GetProfilePath(root, *first_modern_profile); - // When multiple profiles exist, the path to the default profile is returned, - // since the other profiles are used mostly by developers for testing. - for (std::vector<std::string>::const_iterator it = profiles.begin(); - it != profiles.end(); ++it) - if (IsDefaultProfile(root, *it)) - return GetProfilePath(root, *it); - - // If no default profile is found, the path to Profile0 will be returned. - return GetProfilePath(root, profiles.front()); + return GetLegacyDefaultProfilePath(root, legacy_profiles); } #if defined(OS_MACOSX)
diff --git a/chrome/common/importer/firefox_importer_utils.h b/chrome/common/importer/firefox_importer_utils.h index ec57c179..e9feec4 100644 --- a/chrome/common/importer/firefox_importer_utils.h +++ b/chrome/common/importer/firefox_importer_utils.h
@@ -38,13 +38,17 @@ base::FilePath GetFirefoxDylibPath(); #endif // OS_MACOSX -// Returns the path to the Firefox profile. -base::FilePath GetFirefoxProfilePath(); +// Returns the path to the default profile of the Firefox installation with id +// |firefox_install_id|. +base::FilePath GetFirefoxProfilePath(const std::string& firefox_install_id); // Returns the path to the Firefox profile, using a custom dictionary. +// If |firefox_install_id| is not empty returns the default profile associated +// with that id. // Exposed for testing. base::FilePath GetFirefoxProfilePathFromDictionary( - const base::DictionaryValue& root); + const base::DictionaryValue& root, + const std::string& firefox_install_id); // Detects version of Firefox and installation path for the given Firefox // profile.
diff --git a/chrome/common/importer/firefox_importer_utils_unittest.cc b/chrome/common/importer/firefox_importer_utils_unittest.cc index 6fdf99d..16d51771 100644 --- a/chrome/common/importer/firefox_importer_utils_unittest.cc +++ b/chrome/common/importer/firefox_importer_utils_unittest.cc
@@ -21,77 +21,76 @@ std::string pref_name; std::string pref_value; } GetPrefsJsValueCases[] = { - // Basic case. Single pref, unquoted value. - { "user_pref(\"foo.bar\", 1);", "foo.bar", "1" }, - // Value is quoted. Quotes should be stripped. - { "user_pref(\"foo.bar\", \"1\");", "foo.bar", "1" }, - // Value has parens. - { "user_pref(\"foo.bar\", \"Value (detail)\");", - "foo.bar", "Value (detail)" }, - // Multi-line case. - { "user_pref(\"foo.bar\", 1);\n" - "user_pref(\"foo.baz\", 2);\n" - "user_pref(\"foo.bag\", 3);", - "foo.baz", "2" }, - // Malformed content. - { "user_pref(\"foo.bar\", 1);\n" - "user_pref(\"foo.baz\", 2;\n" - "user_pref(\"foo.bag\", 3);", - "foo.baz", "" }, - // Malformed content. - { "uesr_pref(\"foo.bar\", 1);", "foo.bar", "" }, + // Basic case. Single pref, unquoted value. + {"user_pref(\"foo.bar\", 1);", "foo.bar", "1"}, + // Value is quoted. Quotes should be stripped. + {"user_pref(\"foo.bar\", \"1\");", "foo.bar", "1"}, + // Value has parens. + {"user_pref(\"foo.bar\", \"Value (detail)\");", "foo.bar", + "Value (detail)"}, + // Multi-line case. + {"user_pref(\"foo.bar\", 1);\n" + "user_pref(\"foo.baz\", 2);\n" + "user_pref(\"foo.bag\", 3);", + "foo.baz", "2"}, + // Malformed content. + {"user_pref(\"foo.bar\", 1);\n" + "user_pref(\"foo.baz\", 2;\n" + "user_pref(\"foo.bag\", 3);", + "foo.baz", std::string()}, + // Malformed content. + {"uesr_pref(\"foo.bar\", 1);", "foo.bar", std::string()}, }; struct GetFirefoxImporterNameCase { std::string app_ini_content; int resource_id; } GetFirefoxImporterNameCases[] = { - // Basic case - { "[App]\n" - "Vendor=Mozilla\n" - "Name=iceweasel\n" - "Version=10.0.6\n" - "BuildID=20120717115048\n" - "ID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}", - IDS_IMPORT_FROM_ICEWEASEL }, - // Whitespace - { " \t[App] \n" - "Vendor=Mozilla\n" - " Name=Firefox\t \r\n" - "Version=10.0.6\n", - IDS_IMPORT_FROM_FIREFOX }, - // No Name setting - { "[App]\n" - "Vendor=Mozilla\n" - "Version=10.0.6\n" - "BuildID=20120717115048\n" - "ID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}", - IDS_IMPORT_FROM_FIREFOX }, - // No [App] section - { "[Foo]\n" - "Vendor=Mozilla\n" - "Name=Foo\n", - IDS_IMPORT_FROM_FIREFOX }, - // Multiple Name settings in different sections - { "[Foo]\n" - "Vendor=Mozilla\n" - "Name=Firefox\n" - "[App]\n" - "Profile=mozilla/firefox\n" - "Name=iceweasel\n" - "[Bar]\n" - "Name=Bar\n" - "ID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}", - IDS_IMPORT_FROM_ICEWEASEL }, - // Case-insensitivity - { "[App]\n" - "Vendor=Mozilla\n" - "Name=IceWeasel\n" - "Version=10.0.6\n", - IDS_IMPORT_FROM_ICEWEASEL }, - // Empty file - { "", IDS_IMPORT_FROM_FIREFOX } -}; + // Basic case + {"[App]\n" + "Vendor=Mozilla\n" + "Name=iceweasel\n" + "Version=10.0.6\n" + "BuildID=20120717115048\n" + "ID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}", + IDS_IMPORT_FROM_ICEWEASEL}, + // Whitespace + {" \t[App] \n" + "Vendor=Mozilla\n" + " Name=Firefox\t \r\n" + "Version=10.0.6\n", + IDS_IMPORT_FROM_FIREFOX}, + // No Name setting + {"[App]\n" + "Vendor=Mozilla\n" + "Version=10.0.6\n" + "BuildID=20120717115048\n" + "ID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}", + IDS_IMPORT_FROM_FIREFOX}, + // No [App] section + {"[Foo]\n" + "Vendor=Mozilla\n" + "Name=Foo\n", + IDS_IMPORT_FROM_FIREFOX}, + // Multiple Name settings in different sections + {"[Foo]\n" + "Vendor=Mozilla\n" + "Name=Firefox\n" + "[App]\n" + "Profile=mozilla/firefox\n" + "Name=iceweasel\n" + "[Bar]\n" + "Name=Bar\n" + "ID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}", + IDS_IMPORT_FROM_ICEWEASEL}, + // Case-insensitivity + {"[App]\n" + "Vendor=Mozilla\n" + "Name=IceWeasel\n" + "Version=10.0.6\n", + IDS_IMPORT_FROM_ICEWEASEL}, + // Empty file + {std::string(), IDS_IMPORT_FROM_FIREFOX}}; } // anonymous namespace @@ -125,15 +124,17 @@ TEST(FirefoxImporterUtilsTest, GetFirefoxProfilePath) { base::DictionaryValue no_profiles; - EXPECT_EQ("", - GetFirefoxProfilePathFromDictionary(no_profiles).MaybeAsASCII()); + EXPECT_EQ(std::string(), + GetFirefoxProfilePathFromDictionary(no_profiles, std::string()) + .MaybeAsASCII()); base::DictionaryValue single_profile; single_profile.SetString("Profile0.Path", "first"); single_profile.SetString("Profile0.IsRelative", "0"); single_profile.SetString("Profile0.Default", "1"); EXPECT_EQ("first", - GetFirefoxProfilePathFromDictionary(single_profile).MaybeAsASCII()); + GetFirefoxProfilePathFromDictionary(single_profile, std::string()) + .MaybeAsASCII()); base::DictionaryValue no_default; no_default.SetString("Profile0.Path", "first"); @@ -141,7 +142,8 @@ no_default.SetString("Profile1.Path", "second"); no_default.SetString("Profile1.IsRelative", "0"); EXPECT_EQ("first", - GetFirefoxProfilePathFromDictionary(no_default).MaybeAsASCII()); + GetFirefoxProfilePathFromDictionary(no_default, std::string()) + .MaybeAsASCII()); base::DictionaryValue default_first; default_first.SetString("Profile0.Path", "first"); @@ -150,7 +152,8 @@ default_first.SetString("Profile1.Path", "second"); default_first.SetString("Profile1.IsRelative", "0"); EXPECT_EQ("first", - GetFirefoxProfilePathFromDictionary(default_first).MaybeAsASCII()); + GetFirefoxProfilePathFromDictionary(default_first, std::string()) + .MaybeAsASCII()); base::DictionaryValue default_second; default_second.SetString("Profile0.Path", "first"); @@ -159,5 +162,43 @@ default_second.SetString("Profile1.IsRelative", "0"); default_second.SetString("Profile1.Default", "1"); EXPECT_EQ("second", - GetFirefoxProfilePathFromDictionary(default_second).MaybeAsASCII()); + GetFirefoxProfilePathFromDictionary(default_second, std::string()) + .MaybeAsASCII()); + + // Firefox format from version 67 + base::DictionaryValue default_single_install; + default_single_install.SetString("Install01.Default", "second"); + default_single_install.SetString("Profile0.IsRelative", "0"); + default_single_install.SetString("Profile0.Default", "1"); + default_single_install.SetString("Profile1.Path", "second"); + default_single_install.SetString("Profile1.IsRelative", "0"); + EXPECT_EQ("second", GetFirefoxProfilePathFromDictionary( + default_single_install, std::string()) + .MaybeAsASCII()); + + base::DictionaryValue default_single_install_unknown_profile; + default_single_install_unknown_profile.SetString("Install01.Default", + "wrong"); + default_single_install_unknown_profile.SetString("Profile0.Path", "first"); + default_single_install_unknown_profile.SetString("Profile0.IsRelative", "0"); + default_single_install_unknown_profile.SetString("Profile0.Default", "1"); + default_single_install_unknown_profile.SetString("Profile1.Path", "second"); + default_single_install_unknown_profile.SetString("Profile1.IsRelative", "0"); + EXPECT_EQ("first", GetFirefoxProfilePathFromDictionary( + default_single_install_unknown_profile, std::string()) + .MaybeAsASCII()); + + base::DictionaryValue default_multiple_install; + default_single_install_unknown_profile.SetString("Install01.Default", + "first"); + default_single_install_unknown_profile.SetString("Install02.Default", + "second"); + default_single_install_unknown_profile.SetString("Profile0.Path", "first"); + default_single_install_unknown_profile.SetString("Profile0.IsRelative", "0"); + default_single_install_unknown_profile.SetString("Profile0.Default", "1"); + default_single_install_unknown_profile.SetString("Profile1.Path", "second"); + default_single_install_unknown_profile.SetString("Profile1.IsRelative", "0"); + EXPECT_EQ("second", GetFirefoxProfilePathFromDictionary( + default_single_install_unknown_profile, "02") + .MaybeAsASCII()); }
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 13ade0c..4cad314 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -2186,6 +2186,9 @@ // Indicates that debugging features were requested from oobe screen. const char kDebuggingFeaturesRequested[] = "DebuggingFeaturesRequested"; +// Indicates that the user has requested that ARC APK Sideloading be enabled. +const char kEnableAdbSideloadingRequested[] = "EnableAdbSideloadingRequested"; + #if defined(OS_CHROMEOS) // This setting controls initial device timezone that is used before user // session started. It is controlled by device owner.
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index a2801a5..e9db519 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -768,6 +768,7 @@ extern const char kFactoryResetRequested[]; extern const char kFactoryResetTPMFirmwareUpdateMode[]; extern const char kDebuggingFeaturesRequested[]; +extern const char kEnableAdbSideloadingRequested[]; #if defined(OS_CHROMEOS) extern const char kSigninScreenTimezone[];
diff --git a/chrome/test/data/autofill/captured_sites/testcases.json b/chrome/test/data/autofill/captured_sites/testcases.json index 72af0f6..991febbb 100644 --- a/chrome/test/data/autofill/captured_sites/testcases.json +++ b/chrome/test/data/autofill/captured_sites/testcases.json
@@ -180,6 +180,12 @@ { "site_name": "tractorsupply" }, { "site_name": "tradesy", "expectation":"PASS" }, { "site_name": "walmart_ca", "expectation":"PASS" }, + { "site_name": "abebooks", "expectation":"PASS" }, + { "site_name": "bhphotovideo", "expectation":"PASS" }, + { "site_name": "bloomingdales", "expectation":"PASS" }, + { "site_name": "hayneedle", "expectation":"PASS" }, + { "site_name": "sears", "expectation":"PASS" }, + { "site_name": "vans", "expectation":"PASS" }, { "site_name": "worldmarket", "expectation":"PASS", "disabled":true, "bug_number":1006322 } ] }
diff --git a/chrome/test/data/password/captured_sites/testcases.json b/chrome/test/data/password/captured_sites/testcases.json index 42d6ce5..8007173 100644 --- a/chrome/test/data/password/captured_sites/testcases.json +++ b/chrome/test/data/password/captured_sites/testcases.json
@@ -45,7 +45,7 @@ { "scenario_dir":"sign_in_pass", "site_name":"instagram" }, { "scenario_dir":"sign_in_pass", "site_name":"kakao" }, { "scenario_dir":"sign_in_pass", "site_name":"librus" }, - { "scenario_dir":"sign_in_pass", "site_name":"marriott" }, + { "scenario_dir":"sign_in_pass", "site_name":"marriott", "disabled":true, "bug_number":984662 }, { "scenario_dir":"sign_in_pass", "site_name":"mit" }, { "scenario_dir":"sign_in_pass", "site_name":"naukri" }, { "scenario_dir":"sign_in_pass", "site_name":"nexon" },
diff --git a/chrome/test/data/pdf/annotations_feature_enabled_test.js b/chrome/test/data/pdf/annotations_feature_enabled_test.js index f4321ae..017bfb9 100644 --- a/chrome/test/data/pdf/annotations_feature_enabled_test.js +++ b/chrome/test/data/pdf/annotations_feature_enabled_test.js
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {$} from 'chrome://resources/js/util.m.js'; + window.onerror = e => chrome.test.fail(e.stack); window.onunhandledrejection = e => chrome.test.fail(e.reason); @@ -71,9 +73,9 @@ chrome.test.assertEq(3, cameras.length); const expectations = [ - {top: 44.25, left: -106.5, right: 718.5, bottom: -442.5}, - {top: 23.25, left: -3.75, right: 408.75, bottom: -220.125}, - {top: -14.25, left: 33.75, right: 446.25, bottom: -257.625}, + {top: 44.25, left: -106.5, right: 718.5, bottom: -448.5}, + {top: 23.25, left: -3.75, right: 408.75, bottom: -223.125}, + {top: -14.25, left: 33.75, right: 446.25, bottom: -260.625}, ]; for (const expectation of expectations) {
diff --git a/chrome/test/data/pdf/basic_test.js b/chrome/test/data/pdf/basic_test.js index c22a03e..fab4db48 100644 --- a/chrome/test/data/pdf/basic_test.js +++ b/chrome/test/data/pdf/basic_test.js
@@ -3,6 +3,7 @@ // found in the LICENSE file. import {getFilenameFromURL, shouldIgnoreKeyEvents} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/pdf_viewer.js'; +import {$} from 'chrome://resources/js/util.m.js'; import {pressAndReleaseKeyOn} from 'chrome://resources/polymer/v3_0/iron-test-helpers/mock-interactions.js'; var tests = [
diff --git a/chrome/test/data/pdf/gesture_detector_test.js b/chrome/test/data/pdf/gesture_detector_test.js index b534d88..fa86e087 100644 --- a/chrome/test/data/pdf/gesture_detector_test.js +++ b/chrome/test/data/pdf/gesture_detector_test.js
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {GestureDetector} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/gesture_detector.js'; + chrome.test.runTests(function() { 'use strict';
diff --git a/chrome/test/data/pdf/material_elements_test.js b/chrome/test/data/pdf/material_elements_test.js index e81c9e2..b6420ffdf 100644 --- a/chrome/test/data/pdf/material_elements_test.js +++ b/chrome/test/data/pdf/material_elements_test.js
@@ -2,7 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {FittingType} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/pdf_fitting_type.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + import {createBookmarksForTest} from './test_util.js'; /**
diff --git a/chrome/test/data/pdf/metrics_test.js b/chrome/test/data/pdf/metrics_test.js index 4e93e1d3..405df0e 100644 --- a/chrome/test/data/pdf/metrics_test.js +++ b/chrome/test/data/pdf/metrics_test.js
@@ -2,6 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {PDFMetrics} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/metrics.js'; +import {FittingType} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/pdf_fitting_type.js'; + chrome.test.runTests(function() { 'use strict';
diff --git a/chrome/test/data/pdf/navigator_test.js b/chrome/test/data/pdf/navigator_test.js index 4d99664..040561f 100644 --- a/chrome/test/data/pdf/navigator_test.js +++ b/chrome/test/data/pdf/navigator_test.js
@@ -2,6 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {PdfNavigator} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/navigator.js'; +import {OpenPdfParamsParser} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/open_pdf_params_parser.js'; +import {Viewport} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/viewport.js'; + import {MockDocumentDimensions, MockSizer, MockViewportChangedCallback, MockWindow} from './test_util.js'; class MockNavigatorDelegate {
diff --git a/chrome/test/data/pdf/params_parser_test.js b/chrome/test/data/pdf/params_parser_test.js index b0d5195fd..fb4459c 100644 --- a/chrome/test/data/pdf/params_parser_test.js +++ b/chrome/test/data/pdf/params_parser_test.js
@@ -2,6 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {OpenPdfParamsParser} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/open_pdf_params_parser.js'; +import {FittingType} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/pdf_fitting_type.js'; + var tests = [ /** * Test named destinations.
diff --git a/chrome/test/data/pdf/toolbar_manager_test.js b/chrome/test/data/pdf/toolbar_manager_test.js index 4f45f64..9607ca46 100644 --- a/chrome/test/data/pdf/toolbar_manager_test.js +++ b/chrome/test/data/pdf/toolbar_manager_test.js
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {ToolbarManager} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/toolbar_manager.js'; + import {MockWindow} from './test_util.js'; // A cut-down version of MockInteractions.move, which is not exposed
diff --git a/chrome/test/data/pdf/viewport_test.js b/chrome/test/data/pdf/viewport_test.js index 540175e..b1dcddd 100644 --- a/chrome/test/data/pdf/viewport_test.js +++ b/chrome/test/data/pdf/viewport_test.js
@@ -2,6 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {FittingType} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/pdf_fitting_type.js'; +import {Viewport} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/viewport.js'; + import {MockDocumentDimensions, MockSizer, MockViewportChangedCallback, MockWindow} from './test_util.js'; var tests = [
diff --git a/chrome/test/data/pdf/zoom_manager_test.js b/chrome/test/data/pdf/zoom_manager_test.js index 17468e43..44920b7 100644 --- a/chrome/test/data/pdf/zoom_manager_test.js +++ b/chrome/test/data/pdf/zoom_manager_test.js
@@ -2,6 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {BrowserApi} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/browser_api.js'; +import {ZoomManager} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/zoom_manager.js'; +import {EventTracker} from 'chrome://resources/js/event_tracker.m.js'; + chrome.test.runTests(function() { 'use strict';
diff --git a/chromecast/media/cdm/cast_cdm.cc b/chromecast/media/cdm/cast_cdm.cc index e334ba9..98979c17 100644 --- a/chromecast/media/cdm/cast_cdm.cc +++ b/chromecast/media/cdm/cast_cdm.cc
@@ -104,7 +104,6 @@ CastCdm::CastCdm(MediaResourceTracker* media_resource_tracker) : media_resource_tracker_(media_resource_tracker), cast_cdm_context_(new CastCdmContextImpl(this)) { - DCHECK(media_resource_tracker); thread_checker_.DetachFromThread(); } @@ -112,7 +111,6 @@ DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(player_tracker_impl_.get()); player_tracker_impl_->NotifyCdmUnset(); - media_resource_tracker_->DecrementUsageCount(); } void CastCdm::Initialize( @@ -122,7 +120,11 @@ const ::media::SessionExpirationUpdateCB& session_expiration_update_cb) { DCHECK(thread_checker_.CalledOnValidThread()); - media_resource_tracker_->IncrementUsageCount(); + if (media_resource_tracker_) { + media_resource_usage_ = std::make_unique<MediaResourceTracker::ScopedUsage>( + media_resource_tracker_); + } + player_tracker_impl_.reset(new ::media::PlayerTrackerImpl()); session_message_cb_ = session_message_cb;
diff --git a/chromecast/media/cdm/cast_cdm.h b/chromecast/media/cdm/cast_cdm.h index 6adec4c..2477f63 100644 --- a/chromecast/media/cdm/cast_cdm.h +++ b/chromecast/media/cdm/cast_cdm.h
@@ -103,7 +103,10 @@ ::media::SessionKeysChangeCB session_keys_change_cb_; ::media::SessionExpirationUpdateCB session_expiration_update_cb_; - MediaResourceTracker* media_resource_tracker_; + // Track the usage for hardware resource. nullptr means the implementation + // doesn't need hardware resource. + MediaResourceTracker* const media_resource_tracker_; + std::unique_ptr<MediaResourceTracker::ScopedUsage> media_resource_usage_; std::unique_ptr<::media::PlayerTrackerImpl> player_tracker_impl_; std::unique_ptr<CastCdmContext> cast_cdm_context_;
diff --git a/chromecast/media/cma/backend/desktop/BUILD.gn b/chromecast/media/cma/backend/desktop/BUILD.gn index 7ca0dfe..8f994d6f 100644 --- a/chromecast/media/cma/backend/desktop/BUILD.gn +++ b/chromecast/media/cma/backend/desktop/BUILD.gn
@@ -16,7 +16,6 @@ "media_sink_desktop.h", "video_decoder_desktop.cc", "video_decoder_desktop.h", - "volume_control_desktop.cc", ] deps = [ @@ -25,17 +24,16 @@ "//chromecast/public/media", "//media", ] -} - -cast_source_set("video_decoder_for_mixer") { - sources = [ - "cast_media_shlib_video.cc", - ] - - deps = [ - "//base", - "//chromecast/media/cma/backend:null_video", - "//chromecast/public", - "//chromecast/public/media", - ] + if (enable_video_with_mixed_audio) { + deps += [ + "//chromecast/media/cma/backend/alsa:volume_control", + "//chromecast/media/cma/backend:null_video", + "//chromecast/media/cma/backend:for_mixer_audio", + "//chromecast/media/cma/backend/video:av_sync_video", + ] + } else { + sources += [ + "volume_control_desktop.cc", + ] + } }
diff --git a/chromecast/media/cma/backend/desktop/cast_media_desktop.cc b/chromecast/media/cma/backend/desktop/cast_media_desktop.cc index b4c989a..1fc27d0 100644 --- a/chromecast/media/cma/backend/desktop/cast_media_desktop.cc +++ b/chromecast/media/cma/backend/desktop/cast_media_desktop.cc
@@ -4,7 +4,11 @@ #include <memory> +#if defined(ENABLE_VIDEO_WITH_MIXED_AUDIO) +#include "chromecast/media/cma/backend/media_pipeline_backend_for_mixer.h" // nogncheck +#else #include "chromecast/media/cma/backend/desktop/media_pipeline_backend_desktop.h" +#endif #include "chromecast/public/cast_media_shlib.h" #include "chromecast/public/graphics_types.h" #include "chromecast/public/media/media_capabilities_shlib.h" @@ -40,7 +44,11 @@ MediaPipelineBackend* CastMediaShlib::CreateMediaPipelineBackend( const MediaPipelineDeviceParams& params) { +#if defined(ENABLE_VIDEO_WITH_MIXED_AUDIO) + return new MediaPipelineBackendForMixer(params); +#else return new MediaPipelineBackendDesktop(); +#endif } double CastMediaShlib::GetMediaClockRate() { @@ -52,7 +60,10 @@ } void CastMediaShlib::MediaClockRateRange(double* minimum_rate, - double* maximum_rate) {} + double* maximum_rate) { + *minimum_rate = 0.0; + *maximum_rate = 1.0; +} bool CastMediaShlib::SetMediaClockRate(double new_rate) { return false;
diff --git a/chromecast/media/cma/backend/desktop/cast_media_shlib_video.cc b/chromecast/media/cma/backend/desktop/cast_media_shlib_video.cc deleted file mode 100644 index cf76d56..0000000 --- a/chromecast/media/cma/backend/desktop/cast_media_shlib_video.cc +++ /dev/null
@@ -1,37 +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. - -#include <vector> -#include <string> - -#include "base/no_destructor.h" -#include "chromecast/public/cast_media_shlib.h" -#include "chromecast/public/media/media_capabilities_shlib.h" -#include "chromecast/public/video_plane.h" - -namespace chromecast { -namespace media { - -class DesktopVideoPlane : public VideoPlane { - public: - ~DesktopVideoPlane() override = default; - - void SetGeometry(const RectF& display_rect, Transform transform) override {} -}; - -void CastMediaShlib::Initialize(const std::vector<std::string>& argv) {} - -VideoPlane* CastMediaShlib::GetVideoPlane() { - static base::NoDestructor<DesktopVideoPlane> g_video_plane; - return g_video_plane.get(); -} - -bool MediaCapabilitiesShlib::IsSupportedVideoConfig(VideoCodec codec, - VideoProfile profile, - int level) { - return false; -} - -} // namespace media -} // namespace chromecast
diff --git a/chromecast/media/cma/backend/video/BUILD.gn b/chromecast/media/cma/backend/video/BUILD.gn index 1a3a6e1..5279108 100644 --- a/chromecast/media/cma/backend/video/BUILD.gn +++ b/chromecast/media/cma/backend/video/BUILD.gn
@@ -55,12 +55,7 @@ if (use_alsa) { deps += [ "//chromecast/media/cma/backend/alsa:volume_control" ] - if (!is_cast_desktop_build) { - libs = [ "videodecoderformixer" ] - } else { - deps += - [ "//chromecast/media/cma/backend/desktop:video_decoder_for_mixer" ] - } + libs = [ "videodecoderformixer" ] } if (is_fuchsia) {
diff --git a/chromeos/constants/chromeos_features.cc b/chromeos/constants/chromeos_features.cc index 7dbeee4..b1a9094c 100644 --- a/chromeos/constants/chromeos_features.cc +++ b/chromeos/constants/chromeos_features.cc
@@ -20,6 +20,10 @@ const base::Feature kAmbientModeFeature{"ChromeOSAmbientMode", base::FEATURE_DISABLED_BY_DEFAULT}; +// Controls whether to enable ARC ADB sideloading support. +const base::Feature kArcAdbSideloadingFeature{ + "ArcAdbSideloading", base::FEATURE_DISABLED_BY_DEFAULT}; + // Enables or disables auto screen-brightness adjustment when ambient light // changes. const base::Feature kAutoScreenBrightness{"AutoScreenBrightness", @@ -191,7 +195,7 @@ // Enables or disables the shelf hotseat. const base::Feature kShelfHotseat{"ShelfHotseat", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; // Enables or disables a toggle to enable Bluetooth debug logs. const base::Feature kShowBluetoothDebugLogToggle{
diff --git a/chromeos/constants/chromeos_features.h b/chromeos/constants/chromeos_features.h index 5e50e5b..732b2e8 100644 --- a/chromeos/constants/chromeos_features.h +++ b/chromeos/constants/chromeos_features.h
@@ -18,6 +18,8 @@ COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kAmbientModeFeature; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) +extern const base::Feature kArcAdbSideloadingFeature; +COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kAutoScreenBrightness; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kBluetoothAggressiveAppearanceFilter;
diff --git a/chromeos/network/auto_connect_handler.cc b/chromeos/network/auto_connect_handler.cc index 2842707..e2829af 100644 --- a/chromeos/network/auto_connect_handler.cc +++ b/chromeos/network/auto_connect_handler.cc
@@ -258,6 +258,8 @@ } void AutoConnectHandler::NotifyAutoConnectInitiated(int auto_connect_reasons) { + NET_LOG(EVENT) << "AutoConnectInitiated [" + << AutoConnectReasonsToString(auto_connect_reasons_) << "]"; for (auto& observer : observer_list_) observer.OnAutoConnectedInitiated(auto_connect_reasons); }
diff --git a/chromeos/network/network_connection_handler_impl.cc b/chromeos/network/network_connection_handler_impl.cc index 167d178..5eda731 100644 --- a/chromeos/network/network_connection_handler_impl.cc +++ b/chromeos/network/network_connection_handler_impl.cc
@@ -226,7 +226,7 @@ const network_handler::ErrorCallback& error_callback, bool check_error_state, ConnectCallbackMode mode) { - NET_LOG_USER("ConnectToNetwork", service_path); + NET_LOG_USER("ConnectToNetworkRequested", service_path); for (auto& observer : observers_) observer.ConnectToNetworkRequested(service_path);
diff --git a/chromeos/network/network_state_handler.cc b/chromeos/network/network_state_handler.cc index 4b30533..102353c 100644 --- a/chromeos/network/network_state_handler.cc +++ b/chromeos/network/network_state_handler.cc
@@ -1352,8 +1352,12 @@ SCOPED_NET_LOG_IF_SLOW(); bool changed = false; NetworkState* network = GetModifiableNetworkState(service_path); - if (!network) + if (!network || !network->update_received()) { + // Shill may send a service property update before processing Chrome's + // initial GetProperties request. If this occurs, the initial request will + // include the changed property value so we can ignore this update. return; + } std::string prev_connection_state = network->connection_state(); bool prev_is_captive_portal = network->is_captive_portal(); std::string prev_profile_path = network->profile_path();
diff --git a/chromeos/services/network_config/cros_network_config.cc b/chromeos/services/network_config/cros_network_config.cc index eca2ce0..7035a57 100644 --- a/chromeos/services/network_config/cros_network_config.cc +++ b/chromeos/services/network_config/cros_network_config.cc
@@ -992,6 +992,7 @@ eap->identity = GetManagedString(eap_dict, ::onc::eap::kIdentity); eap->inner = GetManagedString(eap_dict, ::onc::eap::kInner); eap->outer = GetManagedString(eap_dict, ::onc::eap::kOuter); + eap->password = GetManagedString(eap_dict, ::onc::eap::kPassword); eap->save_credentials = GetManagedBoolean(eap_dict, ::onc::eap::kSaveCredentials); eap->server_ca_pems = @@ -1096,6 +1097,7 @@ GetManagedString(openvpn_dict, ::onc::openvpn::kKeyDirection); openvpn->ns_cert_type = GetManagedString(openvpn_dict, ::onc::openvpn::kNsCertType); + openvpn->password = GetManagedString(openvpn_dict, ::onc::openvpn::kPassword); openvpn->port = GetManagedInt32(openvpn_dict, ::onc::openvpn::kPort); openvpn->proto = GetManagedString(openvpn_dict, ::onc::openvpn::kProto); openvpn->push_peer_info = @@ -1397,6 +1399,7 @@ wifi->hex_ssid = GetManagedString(wifi_dict, ::onc::wifi::kHexSSID); wifi->hidden_ssid = GetManagedBoolean(wifi_dict, ::onc::wifi::kHiddenSSID); + wifi->passphrase = GetManagedString(wifi_dict, ::onc::wifi::kPassphrase); wifi->roam_threshold = GetManagedInt32(wifi_dict, ::onc::wifi::kRoamThreshold); wifi->ssid = GetRequiredManagedString(wifi_dict, ::onc::wifi::kSSID);
diff --git a/chromeos/services/network_config/public/cpp/cros_network_config_test_helper.cc b/chromeos/services/network_config/public/cpp/cros_network_config_test_helper.cc index 477ccbb..0144550 100644 --- a/chromeos/services/network_config/public/cpp/cros_network_config_test_helper.cc +++ b/chromeos/services/network_config/public/cpp/cros_network_config_test_helper.cc
@@ -5,6 +5,7 @@ #include "chromeos/services/network_config/public/cpp/cros_network_config_test_helper.h" #include "chromeos/network/network_device_handler.h" +#include "chromeos/network/network_handler.h" #include "chromeos/services/network_config/cros_network_config.h" #include "chromeos/services/network_config/in_process_instance.h" @@ -12,16 +13,21 @@ namespace network_config { CrosNetworkConfigTestHelper::CrosNetworkConfigTestHelper() { - network_device_handler_ = - chromeos::NetworkDeviceHandler::InitializeForTesting( - network_state_helper_.network_state_handler()); - cros_network_config_impl_ = - std::make_unique<chromeos::network_config::CrosNetworkConfig>( - network_state_helper_.network_state_handler(), - network_device_handler_.get(), - /*network_configuration_handler=*/nullptr, - /*network_connection_handler=*/nullptr, - /*network_certificate_handler=*/nullptr); + if (NetworkHandler::IsInitialized()) { + cros_network_config_impl_ = std::make_unique<CrosNetworkConfig>(); + } else { + network_state_helper_ = std::make_unique<NetworkStateTestHelper>( + false /* use_default_devices_and_services */); + network_device_handler_ = + chromeos::NetworkDeviceHandler::InitializeForTesting( + network_state_helper_->network_state_handler()); + cros_network_config_impl_ = std::make_unique<CrosNetworkConfig>( + network_state_helper_->network_state_handler(), + network_device_handler_.get(), + /*network_configuration_handler=*/nullptr, + /*network_connection_handler=*/nullptr, + /*network_certificate_handler=*/nullptr); + } OverrideInProcessInstanceForTesting(cros_network_config_impl_.get()); }
diff --git a/chromeos/services/network_config/public/cpp/cros_network_config_test_helper.h b/chromeos/services/network_config/public/cpp/cros_network_config_test_helper.h index 425e7cf..fe01856 100644 --- a/chromeos/services/network_config/public/cpp/cros_network_config_test_helper.h +++ b/chromeos/services/network_config/public/cpp/cros_network_config_test_helper.h
@@ -28,12 +28,11 @@ ~CrosNetworkConfigTestHelper(); NetworkStateTestHelper& network_state_helper() { - return network_state_helper_; + return *network_state_helper_; } private: - NetworkStateTestHelper network_state_helper_{ - false /* use_default_devices_and_services */}; + std::unique_ptr<NetworkStateTestHelper> network_state_helper_; std::unique_ptr<NetworkDeviceHandler> network_device_handler_; std::unique_ptr<CrosNetworkConfig> cros_network_config_impl_;
diff --git a/chromeos/services/network_config/public/mojom/cros_network_config.mojom b/chromeos/services/network_config/public/mojom/cros_network_config.mojom index ad28ac0..71f4034 100644 --- a/chromeos/services/network_config/public/mojom/cros_network_config.mojom +++ b/chromeos/services/network_config/public/mojom/cros_network_config.mojom
@@ -436,6 +436,8 @@ ManagedString? identity; ManagedString? inner; ManagedString? outer; + // Note: |password| contains a placeholder if set to avoid leaking secrets. + ManagedString? password; ManagedBoolean? save_credentials; ManagedStringList? server_ca_pems; ManagedStringList? server_ca_refs; @@ -464,6 +466,7 @@ ManagedEAPProperties? eap; ManagedString? group; ManagedInt32? ike_version; + // Note: |psk| contains a placeholder if set to avoid leaking secrets. ManagedString? psk; ManagedBoolean? save_credentials; ManagedStringList? server_ca_pems; @@ -472,6 +475,7 @@ struct ManagedL2TPProperties { ManagedBoolean? lcp_echo_disabled; + // Note: |password| contains a placeholder if set to avoid leaking secrets. ManagedString? password; ManagedBoolean? save_credentials; ManagedString? username; @@ -516,6 +520,8 @@ ManagedBoolean? ignore_default_route; ManagedString? key_direction; ManagedString? ns_cert_type; + // Note: |password| contains a placeholder if set to avoid leaking secrets. + ManagedString? password; ManagedInt32? port; ManagedString? proto; ManagedBoolean? push_peer_info; @@ -600,6 +606,8 @@ ManagedBoolean? ft_enabled; ManagedString? hex_ssid; ManagedBoolean? hidden_ssid; + // Note: |passphrase| contains a placeholder if set to avoid leaking secrets. + ManagedString? passphrase; ManagedInt32? roam_threshold; ManagedString ssid; SecurityType security;
diff --git a/components/autofill/content/browser/content_autofill_driver.cc b/components/autofill/content/browser/content_autofill_driver.cc index 9d2e0b7..48d16ab 100644 --- a/components/autofill/content/browser/content_autofill_driver.cc +++ b/components/autofill/content/browser/content_autofill_driver.cc
@@ -202,6 +202,14 @@ bounding_box.width(), bounding_box.height()); } +net::NetworkIsolationKey ContentAutofillDriver::NetworkIsolationKey() { + content::RenderFrameHost* top_frame_host = render_frame_host_; + while (top_frame_host->GetParent()) + top_frame_host = top_frame_host->GetParent(); + return net::NetworkIsolationKey(top_frame_host->GetLastCommittedOrigin(), + render_frame_host_->GetLastCommittedOrigin()); +} + void ContentAutofillDriver::FormsSeen(const std::vector<FormData>& forms, base::TimeTicks timestamp) { autofill_handler_->OnFormsSeen(forms, timestamp);
diff --git a/components/autofill/content/browser/content_autofill_driver.h b/components/autofill/content/browser/content_autofill_driver.h index abe86a9..566beed 100644 --- a/components/autofill/content/browser/content_autofill_driver.h +++ b/components/autofill/content/browser/content_autofill_driver.h
@@ -83,6 +83,7 @@ void PopupHidden() override; gfx::RectF TransformBoundingBoxToViewportCoordinates( const gfx::RectF& bounding_box) override; + net::NetworkIsolationKey NetworkIsolationKey() override; // mojom::AutofillDriver: void FormsSeen(const std::vector<FormData>& forms,
diff --git a/components/autofill/core/browser/autofill_download_manager.cc b/components/autofill/core/browser/autofill_download_manager.cc index 47f0b71..969eccc 100644 --- a/components/autofill/core/browser/autofill_download_manager.cc +++ b/components/autofill/core/browser/autofill_download_manager.cc
@@ -852,6 +852,9 @@ resource_request->url = request_url; resource_request->credentials_mode = network::mojom::CredentialsMode::kOmit; resource_request->method = method; + resource_request->trusted_params = network::ResourceRequest::TrustedParams(); + resource_request->trusted_params->network_isolation_key = + driver_->NetworkIsolationKey(); // Add Chrome experiment state to the request headers. variations::AppendVariationsHeaderUnknownSignedIn(
diff --git a/components/autofill/core/browser/autofill_download_manager_unittest.cc b/components/autofill/core/browser/autofill_download_manager_unittest.cc index a62afad..eec16c1 100644 --- a/components/autofill/core/browser/autofill_download_manager_unittest.cc +++ b/components/autofill/core/browser/autofill_download_manager_unittest.cc
@@ -1353,9 +1353,13 @@ // Intialize the autofill driver. shared_url_loader_factory_ = - base::MakeRefCounted<network::TestSharedURLLoaderFactory>(); + base::MakeRefCounted<network::TestSharedURLLoaderFactory>( + nullptr /* network_service */, true /* is_trusted */); driver_ = std::make_unique<TestAutofillDriver>(); driver_->SetSharedURLLoaderFactory(shared_url_loader_factory_); + driver_->SetNetworkIsolationKey( + net::NetworkIsolationKey(url::Origin::Create(GURL("https://abc.com")), + url::Origin::Create(GURL("https://xyz.com")))); // Configure the autofill server communications channel. switch (GetParam()) {
diff --git a/components/autofill/core/browser/autofill_driver.h b/components/autofill/core/browser/autofill_driver.h index e8998205..5c4b81cd 100644 --- a/components/autofill/core/browser/autofill_driver.h +++ b/components/autofill/core/browser/autofill_driver.h
@@ -11,6 +11,7 @@ #include "build/build_config.h" #include "components/autofill/core/common/form_data.h" #include "mojo/public/cpp/bindings/pending_receiver.h" +#include "net/base/network_isolation_key.h" #if !defined(OS_IOS) #include "third_party/blink/public/mojom/webauthn/internal_authenticator.mojom.h" @@ -119,6 +120,8 @@ // renderers cannot do this transformation themselves. virtual gfx::RectF TransformBoundingBoxToViewportCoordinates( const gfx::RectF& bounding_box) = 0; + + virtual net::NetworkIsolationKey NetworkIsolationKey() = 0; }; } // namespace autofill
diff --git a/components/autofill/core/browser/test_autofill_driver.cc b/components/autofill/core/browser/test_autofill_driver.cc index e7ce7623..22a6e4e 100644 --- a/components/autofill/core/browser/test_autofill_driver.cc +++ b/components/autofill/core/browser/test_autofill_driver.cc
@@ -89,6 +89,10 @@ return bounding_box; } +net::NetworkIsolationKey TestAutofillDriver::NetworkIsolationKey() { + return network_isolation_key_; +} + void TestAutofillDriver::SetIsIncognito(bool is_incognito) { is_incognito_ = is_incognito; } @@ -97,6 +101,11 @@ is_in_main_frame_ = is_in_main_frame; } +void TestAutofillDriver::SetNetworkIsolationKey( + const net::NetworkIsolationKey& network_isolation_key) { + network_isolation_key_ = network_isolation_key; +} + void TestAutofillDriver::SetSharedURLLoaderFactory( scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) { test_shared_loader_factory_ = url_loader_factory;
diff --git a/components/autofill/core/browser/test_autofill_driver.h b/components/autofill/core/browser/test_autofill_driver.h index f524de90..2302dd3 100644 --- a/components/autofill/core/browser/test_autofill_driver.h +++ b/components/autofill/core/browser/test_autofill_driver.h
@@ -51,12 +51,15 @@ void PopupHidden() override; gfx::RectF TransformBoundingBoxToViewportCoordinates( const gfx::RectF& bounding_box) override; + net::NetworkIsolationKey NetworkIsolationKey() override; // Methods unique to TestAutofillDriver that tests can use to specialize // functionality. void SetIsIncognito(bool is_incognito); void SetIsInMainFrame(bool is_in_main_frame); + void SetNetworkIsolationKey( + const net::NetworkIsolationKey& network_isolation_key); void SetSharedURLLoaderFactory( scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory); @@ -66,6 +69,7 @@ scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_; bool is_incognito_ = false; bool is_in_main_frame_ = false; + net::NetworkIsolationKey network_isolation_key_; DISALLOW_COPY_AND_ASSIGN(TestAutofillDriver); };
diff --git a/components/autofill/core/common/mojom/BUILD.gn b/components/autofill/core/common/mojom/BUILD.gn index f3ca803..2301e4a 100644 --- a/components/autofill/core/common/mojom/BUILD.gn +++ b/components/autofill/core/common/mojom/BUILD.gn
@@ -5,6 +5,7 @@ import("//mojo/public/tools/bindings/mojom.gni") mojom("mojo_types") { + generate_java = true sources = [ "autofill_types.mojom", ]
diff --git a/components/autofill/ios/browser/autofill_driver_ios.h b/components/autofill/ios/browser/autofill_driver_ios.h index 08226a74..dd7a1a2 100644 --- a/components/autofill/ios/browser/autofill_driver_ios.h +++ b/components/autofill/ios/browser/autofill_driver_ios.h
@@ -65,6 +65,7 @@ void PopupHidden() override; gfx::RectF TransformBoundingBoxToViewportCoordinates( const gfx::RectF& bounding_box) override; + net::NetworkIsolationKey NetworkIsolationKey() override; bool is_processed() const { return processed_; } void set_processed(bool processed) { processed_ = processed; }
diff --git a/components/autofill/ios/browser/autofill_driver_ios.mm b/components/autofill/ios/browser/autofill_driver_ios.mm index c9bce04..79d19e0 100644 --- a/components/autofill/ios/browser/autofill_driver_ios.mm +++ b/components/autofill/ios/browser/autofill_driver_ios.mm
@@ -141,4 +141,20 @@ return bounding_box; } +net::NetworkIsolationKey AutofillDriverIOS::NetworkIsolationKey() { + std::string main_web_frame_id = web::GetMainWebFrameId(web_state_); + web::WebFrame* main_web_frame = + web::GetWebFrameWithId(web_state_, main_web_frame_id); + if (!main_web_frame) + return net::NetworkIsolationKey(); + + web::WebFrame* web_frame = web::GetWebFrameWithId(web_state_, web_frame_id_); + if (!web_frame) + return net::NetworkIsolationKey(); + + return net::NetworkIsolationKey( + url::Origin::Create(main_web_frame->GetSecurityOrigin()), + url::Origin::Create(web_frame->GetSecurityOrigin())); +} + } // namespace autofill
diff --git a/components/content_settings/core/common/BUILD.gn b/components/content_settings/core/common/BUILD.gn index 78123bb0..c7e9c2bddf 100644 --- a/components/content_settings/core/common/BUILD.gn +++ b/components/content_settings/core/common/BUILD.gn
@@ -56,6 +56,7 @@ } mojom("mojo_bindings") { + generate_java = true sources = [ "content_settings.mojom", ]
diff --git a/components/contextual_search/content/common/mojom/BUILD.gn b/components/contextual_search/content/common/mojom/BUILD.gn index c0e820f..74e032c9 100644 --- a/components/contextual_search/content/common/mojom/BUILD.gn +++ b/components/contextual_search/content/common/mojom/BUILD.gn
@@ -5,6 +5,7 @@ import("//mojo/public/tools/bindings/mojom.gni") mojom("mojom") { + generate_java = true sources = [ "contextual_search_js_api_service.mojom", ]
diff --git a/components/domain_reliability/util.cc b/components/domain_reliability/util.cc index 079e200..9bc8f4b 100644 --- a/components/domain_reliability/util.cc +++ b/components/domain_reliability/util.cc
@@ -103,44 +103,14 @@ std::string GetDomainReliabilityProtocol( net::HttpResponseInfo::ConnectionInfo connection_info, bool ssl_info_populated) { - switch (connection_info) { - case net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN: - return ""; - case net::HttpResponseInfo::CONNECTION_INFO_HTTP0_9: - case net::HttpResponseInfo::CONNECTION_INFO_HTTP1_0: - case net::HttpResponseInfo::CONNECTION_INFO_HTTP1_1: + switch (net::HttpResponseInfo::ConnectionInfoToCoarse(connection_info)) { + case net::HttpResponseInfo::CONNECTION_INFO_COARSE_HTTP1: return ssl_info_populated ? "HTTPS" : "HTTP"; - case net::HttpResponseInfo::CONNECTION_INFO_DEPRECATED_SPDY2: - case net::HttpResponseInfo::CONNECTION_INFO_DEPRECATED_SPDY3: - case net::HttpResponseInfo::CONNECTION_INFO_DEPRECATED_HTTP2_14: - case net::HttpResponseInfo::CONNECTION_INFO_DEPRECATED_HTTP2_15: - case net::HttpResponseInfo::CONNECTION_INFO_HTTP2: + case net::HttpResponseInfo::CONNECTION_INFO_COARSE_HTTP2: return "SPDY"; - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_UNKNOWN_VERSION: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_32: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_33: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_34: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_35: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_36: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_37: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_38: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_39: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_40: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_41: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_42: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_43: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_44: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_45: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_46: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_47: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_48: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_49: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_50: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_99: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_999: + case net::HttpResponseInfo::CONNECTION_INFO_COARSE_QUIC: return "QUIC"; - case net::HttpResponseInfo::NUM_OF_CONNECTION_INFOS: - NOTREACHED(); + case net::HttpResponseInfo::CONNECTION_INFO_COARSE_OTHER: return ""; } NOTREACHED();
diff --git a/components/download/internal/common/download_job_factory.cc b/components/download/internal/common/download_job_factory.cc index fb23ce8..f660c6d1 100644 --- a/components/download/internal/common/download_job_factory.cc +++ b/components/download/internal/common/download_job_factory.cc
@@ -29,44 +29,14 @@ ConnectionType GetConnectionType( net::HttpResponseInfo::ConnectionInfo connection_info) { - switch (connection_info) { - case net::HttpResponseInfo::CONNECTION_INFO_HTTP0_9: - case net::HttpResponseInfo::CONNECTION_INFO_HTTP1_0: - case net::HttpResponseInfo::CONNECTION_INFO_HTTP1_1: + switch (net::HttpResponseInfo::ConnectionInfoToCoarse(connection_info)) { + case net::HttpResponseInfo::CONNECTION_INFO_COARSE_HTTP1: return ConnectionType::kHTTP; - case net::HttpResponseInfo::CONNECTION_INFO_DEPRECATED_SPDY2: - case net::HttpResponseInfo::CONNECTION_INFO_DEPRECATED_SPDY3: - case net::HttpResponseInfo::CONNECTION_INFO_DEPRECATED_HTTP2_14: - case net::HttpResponseInfo::CONNECTION_INFO_DEPRECATED_HTTP2_15: - case net::HttpResponseInfo::CONNECTION_INFO_HTTP2: + case net::HttpResponseInfo::CONNECTION_INFO_COARSE_HTTP2: return ConnectionType::kHTTP2; - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_UNKNOWN_VERSION: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_32: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_33: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_34: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_35: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_36: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_37: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_38: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_39: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_40: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_41: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_42: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_43: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_44: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_45: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_46: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_47: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_48: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_49: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_50: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_99: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_999: + case net::HttpResponseInfo::CONNECTION_INFO_COARSE_QUIC: return ConnectionType::kQUIC; - case net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN: - return ConnectionType::kUnknown; - case net::HttpResponseInfo::NUM_OF_CONNECTION_INFOS: - NOTREACHED(); + case net::HttpResponseInfo::CONNECTION_INFO_COARSE_OTHER: return ConnectionType::kUnknown; } NOTREACHED();
diff --git a/components/exo/client_controlled_shell_surface.cc b/components/exo/client_controlled_shell_surface.cc index 53a7f7d..421da77 100644 --- a/components/exo/client_controlled_shell_surface.cc +++ b/components/exo/client_controlled_shell_surface.cc
@@ -1074,7 +1074,8 @@ } void ClientControlledShellSurface::OnSurfaceDestroying(Surface* surface) { - client_controlled_state_->ResetDelegate(); + if (client_controlled_state_) + client_controlled_state_->ResetDelegate(); ShellSurfaceBase::OnSurfaceDestroying(surface); }
diff --git a/components/exo/wayland/fuzzer/fuzzer.cc b/components/exo/wayland/fuzzer/fuzzer.cc index bec68bf..bd09222 100644 --- a/components/exo/wayland/fuzzer/fuzzer.cc +++ b/components/exo/wayland/fuzzer/fuzzer.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "base/at_exit.h" +#include "base/no_destructor.h" #include "components/exo/wayland/fuzzer/actions.pb.h" #include "components/exo/wayland/fuzzer/harness.h" #include "components/exo/wayland/fuzzer/server_environment.h" @@ -19,7 +20,7 @@ }; DEFINE_TEXT_PROTO_FUZZER(const exo::wayland_fuzzer::actions::actions& acts) { - static base::AtExitManager exit_manager; + static base::NoDestructor<base::AtExitManager> exit_manager; static FuzzerEnvironment environment; exo::wayland_fuzzer::Harness().Run(acts);
diff --git a/components/exo/wayland/zcr_remote_shell_unittest.cc b/components/exo/wayland/zcr_remote_shell_unittest.cc index d16e88d..c780d88 100644 --- a/components/exo/wayland/zcr_remote_shell_unittest.cc +++ b/components/exo/wayland/zcr_remote_shell_unittest.cc
@@ -23,7 +23,7 @@ gfx::Insets insets = wayland::GetWorkAreaInsetsInClientPixel( display, device_scale_factor, display.GetSizeInPixel(), display.work_area()); - EXPECT_EQ(gfx::Insets(0, 0, 128, 0).ToString(), insets.ToString()); + EXPECT_EQ(gfx::Insets(0, 0, 110, 0).ToString(), insets.ToString()); auto secondary_display = GetSecondaryDisplay(); gfx::Size secondary_size(secondary_display.size()); @@ -32,7 +32,7 @@ gfx::Insets secondary_insets = wayland::GetWorkAreaInsetsInClientPixel( secondary_display, device_scale_factor, secondary_size_in_client_pixel, secondary_display.work_area()); - EXPECT_EQ(gfx::Insets(0, 0, 126, 0).ToString(), secondary_insets.ToString()); + EXPECT_EQ(gfx::Insets(0, 0, 108, 0).ToString(), secondary_insets.ToString()); // Stable Insets auto widget = CreateTestWidget(); @@ -42,11 +42,11 @@ gfx::Insets stable_insets = wayland::GetWorkAreaInsetsInClientPixel( display, device_scale_factor, display.GetSizeInPixel(), wayland::GetStableWorkArea(display)); - EXPECT_EQ(gfx::Insets(0, 0, 128, 0).ToString(), stable_insets.ToString()); + EXPECT_EQ(gfx::Insets(0, 0, 110, 0).ToString(), stable_insets.ToString()); gfx::Insets secondary_stable_insets = wayland::GetWorkAreaInsetsInClientPixel( secondary_display, device_scale_factor, secondary_size_in_client_pixel, wayland::GetStableWorkArea(secondary_display)); - EXPECT_EQ(gfx::Insets(0, 0, 126, 0).ToString(), + EXPECT_EQ(gfx::Insets(0, 0, 108, 0).ToString(), secondary_stable_insets.ToString()); }
diff --git a/components/ntp_snippets/remote/remote_suggestions_provider_impl_unittest.cc b/components/ntp_snippets/remote/remote_suggestions_provider_impl_unittest.cc index 21a7dbb0..495b577 100644 --- a/components/ntp_snippets/remote/remote_suggestions_provider_impl_unittest.cc +++ b/components/ntp_snippets/remote/remote_suggestions_provider_impl_unittest.cc
@@ -62,7 +62,6 @@ #include "components/strings/grit/components_strings.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "testing/gmock/include/gmock/gmock.h" -#include "testing/gmock_mutant.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/geometry/size.h" @@ -79,7 +78,6 @@ using testing::AnyNumber; using testing::AtMost; using testing::Contains; -using testing::CreateFunctor; using testing::ElementsAre; using testing::ElementsAreArray; using testing::Eq; @@ -1233,11 +1231,8 @@ ElementsAre(Pointee(Property(&RemoteSuggestion::id, "id")))); image_decoder()->SetDecodedImage(gfx::test::CreateImage(1, 1)); - auto serve_one_by_one_image_callback = - base::BindRepeating(&ServeOneByOneImage); EXPECT_CALL(*image_fetcher(), FetchImageAndData_(_, _, _, _)) - .WillOnce(WithArgs<1, 2>( - Invoke(CreateFunctor(serve_one_by_one_image_callback)))); + .WillOnce(WithArgs<1, 2>(Invoke(&ServeOneByOneImage))); gfx::Image image = FetchImage(MakeArticleID("id")); @@ -1304,11 +1299,8 @@ Status::Success(), std::move(fetched_categories)); image_decoder()->SetDecodedImage(gfx::test::CreateImage(1, 1)); - auto serve_one_by_one_image_callback = - base::BindRepeating(&ServeOneByOneImage); EXPECT_CALL(*image_fetcher(), FetchImageAndData_(_, _, _, _)) - .WillOnce(WithArgs<1, 2>( - Invoke(CreateFunctor(serve_one_by_one_image_callback)))); + .WillOnce(WithArgs<1, 2>(Invoke(&ServeOneByOneImage))); gfx::Image image = FetchImage(MakeArticleID("id")); ASSERT_FALSE(image.IsEmpty()); @@ -1473,8 +1465,7 @@ // assumptions for the test are right. EXPECT_CALL(*image_fetcher(), FetchImageAndData_(_, _, _, _)) .Times(2) - .WillRepeatedly(WithArgs<1, 2>( - Invoke(CreateFunctor(base::BindRepeating(&ServeOneByOneImage))))); + .WillRepeatedly(WithArgs<1, 2>(Invoke(&ServeOneByOneImage))); image_decoder()->SetDecodedImage(gfx::test::CreateImage(1, 1)); gfx::Image image = FetchImage(MakeArticleID("http://id-1")); ASSERT_FALSE(image.IsEmpty()); @@ -1637,8 +1628,7 @@ SizeIs(1)); // Load the image to store it in the database. EXPECT_CALL(*image_fetcher(), FetchImageAndData_(_, _, _, _)) - .WillOnce(WithArgs<1, 2>( - Invoke(CreateFunctor(base::BindRepeating(&ServeOneByOneImage))))); + .WillOnce(WithArgs<1, 2>(Invoke(&ServeOneByOneImage))); image_decoder()->SetDecodedImage(gfx::test::CreateImage(1, 1)); gfx::Image image = FetchImage(MakeArticleID("http://site.com")); EXPECT_FALSE(image.IsEmpty()); @@ -1758,8 +1748,7 @@ // TODO(tschumann): Introduce some abstraction to nicely work with image // fetching expectations. EXPECT_CALL(*image_fetcher(), FetchImageAndData_(_, _, _, _)) - .WillOnce(WithArgs<1, 2>( - Invoke(CreateFunctor(base::BindRepeating(&ServeOneByOneImage))))); + .WillOnce(WithArgs<1, 2>(Invoke(&ServeOneByOneImage))); image_decoder()->SetDecodedImage(gfx::test::CreateImage(1, 1)); gfx::Image image = FetchImage(MakeArticleID("http://first/")); EXPECT_FALSE(image.IsEmpty()); @@ -2018,8 +2007,7 @@ std::move(fetched_categories)); EXPECT_CALL(*image_fetcher(), FetchImageAndData_(_, _, _, _)) - .WillOnce(WithArgs<1, 2>( - Invoke(CreateFunctor(base::BindRepeating(&ServeOneByOneImage))))); + .WillOnce(WithArgs<1, 2>(Invoke(&ServeOneByOneImage))); gfx::Image image = FetchImage(MakeArticleID(kSuggestionUrl)); @@ -2146,8 +2134,7 @@ std::move(fetched_categories)); EXPECT_CALL(*image_fetcher(), FetchImageAndData_(_, _, _, _)) - .WillOnce(WithArgs<1, 2>( - Invoke(CreateFunctor(base::BindRepeating(&ServeOneByOneImage))))); + .WillOnce(WithArgs<1, 2>(Invoke(&ServeOneByOneImage))); image_decoder()->SetDecodedImage(gfx::test::CreateImage(1, 1)); gfx::Image image = FetchImage(MakeArticleID(kSuggestionUrl));
diff --git a/components/offline_pages/core/prefetch/prefetch_dispatcher_impl_unittest.cc b/components/offline_pages/core/prefetch/prefetch_dispatcher_impl_unittest.cc index 9982cb7..c805b14b 100644 --- a/components/offline_pages/core/prefetch/prefetch_dispatcher_impl_unittest.cc +++ b/components/offline_pages/core/prefetch/prefetch_dispatcher_impl_unittest.cc
@@ -44,7 +44,6 @@ #include "net/url_request/url_request_test_util.h" #include "testing/gmock/include/gmock/gmock-matchers.h" #include "testing/gmock/include/gmock/gmock.h" -#include "testing/gmock_mutant.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h"
diff --git a/components/optimization_guide/hints_fetcher.cc b/components/optimization_guide/hints_fetcher.cc index 3e69301..e254b02 100644 --- a/components/optimization_guide/hints_fetcher.cc +++ b/components/optimization_guide/hints_fetcher.cc
@@ -161,7 +161,6 @@ resource_request->url = optimization_guide_service_url_; resource_request->method = "POST"; - resource_request->load_flags = net::LOAD_BYPASS_PROXY; resource_request->credentials_mode = network::mojom::CredentialsMode::kOmit; url_loader_ = network::SimpleURLLoader::Create(std::move(resource_request),
diff --git a/components/os_crypt/os_crypt_win.cc b/components/os_crypt/os_crypt_win.cc index d145e8e..8a7f33e7 100644 --- a/components/os_crypt/os_crypt_win.cc +++ b/components/os_crypt/os_crypt_win.cc
@@ -7,7 +7,6 @@ #include <windows.h> #include "base/base64.h" -#include "base/logging.h" #include "base/no_destructor.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" @@ -231,12 +230,7 @@ void OSCrypt::SetRawEncryptionKey(const std::string& raw_key) { DCHECK(!g_use_mock_key) << "Mock key in use."; DCHECK(!raw_key.empty()) << "Bad key."; -#if DCHECK_IS_ON() - if (!GetEncryptionKeyFactory().empty()) { - DCHECK_EQ(raw_key, GetEncryptionKeyFactory()) - << "Different key already set."; - } -#endif + DCHECK(GetEncryptionKeyFactory().empty()) << "Key already set."; GetEncryptionKeyFactory().assign(raw_key); }
diff --git a/components/page_load_metrics/browser/protocol_util.cc b/components/page_load_metrics/browser/protocol_util.cc index efdd0d8..ae03db09 100644 --- a/components/page_load_metrics/browser/protocol_util.cc +++ b/components/page_load_metrics/browser/protocol_util.cc
@@ -8,44 +8,17 @@ NetworkProtocol GetNetworkProtocol( net::HttpResponseInfo::ConnectionInfo connection_info) { - switch (connection_info) { - case net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN: - case net::HttpResponseInfo::CONNECTION_INFO_DEPRECATED_SPDY2: - case net::HttpResponseInfo::CONNECTION_INFO_DEPRECATED_SPDY3: - case net::HttpResponseInfo::CONNECTION_INFO_DEPRECATED_HTTP2_14: - case net::HttpResponseInfo::CONNECTION_INFO_DEPRECATED_HTTP2_15: - case net::HttpResponseInfo::CONNECTION_INFO_HTTP0_9: - case net::HttpResponseInfo::CONNECTION_INFO_HTTP1_0: - case net::HttpResponseInfo::NUM_OF_CONNECTION_INFOS: - return NetworkProtocol::kOther; - case net::HttpResponseInfo::CONNECTION_INFO_HTTP1_1: - return NetworkProtocol::kHttp11; - case net::HttpResponseInfo::CONNECTION_INFO_HTTP2: - return NetworkProtocol::kHttp2; - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_UNKNOWN_VERSION: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_32: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_33: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_34: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_35: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_36: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_37: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_38: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_39: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_40: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_41: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_42: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_43: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_44: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_45: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_46: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_47: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_48: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_49: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_50: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_99: - case net::HttpResponseInfo::CONNECTION_INFO_QUIC_999: - return NetworkProtocol::kQuic; + if (connection_info == net::HttpResponseInfo::CONNECTION_INFO_HTTP1_1) { + return NetworkProtocol::kHttp11; } + if (connection_info == net::HttpResponseInfo::CONNECTION_INFO_HTTP2) { + return NetworkProtocol::kHttp2; + } + if (net::HttpResponseInfo::ConnectionInfoToCoarse(connection_info) == + net::HttpResponseInfo::CONNECTION_INFO_COARSE_QUIC) { + return NetworkProtocol::kQuic; + } + return NetworkProtocol::kOther; } } // namespace page_load_metrics
diff --git a/components/payments/mojom/BUILD.gn b/components/payments/mojom/BUILD.gn index e9d6bde..6caf4541 100644 --- a/components/payments/mojom/BUILD.gn +++ b/components/payments/mojom/BUILD.gn
@@ -5,9 +5,11 @@ import("//mojo/public/tools/bindings/mojom.gni") mojom("mojom") { + generate_java = true sources = [ "payment_request_data.mojom", ] + # TODO(crbug.com/699569): Convert to use the new JS bindings. # use_new_js_bindings = false }
diff --git a/components/policy/resources/PRESUBMIT.py b/components/policy/resources/PRESUBMIT.py index ea33fb8e..9d099a4 100644 --- a/components/policy/resources/PRESUBMIT.py +++ b/components/policy/resources/PRESUBMIT.py
@@ -6,7 +6,7 @@ # mnissler@chromium.org, bartfab@chromium.org or atwilson@chromium.org. import sys -import xml.dom.minidom +from xml.dom import minidom def _GetPolicyTemplates(template_path): # Read list of policies in the template. eval() is used instead of a JSON @@ -77,7 +77,7 @@ histograms = input_api.os_path.join( root, 'tools', 'metrics', 'histograms', 'enums.xml') with open(histograms) as f: - tree = xml.dom.minidom.parseString(f.read()) + tree = minidom.parseString(f.read()) enums = (tree.getElementsByTagName('histogram-configuration')[0] .getElementsByTagName('enums')[0] .getElementsByTagName('enum')) @@ -117,7 +117,7 @@ histograms = input_api.os_path.join( root, 'tools', 'metrics', 'histograms', 'enums.xml') with open(histograms) as f: - tree = xml.dom.minidom.parseString(f.read()) + tree = minidom.parseString(f.read()) enums = (tree.getElementsByTagName('histogram-configuration')[0] .getElementsByTagName('enums')[0] .getElementsByTagName('enum')) @@ -153,11 +153,28 @@ results.append(output_api.PresubmitError(error_extra % atomic_group_id)) return results +def _CheckMissingPlaceholders(input_api, output_api, template_path): + with open(template_path) as f: + template_data = eval(f.read(), {}) + + results = [] + items = template_data['policy_definitions'] \ + + [msg for msg in template_data['messages'].values()] + for item in items: + for key in ['desc', 'text']: + if not key in item: + continue + node = minidom.parseString('<msg>%s</msg>' % item[key]).childNodes[0] + for child in node.childNodes: + if child.nodeType == minidom.Node.TEXT_NODE and '$' in child.data: + warning = ('Character \'$\' found outside of a placeholder in "%s". ' + 'Should it be in a placeholder ?') % item[key] + results.append(output_api.PresubmitPromptWarning(warning)) + return results + def _CommonChecks(input_api, output_api): results = [] - results.extend(_CheckPolicyTemplatesSyntax(input_api, output_api)) - root = input_api.change.RepositoryRoot() template_path = template_path = input_api.os_path.join( root, 'components', 'policy', 'resources', 'policy_templates.json') @@ -166,6 +183,8 @@ root, 'chrome', 'test', 'data', 'policy', 'policy_test_cases.json') affected_files = input_api.change.AffectedFiles() + results.extend(_CheckMissingPlaceholders(input_api, output_api, + template_path)) template_changed = any(f.AbsoluteLocalPath() == template_path \ for f in affected_files) tests_changed = any(f.AbsoluteLocalPath() == test_cases_path \ @@ -179,6 +198,7 @@ return results results.extend(_CheckPolicyTestCases(input_api, output_api, policies)) if template_changed: + results.extend(_CheckPolicyTemplatesSyntax(input_api, output_api)) results.extend(_CheckPolicyHistograms(input_api, output_api, policies)) return results
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index d5cb7fd..33b1e037 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -5221,7 +5221,7 @@ 'tags': ['website-sharing'], 'desc': '''Allows you to specify a list of url patterns that specify sites for which <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> should automatically select a client certificate, if the site requests a certificate. - The value must be an array of stringified JSON dictionaries. Each dictionary must have the form { "pattern": "$URL_PATTERN", "filter" : $FILTER }, where $URL_PATTERN is a content setting pattern. $FILTER restricts from which client certificates the browser will automatically select. Independent of the filter, only certificates will be selected that match the server's certificate request. For example, if $FILTER has the form { "ISSUER": { "CN": "$ISSUER_CN" } }, additionally only client certificates are selected that are issued by a certificate with the CommonName $ISSUER_CN. If $FILTER contains an "ISSUER" and a "SUBJECT" section, a client certificate must satisfy both conditions to be selected. If $FILTER specifies an organization ("O"), a certificate must have at least one organization which matches the specified value to be selected. If $FILTER specifies an organization unit ("OU"), a certificate must have at least one organization unit which matches the specified value to be selected. If $FILTER is the empty dictionary {}, the selection of client certificates is not additionally restricted. + The value must be an array of stringified JSON dictionaries. Each dictionary must have the form <ph name="AUTO_SELECT_CERTIFICATE_FOR_URLS_EXAMPLE">{ "pattern": "$URL_PATTERN", "filter" : $FILTER }</ph>, where <ph name="URL_PATTERN_PLACEHOLDER">$URL_PATTERN</ph> is a content setting pattern. <ph name="FILTER_PLACEHOLDER">$FILTER</ph> restricts from which client certificates the browser will automatically select. Independent of the filter, only certificates will be selected that match the server's certificate request. For example, if <ph name="FILTER_PLACEHOLDER">$FILTER</ph> has the form <ph name="AUTO_SELECT_CERTIFICATE_FOR_URLS_FILTER_EXAMPLE">{ "ISSUER": { "CN": "$ISSUER_CN" } }</ph>, additionally only client certificates are selected that are issued by a certificate with the CommonName <ph name="ISSUER_CN_PLACEHOLDER">$ISSUER_CN</ph>. If <ph name="FILTER_PLACEHOLDER">$FILTER</ph> contains an <ph name="ISSUER_STRING_VALUE">"ISSUER"</ph> and a <ph name="SUBJECT_STRING_VALUE">"SUBJECT"</ph> section, a client certificate must satisfy both conditions to be selected. If <ph name="FILTER_PLACEHOLDER">$FILTER</ph> specifies an organization ("O"), a certificate must have at least one organization which matches the specified value to be selected. If <ph name="FILTER_PLACEHOLDER">$FILTER</ph> specifies an organization unit ("OU"), a certificate must have at least one organization unit which matches the specified value to be selected. If <ph name="FILTER_PLACEHOLDER">$FILTER</ph> is the empty dictionary <ph name="EMPTY_DICTIONARY">{}</ph>, the selection of client certificates is not additionally restricted. If this policy is left not set, no auto-selection will be done for any site.''', }, @@ -5264,7 +5264,7 @@ 'tags': ['website-sharing'], 'desc': '''Allows you to specify a list of url patterns that specify sites for which a client certificate is automatically selected on the sign-in screen in the frame hosting the SAML flow, if the site requests a certificate. An example usage is to configure a device-wide certificate to be presented to the SAML IdP. - The value must be an array of stringified JSON dictionaries. Each dictionary must have the form { "pattern": "$URL_PATTERN", "filter" : $FILTER }, where $URL_PATTERN is a content setting pattern. $FILTER restricts from which client certificates the browser will automatically select. Independent of the filter, only certificates will be selected that match the server's certificate request. If $FILTER has the form { "ISSUER": { "CN": "$ISSUER_CN" } }, additionally only client certificates are selected that are issued by a certificate with the CommonName $ISSUER_CN. If $FILTER is the empty dictionary {}, the selection of client certificates is not additionally restricted. + The value must be an array of stringified JSON dictionaries. Each dictionary must have the form <ph name="DEVICE_LOGIN_SCREEN_AUTO_SELECT_CERTIFICATE_FOR_URLS_EXAMPLE">'{ "pattern": "$URL_PATTERN", "filter" : $FILTER }'</ph>, where <ph name="URL_PATTERN_PLACEHOLDER">$URL_PATTERN</ph> is a content setting pattern. <ph name="FILTER_PLACEHOLDER">$FILTER</ph> restricts from which client certificates the browser will automatically select. Independent of the filter, only certificates will be selected that match the server's certificate request. If <ph name="FILTER_PLACEHOLDER">$FILTER</ph> has the form <ph name="JSON_DICTIONARY_EXAMPLE">'{ "ISSUER": { "CN": "$ISSUER_CN" } }'</ph>, additionally only client certificates are selected that are issued by a certificate with the CommonName <ph name="ISSUER_CN_PLACEHOLDER">$ISSUER_CN</ph>. If <ph name="FILTER_PLACEHOLDER">$FILTER</ph> is the empty dictionary {}, the selection of client certificates is not additionally restricted. If this policy is left not set, no auto-selection will be done for any site.''', }, @@ -14462,7 +14462,7 @@ If this policy is set to a non empty string, that string will be used as the device hostname during DHCP request. - The string can contain variables ${ASSET_ID}, ${SERIAL_NUM}, ${MAC_ADDR}, ${MACHINE_NAME} that would be replaced with values on the device before using as a hostname. Resulting substitution should be a valid hostname (per RFC 1035, section 3.1). + The string can contain variables <ph name="ASSET_ID_PLACEHOLDER">${ASSET_ID}</ph>, <ph name="SERIAL_NUM_PLACEHOLDER">${SERIAL_NUM}</ph>, <ph name="MAC_ADDR_PLACEHOLDER">${MAC_ADDR}</ph>, <ph name="MACHINE_NAME_PLACEHOLDER">${MACHINE_NAME}</ph> that would be replaced with values on the device before using as a hostname. Resulting substitution should be a valid hostname (per RFC 1035, section 3.1). If this policy is not set, or the value after substitution is not a valid hostname, no hostname will be set in DHCP request. ''' }, @@ -16350,9 +16350,9 @@ When this policy is left unset, a platform-specific default is used: Internet Explorer for Windows, or Safari for Mac OS X. On Linux, launching an alternative browser will fail when this is unset. - When this policy is set to one of ${ie}, ${firefox}, ${safari} or - ${opera}, that browser will launch if it is installed. ${ie} is only - available on Windows, and ${safari} is only available on Windows and Mac + When this policy is set to one of <ph name="INTERNET_EXPLORER_VALUE_PLACEHOLDER">${ie}</ph>, <ph name="FIREFOX_VALUE_PLACEHOLDER">${firefox}</ph>, <ph name="SAFARI_VALUE_PLACEHOLDER">${safari}</ph> or + <ph name="OPERA_VALUE_PLACEHOLDER">${opera}</ph>, that browser will launch if it is installed. <ph name="INTERNET_EXPLORER_VALUE_PLACEHOLDER">${ie}</ph> is only + available on Windows, and <ph name="SAFARI_VALUE_PLACEHOLDER">${safari}</ph> is only available on Windows and Mac OS X. When this policy is set to a file path, that file is used as an executable @@ -16387,11 +16387,11 @@ When this policy is set to a list of strings, each string is passed to the alternative browser as a separate command-line parameters. On Windows, the parameters are joined with spaces. On Mac OS X and Linux, a parameter may contain spaces, and still be treated as a single parameter. - If an element contains ${url}, it gets replaced with the URL of the page to open. + If an element contains <ph name="URL_PLACEHOLDER"> ${url}</ph>, it gets replaced with the URL of the page to open. - If no element contains ${url}, the URL is appended at the end of the command line. + If no element contains <ph name="URL_PLACEHOLDER"> ${url}</ph>, the URL is appended at the end of the command line. - Environment variables are expanded. On Windows, %ABC% is replaced with the value of the ABC environment variable. On Mac OS X and Linux, ${ABC} is replaced with the value of the ABC environment variable.''', + Environment variables are expanded. On Windows, <ph name="ENV_VARIABLE_WIN_EXAMPLE">%ABC%</ph> is replaced with the value of the <ph name="ENV_VARIABLE_VALUE">ABC</ph> environment variable. On Mac OS X and Linux, <ph name="ENV_VARIABLE_UNIX_EXAMPLE">${ABC}</ph> is replaced with the value of the <ph name="ENV_VARIABLE">ABC</ph> environment variable.''', }, { 'id': 530, @@ -16415,7 +16415,7 @@ When this policy is set, it will be used to launch <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> when launching <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> from Internet Explorer. - This policy can be set to an executable file path, or ${chrome} to auto-detect Chrome's install location.''', + This policy can be set to an executable file path, or <ph name="PRODUCT_NAME_PLACEHOLDER">${chrome}</ph> to auto-detect Chrome's install location.''', }, { 'id': 531, @@ -16444,11 +16444,11 @@ When this policy is set to a list of strings, the strings are joined with spaces and passed to Chrome as command-line parameters. - If an element contains ${url}, it gets replaced with the URL of the page to open. + If an element contains <ph name="URL_PLACEHOLDER"> ${url}</ph>, it gets replaced with the URL of the page to open. - If no element contains ${url}, the URL is appended at the end of the command line. + If no element contains <ph name="URL_PLACEHOLDER"> ${url}</ph>, the URL is appended at the end of the command line. - Environment variables are expanded. On Windows, %ABC% is replaced with the value of the ABC environment variable.''', + Environment variables are expanded. On Windows, <ph name="ENV_VARIABLE_WIN_EXAMPLE">%ABC%</ph> is replaced with the value of the ABC environment variable.''', }, { 'id': 496, @@ -17693,12 +17693,12 @@ 'type': 'object', 'properties': { 'principal': { - 'description': '''User principal 'user@realm'. The placeholder ${{LOGIN_ID}} is replaced by the username 'user'. The placeholder ${{LOGIN_EMAIL}} is replaced by the full principal 'user@realm'.''', + 'description': '''User principal 'user@realm'. The placeholder <ph name="LOGIN_ID_PLACEHOLDER">${{LOGIN_ID}}</ph> is replaced by the username 'user'. The placeholder <ph name="LOGIN_EMAIL_PLACEHOLDER">${{LOGIN_EMAIL}}</ph> is replaced by the full principal 'user@realm'.''', 'type': 'string', 'pattern': '^(?:[^@]+@[^@]+)|(?:\\${LOGIN_ID})|(?:\\${LOGIN_EMAIL})$', }, 'password': { - 'description': '''Kerberos password. The placeholder ${{PASSWORD}} is replaced by the login password.''', + 'description': '''Kerberos password. The placeholder <ph name="PASSWORD_PLACEHOLDER">${{PASSWORD}}</ph> is replaced by the login password.''', 'type': 'string', 'sensitiveValue': True, }, @@ -17755,7 +17755,7 @@ 'id': 560, 'caption': '''Configure Kerberos accounts''', 'tags': ['website-sharing'], - 'desc': '''Adds prefilled Kerberos accounts. If the Kerberos credentials match the login credentials, an account can be configured to reuse the login credentials by specifying '${{LOGIN_EMAIL}}' and '${{PASSWORD}}' for principal and password, respectively, so that the Kerberos ticket can be retrieved automatically unless two-factor authentication is configured. Users cannot modify accounts added via this policy. + 'desc': '''Adds prefilled Kerberos accounts. If the Kerberos credentials match the login credentials, an account can be configured to reuse the login credentials by specifying '<ph name="LOGIN_EMAIL_PLACEHOLDER">${{LOGIN_EMAIL}}</ph>' and <ph name="PASSWORD_PLACEHOLDER">${{PASSWORD}}</ph>' for principal and password, respectively, so that the Kerberos ticket can be retrieved automatically unless two-factor authentication is configured. Users cannot modify accounts added via this policy. If this policy is enabled, the list of accounts defined by the policy is added to the Kerberos Accounts settings.
diff --git a/components/services/filesystem/public/mojom/BUILD.gn b/components/services/filesystem/public/mojom/BUILD.gn index e799e18..ecd2042 100644 --- a/components/services/filesystem/public/mojom/BUILD.gn +++ b/components/services/filesystem/public/mojom/BUILD.gn
@@ -5,6 +5,7 @@ import("//mojo/public/tools/bindings/mojom.gni") mojom("mojom") { + generate_java = true sources = [ "directory.mojom", "file.mojom",
diff --git a/components/signin/public/identity_manager/primary_account_access_token_fetcher_unittest.cc b/components/signin/public/identity_manager/primary_account_access_token_fetcher_unittest.cc index b08033c..c6ae8526 100644 --- a/components/signin/public/identity_manager/primary_account_access_token_fetcher_unittest.cc +++ b/components/signin/public/identity_manager/primary_account_access_token_fetcher_unittest.cc
@@ -13,12 +13,9 @@ #include "components/signin/public/identity_manager/access_token_info.h" #include "components/signin/public/identity_manager/identity_test_environment.h" #include "testing/gmock/include/gmock/gmock.h" -#include "testing/gmock_mutant.h" #include "testing/gtest/include/gtest/gtest.h" using base::MockCallback; -using testing::CallbackToFunctor; -using testing::InvokeWithoutArgs; using testing::StrictMock; namespace signin {
diff --git a/content/browser/blob_storage/chrome_blob_storage_context.cc b/content/browser/blob_storage/chrome_blob_storage_context.cc index c1bc20a5..1ac96814 100644 --- a/content/browser/blob_storage/chrome_blob_storage_context.cc +++ b/content/browser/blob_storage/chrome_blob_storage_context.cc
@@ -18,14 +18,12 @@ #include "base/supports_user_data.h" #include "base/task/post_task.h" #include "base/task_runner.h" -#include "content/browser/resource_context_impl.h" #include "content/public/browser/blob_handle.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/content_features.h" #include "mojo/public/cpp/bindings/pending_receiver.h" -#include "services/network/public/cpp/resource_request_body.h" #include "services/network/public/cpp/wrapper_shared_url_loader_factory.h" #include "storage/browser/blob/blob_data_builder.h" #include "storage/browser/blob/blob_impl.h" @@ -264,28 +262,6 @@ return blob_storage_context->context(); } -bool GetBodyBlobDataHandles(network::ResourceRequestBody* body, - ResourceContext* resource_context, - BlobHandles* blob_handles) { - blob_handles->clear(); - - storage::BlobStorageContext* blob_context = GetBlobStorageContext( - GetChromeBlobStorageContextForResourceContext(resource_context)); - - DCHECK(blob_context); - for (size_t i = 0; i < body->elements()->size(); ++i) { - const network::DataElement& element = (*body->elements())[i]; - if (element.type() != network::mojom::DataElementType::kBlob) - continue; - std::unique_ptr<storage::BlobDataHandle> handle = - blob_context->GetBlobDataFromUUID(element.blob_uuid()); - if (!handle) - return false; - blob_handles->push_back(std::move(handle)); - } - return true; -} - const char kBlobStorageContextKeyName[] = "content_blob_storage_context"; } // namespace content
diff --git a/content/browser/blob_storage/chrome_blob_storage_context.h b/content/browser/blob_storage/chrome_blob_storage_context.h index 8182634c..93a3ce4 100644 --- a/content/browser/blob_storage/chrome_blob_storage_context.h +++ b/content/browser/blob_storage/chrome_blob_storage_context.h
@@ -25,10 +25,6 @@ class TaskRunner; } -namespace network { -class ResourceRequestBody; -} - namespace storage { class BlobStorageContext; } @@ -36,7 +32,6 @@ namespace content { class BlobHandle; class BrowserContext; -class ResourceContext; // A context class that keeps track of BlobStorageController used by the chrome. // There is an instance associated with each BrowserContext. There could be @@ -109,15 +104,6 @@ storage::BlobStorageContext* GetBlobStorageContext( ChromeBlobStorageContext* blob_storage_context); -using BlobHandles = std::vector<std::unique_ptr<storage::BlobDataHandle>>; - -// Attempts to create a vector of BlobDataHandles that ensure any blob data -// associated with |body| isn't cleaned up until the handles are destroyed. -// Returns false on failure. This is used for POST and PUT requests. -bool GetBodyBlobDataHandles(network::ResourceRequestBody* body, - ResourceContext* resource_context, - BlobHandles* blob_handles); - extern const char kBlobStorageContextKeyName[]; } // namespace content
diff --git a/content/browser/download/download_manager_impl_unittest.cc b/content/browser/download/download_manager_impl_unittest.cc index d0919950..88513e94 100644 --- a/content/browser/download/download_manager_impl_unittest.cc +++ b/content/browser/download/download_manager_impl_unittest.cc
@@ -44,7 +44,6 @@ #include "content/public/test/browser_task_environment.h" #include "content/public/test/test_browser_context.h" #include "testing/gmock/include/gmock/gmock.h" -#include "testing/gmock_mutant.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/origin.h"
diff --git a/content/browser/frame_host/navigation_controller_impl_unittest.cc b/content/browser/frame_host/navigation_controller_impl_unittest.cc index 51b13de..d23cd2e 100644 --- a/content/browser/frame_host/navigation_controller_impl_unittest.cc +++ b/content/browser/frame_host/navigation_controller_impl_unittest.cc
@@ -939,7 +939,7 @@ NavigationControllerImpl& controller = controller_impl(); // First make some history, starting with a privileged URL. - const GURL kExistingURL1("http://privileged"); + const GURL kExistingURL1("chrome://privileged"); auto navigation = NavigationSimulator::CreateBrowserInitiated(kExistingURL1, contents()); navigation->Start(); @@ -947,7 +947,9 @@ // Pretend it has bindings so we can tell if we incorrectly copy it. This has // to be done after ReadyToCommit, otherwise we won't use the current RFH to // commit since its bindings don't match the URL. + EXPECT_EQ(0, main_test_rfh()->GetEnabledBindings()); main_test_rfh()->AllowBindings(BINDINGS_POLICY_MOJO_WEB_UI); + EXPECT_EQ(BINDINGS_POLICY_MOJO_WEB_UI, main_test_rfh()->GetEnabledBindings()); navigation->Commit(); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0;
diff --git a/content/browser/frame_host/render_frame_host_impl_browsertest.cc b/content/browser/frame_host/render_frame_host_impl_browsertest.cc index 0167eee..d8144c6 100644 --- a/content/browser/frame_host/render_frame_host_impl_browsertest.cc +++ b/content/browser/frame_host/render_frame_host_impl_browsertest.cc
@@ -2117,6 +2117,12 @@ EXPECT_EQ(0, process->get_media_stream_count_for_testing()); } +#if defined(OS_CHROMEOS) +// ChromeOS failures are tracked in https://crbug.com/954217 +#define MAYBE_VisibilityScrolledOutOfView DISABLED_VisibilityScrolledOutOfView +#else +#define MAYBE_VisibilityScrolledOutOfView VisibilityScrolledOutOfView +#endif // Test that a frame is visible/hidden depending on its WebContents visibility // state. IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest,
diff --git a/content/browser/indexed_db/database_impl.cc b/content/browser/indexed_db/database_impl.cc index e071f7db..c9a6d8c2 100644 --- a/content/browser/indexed_db/database_impl.cc +++ b/content/browser/indexed_db/database_impl.cc
@@ -87,16 +87,11 @@ return; } - // TODO(dmurph): Fix this to be a preemptive task and handle the error - // correctly. - // Note: This doesn't schedule a task on the transaction because version - // change transactions pre-start in the OpenRequest inside IndexedDBDatabase. - leveldb::Status status = connection_->database()->RenameObjectStoreOperation( - object_store_id, new_name, transaction); - if (!status.ok()) { - indexed_db_context_->GetIDBFactory()->OnDatabaseError( - origin_, status, "Internal error renaming object store."); - } + transaction->ScheduleTask( + blink::mojom::IDBTaskType::Preemptive, + BindWeakOperation(&IndexedDBDatabase::RenameObjectStoreOperation, + connection_->database()->AsWeakPtr(), object_store_id, + new_name)); } void DatabaseImpl::CreateTransaction( @@ -208,15 +203,6 @@ return; } - if (!connection_->database()->IsObjectStoreIdAndMaybeIndexIdInMetadata( - object_store_id, index_id)) { - IndexedDBDatabaseError error(blink::kWebIDBDatabaseExceptionUnknownError, - "Bad request"); - std::move(callback).Run(blink::mojom::IDBDatabaseGetResult::NewErrorResult( - blink::mojom::IDBError::New(error.code(), error.message()))); - return; - } - blink::mojom::IDBDatabase::GetCallback aborting_callback = CreateCallbackAbortOnDestruct<blink::mojom::IDBDatabase::GetCallback, blink::mojom::IDBDatabaseGetResultPtr>( @@ -300,15 +286,12 @@ return; } - // TODO(dmurph): Fix this to be a preemptive task and handle the error - // correctly. - leveldb::Status status = connection_->database()->SetIndexKeysOperation( - object_store_id, std::make_unique<IndexedDBKey>(primary_key), index_keys, - transaction); - if (!status.ok()) { - indexed_db_context_->GetIDBFactory()->OnDatabaseError( - origin_, status, "Internal error setting index keys."); - } + transaction->ScheduleTask( + blink::mojom::IDBTaskType::Preemptive, + BindWeakOperation(&IndexedDBDatabase::SetIndexKeysOperation, + connection_->database()->AsWeakPtr(), object_store_id, + std::make_unique<IndexedDBKey>(primary_key), + index_keys)); } void DatabaseImpl::SetIndexesReady(int64_t transaction_id, @@ -380,11 +363,6 @@ return; } - if (!connection_->database()->IsObjectStoreIdAndMaybeIndexIdInMetadata( - object_store_id, index_id)) { - return; - } - std::unique_ptr<IndexedDBDatabase::OpenCursorOperationParams> params( std::make_unique<IndexedDBDatabase::OpenCursorOperationParams>()); params->object_store_id = object_store_id; @@ -528,17 +506,11 @@ return; } - // TODO(dmurph): Fix this to be a preemptive task and handle the error - // correctly. - // Note: This doesn't schedule a task on the transaction because the - // SetIndexKeys call path isn't asynchronous. - leveldb::Status status = connection_->database()->CreateIndexOperation( - object_store_id, index_id, name, key_path, unique, multi_entry, - transaction); - if (!status.ok()) { - indexed_db_context_->GetIDBFactory()->OnDatabaseError( - origin_, status, "Internal error creating an index."); - } + transaction->ScheduleTask( + blink::mojom::IDBTaskType::Preemptive, + BindWeakOperation(&IndexedDBDatabase::CreateIndexOperation, + connection_->database()->AsWeakPtr(), object_store_id, + index_id, name, key_path, unique, multi_entry)); } void DatabaseImpl::DeleteIndex(int64_t transaction_id,
diff --git a/content/browser/indexed_db/indexed_db_database.cc b/content/browser/indexed_db/indexed_db_database.cc index 11520bd..67723d5 100644 --- a/content/browser/indexed_db/indexed_db_database.cc +++ b/content/browser/indexed_db/indexed_db_database.cc
@@ -478,14 +478,6 @@ if (base::Contains(metadata_.object_stores, object_store_id)) return leveldb::Status::InvalidArgument("Invalid object_store_id"); - // Store creation is done synchronously, as it may be followed by - // index creation (also sync) since preemptive OpenCursor/SetIndexKeys - // may follow. - - // TODO(dmurph): Remove this call once this method is asynchronous (scheduled - // on the transaction). - transaction->EnsureBackingStoreTransactionBegun(); - IndexedDBObjectStoreMetadata object_store_metadata; Status s = metadata_coding_->CreateObjectStore( transaction->BackingStoreTransaction()->transaction(),
diff --git a/content/browser/indexed_db/transaction_impl.cc b/content/browser/indexed_db/transaction_impl.cc index 552bfa35..0ff55b1c 100644 --- a/content/browser/indexed_db/transaction_impl.cc +++ b/content/browser/indexed_db/transaction_impl.cc
@@ -109,22 +109,11 @@ if (!connection->IsConnected()) return; - if (base::Contains(connection->database()->metadata().object_stores, - object_store_id)) { - DLOG(ERROR) << "Invalid object_store_id"; - return; - } - - // TODO(dmurph): Fix this to be a preemptive task and handle the error - // correctly. - // Note: This doesn't schedule a task on the transaction because the - // SetIndexKeys call path isn't asynchronous. - leveldb::Status status = connection->database()->CreateObjectStoreOperation( - object_store_id, name, key_path, auto_increment, transaction_.get()); - if (!status.ok()) { - indexed_db_context_->GetIDBFactory()->OnDatabaseError( - origin_, status, "Internal error creating object store."); - } + transaction_->ScheduleTask( + blink::mojom::IDBTaskType::Preemptive, + BindWeakOperation(&IndexedDBDatabase::CreateObjectStoreOperation, + connection->database()->AsWeakPtr(), object_store_id, + name, key_path, auto_increment)); } void TransactionImpl::DeleteObjectStore(int64_t object_store_id) { @@ -253,9 +242,6 @@ blink::mojom::IDBTransactionPutResultPtr>( std::move(callback), transaction_->AsWeakPtr()); - if (!connection->database()->IsObjectStoreIdInMetadata(object_store_id)) - return; - std::unique_ptr<IndexedDBDatabase::PutOperationParams> params( std::make_unique<IndexedDBDatabase::PutOperationParams>()); params->object_store_id = object_store_id;
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc index 4fbdfaf..d863ac28 100644 --- a/content/browser/loader/navigation_url_loader_impl.cc +++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -747,7 +747,6 @@ if (should_clear_upload) { // The request body is no longer applicable. resource_request_->request_body.reset(); - blob_handles_.clear(); } resource_request_->url = redirect_info_.new_url; @@ -1132,7 +1131,6 @@ std::vector<std::string> url_loader_removed_headers_; net::HttpRequestHeaders url_loader_modified_headers_; - BlobHandles blob_handles_; std::vector<GURL> url_chain_; // Current URL that is being navigated, updated after redirection.
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index d84737f..5b51fc4 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -303,7 +303,7 @@ RendererMainThreadFactoryFunction g_renderer_main_thread_factory = nullptr; -base::Thread* g_in_process_thread; +base::Thread* g_in_process_thread = nullptr; RenderProcessHostFactory* g_render_process_host_factory_ = nullptr; const char kSiteProcessMapKeyName[] = "content_site_process_map"; @@ -1655,10 +1655,11 @@ // thread in the renderer process runs the WebKit code and can sometimes // make blocking calls to the UI thread (i.e. this thread), they need to run // on separate threads. - in_process_renderer_.reset( - g_renderer_main_thread_factory(InProcessChildThreadParams( + in_process_renderer_.reset(g_renderer_main_thread_factory( + InProcessChildThreadParams( base::CreateSingleThreadTaskRunner({BrowserThread::IO}), - &mojo_invitation_, child_connection_->service_token()))); + &mojo_invitation_, child_connection_->service_token()), + base::checked_cast<int32_t>(id_))); base::Thread::Options options; #if defined(OS_WIN) && !defined(OS_MACOSX)
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h index c150bf2..968545d 100644 --- a/content/browser/renderer_host/render_process_host_impl.h +++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -118,7 +118,8 @@ struct ChildProcessTerminationInfo; typedef base::Thread* (*RendererMainThreadFactoryFunction)( - const InProcessChildThreadParams& params); + const InProcessChildThreadParams& params, + int32_t renderer_client_id); // Implements a concrete RenderProcessHost for the browser process for talking // to actual renderer processes (as opposed to mocks).
diff --git a/content/browser/resource_context_impl.cc b/content/browser/resource_context_impl.cc index f5754561..005dc4d 100644 --- a/content/browser/resource_context_impl.cc +++ b/content/browser/resource_context_impl.cc
@@ -8,7 +8,6 @@ #include "base/bind.h" #include "base/logging.h" -#include "content/browser/blob_storage/chrome_blob_storage_context.h" #include "content/browser/webui/url_data_manager_backend.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" @@ -25,13 +24,6 @@ ResourceContext::~ResourceContext() { } -ChromeBlobStorageContext* GetChromeBlobStorageContextForResourceContext( - const ResourceContext* resource_context) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - return UserDataAdapter<ChromeBlobStorageContext>::Get( - resource_context, kBlobStorageContextKeyName); -} - URLDataManagerBackend* GetURLDataManagerForResourceContext( ResourceContext* context) { DCHECK_CURRENTLY_ON(BrowserThread::IO); @@ -46,11 +38,6 @@ void InitializeResourceContext(BrowserContext* browser_context) { ResourceContext* resource_context = browser_context->GetResourceContext(); - resource_context->SetUserData( - kBlobStorageContextKeyName, - std::make_unique<UserDataAdapter<ChromeBlobStorageContext>>( - ChromeBlobStorageContext::GetFor(browser_context))); - resource_context->DetachFromSequence(); }
diff --git a/content/browser/resource_context_impl.h b/content/browser/resource_context_impl.h index 2baade5..bf225e2 100644 --- a/content/browser/resource_context_impl.h +++ b/content/browser/resource_context_impl.h
@@ -10,7 +10,6 @@ namespace content { -class ChromeBlobStorageContext; class BrowserContext; class URLDataManagerBackend; @@ -18,9 +17,6 @@ // the IO thread. These are only accessed by content so they're not on the // public API. -ChromeBlobStorageContext* GetChromeBlobStorageContextForResourceContext( - const ResourceContext* resource_context); - URLDataManagerBackend* GetURLDataManagerForResourceContext( ResourceContext* context);
diff --git a/content/browser/resources/media/manager.js b/content/browser/resources/media/manager.js index 4ab6051..5d9e38c 100644 --- a/content/browser/resources/media/manager.js +++ b/content/browser/resources/media/manager.js
@@ -21,6 +21,7 @@ var copyAllPlayerButton = $('copy-all-player-button'); var copyAllAudioButton = $('copy-all-audio-button'); var hidePlayersButton = $('hide-players-button'); + var devtoolsNoticeWindow = $('devtools-notice-window'); // In tests we may not have these buttons. if (copyAllPlayerButton) { @@ -39,6 +40,9 @@ if (hidePlayersButton) { hidePlayersButton.onclick = this.hidePlayers_.bind(this); } + if (devtoolsNoticeWindow) { + devtoolsNoticeWindow.onclick = this.hideNoticeWindow_; + } } Manager.prototype = { @@ -125,6 +129,10 @@ }, this); }, + hideNoticeWindow_: function() { + this.style.display = 'none'; + }, + updatePlayerInfoNoRecord: function(id, timestamp, key, value) { if (!this.players_[id]) { console.error('[updatePlayerInfo] Id ' + id + ' does not exist');
diff --git a/content/browser/resources/media/media_internals.css b/content/browser/resources/media/media_internals.css index a7e24a9..34f50c2 100644 --- a/content/browser/resources/media/media_internals.css +++ b/content/browser/resources/media/media_internals.css
@@ -237,3 +237,18 @@ #audio-focus-session-list { list-style: none; } + +#devtools-notice-window { + background-color: rgb(252, 247, 134); + border: 1px solid black; + border-radius: 4px; + font-size: 10px; + height: 40px; + left: 50%; + line-height: 20px; + margin-inline-start: -300px; + position: fixed; + text-align: center; + top: 10px; + width: 450px; +} \ No newline at end of file
diff --git a/content/browser/resources/media/media_internals.html b/content/browser/resources/media/media_internals.html index abd3244..7313553 100644 --- a/content/browser/resources/media/media_internals.html +++ b/content/browser/resources/media/media_internals.html
@@ -20,6 +20,17 @@ </head> <body> + <div id="devtools-notice-window"> + <div> + Media Internals functionality is now available in the media tab of the + developer tools. + </div> + <div> + <a href="chrome://flags/#enable-media-internals-devtools"> + To try it, enable the flag here. + </a> + </div> + </div> <tabbox> <tabs> <tab>Players</tab>
diff --git a/content/browser/web_package/signed_exchange_request_handler_browsertest.cc b/content/browser/web_package/signed_exchange_request_handler_browsertest.cc index 26aa8880..0d69e01 100644 --- a/content/browser/web_package/signed_exchange_request_handler_browsertest.cc +++ b/content/browser/web_package/signed_exchange_request_handler_browsertest.cc
@@ -281,6 +281,13 @@ }; IN_PROC_BROWSER_TEST_P(SignedExchangeRequestHandlerBrowserTest, Simple) { +#if defined(OS_CHROMEOS) + // https://crbug.com/1016865 tracks the test failures on CrOS that are only + // happening in the mode special-cased below. + if (UsePrefetch() && SXGPrefetchCacheIsEnabled()) + return; +#endif + InstallMockCert(); InstallMockCertChainInterceptor(); @@ -355,6 +362,13 @@ } IN_PROC_BROWSER_TEST_P(SignedExchangeRequestHandlerBrowserTest, VariantMatch) { +#if defined(OS_CHROMEOS) + // https://crbug.com/1016865 tracks the test failures on CrOS that are only + // happening in the mode special-cased below. + if (UsePrefetch() && SXGPrefetchCacheIsEnabled()) + return; +#endif + if (!SetAcceptLangs("en-US,fr")) return; InstallUrlInterceptor(
diff --git a/content/browser/webui/shared_resources_data_source.cc b/content/browser/webui/shared_resources_data_source.cc index 114de1e..10ef15e 100644 --- a/content/browser/webui/shared_resources_data_source.cc +++ b/content/browser/webui/shared_resources_data_source.cc
@@ -50,9 +50,6 @@ const char kPolymerJs[] = "polymer/v1_0/polymer/polymer-extracted.js"; const char kPolymer2Html[] = "polymer/v1_0/polymer2/polymer.html"; const char kPolymer2Js[] = "polymer/v1_0/polymer2/polymer-extracted.js"; -const char kHtmlImportsJs[] = "polymer/v1_0/html-imports/html-imports.min.js"; -const char kHtmlImportsV0Js[] = - "polymer/v1_0/html-imports-v0/html-imports.min.js"; // Utility for determining if both Polymer 1 and Polymer 2 are needed. bool UsingMultiplePolymerVersions() { @@ -191,11 +188,7 @@ if (base::StartsWith( resource, "../../../third_party/polymer/v1_0/components-chromium/polymer/", - base::CompareCase::SENSITIVE) || - base::StartsWith(resource, - "../../../third_party/polymer/v1_0/components-chromium/" - "html-imports-v0/", - base::CompareCase::SENSITIVE)) { + base::CompareCase::SENSITIVE)) { return true; } @@ -303,14 +296,9 @@ // If this is a Polymer request and multiple Polymer versions are enabled, // return the Polymer 2 path unless the request is from the // |disabled_polymer2_host_|. - if ((path == kPolymerHtml || path == kPolymerJs || path == kHtmlImportsJs) && - UsingMultiplePolymerVersions()) { - bool polymer2 = !IsPolymer2DisabledForPage(wc_getter); - if (polymer2 && (path == kPolymerHtml || path == kPolymerJs)) { - updated_path = path == kPolymerHtml ? kPolymer2Html : kPolymer2Js; - } else if (!polymer2 && path == kHtmlImportsJs) { - updated_path = kHtmlImportsV0Js; - } + if ((path == kPolymerHtml || path == kPolymerJs) && + UsingMultiplePolymerVersions() && !IsPolymer2DisabledForPage(wc_getter)) { + updated_path = path == kPolymerHtml ? kPolymer2Html : kPolymer2Js; } #endif // defined(OS_CHROMEOS)
diff --git a/content/renderer/in_process_renderer_thread.cc b/content/renderer/in_process_renderer_thread.cc index 01ffff7b..45f6e0e7 100644 --- a/content/renderer/in_process_renderer_thread.cc +++ b/content/renderer/in_process_renderer_thread.cc
@@ -21,9 +21,11 @@ #endif InProcessRendererThread::InProcessRendererThread( - const InProcessChildThreadParams& params) - : Thread("Chrome_InProcRendererThread"), params_(params) { -} + const InProcessChildThreadParams& params, + int32_t renderer_client_id) + : Thread("Chrome_InProcRendererThread"), + params_(params), + renderer_client_id_(renderer_client_id) {} InProcessRendererThread::~InProcessRendererThread() { #if defined(OS_ANDROID) @@ -54,7 +56,8 @@ // RenderThreadImpl doesn't currently support a proper shutdown sequence // and it's okay when we're running in multi-process mode because renderers // get killed by the OS. In-process mode is used for test and debug only. - new RenderThreadImpl(params_, std::move(main_thread_scheduler)); + new RenderThreadImpl(params_, renderer_client_id_, + std::move(main_thread_scheduler)); } void InProcessRendererThread::CleanUp() { @@ -80,8 +83,9 @@ } base::Thread* CreateInProcessRendererThread( - const InProcessChildThreadParams& params) { - return new InProcessRendererThread(params); + const InProcessChildThreadParams& params, + int32_t renderer_client_id) { + return new InProcessRendererThread(params, renderer_client_id); } } // namespace content
diff --git a/content/renderer/in_process_renderer_thread.h b/content/renderer/in_process_renderer_thread.h index 73ae552..9ef5e09 100644 --- a/content/renderer/in_process_renderer_thread.h +++ b/content/renderer/in_process_renderer_thread.h
@@ -20,7 +20,8 @@ // single-process mode. It's not used in multi-process mode. class InProcessRendererThread : public base::Thread { public: - explicit InProcessRendererThread(const InProcessChildThreadParams& params); + InProcessRendererThread(const InProcessChildThreadParams& params, + int32_t renderer_client_id); ~InProcessRendererThread() override; protected: @@ -28,14 +29,16 @@ void CleanUp() override; private: - InProcessChildThreadParams params_; + const InProcessChildThreadParams params_; + const int32_t renderer_client_id_; std::unique_ptr<RenderProcess> render_process_; DISALLOW_COPY_AND_ASSIGN(InProcessRendererThread); }; CONTENT_EXPORT base::Thread* CreateInProcessRendererThread( - const InProcessChildThreadParams& params); + const InProcessChildThreadParams& params, + int32_t renderer_client_id); } // namespace content
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 1244105..5260a032 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -1079,26 +1079,6 @@ } // namespace -class RenderFrameImpl::AssertNavigationCommits { - public: - explicit AssertNavigationCommits(RenderFrameImpl* frame) - : frame_(frame->weak_factory_.GetWeakPtr()) { - CHECK_EQ(NavigationCommitState::kNone, frame->navigation_commit_state_); - frame->navigation_commit_state_ = NavigationCommitState::kWillCommitFromIPC; - } - ~AssertNavigationCommits() { - // Frame might have been synchronously detached when dispatching JS events. - if (frame_) { - CHECK_EQ(NavigationCommitState::kDidCommitFromIPC, - frame_->navigation_commit_state_); - frame_->navigation_commit_state_ = NavigationCommitState::kNone; - } - } - - private: - const base::WeakPtr<RenderFrameImpl> frame_; -}; - // This class uses existing WebNavigationBodyLoader to read the whole response // body into in-memory buffer, and then creates another body loader with static // data so that we can parse mhtml archive synchronously. This is a workaround @@ -1110,45 +1090,17 @@ // Once the body is read, fills |navigation_params| with the new body loader // and calls |done_callbcak|. MHTMLBodyLoaderClient( - RenderFrameImpl* frame, std::unique_ptr<blink::WebNavigationParams> navigation_params, base::OnceCallback<void(std::unique_ptr<blink::WebNavigationParams>)> done_callback) - : frame_(frame), - navigation_params_(std::move(navigation_params)), - body_loader_(std::move(navigation_params_->body_loader)), + : navigation_params_(std::move(navigation_params)), done_callback_(std::move(done_callback)) { + body_loader_ = std::move(navigation_params_->body_loader); body_loader_->StartLoadingBody(this, false /* use_isolated_code_cache */); } - ~MHTMLBodyLoaderClient() override { - // MHTMLBodyLoaderClient is reset in several different places. Either: - CHECK( - // - the body load finished and the result is being committed, so - // |BodyLoadingFinished| (see below) should still be on the stack, or - committing_ || - // - MHTMLBodyLoaderClient is abandoned, either because: - // - the browser requested a different navigation be committed in this - // frame, i.e. the navigation commit state should be - // kWillCommitFromIPC, or - NavigationCommitState::kWillCommitFromIPC == - frame_->navigation_commit_state_ || - // - a new renderer-initiated navigation began, which explicitly - // detaches any existing MHTMLBodyLoaderClient - // - this renderer began the navigation and cancelled it with - // |AbortClientNavigation|, e.g. JS called windows.stop(), which - // explicitly detaches any existing MHTMLBodyLoaderClient - // - the frame is detached and self-deleted, which also explicitly - // detaches any existing MHTMLBodyLoaderClient - !frame_); - } + ~MHTMLBodyLoaderClient() override {} - void Detach() { - CHECK(frame_->in_frame_tree_); - frame_ = nullptr; - } - - // blink::WebNavigationBodyLoader::Client overrides: void BodyCodeCacheReceived(mojo_base::BigBuffer data) override {} void BodyDataReceived(base::span<const char> data) override { @@ -1161,8 +1113,6 @@ int64_t total_decoded_body_length, bool should_report_corb_blocking, const base::Optional<WebURLError>& error) override { - committing_ = true; - AssertNavigationCommits assert_navigation_commits(frame_); if (!error.has_value()) { WebNavigationParams::FillBodyLoader(navigation_params_.get(), data_); // Clear |is_static_data| flag to avoid the special behavior it triggers, @@ -1174,9 +1124,6 @@ } private: - // |RenderFrameImpl| owns |this|, so |frame_| is guaranteed to be valid. - RenderFrameImpl* frame_; - bool committing_ = false; WebData data_; std::unique_ptr<blink::WebNavigationParams> navigation_params_; std::unique_ptr<blink::WebNavigationBodyLoader> body_loader_; @@ -3441,8 +3388,6 @@ return; } - AssertNavigationCommits assert_navigation_commits(this); - bool was_initiated_in_this_frame = false; if (IsPerNavigationMojoInterfaceEnabled()) { was_initiated_in_this_frame = @@ -3543,31 +3488,7 @@ // We need this to retrieve the document mime type prior to committing. mhtml_body_loader_client_ = std::make_unique<RenderFrameImpl::MHTMLBodyLoaderClient>( - this, std::move(navigation_params), std::move(commit_with_params)); - // The navigation didn't really commit, but lie about it anyway. Why? MHTML - // is a bit special: the renderer process is responsible for parsing the - // archive, but at this point, the response body isn't fully loaded yet. - // Instead, MHTMLBodyLoaderClient will read the entire response body and - // parse the archive to extract the main resource to be committed. - // - // There are two possibilities from this point: - // - MHTMLBodyLoaderClient::BodyLoadingFinished() is called. At that point, - // the main resource can be extracted, and the navigation should be - // synchronously committed. If this is a provisional frame, it will be - // swapped in and committed. AssertNavigationCommits is used to ensure - // that this always happens. ✔️ - // - Alternatively, the pending archive load may be cancelled. This can only - // happen if the renderer initiates a new navigation, or if the browser - // requests that this frame commit a different navigation. - // - If |this| is already swapped in, the reason for cancelling the - // pending archive load does not matter. There will be no state skew - // between the browser and the renderer, since |this| has already - // committed a navigation. ✔️ - // - If |this| is provisional, the pending archive load may only be - // cancelled by the browser requesting |this| to commit a different - // navigation. AssertNavigationCommits ensures the new request ends up - // committing and swapping in |this|, so this is OK. ✔️ - navigation_commit_state_ = NavigationCommitState::kDidCommitFromIPC; + std::move(navigation_params), std::move(commit_with_params)); return; } @@ -3584,14 +3505,6 @@ !browser_side_navigation_pending_url_.is_empty() && browser_side_navigation_pending_url_ == commit_params.original_url && commit_params.nav_entry_id == 0) { - // If a navigation has been cancelled in the renderer, the renderer must - // have already committed and swapped this frame into the frame tree: - // - a provisional frame cannot run JS, so it cannot self-cancel its own - // navigation. - // - a provisional frame is only partially linked into the frame tree, so - // other frames should not be able to reach into it to cancel the - // navigation either. - CHECK(in_frame_tree_); return true; } return false; @@ -3771,9 +3684,6 @@ TRACE_EVENT1("navigation,benchmark,rail", "RenderFrameImpl::CommitFailedNavigation", "id", routing_id_); DCHECK(!NavigationTypeUtils::IsSameDocument(common_params->navigation_type)); - - AssertNavigationCommits assert_navigation_commits(this); - RenderFrameImpl::PrepareRenderViewForNavigation(common_params->url, *commit_params); sync_navigation_callback_.Cancel(); @@ -3815,16 +3725,6 @@ Send(new FrameHostMsg_DidStopLoading(routing_id_)); browser_side_navigation_pending_ = false; browser_side_navigation_pending_url_ = GURL(); - - // Disarm AssertNavigationCommits and pretend that the commit actually - // happened. Signalling that the load stopped /should/ signal the browser to - // tear down the speculative RFH associated with |this|... - // TODO(dcheng): This is potentially buggy. This means that the browser - // asked the renderer to commit a failed navigation, but it declined. In the - // future, when speculative RFH management is refactored, this will likely - // have to self-discard if |this| is provisional. - navigation_commit_state_ = NavigationCommitState::kDidCommitFromIPC; - return; } @@ -3873,14 +3773,6 @@ } browser_side_navigation_pending_ = false; browser_side_navigation_pending_url_ = GURL(); - - // Disarm AssertNavigationCommits and pretend that the commit actually - // happened. Hopefully, either: - // - the browser process is signalled to stop loading, which /should/ signal - // the browser to tear down the speculative RFH associated with |this| or - // - fallback content is triggered, which /should/ eventually discard |this| - // as well. - navigation_commit_state_ = NavigationCommitState::kDidCommitFromIPC; return; } @@ -4557,11 +4449,6 @@ proxy->set_provisional_frame_routing_id(MSG_ROUTING_NONE); } - if (mhtml_body_loader_client_) { - mhtml_body_loader_client_->Detach(); - mhtml_body_loader_client_.reset(); - } - delete this; // Object is invalid after this point. } @@ -4755,9 +4642,6 @@ "id", routing_id_, "url", GetLoadingUrl().possibly_invalid_spec()); - if (navigation_commit_state_ == NavigationCommitState::kWillCommitFromIPC) - navigation_commit_state_ = NavigationCommitState::kDidCommitFromIPC; - InternalDocumentStateData* internal_data = InternalDocumentStateData::FromDocumentLoader( frame_->GetDocumentLoader()); @@ -5195,13 +5079,9 @@ } void RenderFrameImpl::AbortClientNavigation() { - CHECK(in_frame_tree_); browser_side_navigation_pending_ = false; sync_navigation_callback_.Cancel(); - if (mhtml_body_loader_client_) { - mhtml_body_loader_client_->Detach(); - mhtml_body_loader_client_.reset(); - } + mhtml_body_loader_client_.reset(); NotifyObserversOfFailedProvisionalLoad(); if (!IsPerNavigationMojoInterfaceEnabled()) { Send(new FrameHostMsg_AbortNavigation(routing_id_)); @@ -6270,11 +6150,6 @@ void RenderFrameImpl::BeginNavigation( std::unique_ptr<blink::WebNavigationInfo> info) { - // A provisional frame should never make a renderer-initiated navigation: no - // JS should be running in |this|, and no other frame should have a reference - // to |this|. - CHECK(in_frame_tree_); - // This method is only called for renderer initiated navigations, which // may have originated from a link-click, script, drag-n-drop operation, etc. @@ -6418,10 +6293,7 @@ } sync_navigation_callback_.Cancel(); - if (mhtml_body_loader_client_) { - mhtml_body_loader_client_->Detach(); - mhtml_body_loader_client_.reset(); - } + mhtml_body_loader_client_.reset(); // First navigation in a frame to an empty document must be handled // synchronously.
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index cf244be..eb32a30 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -1749,26 +1749,6 @@ std::unique_ptr<blink::WebURLLoaderFactoryForTest> web_url_loader_factory_override_for_test_; - // When the browser asks the renderer to commit a navigation, it should always - // result in a committed navigation reported via DidCommitProvisionalLoad(). - // This is important because DidCommitProvisionalLoad() is responsible for - // swapping in the provisional local frame during a cross-process navigation. - // Since this involves updating state in both the browser process and the - // renderer process, this assert ensures that the state remains synchronized - // between the two processes. - // - // Note: there is one exception that can result in no commit happening. - // Committing a navigation runs unload handlers, which can detach |this|. In - // that case, it doesn't matter that the navigation never commits, since the - // logical node for |this| has been removed from the DOM. - enum class NavigationCommitState { - kNone, - kWillCommitFromIPC, - kDidCommitFromIPC, - }; - class AssertNavigationCommits; - NavigationCommitState navigation_commit_state_ = NavigationCommitState::kNone; - base::WeakPtrFactory<RenderFrameImpl> weak_factory_{this}; DISALLOW_COPY_AND_ASSIGN(RenderFrameImpl);
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index 9d564f8..7581206 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc
@@ -679,6 +679,7 @@ // the browser RenderThreadImpl::RenderThreadImpl( const InProcessChildThreadParams& params, + int32_t client_id, std::unique_ptr<blink::scheduler::WebThreadScheduler> scheduler) : ChildThreadImpl(base::DoNothing(), Options::Builder() @@ -689,11 +690,23 @@ .Build()), main_thread_scheduler_(std::move(scheduler)), categorized_worker_pool_(new CategorizedWorkerPool()), - client_id_(1) { + client_id_(client_id) { TRACE_EVENT0("startup", "RenderThreadImpl::Create"); Init(); } +namespace { +int32_t GetClientIdFromCommandLine() { + DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kRendererClientId)); + int32_t client_id; + base::StringToInt(base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + switches::kRendererClientId), + &client_id); + return client_id; +} +} // anonymous namespace + // Multi-process mode. RenderThreadImpl::RenderThreadImpl( base::RepeatingClosure quit_closure, @@ -706,13 +719,9 @@ .Build()), main_thread_scheduler_(std::move(scheduler)), categorized_worker_pool_(new CategorizedWorkerPool()), - is_scroll_animator_enabled_(false) { + is_scroll_animator_enabled_(false), + client_id_(GetClientIdFromCommandLine()) { TRACE_EVENT0("startup", "RenderThreadImpl::Create"); - DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kRendererClientId)); - base::StringToInt(base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( - switches::kRendererClientId), - &client_id_); Init(); }
diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h index b9ad30fd..2709a42435 100644 --- a/content/renderer/render_thread_impl.h +++ b/content/renderer/render_thread_impl.h
@@ -151,6 +151,7 @@ std::unique_ptr<blink::scheduler::WebThreadScheduler> scheduler); RenderThreadImpl( const InProcessChildThreadParams& params, + int32_t client_id, std::unique_ptr<blink::scheduler::WebThreadScheduler> scheduler); ~RenderThreadImpl() override; void Shutdown() override;
diff --git a/content/renderer/render_thread_impl_browsertest.cc b/content/renderer/render_thread_impl_browsertest.cc index a2c265a..71222c8 100644 --- a/content/renderer/render_thread_impl_browsertest.cc +++ b/content/renderer/render_thread_impl_browsertest.cc
@@ -213,7 +213,7 @@ thread_ = new RenderThreadImpl( InProcessChildThreadParams(io_task_runner, &invitation, child_connection_->service_token()), - std::move(main_thread_scheduler)); + /*renderer_client_id=*/1, std::move(main_thread_scheduler)); cmd->InitFromArgv(old_argv); run_loop_ = std::make_unique<base::RunLoop>();
diff --git a/device/vr/windows_mixed_reality/mixed_reality_renderloop.cc b/device/vr/windows_mixed_reality/mixed_reality_renderloop.cc index 8b2d9ef..147db96 100644 --- a/device/vr/windows_mixed_reality/mixed_reality_renderloop.cc +++ b/device/vr/windows_mixed_reality/mixed_reality_renderloop.cc
@@ -427,7 +427,11 @@ // and the headset is being worn, but a modal dialog is capturing input. case HolographicSpaceUserPresence:: HolographicSpaceUserPresence_PresentPassive: - SetVisibilityState(device::mojom::XRVisibilityState::VISIBLE_BLURRED); + // TODO(1016907): Should report VISIBLE_BLURRED, but changed to VISIBLE to + // work around an issue in some versions of Windows Mixed Reality which + // only report PresentPassive and never PresentActive. Should be reverted + // after the Windows fix has been widely released. + SetVisibilityState(device::mojom::XRVisibilityState::VISIBLE); return; // Indicates that the browsers immersive content is not visible in the // headset or the user is not wearing the headset.
diff --git a/docs/android_build_instructions.md b/docs/android_build_instructions.md index 2f368e1..eaf250538 100644 --- a/docs/android_build_instructions.md +++ b/docs/android_build_instructions.md
@@ -364,7 +364,7 @@ #### Incremental Install [Incremental Install](/build/android/incremental_install/README.md) uses -reflection and side-loading to speed up the edit & deploy cycle (normally < 10 +reflection and sideloading to speed up the edit & deploy cycle (normally < 10 seconds). The initial launch of the apk will be a lot slower on older Android versions (pre-N) where the OS needs to pre-optimize the side-loaded files, but then be only marginally slower after the first launch. @@ -373,20 +373,11 @@ ```gn incremental_install = true -disable_incremental_isolated_processes = true ``` Some APKs (e.g. WebView) do not work with incremental install, and are -blacklisted from being built as such via `never_incremental = true`. - -**Bug:** Sometimes Android does not notice changes to dex files, and tries to -use prior versions. If you see impossible sounding dex exceptions, try -uninstalling then re-installing: - -```shell -out/Default/bin/chrome_public_apk uninstall -out/Default/bin/chrome_public_apk run -``` +blacklisted from being built as such (via `never_incremental = true`), so are +build as normal APKs even when `incremental_install = true`. ## Installing and Running Chromium on an Emulator
diff --git a/docs/testing/code_coverage.md b/docs/testing/code_coverage.md index f872e65..b437d132 100644 --- a/docs/testing/code_coverage.md +++ b/docs/testing/code_coverage.md
@@ -164,14 +164,14 @@ ### Step 1 Build In Chromium, to compile code with coverage enabled, one needs to add -`use_clang_coverage=true` and `is_component_build=false` GN flags to the args.gn -file in the build output directory. Under the hood, they ensure -`-fprofile-instr-generate` and `-fcoverage-mapping` flags are passed to the -compiler. +`use_clang_coverage=true`, `is_component_build=false` and `is_debug=false` GN +flags to the args.gn file in the build output directory. Under the hood, they +ensure `-fprofile-instr-generate` and `-fcoverage-mapping` flags are passed to +the compiler. ``` $ gn gen out/coverage \ - --args='use_clang_coverage=true is_component_build=false' + --args='use_clang_coverage=true is_component_build=false is_debug=false' $ gclient runhooks $ autoninja -C out/coverage crypto_unittests url_unittests ``` @@ -322,10 +322,7 @@ ### Is coverage reported for the code executed inside the sandbox? -Not at the moment until [crbug.com/842424] is resolved. We do not disable the -sandbox when running the tests. However, if there are any other non-sandbox'ed -tests for the same code, the coverage should be reported from those. For more -information, see [crbug.com/842424]. +Yes! [assert]: http://man7.org/linux/man-pages/man3/assert.3.html @@ -342,7 +339,6 @@ [crbug.com/821617]: https://crbug.com/821617 [crbug.com/831939]: https://crbug.com/831939 [crbug.com/834781]: https://crbug.com/834781 -[crbug.com/842424]: https://crbug.com/842424 [crrev.com/c/1172932]: https://crrev.com/c/1172932 [clang roll]: https://crbug.com/841908 [dead code example]: https://chromium.googlesource.com/chromium/src/+/ac6e09311fcc7e734be2ef21a9ccbbe04c4c4706 @@ -353,4 +349,3 @@ [How do crashes affect code coverage?]: #how-do-crashes-affect-code-coverage [known issues]: https://bugs.chromium.org/p/chromium/issues/list?q=component:Infra%3ETest%3ECodeCoverage [tools link]: https://storage.googleapis.com/chromium-browser-clang-staging/ -[test suite]: https://cs.chromium.org/chromium/src/tools/code_coverage/test_suite.txt
diff --git a/extensions/browser/api/cast_channel/cast_channel_apitest.cc b/extensions/browser/api/cast_channel/cast_channel_apitest.cc index 8787a78..fde69701 100644 --- a/extensions/browser/api/cast_channel/cast_channel_apitest.cc +++ b/extensions/browser/api/cast_channel/cast_channel_apitest.cc
@@ -35,7 +35,6 @@ #include "net/base/net_errors.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "testing/gmock/include/gmock/gmock.h" -#include "testing/gmock_mutant.h" using ::cast_channel::CastMessage; using ::cast_channel::CastSocket;
diff --git a/fuchsia/engine/context_provider_impl.cc b/fuchsia/engine/context_provider_impl.cc index 0a8fadfe..759ad917 100644 --- a/fuchsia/engine/context_provider_impl.cc +++ b/fuchsia/engine/context_provider_impl.cc
@@ -253,6 +253,8 @@ launch_command.AppendSwitch(switches::kEnableOopRasterization); launch_command.AppendSwitchASCII(switches::kUseGL, gl::kGLImplementationStubName); + launch_command.AppendSwitchASCII(switches::kGrContextType, + switches::kGrContextTypeVulkan); } if (enable_widevine) {
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_d3d.cc b/gpu/command_buffer/service/shared_image_backing_factory_d3d.cc index 47dfb89b..85bc5f6 100644 --- a/gpu/command_buffer/service/shared_image_backing_factory_d3d.cc +++ b/gpu/command_buffer/service/shared_image_backing_factory_d3d.cc
@@ -149,6 +149,9 @@ } private: + bool BeginAccess(GLenum mode) override; + void EndAccess() override; + scoped_refptr<gles2::TexturePassthrough> texture_passthrough_; }; @@ -205,7 +208,8 @@ scoped_refptr<gl::GLImageD3D> image, size_t buffer_index, Microsoft::WRL::ComPtr<ID3D11Texture2D> d3d11_texture, - base::win::ScopedHandle shared_handle) + base::win::ScopedHandle shared_handle, + Microsoft::WRL::ComPtr<IDXGIKeyedMutex> dxgi_keyed_mutex) : SharedImageBacking(mailbox, format, size, @@ -220,7 +224,8 @@ image_(std::move(image)), buffer_index_(buffer_index), d3d11_texture_(std::move(d3d11_texture)), - shared_handle_(std::move(shared_handle)) { + shared_handle_(std::move(shared_handle)), + dxgi_keyed_mutex_(std::move(dxgi_keyed_mutex)) { DCHECK(d3d11_texture_); DCHECK((texture_ && !texture_passthrough_) || (!texture_ && texture_passthrough_)); @@ -273,6 +278,9 @@ } swap_chain_ = nullptr; d3d11_texture_.Reset(); + dxgi_keyed_mutex_.Reset(); + keyed_mutex_acquire_key_ = 0; + keyed_mutex_acquired_ = false; shared_handle_.Close(); } @@ -296,6 +304,48 @@ image_->OnMemoryDump(pmd, client_tracing_id, dump_name); } + bool BeginAccessD3D12(uint64_t* acquire_key) { + if (keyed_mutex_acquired_) { + DLOG(ERROR) << "Recursive BeginAccess not supported"; + return false; + } + *acquire_key = keyed_mutex_acquire_key_; + keyed_mutex_acquire_key_++; + keyed_mutex_acquired_ = true; + return true; + } + + void EndAccessD3D12() { keyed_mutex_acquired_ = false; } + + bool BeginAccessD3D11() { + if (dxgi_keyed_mutex_) { + if (keyed_mutex_acquired_) { + DLOG(ERROR) << "Recursive BeginAccess not supported"; + return false; + } + const HRESULT hr = + dxgi_keyed_mutex_->AcquireSync(keyed_mutex_acquire_key_, INFINITE); + if (FAILED(hr)) { + DLOG(ERROR) << "Unable to acquire the keyed mutex " << std::hex << hr; + return false; + } + keyed_mutex_acquire_key_++; + keyed_mutex_acquired_ = true; + } + return true; + } + void EndAccessD3D11() { + if (dxgi_keyed_mutex_) { + const HRESULT hr = + dxgi_keyed_mutex_->ReleaseSync(keyed_mutex_acquire_key_); + if (FAILED(hr)) { + DLOG(ERROR) << "Unable to release the keyed mutex " << std::hex << hr; + return; + } + keyed_mutex_acquired_ = false; + } + } + HANDLE GetSharedHandle() const { return shared_handle_.Get(); } bool PresentSwapChain() override { @@ -362,7 +412,20 @@ scoped_refptr<gl::GLImageD3D> image_; const size_t buffer_index_; Microsoft::WRL::ComPtr<ID3D11Texture2D> d3d11_texture_; + + // If d3d11_texture_ has a keyed mutex, it will be stored in + // dxgi_keyed_mutex. The keyed mutex is used to synchronize + // D3D11 and D3D12 Chromium components. + // dxgi_keyed_mutex_ is the D3D11 side of the keyed mutex. + // To create the corresponding D3D12 interface, pass the handle + // stored in shared_handle_ to ID3D12Device::OpenSharedHandle. + // Only one component is allowed to read/write to the texture + // at a time. keyed_mutex_acquire_key_ is incremented on every + // Acquire/Release usage. base::win::ScopedHandle shared_handle_; + Microsoft::WRL::ComPtr<IDXGIKeyedMutex> dxgi_keyed_mutex_; + uint64_t keyed_mutex_acquire_key_ = 0; + bool keyed_mutex_acquired_ = false; DISALLOW_COPY_AND_ASSIGN(SharedImageBackingD3D); }; @@ -382,6 +445,11 @@ return nullptr; } + uint64_t shared_mutex_acquire_key; + if (!d3d_image_backing->BeginAccessD3D12(&shared_mutex_acquire_key)) { + return nullptr; + } + DawnTextureDescriptor desc; desc.nextInChain = nullptr; desc.format = dawn_texture_format.value(); @@ -392,8 +460,8 @@ desc.mipLevelCount = 1; desc.sampleCount = 1; - texture_ = - dawn_native::d3d12::WrapSharedHandle(device_, &desc, shared_handle, 0); + texture_ = dawn_native::d3d12::WrapSharedHandle(device_, &desc, shared_handle, + shared_mutex_acquire_key); if (texture_) { // Keep a reference to the texture so that it stays valid (its content // might be destroyed). @@ -406,6 +474,8 @@ // uninitialized data. When !IsCleared we should tell dawn_native to // consider the texture lazy-cleared. SetCleared(); + } else { + d3d_image_backing->EndAccessD3D12(); } return texture_; @@ -416,6 +486,9 @@ return; } + SharedImageBackingD3D* d3d_image_backing = + static_cast<SharedImageBackingD3D*>(backing()); + // TODO(cwallez@chromium.org): query dawn_native to know if the texture was // cleared and set IsCleared appropriately. @@ -425,9 +498,24 @@ dawn_procs_.textureRelease(texture_); texture_ = nullptr; + + d3d_image_backing->EndAccessD3D12(); } #endif // BUILDFLAG(USE_DAWN) +bool SharedImageRepresentationGLTexturePassthroughD3D::BeginAccess( + GLenum mode) { + SharedImageBackingD3D* d3d_image_backing = + static_cast<SharedImageBackingD3D*>(backing()); + return d3d_image_backing->BeginAccessD3D11(); +} + +void SharedImageRepresentationGLTexturePassthroughD3D::EndAccess() { + SharedImageBackingD3D* d3d_image_backing = + static_cast<SharedImageBackingD3D*>(backing()); + d3d_image_backing->EndAccessD3D11(); +} + SharedImageBackingFactoryD3D::SharedImageBackingFactoryD3D(bool use_passthrough) : use_passthrough_(use_passthrough), d3d11_device_(gl::QueryD3D11DeviceObjectFromANGLE()) { @@ -478,6 +566,8 @@ api->glTexParameteriFn(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); api->glTexParameteriFn(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + Microsoft::WRL::ComPtr<IDXGIKeyedMutex> dxgi_keyed_mutex; + if (swap_chain) { DCHECK(!d3d11_texture); DCHECK(!shared_handle.IsValid()); @@ -487,9 +577,16 @@ DLOG(ERROR) << "GetBuffer failed with error " << std::hex; return nullptr; } - } else { - DCHECK(d3d11_texture); + } else if (shared_handle.IsValid()) { + const HRESULT hr = d3d11_texture.As(&dxgi_keyed_mutex); + if (FAILED(hr)) { + DLOG(ERROR) << "Unable to QueryInterface for IDXGIKeyedMutex on texture " + "with shared handle " + << std::hex; + return nullptr; + } } + DCHECK(d3d11_texture); // The GL internal format can differ from the underlying swap chain format // e.g. RGBA8 or RGB8 instead of BGRA8. @@ -538,7 +635,8 @@ return std::make_unique<SharedImageBackingD3D>( mailbox, format, size, color_space, usage, std::move(swap_chain), texture, std::move(texture_passthrough), std::move(image), buffer_index, - std::move(d3d11_texture), std::move(shared_handle)); + std::move(d3d11_texture), std::move(shared_handle), + std::move(dxgi_keyed_mutex)); } SharedImageBackingFactoryD3D::SwapChainBackings @@ -671,8 +769,8 @@ desc.Usage = D3D11_USAGE_DEFAULT; desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; desc.CPUAccessFlags = 0; - desc.MiscFlags = - D3D11_RESOURCE_MISC_SHARED_NTHANDLE | D3D11_RESOURCE_MISC_SHARED; + desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_NTHANDLE | + D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX; Microsoft::WRL::ComPtr<ID3D11Texture2D> d3d11_texture; HRESULT hr = d3d11_device_->CreateTexture2D(&desc, nullptr, &d3d11_texture); if (FAILED(hr)) {
diff --git a/gpu/command_buffer/tests/webgpu_test.cc b/gpu/command_buffer/tests/webgpu_test.cc index de660721..db56128 100644 --- a/gpu/command_buffer/tests/webgpu_test.cc +++ b/gpu/command_buffer/tests/webgpu_test.cc
@@ -31,7 +31,8 @@ bool WebGPUTest::WebGPUSharedImageSupported() const { // Currently WebGPUSharedImage is only implemented on Mac, Linux and Windows -#if (defined(OS_MACOSX) || defined(OS_LINUX)) && BUILDFLAG(USE_DAWN) +#if (defined(OS_MACOSX) || defined(OS_LINUX) || defined(OS_WIN)) && \ + BUILDFLAG(USE_DAWN) return true; #else return false;
diff --git a/gpu/ipc/common/BUILD.gn b/gpu/ipc/common/BUILD.gn index 9ff12f1..83f8fe1 100644 --- a/gpu/ipc/common/BUILD.gn +++ b/gpu/ipc/common/BUILD.gn
@@ -200,6 +200,7 @@ } mojom("interfaces") { + generate_java = true sources = [ "capabilities.mojom", "context_result.mojom", @@ -224,6 +225,7 @@ } mojom("gpu_preferences_interface") { + generate_java = true sources = [ "gpu_preferences.mojom", ]
diff --git a/media/audio/audio_input_device_unittest.cc b/media/audio/audio_input_device_unittest.cc index 94209750..16f0414 100644 --- a/media/audio/audio_input_device_unittest.cc +++ b/media/audio/audio_input_device_unittest.cc
@@ -14,7 +14,6 @@ #include "base/sync_socket.h" #include "base/test/task_environment.h" #include "testing/gmock/include/gmock/gmock.h" -#include "testing/gmock_mutant.h" #include "testing/gtest/include/gtest/gtest.h" using base::CancelableSyncSocket;
diff --git a/media/audio/win/audio_low_latency_output_win_unittest.cc b/media/audio/win/audio_low_latency_output_win_unittest.cc index a56ab63a..3005903 100644 --- a/media/audio/win/audio_low_latency_output_win_unittest.cc +++ b/media/audio/win/audio_low_latency_output_win_unittest.cc
@@ -34,18 +34,11 @@ #include "media/base/seekable_buffer.h" #include "media/base/test_data_util.h" #include "testing/gmock/include/gmock/gmock.h" -#include "testing/gmock_mutant.h" #include "testing/gtest/include/gtest/gtest.h" using ::base::ThreadTaskRunnerHandle; using ::testing::_; -using ::testing::AnyNumber; -using ::testing::AtLeast; -using ::testing::Between; -using ::testing::CreateFunctor; using ::testing::DoAll; -using ::testing::Gt; -using ::testing::InvokeWithoutArgs; using ::testing::NotNull; using ::testing::Return;
diff --git a/media/capture/mojom/BUILD.gn b/media/capture/mojom/BUILD.gn index ebadbd0..87209b9 100644 --- a/media/capture/mojom/BUILD.gn +++ b/media/capture/mojom/BUILD.gn
@@ -5,6 +5,7 @@ import("//mojo/public/tools/bindings/mojom.gni") mojom("video_capture") { + generate_java = true sources = [ "video_capture.mojom", "video_capture_types.mojom",
diff --git a/media/learning/mojo/public/mojom/BUILD.gn b/media/learning/mojo/public/mojom/BUILD.gn index 3d0a1f5..403921c8 100644 --- a/media/learning/mojo/public/mojom/BUILD.gn +++ b/media/learning/mojo/public/mojom/BUILD.gn
@@ -6,6 +6,7 @@ import("//mojo/public/tools/bindings/mojom.gni") mojom("mojom") { + generate_java = true sources = [ "learning_task_controller.mojom", "learning_types.mojom",
diff --git a/media/mojo/mojom/BUILD.gn b/media/mojo/mojom/BUILD.gn index d3788eac..6d11386 100644 --- a/media/mojo/mojom/BUILD.gn +++ b/media/mojo/mojom/BUILD.gn
@@ -6,6 +6,8 @@ import("//mojo/public/tools/bindings/mojom.gni") mojom("mojom") { + generate_java = true + # TODO(crbug.com/676224): Conditionally add source files in this list when we # support EnabledIf attribute in mojom files. sources = [
diff --git a/media/renderers/paint_canvas_video_renderer.cc b/media/renderers/paint_canvas_video_renderer.cc index a20127a..3374146 100644 --- a/media/renderers/paint_canvas_video_renderer.cc +++ b/media/renderers/paint_canvas_video_renderer.cc
@@ -433,7 +433,7 @@ const uint8_t* data = video_frame->visible_data(plane); int rows = video_frame->rows(plane); meta.data = - data + meta.stride * chunk_start * rows_per_chunk * rows / height; + data + meta.stride * (chunk_start * rows_per_chunk * rows / height); } }
diff --git a/media/renderers/video_renderer_impl_unittest.cc b/media/renderers/video_renderer_impl_unittest.cc index c59374c..87345cfb 100644 --- a/media/renderers/video_renderer_impl_unittest.cc +++ b/media/renderers/video_renderer_impl_unittest.cc
@@ -35,7 +35,6 @@ #include "media/base/wall_clock_time_source.h" #include "media/renderers/video_renderer_impl.h" #include "media/video/mock_gpu_memory_buffer_video_frame_pool.h" -#include "testing/gmock_mutant.h" #include "testing/gtest/include/gtest/gtest.h" using ::base::test::RunCallback; @@ -44,7 +43,6 @@ using ::testing::_; using ::testing::AnyNumber; using ::testing::Combine; -using ::testing::CreateFunctor; using ::testing::DoAll; using ::testing::Invoke; using ::testing::Mock; @@ -224,7 +222,9 @@ WaitableMessageLoopEvent event; PipelineStatusCB error_cb = event.GetPipelineStatusCB(); - EXPECT_CALL(mock_cb_, OnError(_)).WillOnce(Invoke(CreateFunctor(error_cb))); + EXPECT_CALL(mock_cb_, OnError(_)) + .WillOnce(Invoke( + [error_cb](PipelineStatus status) { error_cb.Run(status); })); event.RunAndWaitForStatus(expected); }
diff --git a/mojo/public/interfaces/bindings/BUILD.gn b/mojo/public/interfaces/bindings/BUILD.gn index eca88c6..29fad88 100644 --- a/mojo/public/interfaces/bindings/BUILD.gn +++ b/mojo/public/interfaces/bindings/BUILD.gn
@@ -5,6 +5,7 @@ import("../../tools/bindings/mojom.gni") mojom_component("bindings") { + generate_java = true output_prefix = "mojo_mojom_bindings" macro_prefix = "MOJO_MOJOM_BINDINGS"
diff --git a/mojo/public/interfaces/bindings/tests/BUILD.gn b/mojo/public/interfaces/bindings/tests/BUILD.gn index 97f241a7..fc7222c 100644 --- a/mojo/public/interfaces/bindings/tests/BUILD.gn +++ b/mojo/public/interfaces/bindings/tests/BUILD.gn
@@ -276,6 +276,7 @@ mojom("test_interfaces") { testonly = true + generate_java = true sources = [ "math_calculator.mojom", "no_module.mojom", @@ -391,6 +392,7 @@ mojom("test_mojom_import") { testonly = true + generate_java = true sources = [ "sample_import.mojom", ] @@ -398,6 +400,7 @@ mojom("test_mojom_import_wrapper") { testonly = true + generate_java = true public_deps = [ ":test_mojom_import", ] @@ -405,6 +408,7 @@ mojom("test_mojom_import_wrapper_wrapper") { testonly = true + generate_java = true public_deps = [ ":test_mojom_import_wrapper", ] @@ -412,6 +416,7 @@ mojom("test_mojom_import2") { testonly = true + generate_java = true sources = [ "sample_import2.mojom", ] @@ -480,6 +485,7 @@ mojom("echo") { testonly = true + generate_java = true sources = [ "echo.mojom", "echo_import/echo_import.mojom", @@ -489,6 +495,7 @@ # These could probably be merged with "test_interfaces" at some point. mojom("other_test_interfaces") { testonly = true + generate_java = true sources = [ "new_endpoint_types.test-mojom", ]
diff --git a/mojo/public/mojom/base/BUILD.gn b/mojo/public/mojom/base/BUILD.gn index 600db56..a99ad79 100644 --- a/mojo/public/mojom/base/BUILD.gn +++ b/mojo/public/mojom/base/BUILD.gn
@@ -5,6 +5,7 @@ import("//mojo/public/tools/bindings/mojom.gni") mojom_component("base") { + generate_java = true sources = [ "application_state.mojom", "big_buffer.mojom",
diff --git a/mojo/public/tools/bindings/mojom.gni b/mojo/public/tools/bindings/mojom.gni index 09156d0..1f65a32 100644 --- a/mojo/public/tools/bindings/mojom.gni +++ b/mojo/public/tools/bindings/mojom.gni
@@ -219,6 +219,11 @@ # will still be generated even when |cpp_only| is set to |true|, unless # you also set |enable_fuzzing| to |false| in your mojom target. # +# generate_java (optional) +# If set to true, Java bindings are generated for Android builds. If +# |cpp_only| is set to true, it overrides this to prevent generation of +# Java bindings. +# # enable_fuzzing (optional) # Enables generation of fuzzing sources for the target if the global build # arg |enable_ipc_fuzzer| is also set to |true|. Defaults to |true|. If @@ -773,6 +778,10 @@ variant_suffix = "_${variant}" cpp_only = true } + generate_java = false + if (!cpp_only && defined(invoker.generate_java)) { + generate_java = invoker.generate_java + } type_mappings_target_name = "${target_name}${variant_suffix}__type_mappings" type_mappings_path = "$target_gen_dir/${target_name}${variant_suffix}__type_mappings" @@ -1135,7 +1144,7 @@ } } - if (!cpp_only && is_android) { + if (generate_java && is_android) { import("//build/config/android/rules.gni") java_generator_target_name = target_name + "_java__generator"
diff --git a/net/BUILD.gn b/net/BUILD.gn index 8b5acb40..81b124d 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -5695,7 +5695,6 @@ "url_request/url_fetcher_response_writer_unittest.cc", "url_request/url_request_context_builder_unittest.cc", "url_request/url_request_context_unittest.cc", - "url_request/url_request_data_job_unittest.cc", "url_request/url_request_filter_unittest.cc", "url_request/url_request_ftp_job_unittest.cc", "url_request/url_request_http_job_unittest.cc", @@ -6253,9 +6252,9 @@ ] } -fuzzer_test("net_data_job_fuzzer") { +fuzzer_test("net_data_url_fuzzer") { sources = [ - "url_request/url_request_data_job_fuzzer.cc", + "base/data_url_fuzzer.cc", ] deps = [ ":net_fuzzer_test_support", @@ -6263,6 +6262,7 @@ "//base", "//net", ] + dict = "data/fuzzer_dictionaries/net_data_url_fuzzer.dict" } fuzzer_test("net_mime_sniffer_fuzzer") { @@ -6326,18 +6326,6 @@ dict = "data/fuzzer_dictionaries/net_parse_proxy_bypass_rules_fuzzer.dict" } -fuzzer_test("net_parse_data_url_fuzzer") { - sources = [ - "base/parse_data_url_fuzzer.cc", - ] - deps = [ - ":net_fuzzer_test_support", - "//base", - "//net", - ] - dict = "data/fuzzer_dictionaries/net_parse_data_url_fuzzer.dict" -} - fuzzer_test("net_parse_ip_pattern_fuzzer") { sources = [ "base/parse_ip_pattern_fuzzer.cc",
diff --git a/net/base/data_url.cc b/net/base/data_url.cc index 90b0bb6..29a3965 100644 --- a/net/base/data_url.cc +++ b/net/base/data_url.cc
@@ -15,12 +15,12 @@ #include "base/strings/string_util.h" #include "net/base/escape.h" #include "net/base/mime_util.h" +#include "net/http/http_response_headers.h" #include "net/http/http_util.h" #include "url/gurl.h" namespace net { -// static bool DataURL::Parse(const GURL& url, std::string* mime_type, std::string* charset, @@ -139,4 +139,38 @@ return true; } +Error DataURL::BuildResponse(const GURL& url, + base::StringPiece method, + std::string* mime_type, + std::string* charset, + std::string* data, + HttpResponseHeaders* headers) { + DCHECK(data); + + if (!DataURL::Parse(url, mime_type, charset, data)) + return ERR_INVALID_URL; + + // |mime_type| set by DataURL::Parse() is guaranteed to be in + // token "/" token + // form. |charset| can be an empty string. + DCHECK(!mime_type->empty()); + + if (headers) { + headers->ReplaceStatusLine("HTTP/1.1 200 OK"); + // "charset" in the Content-Type header is specified explicitly to follow + // the "token" ABNF in the HTTP spec. When the DataURL::Parse() call is + // successful, it's guaranteed that the string in |charset| follows the + // "token" ABNF. + std::string content_type_header = "Content-Type: " + *mime_type; + if (!charset->empty()) + content_type_header.append(";charset=" + *charset); + headers->AddHeader(content_type_header); + } + + if (base::EqualsCaseInsensitiveASCII(method, "HEAD")) + data->clear(); + + return OK; +} + } // namespace net
diff --git a/net/base/data_url.h b/net/base/data_url.h index ee9c6d3..b1bc783 100644 --- a/net/base/data_url.h +++ b/net/base/data_url.h
@@ -7,12 +7,17 @@ #include <string> +#include "base/compiler_specific.h" +#include "base/strings/string_piece.h" +#include "net/base/net_errors.h" #include "net/base/net_export.h" class GURL; namespace net { +class HttpResponseHeaders; + // See RFC 2397 for a complete description of the 'data' URL scheme. // // Briefly, a 'data' URL has the form: @@ -55,11 +60,25 @@ // // OPTIONAL: If |data| is NULL, then the <data> section will not be parsed // or validated. - // static bool Parse(const GURL& url, std::string* mime_type, std::string* charset, - std::string* data); + std::string* data) WARN_UNUSED_RESULT; + + // Similar to parse, except that it also generates a bogus set of response + // headers, with Content-Type populated, and takes a method. Only the "HEAD" + // method modifies the response, resulting in a 0-length body. All arguments + // except |headers| must be non-null. Return net::OK on success. + // + // TODO(mmenke): Make headers mandatory, once URLRequestDataJob has been + // removed. Also improve how it's returned, as requiring consumer to create + // an empty object is strange. + static Error BuildResponse(const GURL& url, + base::StringPiece method, + std::string* mime_type, + std::string* charset, + std::string* data, + HttpResponseHeaders* headers) WARN_UNUSED_RESULT; }; } // namespace net
diff --git a/net/base/data_url_fuzzer.cc b/net/base/data_url_fuzzer.cc new file mode 100644 index 0000000..7743a47f --- /dev/null +++ b/net/base/data_url_fuzzer.cc
@@ -0,0 +1,43 @@ +// 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. + +#include "net/base/data_url.h" + +#include <stddef.h> +#include <stdint.h> + +#include <fuzzer/FuzzedDataProvider.h> + +#include <string> + +#include "base/logging.h" +#include "base/memory/ref_counted.h" +#include "net/base/net_errors.h" +#include "net/http/http_response_headers.h" +#include "url/gurl.h" + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + FuzzedDataProvider provider(data, size); + std::string method = provider.ConsumeRandomLengthString(256); + // Don't restrict to data URLs. + GURL url(provider.ConsumeRemainingBytesAsString()); + + std::string mime_type; + std::string charset; + std::string body; + + std::string mime_type2; + std::string charset2; + std::string body2; + scoped_refptr<net::HttpResponseHeaders> headers( + base::MakeRefCounted<net::HttpResponseHeaders>(std::string())); + + // Run the URL through DataURL::Parse() and DataURL::BuildResponse(). They + // should succeed and fail in exactly the same cases. + CHECK_EQ( + net::DataURL::Parse(url, &mime_type, &charset, &body), + net::OK == net::DataURL::BuildResponse(url, method, &mime_type2, + &charset2, &body2, headers.get())); + return 0; +}
diff --git a/net/base/data_url_unittest.cc b/net/base/data_url_unittest.cc index 80d26715..44de113 100644 --- a/net/base/data_url_unittest.cc +++ b/net/base/data_url_unittest.cc
@@ -3,6 +3,11 @@ // found in the LICENSE file. #include "net/base/data_url.h" + +#include "base/memory/ref_counted.h" +#include "net/base/net_errors.h" +#include "net/http/http_response_headers.h" +#include "net/http/http_version.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -15,7 +20,7 @@ bool is_valid; const char* mime_type; const char* charset; - const char* data; + const std::string data; }; } // namespace @@ -131,7 +136,16 @@ {"data:text/plain,this/is/a/test/%23include/#dontinclude", true, "text/plain", "", "this/is/a/test/#include/"}, - // TODO(darin): add more interesting tests + // More unescaping tests and tests with nulls. + {"data:%00text/plain%41,foo", true, "%00text/plain%41", "", "foo"}, + {"data:text/plain;charset=%00US-ASCII%41,foo", true, "text/plain", + "%00US-ASCII%41", "foo"}, + {"data:text/plain,%00_%41", true, "text/plain", "", + std::string("\x00_A", 3)}, + {"data:text/plain;base64,AA//", true, "text/plain", "", + std::string("\x00\x0F\xFF", 3)}, + // "%62ase64" unescapes to base64, but should not be treated as such. + {"data:text/plain;%62ase64,AA//", true, "text/plain", "", "AA//"}, }; for (const auto& test : tests) { @@ -148,4 +162,98 @@ } } +TEST(DataURLTest, BuildResponseSimple) { + std::string mime_type; + std::string charset; + std::string data; + scoped_refptr<HttpResponseHeaders> headers( + new HttpResponseHeaders(std::string())); + + ASSERT_EQ(OK, DataURL::BuildResponse(GURL("data:,Hello"), "GET", &mime_type, + &charset, &data, headers.get())); + + EXPECT_EQ("text/plain", mime_type); + EXPECT_EQ("US-ASCII", charset); + EXPECT_EQ("Hello", data); + + const HttpVersion& version = headers->GetHttpVersion(); + EXPECT_EQ(1, version.major_value()); + EXPECT_EQ(1, version.minor_value()); + EXPECT_EQ("OK", headers->GetStatusText()); + std::string value; + EXPECT_TRUE(headers->GetNormalizedHeader("Content-Type", &value)); + EXPECT_EQ(value, "text/plain;charset=US-ASCII"); + value.clear(); +} + +TEST(DataURLTest, BuildResponseHead) { + for (const char* method : {"HEAD", "head", "hEaD"}) { + SCOPED_TRACE(method); + + std::string mime_type; + std::string charset; + std::string data; + scoped_refptr<HttpResponseHeaders> headers = + HttpResponseHeaders::TryToCreate(""); + ASSERT_EQ(OK, + DataURL::BuildResponse(GURL("data:,Hello"), method, &mime_type, + &charset, &data, headers.get())); + + EXPECT_EQ("text/plain", mime_type); + EXPECT_EQ("US-ASCII", charset); + EXPECT_EQ("", data); + + HttpVersion version = headers->GetHttpVersion(); + EXPECT_EQ(1, version.major_value()); + EXPECT_EQ(1, version.minor_value()); + EXPECT_EQ("OK", headers->GetStatusText()); + std::string content_type; + EXPECT_TRUE(headers->GetNormalizedHeader("Content-Type", &content_type)); + EXPECT_EQ(content_type, "text/plain;charset=US-ASCII"); + } +} + +TEST(DataURLTest, BuildResponseInput) { + std::string mime_type; + std::string charset; + std::string data; + scoped_refptr<HttpResponseHeaders> headers( + new HttpResponseHeaders(std::string())); + + ASSERT_EQ(ERR_INVALID_URL, + DataURL::BuildResponse(GURL("bogus"), "GET", &mime_type, &charset, + &data, headers.get())); +} + +TEST(DataURLTest, BuildResponseInvalidMimeType) { + std::string mime_type; + std::string charset; + std::string data; + scoped_refptr<HttpResponseHeaders> headers( + new HttpResponseHeaders(std::string())); + + // MIME type contains delimiters. Must be accepted but Content-Type header + // should be generated as if the mediatype was text/plain. + ASSERT_EQ(OK, + DataURL::BuildResponse(GURL("data:f(o/b)r,test"), "GET", &mime_type, + &charset, &data, headers.get())); + + std::string value; + EXPECT_TRUE(headers->GetNormalizedHeader("Content-Type", &value)); + EXPECT_EQ(value, "text/plain;charset=US-ASCII"); +} + +TEST(DataURLTest, InvalidCharset) { + std::string mime_type; + std::string charset; + std::string data; + scoped_refptr<HttpResponseHeaders> headers( + new HttpResponseHeaders(std::string())); + + // MIME type contains delimiters. Must be rejected. + ASSERT_EQ(ERR_INVALID_URL, DataURL::BuildResponse( + GURL("data:text/html;charset=(),test"), "GET", + &mime_type, &charset, &data, headers.get())); +} + } // namespace net
diff --git a/net/base/parse_data_url_fuzzer.cc b/net/base/parse_data_url_fuzzer.cc deleted file mode 100644 index f91b691..0000000 --- a/net/base/parse_data_url_fuzzer.cc +++ /dev/null
@@ -1,19 +0,0 @@ -// Copyright 2016 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. - -#include <stddef.h> -#include <stdint.h> - -#include "net/base/data_url.h" -#include "url/gurl.h" - -// Entry point for LibFuzzer. -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - std::string input(data, data + size); - std::string mime_type; - std::string charset; - std::string urldata; - net::DataURL::Parse(GURL(input), &mime_type, &charset, &urldata); - return 0; -}
diff --git a/net/data/fuzzer_dictionaries/net_data_url_fuzzer.dict b/net/data/fuzzer_dictionaries/net_data_url_fuzzer.dict new file mode 100644 index 0000000..7f40fd3 --- /dev/null +++ b/net/data/fuzzer_dictionaries/net_data_url_fuzzer.dict
@@ -0,0 +1,29 @@ +# 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. + +"GET" +"HEAD" + +"data:" +"data:," + +"text/html" +"text/plain" +"image/png" +"text/plain," +"charset=" +"US-ASCII" +";charset=US-ASCII" + +"base64" +"base64," +";base64," +";base64" + +"all" +"%" +"," +";" +"%20" +"%00"
diff --git a/net/data/fuzzer_dictionaries/net_parse_data_url_fuzzer.dict b/net/data/fuzzer_dictionaries/net_parse_data_url_fuzzer.dict deleted file mode 100644 index 1668f4c..0000000 --- a/net/data/fuzzer_dictionaries/net_parse_data_url_fuzzer.dict +++ /dev/null
@@ -1,449 +0,0 @@ -# Copyright 2016 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. - -# This file has been generated with testing/libfuzzer/dictionary_generator.py -# using net_parse_data_url_fuzzer binary and RFC 3986. -"all" -"DNS" -"text" -"labels" -"DQUOTE" -"\"%D3%81%87%A4%95%81@%C2%85%81%83%88\"." -"[RFC2234]" -"F.," -"FORCE" -"SOCIETY" -"\"%\"" -"with" -"cache" -"WINS," -"D.1." -"0" -"only" -"HTML" -"SPONSORED" -"[RFC1630]." -"D.," -"[RFC1123]" -"US-ASCII" -"(STD" -"[RFC1808]," -"string" -"get" -"==" -"H" -"HEREIN" -"[BCP35]" -"SP)" -"SCTP)" -"(NUL)" -"THE" -"(URI):" -"REPRESENTS" -"[RFC2732]." -"resource" -"A.," -"EXPRESS" -"list" -"(%2E)," -"WILL" -"HE/SHE" -"J." -"INCLUDING" -"common" -"segment." -"[RFC2732]" -"(URL)\"," -"set" -"HTTP" -"IANA" -"INFORMATION" -"(%41-%5A" -"[RFC2518]" -"M." -"direct" -"sign" -"Only" -"Version" -"are" -"allowed." -"\"X\"" -"HTTP," -"(SP)." -"2DIGIT" -"section" -"BUT" -"\"UTF-8," -"3" -"version" -"[RFC1034]" -"probably" -"[UCS]," -"metadata" -"Y.," -"C" -"WWW\"" -"parent" -"0X" -"W3C/IETF" -"S" -"key" -"address" -"INPUT" -"[" -"P." -"WWW:" -"AND" -"received" -"WWW" -"[BCP35]." -"MA" -"\"AS" -"[RFC2718]." -"(IDNA)\"," -"implementation" -"TCP" -"NOT" -"(URN)" -"ANY" -"[RFC1808]" -"WARRANTY" -"useful" -"[RFC1737]." -"[STD63]," -"\"HTTP\"" -"(MIME)" -"TELNET" -"[RFC1630]" -"S." -"D.2." -"B.," -"[RFC2234]." -"[RFC2234]," -"BCP" -"select" -"[STD63];" -"use" -"LATIN" -"from" -"C." -"to" -"WARRANTIES" -"(MHTML)\"," -"ENGINEERING" -"URI;" -"." -"few" -"(DNS)." -"expected" -"USENET" -"type" -"empty" -"XML" -"URL?\"," -"W3C/MIT" -"F" -"CA" -"STD:" -"SMTP" -"[RFC2141]," -"N" -"A)," -"flag" -"NOTE:" -"CR" -"MHTML" -"BY" -"must" -"ANY)," -"ALL" -"[STD63]" -"RIGHTS" -"this" -"SP" -"[BCP19]" -"value" -"INFRINGE" -"while" -"KATAKANA" -"resources" -"error" -"following" -"example" -"loop" -"J.," -"2E:" -"type." -"L." -"have" -"%61-%7A)," -"is" -"allowed" -"thus" -"URI," -"parse" -"STEP" -"MIME" -"UTF-8" -"in" -"[RFC0952]." -"native" -"FOR" -"binary" -"ISO/IEC" -"\"A" -"(%5F)," -")" -"algorithm." -"returning" -"\"A\"," -"[RFC2141]" -"BUFFER" -"ABNF" -"[RFC2557]." -"I." -"WARRANTIES," -"URN" -"EBCDIC" -"A" -"LF" -"used" -"http" -"I" -"IP" -"IS" -"after" -"L" -"Q" -"'A'" -"running" -"HEXDIG" -"such" -"EBCDIC," -"data" -"TASK" -"a" -"task" -"P" -"[ASCII]." -"M.," -"Names" -"flag." -"the" -"If" -"[RFC3490]" -"US-ASCII." -"2C:" -"THAT" -"being" -"when" -"E.," -"(%2D)," -"\"URL:\"" -"mechanism" -"WITH" -"its" -"before" -"tables" -"[UCS]" -"TO" -"BNF" -"platform" -"internal" -"P.," -"ORGANIZATION" -"\"HTTP" -"URI." -"it," -"D" -"format" -"URL" -"S.," -"(0" -"URI\"" -"URI" -"K." -"URI:" -"T" -"D.W." -"not" -"R." -"LIMITED" -"\"%3A\")" -"name" -"OF" -"B." -"[RFC1736]" -"(R)," -"IPR" -"[RFC1738];" -"OUTPUT" -"LALR" -"OR" -"STD" -"[RFC3513]" -"because" -"bytes" -"DNS," -"some" -"back" -"(URI)" -"*DIGIT" -"[RFC2046]" -"[RFC3305]" -"\"%7E\"" -"W3C" -"E." -"for" -"space" -"ABNF\"," -"avoid" -"[RFC1535]." -"/" -"increase" -"may" -"time." -"does" -"'F'" -"[RFC2396]" -"be" -"K.," -"DISCLAIM" -"G" -"(UTF-16)," -"This" -"M" -"INTERNET" -"RFC" -"X3.4," -"base" -"(T):" -"IMPLIED," -"by" -"\"URL\"" -"on" -"DIGIT" -"(ABNF)" -"WEBDAV\"," -"of" -"could" -"R.," -"(ABNF:" -"failed" -"or" -"1*4HEXDIG" -"already" -"No" -"CAPITAL" -"number" -"one" -"ISO" -"FITNESS" -"message" -"open" -"ANSI" -"[BCP19]," -"\"%C3%80\"," -"IETF" -"unknown" -"support" -"\"URN" -"[RFC1123]." -"long" -"[RFC0952]" -"[ASCII]" -":" -"was" -"[RFC3513]." -"[RFC2718]" -"B" -"N." -"that" -"IDNA" -"OCTET" -"but" -"R" -"POSIX" -"LETTER" -"CONTRIBUTOR," -"[RFC1738]" -"line" -"(C)" -"true" -"\"URI\"" -"PARTICULAR" -"target" -"16" -"default" -"double" -"\"URN\"" -"[RFC2557]" -"enabled" -"up" -"TCP," -"PURPOSE." -"MERCHANTABILITY" -"1)" -"IS\"" -"\"IANA" -"called" -"multipart" -"and" -"USE" -"false" -"(IF" -"USA" -"URL," -"an" -"To" -"as" -"(%7E)" -"at" -"file" -"need" -"any" -"\"%E3%82%A2\"." -"physical" -"1*HEXDIG" -"no" -"[RFC1737]" -"-" -"invalid" -"A." -"application" -"valid" -"take" -"which" -"test" -"[RFC2732]," -"you" -"=" -"GRAVE" -"<URI>" -"begin" -"[RFC2396]," -"multiple" -"2B:" -"period," -"UDP," -"[RFC1535]" -"T." -"(UCS)\"," -"U" -"A-F." -"T.," -"The" -"]" -"source" -"D." -"persistent" -"traditional" -"L.," -"As" -"IMPLIED" -"(URL)" -"ALPHA" -"[RFC3305]." -"H.," -"\"MIME"
diff --git a/net/http/http_response_info.cc b/net/http/http_response_info.cc index 1d2af6cea..6363bee4 100644 --- a/net/http/http_response_info.cc +++ b/net/http/http_response_info.cc
@@ -118,6 +118,57 @@ // For now, we don't support storing those. }; +HttpResponseInfo::ConnectionInfoCoarse HttpResponseInfo::ConnectionInfoToCoarse( + ConnectionInfo info) { + switch (info) { + case CONNECTION_INFO_HTTP0_9: + case CONNECTION_INFO_HTTP1_0: + case CONNECTION_INFO_HTTP1_1: + return CONNECTION_INFO_COARSE_HTTP1; + + case CONNECTION_INFO_HTTP2: + case CONNECTION_INFO_DEPRECATED_SPDY2: + case CONNECTION_INFO_DEPRECATED_SPDY3: + case CONNECTION_INFO_DEPRECATED_HTTP2_14: + case CONNECTION_INFO_DEPRECATED_HTTP2_15: + return CONNECTION_INFO_COARSE_HTTP2; + + case CONNECTION_INFO_QUIC_UNKNOWN_VERSION: + case CONNECTION_INFO_QUIC_32: + case CONNECTION_INFO_QUIC_33: + case CONNECTION_INFO_QUIC_34: + case CONNECTION_INFO_QUIC_35: + case CONNECTION_INFO_QUIC_36: + case CONNECTION_INFO_QUIC_37: + case CONNECTION_INFO_QUIC_38: + case CONNECTION_INFO_QUIC_39: + case CONNECTION_INFO_QUIC_40: + case CONNECTION_INFO_QUIC_41: + case CONNECTION_INFO_QUIC_42: + case CONNECTION_INFO_QUIC_43: + case CONNECTION_INFO_QUIC_44: + case CONNECTION_INFO_QUIC_45: + case CONNECTION_INFO_QUIC_46: + case CONNECTION_INFO_QUIC_47: + case CONNECTION_INFO_QUIC_48: + case CONNECTION_INFO_QUIC_49: + case CONNECTION_INFO_QUIC_50: + case CONNECTION_INFO_QUIC_99: + case CONNECTION_INFO_QUIC_999: + return CONNECTION_INFO_COARSE_QUIC; + + case CONNECTION_INFO_UNKNOWN: + return CONNECTION_INFO_COARSE_OTHER; + + case NUM_OF_CONNECTION_INFOS: + NOTREACHED(); + return CONNECTION_INFO_COARSE_OTHER; + } + + NOTREACHED(); + return CONNECTION_INFO_COARSE_OTHER; +} + HttpResponseInfo::HttpResponseInfo() : was_cached(false), cache_entry_status(CacheEntryStatus::ENTRY_UNDEFINED),
diff --git a/net/http/http_response_info.h b/net/http/http_response_info.h index ae75b00e..2b1e9dc 100644 --- a/net/http/http_response_info.h +++ b/net/http/http_response_info.h
@@ -69,6 +69,13 @@ NUM_OF_CONNECTION_INFOS, }; + enum ConnectionInfoCoarse { + CONNECTION_INFO_COARSE_HTTP1, // HTTP/0.9, 1.0 and 1.1 + CONNECTION_INFO_COARSE_HTTP2, + CONNECTION_INFO_COARSE_QUIC, + CONNECTION_INFO_COARSE_OTHER, + }; + // Used for categorizing transactions for reporting in histograms. // CacheEntryStatus covers relatively common use cases being measured and // considered for optimization. Many use cases that are more complex or @@ -97,6 +104,10 @@ ENTRY_MAX, }; + // Returns a more coarse-grained description of the protocol used to fetch the + // response. + static ConnectionInfoCoarse ConnectionInfoToCoarse(ConnectionInfo info); + HttpResponseInfo(); HttpResponseInfo(const HttpResponseInfo& rhs); ~HttpResponseInfo();
diff --git a/net/http/http_stream_factory_job_controller_unittest.cc b/net/http/http_stream_factory_job_controller_unittest.cc index d49c9945..4711f4b9 100644 --- a/net/http/http_stream_factory_job_controller_unittest.cc +++ b/net/http/http_stream_factory_job_controller_unittest.cc
@@ -52,7 +52,6 @@ #include "net/third_party/quiche/src/quic/test_tools/mock_random.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "testing/gmock/include/gmock/gmock.h" -#include "testing/gmock_mutant.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/origin.h"
diff --git a/net/quic/bidirectional_stream_quic_impl.cc b/net/quic/bidirectional_stream_quic_impl.cc index 19a6549f..a48cb34 100644 --- a/net/quic/bidirectional_stream_quic_impl.cc +++ b/net/quic/bidirectional_stream_quic_impl.cc
@@ -216,7 +216,7 @@ // When QPACK is enabled, headers are sent and received on the stream, so // the headers bytes do not need to be accounted for independently. int64_t total_received_bytes = - quic::VersionUsesHttp3(session_->GetQuicVersion()) + quic::VersionUsesHttp3(session_->GetQuicVersion().transport_version) ? 0 : headers_bytes_received_; if (stream_) { @@ -232,9 +232,10 @@ int64_t BidirectionalStreamQuicImpl::GetTotalSentBytes() const { // When QPACK is enabled, headers are sent and received on the stream, so // the headers bytes do not need to be accounted for independently. - int64_t total_sent_bytes = quic::VersionUsesHttp3(session_->GetQuicVersion()) - ? 0 - : headers_bytes_sent_; + int64_t total_sent_bytes = + quic::VersionUsesHttp3(session_->GetQuicVersion().transport_version) + ? 0 + : headers_bytes_sent_; if (stream_) { total_sent_bytes += stream_->stream_bytes_written(); } else {
diff --git a/net/quic/quic_chromium_client_session.cc b/net/quic/quic_chromium_client_session.cc index 4bd8ea2..bfb434b9 100644 --- a/net/quic/quic_chromium_client_session.cc +++ b/net/quic/quic_chromium_client_session.cc
@@ -303,7 +303,7 @@ quic_error_(quic::QUIC_NO_ERROR), port_migration_detected_(false), server_id_(session_->server_id()), - quic_version_(session->connection()->transport_version()), + quic_version_(session->connection()->version()), push_handle_(nullptr), was_ever_used_(false) { DCHECK(session_); @@ -326,7 +326,7 @@ } void QuicChromiumClientSession::Handle::OnSessionClosed( - quic::QuicTransportVersion quic_version, + quic::ParsedQuicVersion quic_version, int net_error, quic::QuicErrorCode quic_error, bool port_migration_detected, @@ -368,12 +368,12 @@ } } -quic::QuicTransportVersion QuicChromiumClientSession::Handle::GetQuicVersion() +quic::ParsedQuicVersion QuicChromiumClientSession::Handle::GetQuicVersion() const { if (!session_) return quic_version_; - return session_->connection()->transport_version(); + return session_->GetQuicVersion(); } void QuicChromiumClientSession::Handle::ResetPromised( @@ -1019,9 +1019,9 @@ void QuicChromiumClientSession::AddHandle(Handle* handle) { if (going_away_) { RecordUnexpectedObservers(ADD_OBSERVER); - handle->OnSessionClosed(connection()->transport_version(), ERR_UNEXPECTED, - error(), port_migration_detected_, - GetConnectTiming(), WasConnectionEverUsed()); + handle->OnSessionClosed(connection()->version(), ERR_UNEXPECTED, error(), + port_migration_detected_, GetConnectTiming(), + WasConnectionEverUsed()); return; } @@ -2428,9 +2428,9 @@ while (!handles_.empty()) { Handle* handle = *handles_.begin(); handles_.erase(handle); - handle->OnSessionClosed(connection()->transport_version(), net_error, - error(), port_migration_detected_, - GetConnectTiming(), WasConnectionEverUsed()); + handle->OnSessionClosed(connection()->version(), net_error, error(), + port_migration_detected_, GetConnectTiming(), + WasConnectionEverUsed()); } } @@ -3199,8 +3199,8 @@ return connect_timing_; } -quic::QuicTransportVersion QuicChromiumClientSession::GetQuicVersion() const { - return connection()->transport_version(); +quic::ParsedQuicVersion QuicChromiumClientSession::GetQuicVersion() const { + return connection()->version(); } size_t QuicChromiumClientSession::EstimateMemoryUsage() const {
diff --git a/net/quic/quic_chromium_client_session.h b/net/quic/quic_chromium_client_session.h index 6602a6a..e190ed1 100644 --- a/net/quic/quic_chromium_client_session.h +++ b/net/quic/quic_chromium_client_session.h
@@ -202,7 +202,7 @@ bool SharesSameSession(const Handle& other) const; // Returns the QUIC version used by the session. - quic::QuicTransportVersion GetQuicVersion() const; + quic::ParsedQuicVersion GetQuicVersion() const; // Copies the remote udp address into |address| and returns a net error // code. @@ -253,7 +253,7 @@ void OnCryptoHandshakeConfirmed(); // Called when the session is closed with a net error. - void OnSessionClosed(quic::QuicTransportVersion quic_version, + void OnSessionClosed(quic::ParsedQuicVersion quic_version, int net_error, quic::QuicErrorCode quic_error, bool port_migration_detected, @@ -282,7 +282,7 @@ quic::QuicErrorCode quic_error_; bool port_migration_detected_; quic::QuicServerId server_id_; - quic::QuicTransportVersion quic_version_; + quic::ParsedQuicVersion quic_version_; LoadTimingInfo::ConnectTiming connect_timing_; quic::QuicClientPushPromiseIndex* push_promise_index_; @@ -660,7 +660,7 @@ const LoadTimingInfo::ConnectTiming& GetConnectTiming(); - quic::QuicTransportVersion GetQuicVersion() const; + quic::ParsedQuicVersion GetQuicVersion() const; // Returns the estimate of dynamically allocated memory in bytes. // See base/trace_event/memory_usage_estimator.h.
diff --git a/net/quic/quic_chromium_client_session_test.cc b/net/quic/quic_chromium_client_session_test.cc index a50ced1..1ccaa5d 100644 --- a/net/quic/quic_chromium_client_session_test.cc +++ b/net/quic/quic_chromium_client_session_test.cc
@@ -366,7 +366,7 @@ session_->CreateHandle(destination_); EXPECT_TRUE(handle->IsConnected()); EXPECT_FALSE(handle->IsCryptoHandshakeConfirmed()); - EXPECT_EQ(version_.transport_version, handle->GetQuicVersion()); + EXPECT_EQ(version_, handle->GetQuicVersion()); EXPECT_EQ(session_key_.server_id(), handle->server_id()); EXPECT_EQ(session_net_log.source().type, handle->net_log().source().type); EXPECT_EQ(session_net_log.source().id, handle->net_log().source().id); @@ -394,7 +394,7 @@ // Veirfy that the handle works correctly after the session is closed. EXPECT_FALSE(handle->IsConnected()); EXPECT_TRUE(handle->IsCryptoHandshakeConfirmed()); - EXPECT_EQ(version_.transport_version, handle->GetQuicVersion()); + EXPECT_EQ(version_, handle->GetQuicVersion()); EXPECT_EQ(session_key_.server_id(), handle->server_id()); EXPECT_EQ(session_net_log.source().type, handle->net_log().source().type); EXPECT_EQ(session_net_log.source().id, handle->net_log().source().id); @@ -418,7 +418,7 @@ // Veirfy that the handle works correctly after the session is deleted. EXPECT_FALSE(handle->IsConnected()); EXPECT_TRUE(handle->IsCryptoHandshakeConfirmed()); - EXPECT_EQ(version_.transport_version, handle->GetQuicVersion()); + EXPECT_EQ(version_, handle->GetQuicVersion()); EXPECT_EQ(session_key_.server_id(), handle->server_id()); EXPECT_EQ(session_net_log.source().type, handle->net_log().source().type); EXPECT_EQ(session_net_log.source().id, handle->net_log().source().id);
diff --git a/net/quic/quic_chromium_client_stream_test.cc b/net/quic/quic_chromium_client_stream_test.cc index fa9f5d76..28ab405 100644 --- a/net/quic/quic_chromium_client_stream_test.cc +++ b/net/quic/quic_chromium_client_stream_test.cc
@@ -27,14 +27,9 @@ #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "testing/gmock/include/gmock/gmock.h" -#include "testing/gmock_mutant.h" -using testing::AnyNumber; -using testing::CreateFunctor; -using testing::Invoke; -using testing::Return; -using testing::StrEq; using testing::_; +using testing::Return; namespace net { namespace test {
diff --git a/net/quic/quic_http_stream.cc b/net/quic/quic_http_stream.cc index 1b27888..6ca02ac4 100644 --- a/net/quic/quic_http_stream.cc +++ b/net/quic/quic_http_stream.cc
@@ -85,8 +85,8 @@ } HttpResponseInfo::ConnectionInfo QuicHttpStream::ConnectionInfoFromQuicVersion( - quic::QuicTransportVersion quic_version) { - switch (quic_version) { + quic::ParsedQuicVersion quic_version) { + switch (quic_version.transport_version) { case quic::QUIC_VERSION_UNSUPPORTED: return HttpResponseInfo::CONNECTION_INFO_QUIC_UNKNOWN_VERSION; case quic::QUIC_VERSION_43: @@ -348,7 +348,7 @@ // When QPACK is enabled, headers are sent and received on the stream, so // the headers bytes do not need to be accounted for independently. int64_t total_received_bytes = - quic::VersionUsesHttp3(quic_session()->GetQuicVersion()) + quic::VersionUsesHttp3(quic_session()->GetQuicVersion().transport_version) ? 0 : headers_bytes_received_; if (stream_) { @@ -365,7 +365,7 @@ // When QPACK is enabled, headers are sent and received on the stream, so // the headers bytes do not need to be accounted for independently. int64_t total_sent_bytes = - quic::VersionUsesHttp3(quic_session()->GetQuicVersion()) + quic::VersionUsesHttp3(quic_session()->GetQuicVersion().transport_version) ? 0 : headers_bytes_sent_; if (stream_) {
diff --git a/net/quic/quic_http_stream.h b/net/quic/quic_http_stream.h index 0440c76..5f56553 100644 --- a/net/quic/quic_http_stream.h +++ b/net/quic/quic_http_stream.h
@@ -68,7 +68,7 @@ void SetPriority(RequestPriority priority) override; static HttpResponseInfo::ConnectionInfo ConnectionInfoFromQuicVersion( - quic::QuicTransportVersion quic_version); + quic::ParsedQuicVersion quic_version); private: friend class test::QuicHttpStreamPeer;
diff --git a/net/quic/quic_network_transaction_unittest.cc b/net/quic/quic_network_transaction_unittest.cc index 46c9a2e5..ee5b39b40 100644 --- a/net/quic/quic_network_transaction_unittest.cc +++ b/net/quic/quic_network_transaction_unittest.cc
@@ -712,8 +712,7 @@ EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); EXPECT_TRUE(response->was_fetched_via_spdy); EXPECT_TRUE(response->was_alpn_negotiated); - EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion( - version_.transport_version), + EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_), response->connection_info); } @@ -5374,9 +5373,8 @@ EXPECT_EQ("HTTP/1.1 425 TOO_EARLY", response->headers->GetStatusLine()); EXPECT_TRUE(response->was_fetched_via_spdy); EXPECT_TRUE(response->was_alpn_negotiated); - EXPECT_EQ( - QuicHttpStream::ConnectionInfoFromQuicVersion(version_.transport_version), - response->connection_info); + EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_), + response->connection_info); } TEST_P(QuicNetworkTransactionTest, @@ -5561,9 +5559,8 @@ EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); EXPECT_TRUE(response->was_fetched_via_spdy); EXPECT_TRUE(response->was_alpn_negotiated); - EXPECT_EQ( - QuicHttpStream::ConnectionInfoFromQuicVersion(version_.transport_version), - response->connection_info); + EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_), + response->connection_info); std::string response_data; ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data)); @@ -7307,8 +7304,7 @@ EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); EXPECT_TRUE(response->was_fetched_via_spdy); EXPECT_TRUE(response->was_alpn_negotiated); - EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion( - version_.transport_version), + EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_), response->connection_info); EXPECT_EQ(443, response->remote_endpoint.port()); }
diff --git a/net/quic/quic_stream_factory.cc b/net/quic/quic_stream_factory.cc index db6fe07..76dad7c 100644 --- a/net/quic/quic_stream_factory.cc +++ b/net/quic/quic_stream_factory.cc
@@ -788,7 +788,7 @@ if (!session_) return; details->connection_info = QuicHttpStream::ConnectionInfoFromQuicVersion( - session_->connection()->transport_version()); + session_->connection()->version()); details->quic_connection_error = session_->error(); }
diff --git a/net/url_request/url_request_data_job.cc b/net/url_request/url_request_data_job.cc index d297f117..b4b67aa 100644 --- a/net/url_request/url_request_data_job.cc +++ b/net/url_request/url_request_data_job.cc
@@ -19,32 +19,7 @@ std::string* charset, std::string* data, HttpResponseHeaders* headers) { - if (!DataURL::Parse(url, mime_type, charset, data)) - return ERR_INVALID_URL; - - // |mime_type| set by DataURL::Parse() is guaranteed to be in - // token "/" token - // form. |charset| can be an empty string. - - DCHECK(!mime_type->empty()); - - if (headers) { - headers->ReplaceStatusLine("HTTP/1.1 200 OK"); - // "charset" in the Content-Type header is specified explicitly to follow - // the "token" ABNF in the HTTP spec. When DataURL::Parse() call is - // successful, it's guaranteed that the string in |charset| follows the - // "token" ABNF. - std::string content_type_header = "Content-Type: " + *mime_type; - if (!charset->empty()) - content_type_header.append(";charset=" + *charset); - headers->AddHeader(content_type_header); - } - - if (base::EqualsCaseInsensitiveASCII(method, "HEAD")) { - data->clear(); - } - - return OK; + return DataURL::BuildResponse(url, method, mime_type, charset, data, headers); } URLRequestDataJob::URLRequestDataJob(
diff --git a/net/url_request/url_request_data_job_fuzzer.cc b/net/url_request/url_request_data_job_fuzzer.cc deleted file mode 100644 index 8432df2..0000000 --- a/net/url_request/url_request_data_job_fuzzer.cc +++ /dev/null
@@ -1,178 +0,0 @@ -// Copyright 2016 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. - -#include <stddef.h> -#include <stdint.h> - -#include <fuzzer/FuzzedDataProvider.h> - -#include <string> - -#include "base/memory/singleton.h" -#include "base/run_loop.h" -#include "base/threading/thread_task_runner_handle.h" -#include "net/http/http_request_headers.h" -#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" -#include "net/url_request/data_protocol_handler.h" -#include "net/url_request/url_request.h" -#include "net/url_request/url_request_job_factory_impl.h" -#include "net/url_request/url_request_test_util.h" - -namespace { - -const size_t kMaxLengthForFuzzedRange = 32; - -} // namespace - -// This class tests creating and reading to completion a URLRequest with fuzzed -// input. The fuzzer provides a data: URL and optionally generates custom Range -// headers. The amount of data read in each Read call is also fuzzed, as is -// the size of the IOBuffer to read data into. -class URLRequestDataJobFuzzerHarness : public net::URLRequest::Delegate { - public: - URLRequestDataJobFuzzerHarness() - : task_runner_(base::ThreadTaskRunnerHandle::Get()), context_(true) { - job_factory_.SetProtocolHandler( - "data", std::make_unique<net::DataProtocolHandler>()); - context_.set_job_factory(&job_factory_); - context_.Init(); - } - - static URLRequestDataJobFuzzerHarness* GetInstance() { - return base::Singleton<URLRequestDataJobFuzzerHarness>::get(); - } - - int CreateAndReadFromDataURLRequest(const uint8_t* data, size_t size) { - FuzzedDataProvider provider(data, size); - read_lengths_.clear(); - - // Allocate an IOBuffer with fuzzed size. - int buf_size = provider.ConsumeIntegralInRange(1, 127); // 7 bits. - buf_ = base::MakeRefCounted<net::IOBufferWithSize>(buf_size); - - // Generate a range header, and a bool determining whether to use it. - // Generate the header regardless of the bool value to keep the data URL and - // header in consistent byte addresses so the fuzzer doesn't have to work as - // hard. - bool use_range = provider.ConsumeBool(); - std::string range = provider.ConsumeBytesAsString(kMaxLengthForFuzzedRange); - - // Generate a sequence of reads sufficient to read the entire data URL, - // capping it at 20000 reads, to avoid hangs. Once the limit is reached, - // all subsequent reads will be 32k. - size_t simulated_bytes_read = 0; - while (simulated_bytes_read < provider.remaining_bytes() && - read_lengths_.size() < 20000u) { - size_t read_length = provider.ConsumeIntegralInRange(1, buf_size); - read_lengths_.push_back(read_length); - simulated_bytes_read += read_length; - } - - // The data URL is the rest of the fuzzed data with "data:" prepended, to - // ensure that if it's a URL, it's a data URL. If the URL is invalid just - // use a test variant, so the fuzzer has a chance to execute something. - std::string data_url_string = - std::string("data:") + provider.ConsumeRemainingBytesAsString(); - GURL data_url(data_url_string); - if (!data_url.is_valid()) - data_url = GURL("data:text/html;charset=utf-8,<p>test</p>"); - - // Create a URLRequest with the given data URL and start reading - // from it. - std::unique_ptr<net::URLRequest> request = context_.CreateRequest( - data_url, net::DEFAULT_PRIORITY, this, TRAFFIC_ANNOTATION_FOR_TESTS); - if (use_range) { - if (!net::HttpUtil::IsValidHeaderValue(range)) - range = "bytes=3-"; - request->SetExtraRequestHeaderByName("Range", range, true); - } - - // Block the thread while the request is read. - base::RunLoop read_loop; - read_loop_ = &read_loop; - request->Start(); - read_loop.Run(); - read_loop_ = nullptr; - return 0; - } - - void QuitLoop() { - DCHECK(read_loop_); - task_runner_->PostTask(FROM_HERE, read_loop_->QuitClosure()); - } - - void ReadFromRequest(net::URLRequest* request) { - int bytes_read = 0; - do { - size_t read_size = 32 * 1024; - // If possible, pop the next read size. - if (read_lengths_.size() > 0) { - read_size = read_lengths_.back(); - read_lengths_.pop_back(); - } - if (read_size > static_cast<size_t>(buf_->size())) - buf_ = base::MakeRefCounted<net::IOBufferWithSize>(read_size); - - bytes_read = request->Read(buf_.get(), read_size); - } while (bytes_read > 0); - - if (bytes_read != net::ERR_IO_PENDING) - QuitLoop(); - } - - // net::URLRequest::Delegate: - void OnReceivedRedirect(net::URLRequest* request, - const net::RedirectInfo& redirect_info, - bool* defer_redirect) override {} - void OnAuthRequired(net::URLRequest* request, - const net::AuthChallengeInfo& auth_info) override {} - void OnCertificateRequested( - net::URLRequest* request, - net::SSLCertRequestInfo* cert_request_info) override {} - void OnSSLCertificateError(net::URLRequest* request, - int net_error, - const net::SSLInfo& ssl_info, - bool fatal) override {} - void OnResponseStarted(net::URLRequest* request, int net_error) override { - DCHECK(buf_.get()); - DCHECK(read_loop_); - DCHECK_NE(net::ERR_IO_PENDING, net_error); - - if (net_error == net::OK) { - ReadFromRequest(request); - } else { - QuitLoop(); - } - } - void OnReadCompleted(net::URLRequest* request, int bytes_read) override { - DCHECK_NE(net::ERR_IO_PENDING, bytes_read); - DCHECK(buf_.get()); - DCHECK(read_loop_); - - if (bytes_read > 0) { - ReadFromRequest(request); - } else { - QuitLoop(); - } - } - - private: - friend struct base::DefaultSingletonTraits<URLRequestDataJobFuzzerHarness>; - - scoped_refptr<base::SingleThreadTaskRunner> task_runner_; - - net::TestURLRequestContext context_; - net::URLRequestJobFactoryImpl job_factory_; - std::vector<size_t> read_lengths_; - scoped_refptr<net::IOBufferWithSize> buf_; - base::RunLoop* read_loop_ = nullptr; - - DISALLOW_COPY_AND_ASSIGN(URLRequestDataJobFuzzerHarness); -}; - -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - // Using a static singleton test harness lets the test run ~3-4x faster. - return URLRequestDataJobFuzzerHarness::GetInstance() - ->CreateAndReadFromDataURLRequest(data, size); -}
diff --git a/net/url_request/url_request_data_job_unittest.cc b/net/url_request/url_request_data_job_unittest.cc deleted file mode 100644 index ff2711a..0000000 --- a/net/url_request/url_request_data_job_unittest.cc +++ /dev/null
@@ -1,109 +0,0 @@ -// Copyright 2014 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. - -#include <string> - -#include "base/memory/ref_counted.h" -#include "net/base/net_errors.h" -#include "net/http/http_response_headers.h" -#include "net/http/http_version.h" -#include "net/url_request/url_request_data_job.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "url/gurl.h" - -namespace net { - -TEST(BuildResponseTest, Simple) { - std::string mime_type; - std::string charset; - std::string data; - scoped_refptr<HttpResponseHeaders> headers( - new HttpResponseHeaders(std::string())); - - ASSERT_EQ(OK, URLRequestDataJob::BuildResponse(GURL("data:,Hello"), "GET", - &mime_type, &charset, &data, - headers.get())); - - EXPECT_EQ("text/plain", mime_type); - EXPECT_EQ("US-ASCII", charset); - EXPECT_EQ("Hello", data); - - const HttpVersion& version = headers->GetHttpVersion(); - EXPECT_EQ(1, version.major_value()); - EXPECT_EQ(1, version.minor_value()); - EXPECT_EQ("OK", headers->GetStatusText()); - std::string value; - EXPECT_TRUE(headers->GetNormalizedHeader("Content-Type", &value)); - EXPECT_EQ(value, "text/plain;charset=US-ASCII"); - value.clear(); -} - -TEST(BuildResponseTest, HeadMethod) { - std::string mime_type; - std::string charset; - std::string data; - scoped_refptr<HttpResponseHeaders> headers = - HttpResponseHeaders::TryToCreate(""); - - ASSERT_EQ(OK, URLRequestDataJob::BuildResponse(GURL("data:,Hello"), "HEAD", - &mime_type, &charset, &data, - headers.get())); - - EXPECT_EQ("text/plain", mime_type); - EXPECT_EQ("US-ASCII", charset); - EXPECT_EQ("", data); - - HttpVersion version = headers->GetHttpVersion(); - EXPECT_EQ(1, version.major_value()); - EXPECT_EQ(1, version.minor_value()); - EXPECT_EQ("OK", headers->GetStatusText()); - std::string content_type; - EXPECT_TRUE(headers->GetNormalizedHeader("Content-Type", &content_type)); - EXPECT_EQ(content_type, "text/plain;charset=US-ASCII"); -} - -TEST(BuildResponseTest, InvalidInput) { - std::string mime_type; - std::string charset; - std::string data; - scoped_refptr<HttpResponseHeaders> headers( - new HttpResponseHeaders(std::string())); - - EXPECT_EQ(ERR_INVALID_URL, - URLRequestDataJob::BuildResponse(GURL("bogus"), "GET", &mime_type, - &charset, &data, headers.get())); -} - -TEST(BuildResponseTest, InvalidMimeType) { - std::string mime_type; - std::string charset; - std::string data; - scoped_refptr<HttpResponseHeaders> headers( - new HttpResponseHeaders(std::string())); - - // MIME type contains delimiters. Must be accepted but Content-Type header - // should be generated as if the mediatype was text/plain. - EXPECT_EQ(OK, URLRequestDataJob::BuildResponse(GURL("data:f(o/b)r,test"), - "GET", &mime_type, &charset, - &data, headers.get())); - - std::string value; - EXPECT_TRUE(headers->GetNormalizedHeader("Content-Type", &value)); - EXPECT_EQ(value, "text/plain;charset=US-ASCII"); -} - -TEST(BuildResponseTest, InvalidCharset) { - std::string mime_type; - std::string charset; - std::string data; - scoped_refptr<HttpResponseHeaders> headers( - new HttpResponseHeaders(std::string())); - - // MIME type contains delimiters. Must be rejected. - EXPECT_EQ(ERR_INVALID_URL, URLRequestDataJob::BuildResponse( - GURL("data:text/html;charset=(),test"), "GET", - &mime_type, &charset, &data, headers.get())); -} - -} // namespace net
diff --git a/remoting/host/chromoting_host_unittest.cc b/remoting/host/chromoting_host_unittest.cc index a066bbb2..e48d3cf 100644 --- a/remoting/host/chromoting_host_unittest.cc +++ b/remoting/host/chromoting_host_unittest.cc
@@ -29,7 +29,6 @@ #include "remoting/protocol/session_config.h" #include "remoting/protocol/transport_context.h" #include "testing/gmock/include/gmock/gmock.h" -#include "testing/gmock_mutant.h" #include "testing/gtest/include/gtest/gtest.h" using ::remoting::protocol::MockClientStub;
diff --git a/remoting/host/config_file_watcher_unittest.cc b/remoting/host/config_file_watcher_unittest.cc index 9f941285..c41f79b3 100644 --- a/remoting/host/config_file_watcher_unittest.cc +++ b/remoting/host/config_file_watcher_unittest.cc
@@ -14,7 +14,6 @@ #include "remoting/base/auto_thread.h" #include "remoting/base/auto_thread_task_runner.h" #include "testing/gmock/include/gmock/gmock.h" -#include "testing/gmock_mutant.h" #include "testing/gtest/include/gtest/gtest.h" using testing::_;
diff --git a/remoting/host/daemon_process_unittest.cc b/remoting/host/daemon_process_unittest.cc index b8fb8be..857868f 100644 --- a/remoting/host/daemon_process_unittest.cc +++ b/remoting/host/daemon_process_unittest.cc
@@ -23,7 +23,6 @@ #include "remoting/host/chromoting_messages.h" #include "remoting/host/desktop_session.h" #include "testing/gmock/include/gmock/gmock.h" -#include "testing/gmock_mutant.h" #include "testing/gtest/include/gtest/gtest.h" using testing::_;
diff --git a/remoting/host/desktop_process_unittest.cc b/remoting/host/desktop_process_unittest.cc index f50ecf4a..e0a0847d 100644 --- a/remoting/host/desktop_process_unittest.cc +++ b/remoting/host/desktop_process_unittest.cc
@@ -34,7 +34,6 @@ #include "remoting/protocol/fake_desktop_capturer.h" #include "remoting/protocol/protocol_mock_objects.h" #include "testing/gmock/include/gmock/gmock.h" -#include "testing/gmock_mutant.h" #include "testing/gtest/include/gtest/gtest.h" using testing::_;
diff --git a/remoting/host/host_status_logger_unittest.cc b/remoting/host/host_status_logger_unittest.cc index 96685af..e79f19a 100644 --- a/remoting/host/host_status_logger_unittest.cc +++ b/remoting/host/host_status_logger_unittest.cc
@@ -10,7 +10,6 @@ #include "remoting/signaling/mock_signal_strategy.h" #include "remoting/signaling/xmpp_log_to_server.h" #include "testing/gmock/include/gmock/gmock.h" -#include "testing/gmock_mutant.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
diff --git a/remoting/host/it2me/it2me_confirmation_dialog_proxy_unittest.cc b/remoting/host/it2me/it2me_confirmation_dialog_proxy_unittest.cc index c4e8496..ce679fda 100644 --- a/remoting/host/it2me/it2me_confirmation_dialog_proxy_unittest.cc +++ b/remoting/host/it2me/it2me_confirmation_dialog_proxy_unittest.cc
@@ -13,11 +13,9 @@ #include "base/test/task_environment.h" #include "base/threading/thread.h" #include "testing/gmock/include/gmock/gmock.h" -#include "testing/gmock_mutant.h" #include "testing/gtest/include/gtest/gtest.h" using ::testing::InvokeWithoutArgs; -using ::testing::CreateFunctor; namespace remoting { @@ -136,13 +134,11 @@ TEST_F(It2MeConfirmationDialogProxyTest, Show) { ResultCallbackTarget callback_target(main_task_runner()); + StubIt2MeConfirmationDialog* confirm_dialog = dialog(); EXPECT_CALL(*dialog(), OnShow()) - .WillOnce( - InvokeWithoutArgs( - CreateFunctor( - &StubIt2MeConfirmationDialog::ReportResult, - base::Unretained(dialog()), - It2MeConfirmationDialog::Result::CANCEL))); + .WillOnce(InvokeWithoutArgs([confirm_dialog]() { + confirm_dialog->ReportResult(It2MeConfirmationDialog::Result::CANCEL); + })); EXPECT_CALL(callback_target, OnDialogResult(It2MeConfirmationDialog::Result::CANCEL))
diff --git a/remoting/host/remoting_me2me_host.cc b/remoting/host/remoting_me2me_host.cc index 2ae52b8..e7b1f926 100644 --- a/remoting/host/remoting_me2me_host.cc +++ b/remoting/host/remoting_me2me_host.cc
@@ -381,7 +381,6 @@ std::string robot_account_username_; std::string serialized_config_; std::string host_owner_; - bool use_service_account_ = false; bool enable_vp9_ = false; bool enable_h264_ = false; @@ -748,8 +747,8 @@ } factory = protocol::Me2MeHostAuthenticatorFactory::CreateWithPin( - use_service_account_, host_owner_, local_certificate, key_pair_, - client_domain_list_, pin_hash_, pairing_registry); + host_owner_, local_certificate, key_pair_, client_domain_list_, + pin_hash_, pairing_registry); host_->set_pairing_registry(pairing_registry); } else { @@ -772,8 +771,8 @@ new TokenValidatorFactoryImpl(third_party_auth_config_, key_pair_, context_->url_request_context_getter()); factory = protocol::Me2MeHostAuthenticatorFactory::CreateWithThirdPartyAuth( - use_service_account_, host_owner_, local_certificate, key_pair_, - client_domain_list_, token_validator_factory); + host_owner_, local_certificate, key_pair_, client_domain_list_, + token_validator_factory); } #if defined(OS_POSIX) @@ -1027,15 +1026,11 @@ if (!host_owner_ptr) { host_owner_ptr = config.FindStringPath(kHostOwnerConfigPath); } - if (host_owner_ptr) { - // Service account configs have a host_owner, different from the xmpp_login. - host_owner_ = *host_owner_ptr; - use_service_account_ = true; - } else { - // User credential configs only have an xmpp_login, which is also the owner. - host_owner_ = robot_account_username_; - use_service_account_ = false; + if (!host_owner_ptr) { + LOG(ERROR) << "Host config has no host_owner or host_owner_email fields."; + return false; } + host_owner_ = *host_owner_ptr; // Allow offering of VP9 encoding to be overridden by the command-line. if (base::CommandLine::ForCurrentProcess()->HasSwitch(kEnableVp9SwitchName)) { @@ -1406,7 +1401,8 @@ auto oauth_credentials = std::make_unique<OAuthTokenGetter::OAuthAuthorizationCredentials>( - robot_account_username_, oauth_refresh_token_, use_service_account_); + robot_account_username_, oauth_refresh_token_, + /* is_service_account */ true); // Unretained is sound because we own the OAuthTokenGetterImpl, and the // callback will never be invoked once it is destroyed. oauth_token_getter_ = std::make_unique<OAuthTokenGetterImpl>(
diff --git a/remoting/host/win/rdp_client_unittest.cc b/remoting/host/win/rdp_client_unittest.cc index e970f233..aa98397 100644 --- a/remoting/host/win/rdp_client_unittest.cc +++ b/remoting/host/win/rdp_client_unittest.cc
@@ -20,7 +20,6 @@ #include "remoting/host/screen_resolution.h" #include "remoting/host/win/wts_terminal_monitor.h" #include "testing/gmock/include/gmock/gmock.h" -#include "testing/gmock_mutant.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
diff --git a/remoting/protocol/me2me_host_authenticator_factory.cc b/remoting/protocol/me2me_host_authenticator_factory.cc index 7809f58..adb0e5f 100644 --- a/remoting/protocol/me2me_host_authenticator_factory.cc +++ b/remoting/protocol/me2me_host_authenticator_factory.cc
@@ -24,7 +24,6 @@ // static std::unique_ptr<AuthenticatorFactory> Me2MeHostAuthenticatorFactory::CreateWithPin( - bool use_service_account, const std::string& host_owner, const std::string& local_cert, scoped_refptr<RsaKeyPair> key_pair, @@ -33,7 +32,6 @@ scoped_refptr<PairingRegistry> pairing_registry) { std::unique_ptr<Me2MeHostAuthenticatorFactory> result( new Me2MeHostAuthenticatorFactory()); - result->use_service_account_ = use_service_account; result->canonical_host_owner_email_ = GetCanonicalEmail(host_owner); result->local_cert_ = local_cert; result->key_pair_ = key_pair; @@ -46,7 +44,6 @@ // static std::unique_ptr<AuthenticatorFactory> Me2MeHostAuthenticatorFactory::CreateWithThirdPartyAuth( - bool use_service_account, const std::string& host_owner, const std::string& local_cert, scoped_refptr<RsaKeyPair> key_pair, @@ -54,7 +51,6 @@ scoped_refptr<TokenValidatorFactory> token_validator_factory) { std::unique_ptr<Me2MeHostAuthenticatorFactory> result( new Me2MeHostAuthenticatorFactory()); - result->use_service_account_ = use_service_account; result->canonical_host_owner_email_ = GetCanonicalEmail(host_owner); result->local_cert_ = local_cert; result->key_pair_ = key_pair; @@ -74,29 +70,14 @@ std::string local_jid = NormalizeSignalingId(original_local_jid); std::string remote_jid = NormalizeSignalingId(original_remote_jid); - std::string remote_jid_prefix; - - if (!use_service_account_) { - // JID prefixes may not match the host owner email, for example, in cases - // where the host owner account does not have an email associated with it. - // In those cases, the only guarantee we have is that JIDs for the same - // account will have the same prefix. - if (!SplitSignalingIdResource(local_jid, &remote_jid_prefix, nullptr)) { - LOG(DFATAL) << "Invalid local JID:" << local_jid; - return base::WrapUnique( - new RejectingAuthenticator(Authenticator::INVALID_CREDENTIALS)); - } - } else { - remote_jid_prefix = canonical_host_owner_email_; - } - // Verify that the client's jid is an ASCII string, and then check that the // client JID has the expected prefix. Comparison is case insensitive. if (!base::IsStringASCII(remote_jid) || - !base::StartsWith(remote_jid, remote_jid_prefix + '/', + !base::StartsWith(remote_jid, canonical_host_owner_email_ + '/', base::CompareCase::INSENSITIVE_ASCII)) { LOG(ERROR) << "Rejecting incoming connection from " << remote_jid - << ": Prefix mismatch. Expected: " << remote_jid_prefix; + << ": Prefix mismatch. Expected: " + << canonical_host_owner_email_; return base::WrapUnique( new RejectingAuthenticator(Authenticator::INVALID_CREDENTIALS)); }
diff --git a/remoting/protocol/me2me_host_authenticator_factory.h b/remoting/protocol/me2me_host_authenticator_factory.h index babac2b1..b80d774 100644 --- a/remoting/protocol/me2me_host_authenticator_factory.h +++ b/remoting/protocol/me2me_host_authenticator_factory.h
@@ -28,7 +28,6 @@ public: // Create a factory that dispenses shared secret authenticators. static std::unique_ptr<AuthenticatorFactory> CreateWithPin( - bool use_service_account, const std::string& host_owner, const std::string& local_cert, scoped_refptr<RsaKeyPair> key_pair, @@ -38,7 +37,6 @@ // Create a factory that dispenses third party authenticators. static std::unique_ptr<AuthenticatorFactory> CreateWithThirdPartyAuth( - bool use_service_account, const std::string& host_owner, const std::string& local_cert, scoped_refptr<RsaKeyPair> key_pair, @@ -55,7 +53,6 @@ private: // Used for all host authenticators. - bool use_service_account_; std::string canonical_host_owner_email_; std::string local_cert_; scoped_refptr<RsaKeyPair> key_pair_;
diff --git a/remoting/test/ftl_signaling_playground.cc b/remoting/test/ftl_signaling_playground.cc index fb9c86c6..0b10ad3 100644 --- a/remoting/test/ftl_signaling_playground.cc +++ b/remoting/test/ftl_signaling_playground.cc
@@ -159,10 +159,8 @@ ? cmd->GetSwitchValueASCII(kSwitchNameHostOwner) : user_email; HOST_LOG << "Using host owner: " << host_owner; - bool is_service_account = - test::TestOAuthTokenGetter::IsServiceAccount(user_email); auto factory = protocol::Me2MeHostAuthenticatorFactory::CreateWithPin( - is_service_account, host_owner, cert, key_pair, + host_owner, cert, key_pair, /* domain_list */ {}, pin_hash, /* pairing_registry */ {}); session_manager_->set_authenticator_factory(std::move(factory)); HOST_LOG << "Waiting for incoming session...";
diff --git a/remoting/test/protocol_perftest.cc b/remoting/test/protocol_perftest.cc index c01a042..ca8444fd 100644 --- a/remoting/test/protocol_perftest.cc +++ b/remoting/test/protocol_perftest.cc
@@ -319,7 +319,7 @@ protocol::GetSharedSecretHash(kHostId, kHostPin); std::unique_ptr<protocol::AuthenticatorFactory> auth_factory = protocol::Me2MeHostAuthenticatorFactory::CreateWithPin( - true, kHostOwner, host_cert, key_pair, std::vector<std::string>(), + kHostOwner, host_cert, key_pair, std::vector<std::string>(), host_pin_hash, nullptr); host_->SetAuthenticatorFactory(std::move(auth_factory));
diff --git a/services/device/public/mojom/BUILD.gn b/services/device/public/mojom/BUILD.gn index e0bcbb0..b5f1cdfd 100644 --- a/services/device/public/mojom/BUILD.gn +++ b/services/device/public/mojom/BUILD.gn
@@ -6,6 +6,7 @@ import("//mojo/public/tools/bindings/mojom.gni") mojom("mojom") { + generate_java = true sources = [ "battery_monitor.mojom", "battery_status.mojom", @@ -63,6 +64,7 @@ } mojom("generic_sensor") { + generate_java = true sources = [ "sensor.mojom", "sensor_provider.mojom", @@ -86,6 +88,7 @@ } mojom("constants") { + generate_java = true sources = [ "constants.mojom", ] @@ -101,6 +104,7 @@ } mojom("usb") { + generate_java = true sources = [ "usb_device.mojom", "usb_enumeration_options.mojom",
diff --git a/services/device/usb/mojo/device_impl.cc b/services/device/usb/mojo/device_impl.cc index 18c95b8f..6507b470 100644 --- a/services/device/usb/mojo/device_impl.cc +++ b/services/device/usb/mojo/device_impl.cc
@@ -130,7 +130,7 @@ return true; } - const mojom::UsbConfigurationInfo* config = device_->active_configuration(); + const mojom::UsbConfigurationInfo* config = device_->GetActiveConfiguration(); if (!config) return false; @@ -218,7 +218,7 @@ return; } - const mojom::UsbConfigurationInfo* config = device_->active_configuration(); + const mojom::UsbConfigurationInfo* config = device_->GetActiveConfiguration(); if (!config) { std::move(callback).Run(false); return;
diff --git a/services/device/usb/usb_device.cc b/services/device/usb/usb_device.cc index a8da2ad..40eabd6c 100644 --- a/services/device/usb/usb_device.cc +++ b/services/device/usb/usb_device.cc
@@ -73,6 +73,14 @@ return GetDeviceVersion(*device_info_); } +const mojom::UsbConfigurationInfo* UsbDevice::GetActiveConfiguration() const { + for (const auto& config : configurations()) { + if (config->configuration_value == device_info_->active_configuration) + return config.get(); + } + return nullptr; +} + void UsbDevice::CheckUsbAccess(ResultCallback callback) { // By default assume that access to the device is allowed. This is implemented // on Chrome OS by checking with permission_broker. @@ -99,12 +107,6 @@ void UsbDevice::ActiveConfigurationChanged(int configuration_value) { device_info_->active_configuration = configuration_value; - for (const auto& config : configurations()) { - if (config->configuration_value == configuration_value) { - active_configuration_ = config.get(); - return; - } - } } void UsbDevice::NotifyDeviceRemoved() {
diff --git a/services/device/usb/usb_device.h b/services/device/usb/usb_device.h index 0c309735..8855a8a 100644 --- a/services/device/usb/usb_device.h +++ b/services/device/usb/usb_device.h
@@ -92,9 +92,7 @@ const std::vector<mojom::UsbConfigurationInfoPtr>& configurations() const { return device_info_->configurations; } - const mojom::UsbConfigurationInfo* active_configuration() const { - return active_configuration_; - } + const mojom::UsbConfigurationInfo* GetActiveConfiguration() const; // On ChromeOS the permission_broker service must be used to open USB devices. // This function asks it to check whether a future Open call will be allowed. @@ -156,11 +154,6 @@ void OnDisconnect(); void HandleClosed(UsbDeviceHandle* handle); - // The current device configuration descriptor. May be null if the device is - // in an unconfigured state; if not null, it is a pointer to one of the - // items in |descriptor_.configurations|. - const mojom::UsbConfigurationInfo* active_configuration_ = nullptr; - // Weak pointers to open handles. HandleClosed() will be called before each // is freed. std::list<UsbDeviceHandle*> handles_;
diff --git a/services/device/usb/usb_device_handle_impl.cc b/services/device/usb/usb_device_handle_impl.cc index 0ff7dacc..b80bef2 100644 --- a/services/device/usb/usb_device_handle_impl.cc +++ b/services/device/usb/usb_device_handle_impl.cc
@@ -1000,7 +1000,7 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(device_); endpoint_map_.clear(); - const mojom::UsbConfigurationInfo* config = device_->active_configuration(); + const mojom::UsbConfigurationInfo* config = device_->GetActiveConfiguration(); if (!config) return;
diff --git a/services/device/usb/usb_device_handle_usbfs.cc b/services/device/usb/usb_device_handle_usbfs.cc index cb74ead..4c6f6f3 100644 --- a/services/device/usb/usb_device_handle_usbfs.cc +++ b/services/device/usb/usb_device_handle_usbfs.cc
@@ -872,7 +872,7 @@ DCHECK(device_); endpoints_.clear(); - const mojom::UsbConfigurationInfo* config = device_->active_configuration(); + const mojom::UsbConfigurationInfo* config = device_->GetActiveConfiguration(); if (!config) return;
diff --git a/services/device/usb/usb_device_handle_win.cc b/services/device/usb/usb_device_handle_win.cc index 6e876f2..874d124a 100644 --- a/services/device/usb/usb_device_handle_win.cc +++ b/services/device/usb/usb_device_handle_win.cc
@@ -491,9 +491,9 @@ blocking_task_runner_(UsbService::CreateBlockingTaskRunner()) { DCHECK(!composite); // Windows only supports configuration 1, which therefore must be active. - DCHECK(device_->active_configuration()); + DCHECK(device_->GetActiveConfiguration()); - for (const auto& interface : device_->active_configuration()->interfaces) { + for (const auto& interface : device_->GetActiveConfiguration()->interfaces) { for (const auto& alternate : interface->alternates) { if (alternate->alternate_setting != 0) continue;
diff --git a/services/media_session/public/mojom/BUILD.gn b/services/media_session/public/mojom/BUILD.gn index f494f9fb..a90f05d 100644 --- a/services/media_session/public/mojom/BUILD.gn +++ b/services/media_session/public/mojom/BUILD.gn
@@ -5,6 +5,7 @@ import("//mojo/public/tools/bindings/mojom.gni") mojom("mojom") { + generate_java = true sources = [ "audio_focus.mojom", "constants.mojom",
diff --git a/services/network/public/mojom/BUILD.gn b/services/network/public/mojom/BUILD.gn index d524845..23e876a 100644 --- a/services/network/public/mojom/BUILD.gn +++ b/services/network/public/mojom/BUILD.gn
@@ -10,6 +10,7 @@ # which comes from the fact that proxy_resolver service uses these interfaces, # and the network service uses the proxy_resolver service. mojom("mojom_ip_address") { + generate_java = true sources = [ "address_family.mojom", "address_list.mojom", @@ -26,6 +27,7 @@ # which comes from the fact that the typemap for url_loader.mojom # (ResourceRequestBody) uses these interfaces. mojom("data_pipe_interfaces") { + generate_java = true sources = [ "chunked_data_pipe_getter.mojom", "data_pipe_getter.mojom", @@ -43,6 +45,7 @@ } mojom("mutable_network_traffic_annotation_interface") { + generate_java = true sources = [ "mutable_network_traffic_annotation_tag.mojom", "mutable_partial_network_traffic_annotation_tag.mojom", @@ -52,6 +55,7 @@ # This target is split from "mojom" target as the lazy serialization may # cause problems. See https://crbug.com/822732. mojom("websocket_mojom") { + generate_java = true sources = [ "network_param.mojom", "websocket.mojom", @@ -72,6 +76,7 @@ } mojom("mojom") { + generate_java = true sources = [ "content_security_policy.mojom", "cookie_manager.mojom",
diff --git a/services/network/test/test_shared_url_loader_factory.cc b/services/network/test/test_shared_url_loader_factory.cc index 77aa9a93..6f835be 100644 --- a/services/network/test/test_shared_url_loader_factory.cc +++ b/services/network/test/test_shared_url_loader_factory.cc
@@ -12,7 +12,8 @@ namespace network { TestSharedURLLoaderFactory::TestSharedURLLoaderFactory( - NetworkService* network_service) { + NetworkService* network_service, + bool is_trusted) { url_request_context_ = std::make_unique<net::TestURLRequestContext>(); mojo::Remote<mojom::NetworkContext> network_context; network_context_ = std::make_unique<NetworkContext>( @@ -23,6 +24,7 @@ mojom::URLLoaderFactoryParams::New(); params->process_id = mojom::kBrowserProcessId; params->is_corb_enabled = false; + params->is_trusted = is_trusted; network_context_->CreateURLLoaderFactory( url_loader_factory_.BindNewPipeAndPassReceiver(), std::move(params)); }
diff --git a/services/network/test/test_shared_url_loader_factory.h b/services/network/test/test_shared_url_loader_factory.h index 9f20e37..2d48d93 100644 --- a/services/network/test/test_shared_url_loader_factory.h +++ b/services/network/test/test_shared_url_loader_factory.h
@@ -26,8 +26,8 @@ // across threads. class TestSharedURLLoaderFactory : public SharedURLLoaderFactory { public: - explicit TestSharedURLLoaderFactory( - NetworkService* network_service = nullptr); + explicit TestSharedURLLoaderFactory(NetworkService* network_service = nullptr, + bool is_trusted = false); // URLLoaderFactory implementation: void CreateLoaderAndStart(mojom::URLLoaderRequest loader,
diff --git a/services/proxy_resolver/public/mojom/BUILD.gn b/services/proxy_resolver/public/mojom/BUILD.gn index e67cde41..3f4da10 100644 --- a/services/proxy_resolver/public/mojom/BUILD.gn +++ b/services/proxy_resolver/public/mojom/BUILD.gn
@@ -5,6 +5,7 @@ import("//mojo/public/tools/bindings/mojom.gni") mojom("mojom") { + generate_java = true sources = [ "proxy_resolver.mojom", ]
diff --git a/services/service_manager/public/mojom/BUILD.gn b/services/service_manager/public/mojom/BUILD.gn index cf653180..0ca4819 100644 --- a/services/service_manager/public/mojom/BUILD.gn +++ b/services/service_manager/public/mojom/BUILD.gn
@@ -5,6 +5,7 @@ import("//mojo/public/tools/bindings/mojom.gni") mojom_component("mojom") { + generate_java = true output_prefix = "service_manager_mojom" macro_prefix = "SERVICE_MANAGER_MOJOM" @@ -25,6 +26,7 @@ } mojom_component("constants") { + generate_java = true output_prefix = "service_manager_mojom_constants" macro_prefix = "SERVICE_MANAGER_MOJOM_CONSTANTS" sources = [
diff --git a/services/shape_detection/public/mojom/BUILD.gn b/services/shape_detection/public/mojom/BUILD.gn index fa3565bb..671cce4a 100644 --- a/services/shape_detection/public/mojom/BUILD.gn +++ b/services/shape_detection/public/mojom/BUILD.gn
@@ -5,6 +5,7 @@ import("//mojo/public/tools/bindings/mojom.gni") mojom("mojom") { + generate_java = true sources = [ "barcodedetection.mojom", "barcodedetection_provider.mojom",
diff --git a/services/test/echo/public/mojom/BUILD.gn b/services/test/echo/public/mojom/BUILD.gn index 4027a8ab..f0d5d4c 100644 --- a/services/test/echo/public/mojom/BUILD.gn +++ b/services/test/echo/public/mojom/BUILD.gn
@@ -5,6 +5,7 @@ import("//mojo/public/tools/bindings/mojom.gni") mojom("mojom") { + generate_java = true sources = [ "echo.mojom", ]
diff --git a/services/viz/public/mojom/BUILD.gn b/services/viz/public/mojom/BUILD.gn index 0b0218d..cb97e65c 100644 --- a/services/viz/public/mojom/BUILD.gn +++ b/services/viz/public/mojom/BUILD.gn
@@ -5,6 +5,7 @@ import("//mojo/public/tools/bindings/mojom.gni") mojom("mojom") { + generate_java = true sources = [ "compositing/begin_frame_args.mojom", "compositing/compositing_mode_watcher.mojom",
diff --git a/skia/public/mojom/BUILD.gn b/skia/public/mojom/BUILD.gn index 3eeb2733..76b549f 100644 --- a/skia/public/mojom/BUILD.gn +++ b/skia/public/mojom/BUILD.gn
@@ -5,6 +5,7 @@ import("//mojo/public/tools/bindings/mojom.gni") mojom("mojom") { + generate_java = true sources = [ "bitmap.mojom", "blur_image_filter_tile_mode.mojom",
diff --git a/testing/buildbot/filters/bfcache.content_unittests.filter b/testing/buildbot/filters/bfcache.content_unittests.filter index 814433b4..d66e465 100644 --- a/testing/buildbot/filters/bfcache.content_unittests.filter +++ b/testing/buildbot/filters/bfcache.content_unittests.filter
@@ -12,14 +12,6 @@ -RenderFrameHostManagerTest.CommitNewNavigationBeforeSendingSwapOut -RenderFrameHostManagerTest.SwapOutFrameAfterSwapOutACK -# Test: -# 1) Normal navigation to a non-webui URL. -# 2) Add the webui capability to the RenderFrameHost. -# 3) Navigate away. -# 4) Navigate back. Hit a CHECK. RenderFrameHost with the webui capability can't -# have non-webUI URL. --NavigationControllerTest.LoadURL_PrivilegedPending - # navigation_simulator_impl.cc(581)] Check failed: state_ <= READY_TO_COMMIT -RenderFrameHostManagerTest.NavigateAfterMissingSwapOutACK
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index d9d26c4..9e3e7cfe 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -1839,6 +1839,24 @@ ] } ], + "CrOSSystemAECDeactivatedGroups": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "AecGroupIdsWithBrowserFallbackFromCrAS", + "params": { + "3": "true" + }, + "enable_features": [ + "CrOSSystemAECDeactivatedGroups" + ] + } + ] + } + ], "D3D11VideoDecoder": [ { "platforms": [ @@ -4038,6 +4056,25 @@ ] } ], + "OmniboxOnDeviceHeadSuggest": [ + { + "platforms": [ + "android", + "windows", + "mac", + "chromeos", + "linux" + ], + "experiments": [ + { + "name": "Beta_OnDeviceHeadSuggest_Enabled", + "enable_features": [ + "OmniboxOnDeviceHeadProvider" + ] + } + ] + } + ], "OmniboxSteadyStateElisions": [ { "platforms": [
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index 8c85e4b..9713693 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc
@@ -401,5 +401,8 @@ const base::Feature kSubresourceRedirect{"SubresourceRedirect", base::FEATURE_DISABLED_BY_DEFAULT}; +// When 'enabled', all cross-origin iframes will get a compositing layer. +const base::Feature kCompositeCrossOriginIframes{ + "CompositeCrossOriginIframes", base::FEATURE_DISABLED_BY_DEFAULT}; } // namespace features } // namespace blink
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h index 9d9bf5bc..e1fe4f9a 100644 --- a/third_party/blink/public/common/features.h +++ b/third_party/blink/public/common/features.h
@@ -128,6 +128,7 @@ BLINK_COMMON_EXPORT extern const base::Feature kARIAAnnotationRoles; BLINK_COMMON_EXPORT extern const base::Feature kDisableDirectlyCompositedImages; +BLINK_COMMON_EXPORT extern const base::Feature kCompositeCrossOriginIframes; BLINK_COMMON_EXPORT extern const base::Feature kSubresourceRedirect;
diff --git a/third_party/blink/public/mojom/BUILD.gn b/third_party/blink/public/mojom/BUILD.gn index d4971ab9..62b385c6 100644 --- a/third_party/blink/public/mojom/BUILD.gn +++ b/third_party/blink/public/mojom/BUILD.gn
@@ -13,6 +13,7 @@ # renderer/platform. In particular these mojom interfaces can't use types that # are typemapped to a type in renderer/core. mojom("mojom_platform") { + generate_java = true sources = [ "ad_tagging/ad_frame.mojom", "app_banner/app_banner.mojom", @@ -209,6 +210,7 @@ # needed by Android's implementation (in chrome/android or in android_webview) # for following mojom files. mojom("android_mojo_bindings") { + generate_java = true sources = [ "blob/blob.mojom", "blob/blob_registry.mojom", @@ -265,6 +267,7 @@ # modules dependencies if it looks necessary, at that time we can put all of # those high-level service worker mojom files there. mojom("mojom_core") { + generate_java = true sources = [ "messaging/cloneable_message.mojom", "messaging/message_port_descriptor.mojom", @@ -415,6 +418,7 @@ } mojom("mojom_mhtml_load_result") { + generate_java = true sources = [ "loader/mhtml_load_result.mojom", ] @@ -428,6 +432,7 @@ # because the chromium typemap for blink mojo_bindings has private content # dependencies. mojom_component("web_feature_mojo_bindings") { + generate_java = true sources = [ "use_counter/css_property_id.mojom", "web_feature/web_feature.mojom", @@ -441,6 +446,7 @@ # mojom files because the chromium typemap for blink mojo_bindings has private # content dependencies. mojom("web_client_hints_types_mojo_bindings") { + generate_java = true sources = [ "web_client_hints/web_client_hints_types.mojom", ] @@ -473,6 +479,7 @@ # This is a separate target because it needs unscrambled message IDs. mojom("authenticator_test_mojo_bindings") { + generate_java = true sources = [ "webauthn/virtual_authenticator.mojom", ]
diff --git a/third_party/blink/public/mojom/usb/BUILD.gn b/third_party/blink/public/mojom/usb/BUILD.gn index e04fd42f..d36828a 100644 --- a/third_party/blink/public/mojom/usb/BUILD.gn +++ b/third_party/blink/public/mojom/usb/BUILD.gn
@@ -5,6 +5,8 @@ import("//mojo/public/tools/bindings/mojom.gni") mojom("usb") { + generate_java = true + # Ideally, this mojom file should be compiled directly in "mojom_platform" # target in the parent directory. But as we need |scramble_message_ids| to # be "false" for its mojom JS file will be used in external WPT tests.
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc index 11b5b9e..a7d12a3 100644 --- a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc +++ b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc
@@ -12,11 +12,14 @@ #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/frame/settings.h" #include "third_party/blink/renderer/core/fullscreen/fullscreen.h" +#include "third_party/blink/renderer/core/html/html_frame_owner_element.h" #include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" +#include "third_party/blink/public/common/features.h" + namespace blink { CompositingReasons CompositingReasonFinder::DirectReasons( @@ -185,13 +188,14 @@ layer.CompositingContainer()->GetLayoutObject().IsVideo()) direct_reasons |= CompositingReason::kVideoOverlay; + const Node* node = layer.GetLayoutObject().GetNode(); + // Special case for immersive-ar DOM overlay mode, see also // PaintLayerCompositor::ApplyXrImmersiveDomOverlayIfNeeded() - if (const Node* node = layer.GetLayoutObject().GetNode()) { - if (node->IsElementNode() && node->GetDocument().IsImmersiveArOverlay() && - node == Fullscreen::FullscreenElementFrom(node->GetDocument())) { - direct_reasons |= CompositingReason::kImmersiveArOverlay; - } + if (node && node->IsElementNode() && + node->GetDocument().IsImmersiveArOverlay() && + node == Fullscreen::FullscreenElementFrom(node->GetDocument())) { + direct_reasons |= CompositingReason::kImmersiveArOverlay; } if (layer.IsRootLayer() && @@ -200,6 +204,19 @@ direct_reasons |= CompositingReason::kRoot; } + // Composite all cross-origin iframes, to improve compositor hit testing for + // input event targeting. crbug.com/1014273 + if (node && node->IsFrameOwnerElement() && + base::FeatureList::IsEnabled( + blink::features::kCompositeCrossOriginIframes)) { + if (Frame* iframe_frame = To<HTMLFrameOwnerElement>(node)->ContentFrame()) { + if (!iframe_frame->GetSecurityContext()->GetSecurityOrigin()->CanAccess( + node->GetDocument().GetSecurityOrigin())) { + direct_reasons |= CompositingReason::kCrossOriginIframe; + } + } + } + direct_reasons |= layout_object.AdditionalCompositingReasons(); DCHECK(
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc index f00bb10..f6017395 100644 --- a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc +++ b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc
@@ -7,6 +7,7 @@ #include "base/test/scoped_feature_list.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" +#include "third_party/blink/renderer/core/html/html_frame_owner_element.h" #include "third_party/blink/renderer/core/layout/layout_block.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/scroll/scroll_types.h" @@ -202,4 +203,41 @@ child_frame_view->GetLayoutView()->Layer()->GetCompositingState()); } +TEST_F(CompositingReasonFinderTest, PromoteCrossOriginIframe) { + base::test::ScopedFeatureList feature_list; + feature_list.InitWithFeatureState( + blink::features::kCompositeCrossOriginIframes, true); + SetBodyInnerHTML(R"HTML( + <!DOCTYPE html> + <iframe id=iframe></iframe> + )HTML"); + UpdateAllLifecyclePhasesForTest(); + + Element* iframe = GetDocument().getElementById("iframe"); + ASSERT_TRUE(iframe); + PaintLayer* iframe_layer = + ToLayoutBoxModelObject(iframe->GetLayoutObject())->Layer(); + ASSERT_TRUE(iframe_layer); + ASSERT_FALSE(To<HTMLFrameOwnerElement>(iframe) + ->ContentFrame() + ->IsCrossOriginSubframe()); + EXPECT_EQ(kNotComposited, iframe_layer->DirectCompositingReasons()); + + SetBodyInnerHTML(R"HTML( + <!DOCTYPE html> + <iframe id=iframe sandbox></iframe> + )HTML"); + UpdateAllLifecyclePhasesForTest(); + + iframe = GetDocument().getElementById("iframe"); + ASSERT_TRUE(iframe); + iframe_layer = ToLayoutBoxModelObject(iframe->GetLayoutObject())->Layer(); + ASSERT_TRUE(iframe_layer); + ASSERT_TRUE(To<HTMLFrameOwnerElement>(iframe) + ->ContentFrame() + ->IsCrossOriginSubframe()); + EXPECT_EQ(CompositingReason::kCrossOriginIframe, + iframe_layer->DirectCompositingReasons()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc b/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc index f685b03..1cacb280 100644 --- a/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc +++ b/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc
@@ -82,8 +82,6 @@ namespace blink { -using namespace html_names; - // FIXME: HTMLConstructionSite has a limit of 512, should these match? static const unsigned kMaxXMLTreeDepth = 5000; @@ -455,8 +453,8 @@ // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-xhtml-syntax.html#xml-fragment-parsing-algorithm // For now we have a hack for script/style innerHTML support: if (context_element && - (context_element->HasLocalName(kScriptTag.LocalName()) || - context_element->HasLocalName(kStyleTag.LocalName()))) { + (context_element->HasLocalName(html_names::kScriptTag.LocalName()) || + context_element->HasLocalName(html_names::kStyleTag.LocalName()))) { fragment->ParserAppendChild(fragment->GetDocument().createTextNode(chunk)); return true; } @@ -981,7 +979,7 @@ prefix_to_namespace_map_, exception_state); AtomicString is; for (const auto& attr : prefixed_attributes) { - if (attr.GetName() == kIsAttr) { + if (attr.GetName() == html_names::kIsAttr) { is = attr.Value(); break; }
diff --git a/third_party/blink/renderer/core/xml/parser/xml_errors.cc b/third_party/blink/renderer/core/xml/parser/xml_errors.cc index e444927..ece2d18 100644 --- a/third_party/blink/renderer/core/xml/parser/xml_errors.cc +++ b/third_party/blink/renderer/core/xml/parser/xml_errors.cc
@@ -38,8 +38,6 @@ namespace blink { -using namespace html_names; - const int kMaxErrors = 25; XMLErrors::XMLErrors(Document* document) @@ -99,30 +97,31 @@ const String& error_messages) { const CreateElementFlags flags = CreateElementFlags::ByParser(); Element* report_element = doc->CreateRawElement( - QualifiedName(g_null_atom, "parsererror", xhtmlNamespaceURI), flags); + QualifiedName(g_null_atom, "parsererror", html_names::xhtmlNamespaceURI), + flags); Vector<Attribute> report_attributes; report_attributes.push_back(Attribute( - kStyleAttr, + html_names::kStyleAttr, "display: block; white-space: pre; border: 2px solid #c77; padding: 0 " "1em 0 1em; margin: 1em; background-color: #fdd; color: black")); report_element->ParserSetAttributes(report_attributes); - Element* h3 = doc->CreateRawElement(kH3Tag, flags); + Element* h3 = doc->CreateRawElement(html_names::kH3Tag, flags); report_element->ParserAppendChild(h3); h3->ParserAppendChild( doc->createTextNode("This page contains the following errors:")); - Element* fixed = doc->CreateRawElement(kDivTag, flags); + Element* fixed = doc->CreateRawElement(html_names::kDivTag, flags); Vector<Attribute> fixed_attributes; - fixed_attributes.push_back( - Attribute(kStyleAttr, "font-family:monospace;font-size:12px")); + fixed_attributes.push_back(Attribute(html_names::kStyleAttr, + "font-family:monospace;font-size:12px")); fixed->ParserSetAttributes(fixed_attributes); report_element->ParserAppendChild(fixed); fixed->ParserAppendChild(doc->createTextNode(error_messages)); - h3 = doc->CreateRawElement(kH3Tag, flags); + h3 = doc->CreateRawElement(html_names::kH3Tag, flags); report_element->ParserAppendChild(h3); h3->ParserAppendChild(doc->createTextNode( "Below is a rendering of the page up to the first error.")); @@ -139,22 +138,24 @@ const CreateElementFlags flags = CreateElementFlags::ByParser(); Element* document_element = document_->documentElement(); if (!document_element) { - Element* root_element = document_->CreateRawElement(kHTMLTag, flags); - Element* body = document_->CreateRawElement(kBodyTag, flags); + Element* root_element = + document_->CreateRawElement(html_names::kHTMLTag, flags); + Element* body = document_->CreateRawElement(html_names::kBodyTag, flags); root_element->ParserAppendChild(body); document_->ParserAppendChild(root_element); document_element = body; } else if (document_element->namespaceURI() == svg_names::kNamespaceURI) { - Element* root_element = document_->CreateRawElement(kHTMLTag, flags); - Element* head = document_->CreateRawElement(kHeadTag, flags); - Element* style = document_->CreateRawElement(kStyleTag, flags); + Element* root_element = + document_->CreateRawElement(html_names::kHTMLTag, flags); + Element* head = document_->CreateRawElement(html_names::kHeadTag, flags); + Element* style = document_->CreateRawElement(html_names::kStyleTag, flags); head->ParserAppendChild(style); style->ParserAppendChild( document_->createTextNode("html, body { height: 100% } parsererror + " "svg { width: 100%; height: 100% }")); style->FinishParsingChildren(); root_element->ParserAppendChild(head); - Element* body = document_->CreateRawElement(kBodyTag, flags); + Element* body = document_->CreateRawElement(html_names::kBodyTag, flags); root_element->ParserAppendChild(body); document_->ParserRemoveChild(*document_element); @@ -171,8 +172,9 @@ if (DocumentXSLT::HasTransformSourceDocument(*document_)) { Vector<Attribute> attributes; - attributes.push_back(Attribute(kStyleAttr, "white-space: normal")); - Element* paragraph = document_->CreateRawElement(kPTag, flags); + attributes.push_back( + Attribute(html_names::kStyleAttr, "white-space: normal")); + Element* paragraph = document_->CreateRawElement(html_names::kPTag, flags); paragraph->ParserSetAttributes(attributes); paragraph->ParserAppendChild(document_->createTextNode( "This document was created as the result of an XSL transformation. The "
diff --git a/third_party/blink/renderer/core/xml/xpath_evaluator.cc b/third_party/blink/renderer/core/xml/xpath_evaluator.cc index 7965d2e2..9879a8a3 100644 --- a/third_party/blink/renderer/core/xml/xpath_evaluator.cc +++ b/third_party/blink/renderer/core/xml/xpath_evaluator.cc
@@ -36,8 +36,6 @@ namespace blink { -using namespace xpath; - XPathExpression* XPathEvaluator::createExpression( const String& expression, XPathNSResolver* resolver, @@ -56,7 +54,7 @@ uint16_t type, const ScriptValue&, ExceptionState& exception_state) { - if (!IsValidContextNode(context_node)) { + if (!xpath::IsValidContextNode(context_node)) { exception_state.ThrowDOMException( DOMExceptionCode::kNotSupportedError, "The node provided is '" + context_node->nodeName() +
diff --git a/third_party/blink/renderer/core/xml/xpath_expression.cc b/third_party/blink/renderer/core/xml/xpath_expression.cc index 7bc0d20..0b39fb0 100644 --- a/third_party/blink/renderer/core/xml/xpath_expression.cc +++ b/third_party/blink/renderer/core/xml/xpath_expression.cc
@@ -36,8 +36,6 @@ namespace blink { -using namespace xpath; - XPathExpression::XPathExpression() = default; XPathExpression* XPathExpression::CreateExpression( @@ -45,7 +43,7 @@ XPathNSResolver* resolver, ExceptionState& exception_state) { auto* expr = MakeGarbageCollected<XPathExpression>(); - Parser parser; + xpath::Parser parser; expr->top_expression_ = parser.ParseStatement(expression, resolver, exception_state); @@ -64,7 +62,7 @@ uint16_t type, const ScriptValue&, ExceptionState& exception_state) { - if (!IsValidContextNode(context_node)) { + if (!xpath::IsValidContextNode(context_node)) { exception_state.ThrowDOMException( DOMExceptionCode::kNotSupportedError, "The node provided is '" + context_node->nodeName() + @@ -72,7 +70,7 @@ return nullptr; } - EvaluationContext evaluation_context(*context_node); + xpath::EvaluationContext evaluation_context(*context_node); auto* result = MakeGarbageCollected<XPathResult>( evaluation_context, top_expression_->Evaluate(evaluation_context));
diff --git a/third_party/blink/renderer/core/xml/xpath_parser.cc b/third_party/blink/renderer/core/xml/xpath_parser.cc index f443f68..b2efc8a 100644 --- a/third_party/blink/renderer/core/xml/xpath_parser.cc +++ b/third_party/blink/renderer/core/xml/xpath_parser.cc
@@ -37,8 +37,7 @@ #include "third_party/blink/renderer/platform/wtf/text/string_hash.h" namespace blink { - -using namespace xpath; +namespace xpath { Parser* Parser::current_parser_ = nullptr; @@ -520,4 +519,5 @@ strings_.erase(s); } +} // namespace xpath } // namespace blink
diff --git a/third_party/blink/renderer/core/xml/xpath_result.cc b/third_party/blink/renderer/core/xml/xpath_result.cc index 3cc8ce4..97c0122 100644 --- a/third_party/blink/renderer/core/xml/xpath_result.cc +++ b/third_party/blink/renderer/core/xml/xpath_result.cc
@@ -33,24 +33,23 @@ namespace blink { -using namespace xpath; - -XPathResult::XPathResult(EvaluationContext& context, const Value& value) +XPathResult::XPathResult(xpath::EvaluationContext& context, + const xpath::Value& value) : value_(value), node_set_position_(0), dom_tree_version_(0) { switch (value_.GetType()) { - case Value::kBooleanValue: + case xpath::Value::kBooleanValue: result_type_ = kBooleanType; return; - case Value::kNumberValue: + case xpath::Value::kNumberValue: result_type_ = kNumberType; return; - case Value::kStringValue: + case xpath::Value::kStringValue: result_type_ = kStringType; return; - case Value::kNodeSetValue: + case xpath::Value::kNodeSetValue: result_type_ = kUnorderedNodeIteratorType; node_set_position_ = 0; - node_set_ = NodeSet::Create(value_.ToNodeSet(&context)); + node_set_ = xpath::NodeSet::Create(value_.ToNodeSet(&context)); document_ = &context.node->GetDocument(); dom_tree_version_ = document_->DomTreeVersion(); return; @@ -152,7 +151,7 @@ return nullptr; } - const NodeSet& nodes = value_.ToNodeSet(nullptr); + const xpath::NodeSet& nodes = value_.ToNodeSet(nullptr); if (resultType() == kFirstOrderedNodeType) return nodes.FirstNode(); return nodes.AnyNode(); @@ -209,7 +208,7 @@ return nullptr; } - const NodeSet& nodes = value_.ToNodeSet(nullptr); + const xpath::NodeSet& nodes = value_.ToNodeSet(nullptr); if (index >= nodes.size()) return nullptr;
diff --git a/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm b/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm index 0b9c2ef..8d01704 100644 --- a/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm +++ b/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm
@@ -194,16 +194,19 @@ NSString* desired_family = desired_family_string; NSFontManager* font_manager = [NSFontManager sharedFontManager]; - // Do a simple case insensitive search for a matching font family. - // NSFontManager requires exact name matches. - // This addresses the problem of matching arial to Arial, etc., but perhaps - // not all the issues. - NSEnumerator* e = [[font_manager availableFontFamilies] objectEnumerator]; - NSString* available_family; - while ((available_family = [e nextObject])) { - if ([desired_family caseInsensitiveCompare:available_family] == - NSOrderedSame) - break; + // From Mac OS 10.15 [NSFontManager availableFonts] does not list certain + // fonts that availableMembersOfFontFamily actually shows results for, for + // example "Hiragino Kaku Gothic ProN" is not listed, only Hiragino Sans is + // listed. We previously enumerated availableFontFamilies and looked for a + // case-insensitive string match here, but instead, we can rely on + // availableMembersOfFontFamily here to do a case-insensitive comparison, then + // set available_family to desired_family if the result was not empty. + // See https://crbug.com/1000542 + NSString* available_family = nil; + NSArray* fonts_in_family = + [font_manager availableMembersOfFontFamily:desired_family]; + if (fonts_in_family && [fonts_in_family count]) { + available_family = desired_family; } int app_kit_font_weight = ToAppKitFontWeight(desired_weight);
diff --git a/third_party/blink/renderer/platform/graphics/compositing_reasons.cc b/third_party/blink/renderer/platform/graphics/compositing_reasons.cc index 4770acc0..c39de6a8 100644 --- a/third_party/blink/renderer/platform/graphics/compositing_reasons.cc +++ b/third_party/blink/renderer/platform/graphics/compositing_reasons.cc
@@ -58,6 +58,8 @@ "Has a backdrop filter"}, {CompositingReason::kRootScroller, "rootScroller", "Is the document.rootScroller"}, + {CompositingReason::kCrossOriginIframe, "crossOriginIframe", + "Is a cross-origin iframe"}, {CompositingReason::kAssumedOverlap, "assumedOverlap", "Might overlap other composited content"}, {CompositingReason::kOverlap, "overlap",
diff --git a/third_party/blink/renderer/platform/graphics/compositing_reasons.h b/third_party/blink/renderer/platform/graphics/compositing_reasons.h index 8d6d9c4..b3b1a04 100644 --- a/third_party/blink/renderer/platform/graphics/compositing_reasons.h +++ b/third_party/blink/renderer/platform/graphics/compositing_reasons.h
@@ -40,6 +40,7 @@ V(WillChangeOther) \ V(BackdropFilter) \ V(RootScroller) \ + V(CrossOriginIframe) \ \ /* Overlap reasons that require knowing what's behind you in paint-order \ before knowing the answer. */ \ @@ -129,7 +130,7 @@ kComboAllDirectNonStyleDeterminedReasons = kVideo | kCanvas | kPlugin | kIFrame | kOverflowScrollingParent | kOutOfFlowClipping | kVideoOverlay | kImmersiveArOverlay | kRoot | - kRootScroller | kScrollDependentPosition, + kRootScroller | kScrollDependentPosition | kCrossOriginIframe, kComboAllDirectReasons = kComboAllDirectStyleDeterminedReasons | kComboAllDirectNonStyleDeterminedReasons,
diff --git a/third_party/blink/tools/blinkpy/web_tests/layout_package/json_results_generator_unittest.py b/third_party/blink/tools/blinkpy/web_tests/layout_package/json_results_generator_unittest.py index fd2620e..fa1123c 100644 --- a/third_party/blink/tools/blinkpy/web_tests/layout_package/json_results_generator_unittest.py +++ b/third_party/blink/tools/blinkpy/web_tests/layout_package/json_results_generator_unittest.py
@@ -36,7 +36,6 @@ def setUp(self): self.builder_name = 'DUMMY_BUILDER_NAME' - self.build_name = 'DUMMY_BUILD_NAME' self.build_number = 'DUMMY_BUILDER_NUMBER' # For archived results.
diff --git a/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py b/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py index e8e21735..4dc9fab 100644 --- a/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py +++ b/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py
@@ -499,13 +499,11 @@ # FIXME: Move these into json_results_generator.py. option_group_definitions.append( ('Result JSON Options', [ - optparse.make_option( - '--build-name', - default='DUMMY_BUILD_NAME', - help='The name of the builder used in its path, e.g. webkit-rel.'), + # TODO(qyearsley): --build-name is unused and should be removed. + optparse.make_option('--build-name', help=optparse.SUPPRESS_HELP), optparse.make_option( '--step-name', - default='webkit_tests', + default='blink_web_tests', help='The name of the step in a build running this script.'), optparse.make_option( '--build-number', @@ -514,15 +512,16 @@ optparse.make_option( '--builder-name', default='', - help=('The name of the builder shown on the waterfall running this script ' - 'e.g. WebKit.')), - optparse.make_option( - '--master-name', - help='The name of the buildbot master.'), + help='The name of the builder shown on the waterfall running ' + 'this script, e.g. "Mac10.13 Tests".'), + # TODO(crbug/1002702): Remove this, it's not actually a Buildbot + # master since Buildbot is gone. + optparse.make_option('--master-name'), optparse.make_option( '--test-results-server', default='', - help='If specified, upload results json files to this appengine server.'), + help='If specified, upload results JSON files to this ' + 'App Engine server.'), ])) option_parser = optparse.OptionParser(
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests index 192cde9..1c98385 100644 --- a/third_party/blink/web_tests/NeverFixTests +++ b/third_party/blink/web_tests/NeverFixTests
@@ -144,6 +144,10 @@ # Linux layout tests do not have a Myanmar fallback font. [ Linux ] inspector-protocol/layout-fonts/fallback-myanmar.js [ WontFix ] +# Mac only test for case-insensitive font-matching. +[ Linux ] inspector-protocol/layout-fonts/mac-case-insensitive-matching.js [ WontFix ] +[ Win ] inspector-protocol/layout-fonts/mac-case-insensitive-matching.js [ WontFix ] + # Segoe UI matching is only relevant on Windows [ Mac ] inspector-protocol/layout-fonts/font-weight-granularity-matching.js [ WontFix ] [ Linux ] inspector-protocol/layout-fonts/font-weight-granularity-matching.js [ WontFix ] @@ -2069,7 +2073,7 @@ external/wpt/pointerevents/pointerevent_touch-action-inherit_parent-none_touch-manual.html [ WontFix ] external/wpt/pointerevents/pointerevent_touch-action-inherit_child-auto-child-none_touch-manual.html [ WontFix ] external/wpt/web-share/share-files-manual.tentative.https.html [ WontFix ] -external/wpt/web-share/share-image-manual.https.html [ WontFix ] +external/wpt/web-share/share-image-manual.tentative.https.html [ WontFix ] external/wpt/uievents/order-of-events/mouse-events/wheel-basic-manual.html [ WontFix ] external/wpt/uievents/order-of-events/mouse-events/wheel-scrolling-manual.html [ WontFix ] external/wpt/html/webappapis/user-prompts/print-manual.html [ WontFix ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 4009d2d..67778500 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -2573,6 +2573,11 @@ crbug.com/1009892 [ Win ] virtual/compositor_threaded_scrollbar_scrolling_hidpi_nozoomfordsf/fast/scrolling/scrollbars/mouse-scrolling-on-div-scrollbar.html [ Failure ] crbug.com/1009892 [ Win ] virtual/compositor_threaded_scrollbar_scrolling_hidpi_nozoomfordsf/fast/scrolling/scrollbars/scrollbar-thumb-snapping.html [ Failure ] +# TODO(arakeri): Mac is the only platform that runs with use_zoom_for_dsf=false. Get rid of this suite when crbug.com/716231 is fixed. +# When DSF = 2 and use_zoom_for_dsf=false, the scroll offsets are different when compared to DSF = 2 and use_zoom_for_dsf=true. +crbug.com/1016186 [ Win ] virtual/compositor_threaded_scrollbar_scrolling_hidpi_nozoomfordsf/fast/scrolling/scrollbars/dsf-ready/mouse-interactions-dsf-2.html [ Failure Timeout ] +crbug.com/1016186 [ Linux ] virtual/compositor_threaded_scrollbar_scrolling_hidpi_nozoomfordsf/fast/scrolling/scrollbars/dsf-ready/mouse-interactions-dsf-2.html [ Failure Timeout ] + # Some control characters still not visible crbug.com/893490 [ Mac ] external/wpt/css/css-text/white-space/control-chars-001.html [ Failure ] crbug.com/893490 [ Mac ] external/wpt/css/css-text/white-space/control-chars-002.html [ Failure ] @@ -5462,7 +5467,6 @@ # Sheriff 2019-07-03 crbug.com/979490 [ Linux Win ] virtual/omt-worker-fetch/external/wpt/workers/modules/dedicated-worker-import-referrer.html [ Pass Timeout ] -crbug.com/981210 external/wpt/web-animations/interfaces/Animation/oncancel.html [ Pass Failure ] # Sheriff 2019-07-04 crbug.com/981267 [ Linux ] http/tests/devtools/persistence/persistence-move-breakpoints-on-reload.js [ Pass Failure ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index efb5506..7b0a3ac 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -525,6 +525,21 @@ "--disable-smooth-scrolling"] }, { + "prefix": "hidpi", + "base": "fast/scrolling/scrollbars/dsf-ready", + "args": ["--disable-smooth-scrolling", + "--force-device-scale-factor=2"] + }, + { + "prefix": "compositor_threaded_scrollbar_scrolling_hidpi", + "base": "fast/scrolling/scrollbars/dsf-ready", + "args": ["--enable-features=CompositorThreadedScrollbarScrolling", + "--enable-threaded-compositing", + "--enable-prefer-compositing-to-lcd-text", + "--disable-smooth-scrolling", + "--force-device-scale-factor=2"] + }, + { "prefix": "compositor_threaded_scrollbar_scrolling_hidpi_nozoomfordsf", "base": "fast/scrolling/scrollbars", "args": ["--enable-features=CompositorThreadedScrollbarScrolling",
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 f1aca7c..ed37a3c 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
@@ -6949,9 +6949,9 @@ {} ] ], - "web-share/share-image-manual.https.html": [ + "web-share/share-image-manual.tentative.https.html": [ [ - "web-share/share-image-manual.https.html", + "web-share/share-image-manual.tentative.https.html", {} ] ], @@ -43567,6 +43567,30 @@ {} ] ], + "css/css-flexbox/flex-minimum-width-flex-items-009.html": [ + [ + "css/css-flexbox/flex-minimum-width-flex-items-009.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "css/css-flexbox/flex-minimum-width-flex-items-010.html": [ + [ + "css/css-flexbox/flex-minimum-width-flex-items-010.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], "css/css-flexbox/flex-order.html": [ [ "css/css-flexbox/flex-order.html", @@ -87601,6 +87625,18 @@ {} ] ], + "css/css-values/percentage-rem-low.html": [ + [ + "css/css-values/percentage-rem-low.html", + [ + [ + "/css/reference/ref-filled-green-100px-square-only.html", + "==" + ] + ], + {} + ] + ], "css/css-values/q-unit-case-insensitivity-001.html": [ [ "css/css-values/q-unit-case-insensitivity-001.html", @@ -98523,6 +98559,18 @@ {} ] ], + "css/css-writing-modes/wm-propagation-svg-root-scrollbar.svg": [ + [ + "css/css-writing-modes/wm-propagation-svg-root-scrollbar.svg", + [ + [ + "/css/reference/blank.html", + "!=" + ] + ], + {} + ] + ], "css/css-writing-modes/writing-mode-horizontal-001l.html": [ [ "css/css-writing-modes/writing-mode-horizontal-001l.html", @@ -138838,6 +138886,12 @@ "css/css-grid/grid-model/support/grid.css": [ [] ], + "css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-001-expected.txt": [ + [] + ], + "css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-002-expected.txt": [ + [] + ], "css/css-grid/layout-algorithm/references/grid-percent-cols-filled-shrinkwrap-001-ref.html": [ [] ], @@ -138868,6 +138922,9 @@ "css/css-grid/parsing/grid-template-rows-computed-nogrid-expected.txt": [ [] ], + "css/css-grid/parsing/grid-template-rows-computed-withcontent-expected.txt": [ + [] + ], "css/css-grid/reference/display-grid-ref.html": [ [] ], @@ -143005,6 +143062,9 @@ "css/css-text/parsing/text-align-all-valid-expected.txt": [ [] ], + "css/css-text/parsing/text-align-computed-expected.txt": [ + [] + ], "css/css-text/parsing/text-align-last-computed-expected.txt": [ [] ], @@ -156058,6 +156118,9 @@ "html/cross-origin-opener-policy/popup-none.https-expected.txt": [ [] ], + "html/cross-origin-opener-policy/popup-redirect-cache.https.html.headers": [ + [] + ], "html/cross-origin-opener-policy/popup-same-origin-non-initial-about-blank.https.html.headers": [ [] ], @@ -163792,12 +163855,6 @@ "media-capabilities/README.md": [ [] ], - "media-capabilities/idlharness.any-expected.txt": [ - [] - ], - "media-capabilities/idlharness.any.worker-expected.txt": [ - [] - ], "media-playback-quality/META.yml": [ [] ], @@ -177169,6 +177226,9 @@ "webmidi/idlharness.window-expected.txt": [ [] ], + "webrtc-extensions/META.yml": [ + [] + ], "webrtc-identity/META.yml": [ [] ], @@ -177205,9 +177265,6 @@ "webrtc-stats/getStats-remote-candidate-address-expected.txt": [ [] ], - "webrtc-svc/RTCRtpParameters-scalability-expected.txt": [ - [] - ], "webrtc/META.yml": [ [] ], @@ -188720,6 +188777,48 @@ {} ] ], + "IndexedDB/structured-clone-transaction-state.any.js": [ + [ + "IndexedDB/structured-clone-transaction-state.any.html", + { + "script_metadata": [ + [ + "script", + "support-promises.js" + ], + [ + "title", + "Indexed DB transaction state during Structured Serializing" + ], + [ + "timeout", + "long" + ] + ], + "timeout": "long" + } + ], + [ + "IndexedDB/structured-clone-transaction-state.any.worker.html", + { + "script_metadata": [ + [ + "script", + "support-promises.js" + ], + [ + "title", + "Indexed DB transaction state during Structured Serializing" + ], + [ + "timeout", + "long" + ] + ], + "timeout": "long" + } + ] + ], "IndexedDB/structured-clone.any.js": [ [ "IndexedDB/structured-clone.any.html", @@ -199179,6 +199278,12 @@ } ] ], + "compat/webkit-box-ignore-box-pack.html": [ + [ + "compat/webkit-box-ignore-box-pack.html", + {} + ] + ], "compat/webkit-box-removing-triggering-anonymous-merge.html": [ [ "compat/webkit-box-removing-triggering-anonymous-merge.html", @@ -209661,6 +209766,12 @@ {} ] ], + "css/css-grid/parsing/grid-template-columns-computed-withcontent.html": [ + [ + "css/css-grid/parsing/grid-template-columns-computed-withcontent.html", + {} + ] + ], "css/css-grid/parsing/grid-template-columns-computed.html": [ [ "css/css-grid/parsing/grid-template-columns-computed.html", @@ -209685,6 +209796,12 @@ {} ] ], + "css/css-grid/parsing/grid-template-rows-computed-withcontent.html": [ + [ + "css/css-grid/parsing/grid-template-rows-computed-withcontent.html", + {} + ] + ], "css/css-grid/parsing/grid-template-rows-computed.html": [ [ "css/css-grid/parsing/grid-template-rows-computed.html", @@ -211791,6 +211908,12 @@ {} ] ], + "css/css-pseudo/before-in-display-none-crash.html": [ + [ + "css/css-pseudo/before-in-display-none-crash.html", + {} + ] + ], "css/css-pseudo/first-letter-crash.html": [ [ "css/css-pseudo/first-letter-crash.html", @@ -222287,6 +222410,14 @@ {} ] ], + "css/selectors/focus-visible-011.html": [ + [ + "css/selectors/focus-visible-011.html", + { + "testdriver": true + } + ] + ], "css/selectors/focus-within-009.html": [ [ "css/selectors/focus-within-009.html", @@ -226574,6 +226705,12 @@ {} ] ], + "element-timing/observe-empty-attribute.html": [ + [ + "element-timing/observe-empty-attribute.html", + {} + ] + ], "element-timing/observe-multiple-images.html": [ [ "element-timing/observe-multiple-images.html", @@ -243464,6 +243601,12 @@ {} ] ], + "html/cross-origin-opener-policy/popup-redirect-cache.https.html": [ + [ + "html/cross-origin-opener-policy/popup-redirect-cache.https.html", + {} + ] + ], "html/cross-origin-opener-policy/popup-same-origin-non-initial-about-blank.https.html": [ [ "html/cross-origin-opener-policy/popup-same-origin-non-initial-about-blank.https.html", @@ -258375,6 +258518,14 @@ {} ] ], + "media-source/mediasource-replay.html": [ + [ + "media-source/mediasource-replay.html", + { + "timeout": "long" + } + ] + ], "media-source/mediasource-seek-beyond-duration.html": [ [ "media-source/mediasource-seek-beyond-duration.html", @@ -310359,24 +310510,18 @@ {} ] ], - "web-nfc/NDEFMessage_constructor.https.html": [ - [ - "web-nfc/NDEFMessage_constructor.https.html", - {} - ] - ], - "web-nfc/NDEFRecord_constructor.https.html": [ - [ - "web-nfc/NDEFRecord_constructor.https.html", - {} - ] - ], "web-nfc/NDEFErrorEvent_constructor.https.html": [ [ "web-nfc/NDEFErrorEvent_constructor.https.html", {} ] ], + "web-nfc/NDEFMessage_constructor.https.html": [ + [ + "web-nfc/NDEFMessage_constructor.https.html", + {} + ] + ], "web-nfc/NDEFReader_options.https.html": [ [ "web-nfc/NDEFReader_options.https.html", @@ -310401,6 +310546,12 @@ {} ] ], + "web-nfc/NDEFRecord_constructor.https.html": [ + [ + "web-nfc/NDEFRecord_constructor.https.html", + {} + ] + ], "web-nfc/NDEFWriter_push.https.html": [ [ "web-nfc/NDEFWriter_push.https.html", @@ -312015,6 +312166,49 @@ {} ] ], + "webmessaging/Channel_postMessage_transfer_xsite_incoming_messages.window.js": [ + [ + "webmessaging/Channel_postMessage_transfer_xsite_incoming_messages.window.html", + { + "script_metadata": [ + [ + "script", + "/common/get-host-info.sub.js" + ] + ] + } + ] + ], + "webmessaging/Channel_postMessage_with_transfer_entangled.any.js": [ + [ + "webmessaging/Channel_postMessage_with_transfer_entangled.any.html", + {} + ], + [ + "webmessaging/Channel_postMessage_with_transfer_entangled.any.worker.html", + {} + ] + ], + "webmessaging/Channel_postMessage_with_transfer_incoming_messages.any.js": [ + [ + "webmessaging/Channel_postMessage_with_transfer_incoming_messages.any.html", + {} + ], + [ + "webmessaging/Channel_postMessage_with_transfer_incoming_messages.any.worker.html", + {} + ] + ], + "webmessaging/Channel_postMessage_with_transfer_outgoing_messages.any.js": [ + [ + "webmessaging/Channel_postMessage_with_transfer_outgoing_messages.any.html", + {} + ], + [ + "webmessaging/Channel_postMessage_with_transfer_outgoing_messages.any.worker.html", + {} + ] + ], "webmessaging/MessageEvent-trusted.html": [ [ "webmessaging/MessageEvent-trusted.html", @@ -312219,6 +312413,19 @@ {} ] ], + "webmessaging/postMessage_MessagePorts_xsite.sub.window.js": [ + [ + "webmessaging/postMessage_MessagePorts_xsite.sub.window.html", + { + "script_metadata": [ + [ + "script", + "/common/get-host-info.sub.js" + ] + ] + } + ] + ], "webmessaging/postMessage_arrays.sub.htm": [ [ "webmessaging/postMessage_arrays.sub.htm", @@ -312662,6 +312869,12 @@ } ] ], + "webrtc-extensions/RTCRtpReceiver-playoutDelayHint.html": [ + [ + "webrtc-extensions/RTCRtpReceiver-playoutDelayHint.html", + {} + ] + ], "webrtc-identity/RTCPeerConnection-constructor.html": [ [ "webrtc-identity/RTCPeerConnection-constructor.html", @@ -335037,7 +335250,7 @@ "testharness" ], "2dcontext/text-styles/2d.text.font.parse.invalid.html": [ - "0cb62e86318bc6cb80f1c417b5fc27e0d180def2", + "9149d4f696f51eb5af075f34881b432f759bca87", "testharness" ], "2dcontext/text-styles/2d.text.font.parse.size.percentage.default.html": [ @@ -335225,7 +335438,7 @@ "support" ], "2dcontext/tools/tests2dtext.yaml": [ - "c57caee8f199279fc3a2d408d993944bdff0030f", + "6d5f8f660fa3fbc8e2b8b8710070241ccde392d0", "support" ], "2dcontext/transformations/2d.transformation.order.html": [ @@ -337336,6 +337549,10 @@ "cc905e56ecf83ea4cd4f1fe2ccfac425cdc5f9d0", "testharness" ], + "IndexedDB/structured-clone-transaction-state.any.js": [ + "8c41d3b72bfc4b72565745531b832b4320729af1", + "testharness" + ], "IndexedDB/structured-clone.any.js": [ "e03ba7aeee47bcd8ae75e2210fc2165581c0a82f", "testharness" @@ -337433,7 +337650,7 @@ "support" ], "README.md": [ - "f728d502e17783c92114c904597eb3cc9b8c473a", + "320176c40ce4d4fc3bfdbd6a637c87e59143cb20", "support" ], "WebCryptoAPI/META.yml": [ @@ -338437,7 +338654,7 @@ "support" ], "animation-worklet/inactive-timeline.https.html": [ - "24dc98c2327e45dd263b63139510445e96141ce1", + "bdd46f9abc0c8702931965f981b9beab2792380f", "testharness" ], "animation-worklet/multiple-effects-on-same-target-driven-by-individual-local-time.https.html": [ @@ -340460,6 +340677,10 @@ "06e728342cdb63a72b420423b40b6e32ae3e2162", "reftest" ], + "compat/webkit-box-ignore-box-pack.html": [ + "80b52fbf1fe13a7c9ec5288f301194e40a381430", + "testharness" + ], "compat/webkit-box-removing-triggering-anonymous-merge.html": [ "8506425548b6ff97491e388dc1a1f3830aa790fc", "testharness" @@ -340777,15 +340998,15 @@ "testharness" ], "content-security-policy/connect-src/connect-src-beacon-allowed.sub.html": [ - "a32913dd3e27b6c4df0f322f2ed5c600eac4f322", + "de032a9f47b3684586bd354fe98c5535d147d1b5", "testharness" ], "content-security-policy/connect-src/connect-src-beacon-blocked.sub.html": [ - "95b4ce9a19116479a8840517dcfabeaf168729b2", + "025a72018429d780a318758f773eca343ec153e8", "testharness" ], "content-security-policy/connect-src/connect-src-beacon-redirect-to-blocked.sub.html": [ - "7328d7a704a3bc803e2497293f61af1d32746fae", + "b0cbea51f5d83b5714d7d03f88f134b807cacfc6", "testharness" ], "content-security-policy/connect-src/connect-src-eventsource-allowed.sub.html": [ @@ -341105,7 +341326,7 @@ "testharness" ], "content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-sandboxed-cross-url-block.html": [ - "654e90e0b82da301dfa655b8fd48d5e74a7327a8", + "d7c83ae2f5b2ee980dd60f7b2605275d6a4586b0", "testharness" ], "content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-cross-none-block.html": [ @@ -341605,7 +341826,7 @@ "testharness" ], "content-security-policy/media-src/media-src-7_3_2.sub.html": [ - "6abe850624f9bbc77f515c41d0042c234ae414e9", + "431a58608ab7f6aca02723b0e81e7d86bf34c92d", "testharness" ], "content-security-policy/media-src/media-src-blocked.sub.html": [ @@ -342141,7 +342362,7 @@ "support" ], "content-security-policy/reporting/report-cross-origin-no-cookies.sub.html": [ - "98d85b6994be5955388d7652cf63c90d9cc58eee", + "a034bdbd4fe6c3ceb87fafb0816a6648da2f4e6d", "testharness" ], "content-security-policy/reporting/report-cross-origin-no-cookies.sub.html.sub.headers": [ @@ -342753,7 +342974,7 @@ "testharness" ], "content-security-policy/script-src/scripthash-unicode-normalization.sub.html": [ - "4212297c68399ad32038f5e7bad2f8c8e4aa3120", + "b082b55e21cbad7501f1cc87cd0f6b073cde4180", "testharness" ], "content-security-policy/script-src/scriptnonce-allowed.sub.html": [ @@ -361885,7 +362106,7 @@ "testharness" ], "css/css-backgrounds/animations/border-image-source-interpolation-expected.txt": [ - "241feb7aa308fafe9fd0c22645b45342f580c94c", + "f11069c94c040f4e1fa2b75a67f9f750e90f480d", "support" ], "css/css-backgrounds/animations/border-image-source-interpolation.html": [ @@ -361905,7 +362126,7 @@ "testharness" ], "css/css-backgrounds/animations/box-shadow-interpolation-expected.txt": [ - "3f594517cf82f0f7c1ca99ea723b1087b0f11878", + "83a8d423116f5266eafa670261a1d4d564850a08", "support" ], "css/css-backgrounds/animations/box-shadow-interpolation.html": [ @@ -364777,7 +364998,7 @@ "testharness" ], "css/css-backgrounds/parsing/background-position-x-computed-expected.txt": [ - "2f99244a7c09ca63b8ee31c6c08ee5eeb364ad6a", + "79c191255c84c57c0bad9bfcd9d926c8d4e720ee", "support" ], "css/css-backgrounds/parsing/background-position-x-computed.html": [ @@ -364797,7 +365018,7 @@ "testharness" ], "css/css-backgrounds/parsing/background-position-y-computed-expected.txt": [ - "f96b97f83ea9cb15609b98a3ff7ae5f207559047", + "1e2a0f510f815af628b46aa4ff20e8b9268076ca", "support" ], "css/css-backgrounds/parsing/background-position-y-computed.html": [ @@ -365901,7 +366122,7 @@ "testharness" ], "css/css-break/parsing/break-after-computed-expected.txt": [ - "e26991ea443bd471029cab225cf88d3d61156214", + "54f97f2dbfd71d1a03268ee9be3950d8c080eaae", "support" ], "css/css-break/parsing/break-after-computed.html": [ @@ -365921,7 +366142,7 @@ "testharness" ], "css/css-break/parsing/break-before-computed-expected.txt": [ - "de032acf957e564ae149a0d4afe16f6bf6215157", + "fc493c390c826286415662fff3bb1dee20622853", "support" ], "css/css-break/parsing/break-before-computed.html": [ @@ -365941,7 +366162,7 @@ "testharness" ], "css/css-break/parsing/break-inside-computed-expected.txt": [ - "790446e827add3ffbf915051e8ef25d04205a3c5", + "3402f4008a0b58d064d78850a3c14ea559f40334", "support" ], "css/css-break/parsing/break-inside-computed.html": [ @@ -369836,6 +370057,14 @@ "3daa38a450d2044491d73011d3fe3a676cf5ffb0", "reftest" ], + "css/css-flexbox/flex-minimum-width-flex-items-009.html": [ + "1700c4a494c89a6c7f7f2b123f0d673d498cc5c5", + "reftest" + ], + "css/css-flexbox/flex-minimum-width-flex-items-010.html": [ + "8845b4896e58d47dac4fc8b25b9fc36b8d594521", + "reftest" + ], "css/css-flexbox/flex-order-ref.html": [ "02f0eb35752e805aa2bc0bd339f73ff2b197c99e", "support" @@ -372293,7 +372522,7 @@ "support" ], "css/css-flexbox/support/200x200-green.png": [ - "1136e7230b51e0b6208fac90a8bb45e34439cb4b", + "1dcc392a6ef71e55302c40d41a547cf3f75a8f24", "support" ], "css/css-flexbox/support/300x150-green.png": [ @@ -372633,7 +372862,7 @@ "testharness" ], "css/css-fonts/animations/font-variation-settings-interpolation-expected.txt": [ - "396a3b9e5cd4debec0ec9ec99203c7f30d6b283b", + "854efe3e4d1412ea3da15bace063e8bfcf46b8c9", "support" ], "css/css-fonts/animations/font-variation-settings-interpolation.html": [ @@ -380621,15 +380850,15 @@ "testharness" ], "css/css-forced-color-adjust/parsing/forced-color-adjust-computed-expected.txt": [ - "3c35187f93f96fc63aa2f8f09e6ae8f73c4247f1", + "59d798f5f6ab85f361729acb5d197bcf8b31a7fc", "support" ], "css/css-forced-color-adjust/parsing/forced-color-adjust-computed.html": [ - "cd9349c075cdf5d0c25d78f1506971e60f1cc925", + "2e1f58974a45d91e36f45c7001c2bb34f5b0e5c3", "testharness" ], "css/css-forced-color-adjust/parsing/forced-color-adjust-invalid.html": [ - "f1b6f696a72cf087915b7905b790e00e20e6a076", + "6329305a9ce381adbee2f4d82409214d7a3c2fbe", "testharness" ], "css/css-forced-color-adjust/parsing/forced-color-adjust-valid-expected.txt": [ @@ -382337,7 +382566,7 @@ "reftest" ], "css/css-grid/animation/grid-template-columns-interpolation-expected.txt": [ - "52ecd70c47d6394238fded231098f371a04957a0", + "d0d09c2ba7a4e66bcc770ee53ad9398b71779977", "support" ], "css/css-grid/animation/grid-template-columns-interpolation.html": [ @@ -382353,7 +382582,7 @@ "reftest" ], "css/css-grid/animation/grid-template-rows-interpolation-expected.txt": [ - "b11bbee2bc981b742ffbe4522e80023da4770ce9", + "737697d46d07f615b1b47049450b67f96ce74774", "support" ], "css/css-grid/animation/grid-template-rows-interpolation.html": [ @@ -383420,10 +383649,18 @@ "ab55502487328d11ac153440fec4963e6e70709c", "testharness" ], + "css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-001-expected.txt": [ + "549da5a597dba9fcf40ae65da6b77f28412653dd", + "support" + ], "css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-001.html": [ "a478f9ace23f0488a60e2ea1e4f2da8ff81221cd", "testharness" ], + "css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-002-expected.txt": [ + "95dd2e63099c11cf58501e9dbc5e7cd2dc0c8d4c", + "support" + ], "css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-002.html": [ "ef5f1ae10932935e990bd83bc8b33e9e88d49fa3", "testharness" @@ -383576,6 +383813,10 @@ "b95914fe3e55bebd04a77f1146279089efd5f964", "testharness" ], + "css/css-grid/parsing/grid-template-columns-computed-withcontent.html": [ + "9b7cd030a7c145a9300ef7d6700ca6a8dd4e3e5e", + "testharness" + ], "css/css-grid/parsing/grid-template-columns-computed.html": [ "f6d0d9721c9dd8ed1c0441a9dd2e2077b71350d3", "testharness" @@ -383596,6 +383837,14 @@ "03e601acb93191cecaa73b571d5f6cd8e2a6710a", "testharness" ], + "css/css-grid/parsing/grid-template-rows-computed-withcontent-expected.txt": [ + "27c7ad78f1b72b3d5917b6da8c8e0fdd7ba6920b", + "support" + ], + "css/css-grid/parsing/grid-template-rows-computed-withcontent.html": [ + "693cf338c0dc42406336ccd99a605b1cf0d4f9be", + "testharness" + ], "css/css-grid/parsing/grid-template-rows-computed.html": [ "40722623aaa1ee805dc6e282951febb0021e2a8a", "testharness" @@ -384161,7 +384410,7 @@ "testharness" ], "css/css-images/parsing/image-orientation-computed-expected.txt": [ - "a1831a7dcd56196d4657d17e4856c54cd01234f3", + "cc727dba18e2c08fb065248221347d7bcf14c99c", "support" ], "css/css-images/parsing/image-orientation-computed.html": [ @@ -384181,7 +384430,7 @@ "testharness" ], "css/css-images/parsing/image-rendering-computed-expected.txt": [ - "8a028d6928cb09f8b7f527fd579950af99a41a8c", + "2f247b24e68ccb1e4d741b0ec42a90383e1ff289", "support" ], "css/css-images/parsing/image-rendering-computed.html": [ @@ -384213,7 +384462,7 @@ "testharness" ], "css/css-images/parsing/object-fit-computed-expected.txt": [ - "6f8cbd7c599870816d16c192609dbd1b7eb3cbdb", + "e619df470288c65263bb0f58a885e51393adbfef", "support" ], "css/css-images/parsing/object-fit-computed.html": [ @@ -384461,7 +384710,7 @@ "testharness" ], "css/css-inline/parsing/alignment-baseline-computed-expected.txt": [ - "f75d42c9356acb9afcc38e9a9123d17fa8281b4c", + "fd197442db1c670fc26dd54b09fc7f4633dd1a47", "support" ], "css/css-inline/parsing/alignment-baseline-computed.html": [ @@ -384505,7 +384754,7 @@ "testharness" ], "css/css-inline/parsing/dominant-baseline-computed-expected.txt": [ - "0f4bdfd3df99244e20c80e4d5527704b0761b972", + "6758b1bd12a6389ee7fef0149908ca17c2230db8", "support" ], "css/css-inline/parsing/dominant-baseline-computed.html": [ @@ -385609,7 +385858,7 @@ "testharness" ], "css/css-lists/parsing/list-style-type-computed-expected.txt": [ - "2ee6f4c99afb2b258f06fd4e9b54d0bad13f0718", + "f65136106e55f4df3c0f892af5c86c3ef417b1d8", "support" ], "css/css-lists/parsing/list-style-type-computed.html": [ @@ -388709,7 +388958,7 @@ "testharness" ], "css/css-multicol/parsing/column-fill-computed-expected.txt": [ - "14df333dba2e4c37c2e09b40461fa0844715b0cb", + "bcb58c71201b14b1d9c1ad05c74488e969c04d6c", "support" ], "css/css-multicol/parsing/column-fill-computed.html": [ @@ -389289,7 +389538,7 @@ "testharness" ], "css/css-overflow/parsing/overflow-computed-expected.txt": [ - "d52fcc5d60ac07b3260d460ee6986c9c3df8841a", + "92a9557fde78ca7960a36ad46f0db9059c0b0f6c", "support" ], "css/css-overflow/parsing/overflow-computed.html": [ @@ -391148,6 +391397,10 @@ "d8844f9c961e94b2fd353628cb2c6e3e12123054", "reftest" ], + "css/css-pseudo/before-in-display-none-crash.html": [ + "5759089a5057a37afcc087abc2c5a1703a75fcb1", + "testharness" + ], "css/css-pseudo/first-letter-001-ref.html": [ "d832a308ef93d85437ea23fccc70447b0c2a339f", "support" @@ -392593,7 +392846,7 @@ "testharness" ], "css/css-shapes/parsing/shape-outside-computed-expected.txt": [ - "8e729c6d76de48eaa318de84de72e4fb8ad72940", + "4f3a992651b78f162b006fd5007b5a6c93da0d79", "support" ], "css/css-shapes/parsing/shape-outside-computed.html": [ @@ -395553,7 +395806,7 @@ "testharness" ], "css/css-text-decor/parsing/text-decoration-computed-expected.txt": [ - "6f128b0126e2c4479f19d89868cf161108beaae9", + "8b3138f7196a7dd03b95388bf7d34956610b1fc2", "support" ], "css/css-text-decor/parsing/text-decoration-computed.html": [ @@ -395565,7 +395818,7 @@ "testharness" ], "css/css-text-decor/parsing/text-decoration-line-computed-expected.txt": [ - "965acb369efdfa28e27ed60452b026e4a4e11ff0", + "fee1e9e757f460299c66637b9bf1a03c4c335e02", "support" ], "css/css-text-decor/parsing/text-decoration-line-computed.html": [ @@ -399753,7 +400006,7 @@ "testharness" ], "css/css-text/parsing/hyphens-computed-expected.txt": [ - "0afda9c1a9ca9176277f3c2ab4fadfe94167fe4c", + "01ec12abed0dcbc709baffde51177fa30040e135", "support" ], "css/css-text/parsing/hyphens-computed.html": [ @@ -399793,7 +400046,7 @@ "testharness" ], "css/css-text/parsing/overflow-wrap-computed-expected.txt": [ - "7983d76c800618d3a625c212e090dabafe5dcba7", + "6866ac85893203f11267894682e1eef594072202", "support" ], "css/css-text/parsing/overflow-wrap-computed.html": [ @@ -399836,6 +400089,10 @@ "f65b15afde028fc9c6a34376817b68b449ccd00c", "testharness" ], + "css/css-text/parsing/text-align-computed-expected.txt": [ + "24d4cd103291a277e1e80be1317525ca23e1c46e", + "support" + ], "css/css-text/parsing/text-align-computed.html": [ "30c231be66f6d297cf6bbf75e59a9b5dd2bded53", "testharness" @@ -399845,7 +400102,7 @@ "testharness" ], "css/css-text/parsing/text-align-last-computed-expected.txt": [ - "ebc6e6c1c247c45617a30c577c4be5312de0ced3", + "faee36e0effbba7c31f4ba401b09106f7fb8abe0", "support" ], "css/css-text/parsing/text-align-last-computed.html": [ @@ -399885,7 +400142,7 @@ "testharness" ], "css/css-text/parsing/text-justify-computed-expected.txt": [ - "4912130427925529a57cab2cb00792362e0b7cb3", + "7dbe744ed510933bdfb21a9ca5a62feaadaf123f", "support" ], "css/css-text/parsing/text-justify-computed.html": [ @@ -399905,7 +400162,7 @@ "testharness" ], "css/css-text/parsing/text-transform-computed-expected.txt": [ - "1eb332b0cdf87638fe36f7a1e7f02b6fe0215fd7", + "53ebbcd5da10f82b643d9a3c56c0ac42006c2e93", "support" ], "css/css-text/parsing/text-transform-computed.html": [ @@ -399961,7 +400218,7 @@ "testharness" ], "css/css-text/parsing/word-wrap-computed-expected.txt": [ - "bd94d44d5a8ab8136eed7e0835f033f2bb8fa3c1", + "6f296dd1c7f8e39482b99c89358ce56962cc9f6e", "support" ], "css/css-text/parsing/word-wrap-computed.html": [ @@ -403485,7 +403742,7 @@ "testharness" ], "css/css-transforms/animation/list-interpolation-expected.txt": [ - "29ac41d17d51dca5687b4dab7388fe40e4eabb97", + "c3140b465ef1b222b9fa1b8e9278b43caaefb025", "support" ], "css/css-transforms/animation/list-interpolation.html": [ @@ -403513,7 +403770,7 @@ "testharness" ], "css/css-transforms/animation/transform-interpolation-001-expected.txt": [ - "fc3be7fe22ad4ea69ff95329b5ebd79e5952a688", + "dd58e6a649dfd745225f2f84b1214187e1ca4405", "support" ], "css/css-transforms/animation/transform-interpolation-001.html": [ @@ -404493,7 +404750,7 @@ "testharness" ], "css/css-transforms/parsing/transform-box-computed-expected.txt": [ - "7a3f2108dca6ec1363e75114d446894fda997e51", + "365f4d52425694397cb8401303f2ad5ba1c2f52b", "support" ], "css/css-transforms/parsing/transform-box-computed.html": [ @@ -408041,7 +408298,7 @@ "testharness" ], "css/css-transitions/parsing/transition-timing-function-computed.html": [ - "e57856bab4f16f11f288197bb0244aaffa57be7e", + "cb110549d0b072311d6f00e23bb5452170b0f43c", "testharness" ], "css/css-transitions/parsing/transition-timing-function-invalid.html": [ @@ -411625,7 +411882,7 @@ "testharness" ], "css/css-ui/parsing/user-select-computed-expected.txt": [ - "cddacbd876fa0e0f37ede326df270a8abe4bd889", + "ccdc1a14944a10d239ea71d3377bde22f5cc3d87", "support" ], "css/css-ui/parsing/user-select-computed.html": [ @@ -413572,6 +413829,10 @@ "d7dd4edb5880e9162a702e3c1ce0a5540dc42679", "testharness" ], + "css/css-values/percentage-rem-low.html": [ + "d06e7522a68e08f2b70cf9ccd71517bbf582b112", + "reftest" + ], "css/css-values/q-unit-case-insensitivity-001.html": [ "b4a08aa117952c6f92e2aec6f57843b46a460104", "reftest" @@ -420600,6 +420861,10 @@ "523928f9ad8e40e4f539e81724cb905b1b18159f", "testharness" ], + "css/css-writing-modes/wm-propagation-svg-root-scrollbar.svg": [ + "a9a7b25ff26854e137c8d6bc5c17160201401cdb", + "reftest" + ], "css/css-writing-modes/writing-mode-horizontal-001l.html": [ "44ef05db12b560fbefb6ddf5b0511645a62f9ed7", "reftest" @@ -422329,7 +422594,7 @@ "support" ], "css/filter-effects/animation/backdrop-filter-interpolation-001-expected.txt": [ - "906f04f367b767333af5b7bda440ffe336faf559", + "f54727be892172c15be80a3d9daf2f70b2f17046", "support" ], "css/filter-effects/animation/backdrop-filter-interpolation-001.html": [ @@ -422349,7 +422614,7 @@ "testharness" ], "css/filter-effects/animation/filter-interpolation-001-expected.txt": [ - "3823e2f6def50e17bfdaf5d1dfe4947e3af6a1cf", + "38b35eb2f945e9e955f1b9834a4bd8f8cec8ff9d", "support" ], "css/filter-effects/animation/filter-interpolation-001.html": [ @@ -422357,7 +422622,7 @@ "testharness" ], "css/filter-effects/animation/filter-interpolation-002-expected.txt": [ - "19f208ef9a9c8e123f30d12e7a1a4908f1965df1", + "cbb055689f368bdbf80d40d54696467166596a4b", "support" ], "css/filter-effects/animation/filter-interpolation-002.html": [ @@ -422365,7 +422630,7 @@ "testharness" ], "css/filter-effects/animation/filter-interpolation-003-expected.txt": [ - "92ca741aed79936f1da77c30255c19bd0cbea2e0", + "2080b37a3d8da56bb9e42657e2a0e4c9750e5d79", "support" ], "css/filter-effects/animation/filter-interpolation-003.html": [ @@ -424360,6 +424625,10 @@ "eb01204b29c8e30b651b083459c01983b99dd70d", "testharness" ], + "css/selectors/focus-visible-011.html": [ + "f95458fc4d3e4a538ecf8788b87528a9a138db5c", + "testharness" + ], "css/selectors/focus-within-001-ref.html": [ "2913775a2204eb173ba45251a84ab2c01cda35bc", "support" @@ -426221,7 +426490,7 @@ "support" ], "css/support/computed-testcommon.js": [ - "c6719784522136093480178197375bef75159d05", + "1e87f2a518cb1c7845a99d6a13330e7a13436eca", "support" ], "css/support/green.ico": [ @@ -426245,7 +426514,7 @@ "support" ], "css/support/interpolation-testcommon.js": [ - "24c47e136c8d98603238a09dbb64bd79cd6751d2", + "9e63b02cb703d44e909c0c525f3bd56708477dda", "support" ], "css/support/parsing-testcommon.js": [ @@ -434449,15 +434718,15 @@ "testharness" ], "element-timing/background-image-multiple-elements.html": [ - "084bb9ca0205815a1c7ad7764ce1979485e88435", + "44755d49f5c39fe8b5f96b73bcb4b7f3067dd2df", "testharness" ], "element-timing/background-image-stretched.html": [ - "930b4cef8eb21b6eecbbfdd1eaf0c79ec87db551", + "0cd56333f50495f770145291df794877fb401a36", "testharness" ], "element-timing/buffer-before-onload.html": [ - "68eeeefe15fdc587cdf0d4382f90c33ee3230290", + "d675c75ba1a2e46bf964a87cbfe9547af9fb09fb", "testharness" ], "element-timing/buffered-flag.html": [ @@ -434477,7 +434746,7 @@ "testharness" ], "element-timing/disconnect-image.html": [ - "82e7461b0417fb6f667ad266c08789b58f06c457", + "fa42397557b9d91d5bf0c4e0cb488b32825d8fc0", "testharness" ], "element-timing/element-only-when-fully-active.html": [ @@ -434501,11 +434770,11 @@ "testharness" ], "element-timing/image-carousel.html": [ - "39d9f0195c6ba17c3e83b41e5d2391203608b15a", + "dc5d8e8dde89b6e8e4c8865b4469c5f42e2330e7", "testharness" ], "element-timing/image-clipped-svg.html": [ - "1e9971c8a8df75274480f2bd11fa2c730dc79adb", + "15c78a4cec5e0d78d91d67ed2d501324a1f9bab6", "testharness" ], "element-timing/image-data-uri.html": [ @@ -434517,7 +434786,7 @@ "testharness" ], "element-timing/image-not-fully-visible.html": [ - "105bb55ebc0a3a64343cfb07a27d845e58e66bd8", + "ece7770467d1cdedd1ea7a0f19775676df756f42", "testharness" ], "element-timing/image-rect-iframe.html": [ @@ -434529,15 +434798,15 @@ "testharness" ], "element-timing/image-with-css-scale.html": [ - "5c15daabe13dda37ce58a9c056cb2884cf1bb584", + "2dbbc0672485cb5e36ccec07f8ce9ccfbac012f0", "testharness" ], "element-timing/image-with-rotation.html": [ - "c545becd19ba960c241ef6d82c998ea9d9dda87e", + "fcffe4acfa587fc1b23b5bc123b25e6595c7e284", "testharness" ], "element-timing/images-repeated-resource.html": [ - "a6ad7acefcbef2891d50b6993457a2026b12f604", + "e3fe9b90db111f7238bf242601eb1e19ced075de", "testharness" ], "element-timing/invisible-images.html": [ @@ -434545,11 +434814,11 @@ "testharness" ], "element-timing/multiple-background-images.html": [ - "626287bf0d44078d4c4cdb0b87baf1efa79260c9", + "b29e66c04a70dffbc17f05f516d3d190159ec1c5", "testharness" ], "element-timing/observe-background-image.html": [ - "c642264a19a89bfa02df83cadd2b5cd2c428d0ce", + "afc6b5b38d74ca3da65a48737b1de4a534dfbb25", "testharness" ], "element-timing/observe-child-element.html": [ @@ -434557,11 +434826,15 @@ "testharness" ], "element-timing/observe-elementtiming.html": [ - "0c67130dcc356ee7da9b3e2e10127352af7d169e", + "164cc4f580afd46ce8a2c5425db7f72841eba441", + "testharness" + ], + "element-timing/observe-empty-attribute.html": [ + "c115a24cf6234b764c34a885c380e6ba5a6cca13", "testharness" ], "element-timing/observe-multiple-images.html": [ - "8a5fa0bb89a31f1bb1d1a277edb1b8102680a4bf", + "6b5c5d9e3cb2099774b48c79821335f346606ec8", "testharness" ], "element-timing/observe-shadow-image.html": [ @@ -434573,7 +434846,7 @@ "testharness" ], "element-timing/observe-svg-image.html": [ - "29fec392a993b793fe824e8a6f6c1a9867740f6c", + "8a0f61d6699d95cc8c450bd5d384405a53d9956b", "testharness" ], "element-timing/observe-text.html": [ @@ -434581,15 +434854,15 @@ "testharness" ], "element-timing/observe-video-poster.html": [ - "9f82478ea27779d7bb52dd9bc4966d5e5c09f6a3", + "a6348377099f29f784ad5f993626960baac7806f", "testharness" ], "element-timing/progressively-loaded-image.html": [ - "a55c5896f2acdcdcc9f9b416a689b9dbba5aef44", + "f156e1a32c4863aecf770c6f18e7bb88e8b694ee", "testharness" ], "element-timing/rectangular-image.html": [ - "0b44c4fdd9212374fc83d6a8c027673d91fcc3e0", + "0c09911c502351d93f58e25b8957cc70f4a521ab", "testharness" ], "element-timing/resources/TAOImage.py": [ @@ -444884,6 +445157,14 @@ "62633457d3f57135658fb4bdf959fce278dc9851", "testharness" ], + "html/cross-origin-opener-policy/popup-redirect-cache.https.html": [ + "519f710596005b5c460e03cfd398fafbb585ce40", + "testharness" + ], + "html/cross-origin-opener-policy/popup-redirect-cache.https.html.headers": [ + "46ad58d83bf6e98913ca4c564b7acb8f19fa0093", + "support" + ], "html/cross-origin-opener-policy/popup-same-origin-non-initial-about-blank.https.html": [ "65ec3b26aa0c6e7e5df857bde88f67d394af2e9e", "testharness" @@ -444945,7 +445226,7 @@ "support" ], "html/cross-origin-opener-policy/resources/coop-coep.py": [ - "8b12341be7356c58c41308e073131ad6c8c3fc35", + "8691e1b59d3134ef210259ed9501d123c002f88c", "support" ], "html/cross-origin-opener-policy/resources/postback.html": [ @@ -450265,7 +450546,7 @@ "testharness" ], "html/infrastructure/urls/resolving-urls/query-encoding/windows-1251-expected.txt": [ - "e0140d8677ded972714d3b09a6fb8ba4c3d22f01", + "2119566a9bb6a1f872c26bc4de1fc50677da6054", "support" ], "html/infrastructure/urls/resolving-urls/query-encoding/windows-1251.html": [ @@ -455865,7 +456146,7 @@ "testharness" ], "html/semantics/forms/textfieldselection/selection-not-application.html": [ - "04b4fdd4f7872d3416db35e57c5ab176ca2e87e5", + "d205ee838a819fc87fa09f616064e77e1ec36571", "testharness" ], "html/semantics/forms/textfieldselection/selection-start-end-extra.html": [ @@ -463653,7 +463934,7 @@ "support" ], "interfaces/media-capabilities.idl": [ - "ef4582d9c8c7c1d970cf399e9a9287dae8ba4fab", + "e067fdc746dd85161fb8e0e7e8f254a3d3d0f5f9", "support" ], "interfaces/media-playback-quality.idl": [ @@ -463713,11 +463994,11 @@ "support" ], "interfaces/paint-timing.idl": [ - "a8f065a3dea52974be6b6052604c43efb3f93ccd", + "0bfb422f88872004bf9b189188dff366a123405a", "support" ], "interfaces/payment-handler.idl": [ - "c87c855d439609adee24d2f49fc77879f9c8352b", + "aadaecc17346e8651c487b9e94e7cd0bf29bee64", "support" ], "interfaces/payment-method-basic-card.idl": [ @@ -463857,7 +464138,7 @@ "support" ], "interfaces/wake-lock.idl": [ - "5bccbe8f9b7cd6464e60343b64bea477c4069057", + "b66c415e6aad71764ca117af0a7fdbfd619d9fd2", "support" ], "interfaces/wasm-js-api.idl": [ @@ -463877,7 +464158,7 @@ "support" ], "interfaces/web-nfc.idl": [ - "5f0dd23a1cde61d4489e60ba82c48ccc74be67dd", + "b917d5e2c11c5b34344638e2d0a2c2526c76137b", "support" ], "interfaces/web-share.idl": [ @@ -464589,7 +464870,7 @@ "testharness" ], "lint.whitelist": [ - "afdc20b67b544ddc7a8ddee518e76f748e147def", + "4226727ec2a167db7853e170f997c1b3590650db", "support" ], "loading/lazyload/common.js": [ @@ -466160,18 +466441,10 @@ "08a3f7569a185215e42f97ca9e9a9803a92c5d7c", "testharness" ], - "media-capabilities/idlharness.any-expected.txt": [ - "d05f05f1255b9944f1d6525406992971659cd635", - "support" - ], "media-capabilities/idlharness.any.js": [ "6da5c7d2848c2dc8a669dfcf621233c40a227c03", "testharness" ], - "media-capabilities/idlharness.any.worker-expected.txt": [ - "df20335ffe471302f98570a7a3f21db42986222c", - "support" - ], "media-playback-quality/META.yml": [ "51b1b4e07ed2654d67d6e42083ed936e9d78848e", "support" @@ -466484,6 +466757,10 @@ "0388565329ff0d734785715a7b7d720c53b3feaa", "testharness" ], + "media-source/mediasource-replay.html": [ + "05a8c0a918ab94bc1d4303b85ef3500e3cea9ddb", + "testharness" + ], "media-source/mediasource-seek-beyond-duration.html": [ "8b07c9f80172c14bcda78e3bf5ba9a7a4be3006c", "testharness" @@ -476161,11 +476438,11 @@ "testharness" ], "offscreen-canvas/text/2d.text.font.parse.invalid.html": [ - "6ed7eb14fb578d250800eaf86479c4cb34ece3a1", + "79860234a56450396c530a901a5ce4691fcbedf4", "testharness" ], "offscreen-canvas/text/2d.text.font.parse.invalid.worker.js": [ - "9a407c0446f556514e574d1813a2141e3cfbfe4e", + "9be1a6d6a845ebe194e41e985646c52d7e676a15", "testharness" ], "offscreen-canvas/text/2d.text.font.parse.system.html": [ @@ -476869,7 +477146,7 @@ "support" ], "offscreen-canvas/tools/tests2d.yaml": [ - "4bdf32db6c1be5c6a53b8d7f38a1b662e623f6e8", + "6b1876d803f4e10e25d4f600372d77397d2d9bdb", "support" ], "offscreen-canvas/transformations/2d.transformation.order.html": [ @@ -477549,15 +477826,15 @@ "testharness" ], "payment-handler/idlharness.https.any.serviceworker-expected.txt": [ - "23a519dbab21341a16df1f520c63bf07fb57b56b", + "c4afc3cbdef256fe9cd6408a1bc62d1535f81ea5", "support" ], "payment-handler/idlharness.https.any.sharedworker-expected.txt": [ - "79279363b3789fde5725b0fe7124604bd986b98f", + "7ff997ec02b7eba54f24e9df856468a430679eec", "support" ], "payment-handler/idlharness.https.any.worker-expected.txt": [ - "79279363b3789fde5725b0fe7124604bd986b98f", + "7ff997ec02b7eba54f24e9df856468a430679eec", "support" ], "payment-handler/manifest.json": [ @@ -478725,7 +479002,7 @@ "testharness" ], "pointerlock/movementX_Y_no-jumps-manual.html": [ - "11b8d2a49e0a3b59b76174e652b55ef7d5bf939e", + "7667ece7538c6fd9408d213e219323caed910e0e", "manual" ], "pointerlock/pointerlock_basic-manual.html": [ @@ -492813,7 +493090,7 @@ "support" ], "resources/chromium/nfc-mock.js": [ - "6ef03b390d8df7df8abd7662e037db6bdf5febce", + "d279fcf40d82525ec8e7ee628d267c2168ed7cd7", "support" ], "resources/chromium/sensor.mojom.js": [ @@ -496557,7 +496834,7 @@ "support" ], "service-workers/service-worker/resources/test-helpers.sub.js": [ - "db7433dcdbdb25d5626725392828a7e0b76708da", + "bbd16abce4b3703a2f7499e7c2c4c7590566d33e", "support" ], "service-workers/service-worker/resources/test-request-headers-worker.js": [ @@ -497177,7 +497454,7 @@ "testharness" ], "shadow-dom/leaktests/html-collection.html": [ - "d156569714636d2bc713390748bfcf560a8d0dbe", + "2f3d49ec267b83c64d37641ce50b22c9b26aa0df", "testharness" ], "shadow-dom/leaktests/window-frames.html": [ @@ -500549,7 +500826,7 @@ "testharness" ], "svg/painting/parsing/image-rendering-computed-expected.txt": [ - "b860c7d4c3a9f62df32567fe58a61b11bbe34589", + "0b4bd4db8b1186cdfaa1b76f842581132db18938", "support" ], "svg/painting/parsing/image-rendering-computed.svg": [ @@ -501957,11 +502234,11 @@ "support" ], "tools/ci/azure/cleanup_win10.yml": [ - "4abb35369de019c458ca6a5bae4a865363336810", + "195cdee8edfb3bd8cd58ac2dc132b63bcb7d531a", "support" ], "tools/ci/azure/fyi_hook.yml": [ - "3d23da3bb7411fde847b3d3de8b95a1c33935eb9", + "f02f3cd8224e0b3eb4f478318f0437f5a475f4e5", "support" ], "tools/ci/azure/install_certs.yml": [ @@ -501973,7 +502250,7 @@ "support" ], "tools/ci/azure/install_edge.yml": [ - "a70dc78e01c7c32c2eb04ae63eff70e4c982dd98", + "e4c425ab7a0f03218d922e7310ea9d8fde0f51aa", "support" ], "tools/ci/azure/install_firefox.yml": [ @@ -502049,15 +502326,15 @@ "support" ], "tools/ci/run_tc.py": [ - "60f175808715e2d8adf173c3145dc06b7bea64c2", + "e6d8cd878aacc58f535be562a85ba511e18676f2", "support" ], "tools/ci/taskcluster-run.py": [ - "fbd2f2ab4ea0b27ffd1690d10d64f88937228d20", + "ad33cb532d2e82cc28a42d75e856709dc53fa22a", "support" ], "tools/ci/tcdownload.py": [ - "46e9005740d39d3a9fcd136f5aeb7effcc3087e6", + "6e4d960da900c670701807455bd67b247e37f34b", "support" ], "tools/ci/website_build.sh": [ @@ -510917,7 +511194,7 @@ "support" ], "url/resources/setters_tests.json": [ - "0b4f6b67387c22879b1f2a03ed4d5d3c1d440d26", + "6b7d19b10164a38901abc70345663a550d4ee737", "support" ], "url/resources/toascii.json": [ @@ -511349,7 +511626,7 @@ "support" ], "wake-lock/META.yml": [ - "7ca3da2d8d2e4c90c55074246589d5464aa7ae3e", + "0123ccef85511aaa86770c53716ef9264377b1c1", "support" ], "wake-lock/OWNERS": [ @@ -511357,15 +511634,15 @@ "support" ], "wake-lock/idlharness.https.any-expected.txt": [ - "af5b66fa23e90e5a40f046103b366b6984003574", + "2891448add546a4fc763a0082a097318614727f3", "support" ], "wake-lock/idlharness.https.any.js": [ - "31d20aed34ce3e148d6cf31aa515058d9cff475c", + "b5d764aee0d85e57b38ee5ff636d18e9c01c1dba", "testharness" ], "wake-lock/idlharness.https.any.worker-expected.txt": [ - "6c96a329cd5dbb0c1dd308d3f908fd5a3b986620", + "b90f5daa337f631eba356074cb211bed49a5efa2", "support" ], "wake-lock/resources/page1.html": [ @@ -512472,60 +512749,60 @@ "32c24570db165422a60a18b767c828dab10c5b9c", "support" ], + "web-nfc/NDEFErrorEvent_constructor.https.html": [ + "243893620c64a7d9fd0e71f506293dc5705716e7", + "testharness" + ], "web-nfc/NDEFMessage_constructor.https-expected.txt": [ "20fd42208617457dbf8f79ef1481254fdeb2b5bf", "support" ], "web-nfc/NDEFMessage_constructor.https.html": [ - "88c9ec4006e60c27a0c33f154a3f7f419f5ee2a3", - "testharness" - ], - "web-nfc/NDEFRecord_constructor.https.html": [ - "849a6ae336ea4026888e9835e89db64fd03eb555", - "testharness" - ], - "web-nfc/NDEFErrorEvent_constructor.https.html": [ - "1cc9ce160be46955a9b15485ee4c040605722961", + "0ba82240781300a934cbc0f2fa96abc6a5ff490c", "testharness" ], "web-nfc/NDEFReader-document-hidden-manual.https-expected.txt": [ - "9fba7c80883b5144c3a444df0b6bfb6fef0ebb64", + "e2f23777367848e025ae4ed06324985debadf654", "support" ], "web-nfc/NDEFReader-document-hidden-manual.https.html": [ - "6d9a52c1ecf5bfb2f9ac9876b0ff5988bcc285e0", + "868cf1a968be65cd28c3ba2f5022f686c3c43b26", "manual" ], "web-nfc/NDEFReader_options.https.html": [ - "5761747f907fad40873023f8ba746bef19fb08e7", + "b9015dc2a57afbd1f511c84f12ae5085be3b18a0", "testharness" ], "web-nfc/NDEFReader_scan.https.html": [ - "638d0c5a1d1b8d0e2e8e8422bd4b9e9488512e54", + "0a3610099486c6d61c4f9171a2d87950e75cd4e5", "testharness" ], "web-nfc/NDEFReader_scan_iframe.https.html": [ - "31e79b0388aa5f407a7c9a1b591f162b3e42001f", + "e9720e98ef65555cf39170ae4026329f257a226c", "testharness" ], "web-nfc/NDEFReadingEvent_constructor.https.html": [ - "20585176b7f89a129fad99f17d068b2deb828f68", + "c23a68a2f79e5527f5d2742c4729bce0d6178c19", + "testharness" + ], + "web-nfc/NDEFRecord_constructor.https.html": [ + "6a57616d126edf339fc7f3e077b8e427e3480c5e", "testharness" ], "web-nfc/NDEFWriter-document-hidden-manual.https-expected.txt": [ - "777243f850377f2f6a0ef99e452fed18cb9fc2d9", + "799e5509bc6b02cc0a1c37091a6c1d4b094023ef", "support" ], "web-nfc/NDEFWriter-document-hidden-manual.https.html": [ - "72d8c8143cd934ad3ff0f8e32968851a1769b0c3", + "2f291e51412f717001339c02db2fbf1bbd7a1ac6", "manual" ], "web-nfc/NDEFWriter_push.https-expected.txt": [ - "72884b7e143029113a014f4653c8f857bc8d0c77", + "ad892ff0d987175d73f6793ab2817179621fcddd", "support" ], "web-nfc/NDEFWriter_push.https.html": [ - "6b4034fccc2987c0366ccdfd58dd394a5111709b", + "b909bee3171dcfa56af951f2d4a351487bd9705e", "testharness" ], "web-nfc/OWNERS": [ @@ -512533,23 +512810,23 @@ "support" ], "web-nfc/README.md": [ - "dd072174e056ec01c00e98505980768fff24e4c4", + "87145b0e3ec0064457dfdcaa6bc6cd2595b88afb", "support" ], "web-nfc/idlharness.https.window-expected.txt": [ - "c55a3fe800baae2828e1ce57badd94e803617564", + "0322ac5f2cddbadb20dec0eef114f412776a4f1f", "support" ], "web-nfc/idlharness.https.window.js": [ - "869433d2ff5a6463f14193e3965c32eb66ab7dd1", + "f59ad9b512ed5548b22ff43b84f8404258e9e6c9", "testharness" ], "web-nfc/nfc_insecure_context.html": [ - "f883f0473b7c7a7b9b622cad5214ca529885b34e", + "9a8e58cf802fceb818fa93000cb5a3db75bddc14", "testharness" ], "web-nfc/resources/nfc-helpers.js": [ - "ed5cc9c9718d01580460535ea14405c2817c0986", + "4685f65090dbd4c8be36af38960267bd4e7f07a0", "support" ], "web-nfc/resources/support-iframe.html": [ @@ -512604,7 +512881,7 @@ "c3941bb4065b28c7f8fd4f615b8ec595ea5281a7", "manual" ], - "web-share/share-image-manual.https.html": [ + "web-share/share-image-manual.tentative.https.html": [ "48ea4c378c194691b78d1b365999408322345a37", "manual" ], @@ -513629,7 +513906,7 @@ "testharness" ], "webaudio/the-audio-api/the-waveshapernode-interface/curve-tests.html": [ - "81e64dc12e9c757b613ddd377c39ed313b3cea47", + "d09cf78fd84131326b2412fba96a2bf7be82b9b9", "testharness" ], "webaudio/the-audio-api/the-waveshapernode-interface/silent-inputs.html": [ @@ -514984,6 +515261,22 @@ "4b00e68d49ef9fc85e92a5526ff76bd92259d4d9", "testharness" ], + "webmessaging/Channel_postMessage_transfer_xsite_incoming_messages.window.js": [ + "23237ae1555e67dafcb170ce8fccab4c966f7a2e", + "testharness" + ], + "webmessaging/Channel_postMessage_with_transfer_entangled.any.js": [ + "2226b278440346290066e622fe6abbaab2b93bd2", + "testharness" + ], + "webmessaging/Channel_postMessage_with_transfer_incoming_messages.any.js": [ + "fe2e96220d34d88127dc596eee70d183f7debd18", + "testharness" + ], + "webmessaging/Channel_postMessage_with_transfer_outgoing_messages.any.js": [ + "aa80b7589cffa58da6f1d790e7cdbeb95642c6e3", + "testharness" + ], "webmessaging/META.yml": [ "95d5071171b5a20cc14a414c97c9eae2f525f43f", "support" @@ -515160,6 +515453,10 @@ "cf2b8eb4c11b0b824a47677079c2d1b8837b3802", "testharness" ], + "webmessaging/postMessage_MessagePorts_xsite.sub.window.js": [ + "ca1e510edaa09f41350426e143923bb15e6df82b", + "testharness" + ], "webmessaging/postMessage_arrays.sub.htm": [ "41e4a75eda616196ab3546943a0913785cbe69be", "testharness" @@ -515484,6 +515781,14 @@ "3b29d8963b28881b347e54afc0afa3ad051924bc", "support" ], + "webrtc-extensions/META.yml": [ + "4ceee0664cbfb800ac8b410c295dde4c7009b024", + "support" + ], + "webrtc-extensions/RTCRtpReceiver-playoutDelayHint.html": [ + "d8e47bda22174c63094c0918ccabed63513ea9fa", + "testharness" + ], "webrtc-identity/META.yml": [ "940144cee1da5f2f0f2bdd27a8dfc8f5bfcc6a1d", "support" @@ -515564,10 +515869,6 @@ "d98712fc485298a0455e44c9f29407dc232fca63", "testharness" ], - "webrtc-svc/RTCRtpParameters-scalability-expected.txt": [ - "a2af47a7dff510592453272a80397170dfdf55b6", - "support" - ], "webrtc-svc/RTCRtpParameters-scalability.html": [ "98a8b3da81f70c9539b55d6f51dbfa9fc5cf183b", "testharness"
diff --git a/third_party/blink/web_tests/external/wpt/2dcontext/text-styles/2d.text.font.parse.invalid.html b/third_party/blink/web_tests/external/wpt/2dcontext/text-styles/2d.text.font.parse.invalid.html index 0cb62e8..9149d4f 100644 --- a/third_party/blink/web_tests/external/wpt/2dcontext/text-styles/2d.text.font.parse.invalid.html +++ b/third_party/blink/web_tests/external/wpt/2dcontext/text-styles/2d.text.font.parse.invalid.html
@@ -23,6 +23,10 @@ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'"); ctx.font = '20px serif'; +ctx.font = ''; +_assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'"); + +ctx.font = '20px serif'; ctx.font = 'bogus'; _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
diff --git a/third_party/blink/web_tests/external/wpt/2dcontext/tools/tests2dtext.yaml b/third_party/blink/web_tests/external/wpt/2dcontext/tools/tests2dtext.yaml index c57caee..6d5f8f6 100644 --- a/third_party/blink/web_tests/external/wpt/2dcontext/tools/tests2dtext.yaml +++ b/third_party/blink/web_tests/external/wpt/2dcontext/tools/tests2dtext.yaml
@@ -79,6 +79,10 @@ @assert ctx.font === '20px serif'; ctx.font = '20px serif'; + ctx.font = ''; + @assert ctx.font === '20px serif'; + + ctx.font = '20px serif'; ctx.font = 'bogus'; @assert ctx.font === '20px serif';
diff --git a/third_party/blink/web_tests/external/wpt/README.md b/third_party/blink/web_tests/external/wpt/README.md index f728d502e..320176c 100644 --- a/third_party/blink/web_tests/external/wpt/README.md +++ b/third_party/blink/web_tests/external/wpt/README.md
@@ -251,27 +251,3 @@ pull request per above to fix it, please [file a new issue](https://github.com/web-platform-tests/wpt/issues/new). Thank you! - -Lint tool ---------- - -We have a lint tool for catching common mistakes in test files. You -can run it manually by starting the `lint` executable from the root of -your local web-platform-tests working directory like this: - -``` -./wpt lint -``` - -The lint tool is also run automatically for every submitted pull -request, and reviewers will not merge branches with tests that have -lint errors, so you must fix any errors the lint tool reports. - -In the unusual case of error reports for things essential to a -certain test or that for other exceptional reasons shouldn't prevent -a merge of a test, update and commit the `lint.whitelist` file in the -web-platform-tests root directory to suppress the error reports. - -For more details, see the [lint-tool documentation][lint-tool]. - -[lint-tool]: https://web-platform-tests.org/writing-tests/lint-tool.html
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/connect-src/connect-src-beacon-allowed.sub.html b/third_party/blink/web_tests/external/wpt/content-security-policy/connect-src/connect-src-beacon-allowed.sub.html index a32913d..de032a9 100644 --- a/third_party/blink/web_tests/external/wpt/content-security-policy/connect-src/connect-src-beacon-allowed.sub.html +++ b/third_party/blink/web_tests/external/wpt/content-security-policy/connect-src/connect-src-beacon-allowed.sub.html
@@ -19,19 +19,19 @@ window.addEventListener('securitypolicyviolation', function(e) { log("FAIL"); }); - - if (typeof navigator.sendBeacon != 'function') { + + if (typeof navigator.sendBeacon != 'function') { t_log.set_status(t_log.NOTRUN, "No navigator.sendBeacon, cannot run test."); t_log.phase = t_log.phases.HAS_RESULT; t_log.done(); } else { - try { - var es = navigator.sendBeacon("http://{{host}}:{{ports[http][0]}}/cors/resources/status.py"); - log("Pass"); - } catch (e) { - log("Fail"); - } - } + try { + var es = navigator.sendBeacon("http://{{host}}:{{ports[http][0]}}/cors/resources/status.py"); + log("Pass"); + } catch (e) { + log("Fail"); + } + } </script> <div id="log"></div> </body>
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/connect-src/connect-src-beacon-blocked.sub.html b/third_party/blink/web_tests/external/wpt/content-security-policy/connect-src/connect-src-beacon-blocked.sub.html index 95b4ce9a..025a7201 100644 --- a/third_party/blink/web_tests/external/wpt/content-security-policy/connect-src/connect-src-beacon-blocked.sub.html +++ b/third_party/blink/web_tests/external/wpt/content-security-policy/connect-src/connect-src-beacon-blocked.sub.html
@@ -3,7 +3,7 @@ <head> <!-- Programmatically converted from a WebKit Reftest, please forgive resulting idiosyncracies.--> - <meta http-equiv="Content-Security-Policy" content="connect-src 'self'; script-src 'self' 'unsafe-inline';"> + <meta http-equiv="Content-Security-Policy" content="connect-src 'self'; script-src 'self' 'unsafe-inline';"> <title>connect-src-beacon-blocked</title> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> @@ -16,22 +16,22 @@ <body> <script> - window.addEventListener('securitypolicyviolation', function(e) { + window.addEventListener('securitypolicyviolation', function(e) { log("violated-directive=" + e.violatedDirective); - }); - - if (typeof navigator.sendBeacon != 'function') { + }); + + if (typeof navigator.sendBeacon != 'function') { t_log.set_status(t_log.NOTRUN, "No navigator.sendBeacon, cannot run test."); t_log.phase = t_log.phases.HAS_RESULT; t_log.done(); - } else { - try { - var es = navigator.sendBeacon("http://www1.{{host}}:{{ports[http][0]}}/security/contentSecurityPolicy/echo-report.php"); - log("Pass"); - } catch (e) { - log("Fail"); - } - } + } else { + try { + var es = navigator.sendBeacon("http://www1.{{host}}:{{ports[http][0]}}/security/contentSecurityPolicy/echo-report.php"); + log("Pass"); + } catch (e) { + log("Fail"); + } + } </script> <div id="log"></div> </body>
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/connect-src/connect-src-beacon-redirect-to-blocked.sub.html b/third_party/blink/web_tests/external/wpt/content-security-policy/connect-src/connect-src-beacon-redirect-to-blocked.sub.html index 7328d7a..b0cbea5 100644 --- a/third_party/blink/web_tests/external/wpt/content-security-policy/connect-src/connect-src-beacon-redirect-to-blocked.sub.html +++ b/third_party/blink/web_tests/external/wpt/content-security-policy/connect-src/connect-src-beacon-redirect-to-blocked.sub.html
@@ -16,12 +16,12 @@ <p>The beacon should not follow the redirect to http://www1.{{host}}:{{ports[http][0]}}/content-security-policy/support/fail.png and send a CSP violation report.</p> <p>Verify that a CSP connect-src directive blocks redirects.</p> <script> - window.addEventListener('securitypolicyviolation', function(e) { + window.addEventListener('securitypolicyviolation', function(e) { log("violated-directive=" + e.violatedDirective); - }); - - if (typeof navigator.sendBeacon != 'function') { - t_log.set_status(t_log.NOTRUN, "No navigator.sendBeacon, cannot run test."); + }); + + if (typeof navigator.sendBeacon != 'function') { + t_log.set_status(t_log.NOTRUN, "No navigator.sendBeacon, cannot run test."); t_log.phase = t_log.phases.HAS_RESULT; t_log.done(); } else {
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-sandboxed-cross-url-block.html b/third_party/blink/web_tests/external/wpt/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-sandboxed-cross-url-block.html index 654e90e0..d7c83ae2 100644 --- a/third_party/blink/web_tests/external/wpt/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-sandboxed-cross-url-block.html +++ b/third_party/blink/web_tests/external/wpt/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-sandboxed-cross-url-block.html
@@ -8,9 +8,9 @@ <body> <script> test = async_test("A 'frame-ancestors' CSP directive with a URL value should compare against each frame's origin rather than URL, " + - "so a nested frame with a sandboxed parent frame should be blocked due to the parent having a unique origin."); + "so a nested frame with a sandboxed parent frame should be blocked due to the parent having a unique origin."); - testNestedSandboxedIFrame(SAMEORIGIN_ORIGIN + " " + CROSSORIGIN_ORIGIN, CROSS_ORIGIN, CROSS_ORIGIN, EXPECT_BLOCK); + testNestedSandboxedIFrame(SAMEORIGIN_ORIGIN + " " + CROSSORIGIN_ORIGIN, CROSS_ORIGIN, CROSS_ORIGIN, EXPECT_BLOCK); </script> </body> </html>
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/media-src/media-src-7_3_2.sub.html b/third_party/blink/web_tests/external/wpt/content-security-policy/media-src/media-src-7_3_2.sub.html index 6abe850..431a586 100644 --- a/third_party/blink/web_tests/external/wpt/content-security-policy/media-src/media-src-7_3_2.sub.html +++ b/third_party/blink/web_tests/external/wpt/content-security-policy/media-src/media-src-7_3_2.sub.html
@@ -15,14 +15,14 @@ async_test("Disallowed track element onerror handler fires."); var trackURL = location.protocol + "//{{domains[www]}}:{{ports[http][0]}}/media/foo.vtt"; - + var t_spv = async_test("Test that securitypolicyviolation events are fired"); var test_count = 1; window.addEventListener("securitypolicyviolation", t_spv.step_func(function(e) { assert_equals(e.violatedDirective, "media-src"); assert_equals(e.blockedURI, trackURL); if (--test_count <= 0) { - t_spv.done(); + t_spv.done(); } })); @@ -62,9 +62,9 @@ setTimeout(function() { if(source_test.phase != source_test.phases.COMPLETE) { - source_test.step( function () { assert_unreached("Onerror event never fired for track element."); }); - source_test.done(); - } + source_test.step( function () { assert_unreached("Onerror event never fired for track element."); }); + source_test.done(); + } }, 2 * 1000); </script>
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/reporting/report-cross-origin-no-cookies.sub.html b/third_party/blink/web_tests/external/wpt/content-security-policy/reporting/report-cross-origin-no-cookies.sub.html index 98d85b6..a034bdb 100644 --- a/third_party/blink/web_tests/external/wpt/content-security-policy/reporting/report-cross-origin-no-cookies.sub.html +++ b/third_party/blink/web_tests/external/wpt/content-security-policy/reporting/report-cross-origin-no-cookies.sub.html
@@ -12,7 +12,7 @@ <body> <script> promise_test(function(test) { - const path = encodeURIComponent("{{domains[www1]}}:{{ports[http][0]}}/"); + const path = encodeURIComponent("{{domains[www1]}}:{{ports[http][0]}}/"); return fetch( "/cookies/resources/set-cookie.py?name=cspViolationReportCookie1&path=" + path, {mode: 'no-cors', credentials: 'include'})
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/script-src/scripthash-unicode-normalization.sub.html b/third_party/blink/web_tests/external/wpt/content-security-policy/script-src/scripthash-unicode-normalization.sub.html index 4212297..b082b55 100644 --- a/third_party/blink/web_tests/external/wpt/content-security-policy/script-src/scripthash-unicode-normalization.sub.html +++ b/third_party/blink/web_tests/external/wpt/content-security-policy/script-src/scripthash-unicode-normalization.sub.html
@@ -49,9 +49,9 @@ script1.test.done(); }); } else { - script1.test.step(function() { + script1.test.step(function() { assert_unreached("nonMatchingContent script ran"); - }); + }); } }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-image-source-interpolation-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-image-source-interpolation-expected.txt index 241feb7a..f11069c9 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-image-source-interpolation-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-image-source-interpolation-expected.txt
@@ -1,200 +1,200 @@ This is a testharness.js-based test. Found 196 tests; 132 PASS, 64 FAIL, 0 TIMEOUT, 0 NOTRUN. -PASS CSS Transitions: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (-0.3) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (0) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (0.3) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (0.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (0.6) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (1) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (1.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions with transition: all: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (-0.3) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions with transition: all: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (0) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions with transition: all: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (0.3) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions with transition: all: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (0.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions with transition: all: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (0.6) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions with transition: all: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (1) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions with transition: all: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (1.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Animations: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (-0.3) should be [none] -PASS CSS Animations: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (0) should be [none] -PASS CSS Animations: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (0.3) should be [none] -PASS CSS Animations: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (0.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Animations: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (0.6) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Animations: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (1) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Animations: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (1.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS Web Animations: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (-0.3) should be [none] -PASS Web Animations: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (0) should be [none] -PASS Web Animations: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (0.3) should be [none] -PASS Web Animations: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (0.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS Web Animations: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (0.6) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS Web Animations: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (1) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS Web Animations: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (1.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] -FAIL CSS Transitions: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (-0.3) should be [url(http://web-platform.test:8001/.../orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "url ( http : / / web - platform.test : 8001 / ... / green.png ) " -FAIL CSS Transitions: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (0) should be [url(http://web-platform.test:8001/.../orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "url ( http : / / web - platform.test : 8001 / ... / green.png ) " -FAIL CSS Transitions: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (0.3) should be [url(http://web-platform.test:8001/.../orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / green.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.3 ) " -FAIL CSS Transitions: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (0.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / green.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.5 ) " -FAIL CSS Transitions: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (0.6) should be [url(http://web-platform.test:8001/.../orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / green.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.6 ) " -PASS CSS Transitions: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (1) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (1.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] -FAIL CSS Transitions with transition: all: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (-0.3) should be [url(http://web-platform.test:8001/.../orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "url ( http : / / web - platform.test : 8001 / ... / green.png ) " -FAIL CSS Transitions with transition: all: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (0) should be [url(http://web-platform.test:8001/.../orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "url ( http : / / web - platform.test : 8001 / ... / green.png ) " -FAIL CSS Transitions with transition: all: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (0.3) should be [url(http://web-platform.test:8001/.../orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / green.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.3 ) " -FAIL CSS Transitions with transition: all: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (0.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / green.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.5 ) " -FAIL CSS Transitions with transition: all: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (0.6) should be [url(http://web-platform.test:8001/.../orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / green.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.6 ) " -PASS CSS Transitions with transition: all: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (1) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions with transition: all: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (1.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Animations: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (-0.3) should be [url(http://web-platform.test:8001/.../green.png)] -PASS CSS Animations: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (0) should be [url(http://web-platform.test:8001/.../green.png)] -FAIL CSS Animations: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (0.3) should be [url(http://web-platform.test:8001/.../green.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / green.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / green.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.3 ) " -FAIL CSS Animations: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (0.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / green.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.5 ) " -FAIL CSS Animations: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (0.6) should be [url(http://web-platform.test:8001/.../orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / green.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.6 ) " -PASS CSS Animations: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (1) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Animations: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (1.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS Web Animations: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (-0.3) should be [url(http://web-platform.test:8001/.../green.png)] -PASS Web Animations: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (0) should be [url(http://web-platform.test:8001/.../green.png)] -FAIL Web Animations: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (0.3) should be [url(http://web-platform.test:8001/.../green.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / green.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / green.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.3 ) " -FAIL Web Animations: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (0.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / green.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.5 ) " -FAIL Web Animations: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (0.6) should be [url(http://web-platform.test:8001/.../orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / green.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.6 ) " -PASS Web Animations: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (1) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS Web Animations: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (1.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (-0.3) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (0) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (0.3) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (0.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (0.6) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (1) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (1.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions with transition: all: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (-0.3) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions with transition: all: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (0) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions with transition: all: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (0.3) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions with transition: all: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (0.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions with transition: all: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (0.6) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions with transition: all: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (1) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions with transition: all: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (1.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Animations: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (-0.3) should be [none] -PASS CSS Animations: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (0) should be [none] -PASS CSS Animations: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (0.3) should be [none] -PASS CSS Animations: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (0.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Animations: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (0.6) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Animations: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (1) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Animations: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (1.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS Web Animations: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (-0.3) should be [none] -PASS Web Animations: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (0) should be [none] -PASS Web Animations: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (0.3) should be [none] -PASS Web Animations: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (0.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS Web Animations: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (0.6) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS Web Animations: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (1) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS Web Animations: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (1.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (-0.3) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (0) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (0.3) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (0.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (0.6) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (1) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (1.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions with transition: all: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (-0.3) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions with transition: all: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (0) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions with transition: all: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (0.3) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions with transition: all: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (0.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions with transition: all: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (0.6) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions with transition: all: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (1) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions with transition: all: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (1.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] +PASS CSS Transitions: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (-0.3) should be [url(../support/orange_color.png)] +PASS CSS Transitions: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (0) should be [url(../support/orange_color.png)] +PASS CSS Transitions: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (0.3) should be [url(../support/orange_color.png)] +PASS CSS Transitions: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (0.5) should be [url(../support/orange_color.png)] +PASS CSS Transitions: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (0.6) should be [url(../support/orange_color.png)] +PASS CSS Transitions: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (1) should be [url(../support/orange_color.png)] +PASS CSS Transitions: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (1.5) should be [url(../support/orange_color.png)] +PASS CSS Transitions with transition: all: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (-0.3) should be [url(../support/orange_color.png)] +PASS CSS Transitions with transition: all: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (0) should be [url(../support/orange_color.png)] +PASS CSS Transitions with transition: all: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (0.3) should be [url(../support/orange_color.png)] +PASS CSS Transitions with transition: all: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (0.5) should be [url(../support/orange_color.png)] +PASS CSS Transitions with transition: all: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (0.6) should be [url(../support/orange_color.png)] +PASS CSS Transitions with transition: all: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (1) should be [url(../support/orange_color.png)] +PASS CSS Transitions with transition: all: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (1.5) should be [url(../support/orange_color.png)] +PASS CSS Animations: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (-0.3) should be [initial] +PASS CSS Animations: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (0) should be [initial] +PASS CSS Animations: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (0.3) should be [initial] +PASS CSS Animations: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (0.5) should be [url(../support/orange_color.png)] +PASS CSS Animations: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (0.6) should be [url(../support/orange_color.png)] +PASS CSS Animations: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (1) should be [url(../support/orange_color.png)] +PASS CSS Animations: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (1.5) should be [url(../support/orange_color.png)] +PASS Web Animations: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (-0.3) should be [initial] +PASS Web Animations: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (0) should be [initial] +PASS Web Animations: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (0.3) should be [initial] +PASS Web Animations: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (0.5) should be [url(../support/orange_color.png)] +PASS Web Animations: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (0.6) should be [url(../support/orange_color.png)] +PASS Web Animations: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (1) should be [url(../support/orange_color.png)] +PASS Web Animations: property <border-image-source> from [initial] to [url(../support/orange_color.png)] at (1.5) should be [url(../support/orange_color.png)] +FAIL CSS Transitions: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (-0.3) should be [url(../support/orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "url ( http : / / web - platform.test : 8001 / ... / green.png ) " +FAIL CSS Transitions: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (0) should be [url(../support/orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "url ( http : / / web - platform.test : 8001 / ... / green.png ) " +FAIL CSS Transitions: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (0.3) should be [url(../support/orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / green.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.3 ) " +FAIL CSS Transitions: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (0.5) should be [url(../support/orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / green.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.5 ) " +FAIL CSS Transitions: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (0.6) should be [url(../support/orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / green.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.6 ) " +PASS CSS Transitions: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (1) should be [url(../support/orange_color.png)] +PASS CSS Transitions: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (1.5) should be [url(../support/orange_color.png)] +FAIL CSS Transitions with transition: all: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (-0.3) should be [url(../support/orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "url ( http : / / web - platform.test : 8001 / ... / green.png ) " +FAIL CSS Transitions with transition: all: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (0) should be [url(../support/orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "url ( http : / / web - platform.test : 8001 / ... / green.png ) " +FAIL CSS Transitions with transition: all: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (0.3) should be [url(../support/orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / green.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.3 ) " +FAIL CSS Transitions with transition: all: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (0.5) should be [url(../support/orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / green.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.5 ) " +FAIL CSS Transitions with transition: all: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (0.6) should be [url(../support/orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / green.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.6 ) " +PASS CSS Transitions with transition: all: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (1) should be [url(../support/orange_color.png)] +PASS CSS Transitions with transition: all: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (1.5) should be [url(../support/orange_color.png)] +PASS CSS Animations: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (-0.3) should be [inherit] +PASS CSS Animations: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (0) should be [inherit] +FAIL CSS Animations: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (0.3) should be [inherit] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / green.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / green.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.3 ) " +FAIL CSS Animations: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (0.5) should be [url(../support/orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / green.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.5 ) " +FAIL CSS Animations: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (0.6) should be [url(../support/orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / green.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.6 ) " +PASS CSS Animations: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (1) should be [url(../support/orange_color.png)] +PASS CSS Animations: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (1.5) should be [url(../support/orange_color.png)] +PASS Web Animations: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (-0.3) should be [inherit] +PASS Web Animations: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (0) should be [inherit] +FAIL Web Animations: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (0.3) should be [inherit] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / green.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / green.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.3 ) " +FAIL Web Animations: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (0.5) should be [url(../support/orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / green.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.5 ) " +FAIL Web Animations: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (0.6) should be [url(../support/orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / green.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.6 ) " +PASS Web Animations: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (1) should be [url(../support/orange_color.png)] +PASS Web Animations: property <border-image-source> from [inherit] to [url(../support/orange_color.png)] at (1.5) should be [url(../support/orange_color.png)] +PASS CSS Transitions: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (-0.3) should be [url(../support/orange_color.png)] +PASS CSS Transitions: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (0) should be [url(../support/orange_color.png)] +PASS CSS Transitions: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (0.3) should be [url(../support/orange_color.png)] +PASS CSS Transitions: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (0.5) should be [url(../support/orange_color.png)] +PASS CSS Transitions: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (0.6) should be [url(../support/orange_color.png)] +PASS CSS Transitions: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (1) should be [url(../support/orange_color.png)] +PASS CSS Transitions: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (1.5) should be [url(../support/orange_color.png)] +PASS CSS Transitions with transition: all: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (-0.3) should be [url(../support/orange_color.png)] +PASS CSS Transitions with transition: all: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (0) should be [url(../support/orange_color.png)] +PASS CSS Transitions with transition: all: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (0.3) should be [url(../support/orange_color.png)] +PASS CSS Transitions with transition: all: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (0.5) should be [url(../support/orange_color.png)] +PASS CSS Transitions with transition: all: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (0.6) should be [url(../support/orange_color.png)] +PASS CSS Transitions with transition: all: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (1) should be [url(../support/orange_color.png)] +PASS CSS Transitions with transition: all: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (1.5) should be [url(../support/orange_color.png)] +PASS CSS Animations: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (-0.3) should be [unset] +PASS CSS Animations: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (0) should be [unset] +PASS CSS Animations: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (0.3) should be [unset] +PASS CSS Animations: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (0.5) should be [url(../support/orange_color.png)] +PASS CSS Animations: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (0.6) should be [url(../support/orange_color.png)] +PASS CSS Animations: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (1) should be [url(../support/orange_color.png)] +PASS CSS Animations: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (1.5) should be [url(../support/orange_color.png)] +PASS Web Animations: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (-0.3) should be [unset] +PASS Web Animations: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (0) should be [unset] +PASS Web Animations: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (0.3) should be [unset] +PASS Web Animations: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (0.5) should be [url(../support/orange_color.png)] +PASS Web Animations: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (0.6) should be [url(../support/orange_color.png)] +PASS Web Animations: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (1) should be [url(../support/orange_color.png)] +PASS Web Animations: property <border-image-source> from [unset] to [url(../support/orange_color.png)] at (1.5) should be [url(../support/orange_color.png)] +PASS CSS Transitions: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (-0.3) should be [url(../support/orange_color.png)] +PASS CSS Transitions: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (0) should be [url(../support/orange_color.png)] +PASS CSS Transitions: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (0.3) should be [url(../support/orange_color.png)] +PASS CSS Transitions: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (0.5) should be [url(../support/orange_color.png)] +PASS CSS Transitions: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (0.6) should be [url(../support/orange_color.png)] +PASS CSS Transitions: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (1) should be [url(../support/orange_color.png)] +PASS CSS Transitions: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (1.5) should be [url(../support/orange_color.png)] +PASS CSS Transitions with transition: all: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (-0.3) should be [url(../support/orange_color.png)] +PASS CSS Transitions with transition: all: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (0) should be [url(../support/orange_color.png)] +PASS CSS Transitions with transition: all: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (0.3) should be [url(../support/orange_color.png)] +PASS CSS Transitions with transition: all: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (0.5) should be [url(../support/orange_color.png)] +PASS CSS Transitions with transition: all: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (0.6) should be [url(../support/orange_color.png)] +PASS CSS Transitions with transition: all: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (1) should be [url(../support/orange_color.png)] +PASS CSS Transitions with transition: all: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (1.5) should be [url(../support/orange_color.png)] PASS CSS Animations: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (-0.3) should be [none] PASS CSS Animations: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (0) should be [none] PASS CSS Animations: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (0.3) should be [none] -PASS CSS Animations: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (0.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Animations: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (0.6) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Animations: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (1) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Animations: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (1.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] +PASS CSS Animations: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (0.5) should be [url(../support/orange_color.png)] +PASS CSS Animations: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (0.6) should be [url(../support/orange_color.png)] +PASS CSS Animations: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (1) should be [url(../support/orange_color.png)] +PASS CSS Animations: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (1.5) should be [url(../support/orange_color.png)] PASS Web Animations: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (-0.3) should be [none] PASS Web Animations: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (0) should be [none] PASS Web Animations: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (0.3) should be [none] -PASS Web Animations: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (0.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS Web Animations: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (0.6) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS Web Animations: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (1) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS Web Animations: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (1.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] -FAIL CSS Transitions: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (-0.3) should be [url(http://web-platform.test:8001/.../orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) " -FAIL CSS Transitions: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (0) should be [url(http://web-platform.test:8001/.../orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) " -FAIL CSS Transitions: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (0.3) should be [url(http://web-platform.test:8001/.../orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.3 ) " -FAIL CSS Transitions: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (0.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.5 ) " -FAIL CSS Transitions: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (0.6) should be [url(http://web-platform.test:8001/.../orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.6 ) " -PASS CSS Transitions: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (1) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (1.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] -FAIL CSS Transitions with transition: all: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (-0.3) should be [url(http://web-platform.test:8001/.../orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) " -FAIL CSS Transitions with transition: all: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (0) should be [url(http://web-platform.test:8001/.../orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) " -FAIL CSS Transitions with transition: all: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (0.3) should be [url(http://web-platform.test:8001/.../orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.3 ) " -FAIL CSS Transitions with transition: all: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (0.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.5 ) " -FAIL CSS Transitions with transition: all: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (0.6) should be [url(http://web-platform.test:8001/.../orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.6 ) " -PASS CSS Transitions with transition: all: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (1) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Transitions with transition: all: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (1.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (-0.3) should be [url(http://web-platform.test:8001/.../aqua_color.png)] -PASS CSS Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (0) should be [url(http://web-platform.test:8001/.../aqua_color.png)] -FAIL CSS Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (0.3) should be [url(http://web-platform.test:8001/.../aqua_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.3 ) " -FAIL CSS Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (0.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.5 ) " -FAIL CSS Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (0.6) should be [url(http://web-platform.test:8001/.../orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.6 ) " -PASS CSS Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (1) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS CSS Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (1.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS Web Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (-0.3) should be [url(http://web-platform.test:8001/.../aqua_color.png)] -PASS Web Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (0) should be [url(http://web-platform.test:8001/.../aqua_color.png)] -FAIL Web Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (0.3) should be [url(http://web-platform.test:8001/.../aqua_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.3 ) " -FAIL Web Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (0.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.5 ) " -FAIL Web Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (0.6) should be [url(http://web-platform.test:8001/.../orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.6 ) " -PASS Web Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (1) should be [url(http://web-platform.test:8001/.../orange_color.png)] -PASS Web Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (1.5) should be [url(http://web-platform.test:8001/.../orange_color.png)] -FAIL CSS Transitions: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (-0.3) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) " -FAIL CSS Transitions: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (0) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) " -FAIL CSS Transitions: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (0.3) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.3 ) " -FAIL CSS Transitions: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (0.5) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.5 ) " -FAIL CSS Transitions: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (0.6) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.6 ) " -PASS CSS Transitions: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (1) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] -PASS CSS Transitions: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (1.5) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] -FAIL CSS Transitions with transition: all: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (-0.3) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) " -FAIL CSS Transitions with transition: all: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (0) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) " -FAIL CSS Transitions with transition: all: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (0.3) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.3 ) " -FAIL CSS Transitions with transition: all: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (0.5) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.5 ) " -FAIL CSS Transitions with transition: all: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (0.6) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.6 ) " -PASS CSS Transitions with transition: all: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (1) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] -PASS CSS Transitions with transition: all: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (1.5) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] -PASS CSS Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (-0.3) should be [url(http://web-platform.test:8001/.../aqua_color.png)] -PASS CSS Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (0) should be [url(http://web-platform.test:8001/.../aqua_color.png)] -FAIL CSS Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (0.3) should be [url(http://web-platform.test:8001/.../aqua_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.3 ) " -FAIL CSS Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (0.5) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.5 ) " -FAIL CSS Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (0.6) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.6 ) " -PASS CSS Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (1) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] -PASS CSS Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (1.5) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] -PASS Web Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (-0.3) should be [url(http://web-platform.test:8001/.../aqua_color.png)] -PASS Web Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (0) should be [url(http://web-platform.test:8001/.../aqua_color.png)] -FAIL Web Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (0.3) should be [url(http://web-platform.test:8001/.../aqua_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.3 ) " -FAIL Web Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (0.5) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.5 ) " -FAIL Web Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (0.6) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.6 ) " -PASS Web Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (1) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] -PASS Web Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (1.5) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] -FAIL CSS Transitions: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (-0.3) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) " -FAIL CSS Transitions: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (0) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) " -FAIL CSS Transitions: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (0.3) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.3 ) " -FAIL CSS Transitions: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (0.5) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.5 ) " -FAIL CSS Transitions: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (0.6) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.6 ) " -PASS CSS Transitions: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (1) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] -PASS CSS Transitions: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (1.5) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] -FAIL CSS Transitions with transition: all: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (-0.3) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) " -FAIL CSS Transitions with transition: all: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (0) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) " -FAIL CSS Transitions with transition: all: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (0.3) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.3 ) " -FAIL CSS Transitions with transition: all: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (0.5) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.5 ) " -FAIL CSS Transitions with transition: all: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (0.6) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.6 ) " -PASS CSS Transitions with transition: all: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (1) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] -PASS CSS Transitions with transition: all: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (1.5) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] -PASS CSS Animations: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (-0.3) should be [linear-gradient(-45deg, rgb(255, 0, 0), rgb(255, 255, 0))] -PASS CSS Animations: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (0) should be [linear-gradient(-45deg, rgb(255, 0, 0), rgb(255, 255, 0))] -FAIL CSS Animations: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (0.3) should be [linear-gradient(-45deg, rgb(255, 0, 0), rgb(255, 255, 0))] assert_equals: expected "linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) " but got "- webkit - cross - fade ( linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.3 ) " -FAIL CSS Animations: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (0.5) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.5 ) " -FAIL CSS Animations: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (0.6) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.6 ) " -PASS CSS Animations: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (1) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] -PASS CSS Animations: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (1.5) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] -PASS Web Animations: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (-0.3) should be [linear-gradient(-45deg, rgb(255, 0, 0), rgb(255, 255, 0))] -PASS Web Animations: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (0) should be [linear-gradient(-45deg, rgb(255, 0, 0), rgb(255, 255, 0))] -FAIL Web Animations: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (0.3) should be [linear-gradient(-45deg, rgb(255, 0, 0), rgb(255, 255, 0))] assert_equals: expected "linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) " but got "- webkit - cross - fade ( linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.3 ) " -FAIL Web Animations: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (0.5) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.5 ) " -FAIL Web Animations: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (0.6) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.6 ) " -PASS Web Animations: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (1) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] -PASS Web Animations: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (1.5) should be [linear-gradient(45deg, rgb(0, 0, 255), rgb(255, 165, 0))] +PASS Web Animations: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (0.5) should be [url(../support/orange_color.png)] +PASS Web Animations: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (0.6) should be [url(../support/orange_color.png)] +PASS Web Animations: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (1) should be [url(../support/orange_color.png)] +PASS Web Animations: property <border-image-source> from [none] to [url(../support/orange_color.png)] at (1.5) should be [url(../support/orange_color.png)] +FAIL CSS Transitions: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (-0.3) should be [url(../support/orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) " +FAIL CSS Transitions: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (0) should be [url(../support/orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) " +FAIL CSS Transitions: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (0.3) should be [url(../support/orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.3 ) " +FAIL CSS Transitions: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (0.5) should be [url(../support/orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.5 ) " +FAIL CSS Transitions: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (0.6) should be [url(../support/orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.6 ) " +PASS CSS Transitions: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (1) should be [url(../support/orange_color.png)] +PASS CSS Transitions: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (1.5) should be [url(../support/orange_color.png)] +FAIL CSS Transitions with transition: all: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (-0.3) should be [url(../support/orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) " +FAIL CSS Transitions with transition: all: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (0) should be [url(../support/orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) " +FAIL CSS Transitions with transition: all: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (0.3) should be [url(../support/orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.3 ) " +FAIL CSS Transitions with transition: all: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (0.5) should be [url(../support/orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.5 ) " +FAIL CSS Transitions with transition: all: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (0.6) should be [url(../support/orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.6 ) " +PASS CSS Transitions with transition: all: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (1) should be [url(../support/orange_color.png)] +PASS CSS Transitions with transition: all: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (1.5) should be [url(../support/orange_color.png)] +PASS CSS Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (-0.3) should be [url(../support/aqua_color.png)] +PASS CSS Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (0) should be [url(../support/aqua_color.png)] +FAIL CSS Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (0.3) should be [url(../support/aqua_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.3 ) " +FAIL CSS Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (0.5) should be [url(../support/orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.5 ) " +FAIL CSS Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (0.6) should be [url(../support/orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.6 ) " +PASS CSS Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (1) should be [url(../support/orange_color.png)] +PASS CSS Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (1.5) should be [url(../support/orange_color.png)] +PASS Web Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (-0.3) should be [url(../support/aqua_color.png)] +PASS Web Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (0) should be [url(../support/aqua_color.png)] +FAIL Web Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (0.3) should be [url(../support/aqua_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.3 ) " +FAIL Web Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (0.5) should be [url(../support/orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.5 ) " +FAIL Web Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (0.6) should be [url(../support/orange_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , url ( http : / / web - platform.test : 8001 / ... / orange_color.png ) , 0.6 ) " +PASS Web Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (1) should be [url(../support/orange_color.png)] +PASS Web Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [url(../support/orange_color.png)] at (1.5) should be [url(../support/orange_color.png)] +FAIL CSS Transitions: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (-0.3) should be [linear-gradient(45deg, blue, orange)] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) " +FAIL CSS Transitions: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (0) should be [linear-gradient(45deg, blue, orange)] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) " +FAIL CSS Transitions: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (0.3) should be [linear-gradient(45deg, blue, orange)] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.3 ) " +FAIL CSS Transitions: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (0.5) should be [linear-gradient(45deg, blue, orange)] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.5 ) " +FAIL CSS Transitions: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (0.6) should be [linear-gradient(45deg, blue, orange)] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.6 ) " +PASS CSS Transitions: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (1) should be [linear-gradient(45deg, blue, orange)] +PASS CSS Transitions: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (1.5) should be [linear-gradient(45deg, blue, orange)] +FAIL CSS Transitions with transition: all: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (-0.3) should be [linear-gradient(45deg, blue, orange)] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) " +FAIL CSS Transitions with transition: all: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (0) should be [linear-gradient(45deg, blue, orange)] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) " +FAIL CSS Transitions with transition: all: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (0.3) should be [linear-gradient(45deg, blue, orange)] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.3 ) " +FAIL CSS Transitions with transition: all: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (0.5) should be [linear-gradient(45deg, blue, orange)] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.5 ) " +FAIL CSS Transitions with transition: all: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (0.6) should be [linear-gradient(45deg, blue, orange)] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.6 ) " +PASS CSS Transitions with transition: all: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (1) should be [linear-gradient(45deg, blue, orange)] +PASS CSS Transitions with transition: all: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (1.5) should be [linear-gradient(45deg, blue, orange)] +PASS CSS Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (-0.3) should be [url(../support/aqua_color.png)] +PASS CSS Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (0) should be [url(../support/aqua_color.png)] +FAIL CSS Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (0.3) should be [url(../support/aqua_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.3 ) " +FAIL CSS Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (0.5) should be [linear-gradient(45deg, blue, orange)] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.5 ) " +FAIL CSS Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (0.6) should be [linear-gradient(45deg, blue, orange)] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.6 ) " +PASS CSS Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (1) should be [linear-gradient(45deg, blue, orange)] +PASS CSS Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (1.5) should be [linear-gradient(45deg, blue, orange)] +PASS Web Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (-0.3) should be [url(../support/aqua_color.png)] +PASS Web Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (0) should be [url(../support/aqua_color.png)] +FAIL Web Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (0.3) should be [url(../support/aqua_color.png)] assert_equals: expected "url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.3 ) " +FAIL Web Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (0.5) should be [linear-gradient(45deg, blue, orange)] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.5 ) " +FAIL Web Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (0.6) should be [linear-gradient(45deg, blue, orange)] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( url ( http : / / web - platform.test : 8001 / ... / aqua_color.png ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.6 ) " +PASS Web Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (1) should be [linear-gradient(45deg, blue, orange)] +PASS Web Animations: property <border-image-source> from [url(../support/aqua_color.png)] to [linear-gradient(45deg, blue, orange)] at (1.5) should be [linear-gradient(45deg, blue, orange)] +FAIL CSS Transitions: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (-0.3) should be [linear-gradient(45deg, blue, orange)] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) " +FAIL CSS Transitions: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (0) should be [linear-gradient(45deg, blue, orange)] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) " +FAIL CSS Transitions: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (0.3) should be [linear-gradient(45deg, blue, orange)] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.3 ) " +FAIL CSS Transitions: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (0.5) should be [linear-gradient(45deg, blue, orange)] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.5 ) " +FAIL CSS Transitions: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (0.6) should be [linear-gradient(45deg, blue, orange)] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.6 ) " +PASS CSS Transitions: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (1) should be [linear-gradient(45deg, blue, orange)] +PASS CSS Transitions: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (1.5) should be [linear-gradient(45deg, blue, orange)] +FAIL CSS Transitions with transition: all: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (-0.3) should be [linear-gradient(45deg, blue, orange)] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) " +FAIL CSS Transitions with transition: all: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (0) should be [linear-gradient(45deg, blue, orange)] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) " +FAIL CSS Transitions with transition: all: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (0.3) should be [linear-gradient(45deg, blue, orange)] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.3 ) " +FAIL CSS Transitions with transition: all: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (0.5) should be [linear-gradient(45deg, blue, orange)] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.5 ) " +FAIL CSS Transitions with transition: all: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (0.6) should be [linear-gradient(45deg, blue, orange)] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.6 ) " +PASS CSS Transitions with transition: all: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (1) should be [linear-gradient(45deg, blue, orange)] +PASS CSS Transitions with transition: all: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (1.5) should be [linear-gradient(45deg, blue, orange)] +PASS CSS Animations: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (-0.3) should be [linear-gradient(-45deg, red, yellow)] +PASS CSS Animations: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (0) should be [linear-gradient(-45deg, red, yellow)] +FAIL CSS Animations: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (0.3) should be [linear-gradient(-45deg, red, yellow)] assert_equals: expected "linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) " but got "- webkit - cross - fade ( linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.3 ) " +FAIL CSS Animations: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (0.5) should be [linear-gradient(45deg, blue, orange)] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.5 ) " +FAIL CSS Animations: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (0.6) should be [linear-gradient(45deg, blue, orange)] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.6 ) " +PASS CSS Animations: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (1) should be [linear-gradient(45deg, blue, orange)] +PASS CSS Animations: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (1.5) should be [linear-gradient(45deg, blue, orange)] +PASS Web Animations: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (-0.3) should be [linear-gradient(-45deg, red, yellow)] +PASS Web Animations: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (0) should be [linear-gradient(-45deg, red, yellow)] +FAIL Web Animations: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (0.3) should be [linear-gradient(-45deg, red, yellow)] assert_equals: expected "linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) " but got "- webkit - cross - fade ( linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.3 ) " +FAIL Web Animations: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (0.5) should be [linear-gradient(45deg, blue, orange)] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.5 ) " +FAIL Web Animations: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (0.6) should be [linear-gradient(45deg, blue, orange)] assert_equals: expected "linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) " but got "- webkit - cross - fade ( linear - gradient ( - 45deg , rgb ( 255 , 0 , 0 ) , rgb ( 255 , 255 , 0 ) ) , linear - gradient ( 45deg , rgb ( 0 , 0 , 255 ) , rgb ( 255 , 165 , 0 ) ) , 0.6 ) " +PASS Web Animations: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (1) should be [linear-gradient(45deg, blue, orange)] +PASS Web Animations: property <border-image-source> from [linear-gradient(-45deg, red, yellow)] to [linear-gradient(45deg, blue, orange)] at (1.5) should be [linear-gradient(45deg, blue, orange)] Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/box-shadow-interpolation-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/box-shadow-interpolation-expected.txt index 3f59451..83a8d423 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/box-shadow-interpolation-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/box-shadow-interpolation-expected.txt
@@ -240,33 +240,33 @@ PASS Web Animations: property <box-shadow> from [10px 20px rgba(255, 255, 0, 0.5), inset 5px 10em #008000] to [none] at (0.6) should be [rgba(255, 255, 0, 0.2) 4px 8px 0px 0px, rgba(0, 128, 0, 0.4) 2px 12px 0px 0px inset] FAIL Web Animations: property <box-shadow> from [10px 20px rgba(255, 255, 0, 0.5), inset 5px 10em #008000] to [none] at (1) should be [rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px inset] assert_equals: expected "rgba ( 0 , 0 , 0 , 0 ) 0px 0px 0px 0px , rgba ( 0 , 0 , 0 , 0 ) 0px 0px 0px 0px inset " but got "none " PASS Web Animations: property <box-shadow> from [10px 20px rgba(255, 255, 0, 0.5), inset 5px 10em #008000] to [none] at (1.5) should be [rgba(0, 0, 0, 0) -5px -10px 0px 0px, rgba(0, 0, 0, 0) -2.5px -15px 0px 0px inset] -PASS CSS Transitions: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (-0.3) should be [rgb(0, 128, 0) 5px 10px 0px 0px inset, rgb(0, 0, 255) 15px 20px 0px 0px] -PASS CSS Transitions: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (0) should be [rgb(0, 128, 0) 5px 10px 0px 0px inset, rgb(0, 0, 255) 15px 20px 0px 0px] -PASS CSS Transitions: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (0.3) should be [rgb(0, 128, 0) 5px 10px 0px 0px inset, rgb(0, 0, 255) 15px 20px 0px 0px] -PASS CSS Transitions: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (0.5) should be [rgb(0, 128, 0) 5px 10px 0px 0px inset, rgb(0, 0, 255) 15px 20px 0px 0px] -PASS CSS Transitions: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (0.6) should be [rgb(0, 128, 0) 5px 10px 0px 0px inset, rgb(0, 0, 255) 15px 20px 0px 0px] -PASS CSS Transitions: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (1) should be [rgb(0, 128, 0) 5px 10px 0px 0px inset, rgb(0, 0, 255) 15px 20px 0px 0px] -PASS CSS Transitions: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (1.5) should be [rgb(0, 128, 0) 5px 10px 0px 0px inset, rgb(0, 0, 255) 15px 20px 0px 0px] -PASS CSS Transitions with transition: all: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (-0.3) should be [rgb(0, 128, 0) 5px 10px 0px 0px inset, rgb(0, 0, 255) 15px 20px 0px 0px] -PASS CSS Transitions with transition: all: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (0) should be [rgb(0, 128, 0) 5px 10px 0px 0px inset, rgb(0, 0, 255) 15px 20px 0px 0px] -PASS CSS Transitions with transition: all: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (0.3) should be [rgb(0, 128, 0) 5px 10px 0px 0px inset, rgb(0, 0, 255) 15px 20px 0px 0px] -PASS CSS Transitions with transition: all: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (0.5) should be [rgb(0, 128, 0) 5px 10px 0px 0px inset, rgb(0, 0, 255) 15px 20px 0px 0px] -PASS CSS Transitions with transition: all: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (0.6) should be [rgb(0, 128, 0) 5px 10px 0px 0px inset, rgb(0, 0, 255) 15px 20px 0px 0px] -PASS CSS Transitions with transition: all: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (1) should be [rgb(0, 128, 0) 5px 10px 0px 0px inset, rgb(0, 0, 255) 15px 20px 0px 0px] -PASS CSS Transitions with transition: all: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (1.5) should be [rgb(0, 128, 0) 5px 10px 0px 0px inset, rgb(0, 0, 255) 15px 20px 0px 0px] -PASS CSS Animations: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (-0.3) should be [rgb(255, 255, 0) 10px 20px 0px 0px, rgb(0, 128, 0) 5px 10px 0px 0px] -PASS CSS Animations: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (0) should be [rgb(255, 255, 0) 10px 20px 0px 0px, rgb(0, 128, 0) 5px 10px 0px 0px] -PASS CSS Animations: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (0.3) should be [rgb(255, 255, 0) 10px 20px 0px 0px, rgb(0, 128, 0) 5px 10px 0px 0px] -PASS CSS Animations: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (0.5) should be [rgb(0, 128, 0) 5px 10px 0px 0px inset, rgb(0, 0, 255) 15px 20px 0px 0px] -PASS CSS Animations: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (0.6) should be [rgb(0, 128, 0) 5px 10px 0px 0px inset, rgb(0, 0, 255) 15px 20px 0px 0px] -PASS CSS Animations: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (1) should be [rgb(0, 128, 0) 5px 10px 0px 0px inset, rgb(0, 0, 255) 15px 20px 0px 0px] -PASS CSS Animations: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (1.5) should be [rgb(0, 128, 0) 5px 10px 0px 0px inset, rgb(0, 0, 255) 15px 20px 0px 0px] -PASS Web Animations: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (-0.3) should be [rgb(255, 255, 0) 10px 20px 0px 0px, rgb(0, 128, 0) 5px 10px 0px 0px] -PASS Web Animations: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (0) should be [rgb(255, 255, 0) 10px 20px 0px 0px, rgb(0, 128, 0) 5px 10px 0px 0px] -PASS Web Animations: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (0.3) should be [rgb(255, 255, 0) 10px 20px 0px 0px, rgb(0, 128, 0) 5px 10px 0px 0px] -PASS Web Animations: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (0.5) should be [rgb(0, 128, 0) 5px 10px 0px 0px inset, rgb(0, 0, 255) 15px 20px 0px 0px] -PASS Web Animations: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (0.6) should be [rgb(0, 128, 0) 5px 10px 0px 0px inset, rgb(0, 0, 255) 15px 20px 0px 0px] -PASS Web Animations: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (1) should be [rgb(0, 128, 0) 5px 10px 0px 0px inset, rgb(0, 0, 255) 15px 20px 0px 0px] -PASS Web Animations: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (1.5) should be [rgb(0, 128, 0) 5px 10px 0px 0px inset, rgb(0, 0, 255) 15px 20px 0px 0px] +PASS CSS Transitions: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (-0.3) should be [inset 5px 10px green, 15px 20px blue] +PASS CSS Transitions: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (0) should be [inset 5px 10px green, 15px 20px blue] +PASS CSS Transitions: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (0.3) should be [inset 5px 10px green, 15px 20px blue] +PASS CSS Transitions: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (0.5) should be [inset 5px 10px green, 15px 20px blue] +PASS CSS Transitions: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (0.6) should be [inset 5px 10px green, 15px 20px blue] +PASS CSS Transitions: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (1) should be [inset 5px 10px green, 15px 20px blue] +PASS CSS Transitions: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (1.5) should be [inset 5px 10px green, 15px 20px blue] +PASS CSS Transitions with transition: all: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (-0.3) should be [inset 5px 10px green, 15px 20px blue] +PASS CSS Transitions with transition: all: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (0) should be [inset 5px 10px green, 15px 20px blue] +PASS CSS Transitions with transition: all: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (0.3) should be [inset 5px 10px green, 15px 20px blue] +PASS CSS Transitions with transition: all: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (0.5) should be [inset 5px 10px green, 15px 20px blue] +PASS CSS Transitions with transition: all: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (0.6) should be [inset 5px 10px green, 15px 20px blue] +PASS CSS Transitions with transition: all: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (1) should be [inset 5px 10px green, 15px 20px blue] +PASS CSS Transitions with transition: all: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (1.5) should be [inset 5px 10px green, 15px 20px blue] +PASS CSS Animations: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (-0.3) should be [10px 20px yellow, 5px 10px green] +PASS CSS Animations: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (0) should be [10px 20px yellow, 5px 10px green] +PASS CSS Animations: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (0.3) should be [10px 20px yellow, 5px 10px green] +PASS CSS Animations: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (0.5) should be [inset 5px 10px green, 15px 20px blue] +PASS CSS Animations: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (0.6) should be [inset 5px 10px green, 15px 20px blue] +PASS CSS Animations: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (1) should be [inset 5px 10px green, 15px 20px blue] +PASS CSS Animations: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (1.5) should be [inset 5px 10px green, 15px 20px blue] +PASS Web Animations: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (-0.3) should be [10px 20px yellow, 5px 10px green] +PASS Web Animations: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (0) should be [10px 20px yellow, 5px 10px green] +PASS Web Animations: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (0.3) should be [10px 20px yellow, 5px 10px green] +PASS Web Animations: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (0.5) should be [inset 5px 10px green, 15px 20px blue] +PASS Web Animations: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (0.6) should be [inset 5px 10px green, 15px 20px blue] +PASS Web Animations: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (1) should be [inset 5px 10px green, 15px 20px blue] +PASS Web Animations: property <box-shadow> from [10px 20px yellow, 5px 10px green] to [inset 5px 10px green, 15px 20px blue] at (1.5) should be [inset 5px 10px green, 15px 20px blue] Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-fonts/animations/font-variation-settings-interpolation-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-fonts/animations/font-variation-settings-interpolation-expected.txt index 396a3b9e..854efe3 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-fonts/animations/font-variation-settings-interpolation-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-fonts/animations/font-variation-settings-interpolation-expected.txt
@@ -1,105 +1,105 @@ This is a testharness.js-based test. Found 288 tests; 270 PASS, 18 FAIL, 0 TIMEOUT, 0 NOTRUN. -PASS CSS Transitions: property <font-variation-settings> from neutral to ["test" 20] at (-0.5) should be ["test" 5] -PASS CSS Transitions: property <font-variation-settings> from neutral to ["test" 20] at (0) should be ["test" 10] -PASS CSS Transitions: property <font-variation-settings> from neutral to ["test" 20] at (0.3) should be ["test" 13] -PASS CSS Transitions: property <font-variation-settings> from neutral to ["test" 20] at (0.7) should be ["test" 17] -PASS CSS Transitions: property <font-variation-settings> from neutral to ["test" 20] at (1) should be ["test" 20] -PASS CSS Transitions: property <font-variation-settings> from neutral to ["test" 20] at (1.5) should be ["test" 25] -PASS CSS Transitions with transition: all: property <font-variation-settings> from neutral to ["test" 20] at (-0.5) should be ["test" 5] -PASS CSS Transitions with transition: all: property <font-variation-settings> from neutral to ["test" 20] at (0) should be ["test" 10] -PASS CSS Transitions with transition: all: property <font-variation-settings> from neutral to ["test" 20] at (0.3) should be ["test" 13] -PASS CSS Transitions with transition: all: property <font-variation-settings> from neutral to ["test" 20] at (0.7) should be ["test" 17] -PASS CSS Transitions with transition: all: property <font-variation-settings> from neutral to ["test" 20] at (1) should be ["test" 20] -PASS CSS Transitions with transition: all: property <font-variation-settings> from neutral to ["test" 20] at (1.5) should be ["test" 25] -PASS CSS Animations: property <font-variation-settings> from neutral to ["test" 20] at (-0.5) should be ["test" 5] -PASS CSS Animations: property <font-variation-settings> from neutral to ["test" 20] at (0) should be ["test" 10] -PASS CSS Animations: property <font-variation-settings> from neutral to ["test" 20] at (0.3) should be ["test" 13] -PASS CSS Animations: property <font-variation-settings> from neutral to ["test" 20] at (0.7) should be ["test" 17] -PASS CSS Animations: property <font-variation-settings> from neutral to ["test" 20] at (1) should be ["test" 20] -PASS CSS Animations: property <font-variation-settings> from neutral to ["test" 20] at (1.5) should be ["test" 25] -PASS Web Animations: property <font-variation-settings> from neutral to ["test" 20] at (-0.5) should be ["test" 5] -PASS Web Animations: property <font-variation-settings> from neutral to ["test" 20] at (0) should be ["test" 10] -PASS Web Animations: property <font-variation-settings> from neutral to ["test" 20] at (0.3) should be ["test" 13] -PASS Web Animations: property <font-variation-settings> from neutral to ["test" 20] at (0.7) should be ["test" 17] -PASS Web Animations: property <font-variation-settings> from neutral to ["test" 20] at (1) should be ["test" 20] -PASS Web Animations: property <font-variation-settings> from neutral to ["test" 20] at (1.5) should be ["test" 25] -PASS CSS Transitions: property <font-variation-settings> from [initial] to ['test' 50] at (-0.3) should be ["test" 50] -PASS CSS Transitions: property <font-variation-settings> from [initial] to ['test' 50] at (0) should be ["test" 50] -PASS CSS Transitions: property <font-variation-settings> from [initial] to ['test' 50] at (0.3) should be ["test" 50] -PASS CSS Transitions: property <font-variation-settings> from [initial] to ['test' 50] at (0.5) should be ["test" 50] -PASS CSS Transitions: property <font-variation-settings> from [initial] to ['test' 50] at (0.6) should be ["test" 50] -PASS CSS Transitions: property <font-variation-settings> from [initial] to ['test' 50] at (1) should be ["test" 50] -PASS CSS Transitions: property <font-variation-settings> from [initial] to ['test' 50] at (1.5) should be ["test" 50] -PASS CSS Transitions with transition: all: property <font-variation-settings> from [initial] to ['test' 50] at (-0.3) should be ["test" 50] -PASS CSS Transitions with transition: all: property <font-variation-settings> from [initial] to ['test' 50] at (0) should be ["test" 50] -PASS CSS Transitions with transition: all: property <font-variation-settings> from [initial] to ['test' 50] at (0.3) should be ["test" 50] -PASS CSS Transitions with transition: all: property <font-variation-settings> from [initial] to ['test' 50] at (0.5) should be ["test" 50] -PASS CSS Transitions with transition: all: property <font-variation-settings> from [initial] to ['test' 50] at (0.6) should be ["test" 50] -PASS CSS Transitions with transition: all: property <font-variation-settings> from [initial] to ['test' 50] at (1) should be ["test" 50] -PASS CSS Transitions with transition: all: property <font-variation-settings> from [initial] to ['test' 50] at (1.5) should be ["test" 50] -PASS CSS Animations: property <font-variation-settings> from [initial] to ['test' 50] at (-0.3) should be [normal] -PASS CSS Animations: property <font-variation-settings> from [initial] to ['test' 50] at (0) should be [normal] -PASS CSS Animations: property <font-variation-settings> from [initial] to ['test' 50] at (0.3) should be [normal] -PASS CSS Animations: property <font-variation-settings> from [initial] to ['test' 50] at (0.5) should be ["test" 50] -PASS CSS Animations: property <font-variation-settings> from [initial] to ['test' 50] at (0.6) should be ["test" 50] -PASS CSS Animations: property <font-variation-settings> from [initial] to ['test' 50] at (1) should be ["test" 50] -PASS CSS Animations: property <font-variation-settings> from [initial] to ['test' 50] at (1.5) should be ["test" 50] -PASS Web Animations: property <font-variation-settings> from [initial] to ['test' 50] at (-0.3) should be [normal] -PASS Web Animations: property <font-variation-settings> from [initial] to ['test' 50] at (0) should be [normal] -PASS Web Animations: property <font-variation-settings> from [initial] to ['test' 50] at (0.3) should be [normal] -PASS Web Animations: property <font-variation-settings> from [initial] to ['test' 50] at (0.5) should be ["test" 50] -PASS Web Animations: property <font-variation-settings> from [initial] to ['test' 50] at (0.6) should be ["test" 50] -PASS Web Animations: property <font-variation-settings> from [initial] to ['test' 50] at (1) should be ["test" 50] -PASS Web Animations: property <font-variation-settings> from [initial] to ['test' 50] at (1.5) should be ["test" 50] -PASS CSS Transitions: property <font-variation-settings> from [inherit] to ['test' 20] at (-0.5) should be ["test" 35] -PASS CSS Transitions: property <font-variation-settings> from [inherit] to ['test' 20] at (0) should be ["test" 30] -PASS CSS Transitions: property <font-variation-settings> from [inherit] to ['test' 20] at (0.3) should be ["test" 27] -PASS CSS Transitions: property <font-variation-settings> from [inherit] to ['test' 20] at (0.7) should be ["test" 23] -PASS CSS Transitions: property <font-variation-settings> from [inherit] to ['test' 20] at (1) should be ["test" 20] -PASS CSS Transitions: property <font-variation-settings> from [inherit] to ['test' 20] at (1.5) should be ["test" 15] -PASS CSS Transitions with transition: all: property <font-variation-settings> from [inherit] to ['test' 20] at (-0.5) should be ["test" 35] -PASS CSS Transitions with transition: all: property <font-variation-settings> from [inherit] to ['test' 20] at (0) should be ["test" 30] -PASS CSS Transitions with transition: all: property <font-variation-settings> from [inherit] to ['test' 20] at (0.3) should be ["test" 27] -PASS CSS Transitions with transition: all: property <font-variation-settings> from [inherit] to ['test' 20] at (0.7) should be ["test" 23] -PASS CSS Transitions with transition: all: property <font-variation-settings> from [inherit] to ['test' 20] at (1) should be ["test" 20] -PASS CSS Transitions with transition: all: property <font-variation-settings> from [inherit] to ['test' 20] at (1.5) should be ["test" 15] -PASS CSS Animations: property <font-variation-settings> from [inherit] to ['test' 20] at (-0.5) should be ["test" 35] -PASS CSS Animations: property <font-variation-settings> from [inherit] to ['test' 20] at (0) should be ["test" 30] -PASS CSS Animations: property <font-variation-settings> from [inherit] to ['test' 20] at (0.3) should be ["test" 27] -PASS CSS Animations: property <font-variation-settings> from [inherit] to ['test' 20] at (0.7) should be ["test" 23] -PASS CSS Animations: property <font-variation-settings> from [inherit] to ['test' 20] at (1) should be ["test" 20] -PASS CSS Animations: property <font-variation-settings> from [inherit] to ['test' 20] at (1.5) should be ["test" 15] -PASS Web Animations: property <font-variation-settings> from [inherit] to ['test' 20] at (-0.5) should be ["test" 35] -PASS Web Animations: property <font-variation-settings> from [inherit] to ['test' 20] at (0) should be ["test" 30] -PASS Web Animations: property <font-variation-settings> from [inherit] to ['test' 20] at (0.3) should be ["test" 27] -PASS Web Animations: property <font-variation-settings> from [inherit] to ['test' 20] at (0.7) should be ["test" 23] -PASS Web Animations: property <font-variation-settings> from [inherit] to ['test' 20] at (1) should be ["test" 20] -PASS Web Animations: property <font-variation-settings> from [inherit] to ['test' 20] at (1.5) should be ["test" 15] -PASS CSS Transitions: property <font-variation-settings> from [unset] to ['test' 20] at (-0.5) should be ["test" 35] -PASS CSS Transitions: property <font-variation-settings> from [unset] to ['test' 20] at (0) should be ["test" 30] -PASS CSS Transitions: property <font-variation-settings> from [unset] to ['test' 20] at (0.3) should be ["test" 27] -PASS CSS Transitions: property <font-variation-settings> from [unset] to ['test' 20] at (0.7) should be ["test" 23] -PASS CSS Transitions: property <font-variation-settings> from [unset] to ['test' 20] at (1) should be ["test" 20] -PASS CSS Transitions: property <font-variation-settings> from [unset] to ['test' 20] at (1.5) should be ["test" 15] -PASS CSS Transitions with transition: all: property <font-variation-settings> from [unset] to ['test' 20] at (-0.5) should be ["test" 35] -PASS CSS Transitions with transition: all: property <font-variation-settings> from [unset] to ['test' 20] at (0) should be ["test" 30] -PASS CSS Transitions with transition: all: property <font-variation-settings> from [unset] to ['test' 20] at (0.3) should be ["test" 27] -PASS CSS Transitions with transition: all: property <font-variation-settings> from [unset] to ['test' 20] at (0.7) should be ["test" 23] -PASS CSS Transitions with transition: all: property <font-variation-settings> from [unset] to ['test' 20] at (1) should be ["test" 20] -PASS CSS Transitions with transition: all: property <font-variation-settings> from [unset] to ['test' 20] at (1.5) should be ["test" 15] -PASS CSS Animations: property <font-variation-settings> from [unset] to ['test' 20] at (-0.5) should be ["test" 35] -PASS CSS Animations: property <font-variation-settings> from [unset] to ['test' 20] at (0) should be ["test" 30] -PASS CSS Animations: property <font-variation-settings> from [unset] to ['test' 20] at (0.3) should be ["test" 27] -PASS CSS Animations: property <font-variation-settings> from [unset] to ['test' 20] at (0.7) should be ["test" 23] -PASS CSS Animations: property <font-variation-settings> from [unset] to ['test' 20] at (1) should be ["test" 20] -PASS CSS Animations: property <font-variation-settings> from [unset] to ['test' 20] at (1.5) should be ["test" 15] -PASS Web Animations: property <font-variation-settings> from [unset] to ['test' 20] at (-0.5) should be ["test" 35] -PASS Web Animations: property <font-variation-settings> from [unset] to ['test' 20] at (0) should be ["test" 30] -PASS Web Animations: property <font-variation-settings> from [unset] to ['test' 20] at (0.3) should be ["test" 27] -PASS Web Animations: property <font-variation-settings> from [unset] to ['test' 20] at (0.7) should be ["test" 23] -PASS Web Animations: property <font-variation-settings> from [unset] to ['test' 20] at (1) should be ["test" 20] -PASS Web Animations: property <font-variation-settings> from [unset] to ['test' 20] at (1.5) should be ["test" 15] +PASS CSS Transitions: property <font-variation-settings> from neutral to ["test" 20] at (-0.5) should be ['test' 5] +PASS CSS Transitions: property <font-variation-settings> from neutral to ["test" 20] at (0) should be ['test' 10] +PASS CSS Transitions: property <font-variation-settings> from neutral to ["test" 20] at (0.3) should be ['test' 13] +PASS CSS Transitions: property <font-variation-settings> from neutral to ["test" 20] at (0.7) should be ['test' 17] +PASS CSS Transitions: property <font-variation-settings> from neutral to ["test" 20] at (1) should be ['test' 20] +PASS CSS Transitions: property <font-variation-settings> from neutral to ["test" 20] at (1.5) should be ['test' 25] +PASS CSS Transitions with transition: all: property <font-variation-settings> from neutral to ["test" 20] at (-0.5) should be ['test' 5] +PASS CSS Transitions with transition: all: property <font-variation-settings> from neutral to ["test" 20] at (0) should be ['test' 10] +PASS CSS Transitions with transition: all: property <font-variation-settings> from neutral to ["test" 20] at (0.3) should be ['test' 13] +PASS CSS Transitions with transition: all: property <font-variation-settings> from neutral to ["test" 20] at (0.7) should be ['test' 17] +PASS CSS Transitions with transition: all: property <font-variation-settings> from neutral to ["test" 20] at (1) should be ['test' 20] +PASS CSS Transitions with transition: all: property <font-variation-settings> from neutral to ["test" 20] at (1.5) should be ['test' 25] +PASS CSS Animations: property <font-variation-settings> from neutral to ["test" 20] at (-0.5) should be ['test' 5] +PASS CSS Animations: property <font-variation-settings> from neutral to ["test" 20] at (0) should be ['test' 10] +PASS CSS Animations: property <font-variation-settings> from neutral to ["test" 20] at (0.3) should be ['test' 13] +PASS CSS Animations: property <font-variation-settings> from neutral to ["test" 20] at (0.7) should be ['test' 17] +PASS CSS Animations: property <font-variation-settings> from neutral to ["test" 20] at (1) should be ['test' 20] +PASS CSS Animations: property <font-variation-settings> from neutral to ["test" 20] at (1.5) should be ['test' 25] +PASS Web Animations: property <font-variation-settings> from neutral to ["test" 20] at (-0.5) should be ['test' 5] +PASS Web Animations: property <font-variation-settings> from neutral to ["test" 20] at (0) should be ['test' 10] +PASS Web Animations: property <font-variation-settings> from neutral to ["test" 20] at (0.3) should be ['test' 13] +PASS Web Animations: property <font-variation-settings> from neutral to ["test" 20] at (0.7) should be ['test' 17] +PASS Web Animations: property <font-variation-settings> from neutral to ["test" 20] at (1) should be ['test' 20] +PASS Web Animations: property <font-variation-settings> from neutral to ["test" 20] at (1.5) should be ['test' 25] +PASS CSS Transitions: property <font-variation-settings> from [initial] to ['test' 50] at (-0.3) should be ['test' 50] +PASS CSS Transitions: property <font-variation-settings> from [initial] to ['test' 50] at (0) should be ['test' 50] +PASS CSS Transitions: property <font-variation-settings> from [initial] to ['test' 50] at (0.3) should be ['test' 50] +PASS CSS Transitions: property <font-variation-settings> from [initial] to ['test' 50] at (0.5) should be ['test' 50] +PASS CSS Transitions: property <font-variation-settings> from [initial] to ['test' 50] at (0.6) should be ['test' 50] +PASS CSS Transitions: property <font-variation-settings> from [initial] to ['test' 50] at (1) should be ['test' 50] +PASS CSS Transitions: property <font-variation-settings> from [initial] to ['test' 50] at (1.5) should be ['test' 50] +PASS CSS Transitions with transition: all: property <font-variation-settings> from [initial] to ['test' 50] at (-0.3) should be ['test' 50] +PASS CSS Transitions with transition: all: property <font-variation-settings> from [initial] to ['test' 50] at (0) should be ['test' 50] +PASS CSS Transitions with transition: all: property <font-variation-settings> from [initial] to ['test' 50] at (0.3) should be ['test' 50] +PASS CSS Transitions with transition: all: property <font-variation-settings> from [initial] to ['test' 50] at (0.5) should be ['test' 50] +PASS CSS Transitions with transition: all: property <font-variation-settings> from [initial] to ['test' 50] at (0.6) should be ['test' 50] +PASS CSS Transitions with transition: all: property <font-variation-settings> from [initial] to ['test' 50] at (1) should be ['test' 50] +PASS CSS Transitions with transition: all: property <font-variation-settings> from [initial] to ['test' 50] at (1.5) should be ['test' 50] +PASS CSS Animations: property <font-variation-settings> from [initial] to ['test' 50] at (-0.3) should be [initial] +PASS CSS Animations: property <font-variation-settings> from [initial] to ['test' 50] at (0) should be [initial] +PASS CSS Animations: property <font-variation-settings> from [initial] to ['test' 50] at (0.3) should be [initial] +PASS CSS Animations: property <font-variation-settings> from [initial] to ['test' 50] at (0.5) should be ['test' 50] +PASS CSS Animations: property <font-variation-settings> from [initial] to ['test' 50] at (0.6) should be ['test' 50] +PASS CSS Animations: property <font-variation-settings> from [initial] to ['test' 50] at (1) should be ['test' 50] +PASS CSS Animations: property <font-variation-settings> from [initial] to ['test' 50] at (1.5) should be ['test' 50] +PASS Web Animations: property <font-variation-settings> from [initial] to ['test' 50] at (-0.3) should be [initial] +PASS Web Animations: property <font-variation-settings> from [initial] to ['test' 50] at (0) should be [initial] +PASS Web Animations: property <font-variation-settings> from [initial] to ['test' 50] at (0.3) should be [initial] +PASS Web Animations: property <font-variation-settings> from [initial] to ['test' 50] at (0.5) should be ['test' 50] +PASS Web Animations: property <font-variation-settings> from [initial] to ['test' 50] at (0.6) should be ['test' 50] +PASS Web Animations: property <font-variation-settings> from [initial] to ['test' 50] at (1) should be ['test' 50] +PASS Web Animations: property <font-variation-settings> from [initial] to ['test' 50] at (1.5) should be ['test' 50] +PASS CSS Transitions: property <font-variation-settings> from [inherit] to ['test' 20] at (-0.5) should be ['test' 35] +PASS CSS Transitions: property <font-variation-settings> from [inherit] to ['test' 20] at (0) should be ['test' 30] +PASS CSS Transitions: property <font-variation-settings> from [inherit] to ['test' 20] at (0.3) should be ['test' 27] +PASS CSS Transitions: property <font-variation-settings> from [inherit] to ['test' 20] at (0.7) should be ['test' 23] +PASS CSS Transitions: property <font-variation-settings> from [inherit] to ['test' 20] at (1) should be ['test' 20] +PASS CSS Transitions: property <font-variation-settings> from [inherit] to ['test' 20] at (1.5) should be ['test' 15] +PASS CSS Transitions with transition: all: property <font-variation-settings> from [inherit] to ['test' 20] at (-0.5) should be ['test' 35] +PASS CSS Transitions with transition: all: property <font-variation-settings> from [inherit] to ['test' 20] at (0) should be ['test' 30] +PASS CSS Transitions with transition: all: property <font-variation-settings> from [inherit] to ['test' 20] at (0.3) should be ['test' 27] +PASS CSS Transitions with transition: all: property <font-variation-settings> from [inherit] to ['test' 20] at (0.7) should be ['test' 23] +PASS CSS Transitions with transition: all: property <font-variation-settings> from [inherit] to ['test' 20] at (1) should be ['test' 20] +PASS CSS Transitions with transition: all: property <font-variation-settings> from [inherit] to ['test' 20] at (1.5) should be ['test' 15] +PASS CSS Animations: property <font-variation-settings> from [inherit] to ['test' 20] at (-0.5) should be ['test' 35] +PASS CSS Animations: property <font-variation-settings> from [inherit] to ['test' 20] at (0) should be ['test' 30] +PASS CSS Animations: property <font-variation-settings> from [inherit] to ['test' 20] at (0.3) should be ['test' 27] +PASS CSS Animations: property <font-variation-settings> from [inherit] to ['test' 20] at (0.7) should be ['test' 23] +PASS CSS Animations: property <font-variation-settings> from [inherit] to ['test' 20] at (1) should be ['test' 20] +PASS CSS Animations: property <font-variation-settings> from [inherit] to ['test' 20] at (1.5) should be ['test' 15] +PASS Web Animations: property <font-variation-settings> from [inherit] to ['test' 20] at (-0.5) should be ['test' 35] +PASS Web Animations: property <font-variation-settings> from [inherit] to ['test' 20] at (0) should be ['test' 30] +PASS Web Animations: property <font-variation-settings> from [inherit] to ['test' 20] at (0.3) should be ['test' 27] +PASS Web Animations: property <font-variation-settings> from [inherit] to ['test' 20] at (0.7) should be ['test' 23] +PASS Web Animations: property <font-variation-settings> from [inherit] to ['test' 20] at (1) should be ['test' 20] +PASS Web Animations: property <font-variation-settings> from [inherit] to ['test' 20] at (1.5) should be ['test' 15] +PASS CSS Transitions: property <font-variation-settings> from [unset] to ['test' 20] at (-0.5) should be ['test' 35] +PASS CSS Transitions: property <font-variation-settings> from [unset] to ['test' 20] at (0) should be ['test' 30] +PASS CSS Transitions: property <font-variation-settings> from [unset] to ['test' 20] at (0.3) should be ['test' 27] +PASS CSS Transitions: property <font-variation-settings> from [unset] to ['test' 20] at (0.7) should be ['test' 23] +PASS CSS Transitions: property <font-variation-settings> from [unset] to ['test' 20] at (1) should be ['test' 20] +PASS CSS Transitions: property <font-variation-settings> from [unset] to ['test' 20] at (1.5) should be ['test' 15] +PASS CSS Transitions with transition: all: property <font-variation-settings> from [unset] to ['test' 20] at (-0.5) should be ['test' 35] +PASS CSS Transitions with transition: all: property <font-variation-settings> from [unset] to ['test' 20] at (0) should be ['test' 30] +PASS CSS Transitions with transition: all: property <font-variation-settings> from [unset] to ['test' 20] at (0.3) should be ['test' 27] +PASS CSS Transitions with transition: all: property <font-variation-settings> from [unset] to ['test' 20] at (0.7) should be ['test' 23] +PASS CSS Transitions with transition: all: property <font-variation-settings> from [unset] to ['test' 20] at (1) should be ['test' 20] +PASS CSS Transitions with transition: all: property <font-variation-settings> from [unset] to ['test' 20] at (1.5) should be ['test' 15] +PASS CSS Animations: property <font-variation-settings> from [unset] to ['test' 20] at (-0.5) should be ['test' 35] +PASS CSS Animations: property <font-variation-settings> from [unset] to ['test' 20] at (0) should be ['test' 30] +PASS CSS Animations: property <font-variation-settings> from [unset] to ['test' 20] at (0.3) should be ['test' 27] +PASS CSS Animations: property <font-variation-settings> from [unset] to ['test' 20] at (0.7) should be ['test' 23] +PASS CSS Animations: property <font-variation-settings> from [unset] to ['test' 20] at (1) should be ['test' 20] +PASS CSS Animations: property <font-variation-settings> from [unset] to ['test' 20] at (1.5) should be ['test' 15] +PASS Web Animations: property <font-variation-settings> from [unset] to ['test' 20] at (-0.5) should be ['test' 35] +PASS Web Animations: property <font-variation-settings> from [unset] to ['test' 20] at (0) should be ['test' 30] +PASS Web Animations: property <font-variation-settings> from [unset] to ['test' 20] at (0.3) should be ['test' 27] +PASS Web Animations: property <font-variation-settings> from [unset] to ['test' 20] at (0.7) should be ['test' 23] +PASS Web Animations: property <font-variation-settings> from [unset] to ['test' 20] at (1) should be ['test' 20] +PASS Web Animations: property <font-variation-settings> from [unset] to ['test' 20] at (1.5) should be ['test' 15] PASS CSS Transitions: property <font-variation-settings> from ['test' 20] to [normal] at (-0.3) should be [normal] PASS CSS Transitions: property <font-variation-settings> from ['test' 20] to [normal] at (0) should be [normal] PASS CSS Transitions: property <font-variation-settings> from ['test' 20] to [normal] at (0.3) should be [normal] @@ -114,179 +114,179 @@ PASS CSS Transitions with transition: all: property <font-variation-settings> from ['test' 20] to [normal] at (0.6) should be [normal] PASS CSS Transitions with transition: all: property <font-variation-settings> from ['test' 20] to [normal] at (1) should be [normal] PASS CSS Transitions with transition: all: property <font-variation-settings> from ['test' 20] to [normal] at (1.5) should be [normal] -PASS CSS Animations: property <font-variation-settings> from ['test' 20] to [normal] at (-0.3) should be ["test" 20] -PASS CSS Animations: property <font-variation-settings> from ['test' 20] to [normal] at (0) should be ["test" 20] -PASS CSS Animations: property <font-variation-settings> from ['test' 20] to [normal] at (0.3) should be ["test" 20] +PASS CSS Animations: property <font-variation-settings> from ['test' 20] to [normal] at (-0.3) should be ['test' 20] +PASS CSS Animations: property <font-variation-settings> from ['test' 20] to [normal] at (0) should be ['test' 20] +PASS CSS Animations: property <font-variation-settings> from ['test' 20] to [normal] at (0.3) should be ['test' 20] PASS CSS Animations: property <font-variation-settings> from ['test' 20] to [normal] at (0.5) should be [normal] PASS CSS Animations: property <font-variation-settings> from ['test' 20] to [normal] at (0.6) should be [normal] PASS CSS Animations: property <font-variation-settings> from ['test' 20] to [normal] at (1) should be [normal] PASS CSS Animations: property <font-variation-settings> from ['test' 20] to [normal] at (1.5) should be [normal] -PASS Web Animations: property <font-variation-settings> from ['test' 20] to [normal] at (-0.3) should be ["test" 20] -PASS Web Animations: property <font-variation-settings> from ['test' 20] to [normal] at (0) should be ["test" 20] -PASS Web Animations: property <font-variation-settings> from ['test' 20] to [normal] at (0.3) should be ["test" 20] +PASS Web Animations: property <font-variation-settings> from ['test' 20] to [normal] at (-0.3) should be ['test' 20] +PASS Web Animations: property <font-variation-settings> from ['test' 20] to [normal] at (0) should be ['test' 20] +PASS Web Animations: property <font-variation-settings> from ['test' 20] to [normal] at (0.3) should be ['test' 20] PASS Web Animations: property <font-variation-settings> from ['test' 20] to [normal] at (0.5) should be [normal] PASS Web Animations: property <font-variation-settings> from ['test' 20] to [normal] at (0.6) should be [normal] PASS Web Animations: property <font-variation-settings> from ['test' 20] to [normal] at (1) should be [normal] PASS Web Animations: property <font-variation-settings> from ['test' 20] to [normal] at (1.5) should be [normal] -PASS CSS Transitions: property <font-variation-settings> from ['test' 20] to ['test' 30] at (-0.5) should be ["test" 15] -PASS CSS Transitions: property <font-variation-settings> from ['test' 20] to ['test' 30] at (0) should be ["test" 20] -PASS CSS Transitions: property <font-variation-settings> from ['test' 20] to ['test' 30] at (0.3) should be ["test" 23] -PASS CSS Transitions: property <font-variation-settings> from ['test' 20] to ['test' 30] at (0.7) should be ["test" 27] -PASS CSS Transitions: property <font-variation-settings> from ['test' 20] to ['test' 30] at (1) should be ["test" 30] -PASS CSS Transitions: property <font-variation-settings> from ['test' 20] to ['test' 30] at (1.5) should be ["test" 35] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['test' 20] to ['test' 30] at (-0.5) should be ["test" 15] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['test' 20] to ['test' 30] at (0) should be ["test" 20] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['test' 20] to ['test' 30] at (0.3) should be ["test" 23] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['test' 20] to ['test' 30] at (0.7) should be ["test" 27] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['test' 20] to ['test' 30] at (1) should be ["test" 30] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['test' 20] to ['test' 30] at (1.5) should be ["test" 35] -PASS CSS Animations: property <font-variation-settings> from ['test' 20] to ['test' 30] at (-0.5) should be ["test" 15] -PASS CSS Animations: property <font-variation-settings> from ['test' 20] to ['test' 30] at (0) should be ["test" 20] -PASS CSS Animations: property <font-variation-settings> from ['test' 20] to ['test' 30] at (0.3) should be ["test" 23] -PASS CSS Animations: property <font-variation-settings> from ['test' 20] to ['test' 30] at (0.7) should be ["test" 27] -PASS CSS Animations: property <font-variation-settings> from ['test' 20] to ['test' 30] at (1) should be ["test" 30] -PASS CSS Animations: property <font-variation-settings> from ['test' 20] to ['test' 30] at (1.5) should be ["test" 35] -PASS Web Animations: property <font-variation-settings> from ['test' 20] to ['test' 30] at (-0.5) should be ["test" 15] -PASS Web Animations: property <font-variation-settings> from ['test' 20] to ['test' 30] at (0) should be ["test" 20] -PASS Web Animations: property <font-variation-settings> from ['test' 20] to ['test' 30] at (0.3) should be ["test" 23] -PASS Web Animations: property <font-variation-settings> from ['test' 20] to ['test' 30] at (0.7) should be ["test" 27] -PASS Web Animations: property <font-variation-settings> from ['test' 20] to ['test' 30] at (1) should be ["test" 30] -PASS Web Animations: property <font-variation-settings> from ['test' 20] to ['test' 30] at (1.5) should be ["test" 35] -PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (-0.5) should be ["aaaa" -5, "bbbb" 5, "cccc" 15] -PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0) should be ["aaaa" 0, "bbbb" 10, "cccc" 20] -PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.3) should be ["aaaa" 3, "bbbb" 13, "cccc" 23] -PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.7) should be ["aaaa" 7, "bbbb" 17, "cccc" 27] -PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (1) should be ["aaaa" 10, "bbbb" 20, "cccc" 30] -PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (1.5) should be ["aaaa" 15, "bbbb" 25, "cccc" 35] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (-0.5) should be ["aaaa" -5, "bbbb" 5, "cccc" 15] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0) should be ["aaaa" 0, "bbbb" 10, "cccc" 20] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.3) should be ["aaaa" 3, "bbbb" 13, "cccc" 23] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.7) should be ["aaaa" 7, "bbbb" 17, "cccc" 27] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (1) should be ["aaaa" 10, "bbbb" 20, "cccc" 30] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (1.5) should be ["aaaa" 15, "bbbb" 25, "cccc" 35] -PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (-0.5) should be ["aaaa" -5, "bbbb" 5, "cccc" 15] -PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0) should be ["aaaa" 0, "bbbb" 10, "cccc" 20] -PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.3) should be ["aaaa" 3, "bbbb" 13, "cccc" 23] -PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.7) should be ["aaaa" 7, "bbbb" 17, "cccc" 27] -PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (1) should be ["aaaa" 10, "bbbb" 20, "cccc" 30] -PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (1.5) should be ["aaaa" 15, "bbbb" 25, "cccc" 35] -PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (-0.5) should be ["aaaa" -5, "bbbb" 5, "cccc" 15] -PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0) should be ["aaaa" 0, "bbbb" 10, "cccc" 20] -PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.3) should be ["aaaa" 3, "bbbb" 13, "cccc" 23] -PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.7) should be ["aaaa" 7, "bbbb" 17, "cccc" 27] -PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (1) should be ["aaaa" 10, "bbbb" 20, "cccc" 30] -PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (1.5) should be ["aaaa" 15, "bbbb" 25, "cccc" 35] -FAIL CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (-0.5) should be ["aaaa" -15, "bbbb" 5, "cccc" 25] assert_array_equals: property 0, expected "\"aaaa\" -15" but got "\"aaaa\" 30" -FAIL CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (0) should be ["aaaa" 0, "bbbb" 10, "cccc" 20] assert_array_equals: property 0, expected "\"aaaa\" 0" but got "\"aaaa\" 30" -FAIL CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (0.3) should be ["aaaa" 9, "bbbb" 13, "cccc" 17] assert_array_equals: property 0, expected "\"aaaa\" 9" but got "\"aaaa\" 30" -FAIL CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (0.7) should be ["aaaa" 21, "bbbb" 17, "cccc" 13] assert_array_equals: property 0, expected "\"aaaa\" 21" but got "\"aaaa\" 30" -PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (1) should be ["aaaa" 30, "bbbb" 20, "cccc" 10] -FAIL CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (1.5) should be ["aaaa" 45, "bbbb" 25, "cccc" 5] assert_array_equals: property 0, expected "\"aaaa\" 45" but got "\"aaaa\" 30" -FAIL CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (-0.5) should be ["aaaa" -15, "bbbb" 5, "cccc" 25] assert_array_equals: property 0, expected "\"aaaa\" -15" but got "\"aaaa\" 30" -FAIL CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (0) should be ["aaaa" 0, "bbbb" 10, "cccc" 20] assert_array_equals: property 0, expected "\"aaaa\" 0" but got "\"aaaa\" 30" -FAIL CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (0.3) should be ["aaaa" 9, "bbbb" 13, "cccc" 17] assert_array_equals: property 0, expected "\"aaaa\" 9" but got "\"aaaa\" 30" -FAIL CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (0.7) should be ["aaaa" 21, "bbbb" 17, "cccc" 13] assert_array_equals: property 0, expected "\"aaaa\" 21" but got "\"aaaa\" 30" -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (1) should be ["aaaa" 30, "bbbb" 20, "cccc" 10] -FAIL CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (1.5) should be ["aaaa" 45, "bbbb" 25, "cccc" 5] assert_array_equals: property 0, expected "\"aaaa\" 45" but got "\"aaaa\" 30" -FAIL CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (-0.5) should be ["aaaa" -15, "bbbb" 5, "cccc" 25] assert_array_equals: property 0, expected "\"aaaa\" -15" but got "\"aaaa\" 0" -PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (0) should be ["aaaa" 0, "bbbb" 10, "cccc" 20] -FAIL CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (0.3) should be ["aaaa" 9, "bbbb" 13, "cccc" 17] assert_array_equals: property 0, expected "\"aaaa\" 9" but got "\"aaaa\" 0" -FAIL CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (0.7) should be ["aaaa" 21, "bbbb" 17, "cccc" 13] assert_array_equals: property 0, expected "\"aaaa\" 21" but got "\"aaaa\" 30" -PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (1) should be ["aaaa" 30, "bbbb" 20, "cccc" 10] -FAIL CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (1.5) should be ["aaaa" 45, "bbbb" 25, "cccc" 5] assert_array_equals: property 0, expected "\"aaaa\" 45" but got "\"aaaa\" 30" -FAIL Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (-0.5) should be ["aaaa" -15, "bbbb" 5, "cccc" 25] assert_array_equals: property 0, expected "\"aaaa\" -15" but got "\"aaaa\" 0" -PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (0) should be ["aaaa" 0, "bbbb" 10, "cccc" 20] -FAIL Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (0.3) should be ["aaaa" 9, "bbbb" 13, "cccc" 17] assert_array_equals: property 0, expected "\"aaaa\" 9" but got "\"aaaa\" 0" -FAIL Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (0.7) should be ["aaaa" 21, "bbbb" 17, "cccc" 13] assert_array_equals: property 0, expected "\"aaaa\" 21" but got "\"aaaa\" 30" -PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (1) should be ["aaaa" 30, "bbbb" 20, "cccc" 10] -FAIL Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (1.5) should be ["aaaa" 45, "bbbb" 25, "cccc" 5] assert_array_equals: property 0, expected "\"aaaa\" 45" but got "\"aaaa\" 30" -PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (-0.3) should be ["aaaa" 10, "bbbb" 20, "cccc" 30] -PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0) should be ["aaaa" 10, "bbbb" 20, "cccc" 30] -PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.3) should be ["aaaa" 10, "bbbb" 20, "cccc" 30] -PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.5) should be ["aaaa" 10, "bbbb" 20, "cccc" 30] -PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.6) should be ["aaaa" 10, "bbbb" 20, "cccc" 30] -PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (1) should be ["aaaa" 10, "bbbb" 20, "cccc" 30] -PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (1.5) should be ["aaaa" 10, "bbbb" 20, "cccc" 30] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (-0.3) should be ["aaaa" 10, "bbbb" 20, "cccc" 30] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0) should be ["aaaa" 10, "bbbb" 20, "cccc" 30] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.3) should be ["aaaa" 10, "bbbb" 20, "cccc" 30] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.5) should be ["aaaa" 10, "bbbb" 20, "cccc" 30] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.6) should be ["aaaa" 10, "bbbb" 20, "cccc" 30] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (1) should be ["aaaa" 10, "bbbb" 20, "cccc" 30] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (1.5) should be ["aaaa" 10, "bbbb" 20, "cccc" 30] -PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (-0.3) should be ["aaaa" 0, "bbbb" 10] -PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0) should be ["aaaa" 0, "bbbb" 10] -PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.3) should be ["aaaa" 0, "bbbb" 10] -PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.5) should be ["aaaa" 10, "bbbb" 20, "cccc" 30] -PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.6) should be ["aaaa" 10, "bbbb" 20, "cccc" 30] -PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (1) should be ["aaaa" 10, "bbbb" 20, "cccc" 30] -PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (1.5) should be ["aaaa" 10, "bbbb" 20, "cccc" 30] -PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (-0.3) should be ["aaaa" 0, "bbbb" 10] -PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0) should be ["aaaa" 0, "bbbb" 10] -PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.3) should be ["aaaa" 0, "bbbb" 10] -PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.5) should be ["aaaa" 10, "bbbb" 20, "cccc" 30] -PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.6) should be ["aaaa" 10, "bbbb" 20, "cccc" 30] -PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (1) should be ["aaaa" 10, "bbbb" 20, "cccc" 30] -PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (1.5) should be ["aaaa" 10, "bbbb" 20, "cccc" 30] -PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (-0.3) should be ["aaaa" 0, "bbbb" 10] -PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (0) should be ["aaaa" 0, "bbbb" 10] -PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (0.3) should be ["aaaa" 0, "bbbb" 10] -PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (0.5) should be ["aaaa" 0, "bbbb" 10] -PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (0.6) should be ["aaaa" 0, "bbbb" 10] -PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (1) should be ["aaaa" 0, "bbbb" 10] -PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (1.5) should be ["aaaa" 0, "bbbb" 10] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (-0.3) should be ["aaaa" 0, "bbbb" 10] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (0) should be ["aaaa" 0, "bbbb" 10] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (0.3) should be ["aaaa" 0, "bbbb" 10] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (0.5) should be ["aaaa" 0, "bbbb" 10] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (0.6) should be ["aaaa" 0, "bbbb" 10] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (1) should be ["aaaa" 0, "bbbb" 10] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (1.5) should be ["aaaa" 0, "bbbb" 10] -PASS CSS Animations: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (-0.3) should be ["aaaa" 10, "bbbb" 20, "cccc" 30] -PASS CSS Animations: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (0) should be ["aaaa" 10, "bbbb" 20, "cccc" 30] -PASS CSS Animations: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (0.3) should be ["aaaa" 10, "bbbb" 20, "cccc" 30] -PASS CSS Animations: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (0.5) should be ["aaaa" 0, "bbbb" 10] -PASS CSS Animations: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (0.6) should be ["aaaa" 0, "bbbb" 10] -PASS CSS Animations: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (1) should be ["aaaa" 0, "bbbb" 10] -PASS CSS Animations: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (1.5) should be ["aaaa" 0, "bbbb" 10] -PASS Web Animations: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (-0.3) should be ["aaaa" 10, "bbbb" 20, "cccc" 30] -PASS Web Animations: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (0) should be ["aaaa" 10, "bbbb" 20, "cccc" 30] -PASS Web Animations: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (0.3) should be ["aaaa" 10, "bbbb" 20, "cccc" 30] -PASS Web Animations: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (0.5) should be ["aaaa" 0, "bbbb" 10] -PASS Web Animations: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (0.6) should be ["aaaa" 0, "bbbb" 10] -PASS Web Animations: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (1) should be ["aaaa" 0, "bbbb" 10] -PASS Web Animations: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (1.5) should be ["aaaa" 0, "bbbb" 10] -PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (-0.3) should be ["dddd" 10, "eeee" 20, "ffff" 30] -PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (0) should be ["dddd" 10, "eeee" 20, "ffff" 30] -PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (0.3) should be ["dddd" 10, "eeee" 20, "ffff" 30] -PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (0.5) should be ["dddd" 10, "eeee" 20, "ffff" 30] -PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (0.6) should be ["dddd" 10, "eeee" 20, "ffff" 30] -PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (1) should be ["dddd" 10, "eeee" 20, "ffff" 30] -PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (1.5) should be ["dddd" 10, "eeee" 20, "ffff" 30] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (-0.3) should be ["dddd" 10, "eeee" 20, "ffff" 30] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (0) should be ["dddd" 10, "eeee" 20, "ffff" 30] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (0.3) should be ["dddd" 10, "eeee" 20, "ffff" 30] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (0.5) should be ["dddd" 10, "eeee" 20, "ffff" 30] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (0.6) should be ["dddd" 10, "eeee" 20, "ffff" 30] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (1) should be ["dddd" 10, "eeee" 20, "ffff" 30] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (1.5) should be ["dddd" 10, "eeee" 20, "ffff" 30] -PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (-0.3) should be ["aaaa" 0, "bbbb" 10, "cccc" 20] -PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (0) should be ["aaaa" 0, "bbbb" 10, "cccc" 20] -PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (0.3) should be ["aaaa" 0, "bbbb" 10, "cccc" 20] -PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (0.5) should be ["dddd" 10, "eeee" 20, "ffff" 30] -PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (0.6) should be ["dddd" 10, "eeee" 20, "ffff" 30] -PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (1) should be ["dddd" 10, "eeee" 20, "ffff" 30] -PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (1.5) should be ["dddd" 10, "eeee" 20, "ffff" 30] -PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (-0.3) should be ["aaaa" 0, "bbbb" 10, "cccc" 20] -PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (0) should be ["aaaa" 0, "bbbb" 10, "cccc" 20] -PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (0.3) should be ["aaaa" 0, "bbbb" 10, "cccc" 20] -PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (0.5) should be ["dddd" 10, "eeee" 20, "ffff" 30] -PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (0.6) should be ["dddd" 10, "eeee" 20, "ffff" 30] -PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (1) should be ["dddd" 10, "eeee" 20, "ffff" 30] -PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (1.5) should be ["dddd" 10, "eeee" 20, "ffff" 30] -PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 30, 'bbbb' 20] to ['aaaa' 20, 'bbbb' 30] at (3.40282e+38) should be ["aaaa" -3.40282e+38, "bbbb" 3.40282e+38] -PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 30, 'bbbb' 20] to ['aaaa' 20, 'bbbb' 30] at (3.40282e+38) should be ["aaaa" -3.40282e+38, "bbbb" 3.40282e+38] -PASS CSS Animations: property <font-variation-settings> from ['aaaa' 30, 'bbbb' 20] to ['aaaa' 20, 'bbbb' 30] at (3.40282e+38) should be ["aaaa" -3.40282e+38, "bbbb" 3.40282e+38] -PASS Web Animations: property <font-variation-settings> from ['aaaa' 30, 'bbbb' 20] to ['aaaa' 20, 'bbbb' 30] at (3.40282e+38) should be ["aaaa" -3.40282e+38, "bbbb" 3.40282e+38] +PASS CSS Transitions: property <font-variation-settings> from ['test' 20] to ['test' 30] at (-0.5) should be ['test' 15] +PASS CSS Transitions: property <font-variation-settings> from ['test' 20] to ['test' 30] at (0) should be ['test' 20] +PASS CSS Transitions: property <font-variation-settings> from ['test' 20] to ['test' 30] at (0.3) should be ['test' 23] +PASS CSS Transitions: property <font-variation-settings> from ['test' 20] to ['test' 30] at (0.7) should be ['test' 27] +PASS CSS Transitions: property <font-variation-settings> from ['test' 20] to ['test' 30] at (1) should be ['test' 30] +PASS CSS Transitions: property <font-variation-settings> from ['test' 20] to ['test' 30] at (1.5) should be ['test' 35] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['test' 20] to ['test' 30] at (-0.5) should be ['test' 15] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['test' 20] to ['test' 30] at (0) should be ['test' 20] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['test' 20] to ['test' 30] at (0.3) should be ['test' 23] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['test' 20] to ['test' 30] at (0.7) should be ['test' 27] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['test' 20] to ['test' 30] at (1) should be ['test' 30] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['test' 20] to ['test' 30] at (1.5) should be ['test' 35] +PASS CSS Animations: property <font-variation-settings> from ['test' 20] to ['test' 30] at (-0.5) should be ['test' 15] +PASS CSS Animations: property <font-variation-settings> from ['test' 20] to ['test' 30] at (0) should be ['test' 20] +PASS CSS Animations: property <font-variation-settings> from ['test' 20] to ['test' 30] at (0.3) should be ['test' 23] +PASS CSS Animations: property <font-variation-settings> from ['test' 20] to ['test' 30] at (0.7) should be ['test' 27] +PASS CSS Animations: property <font-variation-settings> from ['test' 20] to ['test' 30] at (1) should be ['test' 30] +PASS CSS Animations: property <font-variation-settings> from ['test' 20] to ['test' 30] at (1.5) should be ['test' 35] +PASS Web Animations: property <font-variation-settings> from ['test' 20] to ['test' 30] at (-0.5) should be ['test' 15] +PASS Web Animations: property <font-variation-settings> from ['test' 20] to ['test' 30] at (0) should be ['test' 20] +PASS Web Animations: property <font-variation-settings> from ['test' 20] to ['test' 30] at (0.3) should be ['test' 23] +PASS Web Animations: property <font-variation-settings> from ['test' 20] to ['test' 30] at (0.7) should be ['test' 27] +PASS Web Animations: property <font-variation-settings> from ['test' 20] to ['test' 30] at (1) should be ['test' 30] +PASS Web Animations: property <font-variation-settings> from ['test' 20] to ['test' 30] at (1.5) should be ['test' 35] +PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (-0.5) should be ['aaaa' -5, 'bbbb' 5, 'cccc' 15] +PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0) should be ['aaaa' 0, 'bbbb' 10, 'cccc' 20] +PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.3) should be ['aaaa' 3, 'bbbb' 13, 'cccc' 23] +PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.7) should be ['aaaa' 7, 'bbbb' 17, 'cccc' 27] +PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (1) should be ['aaaa' 10, 'bbbb' 20, 'cccc' 30] +PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (1.5) should be ['aaaa' 15, 'bbbb' 25, 'cccc' 35] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (-0.5) should be ['aaaa' -5, 'bbbb' 5, 'cccc' 15] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0) should be ['aaaa' 0, 'bbbb' 10, 'cccc' 20] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.3) should be ['aaaa' 3, 'bbbb' 13, 'cccc' 23] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.7) should be ['aaaa' 7, 'bbbb' 17, 'cccc' 27] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (1) should be ['aaaa' 10, 'bbbb' 20, 'cccc' 30] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (1.5) should be ['aaaa' 15, 'bbbb' 25, 'cccc' 35] +PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (-0.5) should be ['aaaa' -5, 'bbbb' 5, 'cccc' 15] +PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0) should be ['aaaa' 0, 'bbbb' 10, 'cccc' 20] +PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.3) should be ['aaaa' 3, 'bbbb' 13, 'cccc' 23] +PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.7) should be ['aaaa' 7, 'bbbb' 17, 'cccc' 27] +PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (1) should be ['aaaa' 10, 'bbbb' 20, 'cccc' 30] +PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (1.5) should be ['aaaa' 15, 'bbbb' 25, 'cccc' 35] +PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (-0.5) should be ['aaaa' -5, 'bbbb' 5, 'cccc' 15] +PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0) should be ['aaaa' 0, 'bbbb' 10, 'cccc' 20] +PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.3) should be ['aaaa' 3, 'bbbb' 13, 'cccc' 23] +PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.7) should be ['aaaa' 7, 'bbbb' 17, 'cccc' 27] +PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (1) should be ['aaaa' 10, 'bbbb' 20, 'cccc' 30] +PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (1.5) should be ['aaaa' 15, 'bbbb' 25, 'cccc' 35] +FAIL CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (-0.5) should be ['aaaa' -15, 'bbbb' 5, 'cccc' 25] assert_array_equals: property 0, expected "\"aaaa\" -15" but got "\"aaaa\" 30" +FAIL CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (0) should be ['aaaa' 0, 'bbbb' 10, 'cccc' 20] assert_array_equals: property 0, expected "\"aaaa\" 0" but got "\"aaaa\" 30" +FAIL CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (0.3) should be ['aaaa' 9, 'bbbb' 13, 'cccc' 17] assert_array_equals: property 0, expected "\"aaaa\" 9" but got "\"aaaa\" 30" +FAIL CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (0.7) should be ['aaaa' 21, 'bbbb' 17, 'cccc' 13] assert_array_equals: property 0, expected "\"aaaa\" 21" but got "\"aaaa\" 30" +PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (1) should be ['aaaa' 30, 'bbbb' 20, 'cccc' 10] +FAIL CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (1.5) should be ['aaaa' 45, 'bbbb' 25, 'cccc' 5] assert_array_equals: property 0, expected "\"aaaa\" 45" but got "\"aaaa\" 30" +FAIL CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (-0.5) should be ['aaaa' -15, 'bbbb' 5, 'cccc' 25] assert_array_equals: property 0, expected "\"aaaa\" -15" but got "\"aaaa\" 30" +FAIL CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (0) should be ['aaaa' 0, 'bbbb' 10, 'cccc' 20] assert_array_equals: property 0, expected "\"aaaa\" 0" but got "\"aaaa\" 30" +FAIL CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (0.3) should be ['aaaa' 9, 'bbbb' 13, 'cccc' 17] assert_array_equals: property 0, expected "\"aaaa\" 9" but got "\"aaaa\" 30" +FAIL CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (0.7) should be ['aaaa' 21, 'bbbb' 17, 'cccc' 13] assert_array_equals: property 0, expected "\"aaaa\" 21" but got "\"aaaa\" 30" +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (1) should be ['aaaa' 30, 'bbbb' 20, 'cccc' 10] +FAIL CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (1.5) should be ['aaaa' 45, 'bbbb' 25, 'cccc' 5] assert_array_equals: property 0, expected "\"aaaa\" 45" but got "\"aaaa\" 30" +FAIL CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (-0.5) should be ['aaaa' -15, 'bbbb' 5, 'cccc' 25] assert_array_equals: property 0, expected "\"aaaa\" -15" but got "\"aaaa\" 0" +PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (0) should be ['aaaa' 0, 'bbbb' 10, 'cccc' 20] +FAIL CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (0.3) should be ['aaaa' 9, 'bbbb' 13, 'cccc' 17] assert_array_equals: property 0, expected "\"aaaa\" 9" but got "\"aaaa\" 0" +FAIL CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (0.7) should be ['aaaa' 21, 'bbbb' 17, 'cccc' 13] assert_array_equals: property 0, expected "\"aaaa\" 21" but got "\"aaaa\" 30" +PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (1) should be ['aaaa' 30, 'bbbb' 20, 'cccc' 10] +FAIL CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (1.5) should be ['aaaa' 45, 'bbbb' 25, 'cccc' 5] assert_array_equals: property 0, expected "\"aaaa\" 45" but got "\"aaaa\" 30" +FAIL Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (-0.5) should be ['aaaa' -15, 'bbbb' 5, 'cccc' 25] assert_array_equals: property 0, expected "\"aaaa\" -15" but got "\"aaaa\" 0" +PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (0) should be ['aaaa' 0, 'bbbb' 10, 'cccc' 20] +FAIL Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (0.3) should be ['aaaa' 9, 'bbbb' 13, 'cccc' 17] assert_array_equals: property 0, expected "\"aaaa\" 9" but got "\"aaaa\" 0" +FAIL Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (0.7) should be ['aaaa' 21, 'bbbb' 17, 'cccc' 13] assert_array_equals: property 0, expected "\"aaaa\" 21" but got "\"aaaa\" 30" +PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (1) should be ['aaaa' 30, 'bbbb' 20, 'cccc' 10] +FAIL Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['cccc' 10, 'bbbb' 20, 'aaaa' 30] at (1.5) should be ['aaaa' 45, 'bbbb' 25, 'cccc' 5] assert_array_equals: property 0, expected "\"aaaa\" 45" but got "\"aaaa\" 30" +PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (-0.3) should be ['aaaa' 10, 'bbbb' 20, 'cccc' 30] +PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0) should be ['aaaa' 10, 'bbbb' 20, 'cccc' 30] +PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.3) should be ['aaaa' 10, 'bbbb' 20, 'cccc' 30] +PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.5) should be ['aaaa' 10, 'bbbb' 20, 'cccc' 30] +PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.6) should be ['aaaa' 10, 'bbbb' 20, 'cccc' 30] +PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (1) should be ['aaaa' 10, 'bbbb' 20, 'cccc' 30] +PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (1.5) should be ['aaaa' 10, 'bbbb' 20, 'cccc' 30] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (-0.3) should be ['aaaa' 10, 'bbbb' 20, 'cccc' 30] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0) should be ['aaaa' 10, 'bbbb' 20, 'cccc' 30] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.3) should be ['aaaa' 10, 'bbbb' 20, 'cccc' 30] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.5) should be ['aaaa' 10, 'bbbb' 20, 'cccc' 30] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.6) should be ['aaaa' 10, 'bbbb' 20, 'cccc' 30] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (1) should be ['aaaa' 10, 'bbbb' 20, 'cccc' 30] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (1.5) should be ['aaaa' 10, 'bbbb' 20, 'cccc' 30] +PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (-0.3) should be ['aaaa' 0, 'bbbb' 10] +PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0) should be ['aaaa' 0, 'bbbb' 10] +PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.3) should be ['aaaa' 0, 'bbbb' 10] +PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.5) should be ['aaaa' 10, 'bbbb' 20, 'cccc' 30] +PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.6) should be ['aaaa' 10, 'bbbb' 20, 'cccc' 30] +PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (1) should be ['aaaa' 10, 'bbbb' 20, 'cccc' 30] +PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (1.5) should be ['aaaa' 10, 'bbbb' 20, 'cccc' 30] +PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (-0.3) should be ['aaaa' 0, 'bbbb' 10] +PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0) should be ['aaaa' 0, 'bbbb' 10] +PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.3) should be ['aaaa' 0, 'bbbb' 10] +PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.5) should be ['aaaa' 10, 'bbbb' 20, 'cccc' 30] +PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (0.6) should be ['aaaa' 10, 'bbbb' 20, 'cccc' 30] +PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (1) should be ['aaaa' 10, 'bbbb' 20, 'cccc' 30] +PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10] to ['aaaa' 10, 'bbbb' 20, 'cccc' 30] at (1.5) should be ['aaaa' 10, 'bbbb' 20, 'cccc' 30] +PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (-0.3) should be ['aaaa' 0, 'bbbb' 10] +PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (0) should be ['aaaa' 0, 'bbbb' 10] +PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (0.3) should be ['aaaa' 0, 'bbbb' 10] +PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (0.5) should be ['aaaa' 0, 'bbbb' 10] +PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (0.6) should be ['aaaa' 0, 'bbbb' 10] +PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (1) should be ['aaaa' 0, 'bbbb' 10] +PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (1.5) should be ['aaaa' 0, 'bbbb' 10] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (-0.3) should be ['aaaa' 0, 'bbbb' 10] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (0) should be ['aaaa' 0, 'bbbb' 10] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (0.3) should be ['aaaa' 0, 'bbbb' 10] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (0.5) should be ['aaaa' 0, 'bbbb' 10] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (0.6) should be ['aaaa' 0, 'bbbb' 10] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (1) should be ['aaaa' 0, 'bbbb' 10] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (1.5) should be ['aaaa' 0, 'bbbb' 10] +PASS CSS Animations: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (-0.3) should be ['aaaa' 10, 'bbbb' 20, 'cccc' 30] +PASS CSS Animations: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (0) should be ['aaaa' 10, 'bbbb' 20, 'cccc' 30] +PASS CSS Animations: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (0.3) should be ['aaaa' 10, 'bbbb' 20, 'cccc' 30] +PASS CSS Animations: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (0.5) should be ['aaaa' 0, 'bbbb' 10] +PASS CSS Animations: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (0.6) should be ['aaaa' 0, 'bbbb' 10] +PASS CSS Animations: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (1) should be ['aaaa' 0, 'bbbb' 10] +PASS CSS Animations: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (1.5) should be ['aaaa' 0, 'bbbb' 10] +PASS Web Animations: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (-0.3) should be ['aaaa' 10, 'bbbb' 20, 'cccc' 30] +PASS Web Animations: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (0) should be ['aaaa' 10, 'bbbb' 20, 'cccc' 30] +PASS Web Animations: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (0.3) should be ['aaaa' 10, 'bbbb' 20, 'cccc' 30] +PASS Web Animations: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (0.5) should be ['aaaa' 0, 'bbbb' 10] +PASS Web Animations: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (0.6) should be ['aaaa' 0, 'bbbb' 10] +PASS Web Animations: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (1) should be ['aaaa' 0, 'bbbb' 10] +PASS Web Animations: property <font-variation-settings> from ['aaaa' 10, 'bbbb' 20, 'cccc' 30] to ['aaaa' 0, 'bbbb' 10] at (1.5) should be ['aaaa' 0, 'bbbb' 10] +PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (-0.3) should be ['dddd' 10, 'eeee' 20, 'ffff' 30] +PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (0) should be ['dddd' 10, 'eeee' 20, 'ffff' 30] +PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (0.3) should be ['dddd' 10, 'eeee' 20, 'ffff' 30] +PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (0.5) should be ['dddd' 10, 'eeee' 20, 'ffff' 30] +PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (0.6) should be ['dddd' 10, 'eeee' 20, 'ffff' 30] +PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (1) should be ['dddd' 10, 'eeee' 20, 'ffff' 30] +PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (1.5) should be ['dddd' 10, 'eeee' 20, 'ffff' 30] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (-0.3) should be ['dddd' 10, 'eeee' 20, 'ffff' 30] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (0) should be ['dddd' 10, 'eeee' 20, 'ffff' 30] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (0.3) should be ['dddd' 10, 'eeee' 20, 'ffff' 30] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (0.5) should be ['dddd' 10, 'eeee' 20, 'ffff' 30] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (0.6) should be ['dddd' 10, 'eeee' 20, 'ffff' 30] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (1) should be ['dddd' 10, 'eeee' 20, 'ffff' 30] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (1.5) should be ['dddd' 10, 'eeee' 20, 'ffff' 30] +PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (-0.3) should be ['aaaa' 0, 'bbbb' 10, 'cccc' 20] +PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (0) should be ['aaaa' 0, 'bbbb' 10, 'cccc' 20] +PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (0.3) should be ['aaaa' 0, 'bbbb' 10, 'cccc' 20] +PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (0.5) should be ['dddd' 10, 'eeee' 20, 'ffff' 30] +PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (0.6) should be ['dddd' 10, 'eeee' 20, 'ffff' 30] +PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (1) should be ['dddd' 10, 'eeee' 20, 'ffff' 30] +PASS CSS Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (1.5) should be ['dddd' 10, 'eeee' 20, 'ffff' 30] +PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (-0.3) should be ['aaaa' 0, 'bbbb' 10, 'cccc' 20] +PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (0) should be ['aaaa' 0, 'bbbb' 10, 'cccc' 20] +PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (0.3) should be ['aaaa' 0, 'bbbb' 10, 'cccc' 20] +PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (0.5) should be ['dddd' 10, 'eeee' 20, 'ffff' 30] +PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (0.6) should be ['dddd' 10, 'eeee' 20, 'ffff' 30] +PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (1) should be ['dddd' 10, 'eeee' 20, 'ffff' 30] +PASS Web Animations: property <font-variation-settings> from ['aaaa' 0, 'bbbb' 10, 'cccc' 20] to ['dddd' 10, 'eeee' 20, 'ffff' 30] at (1.5) should be ['dddd' 10, 'eeee' 20, 'ffff' 30] +PASS CSS Transitions: property <font-variation-settings> from ['aaaa' 30, 'bbbb' 20] to ['aaaa' 20, 'bbbb' 30] at (3.40282e+38) should be ['aaaa' -3.40282e+38, 'bbbb' 3.40282e+38] +PASS CSS Transitions with transition: all: property <font-variation-settings> from ['aaaa' 30, 'bbbb' 20] to ['aaaa' 20, 'bbbb' 30] at (3.40282e+38) should be ['aaaa' -3.40282e+38, 'bbbb' 3.40282e+38] +PASS CSS Animations: property <font-variation-settings> from ['aaaa' 30, 'bbbb' 20] to ['aaaa' 20, 'bbbb' 30] at (3.40282e+38) should be ['aaaa' -3.40282e+38, 'bbbb' 3.40282e+38] +PASS Web Animations: property <font-variation-settings> from ['aaaa' 30, 'bbbb' 20] to ['aaaa' 20, 'bbbb' 30] at (3.40282e+38) should be ['aaaa' -3.40282e+38, 'bbbb' 3.40282e+38] Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/animation/grid-template-columns-interpolation-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-grid/animation/grid-template-columns-interpolation-expected.txt index 52ecd70..d0d09c2 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/animation/grid-template-columns-interpolation-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/animation/grid-template-columns-interpolation-expected.txt
@@ -136,30 +136,30 @@ FAIL Web Animations: property <grid-template-columns> from [10px 20px 30px] to [20px 30px 40px] at (0.6) should be [16px 26px 36px] assert_equals: expected "16px 26px 36px " but got "20px 30px 40px " PASS Web Animations: property <grid-template-columns> from [10px 20px 30px] to [20px 30px 40px] at (1) should be [20px 30px 40px] FAIL Web Animations: property <grid-template-columns> from [10px 20px 30px] to [20px 30px 40px] at (2) should be [30px 40px 50px] assert_equals: expected "30px 40px 50px " but got "20px 30px 40px " -FAIL CSS Transitions: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (-1) should be [calc(-20% + 20px) calc(-30% + 40px) 20px] assert_equals: expected "calc ( - 20 % + 20px ) calc ( - 30 % + 40px ) 20px " but got "20 % 30 % 40px " -FAIL CSS Transitions: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (0) should be [10px 20px 30px] assert_equals: expected "10px 20px 30px " but got "20 % 30 % 40px " -FAIL CSS Transitions: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (0.4) should be [calc(8% + 6px) calc(12% + 12px) 34px] assert_equals: expected "calc ( 8 % + 6px ) calc ( 12 % + 12px ) 34px " but got "20 % 30 % 40px " -FAIL CSS Transitions: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (0.6) should be [calc(12% + 4px) calc(18% + 8px) 36px] assert_equals: expected "calc ( 12 % + 4px ) calc ( 18 % + 8px ) 36px " but got "20 % 30 % 40px " +FAIL CSS Transitions: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (-1) should be [calc(20px + -20%) calc(40px + -30%) 20px] assert_equals: expected "calc ( - 20 % + 20px ) calc ( - 30 % + 40px ) 20px " but got "20 % 30 % 40px " +FAIL CSS Transitions: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (0) should be [calc(10px + 0%) calc(20px + 0%) 30px] assert_equals: expected "10px 20px 30px " but got "20 % 30 % 40px " +FAIL CSS Transitions: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (0.4) should be [calc(6px + 8%) calc(12px + 12%) 34px] assert_equals: expected "calc ( 8 % + 6px ) calc ( 12 % + 12px ) 34px " but got "20 % 30 % 40px " +FAIL CSS Transitions: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (0.6) should be [calc(4px + 12%) calc(8px + 18%) 36px] assert_equals: expected "calc ( 12 % + 4px ) calc ( 18 % + 8px ) 36px " but got "20 % 30 % 40px " PASS CSS Transitions: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (1) should be [20% 30% 40px] -FAIL CSS Transitions: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (2) should be [calc(40% - 10px) calc(60% - 20px) 50px] assert_equals: expected "calc ( 40 % - 10px ) calc ( 60 % - 20px ) 50px " but got "20 % 30 % 40px " -FAIL CSS Transitions with transition: all: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (-1) should be [calc(-20% + 20px) calc(-30% + 40px) 20px] assert_equals: expected "calc ( - 20 % + 20px ) calc ( - 30 % + 40px ) 20px " but got "20 % 30 % 40px " -FAIL CSS Transitions with transition: all: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (0) should be [10px 20px 30px] assert_equals: expected "10px 20px 30px " but got "20 % 30 % 40px " -FAIL CSS Transitions with transition: all: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (0.4) should be [calc(8% + 6px) calc(12% + 12px) 34px] assert_equals: expected "calc ( 8 % + 6px ) calc ( 12 % + 12px ) 34px " but got "20 % 30 % 40px " -FAIL CSS Transitions with transition: all: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (0.6) should be [calc(12% + 4px) calc(18% + 8px) 36px] assert_equals: expected "calc ( 12 % + 4px ) calc ( 18 % + 8px ) 36px " but got "20 % 30 % 40px " +FAIL CSS Transitions: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (2) should be [calc(-10px + 40%) calc(-20px + 60%) 50px] assert_equals: expected "calc ( 40 % - 10px ) calc ( 60 % - 20px ) 50px " but got "20 % 30 % 40px " +FAIL CSS Transitions with transition: all: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (-1) should be [calc(20px + -20%) calc(40px + -30%) 20px] assert_equals: expected "calc ( - 20 % + 20px ) calc ( - 30 % + 40px ) 20px " but got "20 % 30 % 40px " +FAIL CSS Transitions with transition: all: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (0) should be [calc(10px + 0%) calc(20px + 0%) 30px] assert_equals: expected "10px 20px 30px " but got "20 % 30 % 40px " +FAIL CSS Transitions with transition: all: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (0.4) should be [calc(6px + 8%) calc(12px + 12%) 34px] assert_equals: expected "calc ( 8 % + 6px ) calc ( 12 % + 12px ) 34px " but got "20 % 30 % 40px " +FAIL CSS Transitions with transition: all: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (0.6) should be [calc(4px + 12%) calc(8px + 18%) 36px] assert_equals: expected "calc ( 12 % + 4px ) calc ( 18 % + 8px ) 36px " but got "20 % 30 % 40px " PASS CSS Transitions with transition: all: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (1) should be [20% 30% 40px] -FAIL CSS Transitions with transition: all: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (2) should be [calc(40% - 10px) calc(60% - 20px) 50px] assert_equals: expected "calc ( 40 % - 10px ) calc ( 60 % - 20px ) 50px " but got "20 % 30 % 40px " -FAIL CSS Animations: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (-1) should be [calc(-20% + 20px) calc(-30% + 40px) 20px] assert_equals: expected "calc ( - 20 % + 20px ) calc ( - 30 % + 40px ) 20px " but got "10px 20px 30px " -PASS CSS Animations: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (0) should be [10px 20px 30px] -FAIL CSS Animations: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (0.4) should be [calc(8% + 6px) calc(12% + 12px) 34px] assert_equals: expected "calc ( 8 % + 6px ) calc ( 12 % + 12px ) 34px " but got "10px 20px 30px " -FAIL CSS Animations: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (0.6) should be [calc(12% + 4px) calc(18% + 8px) 36px] assert_equals: expected "calc ( 12 % + 4px ) calc ( 18 % + 8px ) 36px " but got "20 % 30 % 40px " +FAIL CSS Transitions with transition: all: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (2) should be [calc(-10px + 40%) calc(-20px + 60%) 50px] assert_equals: expected "calc ( 40 % - 10px ) calc ( 60 % - 20px ) 50px " but got "20 % 30 % 40px " +FAIL CSS Animations: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (-1) should be [calc(20px + -20%) calc(40px + -30%) 20px] assert_equals: expected "calc ( - 20 % + 20px ) calc ( - 30 % + 40px ) 20px " but got "10px 20px 30px " +PASS CSS Animations: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (0) should be [calc(10px + 0%) calc(20px + 0%) 30px] +FAIL CSS Animations: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (0.4) should be [calc(6px + 8%) calc(12px + 12%) 34px] assert_equals: expected "calc ( 8 % + 6px ) calc ( 12 % + 12px ) 34px " but got "10px 20px 30px " +FAIL CSS Animations: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (0.6) should be [calc(4px + 12%) calc(8px + 18%) 36px] assert_equals: expected "calc ( 12 % + 4px ) calc ( 18 % + 8px ) 36px " but got "20 % 30 % 40px " PASS CSS Animations: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (1) should be [20% 30% 40px] -FAIL CSS Animations: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (2) should be [calc(40% - 10px) calc(60% - 20px) 50px] assert_equals: expected "calc ( 40 % - 10px ) calc ( 60 % - 20px ) 50px " but got "20 % 30 % 40px " -FAIL Web Animations: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (-1) should be [calc(-20% + 20px) calc(-30% + 40px) 20px] assert_equals: expected "calc ( - 20 % + 20px ) calc ( - 30 % + 40px ) 20px " but got "10px 20px 30px " -PASS Web Animations: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (0) should be [10px 20px 30px] -FAIL Web Animations: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (0.4) should be [calc(8% + 6px) calc(12% + 12px) 34px] assert_equals: expected "calc ( 8 % + 6px ) calc ( 12 % + 12px ) 34px " but got "10px 20px 30px " -FAIL Web Animations: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (0.6) should be [calc(12% + 4px) calc(18% + 8px) 36px] assert_equals: expected "calc ( 12 % + 4px ) calc ( 18 % + 8px ) 36px " but got "20 % 30 % 40px " +FAIL CSS Animations: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (2) should be [calc(-10px + 40%) calc(-20px + 60%) 50px] assert_equals: expected "calc ( 40 % - 10px ) calc ( 60 % - 20px ) 50px " but got "20 % 30 % 40px " +FAIL Web Animations: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (-1) should be [calc(20px + -20%) calc(40px + -30%) 20px] assert_equals: expected "calc ( - 20 % + 20px ) calc ( - 30 % + 40px ) 20px " but got "10px 20px 30px " +PASS Web Animations: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (0) should be [calc(10px + 0%) calc(20px + 0%) 30px] +FAIL Web Animations: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (0.4) should be [calc(6px + 8%) calc(12px + 12%) 34px] assert_equals: expected "calc ( 8 % + 6px ) calc ( 12 % + 12px ) 34px " but got "10px 20px 30px " +FAIL Web Animations: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (0.6) should be [calc(4px + 12%) calc(8px + 18%) 36px] assert_equals: expected "calc ( 12 % + 4px ) calc ( 18 % + 8px ) 36px " but got "20 % 30 % 40px " PASS Web Animations: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (1) should be [20% 30% 40px] -FAIL Web Animations: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (2) should be [calc(40% - 10px) calc(60% - 20px) 50px] assert_equals: expected "calc ( 40 % - 10px ) calc ( 60 % - 20px ) 50px " but got "20 % 30 % 40px " +FAIL Web Animations: property <grid-template-columns> from [10px 20px 30px] to [20% 30% 40px] at (2) should be [calc(-10px + 40%) calc(-20px + 60%) 50px] assert_equals: expected "calc ( 40 % - 10px ) calc ( 60 % - 20px ) 50px " but got "20 % 30 % 40px " FAIL CSS Transitions: property <grid-template-columns> from [1fr 1fr 1fr] to [2fr auto 2fr] at (-1) should be [0fr 1fr 0fr] assert_equals: expected "0fr 1fr 0fr " but got "2fr auto 2fr " FAIL CSS Transitions: property <grid-template-columns> from [1fr 1fr 1fr] to [2fr auto 2fr] at (0) should be [1fr 1fr 1fr] assert_equals: expected "1fr 1fr 1fr " but got "2fr auto 2fr " FAIL CSS Transitions: property <grid-template-columns> from [1fr 1fr 1fr] to [2fr auto 2fr] at (0.4) should be [1.4fr 1fr 1.4fr] assert_equals: expected "1.4fr 1fr 1.4fr " but got "2fr auto 2fr " @@ -256,114 +256,114 @@ FAIL Web Animations: property <grid-template-columns> from [minmax(10px, 1fr) minmax(20px, 2fr)] to [minmax(20px, 2fr) minmax(30px, auto)] at (0.6) should be [minmax(16px, 1.6fr) minmax(26px, auto)] assert_equals: expected "minmax ( 16px , 1.6fr ) minmax ( 26px , auto ) " but got "minmax ( 20px , 2fr ) minmax ( 30px , auto ) " PASS Web Animations: property <grid-template-columns> from [minmax(10px, 1fr) minmax(20px, 2fr)] to [minmax(20px, 2fr) minmax(30px, auto)] at (1) should be [minmax(20px, 2fr) minmax(30px, auto)] FAIL Web Animations: property <grid-template-columns> from [minmax(10px, 1fr) minmax(20px, 2fr)] to [minmax(20px, 2fr) minmax(30px, auto)] at (2) should be [minmax(30px, 3fr) minmax(40px, auto)] assert_equals: expected "minmax ( 30px , 3fr ) minmax ( 40px , auto ) " but got "minmax ( 20px , 2fr ) minmax ( 30px , auto ) " -PASS CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (-0.3) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.3) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.5) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.6) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (1) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (1.5) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (-0.3) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.3) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.5) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.6) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (1) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (1.5) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (-0.3) should be [1fr 2fr 30px 2fr 30px 1fr] -PASS CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0) should be [1fr 2fr 30px 2fr 30px 1fr] -PASS CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.3) should be [1fr 2fr 30px 2fr 30px 1fr] -PASS CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.5) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.6) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (1) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (1.5) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (-0.3) should be [1fr 2fr 30px 2fr 30px 1fr] -PASS Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0) should be [1fr 2fr 30px 2fr 30px 1fr] -PASS Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.3) should be [1fr 2fr 30px 2fr 30px 1fr] -PASS Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.5) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.6) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (1) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (1.5) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (-0.3) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.3) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.5) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.6) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (1) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (1.5) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (-0.3) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.3) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.5) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.6) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (1) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (1.5) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (-0.3) should be [1fr 2fr 30px 2fr 30px 1fr] -PASS CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0) should be [1fr 2fr 30px 2fr 30px 1fr] -PASS CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.3) should be [1fr 2fr 30px 2fr 30px 1fr] -PASS CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.5) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.6) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (1) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (1.5) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (-0.3) should be [1fr 2fr 30px 2fr 30px 1fr] -PASS Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0) should be [1fr 2fr 30px 2fr 30px 1fr] -PASS Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.3) should be [1fr 2fr 30px 2fr 30px 1fr] -PASS Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.5) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.6) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (1) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (1.5) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Transitions: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (-0.3) should be [40px 40px 40px 40px] -PASS CSS Transitions: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0) should be [40px 40px 40px 40px] -PASS CSS Transitions: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.3) should be [40px 40px 40px 40px] -PASS CSS Transitions: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.5) should be [40px 40px 40px 40px] -PASS CSS Transitions: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.6) should be [40px 40px 40px 40px] -PASS CSS Transitions: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (1) should be [40px 40px 40px 40px] -PASS CSS Transitions: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (1.5) should be [40px 40px 40px 40px] -PASS CSS Transitions with transition: all: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (-0.3) should be [40px 40px 40px 40px] -PASS CSS Transitions with transition: all: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0) should be [40px 40px 40px 40px] -PASS CSS Transitions with transition: all: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.3) should be [40px 40px 40px 40px] -PASS CSS Transitions with transition: all: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.5) should be [40px 40px 40px 40px] -PASS CSS Transitions with transition: all: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.6) should be [40px 40px 40px 40px] -PASS CSS Transitions with transition: all: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (1) should be [40px 40px 40px 40px] -PASS CSS Transitions with transition: all: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (1.5) should be [40px 40px 40px 40px] -PASS CSS Animations: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (-0.3) should be [2fr 30px 2fr 30px] -PASS CSS Animations: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0) should be [2fr 30px 2fr 30px] -PASS CSS Animations: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.3) should be [2fr 30px 2fr 30px] -PASS CSS Animations: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.5) should be [40px 40px 40px 40px] -PASS CSS Animations: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.6) should be [40px 40px 40px 40px] -PASS CSS Animations: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (1) should be [40px 40px 40px 40px] -PASS CSS Animations: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (1.5) should be [40px 40px 40px 40px] -PASS Web Animations: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (-0.3) should be [2fr 30px 2fr 30px] -PASS Web Animations: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0) should be [2fr 30px 2fr 30px] -PASS Web Animations: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.3) should be [2fr 30px 2fr 30px] -PASS Web Animations: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.5) should be [40px 40px 40px 40px] -PASS Web Animations: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.6) should be [40px 40px 40px 40px] -PASS Web Animations: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (1) should be [40px 40px 40px 40px] -PASS Web Animations: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (1.5) should be [40px 40px 40px 40px] -FAIL CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (-1) should be [0fr 1fr auto 20px 1fr auto 20px 0fr] assert_equals: expected "0fr 1fr auto 20px 1fr auto 20px 0fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " -FAIL CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0) should be [1fr 2fr auto 30px 2fr auto 30px 1fr] assert_equals: expected "1fr 2fr auto 30px 2fr auto 30px 1fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " -FAIL CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0.4) should be [1.4fr 2.4fr auto 34px 2.4fr auto 34px 1.4fr] assert_equals: expected "1.4fr 2.4fr auto 34px 2.4fr auto 34px 1.4fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " -FAIL CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0.6) should be [1.6fr 2.6fr 30px 36px 2.6fr 30px 36px 1.6fr] assert_equals: expected "1.6fr 2.6fr 30px 36px 2.6fr 30px 36px 1.6fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " -PASS CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (1) should be [2fr 3fr 30px 40px 3fr 30px 40px 2fr] -FAIL CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (2) should be [3fr 4fr 30px 50px 4fr 30px 50px 3fr] assert_equals: expected "3fr 4fr 30px 50px 4fr 30px 50px 3fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " -FAIL CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (-1) should be [0fr 1fr auto 20px 1fr auto 20px 0fr] assert_equals: expected "0fr 1fr auto 20px 1fr auto 20px 0fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " -FAIL CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0) should be [1fr 2fr auto 30px 2fr auto 30px 1fr] assert_equals: expected "1fr 2fr auto 30px 2fr auto 30px 1fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " -FAIL CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0.4) should be [1.4fr 2.4fr auto 34px 2.4fr auto 34px 1.4fr] assert_equals: expected "1.4fr 2.4fr auto 34px 2.4fr auto 34px 1.4fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " -FAIL CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0.6) should be [1.6fr 2.6fr 30px 36px 2.6fr 30px 36px 1.6fr] assert_equals: expected "1.6fr 2.6fr 30px 36px 2.6fr 30px 36px 1.6fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " -PASS CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (1) should be [2fr 3fr 30px 40px 3fr 30px 40px 2fr] -FAIL CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (2) should be [3fr 4fr 30px 50px 4fr 30px 50px 3fr] assert_equals: expected "3fr 4fr 30px 50px 4fr 30px 50px 3fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " -FAIL CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (-1) should be [0fr 1fr auto 20px 1fr auto 20px 0fr] assert_equals: expected "0fr 1fr auto 20px 1fr auto 20px 0fr " but got "1fr 2fr auto 30px 2fr auto 30px 1fr " -PASS CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0) should be [1fr 2fr auto 30px 2fr auto 30px 1fr] -FAIL CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0.4) should be [1.4fr 2.4fr auto 34px 2.4fr auto 34px 1.4fr] assert_equals: expected "1.4fr 2.4fr auto 34px 2.4fr auto 34px 1.4fr " but got "1fr 2fr auto 30px 2fr auto 30px 1fr " -FAIL CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0.6) should be [1.6fr 2.6fr 30px 36px 2.6fr 30px 36px 1.6fr] assert_equals: expected "1.6fr 2.6fr 30px 36px 2.6fr 30px 36px 1.6fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " -PASS CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (1) should be [2fr 3fr 30px 40px 3fr 30px 40px 2fr] -FAIL CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (2) should be [3fr 4fr 30px 50px 4fr 30px 50px 3fr] assert_equals: expected "3fr 4fr 30px 50px 4fr 30px 50px 3fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " -FAIL Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (-1) should be [0fr 1fr auto 20px 1fr auto 20px 0fr] assert_equals: expected "0fr 1fr auto 20px 1fr auto 20px 0fr " but got "1fr 2fr auto 30px 2fr auto 30px 1fr " -PASS Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0) should be [1fr 2fr auto 30px 2fr auto 30px 1fr] -FAIL Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0.4) should be [1.4fr 2.4fr auto 34px 2.4fr auto 34px 1.4fr] assert_equals: expected "1.4fr 2.4fr auto 34px 2.4fr auto 34px 1.4fr " but got "1fr 2fr auto 30px 2fr auto 30px 1fr " -FAIL Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0.6) should be [1.6fr 2.6fr 30px 36px 2.6fr 30px 36px 1.6fr] assert_equals: expected "1.6fr 2.6fr 30px 36px 2.6fr 30px 36px 1.6fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " -PASS Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (1) should be [2fr 3fr 30px 40px 3fr 30px 40px 2fr] -FAIL Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (2) should be [3fr 4fr 30px 50px 4fr 30px 50px 3fr] assert_equals: expected "3fr 4fr 30px 50px 4fr 30px 50px 3fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " +PASS CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (-0.3) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.3) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.5) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.6) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (1) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (1.5) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (-0.3) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.3) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.5) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.6) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (1) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (1.5) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (-0.3) should be [1fr repeat(2, 2fr 30px) 1fr] +PASS CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0) should be [1fr repeat(2, 2fr 30px) 1fr] +PASS CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.3) should be [1fr repeat(2, 2fr 30px) 1fr] +PASS CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.5) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.6) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (1) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (1.5) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (-0.3) should be [1fr repeat(2, 2fr 30px) 1fr] +PASS Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0) should be [1fr repeat(2, 2fr 30px) 1fr] +PASS Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.3) should be [1fr repeat(2, 2fr 30px) 1fr] +PASS Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.5) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.6) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (1) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (1.5) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (-0.3) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.3) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.5) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.6) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (1) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (1.5) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (-0.3) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.3) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.5) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.6) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (1) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (1.5) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (-0.3) should be [1fr repeat(2, 2fr 30px) 1fr] +PASS CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0) should be [1fr repeat(2, 2fr 30px) 1fr] +PASS CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.3) should be [1fr repeat(2, 2fr 30px) 1fr] +PASS CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.5) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.6) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (1) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (1.5) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (-0.3) should be [1fr repeat(2, 2fr 30px) 1fr] +PASS Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0) should be [1fr repeat(2, 2fr 30px) 1fr] +PASS Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.3) should be [1fr repeat(2, 2fr 30px) 1fr] +PASS Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.5) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.6) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (1) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (1.5) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Transitions: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (-0.3) should be [repeat(4, 40px)] +PASS CSS Transitions: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0) should be [repeat(4, 40px)] +PASS CSS Transitions: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.3) should be [repeat(4, 40px)] +PASS CSS Transitions: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.5) should be [repeat(4, 40px)] +PASS CSS Transitions: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.6) should be [repeat(4, 40px)] +PASS CSS Transitions: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (1) should be [repeat(4, 40px)] +PASS CSS Transitions: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (1.5) should be [repeat(4, 40px)] +PASS CSS Transitions with transition: all: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (-0.3) should be [repeat(4, 40px)] +PASS CSS Transitions with transition: all: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0) should be [repeat(4, 40px)] +PASS CSS Transitions with transition: all: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.3) should be [repeat(4, 40px)] +PASS CSS Transitions with transition: all: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.5) should be [repeat(4, 40px)] +PASS CSS Transitions with transition: all: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.6) should be [repeat(4, 40px)] +PASS CSS Transitions with transition: all: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (1) should be [repeat(4, 40px)] +PASS CSS Transitions with transition: all: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (1.5) should be [repeat(4, 40px)] +PASS CSS Animations: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (-0.3) should be [repeat(2, 2fr 30px)] +PASS CSS Animations: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0) should be [repeat(2, 2fr 30px)] +PASS CSS Animations: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.3) should be [repeat(2, 2fr 30px)] +PASS CSS Animations: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.5) should be [repeat(4, 40px)] +PASS CSS Animations: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.6) should be [repeat(4, 40px)] +PASS CSS Animations: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (1) should be [repeat(4, 40px)] +PASS CSS Animations: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (1.5) should be [repeat(4, 40px)] +PASS Web Animations: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (-0.3) should be [repeat(2, 2fr 30px)] +PASS Web Animations: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0) should be [repeat(2, 2fr 30px)] +PASS Web Animations: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.3) should be [repeat(2, 2fr 30px)] +PASS Web Animations: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.5) should be [repeat(4, 40px)] +PASS Web Animations: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.6) should be [repeat(4, 40px)] +PASS Web Animations: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (1) should be [repeat(4, 40px)] +PASS Web Animations: property <grid-template-columns> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (1.5) should be [repeat(4, 40px)] +FAIL CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (-1) should be [0fr repeat(2, 1fr auto 20px) 0fr] assert_equals: expected "0fr 1fr auto 20px 1fr auto 20px 0fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " +FAIL CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0) should be [1fr repeat(2, 2fr auto 30px) 1fr] assert_equals: expected "1fr 2fr auto 30px 2fr auto 30px 1fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " +FAIL CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0.4) should be [1.4fr repeat(2, 2.4fr auto 34px) 1.4fr] assert_equals: expected "1.4fr 2.4fr auto 34px 2.4fr auto 34px 1.4fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " +FAIL CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0.6) should be [1.6fr repeat(2, 2.6fr 30px 36px) 1.6fr] assert_equals: expected "1.6fr 2.6fr 30px 36px 2.6fr 30px 36px 1.6fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " +PASS CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (1) should be [2fr repeat(2, 3fr 30px 40px) 2fr] +FAIL CSS Transitions: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (2) should be [3fr repeat(2, 4fr 30px 50px) 3fr] assert_equals: expected "3fr 4fr 30px 50px 4fr 30px 50px 3fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " +FAIL CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (-1) should be [0fr repeat(2, 1fr auto 20px) 0fr] assert_equals: expected "0fr 1fr auto 20px 1fr auto 20px 0fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " +FAIL CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0) should be [1fr repeat(2, 2fr auto 30px) 1fr] assert_equals: expected "1fr 2fr auto 30px 2fr auto 30px 1fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " +FAIL CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0.4) should be [1.4fr repeat(2, 2.4fr auto 34px) 1.4fr] assert_equals: expected "1.4fr 2.4fr auto 34px 2.4fr auto 34px 1.4fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " +FAIL CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0.6) should be [1.6fr repeat(2, 2.6fr 30px 36px) 1.6fr] assert_equals: expected "1.6fr 2.6fr 30px 36px 2.6fr 30px 36px 1.6fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " +PASS CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (1) should be [2fr repeat(2, 3fr 30px 40px) 2fr] +FAIL CSS Transitions with transition: all: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (2) should be [3fr repeat(2, 4fr 30px 50px) 3fr] assert_equals: expected "3fr 4fr 30px 50px 4fr 30px 50px 3fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " +FAIL CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (-1) should be [0fr repeat(2, 1fr auto 20px) 0fr] assert_equals: expected "0fr 1fr auto 20px 1fr auto 20px 0fr " but got "1fr 2fr auto 30px 2fr auto 30px 1fr " +PASS CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0) should be [1fr repeat(2, 2fr auto 30px) 1fr] +FAIL CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0.4) should be [1.4fr repeat(2, 2.4fr auto 34px) 1.4fr] assert_equals: expected "1.4fr 2.4fr auto 34px 2.4fr auto 34px 1.4fr " but got "1fr 2fr auto 30px 2fr auto 30px 1fr " +FAIL CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0.6) should be [1.6fr repeat(2, 2.6fr 30px 36px) 1.6fr] assert_equals: expected "1.6fr 2.6fr 30px 36px 2.6fr 30px 36px 1.6fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " +PASS CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (1) should be [2fr repeat(2, 3fr 30px 40px) 2fr] +FAIL CSS Animations: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (2) should be [3fr repeat(2, 4fr 30px 50px) 3fr] assert_equals: expected "3fr 4fr 30px 50px 4fr 30px 50px 3fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " +FAIL Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (-1) should be [0fr repeat(2, 1fr auto 20px) 0fr] assert_equals: expected "0fr 1fr auto 20px 1fr auto 20px 0fr " but got "1fr 2fr auto 30px 2fr auto 30px 1fr " +PASS Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0) should be [1fr repeat(2, 2fr auto 30px) 1fr] +FAIL Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0.4) should be [1.4fr repeat(2, 2.4fr auto 34px) 1.4fr] assert_equals: expected "1.4fr 2.4fr auto 34px 2.4fr auto 34px 1.4fr " but got "1fr 2fr auto 30px 2fr auto 30px 1fr " +FAIL Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0.6) should be [1.6fr repeat(2, 2.6fr 30px 36px) 1.6fr] assert_equals: expected "1.6fr 2.6fr 30px 36px 2.6fr 30px 36px 1.6fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " +PASS Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (1) should be [2fr repeat(2, 3fr 30px 40px) 2fr] +FAIL Web Animations: property <grid-template-columns> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (2) should be [3fr repeat(2, 4fr 30px 50px) 3fr] assert_equals: expected "3fr 4fr 30px 50px 4fr 30px 50px 3fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " PASS CSS Transitions: property <grid-template-columns> from [10px repeat(auto-fill, minmax(25px, 1fr)) 10px] to [20px 20px repeat(auto-fill, minmax(30px, 1fr))] at (-0.3) should be [20px 20px repeat(auto-fill, minmax(30px, 1fr))] PASS CSS Transitions: property <grid-template-columns> from [10px repeat(auto-fill, minmax(25px, 1fr)) 10px] to [20px 20px repeat(auto-fill, minmax(30px, 1fr))] at (0) should be [20px 20px repeat(auto-fill, minmax(30px, 1fr))] PASS CSS Transitions: property <grid-template-columns> from [10px repeat(auto-fill, minmax(25px, 1fr)) 10px] to [20px 20px repeat(auto-fill, minmax(30px, 1fr))] at (0.3) should be [20px 20px repeat(auto-fill, minmax(30px, 1fr))]
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/animation/grid-template-rows-interpolation-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-grid/animation/grid-template-rows-interpolation-expected.txt index b11bbee..737697d4 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/animation/grid-template-rows-interpolation-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/animation/grid-template-rows-interpolation-expected.txt
@@ -136,30 +136,30 @@ FAIL Web Animations: property <grid-template-rows> from [10px 20px 30px] to [20px 30px 40px] at (0.6) should be [16px 26px 36px] assert_equals: expected "16px 26px 36px " but got "20px 30px 40px " PASS Web Animations: property <grid-template-rows> from [10px 20px 30px] to [20px 30px 40px] at (1) should be [20px 30px 40px] FAIL Web Animations: property <grid-template-rows> from [10px 20px 30px] to [20px 30px 40px] at (2) should be [30px 40px 50px] assert_equals: expected "30px 40px 50px " but got "20px 30px 40px " -FAIL CSS Transitions: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (-1) should be [calc(-20% + 20px) calc(-30% + 40px) 20px] assert_equals: expected "calc ( - 20 % + 20px ) calc ( - 30 % + 40px ) 20px " but got "20 % 30 % 40px " -FAIL CSS Transitions: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (0) should be [10px 20px 30px] assert_equals: expected "10px 20px 30px " but got "20 % 30 % 40px " -FAIL CSS Transitions: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (0.4) should be [calc(8% + 6px) calc(12% + 12px) 34px] assert_equals: expected "calc ( 8 % + 6px ) calc ( 12 % + 12px ) 34px " but got "20 % 30 % 40px " -FAIL CSS Transitions: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (0.6) should be [calc(12% + 4px) calc(18% + 8px) 36px] assert_equals: expected "calc ( 12 % + 4px ) calc ( 18 % + 8px ) 36px " but got "20 % 30 % 40px " +FAIL CSS Transitions: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (-1) should be [calc(20px + -20%) calc(40px + -30%) 20px] assert_equals: expected "calc ( - 20 % + 20px ) calc ( - 30 % + 40px ) 20px " but got "20 % 30 % 40px " +FAIL CSS Transitions: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (0) should be [calc(10px + 0%) calc(20px + 0%) 30px] assert_equals: expected "10px 20px 30px " but got "20 % 30 % 40px " +FAIL CSS Transitions: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (0.4) should be [calc(6px + 8%) calc(12px + 12%) 34px] assert_equals: expected "calc ( 8 % + 6px ) calc ( 12 % + 12px ) 34px " but got "20 % 30 % 40px " +FAIL CSS Transitions: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (0.6) should be [calc(4px + 12%) calc(8px + 18%) 36px] assert_equals: expected "calc ( 12 % + 4px ) calc ( 18 % + 8px ) 36px " but got "20 % 30 % 40px " PASS CSS Transitions: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (1) should be [20% 30% 40px] -FAIL CSS Transitions: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (2) should be [calc(40% - 10px) calc(60% - 20px) 50px] assert_equals: expected "calc ( 40 % - 10px ) calc ( 60 % - 20px ) 50px " but got "20 % 30 % 40px " -FAIL CSS Transitions with transition: all: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (-1) should be [calc(-20% + 20px) calc(-30% + 40px) 20px] assert_equals: expected "calc ( - 20 % + 20px ) calc ( - 30 % + 40px ) 20px " but got "20 % 30 % 40px " -FAIL CSS Transitions with transition: all: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (0) should be [10px 20px 30px] assert_equals: expected "10px 20px 30px " but got "20 % 30 % 40px " -FAIL CSS Transitions with transition: all: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (0.4) should be [calc(8% + 6px) calc(12% + 12px) 34px] assert_equals: expected "calc ( 8 % + 6px ) calc ( 12 % + 12px ) 34px " but got "20 % 30 % 40px " -FAIL CSS Transitions with transition: all: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (0.6) should be [calc(12% + 4px) calc(18% + 8px) 36px] assert_equals: expected "calc ( 12 % + 4px ) calc ( 18 % + 8px ) 36px " but got "20 % 30 % 40px " +FAIL CSS Transitions: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (2) should be [calc(-10px + 40%) calc(-20px + 60%) 50px] assert_equals: expected "calc ( 40 % - 10px ) calc ( 60 % - 20px ) 50px " but got "20 % 30 % 40px " +FAIL CSS Transitions with transition: all: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (-1) should be [calc(20px + -20%) calc(40px + -30%) 20px] assert_equals: expected "calc ( - 20 % + 20px ) calc ( - 30 % + 40px ) 20px " but got "20 % 30 % 40px " +FAIL CSS Transitions with transition: all: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (0) should be [calc(10px + 0%) calc(20px + 0%) 30px] assert_equals: expected "10px 20px 30px " but got "20 % 30 % 40px " +FAIL CSS Transitions with transition: all: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (0.4) should be [calc(6px + 8%) calc(12px + 12%) 34px] assert_equals: expected "calc ( 8 % + 6px ) calc ( 12 % + 12px ) 34px " but got "20 % 30 % 40px " +FAIL CSS Transitions with transition: all: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (0.6) should be [calc(4px + 12%) calc(8px + 18%) 36px] assert_equals: expected "calc ( 12 % + 4px ) calc ( 18 % + 8px ) 36px " but got "20 % 30 % 40px " PASS CSS Transitions with transition: all: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (1) should be [20% 30% 40px] -FAIL CSS Transitions with transition: all: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (2) should be [calc(40% - 10px) calc(60% - 20px) 50px] assert_equals: expected "calc ( 40 % - 10px ) calc ( 60 % - 20px ) 50px " but got "20 % 30 % 40px " -FAIL CSS Animations: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (-1) should be [calc(-20% + 20px) calc(-30% + 40px) 20px] assert_equals: expected "calc ( - 20 % + 20px ) calc ( - 30 % + 40px ) 20px " but got "10px 20px 30px " -PASS CSS Animations: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (0) should be [10px 20px 30px] -FAIL CSS Animations: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (0.4) should be [calc(8% + 6px) calc(12% + 12px) 34px] assert_equals: expected "calc ( 8 % + 6px ) calc ( 12 % + 12px ) 34px " but got "10px 20px 30px " -FAIL CSS Animations: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (0.6) should be [calc(12% + 4px) calc(18% + 8px) 36px] assert_equals: expected "calc ( 12 % + 4px ) calc ( 18 % + 8px ) 36px " but got "20 % 30 % 40px " +FAIL CSS Transitions with transition: all: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (2) should be [calc(-10px + 40%) calc(-20px + 60%) 50px] assert_equals: expected "calc ( 40 % - 10px ) calc ( 60 % - 20px ) 50px " but got "20 % 30 % 40px " +FAIL CSS Animations: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (-1) should be [calc(20px + -20%) calc(40px + -30%) 20px] assert_equals: expected "calc ( - 20 % + 20px ) calc ( - 30 % + 40px ) 20px " but got "10px 20px 30px " +PASS CSS Animations: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (0) should be [calc(10px + 0%) calc(20px + 0%) 30px] +FAIL CSS Animations: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (0.4) should be [calc(6px + 8%) calc(12px + 12%) 34px] assert_equals: expected "calc ( 8 % + 6px ) calc ( 12 % + 12px ) 34px " but got "10px 20px 30px " +FAIL CSS Animations: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (0.6) should be [calc(4px + 12%) calc(8px + 18%) 36px] assert_equals: expected "calc ( 12 % + 4px ) calc ( 18 % + 8px ) 36px " but got "20 % 30 % 40px " PASS CSS Animations: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (1) should be [20% 30% 40px] -FAIL CSS Animations: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (2) should be [calc(40% - 10px) calc(60% - 20px) 50px] assert_equals: expected "calc ( 40 % - 10px ) calc ( 60 % - 20px ) 50px " but got "20 % 30 % 40px " -FAIL Web Animations: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (-1) should be [calc(-20% + 20px) calc(-30% + 40px) 20px] assert_equals: expected "calc ( - 20 % + 20px ) calc ( - 30 % + 40px ) 20px " but got "10px 20px 30px " -PASS Web Animations: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (0) should be [10px 20px 30px] -FAIL Web Animations: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (0.4) should be [calc(8% + 6px) calc(12% + 12px) 34px] assert_equals: expected "calc ( 8 % + 6px ) calc ( 12 % + 12px ) 34px " but got "10px 20px 30px " -FAIL Web Animations: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (0.6) should be [calc(12% + 4px) calc(18% + 8px) 36px] assert_equals: expected "calc ( 12 % + 4px ) calc ( 18 % + 8px ) 36px " but got "20 % 30 % 40px " +FAIL CSS Animations: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (2) should be [calc(-10px + 40%) calc(-20px + 60%) 50px] assert_equals: expected "calc ( 40 % - 10px ) calc ( 60 % - 20px ) 50px " but got "20 % 30 % 40px " +FAIL Web Animations: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (-1) should be [calc(20px + -20%) calc(40px + -30%) 20px] assert_equals: expected "calc ( - 20 % + 20px ) calc ( - 30 % + 40px ) 20px " but got "10px 20px 30px " +PASS Web Animations: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (0) should be [calc(10px + 0%) calc(20px + 0%) 30px] +FAIL Web Animations: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (0.4) should be [calc(6px + 8%) calc(12px + 12%) 34px] assert_equals: expected "calc ( 8 % + 6px ) calc ( 12 % + 12px ) 34px " but got "10px 20px 30px " +FAIL Web Animations: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (0.6) should be [calc(4px + 12%) calc(8px + 18%) 36px] assert_equals: expected "calc ( 12 % + 4px ) calc ( 18 % + 8px ) 36px " but got "20 % 30 % 40px " PASS Web Animations: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (1) should be [20% 30% 40px] -FAIL Web Animations: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (2) should be [calc(40% - 10px) calc(60% - 20px) 50px] assert_equals: expected "calc ( 40 % - 10px ) calc ( 60 % - 20px ) 50px " but got "20 % 30 % 40px " +FAIL Web Animations: property <grid-template-rows> from [10px 20px 30px] to [20% 30% 40px] at (2) should be [calc(-10px + 40%) calc(-20px + 60%) 50px] assert_equals: expected "calc ( 40 % - 10px ) calc ( 60 % - 20px ) 50px " but got "20 % 30 % 40px " FAIL CSS Transitions: property <grid-template-rows> from [1fr 1fr 1fr] to [2fr auto 2fr] at (-1) should be [0fr 1fr 0fr] assert_equals: expected "0fr 1fr 0fr " but got "2fr auto 2fr " FAIL CSS Transitions: property <grid-template-rows> from [1fr 1fr 1fr] to [2fr auto 2fr] at (0) should be [1fr 1fr 1fr] assert_equals: expected "1fr 1fr 1fr " but got "2fr auto 2fr " FAIL CSS Transitions: property <grid-template-rows> from [1fr 1fr 1fr] to [2fr auto 2fr] at (0.4) should be [1.4fr 1fr 1.4fr] assert_equals: expected "1.4fr 1fr 1.4fr " but got "2fr auto 2fr " @@ -256,114 +256,114 @@ FAIL Web Animations: property <grid-template-rows> from [minmax(10px, 1fr) minmax(20px, 2fr)] to [minmax(20px, 2fr) minmax(30px, auto)] at (0.6) should be [minmax(16px, 1.6fr) minmax(26px, auto)] assert_equals: expected "minmax ( 16px , 1.6fr ) minmax ( 26px , auto ) " but got "minmax ( 20px , 2fr ) minmax ( 30px , auto ) " PASS Web Animations: property <grid-template-rows> from [minmax(10px, 1fr) minmax(20px, 2fr)] to [minmax(20px, 2fr) minmax(30px, auto)] at (1) should be [minmax(20px, 2fr) minmax(30px, auto)] FAIL Web Animations: property <grid-template-rows> from [minmax(10px, 1fr) minmax(20px, 2fr)] to [minmax(20px, 2fr) minmax(30px, auto)] at (2) should be [minmax(30px, 3fr) minmax(40px, auto)] assert_equals: expected "minmax ( 30px , 3fr ) minmax ( 40px , auto ) " but got "minmax ( 20px , 2fr ) minmax ( 30px , auto ) " -PASS CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (-0.3) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.3) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.5) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.6) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (1) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (1.5) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (-0.3) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.3) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.5) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.6) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (1) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (1.5) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (-0.3) should be [1fr 2fr 30px 2fr 30px 1fr] -PASS CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0) should be [1fr 2fr 30px 2fr 30px 1fr] -PASS CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.3) should be [1fr 2fr 30px 2fr 30px 1fr] -PASS CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.5) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.6) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (1) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (1.5) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (-0.3) should be [1fr 2fr 30px 2fr 30px 1fr] -PASS Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0) should be [1fr 2fr 30px 2fr 30px 1fr] -PASS Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.3) should be [1fr 2fr 30px 2fr 30px 1fr] -PASS Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.5) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.6) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (1) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (1.5) should be [2fr 3fr 40px 50px 3fr 40px 50px 2fr] -PASS CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (-0.3) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.3) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.5) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.6) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (1) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (1.5) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (-0.3) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.3) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.5) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.6) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (1) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (1.5) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (-0.3) should be [1fr 2fr 30px 2fr 30px 1fr] -PASS CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0) should be [1fr 2fr 30px 2fr 30px 1fr] -PASS CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.3) should be [1fr 2fr 30px 2fr 30px 1fr] -PASS CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.5) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.6) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (1) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (1.5) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (-0.3) should be [1fr 2fr 30px 2fr 30px 1fr] -PASS Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0) should be [1fr 2fr 30px 2fr 30px 1fr] -PASS Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.3) should be [1fr 2fr 30px 2fr 30px 1fr] -PASS Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.5) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.6) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (1) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (1.5) should be [2fr 3fr 40px 3fr 40px 3fr 40px 2fr] -PASS CSS Transitions: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (-0.3) should be [40px 40px 40px 40px] -PASS CSS Transitions: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0) should be [40px 40px 40px 40px] -PASS CSS Transitions: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.3) should be [40px 40px 40px 40px] -PASS CSS Transitions: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.5) should be [40px 40px 40px 40px] -PASS CSS Transitions: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.6) should be [40px 40px 40px 40px] -PASS CSS Transitions: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (1) should be [40px 40px 40px 40px] -PASS CSS Transitions: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (1.5) should be [40px 40px 40px 40px] -PASS CSS Transitions with transition: all: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (-0.3) should be [40px 40px 40px 40px] -PASS CSS Transitions with transition: all: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0) should be [40px 40px 40px 40px] -PASS CSS Transitions with transition: all: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.3) should be [40px 40px 40px 40px] -PASS CSS Transitions with transition: all: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.5) should be [40px 40px 40px 40px] -PASS CSS Transitions with transition: all: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.6) should be [40px 40px 40px 40px] -PASS CSS Transitions with transition: all: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (1) should be [40px 40px 40px 40px] -PASS CSS Transitions with transition: all: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (1.5) should be [40px 40px 40px 40px] -PASS CSS Animations: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (-0.3) should be [2fr 30px 2fr 30px] -PASS CSS Animations: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0) should be [2fr 30px 2fr 30px] -PASS CSS Animations: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.3) should be [2fr 30px 2fr 30px] -PASS CSS Animations: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.5) should be [40px 40px 40px 40px] -PASS CSS Animations: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.6) should be [40px 40px 40px 40px] -PASS CSS Animations: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (1) should be [40px 40px 40px 40px] -PASS CSS Animations: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (1.5) should be [40px 40px 40px 40px] -PASS Web Animations: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (-0.3) should be [2fr 30px 2fr 30px] -PASS Web Animations: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0) should be [2fr 30px 2fr 30px] -PASS Web Animations: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.3) should be [2fr 30px 2fr 30px] -PASS Web Animations: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.5) should be [40px 40px 40px 40px] -PASS Web Animations: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.6) should be [40px 40px 40px 40px] -PASS Web Animations: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (1) should be [40px 40px 40px 40px] -PASS Web Animations: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (1.5) should be [40px 40px 40px 40px] -FAIL CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (-1) should be [0fr 1fr auto 20px 1fr auto 20px 0fr] assert_equals: expected "0fr 1fr auto 20px 1fr auto 20px 0fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " -FAIL CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0) should be [1fr 2fr auto 30px 2fr auto 30px 1fr] assert_equals: expected "1fr 2fr auto 30px 2fr auto 30px 1fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " -FAIL CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0.4) should be [1.4fr 2.4fr auto 34px 2.4fr auto 34px 1.4fr] assert_equals: expected "1.4fr 2.4fr auto 34px 2.4fr auto 34px 1.4fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " -FAIL CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0.6) should be [1.6fr 2.6fr 30px 36px 2.6fr 30px 36px 1.6fr] assert_equals: expected "1.6fr 2.6fr 30px 36px 2.6fr 30px 36px 1.6fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " -PASS CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (1) should be [2fr 3fr 30px 40px 3fr 30px 40px 2fr] -FAIL CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (2) should be [3fr 4fr 30px 50px 4fr 30px 50px 3fr] assert_equals: expected "3fr 4fr 30px 50px 4fr 30px 50px 3fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " -FAIL CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (-1) should be [0fr 1fr auto 20px 1fr auto 20px 0fr] assert_equals: expected "0fr 1fr auto 20px 1fr auto 20px 0fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " -FAIL CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0) should be [1fr 2fr auto 30px 2fr auto 30px 1fr] assert_equals: expected "1fr 2fr auto 30px 2fr auto 30px 1fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " -FAIL CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0.4) should be [1.4fr 2.4fr auto 34px 2.4fr auto 34px 1.4fr] assert_equals: expected "1.4fr 2.4fr auto 34px 2.4fr auto 34px 1.4fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " -FAIL CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0.6) should be [1.6fr 2.6fr 30px 36px 2.6fr 30px 36px 1.6fr] assert_equals: expected "1.6fr 2.6fr 30px 36px 2.6fr 30px 36px 1.6fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " -PASS CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (1) should be [2fr 3fr 30px 40px 3fr 30px 40px 2fr] -FAIL CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (2) should be [3fr 4fr 30px 50px 4fr 30px 50px 3fr] assert_equals: expected "3fr 4fr 30px 50px 4fr 30px 50px 3fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " -FAIL CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (-1) should be [0fr 1fr auto 20px 1fr auto 20px 0fr] assert_equals: expected "0fr 1fr auto 20px 1fr auto 20px 0fr " but got "1fr 2fr auto 30px 2fr auto 30px 1fr " -PASS CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0) should be [1fr 2fr auto 30px 2fr auto 30px 1fr] -FAIL CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0.4) should be [1.4fr 2.4fr auto 34px 2.4fr auto 34px 1.4fr] assert_equals: expected "1.4fr 2.4fr auto 34px 2.4fr auto 34px 1.4fr " but got "1fr 2fr auto 30px 2fr auto 30px 1fr " -FAIL CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0.6) should be [1.6fr 2.6fr 30px 36px 2.6fr 30px 36px 1.6fr] assert_equals: expected "1.6fr 2.6fr 30px 36px 2.6fr 30px 36px 1.6fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " -PASS CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (1) should be [2fr 3fr 30px 40px 3fr 30px 40px 2fr] -FAIL CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (2) should be [3fr 4fr 30px 50px 4fr 30px 50px 3fr] assert_equals: expected "3fr 4fr 30px 50px 4fr 30px 50px 3fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " -FAIL Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (-1) should be [0fr 1fr auto 20px 1fr auto 20px 0fr] assert_equals: expected "0fr 1fr auto 20px 1fr auto 20px 0fr " but got "1fr 2fr auto 30px 2fr auto 30px 1fr " -PASS Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0) should be [1fr 2fr auto 30px 2fr auto 30px 1fr] -FAIL Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0.4) should be [1.4fr 2.4fr auto 34px 2.4fr auto 34px 1.4fr] assert_equals: expected "1.4fr 2.4fr auto 34px 2.4fr auto 34px 1.4fr " but got "1fr 2fr auto 30px 2fr auto 30px 1fr " -FAIL Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0.6) should be [1.6fr 2.6fr 30px 36px 2.6fr 30px 36px 1.6fr] assert_equals: expected "1.6fr 2.6fr 30px 36px 2.6fr 30px 36px 1.6fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " -PASS Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (1) should be [2fr 3fr 30px 40px 3fr 30px 40px 2fr] -FAIL Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (2) should be [3fr 4fr 30px 50px 4fr 30px 50px 3fr] assert_equals: expected "3fr 4fr 30px 50px 4fr 30px 50px 3fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " +PASS CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (-0.3) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.3) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.5) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.6) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (1) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (1.5) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (-0.3) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.3) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.5) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.6) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (1) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (1.5) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (-0.3) should be [1fr repeat(2, 2fr 30px) 1fr] +PASS CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0) should be [1fr repeat(2, 2fr 30px) 1fr] +PASS CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.3) should be [1fr repeat(2, 2fr 30px) 1fr] +PASS CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.5) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.6) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (1) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (1.5) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (-0.3) should be [1fr repeat(2, 2fr 30px) 1fr] +PASS Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0) should be [1fr repeat(2, 2fr 30px) 1fr] +PASS Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.3) should be [1fr repeat(2, 2fr 30px) 1fr] +PASS Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.5) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (0.6) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (1) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(2, 3fr 40px 50px) 2fr] at (1.5) should be [2fr repeat(2, 3fr 40px 50px) 2fr] +PASS CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (-0.3) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.3) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.5) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.6) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (1) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (1.5) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (-0.3) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.3) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.5) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.6) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (1) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (1.5) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (-0.3) should be [1fr repeat(2, 2fr 30px) 1fr] +PASS CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0) should be [1fr repeat(2, 2fr 30px) 1fr] +PASS CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.3) should be [1fr repeat(2, 2fr 30px) 1fr] +PASS CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.5) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.6) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (1) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (1.5) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (-0.3) should be [1fr repeat(2, 2fr 30px) 1fr] +PASS Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0) should be [1fr repeat(2, 2fr 30px) 1fr] +PASS Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.3) should be [1fr repeat(2, 2fr 30px) 1fr] +PASS Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.5) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (0.6) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (1) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr 30px) 1fr] to [2fr repeat(3, 3fr 40px) 2fr] at (1.5) should be [2fr repeat(3, 3fr 40px) 2fr] +PASS CSS Transitions: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (-0.3) should be [repeat(4, 40px)] +PASS CSS Transitions: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0) should be [repeat(4, 40px)] +PASS CSS Transitions: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.3) should be [repeat(4, 40px)] +PASS CSS Transitions: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.5) should be [repeat(4, 40px)] +PASS CSS Transitions: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.6) should be [repeat(4, 40px)] +PASS CSS Transitions: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (1) should be [repeat(4, 40px)] +PASS CSS Transitions: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (1.5) should be [repeat(4, 40px)] +PASS CSS Transitions with transition: all: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (-0.3) should be [repeat(4, 40px)] +PASS CSS Transitions with transition: all: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0) should be [repeat(4, 40px)] +PASS CSS Transitions with transition: all: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.3) should be [repeat(4, 40px)] +PASS CSS Transitions with transition: all: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.5) should be [repeat(4, 40px)] +PASS CSS Transitions with transition: all: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.6) should be [repeat(4, 40px)] +PASS CSS Transitions with transition: all: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (1) should be [repeat(4, 40px)] +PASS CSS Transitions with transition: all: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (1.5) should be [repeat(4, 40px)] +PASS CSS Animations: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (-0.3) should be [repeat(2, 2fr 30px)] +PASS CSS Animations: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0) should be [repeat(2, 2fr 30px)] +PASS CSS Animations: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.3) should be [repeat(2, 2fr 30px)] +PASS CSS Animations: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.5) should be [repeat(4, 40px)] +PASS CSS Animations: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.6) should be [repeat(4, 40px)] +PASS CSS Animations: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (1) should be [repeat(4, 40px)] +PASS CSS Animations: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (1.5) should be [repeat(4, 40px)] +PASS Web Animations: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (-0.3) should be [repeat(2, 2fr 30px)] +PASS Web Animations: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0) should be [repeat(2, 2fr 30px)] +PASS Web Animations: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.3) should be [repeat(2, 2fr 30px)] +PASS Web Animations: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.5) should be [repeat(4, 40px)] +PASS Web Animations: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (0.6) should be [repeat(4, 40px)] +PASS Web Animations: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (1) should be [repeat(4, 40px)] +PASS Web Animations: property <grid-template-rows> from [repeat(2, 2fr 30px)] to [repeat(4, 40px)] at (1.5) should be [repeat(4, 40px)] +FAIL CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (-1) should be [0fr repeat(2, 1fr auto 20px) 0fr] assert_equals: expected "0fr 1fr auto 20px 1fr auto 20px 0fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " +FAIL CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0) should be [1fr repeat(2, 2fr auto 30px) 1fr] assert_equals: expected "1fr 2fr auto 30px 2fr auto 30px 1fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " +FAIL CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0.4) should be [1.4fr repeat(2, 2.4fr auto 34px) 1.4fr] assert_equals: expected "1.4fr 2.4fr auto 34px 2.4fr auto 34px 1.4fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " +FAIL CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0.6) should be [1.6fr repeat(2, 2.6fr 30px 36px) 1.6fr] assert_equals: expected "1.6fr 2.6fr 30px 36px 2.6fr 30px 36px 1.6fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " +PASS CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (1) should be [2fr repeat(2, 3fr 30px 40px) 2fr] +FAIL CSS Transitions: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (2) should be [3fr repeat(2, 4fr 30px 50px) 3fr] assert_equals: expected "3fr 4fr 30px 50px 4fr 30px 50px 3fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " +FAIL CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (-1) should be [0fr repeat(2, 1fr auto 20px) 0fr] assert_equals: expected "0fr 1fr auto 20px 1fr auto 20px 0fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " +FAIL CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0) should be [1fr repeat(2, 2fr auto 30px) 1fr] assert_equals: expected "1fr 2fr auto 30px 2fr auto 30px 1fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " +FAIL CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0.4) should be [1.4fr repeat(2, 2.4fr auto 34px) 1.4fr] assert_equals: expected "1.4fr 2.4fr auto 34px 2.4fr auto 34px 1.4fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " +FAIL CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0.6) should be [1.6fr repeat(2, 2.6fr 30px 36px) 1.6fr] assert_equals: expected "1.6fr 2.6fr 30px 36px 2.6fr 30px 36px 1.6fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " +PASS CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (1) should be [2fr repeat(2, 3fr 30px 40px) 2fr] +FAIL CSS Transitions with transition: all: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (2) should be [3fr repeat(2, 4fr 30px 50px) 3fr] assert_equals: expected "3fr 4fr 30px 50px 4fr 30px 50px 3fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " +FAIL CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (-1) should be [0fr repeat(2, 1fr auto 20px) 0fr] assert_equals: expected "0fr 1fr auto 20px 1fr auto 20px 0fr " but got "1fr 2fr auto 30px 2fr auto 30px 1fr " +PASS CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0) should be [1fr repeat(2, 2fr auto 30px) 1fr] +FAIL CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0.4) should be [1.4fr repeat(2, 2.4fr auto 34px) 1.4fr] assert_equals: expected "1.4fr 2.4fr auto 34px 2.4fr auto 34px 1.4fr " but got "1fr 2fr auto 30px 2fr auto 30px 1fr " +FAIL CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0.6) should be [1.6fr repeat(2, 2.6fr 30px 36px) 1.6fr] assert_equals: expected "1.6fr 2.6fr 30px 36px 2.6fr 30px 36px 1.6fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " +PASS CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (1) should be [2fr repeat(2, 3fr 30px 40px) 2fr] +FAIL CSS Animations: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (2) should be [3fr repeat(2, 4fr 30px 50px) 3fr] assert_equals: expected "3fr 4fr 30px 50px 4fr 30px 50px 3fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " +FAIL Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (-1) should be [0fr repeat(2, 1fr auto 20px) 0fr] assert_equals: expected "0fr 1fr auto 20px 1fr auto 20px 0fr " but got "1fr 2fr auto 30px 2fr auto 30px 1fr " +PASS Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0) should be [1fr repeat(2, 2fr auto 30px) 1fr] +FAIL Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0.4) should be [1.4fr repeat(2, 2.4fr auto 34px) 1.4fr] assert_equals: expected "1.4fr 2.4fr auto 34px 2.4fr auto 34px 1.4fr " but got "1fr 2fr auto 30px 2fr auto 30px 1fr " +FAIL Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (0.6) should be [1.6fr repeat(2, 2.6fr 30px 36px) 1.6fr] assert_equals: expected "1.6fr 2.6fr 30px 36px 2.6fr 30px 36px 1.6fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " +PASS Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (1) should be [2fr repeat(2, 3fr 30px 40px) 2fr] +FAIL Web Animations: property <grid-template-rows> from [1fr repeat(2, 2fr auto 30px) 1fr] to [2fr repeat(2, 3fr 30px 40px) 2fr] at (2) should be [3fr repeat(2, 4fr 30px 50px) 3fr] assert_equals: expected "3fr 4fr 30px 50px 4fr 30px 50px 3fr " but got "2fr 3fr 30px 40px 3fr 30px 40px 2fr " PASS CSS Transitions: property <grid-template-rows> from [10px repeat(auto-fill, minmax(25px, 1fr)) 10px] to [20px 20px repeat(auto-fill, minmax(30px, 1fr))] at (-0.3) should be [20px 20px repeat(auto-fill, minmax(30px, 1fr))] PASS CSS Transitions: property <grid-template-rows> from [10px repeat(auto-fill, minmax(25px, 1fr)) 10px] to [20px 20px repeat(auto-fill, minmax(30px, 1fr))] at (0) should be [20px 20px repeat(auto-fill, minmax(30px, 1fr))] PASS CSS Transitions: property <grid-template-rows> from [10px repeat(auto-fill, minmax(25px, 1fr)) 10px] to [20px 20px repeat(auto-fill, minmax(30px, 1fr))] at (0.3) should be [20px 20px repeat(auto-fill, minmax(30px, 1fr))]
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/list-interpolation-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/list-interpolation-expected.txt index 29ac41d1..c3140b4 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/list-interpolation-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/list-interpolation-expected.txt
@@ -4,50 +4,50 @@ PASS CSS Transitions with transition: all: property <transform> from [none] to [none] at (0.25) should be [none] FAIL CSS Animations: property <transform> from [none] to [none] at (0.25) should be [none] assert_equals: expected "none " but got "matrix ( 1 , 0 , 0 , 1 , 0 , 0 ) " FAIL Web Animations: property <transform> from [none] to [none] at (0.25) should be [none] assert_equals: expected "none " but got "matrix ( 1 , 0 , 0 , 1 , 0 , 0 ) " -PASS CSS Transitions: property <transform> from [none] to [translate(200px) rotate(720deg)] at (0.25) should be [matrix(-1, 1.22465e-16, -1.22465e-16, -1, 50, 0)] -PASS CSS Transitions with transition: all: property <transform> from [none] to [translate(200px) rotate(720deg)] at (0.25) should be [matrix(-1, 1.22465e-16, -1.22465e-16, -1, 50, 0)] -PASS CSS Animations: property <transform> from [none] to [translate(200px) rotate(720deg)] at (0.25) should be [matrix(-1, 1.22465e-16, -1.22465e-16, -1, 50, 0)] -PASS Web Animations: property <transform> from [none] to [translate(200px) rotate(720deg)] at (0.25) should be [matrix(-1, 1.22465e-16, -1.22465e-16, -1, 50, 0)] -PASS CSS Transitions: property <transform> from [translate(200px) rotate(720deg)] to [none] at (0.25) should be [matrix(-1, 3.67394e-16, -3.67394e-16, -1, 150, 0)] -PASS CSS Transitions with transition: all: property <transform> from [translate(200px) rotate(720deg)] to [none] at (0.25) should be [matrix(-1, 3.67394e-16, -3.67394e-16, -1, 150, 0)] -PASS CSS Animations: property <transform> from [translate(200px) rotate(720deg)] to [none] at (0.25) should be [matrix(-1, 3.67394e-16, -3.67394e-16, -1, 150, 0)] -PASS Web Animations: property <transform> from [translate(200px) rotate(720deg)] to [none] at (0.25) should be [matrix(-1, 3.67394e-16, -3.67394e-16, -1, 150, 0)] -PASS CSS Transitions: property <transform> from [translate(100px)] to [translate(200px) rotate(720deg)] at (0.25) should be [matrix(-1, 1.22465e-16, -1.22465e-16, -1, 125, 0)] -PASS CSS Transitions with transition: all: property <transform> from [translate(100px)] to [translate(200px) rotate(720deg)] at (0.25) should be [matrix(-1, 1.22465e-16, -1.22465e-16, -1, 125, 0)] -PASS CSS Animations: property <transform> from [translate(100px)] to [translate(200px) rotate(720deg)] at (0.25) should be [matrix(-1, 1.22465e-16, -1.22465e-16, -1, 125, 0)] -PASS Web Animations: property <transform> from [translate(100px)] to [translate(200px) rotate(720deg)] at (0.25) should be [matrix(-1, 1.22465e-16, -1.22465e-16, -1, 125, 0)] -PASS CSS Transitions: property <transform> from [translate(100px) rotate(720deg)] to [translate(200px)] at (0.25) should be [matrix(-1, 3.67394e-16, -3.67394e-16, -1, 125, 0)] -PASS CSS Transitions with transition: all: property <transform> from [translate(100px) rotate(720deg)] to [translate(200px)] at (0.25) should be [matrix(-1, 3.67394e-16, -3.67394e-16, -1, 125, 0)] -PASS CSS Animations: property <transform> from [translate(100px) rotate(720deg)] to [translate(200px)] at (0.25) should be [matrix(-1, 3.67394e-16, -3.67394e-16, -1, 125, 0)] -PASS Web Animations: property <transform> from [translate(100px) rotate(720deg)] to [translate(200px)] at (0.25) should be [matrix(-1, 3.67394e-16, -3.67394e-16, -1, 125, 0)] -PASS CSS Transitions: property <transform> from [scale(2) rotate(360deg) translate(100px) matrix(1, 0, 0, 1, 100, 0) skew(0deg)] to [scale(3) rotate(1080deg) translate(200px) matrix(1, 0, 0, 1, 0, 200) skew(720deg)] at (0.25) should be [matrix(-2.25, 8.26637e-16, -5.51091e-16, -2.25, -450, -112.5)] -PASS CSS Transitions with transition: all: property <transform> from [scale(2) rotate(360deg) translate(100px) matrix(1, 0, 0, 1, 100, 0) skew(0deg)] to [scale(3) rotate(1080deg) translate(200px) matrix(1, 0, 0, 1, 0, 200) skew(720deg)] at (0.25) should be [matrix(-2.25, 8.26637e-16, -5.51091e-16, -2.25, -450, -112.5)] -PASS CSS Animations: property <transform> from [scale(2) rotate(360deg) translate(100px) matrix(1, 0, 0, 1, 100, 0) skew(0deg)] to [scale(3) rotate(1080deg) translate(200px) matrix(1, 0, 0, 1, 0, 200) skew(720deg)] at (0.25) should be [matrix(-2.25, 8.26637e-16, -5.51091e-16, -2.25, -450, -112.5)] -PASS Web Animations: property <transform> from [scale(2) rotate(360deg) translate(100px) matrix(1, 0, 0, 1, 100, 0) skew(0deg)] to [scale(3) rotate(1080deg) translate(200px) matrix(1, 0, 0, 1, 0, 200) skew(720deg)] at (0.25) should be [matrix(-2.25, 8.26637e-16, -5.51091e-16, -2.25, -450, -112.5)] -PASS CSS Transitions: property <transform> from [translateX(100px) scaleX(3) translate(500px) scale(2)] to [translateY(200px) scale(5) translateX(100px) scaleY(3)] at (0.25) should be [matrix(6.125, 0, 0, 4.5, 1475, 50)] -PASS CSS Transitions with transition: all: property <transform> from [translateX(100px) scaleX(3) translate(500px) scale(2)] to [translateY(200px) scale(5) translateX(100px) scaleY(3)] at (0.25) should be [matrix(6.125, 0, 0, 4.5, 1475, 50)] -PASS CSS Animations: property <transform> from [translateX(100px) scaleX(3) translate(500px) scale(2)] to [translateY(200px) scale(5) translateX(100px) scaleY(3)] at (0.25) should be [matrix(6.125, 0, 0, 4.5, 1475, 50)] -PASS Web Animations: property <transform> from [translateX(100px) scaleX(3) translate(500px) scale(2)] to [translateY(200px) scale(5) translateX(100px) scaleY(3)] at (0.25) should be [matrix(6.125, 0, 0, 4.5, 1475, 50)] -PASS CSS Transitions: property <transform> from [rotateX(90deg) translateX(100px)] to [rotate3d(50, 0, 0, 180deg) translateY(200px)] at (0.25) should be [matrix3d(1, 0, 0, 0, 0, -0.382683, 0.92388, 0, 0, -0.92388, -0.382683, 0, 75, -19.1342, 46.194, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotateX(90deg) translateX(100px)] to [rotate3d(50, 0, 0, 180deg) translateY(200px)] at (0.25) should be [matrix3d(1, 0, 0, 0, 0, -0.382683, 0.92388, 0, 0, -0.92388, -0.382683, 0, 75, -19.1342, 46.194, 1)] -PASS CSS Animations: property <transform> from [rotateX(90deg) translateX(100px)] to [rotate3d(50, 0, 0, 180deg) translateY(200px)] at (0.25) should be [matrix3d(1, 0, 0, 0, 0, -0.382683, 0.92388, 0, 0, -0.92388, -0.382683, 0, 75, -19.1342, 46.194, 1)] -PASS Web Animations: property <transform> from [rotateX(90deg) translateX(100px)] to [rotate3d(50, 0, 0, 180deg) translateY(200px)] at (0.25) should be [matrix3d(1, 0, 0, 0, 0, -0.382683, 0.92388, 0, 0, -0.92388, -0.382683, 0, 75, -19.1342, 46.194, 1)] -PASS CSS Transitions: property <transform> from [rotateX(90deg) translateX(100px)] to [rotateY(0deg) translateY(200px)] at (0.25) should be [matrix3d(1, 0, 0, 0, 0, 0.382683, 0.92388, 0, 0, -0.92388, 0.382683, 0, 75, 19.1342, 46.194, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotateX(90deg) translateX(100px)] to [rotateY(0deg) translateY(200px)] at (0.25) should be [matrix3d(1, 0, 0, 0, 0, 0.382683, 0.92388, 0, 0, -0.92388, 0.382683, 0, 75, 19.1342, 46.194, 1)] -PASS CSS Animations: property <transform> from [rotateX(90deg) translateX(100px)] to [rotateY(0deg) translateY(200px)] at (0.25) should be [matrix3d(1, 0, 0, 0, 0, 0.382683, 0.92388, 0, 0, -0.92388, 0.382683, 0, 75, 19.1342, 46.194, 1)] -PASS Web Animations: property <transform> from [rotateX(90deg) translateX(100px)] to [rotateY(0deg) translateY(200px)] at (0.25) should be [matrix3d(1, 0, 0, 0, 0, 0.382683, 0.92388, 0, 0, -0.92388, 0.382683, 0, 75, 19.1342, 46.194, 1)] -PASS CSS Transitions: property <transform> from [rotate3d(1, 1, 1, -60deg) translateX(100px)] to [rotate3d(2, 2, 2, 60deg) translateY(200px)] at (0.25) should be [matrix3d(0.910684, -0.244017, 0.333333, 0, 0.333333, 0.910684, -0.244017, 0, -0.244017, 0.333333, 0.910684, 0, 84.9679, 27.2329, 12.7992, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotate3d(1, 1, 1, -60deg) translateX(100px)] to [rotate3d(2, 2, 2, 60deg) translateY(200px)] at (0.25) should be [matrix3d(0.910684, -0.244017, 0.333333, 0, 0.333333, 0.910684, -0.244017, 0, -0.244017, 0.333333, 0.910684, 0, 84.9679, 27.2329, 12.7992, 1)] -PASS CSS Animations: property <transform> from [rotate3d(1, 1, 1, -60deg) translateX(100px)] to [rotate3d(2, 2, 2, 60deg) translateY(200px)] at (0.25) should be [matrix3d(0.910684, -0.244017, 0.333333, 0, 0.333333, 0.910684, -0.244017, 0, -0.244017, 0.333333, 0.910684, 0, 84.9679, 27.2329, 12.7992, 1)] -PASS Web Animations: property <transform> from [rotate3d(1, 1, 1, -60deg) translateX(100px)] to [rotate3d(2, 2, 2, 60deg) translateY(200px)] at (0.25) should be [matrix3d(0.910684, -0.244017, 0.333333, 0, 0.333333, 0.910684, -0.244017, 0, -0.244017, 0.333333, 0.910684, 0, 84.9679, 27.2329, 12.7992, 1)] -PASS CSS Transitions: property <transform> from [rotate3d(1, 0, 0, 360deg) translateX(100px)] to [rotate3d(0, 1, 0, -720deg) translateY(200px)] at (0.25) should be [matrix(1, 0, 0, 1, 75, 50)] -PASS CSS Transitions with transition: all: property <transform> from [rotate3d(1, 0, 0, 360deg) translateX(100px)] to [rotate3d(0, 1, 0, -720deg) translateY(200px)] at (0.25) should be [matrix(1, 0, 0, 1, 75, 50)] -PASS CSS Animations: property <transform> from [rotate3d(1, 0, 0, 360deg) translateX(100px)] to [rotate3d(0, 1, 0, -720deg) translateY(200px)] at (0.25) should be [matrix(1, 0, 0, 1, 75, 50)] -PASS Web Animations: property <transform> from [rotate3d(1, 0, 0, 360deg) translateX(100px)] to [rotate3d(0, 1, 0, -720deg) translateY(200px)] at (0.25) should be [matrix(1, 0, 0, 1, 75, 50)] -PASS CSS Transitions: property <transform> from [rotate(0deg) translate(100px)] to [rotate(720deg) scale(2) translate(200px)] at (0.25) should be [matrix(-1.25, 1.53081e-16, -1.53081e-16, -1.25, -175, 2.14313e-14)] -PASS CSS Transitions with transition: all: property <transform> from [rotate(0deg) translate(100px)] to [rotate(720deg) scale(2) translate(200px)] at (0.25) should be [matrix(-1.25, 1.53081e-16, -1.53081e-16, -1.25, -175, 2.14313e-14)] -PASS CSS Animations: property <transform> from [rotate(0deg) translate(100px)] to [rotate(720deg) scale(2) translate(200px)] at (0.25) should be [matrix(-1.25, 1.53081e-16, -1.53081e-16, -1.25, -175, 2.14313e-14)] -PASS Web Animations: property <transform> from [rotate(0deg) translate(100px)] to [rotate(720deg) scale(2) translate(200px)] at (0.25) should be [matrix(-1.25, 1.53081e-16, -1.53081e-16, -1.25, -175, 2.14313e-14)] +PASS CSS Transitions: property <transform> from [none] to [translate(200px) rotate(720deg)] at (0.25) should be [translate(50px) rotate(180deg)] +PASS CSS Transitions with transition: all: property <transform> from [none] to [translate(200px) rotate(720deg)] at (0.25) should be [translate(50px) rotate(180deg)] +PASS CSS Animations: property <transform> from [none] to [translate(200px) rotate(720deg)] at (0.25) should be [translate(50px) rotate(180deg)] +PASS Web Animations: property <transform> from [none] to [translate(200px) rotate(720deg)] at (0.25) should be [translate(50px) rotate(180deg)] +PASS CSS Transitions: property <transform> from [translate(200px) rotate(720deg)] to [none] at (0.25) should be [translate(150px) rotate(540deg)] +PASS CSS Transitions with transition: all: property <transform> from [translate(200px) rotate(720deg)] to [none] at (0.25) should be [translate(150px) rotate(540deg)] +PASS CSS Animations: property <transform> from [translate(200px) rotate(720deg)] to [none] at (0.25) should be [translate(150px) rotate(540deg)] +PASS Web Animations: property <transform> from [translate(200px) rotate(720deg)] to [none] at (0.25) should be [translate(150px) rotate(540deg)] +PASS CSS Transitions: property <transform> from [translate(100px)] to [translate(200px) rotate(720deg)] at (0.25) should be [translate(125px) rotate(180deg)] +PASS CSS Transitions with transition: all: property <transform> from [translate(100px)] to [translate(200px) rotate(720deg)] at (0.25) should be [translate(125px) rotate(180deg)] +PASS CSS Animations: property <transform> from [translate(100px)] to [translate(200px) rotate(720deg)] at (0.25) should be [translate(125px) rotate(180deg)] +PASS Web Animations: property <transform> from [translate(100px)] to [translate(200px) rotate(720deg)] at (0.25) should be [translate(125px) rotate(180deg)] +PASS CSS Transitions: property <transform> from [translate(100px) rotate(720deg)] to [translate(200px)] at (0.25) should be [translate(125px) rotate(540deg)] +PASS CSS Transitions with transition: all: property <transform> from [translate(100px) rotate(720deg)] to [translate(200px)] at (0.25) should be [translate(125px) rotate(540deg)] +PASS CSS Animations: property <transform> from [translate(100px) rotate(720deg)] to [translate(200px)] at (0.25) should be [translate(125px) rotate(540deg)] +PASS Web Animations: property <transform> from [translate(100px) rotate(720deg)] to [translate(200px)] at (0.25) should be [translate(125px) rotate(540deg)] +PASS CSS Transitions: property <transform> from [scale(2) rotate(360deg) translate(100px) matrix(1, 0, 0, 1, 100, 0) skew(0deg)] to [scale(3) rotate(1080deg) translate(200px) matrix(1, 0, 0, 1, 0, 200) skew(720deg)] at (0.25) should be [scale(2.25) rotate(540deg) translate(125px) matrix(1, 0, 0, 1, 75, 50) skew(180deg)] +PASS CSS Transitions with transition: all: property <transform> from [scale(2) rotate(360deg) translate(100px) matrix(1, 0, 0, 1, 100, 0) skew(0deg)] to [scale(3) rotate(1080deg) translate(200px) matrix(1, 0, 0, 1, 0, 200) skew(720deg)] at (0.25) should be [scale(2.25) rotate(540deg) translate(125px) matrix(1, 0, 0, 1, 75, 50) skew(180deg)] +PASS CSS Animations: property <transform> from [scale(2) rotate(360deg) translate(100px) matrix(1, 0, 0, 1, 100, 0) skew(0deg)] to [scale(3) rotate(1080deg) translate(200px) matrix(1, 0, 0, 1, 0, 200) skew(720deg)] at (0.25) should be [scale(2.25) rotate(540deg) translate(125px) matrix(1, 0, 0, 1, 75, 50) skew(180deg)] +PASS Web Animations: property <transform> from [scale(2) rotate(360deg) translate(100px) matrix(1, 0, 0, 1, 100, 0) skew(0deg)] to [scale(3) rotate(1080deg) translate(200px) matrix(1, 0, 0, 1, 0, 200) skew(720deg)] at (0.25) should be [scale(2.25) rotate(540deg) translate(125px) matrix(1, 0, 0, 1, 75, 50) skew(180deg)] +PASS CSS Transitions: property <transform> from [translateX(100px) scaleX(3) translate(500px) scale(2)] to [translateY(200px) scale(5) translateX(100px) scaleY(3)] at (0.25) should be [translate(75px, 50px) scale(3.5, 2) translate(400px, 0px) scale(1.75, 2.25)] +PASS CSS Transitions with transition: all: property <transform> from [translateX(100px) scaleX(3) translate(500px) scale(2)] to [translateY(200px) scale(5) translateX(100px) scaleY(3)] at (0.25) should be [translate(75px, 50px) scale(3.5, 2) translate(400px, 0px) scale(1.75, 2.25)] +PASS CSS Animations: property <transform> from [translateX(100px) scaleX(3) translate(500px) scale(2)] to [translateY(200px) scale(5) translateX(100px) scaleY(3)] at (0.25) should be [translate(75px, 50px) scale(3.5, 2) translate(400px, 0px) scale(1.75, 2.25)] +PASS Web Animations: property <transform> from [translateX(100px) scaleX(3) translate(500px) scale(2)] to [translateY(200px) scale(5) translateX(100px) scaleY(3)] at (0.25) should be [translate(75px, 50px) scale(3.5, 2) translate(400px, 0px) scale(1.75, 2.25)] +PASS CSS Transitions: property <transform> from [rotateX(90deg) translateX(100px)] to [rotate3d(50, 0, 0, 180deg) translateY(200px)] at (0.25) should be [rotateX(112.5deg) translate(75px, 50px)] +PASS CSS Transitions with transition: all: property <transform> from [rotateX(90deg) translateX(100px)] to [rotate3d(50, 0, 0, 180deg) translateY(200px)] at (0.25) should be [rotateX(112.5deg) translate(75px, 50px)] +PASS CSS Animations: property <transform> from [rotateX(90deg) translateX(100px)] to [rotate3d(50, 0, 0, 180deg) translateY(200px)] at (0.25) should be [rotateX(112.5deg) translate(75px, 50px)] +PASS Web Animations: property <transform> from [rotateX(90deg) translateX(100px)] to [rotate3d(50, 0, 0, 180deg) translateY(200px)] at (0.25) should be [rotateX(112.5deg) translate(75px, 50px)] +PASS CSS Transitions: property <transform> from [rotateX(90deg) translateX(100px)] to [rotateY(0deg) translateY(200px)] at (0.25) should be [rotateX(67.5deg) translate(75px, 50px)] +PASS CSS Transitions with transition: all: property <transform> from [rotateX(90deg) translateX(100px)] to [rotateY(0deg) translateY(200px)] at (0.25) should be [rotateX(67.5deg) translate(75px, 50px)] +PASS CSS Animations: property <transform> from [rotateX(90deg) translateX(100px)] to [rotateY(0deg) translateY(200px)] at (0.25) should be [rotateX(67.5deg) translate(75px, 50px)] +PASS Web Animations: property <transform> from [rotateX(90deg) translateX(100px)] to [rotateY(0deg) translateY(200px)] at (0.25) should be [rotateX(67.5deg) translate(75px, 50px)] +PASS CSS Transitions: property <transform> from [rotate3d(1, 1, 1, -60deg) translateX(100px)] to [rotate3d(2, 2, 2, 60deg) translateY(200px)] at (0.25) should be [rotate3d(1, 1, 1, -30deg) translate(75px, 50px)] +PASS CSS Transitions with transition: all: property <transform> from [rotate3d(1, 1, 1, -60deg) translateX(100px)] to [rotate3d(2, 2, 2, 60deg) translateY(200px)] at (0.25) should be [rotate3d(1, 1, 1, -30deg) translate(75px, 50px)] +PASS CSS Animations: property <transform> from [rotate3d(1, 1, 1, -60deg) translateX(100px)] to [rotate3d(2, 2, 2, 60deg) translateY(200px)] at (0.25) should be [rotate3d(1, 1, 1, -30deg) translate(75px, 50px)] +PASS Web Animations: property <transform> from [rotate3d(1, 1, 1, -60deg) translateX(100px)] to [rotate3d(2, 2, 2, 60deg) translateY(200px)] at (0.25) should be [rotate3d(1, 1, 1, -30deg) translate(75px, 50px)] +PASS CSS Transitions: property <transform> from [rotate3d(1, 0, 0, 360deg) translateX(100px)] to [rotate3d(0, 1, 0, -720deg) translateY(200px)] at (0.25) should be [rotate3d(0, 0, 1, 0deg) translate(75px, 50px)] +PASS CSS Transitions with transition: all: property <transform> from [rotate3d(1, 0, 0, 360deg) translateX(100px)] to [rotate3d(0, 1, 0, -720deg) translateY(200px)] at (0.25) should be [rotate3d(0, 0, 1, 0deg) translate(75px, 50px)] +PASS CSS Animations: property <transform> from [rotate3d(1, 0, 0, 360deg) translateX(100px)] to [rotate3d(0, 1, 0, -720deg) translateY(200px)] at (0.25) should be [rotate3d(0, 0, 1, 0deg) translate(75px, 50px)] +PASS Web Animations: property <transform> from [rotate3d(1, 0, 0, 360deg) translateX(100px)] to [rotate3d(0, 1, 0, -720deg) translateY(200px)] at (0.25) should be [rotate3d(0, 0, 1, 0deg) translate(75px, 50px)] +PASS CSS Transitions: property <transform> from [rotate(0deg) translate(100px)] to [rotate(720deg) scale(2) translate(200px)] at (0.25) should be [rotate(180deg) matrix(1.25, 0, 0, 1.25, 175, 0)] +PASS CSS Transitions with transition: all: property <transform> from [rotate(0deg) translate(100px)] to [rotate(720deg) scale(2) translate(200px)] at (0.25) should be [rotate(180deg) matrix(1.25, 0, 0, 1.25, 175, 0)] +PASS CSS Animations: property <transform> from [rotate(0deg) translate(100px)] to [rotate(720deg) scale(2) translate(200px)] at (0.25) should be [rotate(180deg) matrix(1.25, 0, 0, 1.25, 175, 0)] +PASS Web Animations: property <transform> from [rotate(0deg) translate(100px)] to [rotate(720deg) scale(2) translate(200px)] at (0.25) should be [rotate(180deg) matrix(1.25, 0, 0, 1.25, 175, 0)] PASS CSS Transitions: property <transform> from [scale(2) rotate(0deg) translate(100px)] to [rotate(720deg) scale(2) translate(200px)] at (0.25) should be [matrix(2, 0, 0, 2, 250, 0)] PASS CSS Transitions with transition: all: property <transform> from [scale(2) rotate(0deg) translate(100px)] to [rotate(720deg) scale(2) translate(200px)] at (0.25) should be [matrix(2, 0, 0, 2, 250, 0)] PASS CSS Animations: property <transform> from [scale(2) rotate(0deg) translate(100px)] to [rotate(720deg) scale(2) translate(200px)] at (0.25) should be [matrix(2, 0, 0, 2, 250, 0)] @@ -56,25 +56,25 @@ PASS CSS Transitions with transition: all: property <transform> from [scale(2) rotate(0deg)] to [rotate(720deg) scale(2) translate(200px)] at (0.25) should be [matrix(2, 0, 0, 2, 100, 0)] PASS CSS Animations: property <transform> from [scale(2) rotate(0deg)] to [rotate(720deg) scale(2) translate(200px)] at (0.25) should be [matrix(2, 0, 0, 2, 100, 0)] PASS Web Animations: property <transform> from [scale(2) rotate(0deg)] to [rotate(720deg) scale(2) translate(200px)] at (0.25) should be [matrix(2, 0, 0, 2, 100, 0)] -PASS CSS Transitions: property <transform> from [rotate(0deg) scaleX(1)] to [rotate(720deg) translateX(0px) scaleX(2)] at (0.25) should be [matrix(-1.25, 1.53081e-16, -1.22465e-16, -1, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [rotate(0deg) scaleX(1)] to [rotate(720deg) translateX(0px) scaleX(2)] at (0.25) should be [matrix(-1.25, 1.53081e-16, -1.22465e-16, -1, 0, 0)] -PASS CSS Animations: property <transform> from [rotate(0deg) scaleX(1)] to [rotate(720deg) translateX(0px) scaleX(2)] at (0.25) should be [matrix(-1.25, 1.53081e-16, -1.22465e-16, -1, 0, 0)] -PASS Web Animations: property <transform> from [rotate(0deg) scaleX(1)] to [rotate(720deg) translateX(0px) scaleX(2)] at (0.25) should be [matrix(-1.25, 1.53081e-16, -1.22465e-16, -1, 0, 0)] -PASS CSS Transitions: property <transform> from [rotate(720deg) translateX(0px) scaleX(2)] to [rotate(0deg) scaleX(1)] at (0.25) should be [matrix(-1.75, 6.4294e-16, -3.67394e-16, -1, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [rotate(720deg) translateX(0px) scaleX(2)] to [rotate(0deg) scaleX(1)] at (0.25) should be [matrix(-1.75, 6.4294e-16, -3.67394e-16, -1, 0, 0)] -PASS CSS Animations: property <transform> from [rotate(720deg) translateX(0px) scaleX(2)] to [rotate(0deg) scaleX(1)] at (0.25) should be [matrix(-1.75, 6.4294e-16, -3.67394e-16, -1, 0, 0)] -PASS Web Animations: property <transform> from [rotate(720deg) translateX(0px) scaleX(2)] to [rotate(0deg) scaleX(1)] at (0.25) should be [matrix(-1.75, 6.4294e-16, -3.67394e-16, -1, 0, 0)] -PASS CSS Transitions: property <transform> from [scaleX(-3) scaleY(2)] to [scaleY(-3) translateX(0px) scaleX(2)] at (0.25) should be [matrix(-2.5, 0, 0, 0, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [scaleX(-3) scaleY(2)] to [scaleY(-3) translateX(0px) scaleX(2)] at (0.25) should be [matrix(-2.5, 0, 0, 0, 0, 0)] -PASS CSS Animations: property <transform> from [scaleX(-3) scaleY(2)] to [scaleY(-3) translateX(0px) scaleX(2)] at (0.25) should be [matrix(-2.5, 0, 0, 0, 0, 0)] -PASS Web Animations: property <transform> from [scaleX(-3) scaleY(2)] to [scaleY(-3) translateX(0px) scaleX(2)] at (0.25) should be [matrix(-2.5, 0, 0, 0, 0, 0)] -PASS CSS Transitions: property <transform> from [scaleY(-3) translateX(0px) scaleX(2)] to [scaleX(-3) scaleY(2)] at (0.25) should be [matrix(0, 0, 0, -2.5, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [scaleY(-3) translateX(0px) scaleX(2)] to [scaleX(-3) scaleY(2)] at (0.25) should be [matrix(0, 0, 0, -2.5, 0, 0)] -PASS CSS Animations: property <transform> from [scaleY(-3) translateX(0px) scaleX(2)] to [scaleX(-3) scaleY(2)] at (0.25) should be [matrix(0, 0, 0, -2.5, 0, 0)] -PASS Web Animations: property <transform> from [scaleY(-3) translateX(0px) scaleX(2)] to [scaleX(-3) scaleY(2)] at (0.25) should be [matrix(0, 0, 0, -2.5, 0, 0)] -PASS CSS Transitions: property <transform> from [scaleY(-3) translateX(0px)] to [scaleX(-3) scaleY(2)] at (0.25) should be [matrix(0, 0, 0, -2.5, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [scaleY(-3) translateX(0px)] to [scaleX(-3) scaleY(2)] at (0.25) should be [matrix(0, 0, 0, -2.5, 0, 0)] -PASS CSS Animations: property <transform> from [scaleY(-3) translateX(0px)] to [scaleX(-3) scaleY(2)] at (0.25) should be [matrix(0, 0, 0, -2.5, 0, 0)] -PASS Web Animations: property <transform> from [scaleY(-3) translateX(0px)] to [scaleX(-3) scaleY(2)] at (0.25) should be [matrix(0, 0, 0, -2.5, 0, 0)] +PASS CSS Transitions: property <transform> from [rotate(0deg) scaleX(1)] to [rotate(720deg) translateX(0px) scaleX(2)] at (0.25) should be [rotate(180deg) matrix(1.25, 0, 0, 1, 0, 0)] +PASS CSS Transitions with transition: all: property <transform> from [rotate(0deg) scaleX(1)] to [rotate(720deg) translateX(0px) scaleX(2)] at (0.25) should be [rotate(180deg) matrix(1.25, 0, 0, 1, 0, 0)] +PASS CSS Animations: property <transform> from [rotate(0deg) scaleX(1)] to [rotate(720deg) translateX(0px) scaleX(2)] at (0.25) should be [rotate(180deg) matrix(1.25, 0, 0, 1, 0, 0)] +PASS Web Animations: property <transform> from [rotate(0deg) scaleX(1)] to [rotate(720deg) translateX(0px) scaleX(2)] at (0.25) should be [rotate(180deg) matrix(1.25, 0, 0, 1, 0, 0)] +PASS CSS Transitions: property <transform> from [rotate(720deg) translateX(0px) scaleX(2)] to [rotate(0deg) scaleX(1)] at (0.25) should be [rotate(540deg) matrix(1.75, 0, 0, 1, 0, 0)] +PASS CSS Transitions with transition: all: property <transform> from [rotate(720deg) translateX(0px) scaleX(2)] to [rotate(0deg) scaleX(1)] at (0.25) should be [rotate(540deg) matrix(1.75, 0, 0, 1, 0, 0)] +PASS CSS Animations: property <transform> from [rotate(720deg) translateX(0px) scaleX(2)] to [rotate(0deg) scaleX(1)] at (0.25) should be [rotate(540deg) matrix(1.75, 0, 0, 1, 0, 0)] +PASS Web Animations: property <transform> from [rotate(720deg) translateX(0px) scaleX(2)] to [rotate(0deg) scaleX(1)] at (0.25) should be [rotate(540deg) matrix(1.75, 0, 0, 1, 0, 0)] +PASS CSS Transitions: property <transform> from [scaleX(-3) scaleY(2)] to [scaleY(-3) translateX(0px) scaleX(2)] at (0.25) should be [scale(-2, 0) matrix(1.25, 0, 0, 1.75, 0, 0)] +PASS CSS Transitions with transition: all: property <transform> from [scaleX(-3) scaleY(2)] to [scaleY(-3) translateX(0px) scaleX(2)] at (0.25) should be [scale(-2, 0) matrix(1.25, 0, 0, 1.75, 0, 0)] +PASS CSS Animations: property <transform> from [scaleX(-3) scaleY(2)] to [scaleY(-3) translateX(0px) scaleX(2)] at (0.25) should be [scale(-2, 0) matrix(1.25, 0, 0, 1.75, 0, 0)] +PASS Web Animations: property <transform> from [scaleX(-3) scaleY(2)] to [scaleY(-3) translateX(0px) scaleX(2)] at (0.25) should be [scale(-2, 0) matrix(1.25, 0, 0, 1.75, 0, 0)] +PASS CSS Transitions: property <transform> from [scaleY(-3) translateX(0px) scaleX(2)] to [scaleX(-3) scaleY(2)] at (0.25) should be [scale(0, -2) matrix(1.75, 0, 0, 1.25, 0, 0)] +PASS CSS Transitions with transition: all: property <transform> from [scaleY(-3) translateX(0px) scaleX(2)] to [scaleX(-3) scaleY(2)] at (0.25) should be [scale(0, -2) matrix(1.75, 0, 0, 1.25, 0, 0)] +PASS CSS Animations: property <transform> from [scaleY(-3) translateX(0px) scaleX(2)] to [scaleX(-3) scaleY(2)] at (0.25) should be [scale(0, -2) matrix(1.75, 0, 0, 1.25, 0, 0)] +PASS Web Animations: property <transform> from [scaleY(-3) translateX(0px) scaleX(2)] to [scaleX(-3) scaleY(2)] at (0.25) should be [scale(0, -2) matrix(1.75, 0, 0, 1.25, 0, 0)] +PASS CSS Transitions: property <transform> from [scaleY(-3) translateX(0px)] to [scaleX(-3) scaleY(2)] at (0.25) should be [scale(0, -2) matrix(1, 0, 0, 1.25, 0, 0)] +PASS CSS Transitions with transition: all: property <transform> from [scaleY(-3) translateX(0px)] to [scaleX(-3) scaleY(2)] at (0.25) should be [scale(0, -2) matrix(1, 0, 0, 1.25, 0, 0)] +PASS CSS Animations: property <transform> from [scaleY(-3) translateX(0px)] to [scaleX(-3) scaleY(2)] at (0.25) should be [scale(0, -2) matrix(1, 0, 0, 1.25, 0, 0)] +PASS Web Animations: property <transform> from [scaleY(-3) translateX(0px)] to [scaleX(-3) scaleY(2)] at (0.25) should be [scale(0, -2) matrix(1, 0, 0, 1.25, 0, 0)] Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/transform-interpolation-001-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/transform-interpolation-001-expected.txt index fc3be7f..dd58e6a6 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/transform-interpolation-001-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/transform-interpolation-001-expected.txt
@@ -1,412 +1,412 @@ This is a testharness.js-based test. Found 408 tests; 400 PASS, 8 FAIL, 0 TIMEOUT, 0 NOTRUN. -PASS CSS Transitions: property <transform> from [perspective(400px)] to [perspective(500px)] at (-1) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.00333333, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [perspective(400px)] to [perspective(500px)] at (0) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.0025, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [perspective(400px)] to [perspective(500px)] at (0.25) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.00235294, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [perspective(400px)] to [perspective(500px)] at (0.75) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.00210526, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [perspective(400px)] to [perspective(500px)] at (1) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.002, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [perspective(400px)] to [perspective(500px)] at (2) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.00166667, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [perspective(400px)] to [perspective(500px)] at (-1) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.00333333, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [perspective(400px)] to [perspective(500px)] at (0) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.0025, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [perspective(400px)] to [perspective(500px)] at (0.25) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.00235294, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [perspective(400px)] to [perspective(500px)] at (0.75) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.00210526, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [perspective(400px)] to [perspective(500px)] at (1) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.002, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [perspective(400px)] to [perspective(500px)] at (2) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.00166667, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [perspective(400px)] to [perspective(500px)] at (-1) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.00333333, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [perspective(400px)] to [perspective(500px)] at (0) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.0025, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [perspective(400px)] to [perspective(500px)] at (0.25) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.00235294, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [perspective(400px)] to [perspective(500px)] at (0.75) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.00210526, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [perspective(400px)] to [perspective(500px)] at (1) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.002, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [perspective(400px)] to [perspective(500px)] at (2) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.00166667, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [perspective(400px)] to [perspective(500px)] at (-1) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.00333333, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [perspective(400px)] to [perspective(500px)] at (0) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.0025, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [perspective(400px)] to [perspective(500px)] at (0.25) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.00235294, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [perspective(400px)] to [perspective(500px)] at (0.75) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.00210526, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [perspective(400px)] to [perspective(500px)] at (1) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.002, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [perspective(400px)] to [perspective(500px)] at (2) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.00166667, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (-1) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.00333333, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (0) should be [matrix3d(1, 0, 0, 0, 0.648361, 1, 0, 0, 0, 0, 1, -0.0025, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (0.25) should be [matrix3d(1, 0, 0, 0, -0.0664682, 1, 0, 0, 0, 0, 1, -0.00235294, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (0.75) should be [matrix3d(1, 0, 0, 0, -4.44598, 1, 0, 0, 0, 0, 1, -0.00210526, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (1) should be [matrix3d(1, 0, 0, 0, 2.23716, 1, 0, 0, 0, 0, 1, -0.002, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (2) should be [matrix3d(1, 0, 0, 0, -6.40533, 1, 0, 0, 0, 0, 1, -0.00166667, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (-1) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.00333333, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (0) should be [matrix3d(1, 0, 0, 0, 0.648361, 1, 0, 0, 0, 0, 1, -0.0025, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (0.25) should be [matrix3d(1, 0, 0, 0, -0.0664682, 1, 0, 0, 0, 0, 1, -0.00235294, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (0.75) should be [matrix3d(1, 0, 0, 0, -4.44598, 1, 0, 0, 0, 0, 1, -0.00210526, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (1) should be [matrix3d(1, 0, 0, 0, 2.23716, 1, 0, 0, 0, 0, 1, -0.002, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (2) should be [matrix3d(1, 0, 0, 0, -6.40533, 1, 0, 0, 0, 0, 1, -0.00166667, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (-1) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.00333333, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (0) should be [matrix3d(1, 0, 0, 0, 0.648361, 1, 0, 0, 0, 0, 1, -0.0025, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (0.25) should be [matrix3d(1, 0, 0, 0, -0.0664682, 1, 0, 0, 0, 0, 1, -0.00235294, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (0.75) should be [matrix3d(1, 0, 0, 0, -4.44598, 1, 0, 0, 0, 0, 1, -0.00210526, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (1) should be [matrix3d(1, 0, 0, 0, 2.23716, 1, 0, 0, 0, 0, 1, -0.002, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (2) should be [matrix3d(1, 0, 0, 0, -6.40533, 1, 0, 0, 0, 0, 1, -0.00166667, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (-1) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.00333333, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (0) should be [matrix3d(1, 0, 0, 0, 0.648361, 1, 0, 0, 0, 0, 1, -0.0025, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (0.25) should be [matrix3d(1, 0, 0, 0, -0.0664682, 1, 0, 0, 0, 0, 1, -0.00235294, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (0.75) should be [matrix3d(1, 0, 0, 0, -4.44598, 1, 0, 0, 0, 0, 1, -0.00210526, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (1) should be [matrix3d(1, 0, 0, 0, 2.23716, 1, 0, 0, 0, 0, 1, -0.002, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (2) should be [matrix3d(1, 0, 0, 0, -6.40533, 1, 0, 0, 0, 0, 1, -0.00166667, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (-1) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0.00333333, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (0) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.0025, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (0.25) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1.25, -0.00235294, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (0.75) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1.75, -0.00210526, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (1) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, -0.002, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (2) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3, -0.00166667, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (-1) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0.00333333, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (0) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.0025, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (0.25) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1.25, -0.00235294, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (0.75) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1.75, -0.00210526, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (1) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, -0.002, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (2) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3, -0.00166667, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (-1) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0.00333333, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (0) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.0025, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (0.25) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1.25, -0.00235294, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (0.75) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1.75, -0.00210526, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (1) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, -0.002, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (2) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3, -0.00166667, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (-1) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0.00333333, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (0) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.0025, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (0.25) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1.25, -0.00235294, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (0.75) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1.75, -0.00210526, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (1) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, -0.002, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (2) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3, -0.00166667, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (-1) should be [matrix(-1.83697e-16, 1, -1, -1.83697e-16, 0, 0)] -PASS CSS Transitions: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (0) should be [matrix(0.866025, 0.5, -0.5, 0.866025, 0, 0)] -PASS CSS Transitions: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (0.25) should be [matrix(-0.258819, 0.965926, -0.965926, -0.258819, 0, 0)] -PASS CSS Transitions: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (0.75) should be [matrix(-0.258819, -0.965926, 0.965926, -0.258819, 0, 0)] -PASS CSS Transitions: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (1) should be [matrix(0.866025, -0.5, 0.5, 0.866025, 0, 0)] -PASS CSS Transitions: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (2) should be [matrix(-4.28626e-16, -1, 1, -4.28626e-16, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (-1) should be [matrix(-1.83697e-16, 1, -1, -1.83697e-16, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (0) should be [matrix(0.866025, 0.5, -0.5, 0.866025, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (0.25) should be [matrix(-0.258819, 0.965926, -0.965926, -0.258819, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (0.75) should be [matrix(-0.258819, -0.965926, 0.965926, -0.258819, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (1) should be [matrix(0.866025, -0.5, 0.5, 0.866025, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (2) should be [matrix(-4.28626e-16, -1, 1, -4.28626e-16, 0, 0)] -PASS CSS Animations: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (-1) should be [matrix(-1.83697e-16, 1, -1, -1.83697e-16, 0, 0)] -PASS CSS Animations: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (0) should be [matrix(0.866025, 0.5, -0.5, 0.866025, 0, 0)] -PASS CSS Animations: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (0.25) should be [matrix(-0.258819, 0.965926, -0.965926, -0.258819, 0, 0)] -PASS CSS Animations: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (0.75) should be [matrix(-0.258819, -0.965926, 0.965926, -0.258819, 0, 0)] -PASS CSS Animations: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (1) should be [matrix(0.866025, -0.5, 0.5, 0.866025, 0, 0)] -PASS CSS Animations: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (2) should be [matrix(-4.28626e-16, -1, 1, -4.28626e-16, 0, 0)] -PASS Web Animations: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (-1) should be [matrix(-1.83697e-16, 1, -1, -1.83697e-16, 0, 0)] -PASS Web Animations: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (0) should be [matrix(0.866025, 0.5, -0.5, 0.866025, 0, 0)] -PASS Web Animations: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (0.25) should be [matrix(-0.258819, 0.965926, -0.965926, -0.258819, 0, 0)] -PASS Web Animations: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (0.75) should be [matrix(-0.258819, -0.965926, 0.965926, -0.258819, 0, 0)] -PASS Web Animations: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (1) should be [matrix(0.866025, -0.5, 0.5, 0.866025, 0, 0)] -PASS Web Animations: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (2) should be [matrix(-4.28626e-16, -1, 1, -4.28626e-16, 0, 0)] -PASS CSS Transitions: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (-1) should be [matrix3d(1, 0, 0, 0, 0, 0.939693, 0.34202, 0, 0, -0.34202, 0.939693, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Transitions: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (0.25) should be [matrix3d(1, 0, 0, 0, 0, -0.996195, 0.0871557, 0, 0, -0.0871557, -0.996195, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (0.75) should be [matrix3d(1, 0, 0, 0, 0, -0.965926, 0.258819, 0, 0, -0.258819, -0.965926, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (1) should be [matrix3d(1, 0, 0, 0, 0, 0.939693, -0.34202, 0, 0, 0.34202, 0.939693, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (2) should be [matrix3d(1, 0, 0, 0, 0, 0.766044, -0.642788, 0, 0, 0.642788, 0.766044, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (-1) should be [matrix3d(1, 0, 0, 0, 0, 0.939693, 0.34202, 0, 0, -0.34202, 0.939693, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (0.25) should be [matrix3d(1, 0, 0, 0, 0, -0.996195, 0.0871557, 0, 0, -0.0871557, -0.996195, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (0.75) should be [matrix3d(1, 0, 0, 0, 0, -0.965926, 0.258819, 0, 0, -0.258819, -0.965926, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (1) should be [matrix3d(1, 0, 0, 0, 0, 0.939693, -0.34202, 0, 0, 0.34202, 0.939693, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (2) should be [matrix3d(1, 0, 0, 0, 0, 0.766044, -0.642788, 0, 0, 0.642788, 0.766044, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (-1) should be [matrix3d(1, 0, 0, 0, 0, 0.939693, 0.34202, 0, 0, -0.34202, 0.939693, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Animations: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (0.25) should be [matrix3d(1, 0, 0, 0, 0, -0.996195, 0.0871557, 0, 0, -0.0871557, -0.996195, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (0.75) should be [matrix3d(1, 0, 0, 0, 0, -0.965926, 0.258819, 0, 0, -0.258819, -0.965926, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (1) should be [matrix3d(1, 0, 0, 0, 0, 0.939693, -0.34202, 0, 0, 0.34202, 0.939693, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (2) should be [matrix3d(1, 0, 0, 0, 0, 0.766044, -0.642788, 0, 0, 0.642788, 0.766044, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (-1) should be [matrix3d(1, 0, 0, 0, 0, 0.939693, 0.34202, 0, 0, -0.34202, 0.939693, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS Web Animations: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (0.25) should be [matrix3d(1, 0, 0, 0, 0, -0.996195, 0.0871557, 0, 0, -0.0871557, -0.996195, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (0.75) should be [matrix3d(1, 0, 0, 0, 0, -0.965926, 0.258819, 0, 0, -0.258819, -0.965926, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (1) should be [matrix3d(1, 0, 0, 0, 0, 0.939693, -0.34202, 0, 0, 0.34202, 0.939693, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (2) should be [matrix3d(1, 0, 0, 0, 0, 0.766044, -0.642788, 0, 0, 0.642788, 0.766044, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (-1) should be [matrix3d(0.173648, 0, 0.984808, 0, 0, 1, 0, 0, -0.984808, 0, 0.173648, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Transitions: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (0.25) should be [matrix3d(-0.939693, 0, 0.34202, 0, 0, 1, 0, 0, -0.34202, 0, -0.939693, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (0.75) should be [matrix3d(-0.5, 0, 0.866025, 0, 0, 1, 0, 0, -0.866025, 0, -0.5, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (1) should be [matrix3d(0.173648, 0, -0.984808, 0, 0, 1, 0, 0, 0.984808, 0, 0.173648, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (2) should be [matrix3d(-0.939693, 0, -0.34202, 0, 0, 1, 0, 0, 0.34202, 0, -0.939693, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (-1) should be [matrix3d(0.173648, 0, 0.984808, 0, 0, 1, 0, 0, -0.984808, 0, 0.173648, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (0.25) should be [matrix3d(-0.939693, 0, 0.34202, 0, 0, 1, 0, 0, -0.34202, 0, -0.939693, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (0.75) should be [matrix3d(-0.5, 0, 0.866025, 0, 0, 1, 0, 0, -0.866025, 0, -0.5, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (1) should be [matrix3d(0.173648, 0, -0.984808, 0, 0, 1, 0, 0, 0.984808, 0, 0.173648, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (2) should be [matrix3d(-0.939693, 0, -0.34202, 0, 0, 1, 0, 0, 0.34202, 0, -0.939693, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (-1) should be [matrix3d(0.173648, 0, 0.984808, 0, 0, 1, 0, 0, -0.984808, 0, 0.173648, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Animations: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (0.25) should be [matrix3d(-0.939693, 0, 0.34202, 0, 0, 1, 0, 0, -0.34202, 0, -0.939693, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (0.75) should be [matrix3d(-0.5, 0, 0.866025, 0, 0, 1, 0, 0, -0.866025, 0, -0.5, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (1) should be [matrix3d(0.173648, 0, -0.984808, 0, 0, 1, 0, 0, 0.984808, 0, 0.173648, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (2) should be [matrix3d(-0.939693, 0, -0.34202, 0, 0, 1, 0, 0, 0.34202, 0, -0.939693, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (-1) should be [matrix3d(0.173648, 0, 0.984808, 0, 0, 1, 0, 0, -0.984808, 0, 0.173648, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS Web Animations: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (0.25) should be [matrix3d(-0.939693, 0, 0.34202, 0, 0, 1, 0, 0, -0.34202, 0, -0.939693, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (0.75) should be [matrix3d(-0.5, 0, 0.866025, 0, 0, 1, 0, 0, -0.866025, 0, -0.5, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (1) should be [matrix3d(0.173648, 0, -0.984808, 0, 0, 1, 0, 0, 0.984808, 0, 0.173648, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (2) should be [matrix3d(-0.939693, 0, -0.34202, 0, 0, 1, 0, 0, 0.34202, 0, -0.939693, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (-1) should be [matrix(-1, -6.12323e-16, 6.12323e-16, -1, 0, 0)] -PASS CSS Transitions: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Transitions: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (0.25) should be [matrix(-0.707107, -0.707107, 0.707107, -0.707107, 0, 0)] -PASS CSS Transitions: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (0.75) should be [matrix(0.707107, -0.707107, 0.707107, 0.707107, 0, 0)] -PASS CSS Transitions: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (1) should be [matrix(-1, 6.12323e-16, -6.12323e-16, -1, 0, 0)] -PASS CSS Transitions: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (2) should be [matrix(1, -1.22465e-15, 1.22465e-15, 1, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (-1) should be [matrix(-1, -6.12323e-16, 6.12323e-16, -1, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (0.25) should be [matrix(-0.707107, -0.707107, 0.707107, -0.707107, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (0.75) should be [matrix(0.707107, -0.707107, 0.707107, 0.707107, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (1) should be [matrix(-1, 6.12323e-16, -6.12323e-16, -1, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (2) should be [matrix(1, -1.22465e-15, 1.22465e-15, 1, 0, 0)] -PASS CSS Animations: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (-1) should be [matrix(-1, -6.12323e-16, 6.12323e-16, -1, 0, 0)] -PASS CSS Animations: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Animations: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (0.25) should be [matrix(-0.707107, -0.707107, 0.707107, -0.707107, 0, 0)] -PASS CSS Animations: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (0.75) should be [matrix(0.707107, -0.707107, 0.707107, 0.707107, 0, 0)] -PASS CSS Animations: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (1) should be [matrix(-1, 6.12323e-16, -6.12323e-16, -1, 0, 0)] -PASS CSS Animations: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (2) should be [matrix(1, -1.22465e-15, 1.22465e-15, 1, 0, 0)] -PASS Web Animations: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (-1) should be [matrix(-1, -6.12323e-16, 6.12323e-16, -1, 0, 0)] -PASS Web Animations: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS Web Animations: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (0.25) should be [matrix(-0.707107, -0.707107, 0.707107, -0.707107, 0, 0)] -PASS Web Animations: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (0.75) should be [matrix(0.707107, -0.707107, 0.707107, 0.707107, 0, 0)] -PASS Web Animations: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (1) should be [matrix(-1, 6.12323e-16, -6.12323e-16, -1, 0, 0)] -PASS Web Animations: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (2) should be [matrix(1, -1.22465e-15, 1.22465e-15, 1, 0, 0)] -PASS CSS Transitions: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (-1) should be [matrix3d(-1, 0, 6.12323e-16, 0, 0, 1, 0, 0, -6.12323e-16, 0, -1, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Transitions: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (0.25) should be [matrix3d(-0.707107, 0, 0.707107, 0, 0, 1, 0, 0, -0.707107, 0, -0.707107, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (0.75) should be [matrix3d(0.707107, 0, 0.707107, 0, 0, 1, 0, 0, -0.707107, 0, 0.707107, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (1) should be [matrix3d(-1, 0, -6.12323e-16, 0, 0, 1, 0, 0, 6.12323e-16, 0, -1, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (2) should be [matrix3d(1, 0, 1.22465e-15, 0, 0, 1, 0, 0, -1.22465e-15, 0, 1, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (-1) should be [matrix3d(-1, 0, 6.12323e-16, 0, 0, 1, 0, 0, -6.12323e-16, 0, -1, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (0.25) should be [matrix3d(-0.707107, 0, 0.707107, 0, 0, 1, 0, 0, -0.707107, 0, -0.707107, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (0.75) should be [matrix3d(0.707107, 0, 0.707107, 0, 0, 1, 0, 0, -0.707107, 0, 0.707107, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (1) should be [matrix3d(-1, 0, -6.12323e-16, 0, 0, 1, 0, 0, 6.12323e-16, 0, -1, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (2) should be [matrix3d(1, 0, 1.22465e-15, 0, 0, 1, 0, 0, -1.22465e-15, 0, 1, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (-1) should be [matrix3d(-1, 0, 6.12323e-16, 0, 0, 1, 0, 0, -6.12323e-16, 0, -1, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Animations: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (0.25) should be [matrix3d(-0.707107, 0, 0.707107, 0, 0, 1, 0, 0, -0.707107, 0, -0.707107, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (0.75) should be [matrix3d(0.707107, 0, 0.707107, 0, 0, 1, 0, 0, -0.707107, 0, 0.707107, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (1) should be [matrix3d(-1, 0, -6.12323e-16, 0, 0, 1, 0, 0, 6.12323e-16, 0, -1, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (2) should be [matrix3d(1, 0, 1.22465e-15, 0, 0, 1, 0, 0, -1.22465e-15, 0, 1, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (-1) should be [matrix3d(-1, 0, 6.12323e-16, 0, 0, 1, 0, 0, -6.12323e-16, 0, -1, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS Web Animations: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (0.25) should be [matrix3d(-0.707107, 0, 0.707107, 0, 0, 1, 0, 0, -0.707107, 0, -0.707107, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (0.75) should be [matrix3d(0.707107, 0, 0.707107, 0, 0, 1, 0, 0, -0.707107, 0, 0.707107, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (1) should be [matrix3d(-1, 0, -6.12323e-16, 0, 0, 1, 0, 0, 6.12323e-16, 0, -1, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (2) should be [matrix3d(1, 0, 1.22465e-15, 0, 0, 1, 0, 0, -1.22465e-15, 0, 1, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (-1) should be [matrix3d(1, 0, 1.22465e-15, 0, 0, 1, 0, 0, -1.22465e-15, 0, 1, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (0) should be [matrix3d(-1, 0, -6.12323e-16, 0, 0, 1, 0, 0, 6.12323e-16, 0, -1, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (0.25) should be [matrix3d(0.707107, 0, 0.707107, 0, 0, 1, 0, 0, -0.707107, 0, 0.707107, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (0.75) should be [matrix3d(-0.707107, 0, 0.707107, 0, 0, 1, 0, 0, -0.707107, 0, -0.707107, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (1) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Transitions: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (2) should be [matrix3d(-1, 0, 6.12323e-16, 0, 0, 1, 0, 0, -6.12323e-16, 0, -1, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (-1) should be [matrix3d(1, 0, 1.22465e-15, 0, 0, 1, 0, 0, -1.22465e-15, 0, 1, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (0) should be [matrix3d(-1, 0, -6.12323e-16, 0, 0, 1, 0, 0, 6.12323e-16, 0, -1, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (0.25) should be [matrix3d(0.707107, 0, 0.707107, 0, 0, 1, 0, 0, -0.707107, 0, 0.707107, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (0.75) should be [matrix3d(-0.707107, 0, 0.707107, 0, 0, 1, 0, 0, -0.707107, 0, -0.707107, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (1) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (2) should be [matrix3d(-1, 0, 6.12323e-16, 0, 0, 1, 0, 0, -6.12323e-16, 0, -1, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (-1) should be [matrix3d(1, 0, 1.22465e-15, 0, 0, 1, 0, 0, -1.22465e-15, 0, 1, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (0) should be [matrix3d(-1, 0, -6.12323e-16, 0, 0, 1, 0, 0, 6.12323e-16, 0, -1, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (0.25) should be [matrix3d(0.707107, 0, 0.707107, 0, 0, 1, 0, 0, -0.707107, 0, 0.707107, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (0.75) should be [matrix3d(-0.707107, 0, 0.707107, 0, 0, 1, 0, 0, -0.707107, 0, -0.707107, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (1) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Animations: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (2) should be [matrix3d(-1, 0, 6.12323e-16, 0, 0, 1, 0, 0, -6.12323e-16, 0, -1, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (-1) should be [matrix3d(1, 0, 1.22465e-15, 0, 0, 1, 0, 0, -1.22465e-15, 0, 1, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (0) should be [matrix3d(-1, 0, -6.12323e-16, 0, 0, 1, 0, 0, 6.12323e-16, 0, -1, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (0.25) should be [matrix3d(0.707107, 0, 0.707107, 0, 0, 1, 0, 0, -0.707107, 0, 0.707107, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (0.75) should be [matrix3d(-0.707107, 0, 0.707107, 0, 0, 1, 0, 0, -0.707107, 0, -0.707107, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (1) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS Web Animations: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (2) should be [matrix3d(-1, 0, 6.12323e-16, 0, 0, 1, 0, 0, -6.12323e-16, 0, -1, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (-1) should be [matrix3d(0.626289, -0.415263, 0.659787, 0, 0.703923, 0.664948, -0.249672, 0, -0.335045, 0.620806, 0.708763, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (0) should be [matrix3d(0.122789, 0.975131, -0.184507, 0, -0.297561, 0.213535, 0.930516, 0, 0.946774, -0.0593548, 0.31638, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (0.25) should be [matrix3d(-0.319982, 0.925131, 0.204314, 0, 0.0944409, -0.183432, 0.978485, 0, 0.942705, 0.332393, -0.0286754, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (0.75) should be [matrix3d(-0.319982, 0.0944409, 0.942705, 0, 0.925131, -0.183432, 0.332393, 0, 0.204314, 0.978485, -0.0286754, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (1) should be [matrix3d(0.122789, -0.297561, 0.946774, 0, 0.975131, 0.213535, -0.0593548, 0, -0.184507, 0.930516, 0.31638, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (2) should be [matrix3d(0.626289, 0.703923, -0.335045, 0, -0.415263, 0.664948, 0.620806, 0, 0.659787, -0.249672, 0.708763, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (-1) should be [matrix3d(0.626289, -0.415263, 0.659787, 0, 0.703923, 0.664948, -0.249672, 0, -0.335045, 0.620806, 0.708763, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (0) should be [matrix3d(0.122789, 0.975131, -0.184507, 0, -0.297561, 0.213535, 0.930516, 0, 0.946774, -0.0593548, 0.31638, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (0.25) should be [matrix3d(-0.319982, 0.925131, 0.204314, 0, 0.0944409, -0.183432, 0.978485, 0, 0.942705, 0.332393, -0.0286754, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (0.75) should be [matrix3d(-0.319982, 0.0944409, 0.942705, 0, 0.925131, -0.183432, 0.332393, 0, 0.204314, 0.978485, -0.0286754, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (1) should be [matrix3d(0.122789, -0.297561, 0.946774, 0, 0.975131, 0.213535, -0.0593548, 0, -0.184507, 0.930516, 0.31638, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (2) should be [matrix3d(0.626289, 0.703923, -0.335045, 0, -0.415263, 0.664948, 0.620806, 0, 0.659787, -0.249672, 0.708763, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (-1) should be [matrix3d(0.626289, -0.415263, 0.659787, 0, 0.703923, 0.664948, -0.249672, 0, -0.335045, 0.620806, 0.708763, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (0) should be [matrix3d(0.122789, 0.975131, -0.184507, 0, -0.297561, 0.213535, 0.930516, 0, 0.946774, -0.0593548, 0.31638, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (0.25) should be [matrix3d(-0.319982, 0.925131, 0.204314, 0, 0.0944409, -0.183432, 0.978485, 0, 0.942705, 0.332393, -0.0286754, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (0.75) should be [matrix3d(-0.319982, 0.0944409, 0.942705, 0, 0.925131, -0.183432, 0.332393, 0, 0.204314, 0.978485, -0.0286754, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (1) should be [matrix3d(0.122789, -0.297561, 0.946774, 0, 0.975131, 0.213535, -0.0593548, 0, -0.184507, 0.930516, 0.31638, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (2) should be [matrix3d(0.626289, 0.703923, -0.335045, 0, -0.415263, 0.664948, 0.620806, 0, 0.659787, -0.249672, 0.708763, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (-1) should be [matrix3d(0.626289, -0.415263, 0.659787, 0, 0.703923, 0.664948, -0.249672, 0, -0.335045, 0.620806, 0.708763, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (0) should be [matrix3d(0.122789, 0.975131, -0.184507, 0, -0.297561, 0.213535, 0.930516, 0, 0.946774, -0.0593548, 0.31638, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (0.25) should be [matrix3d(-0.319982, 0.925131, 0.204314, 0, 0.0944409, -0.183432, 0.978485, 0, 0.942705, 0.332393, -0.0286754, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (0.75) should be [matrix3d(-0.319982, 0.0944409, 0.942705, 0, 0.925131, -0.183432, 0.332393, 0, 0.204314, 0.978485, -0.0286754, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (1) should be [matrix3d(0.122789, -0.297561, 0.946774, 0, 0.975131, 0.213535, -0.0593548, 0, -0.184507, 0.930516, 0.31638, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (2) should be [matrix3d(0.626289, 0.703923, -0.335045, 0, -0.415263, 0.664948, 0.620806, 0, 0.659787, -0.249672, 0.708763, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (-1) should be [matrix3d(0.252577, -0.357503, 0.899109, 0, 0.934822, 0.329897, -0.131437, 0, -0.249624, 0.873705, 0.417526, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Transitions: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (0.25) should be [matrix3d(-0.033449, 0.996101, -0.0816297, 0, -0.197851, 0.0734596, 0.977476, 0, 0.979661, 0.0488461, 0.194623, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (0.75) should be [matrix3d(0.943106, -0.225303, 0.24452, 0, 0.269249, 0.948991, -0.164075, 0, -0.195081, 0.220576, 0.955662, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (1) should be [matrix3d(0.252577, 0.934822, -0.249624, 0, -0.357503, 0.329897, 0.873705, 0, 0.899109, -0.131437, 0.417526, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (2) should be [matrix3d(-0.494845, 0.57732, 0.649485, 0, 0.57732, -0.340206, 0.742268, 0, 0.649485, 0.742268, -0.164948, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (-1) should be [matrix3d(0.252577, -0.357503, 0.899109, 0, 0.934822, 0.329897, -0.131437, 0, -0.249624, 0.873705, 0.417526, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (0.25) should be [matrix3d(-0.033449, 0.996101, -0.0816297, 0, -0.197851, 0.0734596, 0.977476, 0, 0.979661, 0.0488461, 0.194623, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (0.75) should be [matrix3d(0.943106, -0.225303, 0.24452, 0, 0.269249, 0.948991, -0.164075, 0, -0.195081, 0.220576, 0.955662, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (1) should be [matrix3d(0.252577, 0.934822, -0.249624, 0, -0.357503, 0.329897, 0.873705, 0, 0.899109, -0.131437, 0.417526, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (2) should be [matrix3d(-0.494845, 0.57732, 0.649485, 0, 0.57732, -0.340206, 0.742268, 0, 0.649485, 0.742268, -0.164948, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (-1) should be [matrix3d(0.252577, -0.357503, 0.899109, 0, 0.934822, 0.329897, -0.131437, 0, -0.249624, 0.873705, 0.417526, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Animations: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (0.25) should be [matrix3d(-0.033449, 0.996101, -0.0816297, 0, -0.197851, 0.0734596, 0.977476, 0, 0.979661, 0.0488461, 0.194623, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (0.75) should be [matrix3d(0.943106, -0.225303, 0.24452, 0, 0.269249, 0.948991, -0.164075, 0, -0.195081, 0.220576, 0.955662, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (1) should be [matrix3d(0.252577, 0.934822, -0.249624, 0, -0.357503, 0.329897, 0.873705, 0, 0.899109, -0.131437, 0.417526, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (2) should be [matrix3d(-0.494845, 0.57732, 0.649485, 0, 0.57732, -0.340206, 0.742268, 0, 0.649485, 0.742268, -0.164948, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (-1) should be [matrix3d(0.252577, -0.357503, 0.899109, 0, 0.934822, 0.329897, -0.131437, 0, -0.249624, 0.873705, 0.417526, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS Web Animations: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (0.25) should be [matrix3d(-0.033449, 0.996101, -0.0816297, 0, -0.197851, 0.0734596, 0.977476, 0, 0.979661, 0.0488461, 0.194623, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (0.75) should be [matrix3d(0.943106, -0.225303, 0.24452, 0, 0.269249, 0.948991, -0.164075, 0, -0.195081, 0.220576, 0.955662, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (1) should be [matrix3d(0.252577, 0.934822, -0.249624, 0, -0.357503, 0.329897, 0.873705, 0, 0.899109, -0.131437, 0.417526, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (2) should be [matrix3d(-0.494845, 0.57732, 0.649485, 0, 0.57732, -0.340206, 0.742268, 0, 0.649485, 0.742268, -0.164948, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (-1) should be [matrix3d(3.06162e-16, 0, 1, 0, 0, 1, 0, 0, -1, 0, 3.06162e-16, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Transitions: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (0.25) should be [matrix3d(-0.382683, 0, -0.92388, 0, 0, 1, 0, 0, 0.92388, 0, -0.382683, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (0.75) should be [matrix3d(0.92388, 0, 0.382683, 0, 0, 1, 0, 0, -0.382683, 0, 0.92388, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (1) should be [matrix3d(3.06162e-16, 0, -1, 0, 0, 1, 0, 0, 1, 0, 3.06162e-16, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (2) should be [matrix3d(-1, 0, -6.12323e-16, 0, 0, 1, 0, 0, 6.12323e-16, 0, -1, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (-1) should be [matrix3d(3.06162e-16, 0, 1, 0, 0, 1, 0, 0, -1, 0, 3.06162e-16, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (0.25) should be [matrix3d(-0.382683, 0, -0.92388, 0, 0, 1, 0, 0, 0.92388, 0, -0.382683, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (0.75) should be [matrix3d(0.92388, 0, 0.382683, 0, 0, 1, 0, 0, -0.382683, 0, 0.92388, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (1) should be [matrix3d(3.06162e-16, 0, -1, 0, 0, 1, 0, 0, 1, 0, 3.06162e-16, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (2) should be [matrix3d(-1, 0, -6.12323e-16, 0, 0, 1, 0, 0, 6.12323e-16, 0, -1, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (-1) should be [matrix3d(3.06162e-16, 0, 1, 0, 0, 1, 0, 0, -1, 0, 3.06162e-16, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (0.25) should be [matrix3d(-0.382683, 0, -0.92388, 0, 0, 1, 0, 0, 0.92388, 0, -0.382683, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (0.75) should be [matrix3d(0.92388, 0, 0.382683, 0, 0, 1, 0, 0, -0.382683, 0, 0.92388, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (1) should be [matrix3d(3.06162e-16, 0, -1, 0, 0, 1, 0, 0, 1, 0, 3.06162e-16, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (2) should be [matrix3d(-1, 0, -6.12323e-16, 0, 0, 1, 0, 0, 6.12323e-16, 0, -1, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (-1) should be [matrix3d(3.06162e-16, 0, 1, 0, 0, 1, 0, 0, -1, 0, 3.06162e-16, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS Web Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (0.25) should be [matrix3d(-0.382683, 0, -0.92388, 0, 0, 1, 0, 0, 0.92388, 0, -0.382683, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (0.75) should be [matrix3d(0.92388, 0, 0.382683, 0, 0, 1, 0, 0, -0.382683, 0, 0.92388, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (1) should be [matrix3d(3.06162e-16, 0, -1, 0, 0, 1, 0, 0, 1, 0, 3.06162e-16, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (2) should be [matrix3d(-1, 0, -6.12323e-16, 0, 0, 1, 0, 0, 6.12323e-16, 0, -1, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (-1) should be [matrix3d(3.06162e-16, 0, 1, 0, 0, 1, 0, 0, -1, 0, 3.06162e-16, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Transitions: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (0.25) should be [matrix3d(-0.382683, 0, -0.92388, 0, 0, 1, 0, 0, 0.92388, 0, -0.382683, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (0.75) should be [matrix3d(0.92388, 0, 0.382683, 0, 0, 1, 0, 0, -0.382683, 0, 0.92388, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (1) should be [matrix3d(3.06162e-16, 0, -1, 0, 0, 1, 0, 0, 1, 0, 3.06162e-16, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (2) should be [matrix3d(-1, 0, -6.12323e-16, 0, 0, 1, 0, 0, 6.12323e-16, 0, -1, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (-1) should be [matrix3d(3.06162e-16, 0, 1, 0, 0, 1, 0, 0, -1, 0, 3.06162e-16, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (0.25) should be [matrix3d(-0.382683, 0, -0.92388, 0, 0, 1, 0, 0, 0.92388, 0, -0.382683, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (0.75) should be [matrix3d(0.92388, 0, 0.382683, 0, 0, 1, 0, 0, -0.382683, 0, 0.92388, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (1) should be [matrix3d(3.06162e-16, 0, -1, 0, 0, 1, 0, 0, 1, 0, 3.06162e-16, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (2) should be [matrix3d(-1, 0, -6.12323e-16, 0, 0, 1, 0, 0, 6.12323e-16, 0, -1, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (-1) should be [matrix3d(3.06162e-16, 0, 1, 0, 0, 1, 0, 0, -1, 0, 3.06162e-16, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (0.25) should be [matrix3d(-0.382683, 0, -0.92388, 0, 0, 1, 0, 0, 0.92388, 0, -0.382683, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (0.75) should be [matrix3d(0.92388, 0, 0.382683, 0, 0, 1, 0, 0, -0.382683, 0, 0.92388, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (1) should be [matrix3d(3.06162e-16, 0, -1, 0, 0, 1, 0, 0, 1, 0, 3.06162e-16, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (2) should be [matrix3d(-1, 0, -6.12323e-16, 0, 0, 1, 0, 0, 6.12323e-16, 0, -1, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (-1) should be [matrix3d(3.06162e-16, 0, 1, 0, 0, 1, 0, 0, -1, 0, 3.06162e-16, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS Web Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (0.25) should be [matrix3d(-0.382683, 0, -0.92388, 0, 0, 1, 0, 0, 0.92388, 0, -0.382683, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (0.75) should be [matrix3d(0.92388, 0, 0.382683, 0, 0, 1, 0, 0, -0.382683, 0, 0.92388, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (1) should be [matrix3d(3.06162e-16, 0, -1, 0, 0, 1, 0, 0, 1, 0, 3.06162e-16, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (2) should be [matrix3d(-1, 0, -6.12323e-16, 0, 0, 1, 0, 0, 6.12323e-16, 0, -1, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (-1) should be [matrix3d(-0.25, -0.957107, -0.146447, 0, 0.457107, -0.25, 0.853553, 0, -0.853553, 0.146447, 0.5, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (0) should be [matrix3d(0.5, 0.5, -0.707107, 0, 0.5, 0.5, 0.707107, 0, 0.707107, -0.707107, 6.12323e-17, 0, 0, 0, 0, 1)] -FAIL CSS Transitions: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (0.25) should be [matrix3d(0.0636854, 0.812166, -0.579941, 0, 0.276037, 0.544112, 0.792304, 0, 0.959035, -0.210543, -0.189536, 0, 0, 0, 0, 1)] assert_equals: expected "matrix3d ( 0.06 , 0.81 , - 0.58 , 0 , 0.28 , 0.54 , 0.79 , 0 , 0.96 , - 0.21 , - 0.19 , 0 , 0 , 0 , 0 , 1 ) " but got "matrix3d ( 0.69 , - 0.34 , - 0.64 , 0 , 0.72 , 0.19 , 0.67 , 0 , - 0.1 , - 0.92 , 0.37 , 0 , 0 , 0 , 0 , 1 ) " -FAIL CSS Transitions: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (0.75) should be [matrix3d(-0.848254, 0.5078, -0.150348, 0, -0.0283918, 0.239883, 0.970387, 0, 0.528828, 0.827403, -0.189064, 0, 0, 0, 0, 1)] assert_equals: expected "matrix3d ( - 0.85 , 0.51 , - 0.15 , 0 , - 0.03 , 0.24 , 0.97 , 0 , 0.53 , 0.83 , - 0.19 , 0 , 0 , 0 , 0 , 1 ) " but got "matrix3d ( - 0.63 , - 0.78 , - 0.02 , 0 , 0.28 , - 0.25 , 0.93 , 0 , - 0.73 , 0.58 , 0.37 , 0 , 0 , 0 , 0 , 1 ) " -PASS CSS Transitions: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (1) should be [matrix3d(-1, 8.65956e-17, -8.65956e-17, 0, -8.65956e-17, -2.22045e-16, 1, 0, 8.65956e-17, 1, -2.22045e-16, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (2) should be [matrix3d(0.5, -0.707107, -0.5, 0, 0.707107, 6.12323e-17, 0.707107, 0, -0.5, -0.707107, 0.5, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (-1) should be [matrix3d(-0.25, -0.957107, -0.146447, 0, 0.457107, -0.25, 0.853553, 0, -0.853553, 0.146447, 0.5, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (0) should be [matrix3d(0.5, 0.5, -0.707107, 0, 0.5, 0.5, 0.707107, 0, 0.707107, -0.707107, 6.12323e-17, 0, 0, 0, 0, 1)] -FAIL CSS Transitions with transition: all: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (0.25) should be [matrix3d(0.0636854, 0.812166, -0.579941, 0, 0.276037, 0.544112, 0.792304, 0, 0.959035, -0.210543, -0.189536, 0, 0, 0, 0, 1)] assert_equals: expected "matrix3d ( 0.06 , 0.81 , - 0.58 , 0 , 0.28 , 0.54 , 0.79 , 0 , 0.96 , - 0.21 , - 0.19 , 0 , 0 , 0 , 0 , 1 ) " but got "matrix3d ( 0.69 , - 0.34 , - 0.64 , 0 , 0.72 , 0.19 , 0.67 , 0 , - 0.1 , - 0.92 , 0.37 , 0 , 0 , 0 , 0 , 1 ) " -FAIL CSS Transitions with transition: all: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (0.75) should be [matrix3d(-0.848254, 0.5078, -0.150348, 0, -0.0283918, 0.239883, 0.970387, 0, 0.528828, 0.827403, -0.189064, 0, 0, 0, 0, 1)] assert_equals: expected "matrix3d ( - 0.85 , 0.51 , - 0.15 , 0 , - 0.03 , 0.24 , 0.97 , 0 , 0.53 , 0.83 , - 0.19 , 0 , 0 , 0 , 0 , 1 ) " but got "matrix3d ( - 0.63 , - 0.78 , - 0.02 , 0 , 0.28 , - 0.25 , 0.93 , 0 , - 0.73 , 0.58 , 0.37 , 0 , 0 , 0 , 0 , 1 ) " -PASS CSS Transitions with transition: all: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (1) should be [matrix3d(-1, 8.65956e-17, -8.65956e-17, 0, -8.65956e-17, -2.22045e-16, 1, 0, 8.65956e-17, 1, -2.22045e-16, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (2) should be [matrix3d(0.5, -0.707107, -0.5, 0, 0.707107, 6.12323e-17, 0.707107, 0, -0.5, -0.707107, 0.5, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (-1) should be [matrix3d(-0.25, -0.957107, -0.146447, 0, 0.457107, -0.25, 0.853553, 0, -0.853553, 0.146447, 0.5, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (0) should be [matrix3d(0.5, 0.5, -0.707107, 0, 0.5, 0.5, 0.707107, 0, 0.707107, -0.707107, 6.12323e-17, 0, 0, 0, 0, 1)] -FAIL CSS Animations: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (0.25) should be [matrix3d(0.0636854, 0.812166, -0.579941, 0, 0.276037, 0.544112, 0.792304, 0, 0.959035, -0.210543, -0.189536, 0, 0, 0, 0, 1)] assert_equals: expected "matrix3d ( 0.06 , 0.81 , - 0.58 , 0 , 0.28 , 0.54 , 0.79 , 0 , 0.96 , - 0.21 , - 0.19 , 0 , 0 , 0 , 0 , 1 ) " but got "matrix3d ( 0.69 , - 0.34 , - 0.64 , 0 , 0.72 , 0.19 , 0.67 , 0 , - 0.1 , - 0.92 , 0.37 , 0 , 0 , 0 , 0 , 1 ) " -FAIL CSS Animations: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (0.75) should be [matrix3d(-0.848254, 0.5078, -0.150348, 0, -0.0283918, 0.239883, 0.970387, 0, 0.528828, 0.827403, -0.189064, 0, 0, 0, 0, 1)] assert_equals: expected "matrix3d ( - 0.85 , 0.51 , - 0.15 , 0 , - 0.03 , 0.24 , 0.97 , 0 , 0.53 , 0.83 , - 0.19 , 0 , 0 , 0 , 0 , 1 ) " but got "matrix3d ( - 0.63 , - 0.78 , - 0.02 , 0 , 0.28 , - 0.25 , 0.93 , 0 , - 0.73 , 0.58 , 0.37 , 0 , 0 , 0 , 0 , 1 ) " -PASS CSS Animations: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (1) should be [matrix3d(-1, 8.65956e-17, -8.65956e-17, 0, -8.65956e-17, -2.22045e-16, 1, 0, 8.65956e-17, 1, -2.22045e-16, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (2) should be [matrix3d(0.5, -0.707107, -0.5, 0, 0.707107, 6.12323e-17, 0.707107, 0, -0.5, -0.707107, 0.5, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (-1) should be [matrix3d(-0.25, -0.957107, -0.146447, 0, 0.457107, -0.25, 0.853553, 0, -0.853553, 0.146447, 0.5, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (0) should be [matrix3d(0.5, 0.5, -0.707107, 0, 0.5, 0.5, 0.707107, 0, 0.707107, -0.707107, 6.12323e-17, 0, 0, 0, 0, 1)] -FAIL Web Animations: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (0.25) should be [matrix3d(0.0636854, 0.812166, -0.579941, 0, 0.276037, 0.544112, 0.792304, 0, 0.959035, -0.210543, -0.189536, 0, 0, 0, 0, 1)] assert_equals: expected "matrix3d ( 0.06 , 0.81 , - 0.58 , 0 , 0.28 , 0.54 , 0.79 , 0 , 0.96 , - 0.21 , - 0.19 , 0 , 0 , 0 , 0 , 1 ) " but got "matrix3d ( 0.69 , - 0.34 , - 0.64 , 0 , 0.72 , 0.19 , 0.67 , 0 , - 0.1 , - 0.92 , 0.37 , 0 , 0 , 0 , 0 , 1 ) " -FAIL Web Animations: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (0.75) should be [matrix3d(-0.848254, 0.5078, -0.150348, 0, -0.0283918, 0.239883, 0.970387, 0, 0.528828, 0.827403, -0.189064, 0, 0, 0, 0, 1)] assert_equals: expected "matrix3d ( - 0.85 , 0.51 , - 0.15 , 0 , - 0.03 , 0.24 , 0.97 , 0 , 0.53 , 0.83 , - 0.19 , 0 , 0 , 0 , 0 , 1 ) " but got "matrix3d ( - 0.63 , - 0.78 , - 0.02 , 0 , 0.28 , - 0.25 , 0.93 , 0 , - 0.73 , 0.58 , 0.37 , 0 , 0 , 0 , 0 , 1 ) " -PASS Web Animations: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (1) should be [matrix3d(-1, 8.65956e-17, -8.65956e-17, 0, -8.65956e-17, -2.22045e-16, 1, 0, 8.65956e-17, 1, -2.22045e-16, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (2) should be [matrix3d(0.5, -0.707107, -0.5, 0, 0.707107, 6.12323e-17, 0.707107, 0, -0.5, -0.707107, 0.5, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [none] to [rotate(90deg)] at (-1) should be [matrix(6.12323e-17, -1, 1, 6.12323e-17, 0, 0)] -PASS CSS Transitions: property <transform> from [none] to [rotate(90deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Transitions: property <transform> from [none] to [rotate(90deg)] at (0.25) should be [matrix(0.92388, 0.382683, -0.382683, 0.92388, 0, 0)] -PASS CSS Transitions: property <transform> from [none] to [rotate(90deg)] at (0.75) should be [matrix(0.382683, 0.92388, -0.92388, 0.382683, 0, 0)] -PASS CSS Transitions: property <transform> from [none] to [rotate(90deg)] at (1) should be [matrix(6.12323e-17, 1, -1, 6.12323e-17, 0, 0)] -PASS CSS Transitions: property <transform> from [none] to [rotate(90deg)] at (2) should be [matrix(-1, 1.22465e-16, -1.22465e-16, -1, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [none] to [rotate(90deg)] at (-1) should be [matrix(6.12323e-17, -1, 1, 6.12323e-17, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [none] to [rotate(90deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [none] to [rotate(90deg)] at (0.25) should be [matrix(0.92388, 0.382683, -0.382683, 0.92388, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [none] to [rotate(90deg)] at (0.75) should be [matrix(0.382683, 0.92388, -0.92388, 0.382683, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [none] to [rotate(90deg)] at (1) should be [matrix(6.12323e-17, 1, -1, 6.12323e-17, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [none] to [rotate(90deg)] at (2) should be [matrix(-1, 1.22465e-16, -1.22465e-16, -1, 0, 0)] -PASS CSS Animations: property <transform> from [none] to [rotate(90deg)] at (-1) should be [matrix(6.12323e-17, -1, 1, 6.12323e-17, 0, 0)] -PASS CSS Animations: property <transform> from [none] to [rotate(90deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Animations: property <transform> from [none] to [rotate(90deg)] at (0.25) should be [matrix(0.92388, 0.382683, -0.382683, 0.92388, 0, 0)] -PASS CSS Animations: property <transform> from [none] to [rotate(90deg)] at (0.75) should be [matrix(0.382683, 0.92388, -0.92388, 0.382683, 0, 0)] -PASS CSS Animations: property <transform> from [none] to [rotate(90deg)] at (1) should be [matrix(6.12323e-17, 1, -1, 6.12323e-17, 0, 0)] -PASS CSS Animations: property <transform> from [none] to [rotate(90deg)] at (2) should be [matrix(-1, 1.22465e-16, -1.22465e-16, -1, 0, 0)] -PASS Web Animations: property <transform> from [none] to [rotate(90deg)] at (-1) should be [matrix(6.12323e-17, -1, 1, 6.12323e-17, 0, 0)] -PASS Web Animations: property <transform> from [none] to [rotate(90deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS Web Animations: property <transform> from [none] to [rotate(90deg)] at (0.25) should be [matrix(0.92388, 0.382683, -0.382683, 0.92388, 0, 0)] -PASS Web Animations: property <transform> from [none] to [rotate(90deg)] at (0.75) should be [matrix(0.382683, 0.92388, -0.92388, 0.382683, 0, 0)] -PASS Web Animations: property <transform> from [none] to [rotate(90deg)] at (1) should be [matrix(6.12323e-17, 1, -1, 6.12323e-17, 0, 0)] -PASS Web Animations: property <transform> from [none] to [rotate(90deg)] at (2) should be [matrix(-1, 1.22465e-16, -1.22465e-16, -1, 0, 0)] -PASS CSS Transitions: property <transform> from [rotate(90deg)] to [none] at (-1) should be [matrix(-1, 1.22465e-16, -1.22465e-16, -1, 0, 0)] -PASS CSS Transitions: property <transform> from [rotate(90deg)] to [none] at (0) should be [matrix(6.12323e-17, 1, -1, 6.12323e-17, 0, 0)] -PASS CSS Transitions: property <transform> from [rotate(90deg)] to [none] at (0.25) should be [matrix(0.382683, 0.92388, -0.92388, 0.382683, 0, 0)] -PASS CSS Transitions: property <transform> from [rotate(90deg)] to [none] at (0.75) should be [matrix(0.92388, 0.382683, -0.382683, 0.92388, 0, 0)] -PASS CSS Transitions: property <transform> from [rotate(90deg)] to [none] at (1) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Transitions: property <transform> from [rotate(90deg)] to [none] at (2) should be [matrix(6.12323e-17, -1, 1, 6.12323e-17, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [rotate(90deg)] to [none] at (-1) should be [matrix(-1, 1.22465e-16, -1.22465e-16, -1, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [rotate(90deg)] to [none] at (0) should be [matrix(6.12323e-17, 1, -1, 6.12323e-17, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [rotate(90deg)] to [none] at (0.25) should be [matrix(0.382683, 0.92388, -0.92388, 0.382683, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [rotate(90deg)] to [none] at (0.75) should be [matrix(0.92388, 0.382683, -0.382683, 0.92388, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [rotate(90deg)] to [none] at (1) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [rotate(90deg)] to [none] at (2) should be [matrix(6.12323e-17, -1, 1, 6.12323e-17, 0, 0)] -PASS CSS Animations: property <transform> from [rotate(90deg)] to [none] at (-1) should be [matrix(-1, 1.22465e-16, -1.22465e-16, -1, 0, 0)] -PASS CSS Animations: property <transform> from [rotate(90deg)] to [none] at (0) should be [matrix(6.12323e-17, 1, -1, 6.12323e-17, 0, 0)] -PASS CSS Animations: property <transform> from [rotate(90deg)] to [none] at (0.25) should be [matrix(0.382683, 0.92388, -0.92388, 0.382683, 0, 0)] -PASS CSS Animations: property <transform> from [rotate(90deg)] to [none] at (0.75) should be [matrix(0.92388, 0.382683, -0.382683, 0.92388, 0, 0)] -PASS CSS Animations: property <transform> from [rotate(90deg)] to [none] at (1) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Animations: property <transform> from [rotate(90deg)] to [none] at (2) should be [matrix(6.12323e-17, -1, 1, 6.12323e-17, 0, 0)] -PASS Web Animations: property <transform> from [rotate(90deg)] to [none] at (-1) should be [matrix(-1, 1.22465e-16, -1.22465e-16, -1, 0, 0)] -PASS Web Animations: property <transform> from [rotate(90deg)] to [none] at (0) should be [matrix(6.12323e-17, 1, -1, 6.12323e-17, 0, 0)] -PASS Web Animations: property <transform> from [rotate(90deg)] to [none] at (0.25) should be [matrix(0.382683, 0.92388, -0.92388, 0.382683, 0, 0)] -PASS Web Animations: property <transform> from [rotate(90deg)] to [none] at (0.75) should be [matrix(0.92388, 0.382683, -0.382683, 0.92388, 0, 0)] -PASS Web Animations: property <transform> from [rotate(90deg)] to [none] at (1) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS Web Animations: property <transform> from [rotate(90deg)] to [none] at (2) should be [matrix(6.12323e-17, -1, 1, 6.12323e-17, 0, 0)] -PASS CSS Transitions: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (-1) should be [matrix3d(-0.173648, 0.336824, -0.925417, 0, 1.06329e-16, -0.939693, -0.34202, 0, -0.984808, -0.0593912, 0.163176, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Transitions: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (0.25) should be [matrix3d(0.664463, 0.725494, 0.179296, 0, -0.664463, 0.683338, -0.302553, 0, -0.34202, 0.0818996, 0.936117, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (0.75) should be [matrix3d(-0.353553, 0.524519, -0.774519, 0, -0.353553, -0.841506, -0.408494, 0, -0.866025, 0.12941, 0.482963, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (1) should be [matrix3d(-0.173648, 0.336824, 0.925417, 0, -1.06329e-16, -0.939693, 0.34202, 0, 0.984808, 0.0593912, 0.163176, 0, 0, 0, 0, 1)] -PASS CSS Transitions: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (2) should be [matrix3d(-0.939693, -0.219846, -0.262003, 0, -1.15079e-15, 0.766044, -0.642788, 0, 0.34202, -0.604023, -0.719846, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (-1) should be [matrix3d(-0.173648, 0.336824, -0.925417, 0, 1.06329e-16, -0.939693, -0.34202, 0, -0.984808, -0.0593912, 0.163176, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (0.25) should be [matrix3d(0.664463, 0.725494, 0.179296, 0, -0.664463, 0.683338, -0.302553, 0, -0.34202, 0.0818996, 0.936117, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (0.75) should be [matrix3d(-0.353553, 0.524519, -0.774519, 0, -0.353553, -0.841506, -0.408494, 0, -0.866025, 0.12941, 0.482963, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (1) should be [matrix3d(-0.173648, 0.336824, 0.925417, 0, -1.06329e-16, -0.939693, 0.34202, 0, 0.984808, 0.0593912, 0.163176, 0, 0, 0, 0, 1)] -PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (2) should be [matrix3d(-0.939693, -0.219846, -0.262003, 0, -1.15079e-15, 0.766044, -0.642788, 0, 0.34202, -0.604023, -0.719846, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (-1) should be [matrix3d(-0.173648, 0.336824, -0.925417, 0, 1.06329e-16, -0.939693, -0.34202, 0, -0.984808, -0.0593912, 0.163176, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS CSS Animations: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (0.25) should be [matrix3d(0.664463, 0.725494, 0.179296, 0, -0.664463, 0.683338, -0.302553, 0, -0.34202, 0.0818996, 0.936117, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (0.75) should be [matrix3d(-0.353553, 0.524519, -0.774519, 0, -0.353553, -0.841506, -0.408494, 0, -0.866025, 0.12941, 0.482963, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (1) should be [matrix3d(-0.173648, 0.336824, 0.925417, 0, -1.06329e-16, -0.939693, 0.34202, 0, 0.984808, 0.0593912, 0.163176, 0, 0, 0, 0, 1)] -PASS CSS Animations: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (2) should be [matrix3d(-0.939693, -0.219846, -0.262003, 0, -1.15079e-15, 0.766044, -0.642788, 0, 0.34202, -0.604023, -0.719846, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (-1) should be [matrix3d(-0.173648, 0.336824, -0.925417, 0, 1.06329e-16, -0.939693, -0.34202, 0, -0.984808, -0.0593912, 0.163176, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (0) should be [matrix(1, 0, 0, 1, 0, 0)] -PASS Web Animations: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (0.25) should be [matrix3d(0.664463, 0.725494, 0.179296, 0, -0.664463, 0.683338, -0.302553, 0, -0.34202, 0.0818996, 0.936117, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (0.75) should be [matrix3d(-0.353553, 0.524519, -0.774519, 0, -0.353553, -0.841506, -0.408494, 0, -0.866025, 0.12941, 0.482963, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (1) should be [matrix3d(-0.173648, 0.336824, 0.925417, 0, -1.06329e-16, -0.939693, 0.34202, 0, 0.984808, 0.0593912, 0.163176, 0, 0, 0, 0, 1)] -PASS Web Animations: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (2) should be [matrix3d(-0.939693, -0.219846, -0.262003, 0, -1.15079e-15, 0.766044, -0.642788, 0, 0.34202, -0.604023, -0.719846, 0, 0, 0, 0, 1)] +PASS CSS Transitions: property <transform> from [perspective(400px)] to [perspective(500px)] at (-1) should be [perspective(300px)] +PASS CSS Transitions: property <transform> from [perspective(400px)] to [perspective(500px)] at (0) should be [perspective(400px)] +PASS CSS Transitions: property <transform> from [perspective(400px)] to [perspective(500px)] at (0.25) should be [perspective(425px)] +PASS CSS Transitions: property <transform> from [perspective(400px)] to [perspective(500px)] at (0.75) should be [perspective(475px)] +PASS CSS Transitions: property <transform> from [perspective(400px)] to [perspective(500px)] at (1) should be [perspective(500px)] +PASS CSS Transitions: property <transform> from [perspective(400px)] to [perspective(500px)] at (2) should be [perspective(600px)] +PASS CSS Transitions with transition: all: property <transform> from [perspective(400px)] to [perspective(500px)] at (-1) should be [perspective(300px)] +PASS CSS Transitions with transition: all: property <transform> from [perspective(400px)] to [perspective(500px)] at (0) should be [perspective(400px)] +PASS CSS Transitions with transition: all: property <transform> from [perspective(400px)] to [perspective(500px)] at (0.25) should be [perspective(425px)] +PASS CSS Transitions with transition: all: property <transform> from [perspective(400px)] to [perspective(500px)] at (0.75) should be [perspective(475px)] +PASS CSS Transitions with transition: all: property <transform> from [perspective(400px)] to [perspective(500px)] at (1) should be [perspective(500px)] +PASS CSS Transitions with transition: all: property <transform> from [perspective(400px)] to [perspective(500px)] at (2) should be [perspective(600px)] +PASS CSS Animations: property <transform> from [perspective(400px)] to [perspective(500px)] at (-1) should be [perspective(300px)] +PASS CSS Animations: property <transform> from [perspective(400px)] to [perspective(500px)] at (0) should be [perspective(400px)] +PASS CSS Animations: property <transform> from [perspective(400px)] to [perspective(500px)] at (0.25) should be [perspective(425px)] +PASS CSS Animations: property <transform> from [perspective(400px)] to [perspective(500px)] at (0.75) should be [perspective(475px)] +PASS CSS Animations: property <transform> from [perspective(400px)] to [perspective(500px)] at (1) should be [perspective(500px)] +PASS CSS Animations: property <transform> from [perspective(400px)] to [perspective(500px)] at (2) should be [perspective(600px)] +PASS Web Animations: property <transform> from [perspective(400px)] to [perspective(500px)] at (-1) should be [perspective(300px)] +PASS Web Animations: property <transform> from [perspective(400px)] to [perspective(500px)] at (0) should be [perspective(400px)] +PASS Web Animations: property <transform> from [perspective(400px)] to [perspective(500px)] at (0.25) should be [perspective(425px)] +PASS Web Animations: property <transform> from [perspective(400px)] to [perspective(500px)] at (0.75) should be [perspective(475px)] +PASS Web Animations: property <transform> from [perspective(400px)] to [perspective(500px)] at (1) should be [perspective(500px)] +PASS Web Animations: property <transform> from [perspective(400px)] to [perspective(500px)] at (2) should be [perspective(600px)] +PASS CSS Transitions: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (-1) should be [skewX(0rad) perspective(300px)] +PASS CSS Transitions: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (0) should be [skewX(10rad) perspective(400px)] +PASS CSS Transitions: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (0.25) should be [skewX(12.5rad) perspective(425px)] +PASS CSS Transitions: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (0.75) should be [skewX(17.5rad) perspective(475px)] +PASS CSS Transitions: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (1) should be [skewX(20rad) perspective(500px)] +PASS CSS Transitions: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (2) should be [skewX(30rad) perspective(600px)] +PASS CSS Transitions with transition: all: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (-1) should be [skewX(0rad) perspective(300px)] +PASS CSS Transitions with transition: all: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (0) should be [skewX(10rad) perspective(400px)] +PASS CSS Transitions with transition: all: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (0.25) should be [skewX(12.5rad) perspective(425px)] +PASS CSS Transitions with transition: all: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (0.75) should be [skewX(17.5rad) perspective(475px)] +PASS CSS Transitions with transition: all: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (1) should be [skewX(20rad) perspective(500px)] +PASS CSS Transitions with transition: all: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (2) should be [skewX(30rad) perspective(600px)] +PASS CSS Animations: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (-1) should be [skewX(0rad) perspective(300px)] +PASS CSS Animations: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (0) should be [skewX(10rad) perspective(400px)] +PASS CSS Animations: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (0.25) should be [skewX(12.5rad) perspective(425px)] +PASS CSS Animations: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (0.75) should be [skewX(17.5rad) perspective(475px)] +PASS CSS Animations: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (1) should be [skewX(20rad) perspective(500px)] +PASS CSS Animations: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (2) should be [skewX(30rad) perspective(600px)] +PASS Web Animations: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (-1) should be [skewX(0rad) perspective(300px)] +PASS Web Animations: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (0) should be [skewX(10rad) perspective(400px)] +PASS Web Animations: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (0.25) should be [skewX(12.5rad) perspective(425px)] +PASS Web Animations: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (0.75) should be [skewX(17.5rad) perspective(475px)] +PASS Web Animations: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (1) should be [skewX(20rad) perspective(500px)] +PASS Web Animations: property <transform> from [skewX(10rad) perspective(400px)] to [skewX(20rad) perspective(500px)] at (2) should be [skewX(30rad) perspective(600px)] +PASS CSS Transitions: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (-1) should be [scaleZ(0) perspective(300px)] +PASS CSS Transitions: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (0) should be [scaleZ(1) perspective(400px)] +PASS CSS Transitions: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (0.25) should be [scaleZ(1.25) perspective(425px)] +PASS CSS Transitions: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (0.75) should be [scaleZ(1.75) perspective(475px)] +PASS CSS Transitions: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (1) should be [scaleZ(2) perspective(500px)] +PASS CSS Transitions: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (2) should be [scaleZ(3) perspective(600px)] +PASS CSS Transitions with transition: all: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (-1) should be [scaleZ(0) perspective(300px)] +PASS CSS Transitions with transition: all: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (0) should be [scaleZ(1) perspective(400px)] +PASS CSS Transitions with transition: all: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (0.25) should be [scaleZ(1.25) perspective(425px)] +PASS CSS Transitions with transition: all: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (0.75) should be [scaleZ(1.75) perspective(475px)] +PASS CSS Transitions with transition: all: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (1) should be [scaleZ(2) perspective(500px)] +PASS CSS Transitions with transition: all: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (2) should be [scaleZ(3) perspective(600px)] +PASS CSS Animations: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (-1) should be [scaleZ(0) perspective(300px)] +PASS CSS Animations: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (0) should be [scaleZ(1) perspective(400px)] +PASS CSS Animations: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (0.25) should be [scaleZ(1.25) perspective(425px)] +PASS CSS Animations: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (0.75) should be [scaleZ(1.75) perspective(475px)] +PASS CSS Animations: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (1) should be [scaleZ(2) perspective(500px)] +PASS CSS Animations: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (2) should be [scaleZ(3) perspective(600px)] +PASS Web Animations: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (-1) should be [scaleZ(0) perspective(300px)] +PASS Web Animations: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (0) should be [scaleZ(1) perspective(400px)] +PASS Web Animations: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (0.25) should be [scaleZ(1.25) perspective(425px)] +PASS Web Animations: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (0.75) should be [scaleZ(1.75) perspective(475px)] +PASS Web Animations: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (1) should be [scaleZ(2) perspective(500px)] +PASS Web Animations: property <transform> from [scaleZ(1) perspective(400px)] to [scaleZ(2) perspective(500px)] at (2) should be [scaleZ(3) perspective(600px)] +PASS CSS Transitions: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (-1) should be [rotate(-270deg)] +PASS CSS Transitions: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (0) should be [rotate(30deg)] +PASS CSS Transitions: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (0.25) should be [rotate(105deg)] +PASS CSS Transitions: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (0.75) should be [rotate(255deg)] +PASS CSS Transitions: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (1) should be [rotate(330deg)] +PASS CSS Transitions: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (2) should be [rotate(630deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (-1) should be [rotate(-270deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (0) should be [rotate(30deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (0.25) should be [rotate(105deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (0.75) should be [rotate(255deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (1) should be [rotate(330deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (2) should be [rotate(630deg)] +PASS CSS Animations: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (-1) should be [rotate(-270deg)] +PASS CSS Animations: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (0) should be [rotate(30deg)] +PASS CSS Animations: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (0.25) should be [rotate(105deg)] +PASS CSS Animations: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (0.75) should be [rotate(255deg)] +PASS CSS Animations: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (1) should be [rotate(330deg)] +PASS CSS Animations: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (2) should be [rotate(630deg)] +PASS Web Animations: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (-1) should be [rotate(-270deg)] +PASS Web Animations: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (0) should be [rotate(30deg)] +PASS Web Animations: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (0.25) should be [rotate(105deg)] +PASS Web Animations: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (0.75) should be [rotate(255deg)] +PASS Web Animations: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (1) should be [rotate(330deg)] +PASS Web Animations: property <transform> from [rotate(30deg)] to [rotate(330deg)] at (2) should be [rotate(630deg)] +PASS CSS Transitions: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (-1) should be [rotateX(-700deg)] +PASS CSS Transitions: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (0) should be [rotateX(0deg)] +PASS CSS Transitions: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (0.25) should be [rotateX(175deg)] +PASS CSS Transitions: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (0.75) should be [rotateX(525deg)] +PASS CSS Transitions: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (1) should be [rotateX(700deg)] +PASS CSS Transitions: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (2) should be [rotateX(1400deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (-1) should be [rotateX(-700deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (0) should be [rotateX(0deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (0.25) should be [rotateX(175deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (0.75) should be [rotateX(525deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (1) should be [rotateX(700deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (2) should be [rotateX(1400deg)] +PASS CSS Animations: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (-1) should be [rotateX(-700deg)] +PASS CSS Animations: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (0) should be [rotateX(0deg)] +PASS CSS Animations: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (0.25) should be [rotateX(175deg)] +PASS CSS Animations: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (0.75) should be [rotateX(525deg)] +PASS CSS Animations: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (1) should be [rotateX(700deg)] +PASS CSS Animations: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (2) should be [rotateX(1400deg)] +PASS Web Animations: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (-1) should be [rotateX(-700deg)] +PASS Web Animations: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (0) should be [rotateX(0deg)] +PASS Web Animations: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (0.25) should be [rotateX(175deg)] +PASS Web Animations: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (0.75) should be [rotateX(525deg)] +PASS Web Animations: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (1) should be [rotateX(700deg)] +PASS Web Animations: property <transform> from [rotateX(0deg)] to [rotateX(700deg)] at (2) should be [rotateX(1400deg)] +PASS CSS Transitions: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (-1) should be [rotateY(-800deg)] +PASS CSS Transitions: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (0) should be [rotateY(0deg)] +PASS CSS Transitions: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (0.25) should be [rotateY(200deg)] +PASS CSS Transitions: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (0.75) should be [rotateY(600deg)] +PASS CSS Transitions: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (1) should be [rotateY(800deg)] +PASS CSS Transitions: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (2) should be [rotateY(1600deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (-1) should be [rotateY(-800deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (0) should be [rotateY(0deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (0.25) should be [rotateY(200deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (0.75) should be [rotateY(600deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (1) should be [rotateY(800deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (2) should be [rotateY(1600deg)] +PASS CSS Animations: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (-1) should be [rotateY(-800deg)] +PASS CSS Animations: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (0) should be [rotateY(0deg)] +PASS CSS Animations: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (0.25) should be [rotateY(200deg)] +PASS CSS Animations: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (0.75) should be [rotateY(600deg)] +PASS CSS Animations: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (1) should be [rotateY(800deg)] +PASS CSS Animations: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (2) should be [rotateY(1600deg)] +PASS Web Animations: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (-1) should be [rotateY(-800deg)] +PASS Web Animations: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (0) should be [rotateY(0deg)] +PASS Web Animations: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (0.25) should be [rotateY(200deg)] +PASS Web Animations: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (0.75) should be [rotateY(600deg)] +PASS Web Animations: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (1) should be [rotateY(800deg)] +PASS Web Animations: property <transform> from [rotateY(0deg)] to [rotateY(800deg)] at (2) should be [rotateY(1600deg)] +PASS CSS Transitions: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (-1) should be [rotateZ(-900deg)] +PASS CSS Transitions: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (0) should be [rotateZ(0deg)] +PASS CSS Transitions: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (0.25) should be [rotateZ(225deg)] +PASS CSS Transitions: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (0.75) should be [rotateZ(675deg)] +PASS CSS Transitions: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (1) should be [rotateZ(900deg)] +PASS CSS Transitions: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (2) should be [rotateZ(1800deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (-1) should be [rotateZ(-900deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (0) should be [rotateZ(0deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (0.25) should be [rotateZ(225deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (0.75) should be [rotateZ(675deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (1) should be [rotateZ(900deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (2) should be [rotateZ(1800deg)] +PASS CSS Animations: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (-1) should be [rotateZ(-900deg)] +PASS CSS Animations: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (0) should be [rotateZ(0deg)] +PASS CSS Animations: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (0.25) should be [rotateZ(225deg)] +PASS CSS Animations: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (0.75) should be [rotateZ(675deg)] +PASS CSS Animations: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (1) should be [rotateZ(900deg)] +PASS CSS Animations: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (2) should be [rotateZ(1800deg)] +PASS Web Animations: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (-1) should be [rotateZ(-900deg)] +PASS Web Animations: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (0) should be [rotateZ(0deg)] +PASS Web Animations: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (0.25) should be [rotateZ(225deg)] +PASS Web Animations: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (0.75) should be [rotateZ(675deg)] +PASS Web Animations: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (1) should be [rotateZ(900deg)] +PASS Web Animations: property <transform> from [rotateZ(0deg)] to [rotateZ(900deg)] at (2) should be [rotateZ(1800deg)] +PASS CSS Transitions: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (-1) should be [rotateY(-900deg)] +PASS CSS Transitions: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (0) should be [rotateY(0deg)] +PASS CSS Transitions: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (0.25) should be [rotateY(225deg)] +PASS CSS Transitions: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (0.75) should be [rotateY(675deg)] +PASS CSS Transitions: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (1) should be [rotateY(900deg)] +PASS CSS Transitions: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (2) should be [rotateY(1800deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (-1) should be [rotateY(-900deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (0) should be [rotateY(0deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (0.25) should be [rotateY(225deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (0.75) should be [rotateY(675deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (1) should be [rotateY(900deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (2) should be [rotateY(1800deg)] +PASS CSS Animations: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (-1) should be [rotateY(-900deg)] +PASS CSS Animations: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (0) should be [rotateY(0deg)] +PASS CSS Animations: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (0.25) should be [rotateY(225deg)] +PASS CSS Animations: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (0.75) should be [rotateY(675deg)] +PASS CSS Animations: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (1) should be [rotateY(900deg)] +PASS CSS Animations: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (2) should be [rotateY(1800deg)] +PASS Web Animations: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (-1) should be [rotateY(-900deg)] +PASS Web Animations: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (0) should be [rotateY(0deg)] +PASS Web Animations: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (0.25) should be [rotateY(225deg)] +PASS Web Animations: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (0.75) should be [rotateY(675deg)] +PASS Web Animations: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (1) should be [rotateY(900deg)] +PASS Web Animations: property <transform> from [rotateX(0deg)] to [rotateY(900deg)] at (2) should be [rotateY(1800deg)] +PASS CSS Transitions: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (-1) should be [rotateY(1800deg)] +PASS CSS Transitions: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (0) should be [rotateY(900deg)] +PASS CSS Transitions: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (0.25) should be [rotateY(675deg)] +PASS CSS Transitions: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (0.75) should be [rotateY(225deg)] +PASS CSS Transitions: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (1) should be [rotateY(0deg)] +PASS CSS Transitions: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (2) should be [rotateY(-900deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (-1) should be [rotateY(1800deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (0) should be [rotateY(900deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (0.25) should be [rotateY(675deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (0.75) should be [rotateY(225deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (1) should be [rotateY(0deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (2) should be [rotateY(-900deg)] +PASS CSS Animations: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (-1) should be [rotateY(1800deg)] +PASS CSS Animations: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (0) should be [rotateY(900deg)] +PASS CSS Animations: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (0.25) should be [rotateY(675deg)] +PASS CSS Animations: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (0.75) should be [rotateY(225deg)] +PASS CSS Animations: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (1) should be [rotateY(0deg)] +PASS CSS Animations: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (2) should be [rotateY(-900deg)] +PASS Web Animations: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (-1) should be [rotateY(1800deg)] +PASS Web Animations: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (0) should be [rotateY(900deg)] +PASS Web Animations: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (0.25) should be [rotateY(675deg)] +PASS Web Animations: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (0.75) should be [rotateY(225deg)] +PASS Web Animations: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (1) should be [rotateY(0deg)] +PASS Web Animations: property <transform> from [rotateY(900deg)] to [rotateZ(0deg)] at (2) should be [rotateY(-900deg)] +PASS CSS Transitions: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (-1) should be [rotate3d(7, 8, 9, -60deg)] +PASS CSS Transitions: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (0) should be [rotate3d(7, 8, 9, 100deg)] +PASS CSS Transitions: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (0.25) should be [rotate3d(7, 8, 9, 140deg)] +PASS CSS Transitions: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (0.75) should be [rotate3d(7, 8, 9, 220deg)] +PASS CSS Transitions: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (1) should be [rotate3d(7, 8, 9, 260deg)] +PASS CSS Transitions: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (2) should be [rotate3d(7, 8, 9, 420deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (-1) should be [rotate3d(7, 8, 9, -60deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (0) should be [rotate3d(7, 8, 9, 100deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (0.25) should be [rotate3d(7, 8, 9, 140deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (0.75) should be [rotate3d(7, 8, 9, 220deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (1) should be [rotate3d(7, 8, 9, 260deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (2) should be [rotate3d(7, 8, 9, 420deg)] +PASS CSS Animations: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (-1) should be [rotate3d(7, 8, 9, -60deg)] +PASS CSS Animations: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (0) should be [rotate3d(7, 8, 9, 100deg)] +PASS CSS Animations: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (0.25) should be [rotate3d(7, 8, 9, 140deg)] +PASS CSS Animations: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (0.75) should be [rotate3d(7, 8, 9, 220deg)] +PASS CSS Animations: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (1) should be [rotate3d(7, 8, 9, 260deg)] +PASS CSS Animations: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (2) should be [rotate3d(7, 8, 9, 420deg)] +PASS Web Animations: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (-1) should be [rotate3d(7, 8, 9, -60deg)] +PASS Web Animations: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (0) should be [rotate3d(7, 8, 9, 100deg)] +PASS Web Animations: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (0.25) should be [rotate3d(7, 8, 9, 140deg)] +PASS Web Animations: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (0.75) should be [rotate3d(7, 8, 9, 220deg)] +PASS Web Animations: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (1) should be [rotate3d(7, 8, 9, 260deg)] +PASS Web Animations: property <transform> from [rotate3d(7, 8, 9, 100deg)] to [rotate3d(7, 8, 9, 260deg)] at (2) should be [rotate3d(7, 8, 9, 420deg)] +PASS CSS Transitions: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (-1) should be [rotate3d(7, 8, 9, -450deg)] +PASS CSS Transitions: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (0) should be [rotate3d(7, 8, 9, 0deg)] +PASS CSS Transitions: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (0.25) should be [rotate3d(7, 8, 9, 112.5deg)] +PASS CSS Transitions: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (0.75) should be [rotate3d(7, 8, 9, 337.5deg)] +PASS CSS Transitions: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (1) should be [rotate3d(7, 8, 9, 450deg)] +PASS CSS Transitions: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (2) should be [rotate3d(7, 8, 9, 900deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (-1) should be [rotate3d(7, 8, 9, -450deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (0) should be [rotate3d(7, 8, 9, 0deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (0.25) should be [rotate3d(7, 8, 9, 112.5deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (0.75) should be [rotate3d(7, 8, 9, 337.5deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (1) should be [rotate3d(7, 8, 9, 450deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (2) should be [rotate3d(7, 8, 9, 900deg)] +PASS CSS Animations: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (-1) should be [rotate3d(7, 8, 9, -450deg)] +PASS CSS Animations: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (0) should be [rotate3d(7, 8, 9, 0deg)] +PASS CSS Animations: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (0.25) should be [rotate3d(7, 8, 9, 112.5deg)] +PASS CSS Animations: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (0.75) should be [rotate3d(7, 8, 9, 337.5deg)] +PASS CSS Animations: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (1) should be [rotate3d(7, 8, 9, 450deg)] +PASS CSS Animations: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (2) should be [rotate3d(7, 8, 9, 900deg)] +PASS Web Animations: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (-1) should be [rotate3d(7, 8, 9, -450deg)] +PASS Web Animations: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (0) should be [rotate3d(7, 8, 9, 0deg)] +PASS Web Animations: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (0.25) should be [rotate3d(7, 8, 9, 112.5deg)] +PASS Web Animations: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (0.75) should be [rotate3d(7, 8, 9, 337.5deg)] +PASS Web Animations: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (1) should be [rotate3d(7, 8, 9, 450deg)] +PASS Web Animations: property <transform> from [rotate3d(7, 8, 9, 0deg)] to [rotate3d(7, 8, 9, 450deg)] at (2) should be [rotate3d(7, 8, 9, 900deg)] +PASS CSS Transitions: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (-1) should be [rotate3d(0, 1, 0, -450deg)] +PASS CSS Transitions: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (0) should be [rotate3d(0, 1, 0, 0deg)] +PASS CSS Transitions: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (0.25) should be [rotate3d(0, 1, 0, 112.5deg)] +PASS CSS Transitions: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (0.75) should be [rotate3d(0, 1, 0, 337.5deg)] +PASS CSS Transitions: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (1) should be [rotate3d(0, 1, 0, 450deg)] +PASS CSS Transitions: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (2) should be [rotate3d(0, 1, 0, 900deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (-1) should be [rotate3d(0, 1, 0, -450deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (0) should be [rotate3d(0, 1, 0, 0deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (0.25) should be [rotate3d(0, 1, 0, 112.5deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (0.75) should be [rotate3d(0, 1, 0, 337.5deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (1) should be [rotate3d(0, 1, 0, 450deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (2) should be [rotate3d(0, 1, 0, 900deg)] +PASS CSS Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (-1) should be [rotate3d(0, 1, 0, -450deg)] +PASS CSS Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (0) should be [rotate3d(0, 1, 0, 0deg)] +PASS CSS Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (0.25) should be [rotate3d(0, 1, 0, 112.5deg)] +PASS CSS Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (0.75) should be [rotate3d(0, 1, 0, 337.5deg)] +PASS CSS Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (1) should be [rotate3d(0, 1, 0, 450deg)] +PASS CSS Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (2) should be [rotate3d(0, 1, 0, 900deg)] +PASS Web Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (-1) should be [rotate3d(0, 1, 0, -450deg)] +PASS Web Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (0) should be [rotate3d(0, 1, 0, 0deg)] +PASS Web Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (0.25) should be [rotate3d(0, 1, 0, 112.5deg)] +PASS Web Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (0.75) should be [rotate3d(0, 1, 0, 337.5deg)] +PASS Web Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (1) should be [rotate3d(0, 1, 0, 450deg)] +PASS Web Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 1, 0, 450deg)] at (2) should be [rotate3d(0, 1, 0, 900deg)] +PASS CSS Transitions: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (-1) should be [rotate3d(0, 1, 0, -450deg)] +PASS CSS Transitions: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (0) should be [rotate3d(0, 1, 0, 0deg)] +PASS CSS Transitions: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (0.25) should be [rotate3d(0, 1, 0, 112.5deg)] +PASS CSS Transitions: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (0.75) should be [rotate3d(0, 1, 0, 337.5deg)] +PASS CSS Transitions: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (1) should be [rotate3d(0, 1, 0, 450deg)] +PASS CSS Transitions: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (2) should be [rotate3d(0, 1, 0, 900deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (-1) should be [rotate3d(0, 1, 0, -450deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (0) should be [rotate3d(0, 1, 0, 0deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (0.25) should be [rotate3d(0, 1, 0, 112.5deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (0.75) should be [rotate3d(0, 1, 0, 337.5deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (1) should be [rotate3d(0, 1, 0, 450deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (2) should be [rotate3d(0, 1, 0, 900deg)] +PASS CSS Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (-1) should be [rotate3d(0, 1, 0, -450deg)] +PASS CSS Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (0) should be [rotate3d(0, 1, 0, 0deg)] +PASS CSS Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (0.25) should be [rotate3d(0, 1, 0, 112.5deg)] +PASS CSS Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (0.75) should be [rotate3d(0, 1, 0, 337.5deg)] +PASS CSS Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (1) should be [rotate3d(0, 1, 0, 450deg)] +PASS CSS Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (2) should be [rotate3d(0, 1, 0, 900deg)] +PASS Web Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (-1) should be [rotate3d(0, 1, 0, -450deg)] +PASS Web Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (0) should be [rotate3d(0, 1, 0, 0deg)] +PASS Web Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (0.25) should be [rotate3d(0, 1, 0, 112.5deg)] +PASS Web Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (0.75) should be [rotate3d(0, 1, 0, 337.5deg)] +PASS Web Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (1) should be [rotate3d(0, 1, 0, 450deg)] +PASS Web Animations: property <transform> from [rotate3d(0, 1, 0, 0deg)] to [rotate3d(0, 2, 0, 450deg)] at (2) should be [rotate3d(0, 1, 0, 900deg)] +PASS CSS Transitions: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (-1) should be [rotate3d(0.41, -0.41, -0.82, 120deg)] +PASS CSS Transitions: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (0) should be [rotate3d(1, 1, 0, 90deg)] +FAIL CSS Transitions: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (0.25) should be [rotate3d(0.524083, 0.804261, 0.280178, 106.91deg)] assert_equals: expected "matrix3d ( 0.06 , 0.81 , - 0.58 , 0 , 0.28 , 0.54 , 0.79 , 0 , 0.96 , - 0.21 , - 0.19 , 0 , 0 , 0 , 0 , 1 ) " but got "matrix3d ( 0.69 , - 0.34 , - 0.64 , 0 , 0.72 , 0.19 , 0.67 , 0 , - 0.1 , - 0.92 , 0.37 , 0 , 0 , 0 , 0 , 1 ) " +FAIL CSS Transitions: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (0.75) should be [rotate3d(0.163027, 0.774382, 0.611354, 153.99deg)] assert_equals: expected "matrix3d ( - 0.85 , 0.51 , - 0.15 , 0 , - 0.03 , 0.24 , 0.97 , 0 , 0.53 , 0.83 , - 0.19 , 0 , 0 , 0 , 0 , 1 ) " but got "matrix3d ( - 0.63 , - 0.78 , - 0.02 , 0 , 0.28 , - 0.25 , 0.93 , 0 , - 0.73 , 0.58 , 0.37 , 0 , 0 , 0 , 0 , 1 ) " +PASS CSS Transitions: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (1) should be [rotate3d(0, 1, 1, 180deg)] +PASS CSS Transitions: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (2) should be [rotate3d(0.71, 0, -0.71, 90deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (-1) should be [rotate3d(0.41, -0.41, -0.82, 120deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (0) should be [rotate3d(1, 1, 0, 90deg)] +FAIL CSS Transitions with transition: all: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (0.25) should be [rotate3d(0.524083, 0.804261, 0.280178, 106.91deg)] assert_equals: expected "matrix3d ( 0.06 , 0.81 , - 0.58 , 0 , 0.28 , 0.54 , 0.79 , 0 , 0.96 , - 0.21 , - 0.19 , 0 , 0 , 0 , 0 , 1 ) " but got "matrix3d ( 0.69 , - 0.34 , - 0.64 , 0 , 0.72 , 0.19 , 0.67 , 0 , - 0.1 , - 0.92 , 0.37 , 0 , 0 , 0 , 0 , 1 ) " +FAIL CSS Transitions with transition: all: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (0.75) should be [rotate3d(0.163027, 0.774382, 0.611354, 153.99deg)] assert_equals: expected "matrix3d ( - 0.85 , 0.51 , - 0.15 , 0 , - 0.03 , 0.24 , 0.97 , 0 , 0.53 , 0.83 , - 0.19 , 0 , 0 , 0 , 0 , 1 ) " but got "matrix3d ( - 0.63 , - 0.78 , - 0.02 , 0 , 0.28 , - 0.25 , 0.93 , 0 , - 0.73 , 0.58 , 0.37 , 0 , 0 , 0 , 0 , 1 ) " +PASS CSS Transitions with transition: all: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (1) should be [rotate3d(0, 1, 1, 180deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (2) should be [rotate3d(0.71, 0, -0.71, 90deg)] +PASS CSS Animations: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (-1) should be [rotate3d(0.41, -0.41, -0.82, 120deg)] +PASS CSS Animations: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (0) should be [rotate3d(1, 1, 0, 90deg)] +FAIL CSS Animations: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (0.25) should be [rotate3d(0.524083, 0.804261, 0.280178, 106.91deg)] assert_equals: expected "matrix3d ( 0.06 , 0.81 , - 0.58 , 0 , 0.28 , 0.54 , 0.79 , 0 , 0.96 , - 0.21 , - 0.19 , 0 , 0 , 0 , 0 , 1 ) " but got "matrix3d ( 0.69 , - 0.34 , - 0.64 , 0 , 0.72 , 0.19 , 0.67 , 0 , - 0.1 , - 0.92 , 0.37 , 0 , 0 , 0 , 0 , 1 ) " +FAIL CSS Animations: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (0.75) should be [rotate3d(0.163027, 0.774382, 0.611354, 153.99deg)] assert_equals: expected "matrix3d ( - 0.85 , 0.51 , - 0.15 , 0 , - 0.03 , 0.24 , 0.97 , 0 , 0.53 , 0.83 , - 0.19 , 0 , 0 , 0 , 0 , 1 ) " but got "matrix3d ( - 0.63 , - 0.78 , - 0.02 , 0 , 0.28 , - 0.25 , 0.93 , 0 , - 0.73 , 0.58 , 0.37 , 0 , 0 , 0 , 0 , 1 ) " +PASS CSS Animations: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (1) should be [rotate3d(0, 1, 1, 180deg)] +PASS CSS Animations: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (2) should be [rotate3d(0.71, 0, -0.71, 90deg)] +PASS Web Animations: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (-1) should be [rotate3d(0.41, -0.41, -0.82, 120deg)] +PASS Web Animations: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (0) should be [rotate3d(1, 1, 0, 90deg)] +FAIL Web Animations: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (0.25) should be [rotate3d(0.524083, 0.804261, 0.280178, 106.91deg)] assert_equals: expected "matrix3d ( 0.06 , 0.81 , - 0.58 , 0 , 0.28 , 0.54 , 0.79 , 0 , 0.96 , - 0.21 , - 0.19 , 0 , 0 , 0 , 0 , 1 ) " but got "matrix3d ( 0.69 , - 0.34 , - 0.64 , 0 , 0.72 , 0.19 , 0.67 , 0 , - 0.1 , - 0.92 , 0.37 , 0 , 0 , 0 , 0 , 1 ) " +FAIL Web Animations: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (0.75) should be [rotate3d(0.163027, 0.774382, 0.611354, 153.99deg)] assert_equals: expected "matrix3d ( - 0.85 , 0.51 , - 0.15 , 0 , - 0.03 , 0.24 , 0.97 , 0 , 0.53 , 0.83 , - 0.19 , 0 , 0 , 0 , 0 , 1 ) " but got "matrix3d ( - 0.63 , - 0.78 , - 0.02 , 0 , 0.28 , - 0.25 , 0.93 , 0 , - 0.73 , 0.58 , 0.37 , 0 , 0 , 0 , 0 , 1 ) " +PASS Web Animations: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (1) should be [rotate3d(0, 1, 1, 180deg)] +PASS Web Animations: property <transform> from [rotate3d(1, 1, 0, 90deg)] to [rotate3d(0, 1, 1, 180deg)] at (2) should be [rotate3d(0.71, 0, -0.71, 90deg)] +PASS CSS Transitions: property <transform> from [none] to [rotate(90deg)] at (-1) should be [rotate(-90deg)] +PASS CSS Transitions: property <transform> from [none] to [rotate(90deg)] at (0) should be [rotate(0deg)] +PASS CSS Transitions: property <transform> from [none] to [rotate(90deg)] at (0.25) should be [rotate(22.5deg)] +PASS CSS Transitions: property <transform> from [none] to [rotate(90deg)] at (0.75) should be [rotate(67.5deg)] +PASS CSS Transitions: property <transform> from [none] to [rotate(90deg)] at (1) should be [rotate(90deg)] +PASS CSS Transitions: property <transform> from [none] to [rotate(90deg)] at (2) should be [rotate(180deg)] +PASS CSS Transitions with transition: all: property <transform> from [none] to [rotate(90deg)] at (-1) should be [rotate(-90deg)] +PASS CSS Transitions with transition: all: property <transform> from [none] to [rotate(90deg)] at (0) should be [rotate(0deg)] +PASS CSS Transitions with transition: all: property <transform> from [none] to [rotate(90deg)] at (0.25) should be [rotate(22.5deg)] +PASS CSS Transitions with transition: all: property <transform> from [none] to [rotate(90deg)] at (0.75) should be [rotate(67.5deg)] +PASS CSS Transitions with transition: all: property <transform> from [none] to [rotate(90deg)] at (1) should be [rotate(90deg)] +PASS CSS Transitions with transition: all: property <transform> from [none] to [rotate(90deg)] at (2) should be [rotate(180deg)] +PASS CSS Animations: property <transform> from [none] to [rotate(90deg)] at (-1) should be [rotate(-90deg)] +PASS CSS Animations: property <transform> from [none] to [rotate(90deg)] at (0) should be [rotate(0deg)] +PASS CSS Animations: property <transform> from [none] to [rotate(90deg)] at (0.25) should be [rotate(22.5deg)] +PASS CSS Animations: property <transform> from [none] to [rotate(90deg)] at (0.75) should be [rotate(67.5deg)] +PASS CSS Animations: property <transform> from [none] to [rotate(90deg)] at (1) should be [rotate(90deg)] +PASS CSS Animations: property <transform> from [none] to [rotate(90deg)] at (2) should be [rotate(180deg)] +PASS Web Animations: property <transform> from [none] to [rotate(90deg)] at (-1) should be [rotate(-90deg)] +PASS Web Animations: property <transform> from [none] to [rotate(90deg)] at (0) should be [rotate(0deg)] +PASS Web Animations: property <transform> from [none] to [rotate(90deg)] at (0.25) should be [rotate(22.5deg)] +PASS Web Animations: property <transform> from [none] to [rotate(90deg)] at (0.75) should be [rotate(67.5deg)] +PASS Web Animations: property <transform> from [none] to [rotate(90deg)] at (1) should be [rotate(90deg)] +PASS Web Animations: property <transform> from [none] to [rotate(90deg)] at (2) should be [rotate(180deg)] +PASS CSS Transitions: property <transform> from [rotate(90deg)] to [none] at (-1) should be [rotate(180deg)] +PASS CSS Transitions: property <transform> from [rotate(90deg)] to [none] at (0) should be [rotate(90deg)] +PASS CSS Transitions: property <transform> from [rotate(90deg)] to [none] at (0.25) should be [rotate(67.5deg)] +PASS CSS Transitions: property <transform> from [rotate(90deg)] to [none] at (0.75) should be [rotate(22.5deg)] +PASS CSS Transitions: property <transform> from [rotate(90deg)] to [none] at (1) should be [rotate(0deg)] +PASS CSS Transitions: property <transform> from [rotate(90deg)] to [none] at (2) should be [rotate(-90deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate(90deg)] to [none] at (-1) should be [rotate(180deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate(90deg)] to [none] at (0) should be [rotate(90deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate(90deg)] to [none] at (0.25) should be [rotate(67.5deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate(90deg)] to [none] at (0.75) should be [rotate(22.5deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate(90deg)] to [none] at (1) should be [rotate(0deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotate(90deg)] to [none] at (2) should be [rotate(-90deg)] +PASS CSS Animations: property <transform> from [rotate(90deg)] to [none] at (-1) should be [rotate(180deg)] +PASS CSS Animations: property <transform> from [rotate(90deg)] to [none] at (0) should be [rotate(90deg)] +PASS CSS Animations: property <transform> from [rotate(90deg)] to [none] at (0.25) should be [rotate(67.5deg)] +PASS CSS Animations: property <transform> from [rotate(90deg)] to [none] at (0.75) should be [rotate(22.5deg)] +PASS CSS Animations: property <transform> from [rotate(90deg)] to [none] at (1) should be [rotate(0deg)] +PASS CSS Animations: property <transform> from [rotate(90deg)] to [none] at (2) should be [rotate(-90deg)] +PASS Web Animations: property <transform> from [rotate(90deg)] to [none] at (-1) should be [rotate(180deg)] +PASS Web Animations: property <transform> from [rotate(90deg)] to [none] at (0) should be [rotate(90deg)] +PASS Web Animations: property <transform> from [rotate(90deg)] to [none] at (0.25) should be [rotate(67.5deg)] +PASS Web Animations: property <transform> from [rotate(90deg)] to [none] at (0.75) should be [rotate(22.5deg)] +PASS Web Animations: property <transform> from [rotate(90deg)] to [none] at (1) should be [rotate(0deg)] +PASS Web Animations: property <transform> from [rotate(90deg)] to [none] at (2) should be [rotate(-90deg)] +PASS CSS Transitions: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (-1) should be [rotateX(-700deg) rotateY(-800deg) rotateZ(-900deg)] +PASS CSS Transitions: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (0) should be [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] +PASS CSS Transitions: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (0.25) should be [rotateX(175deg) rotateY(200deg) rotateZ(225deg)] +PASS CSS Transitions: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (0.75) should be [rotateX(525deg) rotateY(600deg) rotateZ(675deg)] +PASS CSS Transitions: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (1) should be [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] +PASS CSS Transitions: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (2) should be [rotateX(1400deg) rotateY(1600deg) rotateZ(1800deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (-1) should be [rotateX(-700deg) rotateY(-800deg) rotateZ(-900deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (0) should be [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (0.25) should be [rotateX(175deg) rotateY(200deg) rotateZ(225deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (0.75) should be [rotateX(525deg) rotateY(600deg) rotateZ(675deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (1) should be [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] +PASS CSS Transitions with transition: all: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (2) should be [rotateX(1400deg) rotateY(1600deg) rotateZ(1800deg)] +PASS CSS Animations: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (-1) should be [rotateX(-700deg) rotateY(-800deg) rotateZ(-900deg)] +PASS CSS Animations: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (0) should be [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] +PASS CSS Animations: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (0.25) should be [rotateX(175deg) rotateY(200deg) rotateZ(225deg)] +PASS CSS Animations: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (0.75) should be [rotateX(525deg) rotateY(600deg) rotateZ(675deg)] +PASS CSS Animations: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (1) should be [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] +PASS CSS Animations: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (2) should be [rotateX(1400deg) rotateY(1600deg) rotateZ(1800deg)] +PASS Web Animations: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (-1) should be [rotateX(-700deg) rotateY(-800deg) rotateZ(-900deg)] +PASS Web Animations: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (0) should be [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] +PASS Web Animations: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (0.25) should be [rotateX(175deg) rotateY(200deg) rotateZ(225deg)] +PASS Web Animations: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (0.75) should be [rotateX(525deg) rotateY(600deg) rotateZ(675deg)] +PASS Web Animations: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (1) should be [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] +PASS Web Animations: property <transform> from [rotateX(0deg) rotateY(0deg) rotateZ(0deg)] to [rotateX(700deg) rotateY(800deg) rotateZ(900deg)] at (2) should be [rotateX(1400deg) rotateY(1600deg) rotateZ(1800deg)] Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-values/percentage-rem-low.html b/third_party/blink/web_tests/external/wpt/css/css-values/percentage-rem-low.html new file mode 100644 index 0000000..d06e752 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-values/percentage-rem-low.html
@@ -0,0 +1,22 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>REM value with :root set to low percentage</title> +<link rel="author" title="Jon Ege Ronnenberg" href="mailto:jon.ronnenberg+wpt@gmail.com"> +<link rel="help" href="https://drafts.csswg.org/css-values/#rem"> +<link rel="help" href="https://drafts.csswg.org/css-fonts/#length-percentage-size-value"> +<link rel="match" href="../reference/ref-filled-green-100px-square-only.html"> +<meta name="assert" content="When :root font-size is 25%, a 25rem length must be 100px, if the browser default for :root font-size is 16px."> +<style> + :root { + /* default is 16px in all desktop browsers */ + /* the math for 100px is: 16px * 0.25 = 4px/rem -> 100px / 4px/rem = 25rem = 100px */ + font-size: 25%; + } + .rem { + width: 25rem; + height: 25rem; + background-color: green; + } +</style> +<p style="font-size:initial;">Test passes if there is a filled green square.</p> +<div class="rem"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/wm-propagation-svg-root-scrollbar.svg b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/wm-propagation-svg-root-scrollbar.svg new file mode 100644 index 0000000..a9a7b25 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/wm-propagation-svg-root-scrollbar.svg
@@ -0,0 +1,11 @@ +<svg xmlns="http://www.w3.org/2000/svg" xmlns:html="http://www.w3.org/1999/xhtml" width="2000px" height="100px" style="direction: rtl;"> + <g id="testmeta"> + <title>CSS-Writing Modes Test: Principal Writing Mode</title> + <html:link rel="author" title="Ting-Yu Lin" href="tlin@mozilla.com"/> + <html:link rel="author" title="Mozilla" href="https://mozilla.org/"/> + <html:link rel="help" href="https://drafts.csswg.org/css-writing-modes-3/#principal-flow"/> + <html:link rel="mismatch" href="../reference/blank.html"/> + <decs class="assert">This test verifies setting "direction:rtl" on the svg root + with a large width can generate a horizontal scroll bar.</decs> + </g> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/animation/backdrop-filter-interpolation-001-expected.txt b/third_party/blink/web_tests/external/wpt/css/filter-effects/animation/backdrop-filter-interpolation-001-expected.txt index 906f04f..f54727b 100644 --- a/third_party/blink/web_tests/external/wpt/css/filter-effects/animation/backdrop-filter-interpolation-001-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/animation/backdrop-filter-interpolation-001-expected.txt
@@ -24,30 +24,30 @@ PASS Web Animations: property <backdrop-filter> from [hue-rotate(0deg) blur(6px)] to [hue-rotate(180deg) blur(10px)] at (0.5) should be [hue-rotate(90deg) blur(8px)] PASS Web Animations: property <backdrop-filter> from [hue-rotate(0deg) blur(6px)] to [hue-rotate(180deg) blur(10px)] at (1) should be [hue-rotate(180deg) blur(10px)] PASS Web Animations: property <backdrop-filter> from [hue-rotate(0deg) blur(6px)] to [hue-rotate(180deg) blur(10px)] at (1.5) should be [hue-rotate(270deg) blur(12px)] -PASS CSS Transitions: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (-0.5) should be [hue-rotate(75deg) blur(15.1181px)] -PASS CSS Transitions: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0) should be [hue-rotate(80deg) blur(22.6772px)] -PASS CSS Transitions: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0.25) should be [hue-rotate(82.5deg) blur(26.4567px)] -PASS CSS Transitions: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0.5) should be [hue-rotate(85deg) blur(30.2362px)] -PASS CSS Transitions: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (1) should be [hue-rotate(90deg) blur(37.7953px)] -PASS CSS Transitions: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (1.5) should be [hue-rotate(95deg) blur(45.3543px)] -PASS CSS Transitions with transition: all: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (-0.5) should be [hue-rotate(75deg) blur(15.1181px)] -PASS CSS Transitions with transition: all: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0) should be [hue-rotate(80deg) blur(22.6772px)] -PASS CSS Transitions with transition: all: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0.25) should be [hue-rotate(82.5deg) blur(26.4567px)] -PASS CSS Transitions with transition: all: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0.5) should be [hue-rotate(85deg) blur(30.2362px)] -PASS CSS Transitions with transition: all: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (1) should be [hue-rotate(90deg) blur(37.7953px)] -PASS CSS Transitions with transition: all: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (1.5) should be [hue-rotate(95deg) blur(45.3543px)] -PASS CSS Animations: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (-0.5) should be [hue-rotate(75deg) blur(15.1181px)] -PASS CSS Animations: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0) should be [hue-rotate(80deg) blur(22.6772px)] -PASS CSS Animations: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0.25) should be [hue-rotate(82.5deg) blur(26.4567px)] -PASS CSS Animations: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0.5) should be [hue-rotate(85deg) blur(30.2362px)] -PASS CSS Animations: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (1) should be [hue-rotate(90deg) blur(37.7953px)] -PASS CSS Animations: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (1.5) should be [hue-rotate(95deg) blur(45.3543px)] -PASS Web Animations: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (-0.5) should be [hue-rotate(75deg) blur(15.1181px)] -PASS Web Animations: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0) should be [hue-rotate(80deg) blur(22.6772px)] -PASS Web Animations: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0.25) should be [hue-rotate(82.5deg) blur(26.4567px)] -PASS Web Animations: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0.5) should be [hue-rotate(85deg) blur(30.2362px)] -PASS Web Animations: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (1) should be [hue-rotate(90deg) blur(37.7953px)] -PASS Web Animations: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (1.5) should be [hue-rotate(95deg) blur(45.3543px)] +PASS CSS Transitions: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (-0.5) should be [hue-rotate(75deg) blur(4mm)] +PASS CSS Transitions: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0) should be [hue-rotate(80deg) blur(6mm)] +PASS CSS Transitions: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0.25) should be [hue-rotate(82.5deg) blur(7mm)] +PASS CSS Transitions: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0.5) should be [hue-rotate(85deg) blur(8mm)] +PASS CSS Transitions: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (1) should be [hue-rotate(90deg) blur(10mm)] +PASS CSS Transitions: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (1.5) should be [hue-rotate(95deg) blur(12mm)] +PASS CSS Transitions with transition: all: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (-0.5) should be [hue-rotate(75deg) blur(4mm)] +PASS CSS Transitions with transition: all: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0) should be [hue-rotate(80deg) blur(6mm)] +PASS CSS Transitions with transition: all: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0.25) should be [hue-rotate(82.5deg) blur(7mm)] +PASS CSS Transitions with transition: all: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0.5) should be [hue-rotate(85deg) blur(8mm)] +PASS CSS Transitions with transition: all: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (1) should be [hue-rotate(90deg) blur(10mm)] +PASS CSS Transitions with transition: all: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (1.5) should be [hue-rotate(95deg) blur(12mm)] +PASS CSS Animations: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (-0.5) should be [hue-rotate(75deg) blur(4mm)] +PASS CSS Animations: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0) should be [hue-rotate(80deg) blur(6mm)] +PASS CSS Animations: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0.25) should be [hue-rotate(82.5deg) blur(7mm)] +PASS CSS Animations: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0.5) should be [hue-rotate(85deg) blur(8mm)] +PASS CSS Animations: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (1) should be [hue-rotate(90deg) blur(10mm)] +PASS CSS Animations: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (1.5) should be [hue-rotate(95deg) blur(12mm)] +PASS Web Animations: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (-0.5) should be [hue-rotate(75deg) blur(4mm)] +PASS Web Animations: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0) should be [hue-rotate(80deg) blur(6mm)] +PASS Web Animations: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0.25) should be [hue-rotate(82.5deg) blur(7mm)] +PASS Web Animations: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0.5) should be [hue-rotate(85deg) blur(8mm)] +PASS Web Animations: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (1) should be [hue-rotate(90deg) blur(10mm)] +PASS Web Animations: property <backdrop-filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (1.5) should be [hue-rotate(95deg) blur(12mm)] PASS CSS Transitions: property <backdrop-filter> from neutral to [hue-rotate(20deg)] at (-0.5) should be [hue-rotate(5deg)] PASS CSS Transitions: property <backdrop-filter> from neutral to [hue-rotate(20deg)] at (0) should be [hue-rotate(10deg)] PASS CSS Transitions: property <backdrop-filter> from neutral to [hue-rotate(20deg)] at (0.3) should be [hue-rotate(13deg)] @@ -192,26 +192,26 @@ PASS Web Animations: property <backdrop-filter> from [hue-rotate(180deg)] to [none] at (0.5) should be [hue-rotate(90deg)] FAIL Web Animations: property <backdrop-filter> from [hue-rotate(180deg)] to [none] at (1) should be [hue-rotate(0deg)] assert_equals: expected "hue - rotate ( 0deg ) " but got "none " PASS Web Animations: property <backdrop-filter> from [hue-rotate(180deg)] to [none] at (1.5) should be [hue-rotate(-90deg)] -PASS CSS Transitions: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (-1) should be [drop-shadow(rgb(255, 255, 255) -20px -10px 0px)] -PASS CSS Transitions: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (0) should be [drop-shadow(rgb(255, 255, 255) 0px 0px 0px)] -PASS CSS Transitions: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (0.5) should be [drop-shadow(rgb(128, 192, 128) 10px 5px 0px)] -PASS CSS Transitions: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (1) should be [drop-shadow(rgb(0, 128, 0) 20px 10px 0px)] -PASS CSS Transitions: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (1.5) should be [drop-shadow(rgb(0, 65, 0) 30px 15px 0px)] -PASS CSS Transitions with transition: all: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (-1) should be [drop-shadow(rgb(255, 255, 255) -20px -10px 0px)] -PASS CSS Transitions with transition: all: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (0) should be [drop-shadow(rgb(255, 255, 255) 0px 0px 0px)] -PASS CSS Transitions with transition: all: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (0.5) should be [drop-shadow(rgb(128, 192, 128) 10px 5px 0px)] -PASS CSS Transitions with transition: all: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (1) should be [drop-shadow(rgb(0, 128, 0) 20px 10px 0px)] -PASS CSS Transitions with transition: all: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (1.5) should be [drop-shadow(rgb(0, 65, 0) 30px 15px 0px)] -PASS CSS Animations: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (-1) should be [drop-shadow(rgb(255, 255, 255) -20px -10px 0px)] -PASS CSS Animations: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (0) should be [drop-shadow(rgb(255, 255, 255) 0px 0px 0px)] -PASS CSS Animations: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (0.5) should be [drop-shadow(rgb(128, 192, 128) 10px 5px 0px)] -PASS CSS Animations: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (1) should be [drop-shadow(rgb(0, 128, 0) 20px 10px 0px)] -PASS CSS Animations: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (1.5) should be [drop-shadow(rgb(0, 65, 0) 30px 15px 0px)] -PASS Web Animations: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (-1) should be [drop-shadow(rgb(255, 255, 255) -20px -10px 0px)] -PASS Web Animations: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (0) should be [drop-shadow(rgb(255, 255, 255) 0px 0px 0px)] -PASS Web Animations: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (0.5) should be [drop-shadow(rgb(128, 192, 128) 10px 5px 0px)] -PASS Web Animations: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (1) should be [drop-shadow(rgb(0, 128, 0) 20px 10px 0px)] -PASS Web Animations: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (1.5) should be [drop-shadow(rgb(0, 65, 0) 30px 15px 0px)] +PASS CSS Transitions: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (-1) should be [drop-shadow(-20px -10px white)] +PASS CSS Transitions: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (0) should be [drop-shadow(0px 0px 0px currentcolor)] +PASS CSS Transitions: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (0.5) should be [drop-shadow(10px 5px #80C080)] +PASS CSS Transitions: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (1) should be [drop-shadow(20px 10px green)] +PASS CSS Transitions: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (1.5) should be [drop-shadow(30px 15px #004100)] +PASS CSS Transitions with transition: all: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (-1) should be [drop-shadow(-20px -10px white)] +PASS CSS Transitions with transition: all: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (0) should be [drop-shadow(0px 0px 0px currentcolor)] +PASS CSS Transitions with transition: all: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (0.5) should be [drop-shadow(10px 5px #80C080)] +PASS CSS Transitions with transition: all: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (1) should be [drop-shadow(20px 10px green)] +PASS CSS Transitions with transition: all: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (1.5) should be [drop-shadow(30px 15px #004100)] +PASS CSS Animations: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (-1) should be [drop-shadow(-20px -10px white)] +PASS CSS Animations: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (0) should be [drop-shadow(0px 0px 0px currentcolor)] +PASS CSS Animations: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (0.5) should be [drop-shadow(10px 5px #80C080)] +PASS CSS Animations: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (1) should be [drop-shadow(20px 10px green)] +PASS CSS Animations: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (1.5) should be [drop-shadow(30px 15px #004100)] +PASS Web Animations: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (-1) should be [drop-shadow(-20px -10px white)] +PASS Web Animations: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (0) should be [drop-shadow(0px 0px 0px currentcolor)] +PASS Web Animations: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (0.5) should be [drop-shadow(10px 5px #80C080)] +PASS Web Animations: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (1) should be [drop-shadow(20px 10px green)] +PASS Web Animations: property <backdrop-filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (1.5) should be [drop-shadow(30px 15px #004100)] PASS CSS Transitions: property <backdrop-filter> from [url("#svgfilter")] to [blur(5px)] at (-0.3) should be [blur(5px)] PASS CSS Transitions: property <backdrop-filter> from [url("#svgfilter")] to [blur(5px)] at (0) should be [blur(5px)] PASS CSS Transitions: property <backdrop-filter> from [url("#svgfilter")] to [blur(5px)] at (0.3) should be [blur(5px)]
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/animation/filter-interpolation-001-expected.txt b/third_party/blink/web_tests/external/wpt/css/filter-effects/animation/filter-interpolation-001-expected.txt index 3823e2f..38b35eb2 100644 --- a/third_party/blink/web_tests/external/wpt/css/filter-effects/animation/filter-interpolation-001-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/animation/filter-interpolation-001-expected.txt
@@ -24,30 +24,30 @@ PASS Web Animations: property <filter> from [hue-rotate(0deg) blur(6px)] to [hue-rotate(180deg) blur(10px)] at (0.5) should be [hue-rotate(90deg) blur(8px)] PASS Web Animations: property <filter> from [hue-rotate(0deg) blur(6px)] to [hue-rotate(180deg) blur(10px)] at (1) should be [hue-rotate(180deg) blur(10px)] PASS Web Animations: property <filter> from [hue-rotate(0deg) blur(6px)] to [hue-rotate(180deg) blur(10px)] at (1.5) should be [hue-rotate(270deg) blur(12px)] -PASS CSS Transitions: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (-0.5) should be [hue-rotate(75deg) blur(15.1181px)] -PASS CSS Transitions: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0) should be [hue-rotate(80deg) blur(22.6772px)] -PASS CSS Transitions: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0.25) should be [hue-rotate(82.5deg) blur(26.4567px)] -PASS CSS Transitions: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0.5) should be [hue-rotate(85deg) blur(30.2362px)] -PASS CSS Transitions: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (1) should be [hue-rotate(90deg) blur(37.7953px)] -PASS CSS Transitions: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (1.5) should be [hue-rotate(95deg) blur(45.3543px)] -PASS CSS Transitions with transition: all: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (-0.5) should be [hue-rotate(75deg) blur(15.1181px)] -PASS CSS Transitions with transition: all: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0) should be [hue-rotate(80deg) blur(22.6772px)] -PASS CSS Transitions with transition: all: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0.25) should be [hue-rotate(82.5deg) blur(26.4567px)] -PASS CSS Transitions with transition: all: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0.5) should be [hue-rotate(85deg) blur(30.2362px)] -PASS CSS Transitions with transition: all: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (1) should be [hue-rotate(90deg) blur(37.7953px)] -PASS CSS Transitions with transition: all: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (1.5) should be [hue-rotate(95deg) blur(45.3543px)] -PASS CSS Animations: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (-0.5) should be [hue-rotate(75deg) blur(15.1181px)] -PASS CSS Animations: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0) should be [hue-rotate(80deg) blur(22.6772px)] -PASS CSS Animations: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0.25) should be [hue-rotate(82.5deg) blur(26.4567px)] -PASS CSS Animations: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0.5) should be [hue-rotate(85deg) blur(30.2362px)] -PASS CSS Animations: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (1) should be [hue-rotate(90deg) blur(37.7953px)] -PASS CSS Animations: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (1.5) should be [hue-rotate(95deg) blur(45.3543px)] -PASS Web Animations: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (-0.5) should be [hue-rotate(75deg) blur(15.1181px)] -PASS Web Animations: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0) should be [hue-rotate(80deg) blur(22.6772px)] -PASS Web Animations: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0.25) should be [hue-rotate(82.5deg) blur(26.4567px)] -PASS Web Animations: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0.5) should be [hue-rotate(85deg) blur(30.2362px)] -PASS Web Animations: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (1) should be [hue-rotate(90deg) blur(37.7953px)] -PASS Web Animations: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (1.5) should be [hue-rotate(95deg) blur(45.3543px)] +PASS CSS Transitions: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (-0.5) should be [hue-rotate(75deg) blur(4mm)] +PASS CSS Transitions: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0) should be [hue-rotate(80deg) blur(6mm)] +PASS CSS Transitions: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0.25) should be [hue-rotate(82.5deg) blur(7mm)] +PASS CSS Transitions: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0.5) should be [hue-rotate(85deg) blur(8mm)] +PASS CSS Transitions: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (1) should be [hue-rotate(90deg) blur(10mm)] +PASS CSS Transitions: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (1.5) should be [hue-rotate(95deg) blur(12mm)] +PASS CSS Transitions with transition: all: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (-0.5) should be [hue-rotate(75deg) blur(4mm)] +PASS CSS Transitions with transition: all: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0) should be [hue-rotate(80deg) blur(6mm)] +PASS CSS Transitions with transition: all: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0.25) should be [hue-rotate(82.5deg) blur(7mm)] +PASS CSS Transitions with transition: all: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0.5) should be [hue-rotate(85deg) blur(8mm)] +PASS CSS Transitions with transition: all: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (1) should be [hue-rotate(90deg) blur(10mm)] +PASS CSS Transitions with transition: all: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (1.5) should be [hue-rotate(95deg) blur(12mm)] +PASS CSS Animations: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (-0.5) should be [hue-rotate(75deg) blur(4mm)] +PASS CSS Animations: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0) should be [hue-rotate(80deg) blur(6mm)] +PASS CSS Animations: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0.25) should be [hue-rotate(82.5deg) blur(7mm)] +PASS CSS Animations: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0.5) should be [hue-rotate(85deg) blur(8mm)] +PASS CSS Animations: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (1) should be [hue-rotate(90deg) blur(10mm)] +PASS CSS Animations: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (1.5) should be [hue-rotate(95deg) blur(12mm)] +PASS Web Animations: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (-0.5) should be [hue-rotate(75deg) blur(4mm)] +PASS Web Animations: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0) should be [hue-rotate(80deg) blur(6mm)] +PASS Web Animations: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0.25) should be [hue-rotate(82.5deg) blur(7mm)] +PASS Web Animations: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (0.5) should be [hue-rotate(85deg) blur(8mm)] +PASS Web Animations: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (1) should be [hue-rotate(90deg) blur(10mm)] +PASS Web Animations: property <filter> from [hue-rotate(80deg) blur(6mm)] to [hue-rotate(100grad) blur(1cm)] at (1.5) should be [hue-rotate(95deg) blur(12mm)] PASS CSS Transitions: property <filter> from neutral to [hue-rotate(20deg)] at (-0.5) should be [hue-rotate(5deg)] PASS CSS Transitions: property <filter> from neutral to [hue-rotate(20deg)] at (0) should be [hue-rotate(10deg)] PASS CSS Transitions: property <filter> from neutral to [hue-rotate(20deg)] at (0.3) should be [hue-rotate(13deg)]
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/animation/filter-interpolation-002-expected.txt b/third_party/blink/web_tests/external/wpt/css/filter-effects/animation/filter-interpolation-002-expected.txt index 19f208e..cbb0556 100644 --- a/third_party/blink/web_tests/external/wpt/css/filter-effects/animation/filter-interpolation-002-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/animation/filter-interpolation-002-expected.txt
@@ -96,30 +96,30 @@ PASS Web Animations: property <filter> from [hue-rotate(180deg)] to [none] at (0.5) should be [hue-rotate(90deg)] FAIL Web Animations: property <filter> from [hue-rotate(180deg)] to [none] at (1) should be [hue-rotate(0deg)] assert_equals: expected "hue - rotate ( 0deg ) " but got "none " PASS Web Animations: property <filter> from [hue-rotate(180deg)] to [none] at (1.5) should be [hue-rotate(-90deg)] -PASS CSS Transitions: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (-1) should be [drop-shadow(rgb(255, 255, 255) -20px -10px 0px)] -PASS CSS Transitions: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (0) should be [drop-shadow(rgb(255, 255, 255) 0px 0px 0px)] -PASS CSS Transitions: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (0.5) should be [drop-shadow(rgb(128, 192, 128) 10px 5px 0px)] -PASS CSS Transitions: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (1) should be [drop-shadow(rgb(0, 128, 0) 20px 10px 0px)] -PASS CSS Transitions: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (1.5) should be [drop-shadow(rgb(0, 65, 0) 30px 15px 0px)] -PASS CSS Transitions with transition: all: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (-1) should be [drop-shadow(rgb(255, 255, 255) -20px -10px 0px)] -PASS CSS Transitions with transition: all: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (0) should be [drop-shadow(rgb(255, 255, 255) 0px 0px 0px)] -PASS CSS Transitions with transition: all: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (0.5) should be [drop-shadow(rgb(128, 192, 128) 10px 5px 0px)] -PASS CSS Transitions with transition: all: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (1) should be [drop-shadow(rgb(0, 128, 0) 20px 10px 0px)] -PASS CSS Transitions with transition: all: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (1.5) should be [drop-shadow(rgb(0, 65, 0) 30px 15px 0px)] -PASS CSS Animations: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (-1) should be [drop-shadow(rgb(255, 255, 255) -20px -10px 0px)] -PASS CSS Animations: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (0) should be [drop-shadow(rgb(255, 255, 255) 0px 0px 0px)] -PASS CSS Animations: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (0.5) should be [drop-shadow(rgb(128, 192, 128) 10px 5px 0px)] -PASS CSS Animations: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (1) should be [drop-shadow(rgb(0, 128, 0) 20px 10px 0px)] -PASS CSS Animations: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (1.5) should be [drop-shadow(rgb(0, 65, 0) 30px 15px 0px)] -PASS Web Animations: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (-1) should be [drop-shadow(rgb(255, 255, 255) -20px -10px 0px)] -PASS Web Animations: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (0) should be [drop-shadow(rgb(255, 255, 255) 0px 0px 0px)] -PASS Web Animations: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (0.5) should be [drop-shadow(rgb(128, 192, 128) 10px 5px 0px)] -PASS Web Animations: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (1) should be [drop-shadow(rgb(0, 128, 0) 20px 10px 0px)] -PASS Web Animations: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (1.5) should be [drop-shadow(rgb(0, 65, 0) 30px 15px 0px)] -PASS CSS Transitions: property <filter> from [drop-shadow(20px 10px blue)] to [drop-shadow(20px 10px green)] at (2147483648) should be [drop-shadow(rgb(0, 255, 0) 20px 10px 0px)] -PASS CSS Transitions with transition: all: property <filter> from [drop-shadow(20px 10px blue)] to [drop-shadow(20px 10px green)] at (2147483648) should be [drop-shadow(rgb(0, 255, 0) 20px 10px 0px)] -PASS CSS Animations: property <filter> from [drop-shadow(20px 10px blue)] to [drop-shadow(20px 10px green)] at (2147483648) should be [drop-shadow(rgb(0, 255, 0) 20px 10px 0px)] -PASS Web Animations: property <filter> from [drop-shadow(20px 10px blue)] to [drop-shadow(20px 10px green)] at (2147483648) should be [drop-shadow(rgb(0, 255, 0) 20px 10px 0px)] +PASS CSS Transitions: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (-1) should be [drop-shadow(-20px -10px white)] +PASS CSS Transitions: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (0) should be [drop-shadow(0px 0px 0px currentcolor)] +PASS CSS Transitions: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (0.5) should be [drop-shadow(10px 5px #80C080)] +PASS CSS Transitions: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (1) should be [drop-shadow(20px 10px green)] +PASS CSS Transitions: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (1.5) should be [drop-shadow(30px 15px #004100)] +PASS CSS Transitions with transition: all: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (-1) should be [drop-shadow(-20px -10px white)] +PASS CSS Transitions with transition: all: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (0) should be [drop-shadow(0px 0px 0px currentcolor)] +PASS CSS Transitions with transition: all: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (0.5) should be [drop-shadow(10px 5px #80C080)] +PASS CSS Transitions with transition: all: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (1) should be [drop-shadow(20px 10px green)] +PASS CSS Transitions with transition: all: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (1.5) should be [drop-shadow(30px 15px #004100)] +PASS CSS Animations: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (-1) should be [drop-shadow(-20px -10px white)] +PASS CSS Animations: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (0) should be [drop-shadow(0px 0px 0px currentcolor)] +PASS CSS Animations: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (0.5) should be [drop-shadow(10px 5px #80C080)] +PASS CSS Animations: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (1) should be [drop-shadow(20px 10px green)] +PASS CSS Animations: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (1.5) should be [drop-shadow(30px 15px #004100)] +PASS Web Animations: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (-1) should be [drop-shadow(-20px -10px white)] +PASS Web Animations: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (0) should be [drop-shadow(0px 0px 0px currentcolor)] +PASS Web Animations: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (0.5) should be [drop-shadow(10px 5px #80C080)] +PASS Web Animations: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (1) should be [drop-shadow(20px 10px green)] +PASS Web Animations: property <filter> from [drop-shadow(0px 0px 0px currentcolor)] to [drop-shadow(20px 10px green)] at (1.5) should be [drop-shadow(30px 15px #004100)] +PASS CSS Transitions: property <filter> from [drop-shadow(20px 10px blue)] to [drop-shadow(20px 10px green)] at (2147483648) should be [drop-shadow(20px 10px #00FF00] +PASS CSS Transitions with transition: all: property <filter> from [drop-shadow(20px 10px blue)] to [drop-shadow(20px 10px green)] at (2147483648) should be [drop-shadow(20px 10px #00FF00] +PASS CSS Animations: property <filter> from [drop-shadow(20px 10px blue)] to [drop-shadow(20px 10px green)] at (2147483648) should be [drop-shadow(20px 10px #00FF00] +PASS Web Animations: property <filter> from [drop-shadow(20px 10px blue)] to [drop-shadow(20px 10px green)] at (2147483648) should be [drop-shadow(20px 10px #00FF00] PASS CSS Transitions: property <filter> from [grayscale(0) blur(0px)] to [blur(10px)] at (-0.3) should be [blur(10px)] PASS CSS Transitions: property <filter> from [grayscale(0) blur(0px)] to [blur(10px)] at (0) should be [blur(10px)] PASS CSS Transitions: property <filter> from [grayscale(0) blur(0px)] to [blur(10px)] at (0.3) should be [blur(10px)]
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/animation/filter-interpolation-003-expected.txt b/third_party/blink/web_tests/external/wpt/css/filter-effects/animation/filter-interpolation-003-expected.txt index 92ca741..2080b37a 100644 --- a/third_party/blink/web_tests/external/wpt/css/filter-effects/animation/filter-interpolation-003-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/animation/filter-interpolation-003-expected.txt
@@ -60,26 +60,26 @@ PASS Web Animations: property <filter> from [contrast(0)] to [none] at (0.5) should be [contrast(0.5)] FAIL Web Animations: property <filter> from [contrast(0)] to [none] at (1) should be [contrast(1)] assert_equals: expected "contrast ( 1 ) " but got "none " PASS Web Animations: property <filter> from [contrast(0)] to [none] at (1.5) should be [contrast(1.5)] -PASS CSS Transitions: property <filter> from [none] to [drop-shadow(20px 10px green)] at (-1) should be [drop-shadow(rgba(0, 0, 0, 0) -20px -10px 0px)] -FAIL CSS Transitions: property <filter> from [none] to [drop-shadow(20px 10px green)] at (0) should be [drop-shadow(rgba(0, 0, 0, 0) 0px 0px 0px)] assert_equals: expected "drop - shadow ( rgba ( 0 , 0 , 0 , 0 ) 0px 0px 0px ) " but got "none " -PASS CSS Transitions: property <filter> from [none] to [drop-shadow(20px 10px green)] at (0.5) should be [drop-shadow(rgba(0, 128, 0, 0.5) 10px 5px 0px)] -PASS CSS Transitions: property <filter> from [none] to [drop-shadow(20px 10px green)] at (1) should be [drop-shadow(rgb(0, 128, 0) 20px 10px 0px)] -PASS CSS Transitions: property <filter> from [none] to [drop-shadow(20px 10px green)] at (1.5) should be [drop-shadow(rgb(0, 192, 0) 30px 15px 0px)] -PASS CSS Transitions with transition: all: property <filter> from [none] to [drop-shadow(20px 10px green)] at (-1) should be [drop-shadow(rgba(0, 0, 0, 0) -20px -10px 0px)] -FAIL CSS Transitions with transition: all: property <filter> from [none] to [drop-shadow(20px 10px green)] at (0) should be [drop-shadow(rgba(0, 0, 0, 0) 0px 0px 0px)] assert_equals: expected "drop - shadow ( rgba ( 0 , 0 , 0 , 0 ) 0px 0px 0px ) " but got "none " -PASS CSS Transitions with transition: all: property <filter> from [none] to [drop-shadow(20px 10px green)] at (0.5) should be [drop-shadow(rgba(0, 128, 0, 0.5) 10px 5px 0px)] -PASS CSS Transitions with transition: all: property <filter> from [none] to [drop-shadow(20px 10px green)] at (1) should be [drop-shadow(rgb(0, 128, 0) 20px 10px 0px)] -PASS CSS Transitions with transition: all: property <filter> from [none] to [drop-shadow(20px 10px green)] at (1.5) should be [drop-shadow(rgb(0, 192, 0) 30px 15px 0px)] -PASS CSS Animations: property <filter> from [none] to [drop-shadow(20px 10px green)] at (-1) should be [drop-shadow(rgba(0, 0, 0, 0) -20px -10px 0px)] -FAIL CSS Animations: property <filter> from [none] to [drop-shadow(20px 10px green)] at (0) should be [drop-shadow(rgba(0, 0, 0, 0) 0px 0px 0px)] assert_equals: expected "drop - shadow ( rgba ( 0 , 0 , 0 , 0 ) 0px 0px 0px ) " but got "none " -PASS CSS Animations: property <filter> from [none] to [drop-shadow(20px 10px green)] at (0.5) should be [drop-shadow(rgba(0, 128, 0, 0.5) 10px 5px 0px)] -PASS CSS Animations: property <filter> from [none] to [drop-shadow(20px 10px green)] at (1) should be [drop-shadow(rgb(0, 128, 0) 20px 10px 0px)] -PASS CSS Animations: property <filter> from [none] to [drop-shadow(20px 10px green)] at (1.5) should be [drop-shadow(rgb(0, 192, 0) 30px 15px 0px)] -PASS Web Animations: property <filter> from [none] to [drop-shadow(20px 10px green)] at (-1) should be [drop-shadow(rgba(0, 0, 0, 0) -20px -10px 0px)] -FAIL Web Animations: property <filter> from [none] to [drop-shadow(20px 10px green)] at (0) should be [drop-shadow(rgba(0, 0, 0, 0) 0px 0px 0px)] assert_equals: expected "drop - shadow ( rgba ( 0 , 0 , 0 , 0 ) 0px 0px 0px ) " but got "none " -PASS Web Animations: property <filter> from [none] to [drop-shadow(20px 10px green)] at (0.5) should be [drop-shadow(rgba(0, 128, 0, 0.5) 10px 5px 0px)] -PASS Web Animations: property <filter> from [none] to [drop-shadow(20px 10px green)] at (1) should be [drop-shadow(rgb(0, 128, 0) 20px 10px 0px)] -PASS Web Animations: property <filter> from [none] to [drop-shadow(20px 10px green)] at (1.5) should be [drop-shadow(rgb(0, 192, 0) 30px 15px 0px)] +PASS CSS Transitions: property <filter> from [none] to [drop-shadow(20px 10px green)] at (-1) should be [drop-shadow(-20px -10px transparent)] +FAIL CSS Transitions: property <filter> from [none] to [drop-shadow(20px 10px green)] at (0) should be [drop-shadow(0px 0px 0px transparent)] assert_equals: expected "drop - shadow ( rgba ( 0 , 0 , 0 , 0 ) 0px 0px 0px ) " but got "none " +PASS CSS Transitions: property <filter> from [none] to [drop-shadow(20px 10px green)] at (0.5) should be [drop-shadow(10px 5px rgba(0, 128, 0, 0.5))] +PASS CSS Transitions: property <filter> from [none] to [drop-shadow(20px 10px green)] at (1) should be [drop-shadow(20px 10px green)] +PASS CSS Transitions: property <filter> from [none] to [drop-shadow(20px 10px green)] at (1.5) should be [drop-shadow(30px 15px #00C000)] +PASS CSS Transitions with transition: all: property <filter> from [none] to [drop-shadow(20px 10px green)] at (-1) should be [drop-shadow(-20px -10px transparent)] +FAIL CSS Transitions with transition: all: property <filter> from [none] to [drop-shadow(20px 10px green)] at (0) should be [drop-shadow(0px 0px 0px transparent)] assert_equals: expected "drop - shadow ( rgba ( 0 , 0 , 0 , 0 ) 0px 0px 0px ) " but got "none " +PASS CSS Transitions with transition: all: property <filter> from [none] to [drop-shadow(20px 10px green)] at (0.5) should be [drop-shadow(10px 5px rgba(0, 128, 0, 0.5))] +PASS CSS Transitions with transition: all: property <filter> from [none] to [drop-shadow(20px 10px green)] at (1) should be [drop-shadow(20px 10px green)] +PASS CSS Transitions with transition: all: property <filter> from [none] to [drop-shadow(20px 10px green)] at (1.5) should be [drop-shadow(30px 15px #00C000)] +PASS CSS Animations: property <filter> from [none] to [drop-shadow(20px 10px green)] at (-1) should be [drop-shadow(-20px -10px transparent)] +FAIL CSS Animations: property <filter> from [none] to [drop-shadow(20px 10px green)] at (0) should be [drop-shadow(0px 0px 0px transparent)] assert_equals: expected "drop - shadow ( rgba ( 0 , 0 , 0 , 0 ) 0px 0px 0px ) " but got "none " +PASS CSS Animations: property <filter> from [none] to [drop-shadow(20px 10px green)] at (0.5) should be [drop-shadow(10px 5px rgba(0, 128, 0, 0.5))] +PASS CSS Animations: property <filter> from [none] to [drop-shadow(20px 10px green)] at (1) should be [drop-shadow(20px 10px green)] +PASS CSS Animations: property <filter> from [none] to [drop-shadow(20px 10px green)] at (1.5) should be [drop-shadow(30px 15px #00C000)] +PASS Web Animations: property <filter> from [none] to [drop-shadow(20px 10px green)] at (-1) should be [drop-shadow(-20px -10px transparent)] +FAIL Web Animations: property <filter> from [none] to [drop-shadow(20px 10px green)] at (0) should be [drop-shadow(0px 0px 0px transparent)] assert_equals: expected "drop - shadow ( rgba ( 0 , 0 , 0 , 0 ) 0px 0px 0px ) " but got "none " +PASS Web Animations: property <filter> from [none] to [drop-shadow(20px 10px green)] at (0.5) should be [drop-shadow(10px 5px rgba(0, 128, 0, 0.5))] +PASS Web Animations: property <filter> from [none] to [drop-shadow(20px 10px green)] at (1) should be [drop-shadow(20px 10px green)] +PASS Web Animations: property <filter> from [none] to [drop-shadow(20px 10px green)] at (1.5) should be [drop-shadow(30px 15px #00C000)] PASS CSS Transitions: property <filter> from [none] to [grayscale(1)] at (-1) should be [grayscale(0)] FAIL CSS Transitions: property <filter> from [none] to [grayscale(1)] at (0) should be [grayscale(0)] assert_equals: expected "grayscale ( 0 ) " but got "none " PASS CSS Transitions: property <filter> from [none] to [grayscale(1)] at (0.5) should be [grayscale(0.5)]
diff --git a/third_party/blink/web_tests/external/wpt/css/support/interpolation-testcommon.js b/third_party/blink/web_tests/external/wpt/css/support/interpolation-testcommon.js index 24c47e1..9e63b02 100644 --- a/third_party/blink/web_tests/external/wpt/css/support/interpolation-testcommon.js +++ b/third_party/blink/web_tests/external/wpt/css/support/interpolation-testcommon.js
@@ -284,7 +284,7 @@ comparisonFunction( getComputedStyle(target).getPropertyValue(property), expectedValue); - }, `${testText} at (${expectation.at}) should be [${sanitizeUrls(expectedValue)}]`); + }, `${testText} at (${expectation.at}) should be [${sanitizeUrls(expectation.expect)}]`); }; return target; });
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/popup-redirect-cache.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/popup-redirect-cache.https.html new file mode 100644 index 0000000..519f710 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/popup-redirect-cache.https.html
@@ -0,0 +1,72 @@ +<!doctype html> +<meta charset=utf-8> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/get-host-info.sub.js"></script> +<script src="resources/common.js"></script> +<script src="/common/utils.js"></script> <!-- Use token() to allow running tests in parallel --> + +<div id=log></div> +<script> + +function url_test_cache(t, url, channelName, hasOpener) { + const bc = new BroadcastChannel(channelName); + bc.onmessage = t.step_func(event => { + const payload = event.data; + assert_equals(payload.name, hasOpener ? channelName : ""); + assert_equals(payload.opener, hasOpener); + bc.close() + + // test the same url for cache + url_test(t, url, channelName, hasOpener); + }); + + const w = window.open(url, channelName); + + // w will be closed by its postback iframe. When out of process, + // window.close() does not work. + t.add_cleanup(() => w.close()); +} + +// Redirect from hostA to hostB with same coop and coep. +// Cache the hostA page if redirectCache is true. +// Cache the hostB page if destCache is true. +function coop_redirect_cache_test(t, hostA, hostB, coop, coep, redirectCache, destCache, channelName, hasOpener) { + let redirectUrl = `${hostA.origin}/html/cross-origin-opener-policy/resources/coop-coep.py`; + let redirectCacheString = redirectCache ? "&cache=1" : ""; + let destCacheString = destCache ? "&cache=1" : ""; + let destUrl = `${hostB.origin}/html/cross-origin-opener-policy/resources/coop-coep.py?coop=${coop}&coep=${coep}${destCacheString}&channel=${channelName}`; + let url = `${redirectUrl}?coop=${coop}&coep=${coep}${redirectCacheString}&redirect=${encodeURIComponent(destUrl)}`; + + url_test_cache(t, url, channelName, hasOpener); +} + +function run_redirect_cache_tests(documentCOOPValueTitle, testArray) { + for (const test of tests) { + async_test(t => { + coop_redirect_cache_test(t, test[0], test[1], "same-origin", "require-corp", test[2], test[3], test[4], test[5]); + }, `${documentCOOPValueTitle} document opening popup redirect from ${test[0].origin} to ${test[1].origin} with redirectCache ${test[2]} and destCache ${test[3]}`); + } +} + +let tests = [ + // popup Origin, final Origin, isCacheRedirect, isCacheDestination, channelName, hasOpener + // Origin A->A->B + [SAME_ORIGIN, CROSS_ORIGIN, true, false, token(), false], + [SAME_ORIGIN, CROSS_ORIGIN, false, true, token(), false], + [SAME_ORIGIN, CROSS_ORIGIN, true, true, token(), false], + + // Origin A->B->B + [CROSS_ORIGIN, SAME_ORIGIN, true, false, token(), false], + [CROSS_ORIGIN, SAME_ORIGIN, false, true, token(), false], + [CROSS_ORIGIN, SAME_ORIGIN, true, true, token(), false], + + // Origin A->B->C + [SAME_SITE, CROSS_ORIGIN, true, false, token(), false], + [SAME_SITE, CROSS_ORIGIN, false, true, token(), false], + [SAME_SITE, CROSS_ORIGIN, true, true, token(), false], +]; + +run_redirect_cache_tests("same-origin", tests); + +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/popup-redirect-cache.https.html.headers b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/popup-redirect-cache.https.html.headers new file mode 100644 index 0000000..46ad58d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/popup-redirect-cache.https.html.headers
@@ -0,0 +1 @@ +Cross-Origin-Opener-Policy: same-origin
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/resources/coop-coep.py b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/resources/coop-coep.py index 8b12341..8691e1b 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/resources/coop-coep.py +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/resources/coop-coep.py
@@ -6,6 +6,8 @@ response.headers.set("Cross-Origin-Opener-Policy", coop) if coep != "": response.headers.set("Cross-Origin-Embedder-Policy", coep) + if 'cache' in request.GET: + response.headers.set('Cache-Control', 'max-age=3600') if redirect != None: response.status = 302
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/textfieldselection/selection-not-application.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/textfieldselection/selection-not-application.html index 04b4fdd4..d205ee83 100644 --- a/third_party/blink/web_tests/external/wpt/html/semantics/forms/textfieldselection/selection-not-application.html +++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/textfieldselection/selection-not-application.html
@@ -14,6 +14,11 @@ var el = document.createElement("input"); el.type = type; + if (el.type != type) { + // Type is not supported - don't bother with the following checks. + return; + } + test(() => { assert_equals(el.selectionStart, null); }, `selectionStart on an input[type=${type}] returns null`); @@ -70,7 +75,7 @@ }, `selectionEnd on an input[type=${type}] returns a value`); test(() => { - assert_equals(el.selectionDirection, "none"); + assert_in_array(el.selectionDirection, ["forward", "none"]); }, `selectionDirection on an input[type=${type}] returns a value`); test(() => {
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/media-capabilities.idl b/third_party/blink/web_tests/external/wpt/interfaces/media-capabilities.idl index ef4582d..e067fdc7 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/media-capabilities.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/media-capabilities.idl
@@ -34,6 +34,27 @@ required unsigned long long bitrate; required double framerate; boolean hasAlphaChannel; + HdrMetadataType hdrMetadataType; + ColorGamut colorGamut; + TransferFunction transferFunction; +}; + +enum HdrMetadataType { + "smpteSt2086", + "smpteSt2094-10", + "smpteSt2094-40" +}; + +enum ColorGamut { + "srgb", + "p3", + "rec2020" +}; + +enum TransferFunction { + "srgb", + "pq", + "hlg" }; dictionary AudioConfiguration { @@ -80,23 +101,3 @@ [NewObject] Promise<MediaCapabilitiesDecodingInfo> decodingInfo(MediaDecodingConfiguration configuration); [NewObject] Promise<MediaCapabilitiesInfo> encodingInfo(MediaEncodingConfiguration configuration); }; - -[Exposed=Window] -interface ScreenLuminance { - readonly attribute double min; - readonly attribute double max; - readonly attribute double maxAverage; -}; - -enum ScreenColorGamut { - "srgb", - "p3", - "rec2020", -}; - -partial interface Screen { - readonly attribute ScreenColorGamut colorGamut; - readonly attribute ScreenLuminance? luminance; - - attribute EventHandler onchange; -};
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/paint-timing.idl b/third_party/blink/web_tests/external/wpt/interfaces/paint-timing.idl index a8f065a..0bfb422f 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/paint-timing.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/paint-timing.idl
@@ -3,4 +3,5 @@ // (https://github.com/tidoust/reffy-reports) // Source: Paint Timing 1 (https://w3c.github.io/paint-timing/) +[Exposed=Window] interface PerformancePaintTiming : PerformanceEntry {};
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/payment-handler.idl b/third_party/blink/web_tests/external/wpt/interfaces/payment-handler.idl index c87c855..aadaecc 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/payment-handler.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/payment-handler.idl
@@ -11,6 +11,14 @@ interface PaymentManager { [SameObject] readonly attribute PaymentInstruments instruments; attribute DOMString userHint; + Promise<void> enableDelegations(FrozenArray<PaymentDelegation> delegations); +}; + +enum PaymentDelegation { + "shippingAddress", + "payerName", + "payerPhone", + "payerEmail" }; [SecureContext, Exposed=(Window,Worker)] @@ -59,11 +67,13 @@ attribute EventHandler onpaymentrequest; }; -dictionary PaymentMethodChangeResponse { +dictionary PaymentRequestDetailsUpdate { DOMString error; PaymentCurrencyAmount total; FrozenArray<PaymentDetailsModifier> modifiers; + FrozenArray<PaymentShippingOption> shippingOptions; object paymentMethodErrors; + AddressErrors shippingAddressErrors; }; [Exposed=ServiceWorker] @@ -77,8 +87,12 @@ readonly attribute FrozenArray<PaymentDetailsModifier> modifiers; readonly attribute DOMString instrumentKey; readonly attribute boolean requestBillingAddress; + readonly attribute object? paymentOptions; + readonly attribute FrozenArray<PaymentShippingOption>? shippingOptions; Promise<WindowClient?> openWindow(USVString url); - Promise<PaymentMethodChangeResponse?> changePaymentMethod(DOMString methodName, optional object? methodDetails = null); + Promise<PaymentRequestDetailsUpdate?> changePaymentMethod(DOMString methodName, optional object? methodDetails = null); + Promise<PaymentRequestDetailsUpdate?> changeShippingAddress(AddressInit shippingAddress); + Promise<PaymentRequestDetailsUpdate?> changeShippingOption(DOMString shippingOption); void respondWith(Promise<PaymentHandlerResponse> handlerResponsePromise); }; @@ -90,9 +104,16 @@ PaymentCurrencyAmount total; sequence<PaymentDetailsModifier> modifiers; DOMString instrumentKey; + PaymentOptions paymentOptions; + sequence<PaymentShippingOption> shippingOptions; }; dictionary PaymentHandlerResponse { DOMString methodName; object details; +DOMString? payerName; +DOMString? payerEmail; +DOMString? payerPhone; +AddressInit shippingAddress; +DOMString? shippingOption; };
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/wake-lock.idl b/third_party/blink/web_tests/external/wpt/interfaces/wake-lock.idl index 5bccbe8..b66c415 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/wake-lock.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/wake-lock.idl
@@ -4,17 +4,29 @@ // Source: Wake Lock API (https://w3c.github.io/wake-lock/) dictionary WakeLockPermissionDescriptor : PermissionDescriptor { - WakeLockType type; + required WakeLockType type; }; enum WakeLockType { "screen", "system" }; -[SecureContext, Exposed=(DedicatedWorker, Window)] -interface WakeLock { - [Exposed=Window] static Promise<PermissionState> requestPermission(WakeLockType type); - static Promise<void> request(WakeLockType type, optional WakeLockRequestOptions options = {}); +[SecureContext] +partial interface Navigator { + [SameObject] readonly attribute WakeLock wakeLock; }; -dictionary WakeLockRequestOptions { - AbortSignal signal; +[SecureContext] +partial interface WorkerNavigator { + [SameObject] readonly attribute WakeLock wakeLock; +}; + +[SecureContext, Exposed=(DedicatedWorker,Window)] +interface WakeLock { + Promise<WakeLockSentinel> request(WakeLockType type); +}; + +[SecureContext, Exposed=(DedicatedWorker,Window)] +interface WakeLockSentinel : EventTarget { + readonly attribute WakeLockType type; + Promise<void> release(); + attribute EventHandler onrelease; };
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/web-nfc.idl b/third_party/blink/web_tests/external/wpt/interfaces/web-nfc.idl index 56b7479e..b917d5e 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/web-nfc.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/web-nfc.idl
@@ -25,9 +25,6 @@ readonly attribute USVString? encoding; readonly attribute USVString? lang; - USVString? text(); - [NewObject] ArrayBuffer? arrayBuffer(); - [NewObject] any json(); sequence<NDEFRecord> toRecords(); }; @@ -56,9 +53,8 @@ constructor(); attribute EventHandler onreading; - attribute EventHandler onerror; - void scan(optional NDEFScanOptions options={}); + Promise<void> scan(optional NDEFScanOptions options={}); }; [SecureContext, Exposed=Window] @@ -74,17 +70,6 @@ required NDEFMessageInit message; }; -[SecureContext, Exposed=Window] -interface NDEFErrorEvent : Event { - constructor(DOMString type, NDEFErrorEventInit errorEventInitDict); - - readonly attribute DOMException error; -}; - -dictionary NDEFErrorEventInit : EventInit { - required DOMException error; -}; - dictionary NDEFPushOptions { NDEFPushTarget target = "any"; unrestricted double timeout = Infinity;
diff --git a/third_party/blink/web_tests/external/wpt/lint.whitelist b/third_party/blink/web_tests/external/wpt/lint.whitelist index afdc20b6..4226727 100644 --- a/third_party/blink/web_tests/external/wpt/lint.whitelist +++ b/third_party/blink/web_tests/external/wpt/lint.whitelist
@@ -7,13 +7,7 @@ ## Whitespace rules that we can't enforce yet ## -INDENT TABS: .gitmodules INDENT TABS: conformance-checkers/* -INDENT TABS: content-security-policy/* -INDENT TABS: pointerlock/* -INDENT TABS: shadow-dom/* -INDENT TABS: webaudio/* -INDENT TABS: webvtt/* INDENT TABS: encoding/legacy*/* TRAILING WHITESPACE: 2dcontext/tools/current-work-canvas.xhtml @@ -76,8 +70,8 @@ WEB-PLATFORM.TEST:README.md WEB-PLATFORM.TEST:*/README.md WEB-PLATFORM.TEST:docs/* -INDENT TABS:docs/* -CR AT EOL:docs/* +CR AT EOL, INDENT TABS:docs/make.bat +INDENT TABS:docs/Makefile ## Helper scripts ## @@ -106,6 +100,8 @@ # Intentional use of tabs INDENT TABS: html/semantics/embedded-content/the-canvas-element/size.attributes.parse.whitespace.html +INDENT TABS: webvtt/parsing/file-parsing/tests/support/header-tab.vtt +INDENT TABS: webvtt/parsing/file-parsing/tests/support/whitespace-chars.vtt # Intentional use of print statements PRINT STATEMENT: dom/nodes/Document-createElement-namespace-tests/generate.py
diff --git a/third_party/blink/web_tests/external/wpt/media-capabilities/idlharness.any-expected.txt b/third_party/blink/web_tests/external/wpt/media-capabilities/idlharness.any-expected.txt deleted file mode 100644 index d05f05f..0000000 --- a/third_party/blink/web_tests/external/wpt/media-capabilities/idlharness.any-expected.txt +++ /dev/null
@@ -1,64 +0,0 @@ -This is a testharness.js-based test. -Found 60 tests; 40 PASS, 20 FAIL, 0 TIMEOUT, 0 NOTRUN. -PASS idlharness -PASS idl_test setup -PASS idl_test validation -PASS Partial interface Navigator: original interface defined -PASS Partial interface Navigator: valid exposure set -PASS Partial interface Navigator: member names are unique -PASS Partial interface WorkerNavigator: original interface defined -PASS Partial interface WorkerNavigator: valid exposure set -PASS Partial interface WorkerNavigator: member names are unique -PASS Partial interface Screen: original interface defined -PASS Partial interface Screen: member names are unique -PASS Partial interface mixin NavigatorID: member names are unique -PASS Navigator includes NavigatorID: member names are unique -PASS Navigator includes NavigatorLanguage: member names are unique -PASS Navigator includes NavigatorOnLine: member names are unique -PASS Navigator includes NavigatorContentUtils: member names are unique -PASS Navigator includes NavigatorCookies: member names are unique -PASS Navigator includes NavigatorPlugins: member names are unique -PASS Navigator includes NavigatorConcurrentHardware: member names are unique -PASS WorkerNavigator includes NavigatorID: member names are unique -PASS WorkerNavigator includes NavigatorLanguage: member names are unique -PASS WorkerNavigator includes NavigatorOnLine: member names are unique -PASS WorkerNavigator includes NavigatorConcurrentHardware: member names are unique -PASS MediaCapabilities interface: existence and properties of interface object -PASS MediaCapabilities interface object length -PASS MediaCapabilities interface object name -PASS MediaCapabilities interface: existence and properties of interface prototype object -PASS MediaCapabilities interface: existence and properties of interface prototype object's "constructor" property -PASS MediaCapabilities interface: existence and properties of interface prototype object's @@unscopables property -PASS MediaCapabilities interface: operation decodingInfo(MediaDecodingConfiguration) -PASS MediaCapabilities interface: operation encodingInfo(MediaEncodingConfiguration) -PASS MediaCapabilities must be primary interface of navigator.mediaCapabilities -PASS Stringification of navigator.mediaCapabilities -PASS MediaCapabilities interface: navigator.mediaCapabilities must inherit property "decodingInfo(MediaDecodingConfiguration)" with the proper type -PASS MediaCapabilities interface: calling decodingInfo(MediaDecodingConfiguration) on navigator.mediaCapabilities with too few arguments must throw TypeError -PASS MediaCapabilities interface: navigator.mediaCapabilities must inherit property "encodingInfo(MediaEncodingConfiguration)" with the proper type -PASS MediaCapabilities interface: calling encodingInfo(MediaEncodingConfiguration) on navigator.mediaCapabilities with too few arguments must throw TypeError -FAIL ScreenLuminance interface: existence and properties of interface object assert_own_property: self does not have own property "ScreenLuminance" expected property "ScreenLuminance" missing -FAIL ScreenLuminance interface object length assert_own_property: self does not have own property "ScreenLuminance" expected property "ScreenLuminance" missing -FAIL ScreenLuminance interface object name assert_own_property: self does not have own property "ScreenLuminance" expected property "ScreenLuminance" missing -FAIL ScreenLuminance interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ScreenLuminance" expected property "ScreenLuminance" missing -FAIL ScreenLuminance interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ScreenLuminance" expected property "ScreenLuminance" missing -FAIL ScreenLuminance interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ScreenLuminance" expected property "ScreenLuminance" missing -FAIL ScreenLuminance interface: attribute min assert_own_property: self does not have own property "ScreenLuminance" expected property "ScreenLuminance" missing -FAIL ScreenLuminance interface: attribute max assert_own_property: self does not have own property "ScreenLuminance" expected property "ScreenLuminance" missing -FAIL ScreenLuminance interface: attribute maxAverage assert_own_property: self does not have own property "ScreenLuminance" expected property "ScreenLuminance" missing -FAIL ScreenLuminance must be primary interface of screen.luminance assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL Stringification of screen.luminance assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ScreenLuminance interface: screen.luminance must inherit property "min" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ScreenLuminance interface: screen.luminance must inherit property "max" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ScreenLuminance interface: screen.luminance must inherit property "maxAverage" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -PASS Navigator interface: attribute mediaCapabilities -PASS Navigator interface: navigator must inherit property "mediaCapabilities" with the proper type -PASS WorkerNavigator interface: existence and properties of interface object -FAIL Screen interface: attribute colorGamut assert_true: The prototype object must have a property "colorGamut" expected true got false -FAIL Screen interface: attribute luminance assert_true: The prototype object must have a property "luminance" expected true got false -FAIL Screen interface: attribute onchange assert_true: The prototype object must have a property "onchange" expected true got false -FAIL Screen interface: screen must inherit property "colorGamut" with the proper type assert_inherits: property "colorGamut" not found in prototype chain -FAIL Screen interface: screen must inherit property "luminance" with the proper type assert_inherits: property "luminance" not found in prototype chain -FAIL Screen interface: screen must inherit property "onchange" with the proper type assert_inherits: property "onchange" not found in prototype chain -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/media-capabilities/idlharness.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/media-capabilities/idlharness.any.worker-expected.txt deleted file mode 100644 index df20335..0000000 --- a/third_party/blink/web_tests/external/wpt/media-capabilities/idlharness.any.worker-expected.txt +++ /dev/null
@@ -1,54 +0,0 @@ -This is a testharness.js-based test. -Found 50 tests; 42 PASS, 8 FAIL, 0 TIMEOUT, 0 NOTRUN. -PASS idlharness -PASS idl_test setup -PASS idl_test validation -PASS Partial interface Navigator: original interface defined -PASS Partial interface Navigator: valid exposure set -PASS Partial interface Navigator: member names are unique -PASS Partial interface WorkerNavigator: original interface defined -PASS Partial interface WorkerNavigator: valid exposure set -PASS Partial interface WorkerNavigator: member names are unique -PASS Partial interface Screen: original interface defined -PASS Partial interface Screen: member names are unique -PASS Partial interface mixin NavigatorID: member names are unique -PASS Navigator includes NavigatorID: member names are unique -PASS Navigator includes NavigatorLanguage: member names are unique -PASS Navigator includes NavigatorOnLine: member names are unique -PASS Navigator includes NavigatorContentUtils: member names are unique -PASS Navigator includes NavigatorCookies: member names are unique -PASS Navigator includes NavigatorPlugins: member names are unique -PASS Navigator includes NavigatorConcurrentHardware: member names are unique -PASS WorkerNavigator includes NavigatorID: member names are unique -PASS WorkerNavigator includes NavigatorLanguage: member names are unique -PASS WorkerNavigator includes NavigatorOnLine: member names are unique -PASS WorkerNavigator includes NavigatorConcurrentHardware: member names are unique -PASS MediaCapabilities interface: existence and properties of interface object -PASS MediaCapabilities interface object length -PASS MediaCapabilities interface object name -PASS MediaCapabilities interface: existence and properties of interface prototype object -PASS MediaCapabilities interface: existence and properties of interface prototype object's "constructor" property -PASS MediaCapabilities interface: existence and properties of interface prototype object's @@unscopables property -PASS MediaCapabilities interface: operation decodingInfo(MediaDecodingConfiguration) -PASS MediaCapabilities interface: operation encodingInfo(MediaEncodingConfiguration) -PASS MediaCapabilities must be primary interface of navigator.mediaCapabilities -PASS Stringification of navigator.mediaCapabilities -PASS MediaCapabilities interface: navigator.mediaCapabilities must inherit property "decodingInfo(MediaDecodingConfiguration)" with the proper type -PASS MediaCapabilities interface: calling decodingInfo(MediaDecodingConfiguration) on navigator.mediaCapabilities with too few arguments must throw TypeError -PASS MediaCapabilities interface: navigator.mediaCapabilities must inherit property "encodingInfo(MediaEncodingConfiguration)" with the proper type -PASS MediaCapabilities interface: calling encodingInfo(MediaEncodingConfiguration) on navigator.mediaCapabilities with too few arguments must throw TypeError -PASS ScreenLuminance interface: existence and properties of interface object -FAIL ScreenLuminance must be primary interface of screen.luminance assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: screen is not defined" -FAIL Stringification of screen.luminance assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: screen is not defined" -FAIL ScreenLuminance interface: screen.luminance must not have property "min" assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: screen is not defined" -FAIL ScreenLuminance interface: screen.luminance must not have property "max" assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: screen is not defined" -FAIL ScreenLuminance interface: screen.luminance must not have property "maxAverage" assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: screen is not defined" -PASS Navigator interface: existence and properties of interface object -PASS WorkerNavigator interface: attribute mediaCapabilities -PASS WorkerNavigator interface: navigator must inherit property "mediaCapabilities" with the proper type -PASS Screen interface: existence and properties of interface object -FAIL Screen interface: screen must not have property "colorGamut" assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: screen is not defined" -FAIL Screen interface: screen must not have property "luminance" assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: screen is not defined" -FAIL Screen interface: screen must not have property "onchange" assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: screen is not defined" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/media-source/mediasource-replay.html b/third_party/blink/web_tests/external/wpt/media-source/mediasource-replay.html new file mode 100644 index 0000000..05a8c0a9 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/media-source/mediasource-replay.html
@@ -0,0 +1,41 @@ +<!DOCTYPE html> +<!-- Copyright © 2019 Igalia S.L --> +<html> +<head> + <title>MediaSource replay test case.</title> + <meta name="timeout" content="long"> + <meta charset="utf-8"> + <link rel="author" title="Alicia Boya García" href="mailto:aboya@igalia.com"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="mediasource-util.js"></script> +</head> +<body> +<div id="log"></div> +<script> + mediasource_testafterdataloaded(function (test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData) { + mediaElement.addEventListener('error', test.unreached_func("Unexpected event 'error'")); + + test.expectEvent(sourceBuffer, 'updateend', 'sourceBuffer'); + + sourceBuffer.appendBuffer(mediaData); + + test.waitForExpectedEvents(function () { + mediaSource.endOfStream(); + + // Start playing near the end. + mediaElement.currentTime = 6.2; + mediaElement.play(); + test.expectEvent(mediaElement, 'ended', 'mediaElement'); + }); + + test.waitForExpectedEvents(function () { + mediaElement.play(); + assert_equals(mediaElement.currentTime, 0, "currentTime"); + // If currentTime is able to advance, the player did not get stuck and it's a pass. + test.waitForCurrentTimeChange(mediaElement, test.step_func_done()); + }); + }, "Test replaying video after 'ended'"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/offscreen-canvas/text/2d.text.font.parse.invalid.html b/third_party/blink/web_tests/external/wpt/offscreen-canvas/text/2d.text.font.parse.invalid.html index 6ed7eb14..7986023 100644 --- a/third_party/blink/web_tests/external/wpt/offscreen-canvas/text/2d.text.font.parse.invalid.html +++ b/third_party/blink/web_tests/external/wpt/offscreen-canvas/text/2d.text.font.parse.invalid.html
@@ -20,6 +20,10 @@ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'"); ctx.font = '20px serif'; +ctx.font = ''; +_assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'"); + +ctx.font = '20px serif'; ctx.font = 'bogus'; _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
diff --git a/third_party/blink/web_tests/external/wpt/offscreen-canvas/text/2d.text.font.parse.invalid.worker.js b/third_party/blink/web_tests/external/wpt/offscreen-canvas/text/2d.text.font.parse.invalid.worker.js index 9a407c0..9be1a6d6 100644 --- a/third_party/blink/web_tests/external/wpt/offscreen-canvas/text/2d.text.font.parse.invalid.worker.js +++ b/third_party/blink/web_tests/external/wpt/offscreen-canvas/text/2d.text.font.parse.invalid.worker.js
@@ -16,6 +16,10 @@ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'"); ctx.font = '20px serif'; +ctx.font = ''; +_assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'"); + +ctx.font = '20px serif'; ctx.font = 'bogus'; _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
diff --git a/third_party/blink/web_tests/external/wpt/offscreen-canvas/tools/tests2d.yaml b/third_party/blink/web_tests/external/wpt/offscreen-canvas/tools/tests2d.yaml index 4bdf32db..6b1876d 100644 --- a/third_party/blink/web_tests/external/wpt/offscreen-canvas/tools/tests2d.yaml +++ b/third_party/blink/web_tests/external/wpt/offscreen-canvas/tools/tests2d.yaml
@@ -9305,6 +9305,10 @@ @assert ctx.font === '20px serif'; ctx.font = '20px serif'; + ctx.font = ''; + @assert ctx.font === '20px serif'; + + ctx.font = '20px serif'; ctx.font = 'bogus'; @assert ctx.font === '20px serif';
diff --git a/third_party/blink/web_tests/external/wpt/payment-handler/idlharness.https.any.serviceworker-expected.txt b/third_party/blink/web_tests/external/wpt/payment-handler/idlharness.https.any.serviceworker-expected.txt index 23a519d..c4afc3cb 100644 --- a/third_party/blink/web_tests/external/wpt/payment-handler/idlharness.https.any.serviceworker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/payment-handler/idlharness.https.any.serviceworker-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 101 tests; 68 PASS, 33 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 114 tests; 74 PASS, 40 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS idl_test setup PASS idl_test validation PASS Partial interface ServiceWorkerRegistration: original interface defined @@ -17,10 +17,13 @@ FAIL PaymentManager interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "PaymentManager" expected property "PaymentManager" missing FAIL PaymentManager interface: attribute instruments assert_own_property: self does not have own property "PaymentManager" expected property "PaymentManager" missing FAIL PaymentManager interface: attribute userHint assert_own_property: self does not have own property "PaymentManager" expected property "PaymentManager" missing +FAIL PaymentManager interface: operation enableDelegations([object Object]) assert_own_property: self does not have own property "PaymentManager" expected property "PaymentManager" missing FAIL PaymentManager must be primary interface of paymentManager assert_own_property: self does not have own property "PaymentManager" expected property "PaymentManager" missing PASS Stringification of paymentManager PASS PaymentManager interface: paymentManager must inherit property "instruments" with the proper type PASS PaymentManager interface: paymentManager must inherit property "userHint" with the proper type +PASS PaymentManager interface: paymentManager must inherit property "enableDelegations([object Object])" with the proper type +PASS PaymentManager interface: calling enableDelegations([object Object]) on paymentManager with too few arguments must throw TypeError PASS PaymentInstruments interface: existence and properties of interface object PASS PaymentInstruments interface object length PASS PaymentInstruments interface object name @@ -76,8 +79,12 @@ PASS PaymentRequestEvent interface: attribute modifiers PASS PaymentRequestEvent interface: attribute instrumentKey FAIL PaymentRequestEvent interface: attribute requestBillingAddress assert_true: The prototype object must have a property "requestBillingAddress" expected true got false +PASS PaymentRequestEvent interface: attribute paymentOptions +PASS PaymentRequestEvent interface: attribute shippingOptions PASS PaymentRequestEvent interface: operation openWindow(USVString) PASS PaymentRequestEvent interface: operation changePaymentMethod(DOMString, object) +PASS PaymentRequestEvent interface: operation changeShippingAddress(AddressInit) +PASS PaymentRequestEvent interface: operation changeShippingOption(DOMString) PASS PaymentRequestEvent interface: operation respondWith([object Object]) FAIL PaymentRequestEvent must be primary interface of new PaymentRequestEvent("type") assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'PaymentRequestEvent': 2 arguments required, but only 1 present." FAIL Stringification of new PaymentRequestEvent("type") assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'PaymentRequestEvent': 2 arguments required, but only 1 present." @@ -89,10 +96,16 @@ FAIL PaymentRequestEvent interface: new PaymentRequestEvent("type") must inherit property "modifiers" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'PaymentRequestEvent': 2 arguments required, but only 1 present." FAIL PaymentRequestEvent interface: new PaymentRequestEvent("type") must inherit property "instrumentKey" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'PaymentRequestEvent': 2 arguments required, but only 1 present." FAIL PaymentRequestEvent interface: new PaymentRequestEvent("type") must inherit property "requestBillingAddress" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'PaymentRequestEvent': 2 arguments required, but only 1 present." +FAIL PaymentRequestEvent interface: new PaymentRequestEvent("type") must inherit property "paymentOptions" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'PaymentRequestEvent': 2 arguments required, but only 1 present." +FAIL PaymentRequestEvent interface: new PaymentRequestEvent("type") must inherit property "shippingOptions" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'PaymentRequestEvent': 2 arguments required, but only 1 present." FAIL PaymentRequestEvent interface: new PaymentRequestEvent("type") must inherit property "openWindow(USVString)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'PaymentRequestEvent': 2 arguments required, but only 1 present." FAIL PaymentRequestEvent interface: calling openWindow(USVString) on new PaymentRequestEvent("type") with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'PaymentRequestEvent': 2 arguments required, but only 1 present." FAIL PaymentRequestEvent interface: new PaymentRequestEvent("type") must inherit property "changePaymentMethod(DOMString, object)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'PaymentRequestEvent': 2 arguments required, but only 1 present." FAIL PaymentRequestEvent interface: calling changePaymentMethod(DOMString, object) on new PaymentRequestEvent("type") with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'PaymentRequestEvent': 2 arguments required, but only 1 present." +FAIL PaymentRequestEvent interface: new PaymentRequestEvent("type") must inherit property "changeShippingAddress(AddressInit)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'PaymentRequestEvent': 2 arguments required, but only 1 present." +FAIL PaymentRequestEvent interface: calling changeShippingAddress(AddressInit) on new PaymentRequestEvent("type") with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'PaymentRequestEvent': 2 arguments required, but only 1 present." +FAIL PaymentRequestEvent interface: new PaymentRequestEvent("type") must inherit property "changeShippingOption(DOMString)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'PaymentRequestEvent': 2 arguments required, but only 1 present." +FAIL PaymentRequestEvent interface: calling changeShippingOption(DOMString) on new PaymentRequestEvent("type") with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'PaymentRequestEvent': 2 arguments required, but only 1 present." FAIL PaymentRequestEvent interface: new PaymentRequestEvent("type") must inherit property "respondWith([object Object])" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'PaymentRequestEvent': 2 arguments required, but only 1 present." FAIL PaymentRequestEvent interface: calling respondWith([object Object]) on new PaymentRequestEvent("type") with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'PaymentRequestEvent': 2 arguments required, but only 1 present." PASS ServiceWorkerRegistration interface: attribute paymentManager
diff --git a/third_party/blink/web_tests/external/wpt/payment-handler/idlharness.https.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/payment-handler/idlharness.https.any.sharedworker-expected.txt index 7927936..7ff997e 100644 --- a/third_party/blink/web_tests/external/wpt/payment-handler/idlharness.https.any.sharedworker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/payment-handler/idlharness.https.any.sharedworker-expected.txt
@@ -16,6 +16,7 @@ FAIL PaymentManager interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "PaymentManager" expected property "PaymentManager" missing FAIL PaymentManager interface: attribute instruments assert_own_property: self does not have own property "PaymentManager" expected property "PaymentManager" missing FAIL PaymentManager interface: attribute userHint assert_own_property: self does not have own property "PaymentManager" expected property "PaymentManager" missing +FAIL PaymentManager interface: operation enableDelegations([object Object]) assert_own_property: self does not have own property "PaymentManager" expected property "PaymentManager" missing PASS PaymentInstruments interface: existence and properties of interface object PASS PaymentInstruments interface object length PASS PaymentInstruments interface object name
diff --git a/third_party/blink/web_tests/external/wpt/payment-handler/idlharness.https.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/payment-handler/idlharness.https.any.worker-expected.txt index 7927936..7ff997e 100644 --- a/third_party/blink/web_tests/external/wpt/payment-handler/idlharness.https.any.worker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/payment-handler/idlharness.https.any.worker-expected.txt
@@ -16,6 +16,7 @@ FAIL PaymentManager interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "PaymentManager" expected property "PaymentManager" missing FAIL PaymentManager interface: attribute instruments assert_own_property: self does not have own property "PaymentManager" expected property "PaymentManager" missing FAIL PaymentManager interface: attribute userHint assert_own_property: self does not have own property "PaymentManager" expected property "PaymentManager" missing +FAIL PaymentManager interface: operation enableDelegations([object Object]) assert_own_property: self does not have own property "PaymentManager" expected property "PaymentManager" missing PASS PaymentInstruments interface: existence and properties of interface object PASS PaymentInstruments interface object length PASS PaymentInstruments interface object name
diff --git a/third_party/blink/web_tests/external/wpt/pointerlock/movementX_Y_no-jumps-manual.html b/third_party/blink/web_tests/external/wpt/pointerlock/movementX_Y_no-jumps-manual.html index 11b8d2a..7667ece 100644 --- a/third_party/blink/web_tests/external/wpt/pointerlock/movementX_Y_no-jumps-manual.html +++ b/third_party/blink/web_tests/external/wpt/pointerlock/movementX_Y_no-jumps-manual.html
@@ -33,14 +33,14 @@ <div id="status-log">Waiting... Click to start loging.</div> <div class="data-log"> - <table> - <tr><td></td><td>X</td><td>Y</td></tr> - <tr><td>client_init:</td><td id="clientX_init-log">X</td><td id="clientY_init-log">Y</td></tr> - <tr><td>client_last:</td><td id="clientX_last-log">X</td><td id="clientY_last-log">Y</td></tr> - <tr><td>client_delta:</td><td id="clientX_delta-log">X</td><td id="clientY_delta-log">Y</td></tr> - <tr><td>movement_sum:</td><td id="movementX_sum-log">X</td><td id="movementY_sum-log">Y</td></tr> - <tr><td>movement:</td><td id="movementX-log">X</td><td id="movementY-log">Y</td></tr> - </table> + <table> + <tr><td></td><td>X</td><td>Y</td></tr> + <tr><td>client_init:</td><td id="clientX_init-log">X</td><td id="clientY_init-log">Y</td></tr> + <tr><td>client_last:</td><td id="clientX_last-log">X</td><td id="clientY_last-log">Y</td></tr> + <tr><td>client_delta:</td><td id="clientX_delta-log">X</td><td id="clientY_delta-log">Y</td></tr> + <tr><td>movement_sum:</td><td id="movementX_sum-log">X</td><td id="movementY_sum-log">Y</td></tr> + <tr><td>movement:</td><td id="movementX-log">X</td><td id="movementY-log">Y</td></tr> + </table> </div> <hr/> @@ -98,10 +98,10 @@ movementY_sum = movementY; } - movementX_Y_outside_window_Test.step(function() { - assert_less_than(Math.abs(movementX), 50, "movementX should not have large jumps in value."); - assert_less_than(Math.abs(movementY), 50, "movementY should not have large jumps in value."); - }); + movementX_Y_outside_window_Test.step(function() { + assert_less_than(Math.abs(movementX), 50, "movementX should not have large jumps in value."); + assert_less_than(Math.abs(movementY), 50, "movementY should not have large jumps in value."); + }); movementX_sum += movementX; movementY_sum += movementY; @@ -117,10 +117,10 @@ document.addEventListener("mouseenter", function (e) { if(click_counter === 1) { - movementX_Y_outside_window_Test.step(function() { + movementX_Y_outside_window_Test.step(function() { assert_greater_than(Math.abs(e.clientX-clientX_last) + Math.abs(e.clientY-clientY_last), 100, "Test requires mouse to be moved at least 100 pixels outside of window."); - }); - } + }); + } }); function updateData() {
diff --git a/third_party/blink/web_tests/external/wpt/shadow-dom/leaktests/html-collection.html b/third_party/blink/web_tests/external/wpt/shadow-dom/leaktests/html-collection.html index d156569..2f3d49e 100644 --- a/third_party/blink/web_tests/external/wpt/shadow-dom/leaktests/html-collection.html +++ b/third_party/blink/web_tests/external/wpt/shadow-dom/leaktests/html-collection.html
@@ -29,10 +29,10 @@ var tmpl = document.getElementById('collection-template'); root.appendChild(document.importNode(tmpl.content, true)); for (var i = 0; i < root.childNodes.length; ++i) { - var el = root.childNodes[i]; - if (el.nodeType != 1) - continue; - el.id = prefix + el.tagName.toLowerCase(); + var el = root.childNodes[i]; + if (el.nodeType != 1) + continue; + el.id = prefix + el.tagName.toLowerCase(); } }
diff --git a/third_party/blink/web_tests/external/wpt/tools/ci/azure/cleanup_win10.yml b/third_party/blink/web_tests/external/wpt/tools/ci/azure/cleanup_win10.yml index 4abb353..195cdee 100644 --- a/third_party/blink/web_tests/external/wpt/tools/ci/azure/cleanup_win10.yml +++ b/third_party/blink/web_tests/external/wpt/tools/ci/azure/cleanup_win10.yml
@@ -9,17 +9,23 @@ cmd /c taskkill /f /im setup.exe `> nul 2`> nul if (Test-Path $edgePath) { $installerPath = Get-ChildItem -PATH $edgePath -Filter "setup.exe" -Recurse | Select -First 1 FullName - if (Test-Path $installerPath.FullName) { + if(-not($installerPath -eq $nul) -and (Test-Path $installerPath.FullName)) { Write-Host "Uninstall: $($installerPath.FullName) $uninstallArgs" Start-Process "$($installerPath.FullName)" -ArgumentList $uninstallArgs -Wait Remove-Item -Path $edgePath -Recurse -Force -ErrorAction SilentlyContinue + } else { + Write-Host "Failed to find setup.exe under $edgePath" } } } catch [Exception] { - Write-Host "Failed to unstall Edge from $edgePath. ERROR= $($_.Exception.Message)" -ForegroundColor Red + Write-Host "Failed to uninstall Edge from $edgePath. ERROR= $($_.Exception.Message)" -ForegroundColor Red } } + function IsEdgeRunning() { + return (Get-Process | Where-Object { $_.Name -eq "msedge" }).Length -gt 0 + } + # restore hosts file $hostFile = "$env:systemroot\System32\drivers\etc\hosts" Copy-Item -Path "$hostFile.back" -Destination $hostFile -Force @@ -32,6 +38,18 @@ UninstallEdge "$env:systemdrive\Program Files (x86)\Microsoft\Edge Dev\Application" "--uninstall --msedge-dev --system-level --force-uninstall" # uninstall Edge Beta channel UninstallEdge "$env:systemdrive\Program Files (x86)\Microsoft\Edge Beta\Application" "--uninstall --msedge-beta --system-level --force-uninstall" + + # Check if Edge is still running and try to close it. + # If we fail to close it, then reboot the system + # as this lingering process can lead to run instability. + if (IsEdgeRunning) { + Write-Host "Found Edge process running, try to close it." + Stop-Process -Name "msedge" -Force + if (IsEdgeRunning) { + Write-Host "Failed to close running Edge process, reboot the system." -ForegroundColor Red + Restart-Computer -Force + } + } displayName: 'Restore hosts file and cleanup test machine' condition: always() errorActionPreference: silentlyContinue
diff --git a/third_party/blink/web_tests/external/wpt/tools/ci/azure/fyi_hook.yml b/third_party/blink/web_tests/external/wpt/tools/ci/azure/fyi_hook.yml index 3d23da3b..f02f3cd 100644 --- a/third_party/blink/web_tests/external/wpt/tools/ci/azure/fyi_hook.yml +++ b/third_party/blink/web_tests/external/wpt/tools/ci/azure/fyi_hook.yml
@@ -10,7 +10,7 @@ displayName: 'wpt.fyi hook: ${{ parameters.artifactName }}' dependsOn: ${{ parameters.dependsOn }} pool: - vmImage: 'ubuntu-16.04' + vmImage: 'ubuntu-18.04' steps: - checkout: none - script: curl -f -s -S -d "artifact=${{ parameters.artifactName }}" -X POST https://wpt.fyi/api/checks/azure/$(Build.BuildId)
diff --git a/third_party/blink/web_tests/external/wpt/tools/ci/azure/install_edge.yml b/third_party/blink/web_tests/external/wpt/tools/ci/azure/install_edge.yml index a70dc78..e4c425ab 100644 --- a/third_party/blink/web_tests/external/wpt/tools/ci/azure/install_edge.yml +++ b/third_party/blink/web_tests/external/wpt/tools/ci/azure/install_edge.yml
@@ -9,12 +9,18 @@ $edgeInstallerName = 'MicrosoftEdgeSetup.exe' # Link to Canary channel installer Start-BitsTransfer -Source 'https://go.microsoft.com/fwlink/?linkid=2084649&Channel=Canary&language=en-us' -Destination MicrosoftEdgeSetup.exe + if (-not (Test-Path $edgeInstallerName)) { + Throw "Failed to download Edge installer to $edgeInstallerName." + } cmd /c START /WAIT $edgeInstallerName /silent /install $edgePath = "$env:localappdata\Microsoft\Edge SxS\Application" if (Test-Path $edgePath) { Write-Host "##vso[task.prependpath]$edgePath" + Write-Host "Edge Canary installed at $edgePath." + (Get-Item -Path "$edgePath\msedge.exe").VersionInfo | Format-List } else { - Throw "Failed to install Edge at $edgePath" + Copy-Item -Path "$env:temp\*edge*.log" -Destination $(Build.ArtifactStagingDirectory) -Force + Throw "Failed to install Edge Canary at $edgePath" } displayName: 'Install Edge Canary' - ${{ if eq(parameters.channel, 'dev') }}: @@ -26,7 +32,10 @@ $edgePath = "$env:systemdrive\Program Files (x86)\Microsoft\Edge Dev\Application" if (Test-Path $edgePath) { Write-Host "##vso[task.prependpath]$edgePath" + Write-Host "Edge Canary installed at $edgePath." + (Get-Item -Path "$edgePath\msedge.exe").VersionInfo | Format-List } else { - Throw "Failed to install Edge at $edgePath" + Copy-Item -Path "$env:temp\*edge*.log" -Destination $(Build.ArtifactStagingDirectory) -Force + Throw "Failed to install Edge Dev at $edgePath" } displayName: 'Install Edge Dev'
diff --git a/third_party/blink/web_tests/external/wpt/tools/ci/run_tc.py b/third_party/blink/web_tests/external/wpt/tools/ci/run_tc.py index 60f1758..e6d8cd8 100755 --- a/third_party/blink/web_tests/external/wpt/tools/ci/run_tc.py +++ b/third_party/blink/web_tests/external/wpt/tools/ci/run_tc.py
@@ -1,8 +1,8 @@ #!/usr/bin/env python -"""Wrapper script for running jobs in TaskCluster +"""Wrapper script for running jobs in Taskcluster -This is intended for running test jobs in TaskCluster. The script +This is intended for running test jobs in Taskcluster. The script takes a two positional arguments which are the name of the test job and the script to actually run.
diff --git a/third_party/blink/web_tests/external/wpt/tools/ci/taskcluster-run.py b/third_party/blink/web_tests/external/wpt/tools/ci/taskcluster-run.py index fbd2f2ab..ad33cb53 100755 --- a/third_party/blink/web_tests/external/wpt/tools/ci/taskcluster-run.py +++ b/third_party/blink/web_tests/external/wpt/tools/ci/taskcluster-run.py
@@ -34,7 +34,7 @@ def main(product, commit_range, wpt_args): - """Invoke the `wpt run` command according to the needs of the TaskCluster + """Invoke the `wpt run` command according to the needs of the Taskcluster continuous integration service.""" logger = logging.getLogger("tc-run")
diff --git a/third_party/blink/web_tests/external/wpt/tools/ci/tcdownload.py b/third_party/blink/web_tests/external/wpt/tools/ci/tcdownload.py index 46e9005..6e4d960 100644 --- a/third_party/blink/web_tests/external/wpt/tools/ci/tcdownload.py +++ b/third_party/blink/web_tests/external/wpt/tools/ci/tcdownload.py
@@ -19,7 +19,7 @@ help="Log type to fetch") parser.add_argument("--repo-name", action="store", default="web-platform-tests/wpt", help="GitHub repo name in the format owner/repo. " - "This must be the repo from which the TaskCluster run was scheduled " + "This must be the repo from which the Taskcluster run was scheduled " "(for PRs this is the repo into which the PR would merge)") parser.add_argument("--token-file", action="store", help="File containing GitHub token") @@ -70,7 +70,7 @@ taskgroups.add(taskgroup_id) if not taskgroups: - logger.error("No complete TaskCluster runs found for ref %s" % kwargs["ref"]) + logger.error("No complete Taskcluster runs found for ref %s" % kwargs["ref"]) return 1 for taskgroup in taskgroups:
diff --git a/third_party/blink/web_tests/external/wpt/url/resources/setters_tests.json b/third_party/blink/web_tests/external/wpt/url/resources/setters_tests.json index 0b4f6b6..6b7d19b 100644 --- a/third_party/blink/web_tests/external/wpt/url/resources/setters_tests.json +++ b/third_party/blink/web_tests/external/wpt/url/resources/setters_tests.json
@@ -122,7 +122,7 @@ "href": "gopher://example.net:1234", "new_value": "file", "expected": { - "href": "gopher://example.net:1234/", + "href": "gopher://example.net:1234", "protocol": "gopher:" } }, @@ -212,7 +212,7 @@ }, { "href": "ssh://me@example.net", - "new_value": "gopher", + "new_value": "https", "expected": { "href": "ssh://me@example.net", "protocol": "ssh:"
diff --git a/third_party/blink/web_tests/external/wpt/wake-lock/META.yml b/third_party/blink/web_tests/external/wpt/wake-lock/META.yml index 7ca3da2..0123ccef 100644 --- a/third_party/blink/web_tests/external/wpt/wake-lock/META.yml +++ b/third_party/blink/web_tests/external/wpt/wake-lock/META.yml
@@ -1,4 +1,6 @@ spec: https://w3c.github.io/wake-lock/ suggested_reviewers: - - marcoscaceres - Honry + - marcoscaceres + - rakuco + - reillyeon
diff --git a/third_party/blink/web_tests/external/wpt/wake-lock/idlharness.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/wake-lock/idlharness.https.any-expected.txt index af5b66f..2891448 100644 --- a/third_party/blink/web_tests/external/wpt/wake-lock/idlharness.https.any-expected.txt +++ b/third_party/blink/web_tests/external/wpt/wake-lock/idlharness.https.any-expected.txt
@@ -1,19 +1,49 @@ This is a testharness.js-based test. -PASS idl_test setup +FAIL idl_test setup promise_test: Unhandled rejection with value: object "NotAllowedError: Wake Lock permission request denied" PASS idl_test validation +PASS Partial interface Navigator: original interface defined +PASS Partial interface Navigator: member names are unique +PASS Partial interface WorkerNavigator: original interface defined +PASS Partial interface WorkerNavigator: member names are unique +PASS Partial interface mixin NavigatorID: member names are unique +PASS Navigator includes NavigatorID: member names are unique +PASS Navigator includes NavigatorLanguage: member names are unique +PASS Navigator includes NavigatorOnLine: member names are unique +PASS Navigator includes NavigatorContentUtils: member names are unique +PASS Navigator includes NavigatorCookies: member names are unique +PASS Navigator includes NavigatorPlugins: member names are unique +PASS Navigator includes NavigatorConcurrentHardware: member names are unique +PASS WorkerNavigator includes NavigatorID: member names are unique +PASS WorkerNavigator includes NavigatorLanguage: member names are unique +PASS WorkerNavigator includes NavigatorOnLine: member names are unique +PASS WorkerNavigator includes NavigatorConcurrentHardware: member names are unique PASS WakeLock interface: existence and properties of interface object PASS WakeLock interface object length PASS WakeLock interface object name PASS WakeLock interface: existence and properties of interface prototype object PASS WakeLock interface: existence and properties of interface prototype object's "constructor" property PASS WakeLock interface: existence and properties of interface prototype object's @@unscopables property -FAIL WakeLock interface: operation requestPermission(WakeLockType) assert_own_property: interface object missing static operation expected property "requestPermission" missing -FAIL WakeLock interface: operation request(WakeLockType, WakeLockRequestOptions) assert_own_property: interface object missing static operation expected property "request" missing +PASS WakeLock interface: operation request(WakeLockType) PASS WakeLock must be primary interface of navigator.wakeLock PASS Stringification of navigator.wakeLock -PASS WakeLock interface: navigator.wakeLock must inherit property "requestPermission(WakeLockType)" with the proper type -FAIL WakeLock interface: calling requestPermission(WakeLockType) on navigator.wakeLock with too few arguments must throw TypeError assert_own_property: interface object must have static operation as own property expected property "requestPermission" missing -PASS WakeLock interface: navigator.wakeLock must inherit property "request(WakeLockType, WakeLockRequestOptions)" with the proper type -FAIL WakeLock interface: calling request(WakeLockType, WakeLockRequestOptions) on navigator.wakeLock with too few arguments must throw TypeError assert_own_property: interface object must have static operation as own property expected property "request" missing +PASS WakeLock interface: navigator.wakeLock must inherit property "request(WakeLockType)" with the proper type +PASS WakeLock interface: calling request(WakeLockType) on navigator.wakeLock with too few arguments must throw TypeError +PASS WakeLockSentinel interface: existence and properties of interface object +PASS WakeLockSentinel interface object length +PASS WakeLockSentinel interface object name +PASS WakeLockSentinel interface: existence and properties of interface prototype object +PASS WakeLockSentinel interface: existence and properties of interface prototype object's "constructor" property +PASS WakeLockSentinel interface: existence and properties of interface prototype object's @@unscopables property +PASS WakeLockSentinel interface: attribute type +PASS WakeLockSentinel interface: operation release() +PASS WakeLockSentinel interface: attribute onrelease +FAIL WakeLockSentinel must be primary interface of sentinel assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: sentinel is not defined" +FAIL Stringification of sentinel assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: sentinel is not defined" +FAIL WakeLockSentinel interface: sentinel must inherit property "type" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: sentinel is not defined" +FAIL WakeLockSentinel interface: sentinel must inherit property "release()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: sentinel is not defined" +FAIL WakeLockSentinel interface: sentinel must inherit property "onrelease" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: sentinel is not defined" +PASS Navigator interface: attribute wakeLock +PASS Navigator interface: navigator must inherit property "wakeLock" with the proper type +PASS WorkerNavigator interface: existence and properties of interface object Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/wake-lock/idlharness.https.any.js b/third_party/blink/web_tests/external/wpt/wake-lock/idlharness.https.any.js index 31d20aed..b5d764a 100644 --- a/third_party/blink/web_tests/external/wpt/wake-lock/idlharness.https.any.js +++ b/third_party/blink/web_tests/external/wpt/wake-lock/idlharness.https.any.js
@@ -8,9 +8,20 @@ idl_test( ['wake-lock'], ['dom', 'html', 'permissions'], - idl_array => { + async idl_array => { + if (self.GLOBAL.isWorker()) { + idl_array.add_objects({ WorkerNavigator: ['navigator'] }); + } else { + idl_array.add_objects({ Navigator: ['navigator'] }); + } idl_array.add_objects({ WakeLock: ['navigator.wakeLock'], + WakeLockSentinel: ['sentinel'], }); + + // For now, this assumes the request will be granted and the promise will + // be fulfilled with a WakeLockSentinel object. + self.sentinel = await navigator.wakeLock.request('screen'); + self.sentinel.release(); } );
diff --git a/third_party/blink/web_tests/external/wpt/wake-lock/idlharness.https.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/wake-lock/idlharness.https.any.worker-expected.txt index 6c96a32..b90f5daa 100644 --- a/third_party/blink/web_tests/external/wpt/wake-lock/idlharness.https.any.worker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/wake-lock/idlharness.https.any.worker-expected.txt
@@ -1,18 +1,49 @@ This is a testharness.js-based test. -PASS idl_test setup +FAIL idl_test setup promise_test: Unhandled rejection with value: object "NotAllowedError: Screen locks cannot be requested from workers" PASS idl_test validation +PASS Partial interface Navigator: original interface defined +PASS Partial interface Navigator: member names are unique +PASS Partial interface WorkerNavigator: original interface defined +PASS Partial interface WorkerNavigator: member names are unique +PASS Partial interface mixin NavigatorID: member names are unique +PASS Navigator includes NavigatorID: member names are unique +PASS Navigator includes NavigatorLanguage: member names are unique +PASS Navigator includes NavigatorOnLine: member names are unique +PASS Navigator includes NavigatorContentUtils: member names are unique +PASS Navigator includes NavigatorCookies: member names are unique +PASS Navigator includes NavigatorPlugins: member names are unique +PASS Navigator includes NavigatorConcurrentHardware: member names are unique +PASS WorkerNavigator includes NavigatorID: member names are unique +PASS WorkerNavigator includes NavigatorLanguage: member names are unique +PASS WorkerNavigator includes NavigatorOnLine: member names are unique +PASS WorkerNavigator includes NavigatorConcurrentHardware: member names are unique PASS WakeLock interface: existence and properties of interface object PASS WakeLock interface object length PASS WakeLock interface object name PASS WakeLock interface: existence and properties of interface prototype object PASS WakeLock interface: existence and properties of interface prototype object's "constructor" property PASS WakeLock interface: existence and properties of interface prototype object's @@unscopables property -PASS WakeLock interface: member requestPermission -FAIL WakeLock interface: operation request(WakeLockType, WakeLockRequestOptions) assert_own_property: interface object missing static operation expected property "request" missing +PASS WakeLock interface: operation request(WakeLockType) PASS WakeLock must be primary interface of navigator.wakeLock PASS Stringification of navigator.wakeLock -PASS WakeLock interface: navigator.wakeLock must not have property "requestPermission" -PASS WakeLock interface: navigator.wakeLock must inherit property "request(WakeLockType, WakeLockRequestOptions)" with the proper type -FAIL WakeLock interface: calling request(WakeLockType, WakeLockRequestOptions) on navigator.wakeLock with too few arguments must throw TypeError assert_own_property: interface object must have static operation as own property expected property "request" missing +PASS WakeLock interface: navigator.wakeLock must inherit property "request(WakeLockType)" with the proper type +PASS WakeLock interface: calling request(WakeLockType) on navigator.wakeLock with too few arguments must throw TypeError +PASS WakeLockSentinel interface: existence and properties of interface object +PASS WakeLockSentinel interface object length +PASS WakeLockSentinel interface object name +PASS WakeLockSentinel interface: existence and properties of interface prototype object +PASS WakeLockSentinel interface: existence and properties of interface prototype object's "constructor" property +PASS WakeLockSentinel interface: existence and properties of interface prototype object's @@unscopables property +PASS WakeLockSentinel interface: attribute type +PASS WakeLockSentinel interface: operation release() +PASS WakeLockSentinel interface: attribute onrelease +FAIL WakeLockSentinel must be primary interface of sentinel assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: sentinel is not defined" +FAIL Stringification of sentinel assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: sentinel is not defined" +FAIL WakeLockSentinel interface: sentinel must inherit property "type" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: sentinel is not defined" +FAIL WakeLockSentinel interface: sentinel must inherit property "release()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: sentinel is not defined" +FAIL WakeLockSentinel interface: sentinel must inherit property "onrelease" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: sentinel is not defined" +PASS Navigator interface: existence and properties of interface object +PASS WorkerNavigator interface: attribute wakeLock +PASS WorkerNavigator interface: navigator must inherit property "wakeLock" with the proper type Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/Animation/oncancel.html b/third_party/blink/web_tests/external/wpt/web-animations/interfaces/Animation/oncancel.html index 3e918a4..d539119 100644 --- a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/Animation/oncancel.html +++ b/third_party/blink/web_tests/external/wpt/web-animations/interfaces/Animation/oncancel.html
@@ -21,7 +21,7 @@ animation.oncancel = t.step_func_done(event => { assert_equals(event.currentTime, null, 'event.currentTime should be null'); - assert_equals(event.timelineTime, finishedTimelineTime, + assert_times_equal(event.timelineTime, finishedTimelineTime, 'event.timelineTime should equal to the animation timeline ' + 'when finished promise is rejected'); });
diff --git a/third_party/blink/web_tests/external/wpt/web-nfc/idlharness.https.window-expected.txt b/third_party/blink/web_tests/external/wpt/web-nfc/idlharness.https.window-expected.txt index a7defad..0322ac5 100644 --- a/third_party/blink/web_tests/external/wpt/web-nfc/idlharness.https.window-expected.txt +++ b/third_party/blink/web_tests/external/wpt/web-nfc/idlharness.https.window-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 88 tests; 81 PASS, 7 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 70 tests; 62 PASS, 8 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS idl_test setup PASS idl_test validation PASS NDEFMessage interface: existence and properties of interface object @@ -24,9 +24,6 @@ PASS NDEFRecord interface: attribute data FAIL NDEFRecord interface: attribute encoding assert_true: The prototype object must have a property "encoding" expected true got false FAIL NDEFRecord interface: attribute lang assert_true: The prototype object must have a property "lang" expected true got false -PASS NDEFRecord interface: operation text() -PASS NDEFRecord interface: operation arrayBuffer() -PASS NDEFRecord interface: operation json() FAIL NDEFRecord interface: operation toRecords() assert_own_property: interface prototype object missing non-static operation expected property "toRecords" missing PASS NDEFRecord must be primary interface of new NDEFRecord({"recordType":"text","mediaType":"text/plain","data":"Hello World","id":"/custom/path"}); PASS Stringification of new NDEFRecord({"recordType":"text","mediaType":"text/plain","data":"Hello World","id":"/custom/path"}); @@ -36,9 +33,6 @@ FAIL NDEFRecord interface: new NDEFRecord({"recordType":"text","mediaType":"text/plain","data":"Hello World","id":"/custom/path"}); must inherit property "data" with the proper type Unrecognized type DataView FAIL NDEFRecord interface: new NDEFRecord({"recordType":"text","mediaType":"text/plain","data":"Hello World","id":"/custom/path"}); must inherit property "encoding" with the proper type assert_inherits: property "encoding" not found in prototype chain FAIL NDEFRecord interface: new NDEFRecord({"recordType":"text","mediaType":"text/plain","data":"Hello World","id":"/custom/path"}); must inherit property "lang" with the proper type assert_inherits: property "lang" not found in prototype chain -PASS NDEFRecord interface: new NDEFRecord({"recordType":"text","mediaType":"text/plain","data":"Hello World","id":"/custom/path"}); must inherit property "text()" with the proper type -PASS NDEFRecord interface: new NDEFRecord({"recordType":"text","mediaType":"text/plain","data":"Hello World","id":"/custom/path"}); must inherit property "arrayBuffer()" with the proper type -PASS NDEFRecord interface: new NDEFRecord({"recordType":"text","mediaType":"text/plain","data":"Hello World","id":"/custom/path"}); must inherit property "json()" with the proper type FAIL NDEFRecord interface: new NDEFRecord({"recordType":"text","mediaType":"text/plain","data":"Hello World","id":"/custom/path"}); must inherit property "toRecords()" with the proper type assert_inherits: property "toRecords" not found in prototype chain PASS NDEFWriter interface: existence and properties of interface object PASS NDEFWriter interface object length @@ -58,12 +52,10 @@ PASS NDEFReader interface: existence and properties of interface prototype object's "constructor" property PASS NDEFReader interface: existence and properties of interface prototype object's @@unscopables property PASS NDEFReader interface: attribute onreading -PASS NDEFReader interface: attribute onerror -PASS NDEFReader interface: operation scan(NDEFScanOptions) +FAIL NDEFReader interface: operation scan(NDEFScanOptions) assert_unreached: Throws "TypeError: Illegal invocation" instead of rejecting promise Reached unreachable code PASS NDEFReader must be primary interface of new NDEFReader(); PASS Stringification of new NDEFReader(); PASS NDEFReader interface: new NDEFReader(); must inherit property "onreading" with the proper type -PASS NDEFReader interface: new NDEFReader(); must inherit property "onerror" with the proper type PASS NDEFReader interface: new NDEFReader(); must inherit property "scan(NDEFScanOptions)" with the proper type PASS NDEFReader interface: calling scan(NDEFScanOptions) on new NDEFReader(); with too few arguments must throw TypeError PASS NDEFReadingEvent interface: existence and properties of interface object @@ -78,15 +70,5 @@ PASS Stringification of new NDEFReadingEvent("reading", { message: {"url":"/custom/path","records":[{"recordType":"text","mediaType":"text/plain","data":"Hello World","id":"/custom/path"}]} }) PASS NDEFReadingEvent interface: new NDEFReadingEvent("reading", { message: {"url":"/custom/path","records":[{"recordType":"text","mediaType":"text/plain","data":"Hello World","id":"/custom/path"}]} }) must inherit property "serialNumber" with the proper type PASS NDEFReadingEvent interface: new NDEFReadingEvent("reading", { message: {"url":"/custom/path","records":[{"recordType":"text","mediaType":"text/plain","data":"Hello World","id":"/custom/path"}]} }) must inherit property "message" with the proper type -PASS NDEFErrorEvent interface: existence and properties of interface object -PASS NDEFErrorEvent interface object length -PASS NDEFErrorEvent interface object name -PASS NDEFErrorEvent interface: existence and properties of interface prototype object -PASS NDEFErrorEvent interface: existence and properties of interface prototype object's "constructor" property -PASS NDEFErrorEvent interface: existence and properties of interface prototype object's @@unscopables property -PASS NDEFErrorEvent interface: attribute error -PASS NDEFErrorEvent must be primary interface of new NDEFErrorEvent("error", { error: new DOMException() }); -PASS Stringification of new NDEFErrorEvent("error", { error: new DOMException() }); -PASS NDEFErrorEvent interface: new NDEFErrorEvent("error", { error: new DOMException() }); must inherit property "error" with the proper type Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/web-share/share-image-manual.https.html b/third_party/blink/web_tests/external/wpt/web-share/share-image-manual.tentative.https.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/web-share/share-image-manual.https.html rename to third_party/blink/web_tests/external/wpt/web-share/share-image-manual.tentative.https.html
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-waveshapernode-interface/curve-tests.html b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-waveshapernode-interface/curve-tests.html index 81e64dc1..d09cf78 100644 --- a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-waveshapernode-interface/curve-tests.html +++ b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-waveshapernode-interface/curve-tests.html
@@ -1,184 +1,184 @@ <!doctype html> <html> <head> - <title>WaveShaperNode interface - Curve tests | WebAudio</title> + <title>WaveShaperNode interface - Curve tests | WebAudio</title> - <script type="text/javascript" src="/resources/testharness.js"></script> - <script type="text/javascript" src="/resources/testharnessreport.js"></script> + <script type="text/javascript" src="/resources/testharness.js"></script> + <script type="text/javascript" src="/resources/testharnessreport.js"></script> </head> <body> - <div id="log"> - </div> + <div id="log"> + </div> - <script type="text/javascript"> - var sampleRate=44100.0; - var tolerance=0.01; + <script type="text/javascript"> + var sampleRate=44100.0; + var tolerance=0.01; - /* - Testing that -1, 0 and +1 map correctly to curve (with 1:1 correlation) - ======================================================================= - From the specification: - The input signal is nominally within the range -1 -> +1. - Each input sample within this range will index into the shaping curve with a signal level of zero corresponding - to the center value of the curve array. - */ - (function() { - var threeElementCurve=[2.0, -3.0, 4.0]; - var inputData=[-1.0, 0, 1.0]; - var expectedData=[2.0, -3.0, 4.0]; - executeTest(threeElementCurve, inputData, expectedData, "Testing that -1, 0 and +1 map correctly to curve (with 1:1 correlation)"); - })(); + /* + Testing that -1, 0 and +1 map correctly to curve (with 1:1 correlation) + ======================================================================= + From the specification: + The input signal is nominally within the range -1 -> +1. + Each input sample within this range will index into the shaping curve with a signal level of zero corresponding + to the center value of the curve array. + */ + (function() { + var threeElementCurve=[2.0, -3.0, 4.0]; + var inputData=[-1.0, 0, 1.0]; + var expectedData=[2.0, -3.0, 4.0]; + executeTest(threeElementCurve, inputData, expectedData, "Testing that -1, 0 and +1 map correctly to curve (with 1:1 correlation)"); + })(); - /* - Testing interpolation (where inputs don't correlate directly to curve elements) - =============================================================================== - From the specification: - The implementation must perform linear interpolation between adjacent points in the curve. - */ - (function() { - var threeElementCurve=[2.0, -3.0, 4.0]; - var inputData=[-0.5, +0.5, +0.75]; - var expectedData=[-0.5, +0.5, +2.25]; - executeTest(threeElementCurve, inputData, expectedData, "Testing interpolation (where inputs don't correlate directly to curve elements)"); - })(); + /* + Testing interpolation (where inputs don't correlate directly to curve elements) + =============================================================================== + From the specification: + The implementation must perform linear interpolation between adjacent points in the curve. + */ + (function() { + var threeElementCurve=[2.0, -3.0, 4.0]; + var inputData=[-0.5, +0.5, +0.75]; + var expectedData=[-0.5, +0.5, +2.25]; + executeTest(threeElementCurve, inputData, expectedData, "Testing interpolation (where inputs don't correlate directly to curve elements)"); + })(); - /* - Testing out-of-range inputs (should be mapped to the first/last elements of the curve) - ====================================================================================== - From the specification: - Any sample value less than -1 will correspond to the first value in the curve array. - Any sample value greater than +1 will correspond to the last value in the curve array. - */ - (function() { - var threeElementCurve=[2.0, -3.0, 4.0]; - var inputData=[-1.5, +1.5]; - var expectedData=[2.0, 4.0]; - executeTest(threeElementCurve, inputData, expectedData, "Testing out-of-range inputs (should be mapped to the first/last elements of the curve)"); - })(); + /* + Testing out-of-range inputs (should be mapped to the first/last elements of the curve) + ====================================================================================== + From the specification: + Any sample value less than -1 will correspond to the first value in the curve array. + Any sample value greater than +1 will correspond to the last value in the curve array. + */ + (function() { + var threeElementCurve=[2.0, -3.0, 4.0]; + var inputData=[-1.5, +1.5]; + var expectedData=[2.0, 4.0]; + executeTest(threeElementCurve, inputData, expectedData, "Testing out-of-range inputs (should be mapped to the first/last elements of the curve)"); + })(); - /* - Testing a 2-element curve (does not have a middle element) - ========================================================== - From the specification: - Each input sample within this range will index into the shaping curve with a signal level of zero corresponding - to the center value of the curve array. - The implementation must perform linear interpolation between adjacent points in the curve. - */ - (function() { - var twoElementCurve=[2.0, -2.0]; - var inputData=[-1.0, 0, 1.0]; - var expectedData=[2.0, 0.0, -2.0]; - executeTest(twoElementCurve, inputData, expectedData, "Testing a 2-element curve (does not have a middle element)"); - })(); + /* + Testing a 2-element curve (does not have a middle element) + ========================================================== + From the specification: + Each input sample within this range will index into the shaping curve with a signal level of zero corresponding + to the center value of the curve array. + The implementation must perform linear interpolation between adjacent points in the curve. + */ + (function() { + var twoElementCurve=[2.0, -2.0]; + var inputData=[-1.0, 0, 1.0]; + var expectedData=[2.0, 0.0, -2.0]; + executeTest(twoElementCurve, inputData, expectedData, "Testing a 2-element curve (does not have a middle element)"); + })(); - /* - Testing a 4-element curve (does not have a middle element) - ========================================================== - From the specification: - Each input sample within this range will index into the shaping curve with a signal level of zero corresponding - to the center value of the curve array. - The implementation must perform linear interpolation between adjacent points in the curve. - */ - (function() { - var fourElementCurve=[1.0, 2.0, 4.0, 7.0]; - var inputData=[-1.0, 0, 1.0]; - var expectedData=[1.0, 3.0, 7.0]; - executeTest(fourElementCurve, inputData, expectedData, "Testing a 4-element curve (does not have a middle element)"); - })(); + /* + Testing a 4-element curve (does not have a middle element) + ========================================================== + From the specification: + Each input sample within this range will index into the shaping curve with a signal level of zero corresponding + to the center value of the curve array. + The implementation must perform linear interpolation between adjacent points in the curve. + */ + (function() { + var fourElementCurve=[1.0, 2.0, 4.0, 7.0]; + var inputData=[-1.0, 0, 1.0]; + var expectedData=[1.0, 3.0, 7.0]; + executeTest(fourElementCurve, inputData, expectedData, "Testing a 4-element curve (does not have a middle element)"); + })(); - /* - Testing a huge curve - ==================== - From the specification: - Each input sample within this range will index into the shaping curve with a signal level of zero corresponding - to the center value of the curve array. - */ - (function() { - var bigCurve=[]; - for(var i=0;i<=60000;i++) { bigCurve.push(i/3.5435); } - var inputData=[-1.0, 0, 1.0]; - var expectedData=[bigCurve[0], bigCurve[30000], bigCurve[60000]]; - executeTest(bigCurve, inputData, expectedData, "Testing a huge curve"); - })(); + /* + Testing a huge curve + ==================== + From the specification: + Each input sample within this range will index into the shaping curve with a signal level of zero corresponding + to the center value of the curve array. + */ + (function() { + var bigCurve=[]; + for(var i=0;i<=60000;i++) { bigCurve.push(i/3.5435); } + var inputData=[-1.0, 0, 1.0]; + var expectedData=[bigCurve[0], bigCurve[30000], bigCurve[60000]]; + executeTest(bigCurve, inputData, expectedData, "Testing a huge curve"); + })(); - /* - Testing single-element curve (boundary condition) - ================================================= - From the specification: - Each input sample within this range will index into the shaping curve with a signal level of zero corresponding - to the center value of the curve array. - Any sample value less than -1 will correspond to the first value in the curve array. - Any sample value greater than +1 will correspond to the last value in the curve array. - The implementation must perform linear interpolation between adjacent points in the curve. - */ + /* + Testing single-element curve (boundary condition) + ================================================= + From the specification: + Each input sample within this range will index into the shaping curve with a signal level of zero corresponding + to the center value of the curve array. + Any sample value less than -1 will correspond to the first value in the curve array. + Any sample value greater than +1 will correspond to the last value in the curve array. + The implementation must perform linear interpolation between adjacent points in the curve. + */ - /* - Testing null curve (should return input values) - =============================================== - From the specification: - Initially the curve attribute is null, which means that the WaveShaperNode will pass its input to its output - without modification. - */ - (function() { - var inputData=[-1.0, 0, 1.0, 2.0]; - var expectedData=[-1.0, 0.0, 1.0, 2.0]; - executeTest(null, inputData, expectedData, "Testing null curve (should return input values)"); - })(); + /* + Testing null curve (should return input values) + =============================================== + From the specification: + Initially the curve attribute is null, which means that the WaveShaperNode will pass its input to its output + without modification. + */ + (function() { + var inputData=[-1.0, 0, 1.0, 2.0]; + var expectedData=[-1.0, 0.0, 1.0, 2.0]; + executeTest(null, inputData, expectedData, "Testing null curve (should return input values)"); + })(); - /** - * Function that does the actual testing (using an asynchronous test). - * @param {?Array.<number>} curveData - Array containing values for the WaveShaper curve. - * @param {!Array.<number>} inputData - Array containing values for the input stream. - * @param {!Array.<number>} expectedData - Array containing expected results for each of the corresponding inputs. - * @param {!string} testName - Name of the test case. - */ - function executeTest(curveData, inputData, expectedData, testName) { - var stTest=async_test("WaveShaperNode - "+testName); - stTest.step(function() { + /** + * Function that does the actual testing (using an asynchronous test). + * @param {?Array.<number>} curveData - Array containing values for the WaveShaper curve. + * @param {!Array.<number>} inputData - Array containing values for the input stream. + * @param {!Array.<number>} expectedData - Array containing expected results for each of the corresponding inputs. + * @param {!string} testName - Name of the test case. + */ + function executeTest(curveData, inputData, expectedData, testName) { + var stTest=async_test("WaveShaperNode - "+testName); + stTest.step(function() { - // Create offline audio context. - var ac=new OfflineAudioContext(1, inputData.length, sampleRate); + // Create offline audio context. + var ac=new OfflineAudioContext(1, inputData.length, sampleRate); - // Create the WaveShaper and its curve. - var waveShaper=ac.createWaveShaper(); - if(curveData!=null) { - var curve=new Float32Array(curveData.length); - for(var i=0;i<curveData.length;i++) { curve[i]=curveData[i]; } - waveShaper.curve=curve; - } - waveShaper.connect(ac.destination); + // Create the WaveShaper and its curve. + var waveShaper=ac.createWaveShaper(); + if(curveData!=null) { + var curve=new Float32Array(curveData.length); + for(var i=0;i<curveData.length;i++) { curve[i]=curveData[i]; } + waveShaper.curve=curve; + } + waveShaper.connect(ac.destination); - // Create buffer containing the input values. - var inputBuffer=ac.createBuffer(1, Math.max(inputData.length, 2), sampleRate); - var d=inputBuffer.getChannelData(0); - for(var i=0;i<inputData.length;i++) { d[i]=inputData[i]; } + // Create buffer containing the input values. + var inputBuffer=ac.createBuffer(1, Math.max(inputData.length, 2), sampleRate); + var d=inputBuffer.getChannelData(0); + for(var i=0;i<inputData.length;i++) { d[i]=inputData[i]; } - // Play the input buffer through the WaveShaper. - var src=ac.createBufferSource(); - src.buffer=inputBuffer; - src.connect(waveShaper); - src.start(); + // Play the input buffer through the WaveShaper. + var src=ac.createBufferSource(); + src.buffer=inputBuffer; + src.connect(waveShaper); + src.start(); - // Test the outputs match the expected values. - ac.oncomplete=stTest.step_func_done(function(ev) { - var d=ev.renderedBuffer.getChannelData(0); + // Test the outputs match the expected values. + ac.oncomplete=stTest.step_func_done(function(ev) { + var d=ev.renderedBuffer.getChannelData(0); - for(var i=0;i<expectedData.length;i++) { - var curveText="null"; - if(curve!=null) { - if(curveData.length<20) { - curveText=curveData.join(","); - } else { - curveText="TooBigToDisplay ("+(curveData.length-1)+" elements)"; - } - } - var comment="Input="+inputData[i]+", Curve=["+curveText+"] >>> "; - assert_approx_equals(d[i], expectedData[i], tolerance, comment); - } - }); - ac.startRendering(); - }); - } - </script> + for(var i=0;i<expectedData.length;i++) { + var curveText="null"; + if(curve!=null) { + if(curveData.length<20) { + curveText=curveData.join(","); + } else { + curveText="TooBigToDisplay ("+(curveData.length-1)+" elements)"; + } + } + var comment="Input="+inputData[i]+", Curve=["+curveText+"] >>> "; + assert_approx_equals(d[i], expectedData[i], tolerance, comment); + } + }); + ac.startRendering(); + }); + } + </script> </body> </html>
diff --git a/third_party/blink/web_tests/external/wpt/webmessaging/Channel_postMessage_transfer_xsite_incoming_messages.window.js b/third_party/blink/web_tests/external/wpt/webmessaging/Channel_postMessage_transfer_xsite_incoming_messages.window.js new file mode 100644 index 0000000..23237ae --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webmessaging/Channel_postMessage_transfer_xsite_incoming_messages.window.js
@@ -0,0 +1,32 @@ +// META: script=/common/get-host-info.sub.js + +async_test(function(t) { + var channel1 = new MessageChannel(); + var host = get_host_info(); + let iframe = document.createElement('iframe'); + iframe.src = host.HTTP_NOTSAMESITE_ORIGIN + "/webmessaging/support/ChildWindowPostMessage.htm"; + document.body.appendChild(iframe); + var TARGET = document.querySelector("iframe").contentWindow; + iframe.onload = t.step_func(function() { + // Enable the port. + channel1.port1.onmessage = t.step_func(function (evt) { + assert_equals(Number(evt.data), 0); + + // Send a message, expecting it to be received in the iframe. + channel1.port2.postMessage(1) + + // Transfer the port. + TARGET.postMessage("ports", "*", [channel1.port1]); + }); + + // Send a message, expecting it to be received here. + channel1.port2.postMessage(0) + + channel1.port2.onmessage = t.step_func(function (evt) { + assert_equals(Number(evt.data), 1); + t.done(); + }); + }); +}, `Tasks enqueued on the port-message-queue of an enabled port, + are transferred along with the port, when the transfer happens in the same task + during which postMessage is called`);
diff --git a/third_party/blink/web_tests/external/wpt/webmessaging/Channel_postMessage_with_transfer_entangled.any.js b/third_party/blink/web_tests/external/wpt/webmessaging/Channel_postMessage_with_transfer_entangled.any.js new file mode 100644 index 0000000..2226b27 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webmessaging/Channel_postMessage_with_transfer_entangled.any.js
@@ -0,0 +1,36 @@ +async_test(function(t) { + var channel1 = new MessageChannel(); + var channel2 = new MessageChannel(); + + // One, send a message. + channel1.port1.postMessage(1); + + // Two, transfer both ports. + channel2.port1.postMessage("transfer", [channel1.port1]); + channel2.port1.postMessage("transfer", [channel1.port2]); + + var transfer_counter = 0; + var sender; + channel2.port2.onmessage = t.step_func(function (evt) { + if (transfer_counter == 0) { + sender = evt.ports[0]; + transfer_counter = 1; + } else { + sender.postMessage(2); + var counter = 0; + evt.ports[0].onmessage = t.step_func(function (evt) { + if (counter == 0) { + assert_equals(evt.data, 1); + counter = 1; + } else if (counter == 1) { + assert_equals(evt.data, 2); + counter = 2; + } else { + assert_equals(evt.data, 3); + t.done(); + } + }); + sender.postMessage(3); + } + }); +}, "An entangled port transferred to the same origin receives messages in order");
diff --git a/third_party/blink/web_tests/external/wpt/webmessaging/Channel_postMessage_with_transfer_incoming_messages.any.js b/third_party/blink/web_tests/external/wpt/webmessaging/Channel_postMessage_with_transfer_incoming_messages.any.js new file mode 100644 index 0000000..fe2e962 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webmessaging/Channel_postMessage_with_transfer_incoming_messages.any.js
@@ -0,0 +1,32 @@ +async_test(function(t) { + var channel1 = new MessageChannel(); + var channel2 = new MessageChannel(); + var channel3 = new MessageChannel(); + channel2.port2.onmessage = t.step_func(function (evt) { + channel3.port1.onmessage = t.step_func(function (evt) { + var counter = 0; + evt.ports[0].onmessage = t.step_func(function (evt) { + if (counter == 0) { + assert_equals(evt.data, "First"); + counter = 1; + } else if (counter == 1) { + assert_equals(evt.data, "Second"); + counter = 2; + } else if (counter == 2) { + assert_equals(evt.data, "Third"); + counter = 3; + } else if (counter == 3) { + assert_equals(evt.data, "Fourth"); + t.done(); + } + }); + channel1.port2.postMessage("Fourth"); + }); + channel1.port2.postMessage("Second"); + channel1.port2.postMessage("Third"); + channel3.port2.postMessage("2", evt.ports); + }); + channel1.port2.postMessage("First"); + channel2.port1.postMessage("1", [channel1.port1]); +}, `When transferring a non-enabled port mutiple times, + incoming messages sent at various transfer steps are received in order upon enablement.`);
diff --git a/third_party/blink/web_tests/external/wpt/webmessaging/Channel_postMessage_with_transfer_outgoing_messages.any.js b/third_party/blink/web_tests/external/wpt/webmessaging/Channel_postMessage_with_transfer_outgoing_messages.any.js new file mode 100644 index 0000000..aa80b75 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webmessaging/Channel_postMessage_with_transfer_outgoing_messages.any.js
@@ -0,0 +1,35 @@ + +async_test(function(t) { + var channel1 = new MessageChannel(); + var channel2 = new MessageChannel(); + var channel3 = new MessageChannel(); + channel2.port2.onmessage = t.step_func(function (evt) { + evt.ports[0].postMessage("Second"); + evt.ports[0].postMessage("Third"); + channel3.port1.onmessage = t.step_func(function (evt) { + evt.ports[0].postMessage("Fourth"); + }); + channel3.port2.postMessage("2", evt.ports); + }); + channel1.port1.postMessage("First"); + channel2.port1.postMessage("1", [channel1.port1]); + var counter = 0; + channel1.port2.onmessage = t.step_func(function (evt) { + if (counter == 0) { + assert_equals(evt.data, "First"); + counter = 1; + } else if (counter == 1) { + assert_equals(evt.data, "Second"); + counter = 2; + } + else if (counter == 2) { + assert_equals(evt.data, "Third"); + counter = 3; + } + else if (counter == 3) { + assert_equals(evt.data, "Fourth"); + t.done(); + } + }); +}, `When transferring a port, + outgoing messages sent at each transfer step are received in order by the entangled port.`);
diff --git a/third_party/blink/web_tests/external/wpt/webmessaging/postMessage_MessagePorts_xsite.sub.window.js b/third_party/blink/web_tests/external/wpt/webmessaging/postMessage_MessagePorts_xsite.sub.window.js new file mode 100644 index 0000000..ca1e510e --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webmessaging/postMessage_MessagePorts_xsite.sub.window.js
@@ -0,0 +1,66 @@ +// META: script=/common/get-host-info.sub.js + +async_test(function(t) { + var host = get_host_info(); + var noteSameSiteURL = host.HTTP_NOTSAMESITE_ORIGIN + "/webmessaging/support/ChildWindowPostMessage.htm"; + var TOTALPORTS = 100; + var LocalPorts = []; + var RemotePorts = []; + var PassedResult = 0; + var sum = 0; + let iframe = document.createElement('iframe'); + iframe.src = noteSameSiteURL; + document.body.appendChild(iframe); + var TARGET = document.querySelector("iframe").contentWindow; + iframe.onload = t.step_func(function() { + assert_own_property(window, "MessageChannel", "window"); + + var channels = []; + + for (var i=0; i<TOTALPORTS; i++) + { + channels[i] = new MessageChannel(); + LocalPorts[i] = channels[i].port1; + LocalPorts[i].foo = i; + RemotePorts[i] = channels[i].port2; + + LocalPorts[i].onmessage = t.step_func(function(e) + { + assert_equals(e.target.foo, e.data); + + PassedResult++; + sum += e.data; + + if (PassedResult == TOTALPORTS) + { + assert_equals(sum, 4950); + t.done(); + } + }); + } + // Sending in two batches, to test the two postMessage variants. + var firstBatch = RemotePorts.slice(0, 50); + var secondBatch = RemotePorts.slice(50, 100); + TARGET.postMessage("ports", "*", firstBatch); + TARGET.postMessage("ports", {targetOrigin: '*', transfer: secondBatch}); + }); + var counter = 0; + window.onmessage = function(e) + { + if (e.data === "ports") + { + if (counter == 0) { + for (var i=0; i<51; i++) + { + LocalPorts[i].postMessage(LocalPorts[i].foo); + } + counter = 1; + } else { + for (var i=51; i<100; i++) + { + LocalPorts[i].postMessage(LocalPorts[i].foo); + } + } + } + } +}, "Test Description: postMessage to cross-site iframe with MessagePort array containing 100 ports.");
diff --git a/third_party/blink/web_tests/fast/scrolling/scrollbars/dsf-ready/mouse-interactions-dsf-2.html b/third_party/blink/web_tests/fast/scrolling/scrollbars/dsf-ready/mouse-interactions-dsf-2.html new file mode 100644 index 0000000..1ddbd5d7 --- /dev/null +++ b/third_party/blink/web_tests/fast/scrolling/scrollbars/dsf-ready/mouse-interactions-dsf-2.html
@@ -0,0 +1,121 @@ +<!DOCTYPE html> +<title>Tests mouse interactions when DSF=2 and --enable-use-zoom-for-dsf=true.</title> +<script src="../../../../resources/testharness.js"></script> +<script src="../../../../resources/testharnessreport.js"></script> +<script src="../../../../resources/gesture-util.js"></script> +<script src="../../../../resources/scrollbar-util.js"></script> +<style> +.appearance { + width: 100px; + height: 100px; + overflow: scroll; + border: 1px solid black; +} +.standardLocation { + position: absolute; + top: 100px; + left: 100px; +} +.customLocation { + position: absolute; + top: 250px; + left: 100px; +} + +.space { + height: 1000px; + width: 1000px; +} +</style> + +<!-- Composited non-custom fast scroller --> +<div id="standard" class="appearance standardLocation"> + <div class="space"></div> +</div> + +<script> +if (window.internals) + internals.settings.setScrollAnimatorEnabled(false); + +window.onload = () => { + // http://crrev.com/c/1856359 disables mock theme and makes tests use the + // native theme. Hence, values will differ between platforms for both, main + // and compositor thread scrolling. + const onLinuxPlatform = navigator.userAgent.search(/\bLinux\b/) != -1; + const onMacPlatform = navigator.userAgent.search(/\bMac OS X\b/) != -1; + + const standardDivFast = document.getElementById("standard"); + const standardRectFast = standardDivFast.getBoundingClientRect(); + + const TRACK_WIDTH = calculateScrollbarThickness(); + const BUTTON_WIDTH = TRACK_WIDTH; + const SCROLL_CORNER = TRACK_WIDTH; + const SCROLLBAR_BUTTON_FWD = { + x: standardRectFast.right - BUTTON_WIDTH / 2, + y: standardRectFast.bottom - SCROLL_CORNER - BUTTON_WIDTH / 2 + } + const SCROLLBAR_THUMB = { + x: standardRectFast.right - TRACK_WIDTH / 2, + y: standardRectFast.top + BUTTON_WIDTH + 5 + } + + promise_test (async () => { + resetScrollOffset(standardDivFast); + + // Testing the vertical scrollbar thumb. + await mouseDragAndDrop(SCROLLBAR_THUMB.x, SCROLLBAR_THUMB.y, SCROLLBAR_THUMB.x, SCROLLBAR_THUMB.y + 20); + let expected_offset = 0; + + // TODO(arakeri): crbug.com/1016188 has been filed to investigate the differences + // in scroll offsets between platforms. + if (onLinuxPlatform) + expected_offset = window.devicePixelRatio == 1 ? 732 : 457.5; + else if (onMacPlatform) + expected_offset = 281; + else + expected_offset = window.devicePixelRatio == 1 ? 481 : 362; + assert_equals(standardDivFast.scrollTop, expected_offset, "Vertical thumb drag downwards did not scroll as expected."); + }, "Test mouse drags on non-custom composited div scrollbar thumb."); + + promise_test (async (test) => { + // Since scrollbars on Mac don't have buttons, this test is irrelevant. + if(onMacPlatform) + test.done(); + + resetScrollOffset(standardDivFast); + + // Click on the Down arrow for standardRectFast. + await mouseClickOn(SCROLLBAR_BUTTON_FWD.x, SCROLLBAR_BUTTON_FWD.y); + assert_equals(standardDivFast.scrollTop, 40, "Pressing the down arrow didn't scroll."); + }, "Test mouse click on non-custom composited div scrollbar arrows."); + + promise_test (async (test) => { + // TODO (arakeri): Track clicks on Mac don't work yet (crbug.com/1016452). + if(onMacPlatform) + test.done(); + + resetScrollOffset(standardDivFast); + + // Click on the track part just above the down arrow. + await mouseClickOn(SCROLLBAR_BUTTON_FWD.x, SCROLLBAR_BUTTON_FWD.y - 10); + assert_equals(standardDivFast.scrollTop, 74, "Pressing the down trackpart didn't scroll."); + }, "Test mouse click on non-custom composited div scrollbar empty trackparts."); + + promise_test (async (test) => { + // TODO (arakeri): Track clicks on Mac don't work yet (crbug.com/1016452). + if(onMacPlatform) + test.done(); + + resetScrollOffset(standardDivFast); + + // Testing forward scroll on vertical scrollbar. + await mouseClickOn(SCROLLBAR_BUTTON_FWD.x, standardRectFast.top + 50, /*left_click*/0, /*modifier*/ "Shift"); + let expected_offset = 0; + if (onLinuxPlatform) + expected_offset = window.devicePixelRatio == 1 ? 695 : 606; + else + expected_offset = window.devicePixelRatio == 1 ? 626 : 579.5; + assert_equals(standardDivFast.scrollTop, expected_offset, "Shift + click forward didn't scroll."); + }, "Test shift + click on non-custom composited scrollbars."); +} +</script>
diff --git a/third_party/blink/web_tests/inspector-protocol/layout-fonts/mac-case-insensitive-matching.js b/third_party/blink/web_tests/inspector-protocol/layout-fonts/mac-case-insensitive-matching.js new file mode 100644 index 0000000..ffee61a1 --- /dev/null +++ b/third_party/blink/web_tests/inspector-protocol/layout-fonts/mac-case-insensitive-matching.js
@@ -0,0 +1,37 @@ +(async function(testRunner) { + var page = await testRunner.createPage(); + await page.loadHTML(` + <html> + <meta charset="UTF-8"> + <style> + </style> + <body> + <div class="test"> + <!-- Use a different font size in order to avoid caching the FontDescriptions and skipping matching. --> + <div id="mixed_case_1" style="font-family: HIragINO KakU GothiC ProN; font-size: 12px;">クローミアム</div> + <div id="mixed_case_2" style="font-family: hiRAGino kAKu gOTHIc pROn; font-size: 13px;">クローミアム</div> + <div id="all_lower_case" style="font-family: hiragino kaku gothic pron; font-size: 14px;">クローミアム</div> + <div id="all_upper_case" style="font-family: HIRAGINO KAKU GOTHIC PRON; font-size: 15px;">クローミアム</div> + <div id="exact_case" style="font-family: Hiragino Kaku Gothic ProN; font-size: 16px;">クローミアム</div> + </div> + </body> + </html> + `); + var session = await page.createSession(); + testRunner.log('Test passes if each of the test divs uses the Hiragino Kaku Gothic ProN ' + + 'independently of capitalization of the font family name..'); + + var helper = await testRunner.loadScript('./resources/layout-font-test.js'); + var results = await helper(testRunner, session); + + var passed = results.length == 5; + const reduce_match_regexp = (passed, currentValue) => { + var current_value_passes = /Hiragino Kaku Gothic ProN/.test(currentValue.usedFonts[0].familyName) + && currentValue.usedFonts[0].glyphCount == 6; + return passed && current_value_passes; + } + passed = passed && results.reduce(reduce_match_regexp); + + testRunner.log(passed ? 'PASS' : 'FAIL'); + testRunner.completeTest(); +})
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-002-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-002-expected.txt new file mode 100644 index 0000000..95dd2e6 --- /dev/null +++ b/third_party/blink/web_tests/platform/linux/external/wpt/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-002-expected.txt
@@ -0,0 +1,8 @@ +This is a testharness.js-based test. +FAIL 'grid' with: grid-template-columns: minmax(0, 1fr) auto auto auto; and grid-template-rows: minmax(0, 1fr) auto auto auto; assert_in_array: gridTemplateColumns value "0px 50px 50px 50px" not in array ["0px 60px 45px 45px"] +FAIL 'grid' with: grid-template-columns: 1fr auto auto auto; and grid-template-rows: 1fr auto auto auto; assert_in_array: gridTemplateColumns value "0px 50px 50px 50px" not in array ["10px 50px 50px 50px"] +FAIL 'grid' with: grid-template-columns: 1fr 1fr 1fr 1fr; and grid-template-rows: 1fr 1fr 1fr 1fr; assert_in_array: gridTemplateColumns value "12.5px 12.5px 12.5px 12.5px" not in array ["30px 50px 50px 50px"] +FAIL 'grid' with: grid-template-columns: 1fr 1fr 1fr 4fr; and grid-template-rows: 1fr 1fr 1fr 4fr; assert_in_array: gridTemplateColumns value "7.14062px 7.14062px 7.14062px 28.5625px" not in array ["30px 30px 25px 100px"] +FAIL 'grid' with: grid-template-columns: 1fr 1fr 1fr; and grid-template-rows: 1fr 1fr 1fr; assert_in_array: gridTemplateColumns value "60px 0px 0px" not in array ["60px 50px 50px"] +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/url/url-setters-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/url/url-setters-expected.txt index 45715a7..5078e8a 100644 --- a/third_party/blink/web_tests/platform/linux/external/wpt/url/url-setters-expected.txt +++ b/third_party/blink/web_tests/platform/linux/external/wpt/url/url-setters-expected.txt
@@ -34,9 +34,9 @@ FAIL URL: Setting <http://test@example.net>.protocol = 'file' Can’t switch from URL containing username/password/port to file assert_equals: expected "http://test@example.net/" but got "file://test%40example.net/" FAIL <a>: Setting <http://test@example.net>.protocol = 'file' Can’t switch from URL containing username/password/port to file assert_equals: expected "http://test@example.net/" but got "file://test%40example.net/" FAIL <area>: Setting <http://test@example.net>.protocol = 'file' Can’t switch from URL containing username/password/port to file assert_equals: expected "http://test@example.net/" but got "file://test%40example.net/" -FAIL URL: Setting <gopher://example.net:1234>.protocol = 'file' assert_equals: expected "gopher://example.net:1234/" but got "file://example.net:1234/" -FAIL <a>: Setting <gopher://example.net:1234>.protocol = 'file' assert_equals: expected "gopher://example.net:1234/" but got "file://example.net:1234/" -FAIL <area>: Setting <gopher://example.net:1234>.protocol = 'file' assert_equals: expected "gopher://example.net:1234/" but got "file://example.net:1234/" +FAIL URL: Setting <gopher://example.net:1234>.protocol = 'file' assert_equals: expected "gopher://example.net:1234" but got "file://example.net:1234/" +FAIL <a>: Setting <gopher://example.net:1234>.protocol = 'file' assert_equals: expected "gopher://example.net:1234" but got "file://example.net:1234/" +FAIL <area>: Setting <gopher://example.net:1234>.protocol = 'file' assert_equals: expected "gopher://example.net:1234" but got "file://example.net:1234/" FAIL URL: Setting <wss://x:x@example.net:1234>.protocol = 'file' assert_equals: expected "wss://x:x@example.net:1234/" but got "file://x:x%40example.net:1234/" FAIL <a>: Setting <wss://x:x@example.net:1234>.protocol = 'file' assert_equals: expected "wss://x:x@example.net:1234/" but got "file://x:x%40example.net:1234/" FAIL <area>: Setting <wss://x:x@example.net:1234>.protocol = 'file' assert_equals: expected "wss://x:x@example.net:1234/" but got "file://x:x%40example.net:1234/" @@ -67,9 +67,9 @@ FAIL URL: Setting <ssh://me@example.net>.protocol = 'http' Can’t switch from non-special scheme to special assert_equals: expected "ssh://me@example.net" but got "http://me@example.net/" FAIL <a>: Setting <ssh://me@example.net>.protocol = 'http' Can’t switch from non-special scheme to special assert_equals: expected "ssh://me@example.net" but got "http://me@example.net/" FAIL <area>: Setting <ssh://me@example.net>.protocol = 'http' Can’t switch from non-special scheme to special assert_equals: expected "ssh://me@example.net" but got "http://me@example.net/" -FAIL URL: Setting <ssh://me@example.net>.protocol = 'gopher' assert_equals: expected "ssh://me@example.net" but got "gopher://me@example.net" -FAIL <a>: Setting <ssh://me@example.net>.protocol = 'gopher' assert_equals: expected "ssh://me@example.net" but got "gopher://me@example.net" -FAIL <area>: Setting <ssh://me@example.net>.protocol = 'gopher' assert_equals: expected "ssh://me@example.net" but got "gopher://me@example.net" +FAIL URL: Setting <ssh://me@example.net>.protocol = 'https' assert_equals: expected "ssh://me@example.net" but got "https://me@example.net/" +FAIL <a>: Setting <ssh://me@example.net>.protocol = 'https' assert_equals: expected "ssh://me@example.net" but got "https://me@example.net/" +FAIL <area>: Setting <ssh://me@example.net>.protocol = 'https' assert_equals: expected "ssh://me@example.net" but got "https://me@example.net/" FAIL URL: Setting <ssh://me@example.net>.protocol = 'file' assert_equals: expected "ssh://me@example.net" but got "file://me%40example.net/" FAIL <a>: Setting <ssh://me@example.net>.protocol = 'file' assert_equals: expected "ssh://me@example.net" but got "file://me%40example.net/" FAIL <area>: Setting <ssh://me@example.net>.protocol = 'file' assert_equals: expected "ssh://me@example.net" but got "file://me%40example.net/"
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/url/url-setters-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/url/url-setters-expected.txt index 45715a7..5078e8a 100644 --- a/third_party/blink/web_tests/platform/mac/external/wpt/url/url-setters-expected.txt +++ b/third_party/blink/web_tests/platform/mac/external/wpt/url/url-setters-expected.txt
@@ -34,9 +34,9 @@ FAIL URL: Setting <http://test@example.net>.protocol = 'file' Can’t switch from URL containing username/password/port to file assert_equals: expected "http://test@example.net/" but got "file://test%40example.net/" FAIL <a>: Setting <http://test@example.net>.protocol = 'file' Can’t switch from URL containing username/password/port to file assert_equals: expected "http://test@example.net/" but got "file://test%40example.net/" FAIL <area>: Setting <http://test@example.net>.protocol = 'file' Can’t switch from URL containing username/password/port to file assert_equals: expected "http://test@example.net/" but got "file://test%40example.net/" -FAIL URL: Setting <gopher://example.net:1234>.protocol = 'file' assert_equals: expected "gopher://example.net:1234/" but got "file://example.net:1234/" -FAIL <a>: Setting <gopher://example.net:1234>.protocol = 'file' assert_equals: expected "gopher://example.net:1234/" but got "file://example.net:1234/" -FAIL <area>: Setting <gopher://example.net:1234>.protocol = 'file' assert_equals: expected "gopher://example.net:1234/" but got "file://example.net:1234/" +FAIL URL: Setting <gopher://example.net:1234>.protocol = 'file' assert_equals: expected "gopher://example.net:1234" but got "file://example.net:1234/" +FAIL <a>: Setting <gopher://example.net:1234>.protocol = 'file' assert_equals: expected "gopher://example.net:1234" but got "file://example.net:1234/" +FAIL <area>: Setting <gopher://example.net:1234>.protocol = 'file' assert_equals: expected "gopher://example.net:1234" but got "file://example.net:1234/" FAIL URL: Setting <wss://x:x@example.net:1234>.protocol = 'file' assert_equals: expected "wss://x:x@example.net:1234/" but got "file://x:x%40example.net:1234/" FAIL <a>: Setting <wss://x:x@example.net:1234>.protocol = 'file' assert_equals: expected "wss://x:x@example.net:1234/" but got "file://x:x%40example.net:1234/" FAIL <area>: Setting <wss://x:x@example.net:1234>.protocol = 'file' assert_equals: expected "wss://x:x@example.net:1234/" but got "file://x:x%40example.net:1234/" @@ -67,9 +67,9 @@ FAIL URL: Setting <ssh://me@example.net>.protocol = 'http' Can’t switch from non-special scheme to special assert_equals: expected "ssh://me@example.net" but got "http://me@example.net/" FAIL <a>: Setting <ssh://me@example.net>.protocol = 'http' Can’t switch from non-special scheme to special assert_equals: expected "ssh://me@example.net" but got "http://me@example.net/" FAIL <area>: Setting <ssh://me@example.net>.protocol = 'http' Can’t switch from non-special scheme to special assert_equals: expected "ssh://me@example.net" but got "http://me@example.net/" -FAIL URL: Setting <ssh://me@example.net>.protocol = 'gopher' assert_equals: expected "ssh://me@example.net" but got "gopher://me@example.net" -FAIL <a>: Setting <ssh://me@example.net>.protocol = 'gopher' assert_equals: expected "ssh://me@example.net" but got "gopher://me@example.net" -FAIL <area>: Setting <ssh://me@example.net>.protocol = 'gopher' assert_equals: expected "ssh://me@example.net" but got "gopher://me@example.net" +FAIL URL: Setting <ssh://me@example.net>.protocol = 'https' assert_equals: expected "ssh://me@example.net" but got "https://me@example.net/" +FAIL <a>: Setting <ssh://me@example.net>.protocol = 'https' assert_equals: expected "ssh://me@example.net" but got "https://me@example.net/" +FAIL <area>: Setting <ssh://me@example.net>.protocol = 'https' assert_equals: expected "ssh://me@example.net" but got "https://me@example.net/" FAIL URL: Setting <ssh://me@example.net>.protocol = 'file' assert_equals: expected "ssh://me@example.net" but got "file://me%40example.net/" FAIL <a>: Setting <ssh://me@example.net>.protocol = 'file' assert_equals: expected "ssh://me@example.net" but got "file://me%40example.net/" FAIL <area>: Setting <ssh://me@example.net>.protocol = 'file' assert_equals: expected "ssh://me@example.net" but got "file://me%40example.net/"
diff --git a/third_party/blink/web_tests/platform/mac/inspector-protocol/layout-fonts/mac-case-insensitive-matching-expected.txt b/third_party/blink/web_tests/platform/mac/inspector-protocol/layout-fonts/mac-case-insensitive-matching-expected.txt new file mode 100644 index 0000000..2fe13cd --- /dev/null +++ b/third_party/blink/web_tests/platform/mac/inspector-protocol/layout-fonts/mac-case-insensitive-matching-expected.txt
@@ -0,0 +1,23 @@ +Test passes if each of the test divs uses the Hiragino Kaku Gothic ProN independently of capitalization of the font family name.. +クローミアム +#mixed_case_1: +"Hiragino Kaku Gothic ProN" : 6 + +クローミアム +#mixed_case_2: +"Hiragino Kaku Gothic ProN" : 6 + +クローミアム +#all_lower_case: +"Hiragino Kaku Gothic ProN" : 6 + +クローミアム +#all_upper_case: +"Hiragino Kaku Gothic ProN" : 6 + +クローミアム +#exact_case: +"Hiragino Kaku Gothic ProN" : 6 + +PASS +
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-002-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-002-expected.txt new file mode 100644 index 0000000..eb2a35ee --- /dev/null +++ b/third_party/blink/web_tests/platform/win/external/wpt/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-002-expected.txt
@@ -0,0 +1,8 @@ +This is a testharness.js-based test. +FAIL 'grid' with: grid-template-columns: minmax(0, 1fr) auto auto auto; and grid-template-rows: minmax(0, 1fr) auto auto auto; assert_in_array: gridTemplateColumns value "0px 50px 50px 50px" not in array ["0px 60px 45px 45px"] +FAIL 'grid' with: grid-template-columns: 1fr auto auto auto; and grid-template-rows: 1fr auto auto auto; assert_in_array: gridTemplateColumns value "0px 50px 50px 50px" not in array ["10px 50px 50px 50px"] +FAIL 'grid' with: grid-template-columns: 1fr 1fr 1fr 1fr; and grid-template-rows: 1fr 1fr 1fr 1fr; assert_in_array: gridTemplateColumns value "12.5px 12.5px 12.5px 12.5px" not in array ["30px 50px 50px 50px"] +FAIL 'grid' with: grid-template-columns: 1fr 1fr 1fr 4fr; and grid-template-rows: 1fr 1fr 1fr 4fr; assert_in_array: gridTemplateColumns value "7.14063px 7.14063px 7.14063px 28.5625px" not in array ["30px 30px 25px 100px"] +FAIL 'grid' with: grid-template-columns: 1fr 1fr 1fr; and grid-template-rows: 1fr 1fr 1fr; assert_in_array: gridTemplateColumns value "60px 0px 0px" not in array ["60px 50px 50px"] +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/html/semantics/forms/textfieldselection/selection-not-application-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/html/semantics/forms/textfieldselection/selection-not-application-expected.txt deleted file mode 100644 index 3a4b37af..0000000 --- a/third_party/blink/web_tests/platform/win/external/wpt/html/semantics/forms/textfieldselection/selection-not-application-expected.txt +++ /dev/null
@@ -1,196 +0,0 @@ -This is a testharness.js-based test. -Found 192 tests; 185 PASS, 7 FAIL, 0 TIMEOUT, 0 NOTRUN. -PASS selectionStart on an input[type=hidden] returns null -PASS selectionEnd on an input[type=hidden] returns null -PASS selectionDirection on an input[type=hidden] returns null -PASS assigning selectionStart on an input[type=hidden] throws InvalidStateError -PASS assigning selectionEnd on an input[type=hidden] throws InvalidStateError -PASS assigning selectionDirection on an input[type=hidden] throws InvalidStateError -PASS setRangeText on an input[type=hidden] throws InvalidStateError -PASS setSelectionRange on an input[type=hidden] throws InvalidStateError -PASS selectionStart on an input[type=email] returns null -PASS selectionEnd on an input[type=email] returns null -PASS selectionDirection on an input[type=email] returns null -PASS assigning selectionStart on an input[type=email] throws InvalidStateError -PASS assigning selectionEnd on an input[type=email] throws InvalidStateError -PASS assigning selectionDirection on an input[type=email] throws InvalidStateError -PASS setRangeText on an input[type=email] throws InvalidStateError -PASS setSelectionRange on an input[type=email] throws InvalidStateError -PASS selectionStart on an input[type=datetime-local] returns null -PASS selectionEnd on an input[type=datetime-local] returns null -PASS selectionDirection on an input[type=datetime-local] returns null -PASS assigning selectionStart on an input[type=datetime-local] throws InvalidStateError -PASS assigning selectionEnd on an input[type=datetime-local] throws InvalidStateError -PASS assigning selectionDirection on an input[type=datetime-local] throws InvalidStateError -PASS setRangeText on an input[type=datetime-local] throws InvalidStateError -PASS setSelectionRange on an input[type=datetime-local] throws InvalidStateError -PASS selectionStart on an input[type=date] returns null -PASS selectionEnd on an input[type=date] returns null -PASS selectionDirection on an input[type=date] returns null -PASS assigning selectionStart on an input[type=date] throws InvalidStateError -PASS assigning selectionEnd on an input[type=date] throws InvalidStateError -PASS assigning selectionDirection on an input[type=date] throws InvalidStateError -PASS setRangeText on an input[type=date] throws InvalidStateError -PASS setSelectionRange on an input[type=date] throws InvalidStateError -PASS selectionStart on an input[type=month] returns null -PASS selectionEnd on an input[type=month] returns null -PASS selectionDirection on an input[type=month] returns null -PASS assigning selectionStart on an input[type=month] throws InvalidStateError -PASS assigning selectionEnd on an input[type=month] throws InvalidStateError -PASS assigning selectionDirection on an input[type=month] throws InvalidStateError -PASS setRangeText on an input[type=month] throws InvalidStateError -PASS setSelectionRange on an input[type=month] throws InvalidStateError -PASS selectionStart on an input[type=week] returns null -PASS selectionEnd on an input[type=week] returns null -PASS selectionDirection on an input[type=week] returns null -PASS assigning selectionStart on an input[type=week] throws InvalidStateError -PASS assigning selectionEnd on an input[type=week] throws InvalidStateError -PASS assigning selectionDirection on an input[type=week] throws InvalidStateError -PASS setRangeText on an input[type=week] throws InvalidStateError -PASS setSelectionRange on an input[type=week] throws InvalidStateError -PASS selectionStart on an input[type=time] returns null -PASS selectionEnd on an input[type=time] returns null -PASS selectionDirection on an input[type=time] returns null -PASS assigning selectionStart on an input[type=time] throws InvalidStateError -PASS assigning selectionEnd on an input[type=time] throws InvalidStateError -PASS assigning selectionDirection on an input[type=time] throws InvalidStateError -PASS setRangeText on an input[type=time] throws InvalidStateError -PASS setSelectionRange on an input[type=time] throws InvalidStateError -PASS selectionStart on an input[type=number] returns null -PASS selectionEnd on an input[type=number] returns null -PASS selectionDirection on an input[type=number] returns null -PASS assigning selectionStart on an input[type=number] throws InvalidStateError -PASS assigning selectionEnd on an input[type=number] throws InvalidStateError -PASS assigning selectionDirection on an input[type=number] throws InvalidStateError -PASS setRangeText on an input[type=number] throws InvalidStateError -PASS setSelectionRange on an input[type=number] throws InvalidStateError -PASS selectionStart on an input[type=range] returns null -PASS selectionEnd on an input[type=range] returns null -PASS selectionDirection on an input[type=range] returns null -PASS assigning selectionStart on an input[type=range] throws InvalidStateError -PASS assigning selectionEnd on an input[type=range] throws InvalidStateError -PASS assigning selectionDirection on an input[type=range] throws InvalidStateError -PASS setRangeText on an input[type=range] throws InvalidStateError -PASS setSelectionRange on an input[type=range] throws InvalidStateError -PASS selectionStart on an input[type=color] returns null -PASS selectionEnd on an input[type=color] returns null -PASS selectionDirection on an input[type=color] returns null -PASS assigning selectionStart on an input[type=color] throws InvalidStateError -PASS assigning selectionEnd on an input[type=color] throws InvalidStateError -PASS assigning selectionDirection on an input[type=color] throws InvalidStateError -PASS setRangeText on an input[type=color] throws InvalidStateError -PASS setSelectionRange on an input[type=color] throws InvalidStateError -PASS selectionStart on an input[type=checkbox] returns null -PASS selectionEnd on an input[type=checkbox] returns null -PASS selectionDirection on an input[type=checkbox] returns null -PASS assigning selectionStart on an input[type=checkbox] throws InvalidStateError -PASS assigning selectionEnd on an input[type=checkbox] throws InvalidStateError -PASS assigning selectionDirection on an input[type=checkbox] throws InvalidStateError -PASS setRangeText on an input[type=checkbox] throws InvalidStateError -PASS setSelectionRange on an input[type=checkbox] throws InvalidStateError -PASS selectionStart on an input[type=radio] returns null -PASS selectionEnd on an input[type=radio] returns null -PASS selectionDirection on an input[type=radio] returns null -PASS assigning selectionStart on an input[type=radio] throws InvalidStateError -PASS assigning selectionEnd on an input[type=radio] throws InvalidStateError -PASS assigning selectionDirection on an input[type=radio] throws InvalidStateError -PASS setRangeText on an input[type=radio] throws InvalidStateError -PASS setSelectionRange on an input[type=radio] throws InvalidStateError -PASS selectionStart on an input[type=file] returns null -PASS selectionEnd on an input[type=file] returns null -PASS selectionDirection on an input[type=file] returns null -PASS assigning selectionStart on an input[type=file] throws InvalidStateError -PASS assigning selectionEnd on an input[type=file] throws InvalidStateError -PASS assigning selectionDirection on an input[type=file] throws InvalidStateError -PASS setRangeText on an input[type=file] throws InvalidStateError -PASS setSelectionRange on an input[type=file] throws InvalidStateError -PASS selectionStart on an input[type=submit] returns null -PASS selectionEnd on an input[type=submit] returns null -PASS selectionDirection on an input[type=submit] returns null -PASS assigning selectionStart on an input[type=submit] throws InvalidStateError -PASS assigning selectionEnd on an input[type=submit] throws InvalidStateError -PASS assigning selectionDirection on an input[type=submit] throws InvalidStateError -PASS setRangeText on an input[type=submit] throws InvalidStateError -PASS setSelectionRange on an input[type=submit] throws InvalidStateError -PASS selectionStart on an input[type=image] returns null -PASS selectionEnd on an input[type=image] returns null -PASS selectionDirection on an input[type=image] returns null -PASS assigning selectionStart on an input[type=image] throws InvalidStateError -PASS assigning selectionEnd on an input[type=image] throws InvalidStateError -PASS assigning selectionDirection on an input[type=image] throws InvalidStateError -PASS setRangeText on an input[type=image] throws InvalidStateError -PASS setSelectionRange on an input[type=image] throws InvalidStateError -PASS selectionStart on an input[type=reset] returns null -PASS selectionEnd on an input[type=reset] returns null -PASS selectionDirection on an input[type=reset] returns null -PASS assigning selectionStart on an input[type=reset] throws InvalidStateError -PASS assigning selectionEnd on an input[type=reset] throws InvalidStateError -PASS assigning selectionDirection on an input[type=reset] throws InvalidStateError -PASS setRangeText on an input[type=reset] throws InvalidStateError -PASS setSelectionRange on an input[type=reset] throws InvalidStateError -PASS selectionStart on an input[type=button] returns null -PASS selectionEnd on an input[type=button] returns null -PASS selectionDirection on an input[type=button] returns null -PASS assigning selectionStart on an input[type=button] throws InvalidStateError -PASS assigning selectionEnd on an input[type=button] throws InvalidStateError -PASS assigning selectionDirection on an input[type=button] throws InvalidStateError -PASS setRangeText on an input[type=button] throws InvalidStateError -PASS setSelectionRange on an input[type=button] throws InvalidStateError -PASS selectionStart on an input[type=text] returns a value -PASS selectionEnd on an input[type=text] returns a value -FAIL selectionDirection on an input[type=text] returns a value assert_equals: expected "none" but got "forward" -PASS assigning selectionStart on an input[type=text] doesn't throw an exception -PASS assigning selectionEnd on an input[type=text] doesn't throw an exception -PASS assigning selectionDirection on an input[type=text] doesn't throw an exception -PASS setRangeText on an input[type=text] doesn't throw an exception -PASS setSelectionRange on an input[type=text] doesn't throw an exception -PASS selectionStart on an input[type=search] returns a value -PASS selectionEnd on an input[type=search] returns a value -FAIL selectionDirection on an input[type=search] returns a value assert_equals: expected "none" but got "forward" -PASS assigning selectionStart on an input[type=search] doesn't throw an exception -PASS assigning selectionEnd on an input[type=search] doesn't throw an exception -PASS assigning selectionDirection on an input[type=search] doesn't throw an exception -PASS setRangeText on an input[type=search] doesn't throw an exception -PASS setSelectionRange on an input[type=search] doesn't throw an exception -PASS selectionStart on an input[type=tel] returns a value -PASS selectionEnd on an input[type=tel] returns a value -FAIL selectionDirection on an input[type=tel] returns a value assert_equals: expected "none" but got "forward" -PASS assigning selectionStart on an input[type=tel] doesn't throw an exception -PASS assigning selectionEnd on an input[type=tel] doesn't throw an exception -PASS assigning selectionDirection on an input[type=tel] doesn't throw an exception -PASS setRangeText on an input[type=tel] doesn't throw an exception -PASS setSelectionRange on an input[type=tel] doesn't throw an exception -PASS selectionStart on an input[type=url] returns a value -PASS selectionEnd on an input[type=url] returns a value -FAIL selectionDirection on an input[type=url] returns a value assert_equals: expected "none" but got "forward" -PASS assigning selectionStart on an input[type=url] doesn't throw an exception -PASS assigning selectionEnd on an input[type=url] doesn't throw an exception -PASS assigning selectionDirection on an input[type=url] doesn't throw an exception -PASS setRangeText on an input[type=url] doesn't throw an exception -PASS setSelectionRange on an input[type=url] doesn't throw an exception -PASS selectionStart on an input[type=password] returns a value -PASS selectionEnd on an input[type=password] returns a value -FAIL selectionDirection on an input[type=password] returns a value assert_equals: expected "none" but got "forward" -PASS assigning selectionStart on an input[type=password] doesn't throw an exception -PASS assigning selectionEnd on an input[type=password] doesn't throw an exception -PASS assigning selectionDirection on an input[type=password] doesn't throw an exception -PASS setRangeText on an input[type=password] doesn't throw an exception -PASS setSelectionRange on an input[type=password] doesn't throw an exception -PASS selectionStart on an input[type=aninvalidtype] returns a value -PASS selectionEnd on an input[type=aninvalidtype] returns a value -FAIL selectionDirection on an input[type=aninvalidtype] returns a value assert_equals: expected "none" but got "forward" -PASS assigning selectionStart on an input[type=aninvalidtype] doesn't throw an exception -PASS assigning selectionEnd on an input[type=aninvalidtype] doesn't throw an exception -PASS assigning selectionDirection on an input[type=aninvalidtype] doesn't throw an exception -PASS setRangeText on an input[type=aninvalidtype] doesn't throw an exception -PASS setSelectionRange on an input[type=aninvalidtype] doesn't throw an exception -PASS selectionStart on an input[type=null] returns a value -PASS selectionEnd on an input[type=null] returns a value -FAIL selectionDirection on an input[type=null] returns a value assert_equals: expected "none" but got "forward" -PASS assigning selectionStart on an input[type=null] doesn't throw an exception -PASS assigning selectionEnd on an input[type=null] doesn't throw an exception -PASS assigning selectionDirection on an input[type=null] doesn't throw an exception -PASS setRangeText on an input[type=null] doesn't throw an exception -PASS setSelectionRange on an input[type=null] doesn't throw an exception -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/url/url-setters-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/url/url-setters-expected.txt index a14b6eca..13c7f6a 100644 --- a/third_party/blink/web_tests/platform/win/external/wpt/url/url-setters-expected.txt +++ b/third_party/blink/web_tests/platform/win/external/wpt/url/url-setters-expected.txt
@@ -34,9 +34,9 @@ FAIL URL: Setting <http://test@example.net>.protocol = 'file' Can’t switch from URL containing username/password/port to file assert_equals: expected "http://test@example.net/" but got "file://test%40example.net/" FAIL <a>: Setting <http://test@example.net>.protocol = 'file' Can’t switch from URL containing username/password/port to file assert_equals: expected "http://test@example.net/" but got "file://test%40example.net/" FAIL <area>: Setting <http://test@example.net>.protocol = 'file' Can’t switch from URL containing username/password/port to file assert_equals: expected "http://test@example.net/" but got "file://test%40example.net/" -FAIL URL: Setting <gopher://example.net:1234>.protocol = 'file' assert_equals: expected "gopher://example.net:1234/" but got "file://example.net:1234/" -FAIL <a>: Setting <gopher://example.net:1234>.protocol = 'file' assert_equals: expected "gopher://example.net:1234/" but got "file://example.net:1234/" -FAIL <area>: Setting <gopher://example.net:1234>.protocol = 'file' assert_equals: expected "gopher://example.net:1234/" but got "file://example.net:1234/" +FAIL URL: Setting <gopher://example.net:1234>.protocol = 'file' assert_equals: expected "gopher://example.net:1234" but got "file://example.net:1234/" +FAIL <a>: Setting <gopher://example.net:1234>.protocol = 'file' assert_equals: expected "gopher://example.net:1234" but got "file://example.net:1234/" +FAIL <area>: Setting <gopher://example.net:1234>.protocol = 'file' assert_equals: expected "gopher://example.net:1234" but got "file://example.net:1234/" FAIL URL: Setting <wss://x:x@example.net:1234>.protocol = 'file' assert_equals: expected "wss://x:x@example.net:1234/" but got "file:///X:/x@example.net:1234/" FAIL <a>: Setting <wss://x:x@example.net:1234>.protocol = 'file' assert_equals: expected "wss://x:x@example.net:1234/" but got "file:///X:/x@example.net:1234/" FAIL <area>: Setting <wss://x:x@example.net:1234>.protocol = 'file' assert_equals: expected "wss://x:x@example.net:1234/" but got "file:///X:/x@example.net:1234/" @@ -67,9 +67,9 @@ FAIL URL: Setting <ssh://me@example.net>.protocol = 'http' Can’t switch from non-special scheme to special assert_equals: expected "ssh://me@example.net" but got "http://me@example.net/" FAIL <a>: Setting <ssh://me@example.net>.protocol = 'http' Can’t switch from non-special scheme to special assert_equals: expected "ssh://me@example.net" but got "http://me@example.net/" FAIL <area>: Setting <ssh://me@example.net>.protocol = 'http' Can’t switch from non-special scheme to special assert_equals: expected "ssh://me@example.net" but got "http://me@example.net/" -FAIL URL: Setting <ssh://me@example.net>.protocol = 'gopher' assert_equals: expected "ssh://me@example.net" but got "gopher://me@example.net" -FAIL <a>: Setting <ssh://me@example.net>.protocol = 'gopher' assert_equals: expected "ssh://me@example.net" but got "gopher://me@example.net" -FAIL <area>: Setting <ssh://me@example.net>.protocol = 'gopher' assert_equals: expected "ssh://me@example.net" but got "gopher://me@example.net" +FAIL URL: Setting <ssh://me@example.net>.protocol = 'https' assert_equals: expected "ssh://me@example.net" but got "https://me@example.net/" +FAIL <a>: Setting <ssh://me@example.net>.protocol = 'https' assert_equals: expected "ssh://me@example.net" but got "https://me@example.net/" +FAIL <area>: Setting <ssh://me@example.net>.protocol = 'https' assert_equals: expected "ssh://me@example.net" but got "https://me@example.net/" FAIL URL: Setting <ssh://me@example.net>.protocol = 'file' assert_equals: expected "ssh://me@example.net" but got "file://me%40example.net/" FAIL <a>: Setting <ssh://me@example.net>.protocol = 'file' assert_equals: expected "ssh://me@example.net" but got "file://me%40example.net/" FAIL <area>: Setting <ssh://me@example.net>.protocol = 'file' assert_equals: expected "ssh://me@example.net" but got "file://me%40example.net/"
diff --git a/third_party/blink/web_tests/virtual/compositor_threaded_scrollbar_scrolling_hidpi/README.md b/third_party/blink/web_tests/virtual/compositor_threaded_scrollbar_scrolling_hidpi/README.md new file mode 100644 index 0000000..2fb1e160 --- /dev/null +++ b/third_party/blink/web_tests/virtual/compositor_threaded_scrollbar_scrolling_hidpi/README.md
@@ -0,0 +1,2 @@ +This directory is dedicated for testing scrollbar interactions on the +compositor thread with device_scale_factor set to 2.
diff --git a/third_party/blink/web_tests/virtual/hidpi/README.md b/third_party/blink/web_tests/virtual/hidpi/README.md new file mode 100644 index 0000000..2079fc44 --- /dev/null +++ b/third_party/blink/web_tests/virtual/hidpi/README.md
@@ -0,0 +1,2 @@ +This directory is dedicated for testing scrollbar interactions on the +main thread with device_scale_factor set to 2.
diff --git a/third_party/polymer/v1_0/bower.json b/third_party/polymer/v1_0/bower.json index f44cbde..c09e396 100644 --- a/third_party/polymer/v1_0/bower.json +++ b/third_party/polymer/v1_0/bower.json
@@ -4,7 +4,6 @@ "dependencies": { "font-roboto": "PolymerElements/font-roboto#1.0.1", "html-imports": "webcomponents/html-imports#1.2.0", - "html-imports-v0": "webcomponents/html-imports#v0", "iron-a11y-announcer": "PolymerElements/iron-a11y-announcer#2.1.0", "iron-a11y-keys-behavior": "PolymerElements/iron-a11y-keys-behavior#2.1.1", "iron-a11y-keys": "PolymerElements/iron-a11y-keys#2.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/html-imports-v0/bower.json b/third_party/polymer/v1_0/components-chromium/html-imports-v0/bower.json deleted file mode 100644 index 8be0702..0000000 --- a/third_party/polymer/v1_0/components-chromium/html-imports-v0/bower.json +++ /dev/null
@@ -1,22 +0,0 @@ -{ - "name": "html-imports", - "main": "html-imports.min.js", - "version": "0.0.1", - "homepage": "http://webcomponents.org", - "authors": [ - "The Polymer Authors" - ], - "repository": { - "type": "git", - "url": "https://github.com/webcomponents/html-imports.git" - }, - "keywords": [ - "webcomponents" - ], - "license": "BSD", - "ignore": [], - "devDependencies": { - "web-component-tester": "^4.0.1", - "polymer": "2.0-preview" - } -}
diff --git a/third_party/polymer/v1_0/components-chromium/html-imports-v0/html-imports.min.js b/third_party/polymer/v1_0/components-chromium/html-imports-v0/html-imports.min.js deleted file mode 100644 index 0347c61..0000000 --- a/third_party/polymer/v1_0/components-chromium/html-imports-v0/html-imports.min.js +++ /dev/null
@@ -1,11 +0,0 @@ -/** - * @license - * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. - * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt - * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt - * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt - * Code distributed by Google as part of the polymer project is also - * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt - */ -// @version 0.7.23 -"undefined"==typeof WeakMap&&!function(){var e=Object.defineProperty,t=Date.now()%1e9,n=function(){this.name="__st"+(1e9*Math.random()>>>0)+(t++ +"__")};n.prototype={set:function(t,n){var r=t[this.name];return r&&r[0]===t?r[1]=n:e(t,this.name,{value:[t,n],writable:!0}),this},get:function(e){var t;return(t=e[this.name])&&t[0]===e?t[1]:void 0},"delete":function(e){var t=e[this.name];return!(!t||t[0]!==e)&&(t[0]=t[1]=void 0,!0)},has:function(e){var t=e[this.name];return!!t&&t[0]===e}},window.WeakMap=n}(),function(e){function t(e){E.push(e),g||(g=!0,f(r))}function n(e){return window.ShadowDOMPolyfill&&window.ShadowDOMPolyfill.wrapIfNeeded(e)||e}function r(){g=!1;var e=E;E=[],e.sort(function(e,t){return e.uid_-t.uid_});var t=!1;e.forEach(function(e){var n=e.takeRecords();o(e),n.length&&(e.callback_(n,e),t=!0)}),t&&r()}function o(e){e.nodes_.forEach(function(t){var n=v.get(t);n&&n.forEach(function(t){t.observer===e&&t.removeTransientObservers()})})}function i(e,t){for(var n=e;n;n=n.parentNode){var r=v.get(n);if(r)for(var o=0;o<r.length;o++){var i=r[o],a=i.options;if(n===e||a.subtree){var s=t(a);s&&i.enqueue(s)}}}}function a(e){this.callback_=e,this.nodes_=[],this.records_=[],this.uid_=++_}function s(e,t){this.type=e,this.target=t,this.addedNodes=[],this.removedNodes=[],this.previousSibling=null,this.nextSibling=null,this.attributeName=null,this.attributeNamespace=null,this.oldValue=null}function d(e){var t=new s(e.type,e.target);return t.addedNodes=e.addedNodes.slice(),t.removedNodes=e.removedNodes.slice(),t.previousSibling=e.previousSibling,t.nextSibling=e.nextSibling,t.attributeName=e.attributeName,t.attributeNamespace=e.attributeNamespace,t.oldValue=e.oldValue,t}function c(e,t){return y=new s(e,t)}function u(e){return L?L:(L=d(y),L.oldValue=e,L)}function l(){y=L=void 0}function h(e){return e===L||e===y}function m(e,t){return e===t?e:L&&h(e)?L:null}function p(e,t,n){this.observer=e,this.target=t,this.options=n,this.transientObservedNodes=[]}if(!e.JsMutationObserver){var f,v=new WeakMap;if(/Trident|Edge/.test(navigator.userAgent))f=setTimeout;else if(window.setImmediate)f=window.setImmediate;else{var w=[],b=String(Math.random());window.addEventListener("message",function(e){if(e.data===b){var t=w;w=[],t.forEach(function(e){e()})}}),f=function(e){w.push(e),window.postMessage(b,"*")}}var g=!1,E=[],_=0;a.prototype={observe:function(e,t){if(e=n(e),!t.childList&&!t.attributes&&!t.characterData||t.attributeOldValue&&!t.attributes||t.attributeFilter&&t.attributeFilter.length&&!t.attributes||t.characterDataOldValue&&!t.characterData)throw new SyntaxError;var r=v.get(e);r||v.set(e,r=[]);for(var o,i=0;i<r.length;i++)if(r[i].observer===this){o=r[i],o.removeListeners(),o.options=t;break}o||(o=new p(this,e,t),r.push(o),this.nodes_.push(e)),o.addListeners()},disconnect:function(){this.nodes_.forEach(function(e){for(var t=v.get(e),n=0;n<t.length;n++){var r=t[n];if(r.observer===this){r.removeListeners(),t.splice(n,1);break}}},this),this.records_=[]},takeRecords:function(){var e=this.records_;return this.records_=[],e}};var y,L;p.prototype={enqueue:function(e){var n=this.observer.records_,r=n.length;if(n.length>0){var o=n[r-1],i=m(o,e);if(i)return void(n[r-1]=i)}else t(this.observer);n[r]=e},addListeners:function(){this.addListeners_(this.target)},addListeners_:function(e){var t=this.options;t.attributes&&e.addEventListener("DOMAttrModified",this,!0),t.characterData&&e.addEventListener("DOMCharacterDataModified",this,!0),t.childList&&e.addEventListener("DOMNodeInserted",this,!0),(t.childList||t.subtree)&&e.addEventListener("DOMNodeRemoved",this,!0)},removeListeners:function(){this.removeListeners_(this.target)},removeListeners_:function(e){var t=this.options;t.attributes&&e.removeEventListener("DOMAttrModified",this,!0),t.characterData&&e.removeEventListener("DOMCharacterDataModified",this,!0),t.childList&&e.removeEventListener("DOMNodeInserted",this,!0),(t.childList||t.subtree)&&e.removeEventListener("DOMNodeRemoved",this,!0)},addTransientObserver:function(e){if(e!==this.target){this.addListeners_(e),this.transientObservedNodes.push(e);var t=v.get(e);t||v.set(e,t=[]),t.push(this)}},removeTransientObservers:function(){var e=this.transientObservedNodes;this.transientObservedNodes=[],e.forEach(function(e){this.removeListeners_(e);for(var t=v.get(e),n=0;n<t.length;n++)if(t[n]===this){t.splice(n,1);break}},this)},handleEvent:function(e){switch(e.stopImmediatePropagation(),e.type){case"DOMAttrModified":var t=e.attrName,n=e.relatedNode.namespaceURI,r=e.target,o=new c("attributes",r);o.attributeName=t,o.attributeNamespace=n;var a=e.attrChange===MutationEvent.ADDITION?null:e.prevValue;i(r,function(e){if(e.attributes&&(!e.attributeFilter||!e.attributeFilter.length||e.attributeFilter.indexOf(t)!==-1||e.attributeFilter.indexOf(n)!==-1))return e.attributeOldValue?u(a):o});break;case"DOMCharacterDataModified":var r=e.target,o=c("characterData",r),a=e.prevValue;i(r,function(e){if(e.characterData)return e.characterDataOldValue?u(a):o});break;case"DOMNodeRemoved":this.addTransientObserver(e.target);case"DOMNodeInserted":var s,d,h=e.target;"DOMNodeInserted"===e.type?(s=[h],d=[]):(s=[],d=[h]);var m=h.previousSibling,p=h.nextSibling,o=c("childList",e.target.parentNode);o.addedNodes=s,o.removedNodes=d,o.previousSibling=m,o.nextSibling=p,i(e.relatedNode,function(e){if(e.childList)return o})}l()}},e.JsMutationObserver=a,e.MutationObserver||(e.MutationObserver=a,a._isPolyfilled=!0)}}(self),function(e){"use strict";if(!window.performance||!window.performance.now){var t=Date.now();window.performance={now:function(){return Date.now()-t}}}window.requestAnimationFrame||(window.requestAnimationFrame=function(){var e=window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame;return e?function(t){return e(function(){t(performance.now())})}:function(e){return window.setTimeout(e,1e3/60)}}()),window.cancelAnimationFrame||(window.cancelAnimationFrame=function(){return window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||function(e){clearTimeout(e)}}());var n=function(){var e=document.createEvent("Event");return e.initEvent("foo",!0,!0),e.preventDefault(),e.defaultPrevented}();if(!n){var r=Event.prototype.preventDefault;Event.prototype.preventDefault=function(){this.cancelable&&(r.call(this),Object.defineProperty(this,"defaultPrevented",{get:function(){return!0},configurable:!0}))}}var o=/Trident/.test(navigator.userAgent);if((!window.CustomEvent||o&&"function"!=typeof window.CustomEvent)&&(window.CustomEvent=function(e,t){t=t||{};var n=document.createEvent("CustomEvent");return n.initCustomEvent(e,Boolean(t.bubbles),Boolean(t.cancelable),t.detail),n},window.CustomEvent.prototype=window.Event.prototype),!window.Event||o&&"function"!=typeof window.Event){var i=window.Event;window.Event=function(e,t){t=t||{};var n=document.createEvent("Event");return n.initEvent(e,Boolean(t.bubbles),Boolean(t.cancelable)),n},window.Event.prototype=i.prototype}}(window.WebComponents),window.HTMLImports=window.HTMLImports||{flags:{}},function(e){function t(e,t){t=t||p,r(function(){i(e,t)},t)}function n(e){return"complete"===e.readyState||e.readyState===w}function r(e,t){if(n(t))e&&e();else{var o=function(){"complete"!==t.readyState&&t.readyState!==w||(t.removeEventListener(b,o),r(e,t))};t.addEventListener(b,o)}}function o(e){e.target.__loaded=!0}function i(e,t){function n(){d==c&&e&&e({allImports:s,loadedImports:u,errorImports:l})}function r(e){o(e),u.push(this),d++,n()}function i(e){l.push(this),d++,n()}var s=t.querySelectorAll("link[rel=import]"),d=0,c=s.length,u=[],l=[];if(c)for(var h,m=0;m<c&&(h=s[m]);m++)a(h)?(u.push(this),d++,n()):(h.addEventListener("load",r),h.addEventListener("error",i));else n()}function a(e){return l?e.__loaded||e["import"]&&"loading"!==e["import"].readyState:e.__importParsed}function s(e){for(var t,n=0,r=e.length;n<r&&(t=e[n]);n++)d(t)&&c(t)}function d(e){return"link"===e.localName&&"import"===e.rel}function c(e){var t=e["import"];t?o({target:e}):(e.addEventListener("load",o),e.addEventListener("error",o))}var u="import",l=Boolean(u in document.createElement("link")),h=Boolean(window.ShadowDOMPolyfill),m=function(e){return h?window.ShadowDOMPolyfill.wrapIfNeeded(e):e},p=m(document),f={get:function(){var e=window.HTMLImports.currentScript||document.currentScript||("complete"!==document.readyState?document.scripts[document.scripts.length-1]:null);return m(e)},configurable:!0};Object.defineProperty(document,"_currentScript",f),Object.defineProperty(p,"_currentScript",f);var v=/Trident/.test(navigator.userAgent),w=v?"complete":"interactive",b="readystatechange";l&&(new MutationObserver(function(e){for(var t,n=0,r=e.length;n<r&&(t=e[n]);n++)t.addedNodes&&s(t.addedNodes)}).observe(document.head,{childList:!0}),function(){if("loading"===document.readyState)for(var e,t=document.querySelectorAll("link[rel=import]"),n=0,r=t.length;n<r&&(e=t[n]);n++)c(e)}()),t(function(e){window.HTMLImports.ready=!0,window.HTMLImports.readyTime=(new Date).getTime();var t=p.createEvent("CustomEvent");t.initCustomEvent("HTMLImportsLoaded",!0,!0,e),p.dispatchEvent(t)}),e.IMPORT_LINK_TYPE=u,e.useNative=l,e.rootDocument=p,e.whenReady=t,e.isIE=v}(window.HTMLImports),function(e){var t=[],n=function(e){t.push(e)},r=function(){t.forEach(function(t){t(e)})};e.addModule=n,e.initializeModules=r}(window.HTMLImports),window.HTMLImports.addModule(function(e){var t=/(url\()([^)]*)(\))/g,n=/(@import[\s]+(?!url\())([^;]*)(;)/g,r={resolveUrlsInStyle:function(e,t){var n=e.ownerDocument,r=n.createElement("a");return e.textContent=this.resolveUrlsInCssText(e.textContent,t,r),e},resolveUrlsInCssText:function(e,r,o){var i=this.replaceUrls(e,o,r,t);return i=this.replaceUrls(i,o,r,n)},replaceUrls:function(e,t,n,r){return e.replace(r,function(e,r,o,i){var a=o.replace(/["']/g,"");return n&&(a=new URL(a,n).href),t.href=a,a=t.href,r+"'"+a+"'"+i})}};e.path=r}),window.HTMLImports.addModule(function(e){var t={async:!0,ok:function(e){return e.status>=200&&e.status<300||304===e.status||0===e.status},load:function(n,r,o){var i=new XMLHttpRequest;return(e.flags.debug||e.flags.bust)&&(n+="?"+Math.random()),i.open("GET",n,t.async),i.addEventListener("readystatechange",function(e){if(4===i.readyState){var n=null;try{var a=i.getResponseHeader("Location");a&&(n="/"===a.substr(0,1)?location.origin+a:a)}catch(e){console.error(e.message)}r.call(o,!t.ok(i)&&i,i.response||i.responseText,n)}}),i.send(),i},loadDocument:function(e,t,n){this.load(e,t,n).responseType="document"}};e.xhr=t}),window.HTMLImports.addModule(function(e){var t=e.xhr,n=e.flags,r=function(e,t){this.cache={},this.onload=e,this.oncomplete=t,this.inflight=0,this.pending={}};r.prototype={addNodes:function(e){this.inflight+=e.length;for(var t,n=0,r=e.length;n<r&&(t=e[n]);n++)this.require(t);this.checkDone()},addNode:function(e){this.inflight++,this.require(e),this.checkDone()},require:function(e){var t=e.src||e.href;e.__nodeUrl=t,this.dedupe(t,e)||this.fetch(t,e)},dedupe:function(e,t){if(this.pending[e])return this.pending[e].push(t),!0;return this.cache[e]?(this.onload(e,t,this.cache[e]),this.tail(),!0):(this.pending[e]=[t],!1)},fetch:function(e,r){if(n.load&&console.log("fetch",e,r),e)if(e.match(/^data:/)){var o=e.split(","),i=o[0],a=o[1];a=i.indexOf(";base64")>-1?atob(a):decodeURIComponent(a),setTimeout(function(){this.receive(e,r,null,a)}.bind(this),0)}else{var s=function(t,n,o){this.receive(e,r,t,n,o)}.bind(this);t.load(e,s)}else setTimeout(function(){this.receive(e,r,{error:"href must be specified"},null)}.bind(this),0)},receive:function(e,t,n,r,o){this.cache[e]=r;for(var i,a=this.pending[e],s=0,d=a.length;s<d&&(i=a[s]);s++)this.onload(e,i,r,n,o),this.tail();this.pending[e]=null},tail:function(){--this.inflight,this.checkDone()},checkDone:function(){this.inflight||this.oncomplete()}},e.Loader=r}),window.HTMLImports.addModule(function(e){var t=function(e){this.addCallback=e,this.mo=new MutationObserver(this.handler.bind(this))};t.prototype={handler:function(e){for(var t,n=0,r=e.length;n<r&&(t=e[n]);n++)"childList"===t.type&&t.addedNodes.length&&this.addedNodes(t.addedNodes)},addedNodes:function(e){this.addCallback&&this.addCallback(e);for(var t,n=0,r=e.length;n<r&&(t=e[n]);n++)t.children&&t.children.length&&this.addedNodes(t.children)},observe:function(e){this.mo.observe(e.head,{childList:!0,subtree:!0}),this.mo.observe(e.body,{childList:!0,subtree:!0})}},e.Observer=t}),window.HTMLImports.addModule(function(e){function t(e){return"link"===e.localName&&e.rel===u}function n(e){var t=r(e);return"data:text/javascript;charset=utf-8,"+encodeURIComponent(t)}function r(e){return e.textContent+o(e)}function o(e){var t=e.ownerDocument;t.__importedScripts=t.__importedScripts||0;var n=e.ownerDocument.baseURI,r=t.__importedScripts?"-"+t.__importedScripts:"";return t.__importedScripts++,"\n//# sourceURL="+n+r+".js\n"}function i(e){var t=e.ownerDocument.createElement("style");return t.textContent=e.textContent,a.resolveUrlsInStyle(t),t}var a=e.path,s=e.rootDocument,d=e.flags,c=e.isIE,u=e.IMPORT_LINK_TYPE,l="link[rel="+u+"]",h={documentSelectors:l,importsSelectors:[l,"link[rel=stylesheet]:not([type])","style:not([type])","script:not([type])",'script[type="application/javascript"]','script[type="text/javascript"]'].join(","),map:{link:"parseLink",script:"parseScript",style:"parseStyle"},dynamicElements:[],parseNext:function(){var e=this.nextToParse();e&&this.parse(e)},parse:function(e){if(this.isParsed(e))return void(d.parse&&console.log("[%s] is already parsed",e.localName));var t=this[this.map[e.localName]];t&&(this.markParsing(e),t.call(this,e))},parseDynamic:function(e,t){this.dynamicElements.push(e),t||this.parseNext()},markParsing:function(e){d.parse&&console.log("parsing",e),this.parsingElement=e},markParsingComplete:function(e){e.__importParsed=!0,this.markDynamicParsingComplete(e),e.__importElement&&(e.__importElement.__importParsed=!0,this.markDynamicParsingComplete(e.__importElement)),this.parsingElement=null,d.parse&&console.log("completed",e)},markDynamicParsingComplete:function(e){var t=this.dynamicElements.indexOf(e);t>=0&&this.dynamicElements.splice(t,1)},parseImport:function(e){if(e["import"]=e.__doc,window.HTMLImports.__importsParsingHook&&window.HTMLImports.__importsParsingHook(e),e["import"]&&(e["import"].__importParsed=!0),this.markParsingComplete(e),e.__resource&&!e.__error?e.dispatchEvent(new CustomEvent("load",{bubbles:!1})):e.dispatchEvent(new CustomEvent("error",{bubbles:!1})),e.__pending)for(var t;e.__pending.length;)t=e.__pending.shift(),t&&t({target:e});this.parseNext()},parseLink:function(e){t(e)?this.parseImport(e):(e.href=e.href,this.parseGeneric(e))},parseStyle:function(e){var t=e;e=i(e),t.__appliedElement=e,e.__importElement=t,this.parseGeneric(e)},parseGeneric:function(e){this.trackElement(e),this.addElementToDocument(e)},rootImportForElement:function(e){for(var t=e;t.ownerDocument.head.__importLink;)t=t.ownerDocument.head.__importLink;return t},addElementToDocument:function(e){var t=this.rootImportForElement(e.__importElement||e);t.parentNode.insertBefore(e,t)},trackElement:function(e,t){var n=this,r=function(o){e.removeEventListener("load",r),e.removeEventListener("error",r),t&&t(o),n.markParsingComplete(e),n.parseNext()};if(e.addEventListener("load",r),e.addEventListener("error",r),c&&"style"===e.localName){var o=!1;if(e.textContent.indexOf("@import")==-1)o=!0;else if(e.sheet){o=!0;for(var i,a=e.sheet.cssRules,s=a?a.length:0,d=0;d<s&&(i=a[d]);d++)i.type===CSSRule.IMPORT_RULE&&(o=o&&Boolean(i.styleSheet))}o&&setTimeout(function(){e.dispatchEvent(new CustomEvent("load",{bubbles:!1}))})}},parseScript:function(t){var r=document.createElement("script");r.__importElement=t,r.src=t.src?t.src:n(t),e.currentScript=t,this.trackElement(r,function(t){r.parentNode&&r.parentNode.removeChild(r),e.currentScript=null}),this.addElementToDocument(r)},nextToParse:function(){return this._mayParse=[],!this.parsingElement&&(this.nextToParseInDoc(s)||this.nextToParseDynamic())},nextToParseInDoc:function(e,n){if(e&&this._mayParse.indexOf(e)<0){this._mayParse.push(e);for(var r,o=e.querySelectorAll(this.parseSelectorsForNode(e)),i=0,a=o.length;i<a&&(r=o[i]);i++)if(!this.isParsed(r))return this.hasResource(r)?t(r)?this.nextToParseInDoc(r.__doc,r):r:void 0}return n},nextToParseDynamic:function(){return this.dynamicElements[0]},parseSelectorsForNode:function(e){var t=e.ownerDocument||e;return t===s?this.documentSelectors:this.importsSelectors},isParsed:function(e){return e.__importParsed},needsDynamicParsing:function(e){return this.dynamicElements.indexOf(e)>=0},hasResource:function(e){return!t(e)||void 0!==e.__doc}};e.parser=h,e.IMPORT_SELECTOR=l}),window.HTMLImports.addModule(function(e){function t(e){return n(e,a)}function n(e,t){return"link"===e.localName&&e.getAttribute("rel")===t}function r(e){return!!Object.getOwnPropertyDescriptor(e,"baseURI")}function o(e,t){var n=document.implementation.createHTMLDocument(a);n._URL=t;var o=n.createElement("base");o.setAttribute("href",t),n.baseURI||r(n)||Object.defineProperty(n,"baseURI",{value:t});var i=n.createElement("meta");return i.setAttribute("charset","utf-8"),n.head.appendChild(i),n.head.appendChild(o),n.body.innerHTML=e,window.HTMLTemplateElement&&HTMLTemplateElement.bootstrap&&HTMLTemplateElement.bootstrap(n),n}var i=e.flags,a=e.IMPORT_LINK_TYPE,s=e.IMPORT_SELECTOR,d=e.rootDocument,c=e.Loader,u=e.Observer,l=e.parser,h={documents:{},documentPreloadSelectors:s,importsPreloadSelectors:[s].join(","),loadNode:function(e){m.addNode(e)},loadSubtree:function(e){var t=this.marshalNodes(e);m.addNodes(t)},marshalNodes:function(e){return e.querySelectorAll(this.loadSelectorsForNode(e))},loadSelectorsForNode:function(e){var t=e.ownerDocument||e;return t===d?this.documentPreloadSelectors:this.importsPreloadSelectors},loaded:function(e,n,r,a,s){if(i.load&&console.log("loaded",e,n),n.__resource=r,n.__error=a,t(n)){var d=this.documents[e];void 0===d&&(d=a?null:o(r,s||e),d&&(d.head.__importLink=n,this.bootDocument(d)),this.documents[e]=d),n.__doc=d}l.parseNext()},bootDocument:function(e){this.loadSubtree(e),this.observer.observe(e),l.parseNext()},loadedAll:function(){l.parseNext()}},m=new c(h.loaded.bind(h),h.loadedAll.bind(h));if(h.observer=new u,!document.baseURI){var p={get:function(){var e=document.querySelector("base");return e?e.href:window.location.href},configurable:!0};Object.defineProperty(document,"baseURI",p),Object.defineProperty(d,"baseURI",p)}e.importer=h,e.importLoader=m}),window.HTMLImports.addModule(function(e){var t=e.parser,n=e.importer,r={added:function(e){for(var r,o,i,a,s=0,d=e.length;s<d&&(a=e[s]);s++)r||(r=a.ownerDocument,o=t.isParsed(r)),i=this.shouldLoadNode(a),i&&n.loadNode(a),this.shouldParseNode(a)&&o&&t.parseDynamic(a,i)},shouldLoadNode:function(e){return 1===e.nodeType&&o.call(e,n.loadSelectorsForNode(e))},shouldParseNode:function(e){return 1===e.nodeType&&o.call(e,t.parseSelectorsForNode(e))}};n.observer.addCallback=r.added.bind(r);var o=HTMLElement.prototype.matches||HTMLElement.prototype.matchesSelector||HTMLElement.prototype.webkitMatchesSelector||HTMLElement.prototype.mozMatchesSelector||HTMLElement.prototype.msMatchesSelector}),function(e){function t(){window.HTMLImports.importer.bootDocument(r)}var n=e.initializeModules;e.isIE;if(!e.useNative){n();var r=e.rootDocument;"complete"===document.readyState||"interactive"===document.readyState&&!window.attachEvent?t():document.addEventListener("DOMContentLoaded",t)}}(window.HTMLImports); \ No newline at end of file
diff --git a/third_party/polymer/v1_0/components_summary.txt b/third_party/polymer/v1_0/components_summary.txt index 3320e605..b3b2b2c 100644 --- a/third_party/polymer/v1_0/components_summary.txt +++ b/third_party/polymer/v1_0/components_summary.txt
@@ -10,12 +10,6 @@ Revision: bcdbb81201faad37270b03f59a29f2f27cb70312 Tree link: https://github.com/webcomponents/html-imports/tree/v1.2.0 -Name: html-imports -Repository: https://github.com/webcomponents/html-imports.git -Tree: v0 -Revision: 5832a3028a3bb6f8f29f0c53b0c8d631efdfa0b4 -Tree link: https://github.com/webcomponents/html-imports/tree/v0 - Name: iron-a11y-announcer Repository: https://github.com/PolymerElements/iron-a11y-announcer.git Tree: v2.1.0
diff --git a/third_party/polymer/v1_0/find_unused_elements.py b/third_party/polymer/v1_0/find_unused_elements.py index 32aa3b4..3a8aae0 100644 --- a/third_party/polymer/v1_0/find_unused_elements.py +++ b/third_party/polymer/v1_0/find_unused_elements.py
@@ -31,7 +31,6 @@ 'shadycss', # Not used yet. Will be used when pages are moved off of HTML imports. 'html-imports', - 'html-imports-v0', ) def __init__(self):
diff --git a/third_party/polymer/v1_0/rsync_exclude.txt b/third_party/polymer/v1_0/rsync_exclude.txt index b5da044..cca26307d 100644 --- a/third_party/polymer/v1_0/rsync_exclude.txt +++ b/third_party/polymer/v1_0/rsync_exclude.txt
@@ -32,10 +32,6 @@ html-imports/src/* html-imports/gulpfile.js -# html-imports-v0 -html-imports-v0/src/* -html-imports-v0/gulpfile.js - # iron-autogrow-textarea iron-autogrow-textarea/*
diff --git a/tools/binary_size/BUILD.gn b/tools/binary_size/BUILD.gn index 98493f10..a9629c2 100644 --- a/tools/binary_size/BUILD.gn +++ b/tools/binary_size/BUILD.gn
@@ -23,8 +23,10 @@ ] } -group("caspian") { - deps = [ - "//tools/binary_size/libsupersize/caspian:cli($host_toolchain)", - ] +if (is_linux) { + group("caspian") { + deps = [ + "//tools/binary_size/libsupersize/caspian:cli($host_toolchain)", + ] + } }
diff --git a/tools/binary_size/libsupersize/caspian/BUILD.gn b/tools/binary_size/libsupersize/caspian/BUILD.gn index b2b3f1c5..a0572fd0 100644 --- a/tools/binary_size/libsupersize/caspian/BUILD.gn +++ b/tools/binary_size/libsupersize/caspian/BUILD.gn
@@ -2,6 +2,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +assert(is_linux) + source_set("caspian-lib") { sources = [ "file_format.cc",
diff --git a/tools/binary_size/libsupersize/caspian/file_format.cc b/tools/binary_size/libsupersize/caspian/file_format.cc index 15e04e8..d11a192 100644 --- a/tools/binary_size/libsupersize/caspian/file_format.cc +++ b/tools/binary_size/libsupersize/caspian/file_format.cc
@@ -9,9 +9,11 @@ #include "tools/binary_size/libsupersize/caspian/file_format.h" #include <assert.h> +#include <stdint.h> #include <cstring> #include <iostream> +#include <memory> #include <numeric> #include <sstream> #include <string> @@ -19,58 +21,79 @@ #include "third_party/jsoncpp/source/include/json/json.h" #include "third_party/zlib/google/compression_utils_portable.h" - #include "tools/binary_size/libsupersize/caspian/model.h" namespace { -const std::string SERIALIZATION_VERSION = "Size File Format v1"; +const char SERIALIZATION_VERSION[] = "Size File Format v1"; -int ReadLoneInt(std::stringstream* stream) { - int val; - *stream >> val; - stream->ignore(); // Drop newline. - return val; +int ReadLoneInt(char** rest) { + char* token = strsep(rest, "\n"); + return std::strtol(token, nullptr, 10); } -std::stringstream Decompress(const char* gzipped, unsigned long len) { - uint32_t uncompressed_size; - memcpy(&uncompressed_size, &gzipped[len - sizeof(uncompressed_size)], - sizeof(uncompressed_size)); +void Decompress(const char* gzipped, + unsigned long len, + std::vector<char>* uncompressed) { + // gzip format stores the uncompressed size in the last four bytes. + if (len < sizeof(uint32_t)) { + std::cerr << "Input too short to be gzipped" << std::endl; + exit(1); + } + uint32_t uncompressed_size = *reinterpret_cast<const uint32_t*>( + &gzipped[len - sizeof(uncompressed_size)]); + + // Should be little-endian. + int num = 1; + if (*reinterpret_cast<char*>(&num) != 1) { + uncompressed_size = __builtin_bswap32(uncompressed_size); + } + + // Using resize() instead of reserve() here is significantly slower when + // compiled to WebAssembly. + uncompressed->reserve(uncompressed_size + 1); + // Add terminating null for safety. + (*uncompressed)[uncompressed_size] = '\0'; + unsigned long long_uncompressed_size(uncompressed_size); - - std::string uncompressed; - uncompressed.resize(uncompressed_size); - auto ret = zlib_internal::GzipUncompressHelper( - reinterpret_cast<Bytef*>(&uncompressed[0]), &long_uncompressed_size, + reinterpret_cast<Bytef*>(&(*uncompressed)[0]), &long_uncompressed_size, reinterpret_cast<const Bytef*>(gzipped), len); if (Z_OK == ret) { - return std::stringstream(uncompressed); + return; } std::cerr << "Failed to decompress. Zlib code: " << ret << std::endl; exit(1); } -std::vector<std::string> ReadValuesFromLine(std::istream* stream, +std::vector<const char*> ReadValuesFromLine(char** rest, const char* delimiter) { - std::string line; - std::getline(*stream, line); - std::vector<std::string> ret; - char* cstr = std::strtok(&line[0], delimiter); - while (cstr != nullptr) { - ret.push_back(std::string(cstr)); - cstr = std::strtok(nullptr, delimiter); + char* rest_of_line = strsep(rest, "\n"); + + std::vector<const char*> ret; + while (true) { + char* token = strsep(&rest_of_line, delimiter); + if (!token) + break; + ret.push_back(token); } return ret; } template <typename T> -std::vector<T> ReadIntList(std::istream* stream, int n, bool stored_as_delta) { +std::vector<T> ReadIntList(char** rest, + const char* delim, + int n, + bool stored_as_delta) { + char* rest_of_line = strsep(rest, "\n"); + std::vector<T> result; result.resize(n); - for (int i = 0; i < n; i++) - *stream >> result[i]; + for (int i = 0; i < n; i++) { + char* token = strsep(&rest_of_line, delim); + result[i] = std::strtol(token, nullptr, 10); + } + if (stored_as_delta) std::partial_sum(result.begin(), result.end(), result.begin()); return result; @@ -78,17 +101,56 @@ template <typename T> std::vector<std::vector<T>> ReadIntListForEachSection( - std::istream* stream, + char** rest, const std::vector<int>& section_counts, bool stored_as_delta) { std::vector<std::vector<T>> ret; ret.reserve(section_counts.size()); for (int nsymbols : section_counts) { - ret.emplace_back(ReadIntList<T>(stream, nsymbols, stored_as_delta)); + ret.push_back(ReadIntList<T>(rest, " ", nsymbols, stored_as_delta)); } return ret; } +void ReadJsonBlob(char** rest, Json::Value* metadata) { + // Metadata begins with its length in bytes, followed by a json blob. + int metadata_len = ReadLoneInt(rest); + if (metadata_len < 0) { + std::cerr << "Unexpected negative metadata length: " << metadata_len + << std::endl; + exit(1); + } + char* json_start = *rest; + *rest += metadata_len + 1; + + std::unique_ptr<Json::CharReader> reader; + reader.reset(Json::CharReaderBuilder().newCharReader()); + std::string json_errors; + if (!reader->parse(json_start, json_start + metadata_len, metadata, + &json_errors)) { + std::cerr << "Failed to parse JSON metadata:" << *rest << std::endl; + std::cerr << json_errors << std::endl; + exit(1); + } +} + +void CheckNoNonEmptyLinesRemain(char* rest) { + if (rest) { + int lines_remaining = 50; + bool newlines_only = true; + char* line = nullptr; + while (lines_remaining > 0 && (line = strsep(&rest, "\n"))) { + if (strcmp("", line)) { + std::cerr << "Unparsed line: " << line << std::endl; + newlines_only = false; + lines_remaining--; + } + } + if (!newlines_only) { + exit(1); + } + } +} } // namespace namespace caspian { @@ -96,90 +158,78 @@ void ParseSizeInfo(const char* gzipped, unsigned long len, ::caspian::SizeInfo* info) { - std::stringstream ss = Decompress(gzipped, len); + // To avoid memory allocations, all the char* in our final Symbol set will + // be pointers into the region originally pointed to by |decompressed_start|. + // Calls to strsep() replace delimiter characters with null terminators. + Decompress(gzipped, len, &info->raw_decompressed); + char* rest = &info->raw_decompressed[0]; // Ignore generated header - std::string line; - std::getline(ss, line); + char* line = strsep(&rest, "\n"); // Serialization version - std::getline(ss, line); - if (line != SERIALIZATION_VERSION) { + line = strsep(&rest, "\n"); + if (std::strcmp(line, SERIALIZATION_VERSION)) { std::cerr << "Serialization version: '" << line << "' not recognized." << std::endl; exit(1); } - // Metadata - int metadata_len = ReadLoneInt(&ss) + 1; - if (metadata_len < 0) { - std::cerr << "Unexpected negative metadata length: " << metadata_len - << std::endl; - exit(1); - } + ReadJsonBlob(&rest, &info->metadata); - std::vector<char> metadata_str; - metadata_str.resize(metadata_len); - ss.get(metadata_str.data(), metadata_len, EOF); - Json::Value root; - std::stringstream(metadata_str.data()) >> root; - - if (!root) { - std::cerr << "Failed to parse JSON metadata:" << metadata_str.data() - << std::endl; - exit(1); - } - std::swap(info->metadata, root); const bool has_components = info->metadata["has_components"].asBool(); // List of paths: (object_path, [source_path]) - int n_paths = ReadLoneInt(&ss); + int n_paths = ReadLoneInt(&rest); if (n_paths < 0) { std::cerr << "Unexpected negative path list length: " << n_paths << std::endl; exit(1); } + std::cout << "Reading " << n_paths << " paths" << std::endl; info->object_paths.reserve(n_paths); info->source_paths.reserve(n_paths); for (int i = 0; i < n_paths; i++) { - const std::vector<std::string> paths = ReadValuesFromLine(&ss, "\t"); - if (paths.size() == 2) { - info->object_paths.push_back(paths[0]); - info->source_paths.push_back(paths[1]); - } else if (paths.size() == 1) { - info->object_paths.push_back(paths[0]); + char* line = strsep(&rest, "\n"); + char* first = strsep(&line, "\t"); + char* second = strsep(&line, "\t"); + if (second) { + info->object_paths.push_back(first); + info->source_paths.push_back(second); + } else if (first) { + info->object_paths.push_back(first); info->source_paths.push_back(""); - } else if (paths.empty()) { - info->object_paths.push_back(""); - info->source_paths.push_back(""); - } else { + } else if (line) { std::cerr << "Too many tokens on path row: " << i << std::endl; exit(1); + } else { + info->object_paths.push_back(""); + info->source_paths.push_back(""); } } // List of component names - int n_components = ReadLoneInt(&ss); - if (n_components < 0) { - std::cerr << "Unexpected negative components list length: " << n_components - << std::endl; + int n_components = ReadLoneInt(&rest); + if (n_components <= 0) { + std::cerr << "Unexpected non-positive components list length: " + << n_components << std::endl; exit(1); } std::cout << "Reading " << n_components << " components" << std::endl; info->components.reserve(n_components); for (int i = 0; i < n_components; i++) { - std::getline(ss, line); - info->components.push_back(line); + info->components.push_back(strsep(&rest, "\n")); } // Section names - info->section_names = ReadValuesFromLine(&ss, "\t"); + info->section_names = ReadValuesFromLine(&rest, "\t"); int n_sections = info->section_names.size(); // Symbol counts for each section - std::vector<int> section_counts = ReadIntList<int>(&ss, n_sections, false); + std::vector<int> section_counts = + ReadIntList<int>(&rest, "\t", n_sections, false); std::cout << "Section counts:" << std::endl; int total_symbols = std::accumulate(section_counts.begin(), section_counts.end(), 0); @@ -190,63 +240,68 @@ } std::vector<std::vector<int64_t>> addresses = - ReadIntListForEachSection<int64_t>(&ss, section_counts, true); - std::vector<std::vector<int>> sizes = - ReadIntListForEachSection<int>(&ss, section_counts, false); - std::vector<std::vector<int>> path_indices = - ReadIntListForEachSection<int>(&ss, section_counts, true); - std::vector<std::vector<int>> component_indices; + ReadIntListForEachSection<int64_t>(&rest, section_counts, true); + std::vector<std::vector<int32_t>> sizes = + ReadIntListForEachSection<int32_t>(&rest, section_counts, false); + std::vector<std::vector<int32_t>> path_indices = + ReadIntListForEachSection<int32_t>(&rest, section_counts, true); + std::vector<std::vector<int32_t>> component_indices; if (has_components) { component_indices = - ReadIntListForEachSection<int>(&ss, section_counts, true); + ReadIntListForEachSection<int32_t>(&rest, section_counts, true); } else { component_indices.resize(addresses.size()); } - ss.ignore(); info->raw_symbols.reserve(total_symbols); // Construct raw symbols for (int section_idx = 0; section_idx < n_sections; section_idx++) { - const std::string* cur_section_name = &info->section_names[section_idx]; + const char* cur_section_name = info->section_names[section_idx]; const int cur_section_count = section_counts[section_idx]; const std::vector<int64_t>& cur_addresses = addresses[section_idx]; - const std::vector<int>& cur_sizes = sizes[section_idx]; - const std::vector<int>& cur_path_indices = path_indices[section_idx]; - const std::vector<int>& cur_component_indices = + const std::vector<int32_t>& cur_sizes = sizes[section_idx]; + const std::vector<int32_t>& cur_path_indices = path_indices[section_idx]; + const std::vector<int32_t>& cur_component_indices = component_indices[section_idx]; int32_t alias_counter = 0; for (int i = 0; i < cur_section_count; i++) { - const std::vector<std::string> parts = ReadValuesFromLine(&ss, "\t"); - if (parts.empty()) { - std::cout << "Row " << i << " of symbols is blank" << std::endl; - continue; - } - uint32_t flags = 0; - uint32_t num_aliases = 0; - if (parts.size() == 3) { - num_aliases = std::strtol(parts[1].c_str(), nullptr, 16); - flags = std::strtol(parts[1].c_str(), nullptr, 16); - } else if (parts.size() == 2) { - if (parts[1][0] == '0') { - // full_name aliases_part - num_aliases = std::strtol(parts[1].c_str(), nullptr, 16); - } else { - // full_name flags_part - flags = std::strtol(parts[1].c_str(), nullptr, 16); - } - } - info->raw_symbols.emplace_back(); caspian::Symbol& new_sym = info->raw_symbols.back(); + + int32_t flags = 0; + int32_t num_aliases = 0; + char* line = strsep(&rest, "\n"); + if (*line) { + new_sym.full_name = strsep(&line, "\t"); + char* first = nullptr; + char* second = nullptr; + if (line) { + first = strsep(&line, "\t"); + } + if (line) { + second = strsep(&line, "\t"); + } + if (second) { + num_aliases = std::strtol(first, nullptr, 16); + flags = std::strtol(second, nullptr, 16); + } else if (first) { + if (first[0] == '0') { + // full_name aliases_part + num_aliases = std::strtol(first, nullptr, 16); + } else { + // full_name flags_part + flags = std::strtol(first, nullptr, 16); + } + } + } new_sym.section_name = cur_section_name; - new_sym.full_name = parts[0]; new_sym.address = cur_addresses[i]; new_sym.size = cur_sizes[i]; - new_sym.object_path = &info->object_paths[cur_path_indices[i]]; - new_sym.source_path = &info->source_paths[cur_path_indices[i]]; + new_sym.object_path = info->object_paths[cur_path_indices[i]]; + new_sym.source_path = info->source_paths[cur_path_indices[i]]; if (has_components) { - new_sym.component = &info->components[cur_component_indices[i]]; + new_sym.component = info->components[cur_component_indices[i]]; } new_sym.flags = flags; @@ -265,14 +320,8 @@ } } - if (std::getline(ss, line)) { - int lines_remaining = 50; - do { - std::cerr << "Unparsed line: " << line << std::endl; - lines_remaining++; - } while (lines_remaining > 0 && std::getline(ss, line)); - exit(1); - } + // If there are unparsed non-empty lines, something's gone wrong. + CheckNoNonEmptyLinesRemain(rest); std::cout << "Parsed " << info->raw_symbols.size() << " symbols" << std::endl; }
diff --git a/tools/binary_size/libsupersize/caspian/model.h b/tools/binary_size/libsupersize/caspian/model.h index 1157d649..819e825f 100644 --- a/tools/binary_size/libsupersize/caspian/model.h +++ b/tools/binary_size/libsupersize/caspian/model.h
@@ -8,7 +8,6 @@ #include <stdlib.h> #include <deque> -#include <string> #include <vector> #include "third_party/jsoncpp/source/include/json/json.h" @@ -25,13 +24,11 @@ int32_t size = 0; int32_t flags = 0; int32_t padding = 0; - std::string full_name; - std::string template_name; - std::string name; - const std::string* object_path = nullptr; - const std::string* section_name = nullptr; - const std::string* source_path = nullptr; - const std::string* component = nullptr; + const char* full_name = nullptr; + const char* section_name = nullptr; + const char* object_path = nullptr; + const char* source_path = nullptr; + const char* component = nullptr; std::vector<Symbol*>* aliases = nullptr; }; @@ -45,11 +42,11 @@ Json::Value metadata; // Entries in |raw_symbols| hold pointers to this data. - // Appending to one will change their capacity and invalidate pointers. - std::vector<std::string> object_paths; - std::vector<std::string> source_paths; - std::vector<std::string> components; - std::vector<std::string> section_names; + std::vector<const char*> object_paths; + std::vector<const char*> source_paths; + std::vector<const char*> components; + std::vector<const char*> section_names; + std::vector<char> raw_decompressed; // A container for each symbol group. std::deque<std::vector<Symbol*>> alias_groups;
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index f32eca7..6cee84ac 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -20713,6 +20713,14 @@ </description> </action> +<action name="StartSurface.TasksOnly"> + <owner>gogerald@chromium.org</owner> + <description> + Metric record when the tasks only start surface is shown (the user taps the + tab switcher button or on chrome start). + </description> +</action> + <action name="StartSurface.TwoPanes"> <owner>gogerald@chromium.org</owner> <description>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index b03839f1..d4a4f16a 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -41436,6 +41436,9 @@ <histogram name="Event.Pen.InputEventTimeStamp.DeltaBetweenTimeNowAndPerformanceCount.Negative" units="microseconds" expires_after="2020-03-29"> + <obsolete> + Deprecated 10/2019 due to the completion of the experiment. + </obsolete> <owner>nzolghadr@chromium.org</owner> <owner>sarsha@microsoft.com</owner> <summary> @@ -41450,6 +41453,9 @@ <histogram name="Event.Pen.InputEventTimeStamp.DeltaBetweenTimeNowAndPerformanceCount.Positive" units="microseconds" expires_after="M79"> + <obsolete> + Deprecated 10/2019 due to the completion of the experiment. + </obsolete> <owner>nzolghadr@chromium.org</owner> <owner>sarsha@microsoft.com</owner> <summary> @@ -41577,6 +41583,9 @@ <histogram name="Event.Touch.InputEventTimeStamp.DeltaBetweenTimeNowAndPerformanceCount.Negative" units="microseconds" expires_after="2020-03-29"> + <obsolete> + Deprecated 10/2019 due to the completion of the experiment. + </obsolete> <owner>nzolghadr@chromium.org</owner> <owner>sarsha@microsoft.com</owner> <summary> @@ -41591,6 +41600,9 @@ <histogram name="Event.Touch.InputEventTimeStamp.DeltaBetweenTimeNowAndPerformanceCount.Positive" units="microseconds" expires_after="2020-03-29"> + <obsolete> + Deprecated 10/2019 due to the completion of the experiment. + </obsolete> <owner>nzolghadr@chromium.org</owner> <owner>sarsha@microsoft.com</owner> <summary> @@ -42765,7 +42777,7 @@ </histogram> <histogram name="ExtensionContentVerifyJob.TimeSpentUS" units="microseconds" - expires_after="2019-11-30"> + expires_after="2020-11-30"> <owner>lazyboy@chromium.org</owner> <summary> The time taken in computation (hashing actual bytes read and comparing @@ -43503,7 +43515,7 @@ </histogram> <histogram name="Extensions.ContentVerification.ComputedHashesInitTime" - units="ms" expires_after="2019-11-30"> + units="ms" expires_after="2020-11-30"> <owner>lazyboy@chromium.org</owner> <owner>rdevlin.cronin@chromium.org</owner> <owner>extensions-core@chromium.org</owner> @@ -43514,7 +43526,7 @@ </histogram> <histogram name="Extensions.ContentVerification.ComputedHashesReadResult" - enum="BooleanSuccess" expires_after="2019-11-30"> + enum="BooleanSuccess" expires_after="2020-11-30"> <owner>lazyboy@chromium.org</owner> <owner>rdevlin.cronin@chromium.org</owner> <owner>extensions-core@chromium.org</owner> @@ -43525,7 +43537,7 @@ </histogram> <histogram name="Extensions.ContentVerification.FetchResult" - enum="BooleanSuccess" expires_after="2019-11-30"> + enum="BooleanSuccess" expires_after="2020-11-30"> <owner>lazyboy@chromium.org</owner> <owner>rdevlin.cronin@chromium.org</owner> <owner>extensions-core@chromium.org</owner> @@ -43536,7 +43548,7 @@ </histogram> <histogram name="Extensions.ContentVerification.ReadContentHashTime" units="ms" - expires_after="2019-11-30"> + expires_after="2020-11-30"> <owner>lazyboy@chromium.org</owner> <owner>rdevlin.cronin@chromium.org</owner> <summary> @@ -43547,7 +43559,7 @@ </histogram> <histogram name="Extensions.ContentVerification.VerifiedContentsInitResult" - enum="BooleanSuccess" expires_after="2019-11-30"> + enum="BooleanSuccess" expires_after="2020-11-30"> <owner>lazyboy@chromium.org</owner> <owner>rdevlin.cronin@chromium.org</owner> <owner>extensions-core@chromium.org</owner> @@ -43559,7 +43571,7 @@ </histogram> <histogram name="Extensions.ContentVerification.VerifiedContentsInitTime" - units="ms" expires_after="2019-11-30"> + units="ms" expires_after="2020-11-30"> <owner>lazyboy@chromium.org</owner> <owner>rdevlin.cronin@chromium.org</owner> <owner>extensions-core@chromium.org</owner> @@ -47690,7 +47702,7 @@ </histogram> <histogram name="ExtensionUrlRequest.Latency" units="ms" - expires_after="2019-11-30"> + expires_after="2020-11-30"> <owner>lazyboy@chromium.org</owner> <summary>The time taken to complete an extension url request.</summary> </histogram> @@ -47725,7 +47737,7 @@ </histogram> <histogram name="ExtensionUrlRequest.SeekPosition" units="units" - expires_after="2019-11-30"> + expires_after="2020-11-30"> <owner>lazyboy@chromium.org</owner> <summary> When fetching a chrome-extension:// URL, this indicates the first byte @@ -47737,7 +47749,7 @@ </histogram> <histogram name="ExtensionUrlRequest.TotalKbRead" units="KB" - expires_after="2019-11-30"> + expires_after="2020-11-30"> <owner>lazyboy@chromium.org</owner> <summary> The total number of bytes read for a chrome-extension:// URL, logged when @@ -70493,7 +70505,7 @@ </histogram> <histogram name="MobileDownload.FirstBackground.InterruptionCount" - units="interruptions" expires_after="2019-12-05"> + units="interruptions" expires_after="2020-04-05"> <owner>hnakashima@chromium.org</owner> <owner>hanxi@chromium.org</owner> <owner>qinmin@chromium.org</owner> @@ -70504,7 +70516,7 @@ </histogram> <histogram name="MobileDownload.FirstBackground.Reason" enum="InterruptReason" - expires_after="2019-12-05"> + expires_after="2020-04-05"> <owner>hnakashima@chromium.org</owner> <owner>hanxi@chromium.org</owner> <owner>qinmin@chromium.org</owner> @@ -106539,7 +106551,7 @@ </histogram> <histogram name="Platform.Cast.MeminfoMemAvailable2" units="MiB" - expires_after="2019-11-30"> + expires_after="2021-11-30"> <owner>halliwell@chromium.org</owner> <summary> /proc/meminfo's 'MemAvailable' in MiB. Collected every 5s on Cast devices @@ -106560,7 +106572,7 @@ </histogram> <histogram name="Platform.Cast.MeminfoMemFreeDerived2" units="MiB" - expires_after="2019-11-30"> + expires_after="2021-11-30"> <owner>halliwell@chromium.org</owner> <summary> Collect free + buffers + cache memory in MiB every 5s on Cast devices, @@ -129506,6 +129518,17 @@ </summary> </histogram> +<histogram name="Security.LegacyTLS.FormSubmission" enum="Boolean" + expires_after="M85"> + <owner>cthomp@chromium.org</owner> + <summary> + Records whether the page would have a legacy TLS warning (if the user were + in the appropriate field trial) when submitting a form. This is recorded + whenever a form submission navigation begins. The recorded status is of the + page the form was submitted from, not the one that the form targets. + </summary> +</histogram> + <histogram name="Security.LegacyTLS.OnCommit" enum="Boolean" expires_after="M85"> <owner>cthomp@chromium.org</owner> @@ -129516,6 +129539,15 @@ </summary> </histogram> +<histogram name="Security.LegacyTLS.PageInfo.Action" + enum="WebsiteSettingsAction" expires_after="M85"> + <owner>cthomp@chromium.org</owner> + <summary> + Tracks Page Info bubble actions along with whether the page would have a + legacy TLS warning (if the user were in the appropriate field trial). + </summary> +</histogram> + <histogram base="true" name="Security.PageEndReason" enum="PageEndReason" expires_after="M81"> <owner>cthomp@chromium.org</owner> @@ -171404,7 +171436,11 @@ <suffix name="LegacyTLS_NotTriggered" label="Page didn't trigger legacy TLS warning"/> <suffix name="LegacyTLS_Triggered" label="Page triggered legacy TLS warning"/> + <affected-histogram name="Security.LegacyTLS.PageInfo.Action"/> <affected-histogram name="Security.PageEndReason"/> + <affected-histogram name="Security.PageInfo.TimeOpen"/> + <affected-histogram name="Security.PageInfo.TimeOpen.Action"/> + <affected-histogram name="Security.PageInfo.TimeOpen.NoAction"/> <affected-histogram name="Security.TimeOnPage2"/> </histogram_suffixes>
diff --git a/ui/accessibility/extensions/BUILD.gn b/ui/accessibility/extensions/BUILD.gn index 4d43c67..183627b 100644 --- a/ui/accessibility/extensions/BUILD.gn +++ b/ui/accessibility/extensions/BUILD.gn
@@ -6,17 +6,11 @@ group("extensions") { deps = [ + ":caretbrowsing", ":colorenhancer", ] } -group("colorenhancer") { - deps = [ - ":colorenhancer_copy", - ":colorenhancer_strings", - ] -} - locale_files = [ "_locales/am/messages.json", "_locales/ar/messages.json", @@ -73,6 +67,17 @@ "_locales/zh_TW/messages.json", ] +# +# Color Enhancer +# + +group("colorenhancer") { + deps = [ + ":colorenhancer_copy", + ":colorenhancer_strings", + ] +} + grit("colorenhancer_strings") { source = "strings/accessibility_extensions_strings.grd" outputs = locale_files @@ -103,3 +108,46 @@ "$root_out_dir/{{source_target_relative}}", ] } + +# +# Caret Browsing +# + +group("caretbrowsing") { + deps = [ + ":caretbrowsing_copy", + ":caretbrowsing_strings", + ] +} + +grit("caretbrowsing_strings") { + source = "strings/accessibility_extensions_strings.grd" + outputs = locale_files + output_dir = "$root_out_dir/caretbrowsing" + depfile_dir = "$root_out_dir" + resource_ids = "" +} + +caretbrowsing_files = [ + "caretbrowsing/background.js", + "caretbrowsing/caret_128.png", + "caretbrowsing/caret_16.png", + "caretbrowsing/caret_19_on.png", + "caretbrowsing/caret_19.png", + "caretbrowsing/caret_48.png", + "caretbrowsing/caretbrowsing.css", + "caretbrowsing/caretbrowsing.js", + "caretbrowsing/increase_brightness.png", + "caretbrowsing/manifest.json", + "caretbrowsing/options.html", + "caretbrowsing/options.js", + "caretbrowsing/traverse_util.js", + "//third_party/accessibility-audit/axs_testing.js", +] + +copy("caretbrowsing_copy") { + sources = caretbrowsing_files + outputs = [ + "$root_out_dir/caretbrowsing/{{source_file_part}}", + ] +}
diff --git a/ui/accessibility/extensions/README.chromium b/ui/accessibility/extensions/README.chromium index 75856ce..a11db4a 100644 --- a/ui/accessibility/extensions/README.chromium +++ b/ui/accessibility/extensions/README.chromium
@@ -6,8 +6,7 @@ # Building # -Right now only the colorenhancer needs to be built, because it has localized -strings. To build it: +Some of the extensions have localized strings and need to be built: ninja -C out/Release ui/accessibility/extensions
diff --git a/ui/accessibility/extensions/caretbrowsing/_locales/en/messages.json b/ui/accessibility/extensions/caretbrowsing/_locales/en/messages.json index 76ec13a..69f981c 100644 --- a/ui/accessibility/extensions/caretbrowsing/_locales/en/messages.json +++ b/ui/accessibility/extensions/caretbrowsing/_locales/en/messages.json
@@ -28,8 +28,8 @@ "description": "Instructions for how to enable or disable this feature on any platform other than Chrome OS." }, "enableDisableCros": { - "message": "Press <span class='key'>Alt</span> + <img src='increase_brightness.png'> (the Increase Brightness key, or F7) to turn on Caret Browsing. Press it again to turn it off.", - "description": "Instructions for how to enable or disable this feature on a Chromebook, where you have to hold Alt and press the special Increase Brightness key on the top of the keyboard, or F7 if you're using an alternate keyboard." + "message": "Press <span class='key'>Search</span> + <img src='increase_brightness.png'> (the Increase Brightness key, or F7) to turn on Caret Browsing. Press it again to turn it off.", + "description": "Instructions for how to enable or disable this feature on a Chromebook, where you have to hold Search and press the special Increase Brightness key on the top of the keyboard, or F7 if you're using an alternate keyboard." }, "moveByWordsNonMac": { "message": "Hold down <span class='key'>Control</span> to move by words.",
diff --git a/ui/accessibility/extensions/caretbrowsing/caretbrowsing.js b/ui/accessibility/extensions/caretbrowsing/caretbrowsing.js index df99efe..912154a 100644 --- a/ui/accessibility/extensions/caretbrowsing/caretbrowsing.js +++ b/ui/accessibility/extensions/caretbrowsing/caretbrowsing.js
@@ -618,8 +618,8 @@ var style = window.getComputedStyle(elem); var bg = axs.utils.getBgColor(style, elem); var fg = axs.utils.getFgColor(style, elem, bg); - CaretBrowsing.caretBackground = axs.utils.colorToString(bg); - CaretBrowsing.caretForeground = axs.utils.colorToString(fg); + CaretBrowsing.caretBackground = axs.color.colorToString(bg); + CaretBrowsing.caretForeground = axs.color.colorToString(fg); if (scrollToSelection) { // Scroll just to the "focus" position of the selection,
diff --git a/ui/accessibility/extensions/caretbrowsing/manifest.json b/ui/accessibility/extensions/caretbrowsing/manifest.json index 188ae0e..04050275 100644 --- a/ui/accessibility/extensions/caretbrowsing/manifest.json +++ b/ui/accessibility/extensions/caretbrowsing/manifest.json
@@ -1,6 +1,6 @@ { "name": "__MSG_CARET_BROWSING_APPNAME__", - "version": "1.0.1", + "version": "1.0.2", "description": "__MSG_CARET_BROWSING_APPDESC__", "manifest_version": 2, "permissions": [
diff --git a/ui/accessibility/extensions/strings/accessibility_extensions_strings.grd b/ui/accessibility/extensions/strings/accessibility_extensions_strings.grd index ee0ad239..d7e7c6e 100644 --- a/ui/accessibility/extensions/strings/accessibility_extensions_strings.grd +++ b/ui/accessibility/extensions/strings/accessibility_extensions_strings.grd
@@ -217,8 +217,8 @@ <message desc="The title of the options page." name="IDS_CARET_BROWSING_CARETBROWSINGOPTIONS"> Caret Browsing Options </message> - <message desc="Instructions for how to enable or disable this feature on a Chromebook, where you have to hold Alt and press the special Increase Brightness key on the top of the keyboard, or F7 if you're using an alternate keyboard." name="IDS_CARET_BROWSING_ENABLEDISABLECROS"> - Press <span class='key'>Alt</span> + <img src='increase_brightness.png'> (the Increase Brightness key, or F7) to turn on Caret Browsing. Press it again to turn it off. + <message desc="Instructions for how to enable or disable this feature on a Chromebook, where you have to hold Search and press the special Increase Brightness key on the top of the keyboard, or F7 if you're using an alternate keyboard." name="IDS_CARET_BROWSING_ENABLEDISABLECROS"> + Press <span class='key'>Search</span> + <img src='increase_brightness.png'> (the Increase Brightness key, or F7) to turn on Caret Browsing. Press it again to turn it off. </message> <message desc="Instructions for how to enable or disable this feature on any platform other than Chrome OS." name="IDS_CARET_BROWSING_ENABLEDISABLENONCROS"> Press <span class='key'>F7</span> to turn on Caret Browsing. Press it again to turn it off.
diff --git a/ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java b/ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java index 69f2457..54684fb6 100644 --- a/ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java +++ b/ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java
@@ -9,6 +9,7 @@ import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; +import android.content.IntentSender; import android.content.IntentSender.SendIntentException; import org.chromium.base.ActivityState; @@ -76,18 +77,25 @@ return (ActivityKeyboardVisibilityDelegate) super.getKeyboardDelegate(); } + /** Uses the provided intent sender to start the intent. */ + protected boolean startIntentSenderForResult(IntentSender intentSender, int requestCode) { + Activity activity = getActivity().get(); + if (activity == null) return false; + + try { + activity.startIntentSenderForResult(intentSender, requestCode, new Intent(), 0, 0, 0); + } catch (SendIntentException e) { + return false; + } + return true; + } + @Override public int showCancelableIntent( PendingIntent intent, IntentCallback callback, Integer errorId) { - Activity activity = getActivity().get(); - if (activity == null) return START_INTENT_FAILURE; - int requestCode = generateNextRequestCode(); - try { - activity.startIntentSenderForResult( - intent.getIntentSender(), requestCode, new Intent(), 0, 0, 0); - } catch (SendIntentException e) { + if (!startIntentSenderForResult(intent.getIntentSender(), requestCode)) { return START_INTENT_FAILURE; } @@ -95,16 +103,24 @@ return requestCode; } - @Override - public int showCancelableIntent(Intent intent, IntentCallback callback, Integer errorId) { + /** Starts an activity for the provided intent. */ + protected boolean startActivityForResult(Intent intent, int requestCode) { Activity activity = getActivity().get(); - if (activity == null) return START_INTENT_FAILURE; - - int requestCode = generateNextRequestCode(); + if (activity == null) return false; try { activity.startActivityForResult(intent, requestCode); } catch (ActivityNotFoundException e) { + return false; + } + return true; + } + + @Override + public int showCancelableIntent(Intent intent, IntentCallback callback, Integer errorId) { + int requestCode = generateNextRequestCode(); + + if (!startActivityForResult(intent, requestCode)) { return START_INTENT_FAILURE; }
diff --git a/ui/base/BUILD.gn b/ui/base/BUILD.gn index bf5f650..797bf4b 100644 --- a/ui/base/BUILD.gn +++ b/ui/base/BUILD.gn
@@ -995,6 +995,7 @@ sources += [ "ime/win/imm32_manager_unittest.cc", "ime/win/on_screen_keyboard_display_manager_unittest.cc", + "ime/win/tsf_input_policy_unittest.cc", "ime/win/tsf_input_scope_unittest.cc", "ime/win/tsf_text_store_unittest.cc", ]
diff --git a/ui/base/ime/mojom/BUILD.gn b/ui/base/ime/mojom/BUILD.gn index 46d8c17..c7467f1 100644 --- a/ui/base/ime/mojom/BUILD.gn +++ b/ui/base/ime/mojom/BUILD.gn
@@ -5,6 +5,7 @@ import("//mojo/public/tools/bindings/mojom.gni") mojom("mojom") { + generate_java = true sources = [ "ime_types.mojom", ]
diff --git a/ui/base/ime/win/input_method_win_tsf.cc b/ui/base/ime/win/input_method_win_tsf.cc index cb6ff5c..37d2888 100644 --- a/ui/base/ime/win/input_method_win_tsf.cc +++ b/ui/base/ime/win/input_method_win_tsf.cc
@@ -57,6 +57,9 @@ return; } tsf_event_router_->SetManager(nullptr); + // Set the policy back to manual as window has lost focus + ui::TSFBridge::GetInstance()->SetInputPanelPolicy( + /*inputPanelPolicyManual*/ true); ui::TSFBridge::GetInstance()->RemoveInputMethodDelegate(); } @@ -126,6 +129,9 @@ return; } InputMethodWinBase::DetachTextInputClient(client); + // Set the policy back to manual as the TextInputClient is no longer valid. + ui::TSFBridge::GetInstance()->SetInputPanelPolicy( + /*inputPanelPolicyManual*/ true); ui::TSFBridge::GetInstance()->RemoveFocusedClient(client); } @@ -180,4 +186,10 @@ ui::TSFBridge::GetInstance()->ConfirmComposition(); } +void InputMethodWinTSF::ShowVirtualKeyboardIfEnabled() { + if (ui::TSFBridge::GetInstance()) + ui::TSFBridge::GetInstance()->SetInputPanelPolicy( + /*inputPanelPolicyManual*/ false); +} + } // namespace ui
diff --git a/ui/base/ime/win/input_method_win_tsf.h b/ui/base/ime/win/input_method_win_tsf.h index 9798bf7..58d7855 100644 --- a/ui/base/ime/win/input_method_win_tsf.h +++ b/ui/base/ime/win/input_method_win_tsf.h
@@ -43,6 +43,8 @@ TextInputClient* focused) override; void ConfirmCompositionText(bool reset_engine) override; + void ShowVirtualKeyboardIfEnabled() override; + private: class TSFEventObserver;
diff --git a/ui/base/ime/win/mock_tsf_bridge.cc b/ui/base/ime/win/mock_tsf_bridge.cc index d634989..62364c9 100644 --- a/ui/base/ime/win/mock_tsf_bridge.cc +++ b/ui/base/ime/win/mock_tsf_bridge.cc
@@ -62,6 +62,15 @@ return text_input_client_; } +void MockTSFBridge::SetInputPanelPolicy(bool input_panel_policy_manual) { + if (tsf_text_store_) + tsf_text_store_->SetInputPanelPolicy(input_panel_policy_manual); +} + +bool MockTSFBridge::IsInputLanguageCJK() { + return false; +} + void MockTSFBridge::Reset() { enable_ime_call_count_ = 0; disable_ime_call_count_ = 0;
diff --git a/ui/base/ime/win/mock_tsf_bridge.h b/ui/base/ime/win/mock_tsf_bridge.h index 4c71fa1..10661bf0 100644 --- a/ui/base/ime/win/mock_tsf_bridge.h +++ b/ui/base/ime/win/mock_tsf_bridge.h
@@ -12,6 +12,7 @@ #include "ui/base/ime/input_method_delegate.h" #include "ui/base/ime/text_input_type.h" #include "ui/base/ime/win/tsf_bridge.h" +#include "ui/base/ime/win/tsf_text_store.h" namespace ui { @@ -31,6 +32,8 @@ void RemoveInputMethodDelegate() override; Microsoft::WRL::ComPtr<ITfThreadMgr> GetThreadManager() override; TextInputClient* GetFocusedTextInputClient() const override; + bool IsInputLanguageCJK() override; + void SetInputPanelPolicy(bool input_panel_policy_manual) override; // Resets MockTSFBridge state including function call counter. void Reset(); @@ -80,6 +83,10 @@ return latest_text_input_type_; } + void SetTSFTextStoreForTesting(TSFTextStore* tsf_text_store) { + tsf_text_store_ = tsf_text_store; + } + private: unsigned enable_ime_call_count_ = 0; unsigned disable_ime_call_count_ = 0; @@ -94,6 +101,7 @@ HWND focused_window_ = nullptr; TextInputType latest_text_input_type_ = TEXT_INPUT_TYPE_NONE; Microsoft::WRL::ComPtr<ITfThreadMgr> thread_manager_; + TSFTextStore* tsf_text_store_ = nullptr; DISALLOW_COPY_AND_ASSIGN(MockTSFBridge); };
diff --git a/ui/base/ime/win/on_screen_keyboard_display_manager_input_pane.cc b/ui/base/ime/win/on_screen_keyboard_display_manager_input_pane.cc index 86414f1..ca0aeab1 100644 --- a/ui/base/ime/win/on_screen_keyboard_display_manager_input_pane.cc +++ b/ui/base/ime/win/on_screen_keyboard_display_manager_input_pane.cc
@@ -44,19 +44,17 @@ } void TryShowInBackgroundThread(HWND hwnd) { + // TODO(crbug.com/1007958): Remove this API after landing TSF virtual keyboard DCHECK(!main_task_runner_->BelongsToCurrentThread()); if (!EnsureInputPanePointersInBackgroundThread(hwnd)) return; - boolean res; - input_pane2_->TryShow(&res); } void TryHideInBackgroundThread() { + // TODO(crbug.com/1007958): Remove this API after landing TSF virtual keyboard DCHECK(!main_task_runner_->BelongsToCurrentThread()); if (!input_pane2_) return; - boolean res; - input_pane2_->TryHide(&res); } private:
diff --git a/ui/base/ime/win/on_screen_keyboard_display_manager_unittest.cc b/ui/base/ime/win/on_screen_keyboard_display_manager_unittest.cc index b0875633..0bff39d 100644 --- a/ui/base/ime/win/on_screen_keyboard_display_manager_unittest.cc +++ b/ui/base/ime/win/on_screen_keyboard_display_manager_unittest.cc
@@ -161,30 +161,4 @@ EXPECT_TRUE(base::PathExists(base::FilePath(osk_path))); } -TEST_F(OnScreenKeyboardTest, InputPane) { - // InputPane is supported only on RS1 and later. - if (base::win::GetVersion() < base::win::Version::WIN10_RS1) - return; - std::unique_ptr<OnScreenKeyboardDisplayManagerInputPane> - keyboard_display_manager = CreateInputPane(); - - std::unique_ptr<MockInputMethodKeyboardControllerObserver> observer = - std::make_unique<MockInputMethodKeyboardControllerObserver>(); - - Microsoft::WRL::ComPtr<MockInputPane> input_pane = - Microsoft::WRL::Make<MockInputPane>(); - keyboard_display_manager->SetInputPaneForTesting(input_pane); - - EXPECT_CALL(*observer, OnKeyboardVisible(testing::_)).Times(1); - keyboard_display_manager->AddObserver(observer.get()); - keyboard_display_manager->DisplayVirtualKeyboard(); - WaitForEventsWithTimeDelay(100); - - testing::Mock::VerifyAndClearExpectations(observer.get()); - EXPECT_CALL(*observer, OnKeyboardHidden()).Times(1); - keyboard_display_manager->DismissVirtualKeyboard(); - WaitForEventsWithTimeDelay(100); - keyboard_display_manager->RemoveObserver(observer.get()); -} - } // namespace ui
diff --git a/ui/base/ime/win/tsf_bridge.cc b/ui/base/ime/win/tsf_bridge.cc index 5d4455e4..6f87906 100644 --- a/ui/base/ime/win/tsf_bridge.cc +++ b/ui/base/ime/win/tsf_bridge.cc
@@ -45,6 +45,7 @@ bool IsInputLanguageCJK() override; Microsoft::WRL::ComPtr<ITfThreadMgr> GetThreadManager() override; TextInputClient* GetFocusedTextInputClient() const override; + void SetInputPanelPolicy(bool input_panel_policy_manual) override; private: // Returns true if |tsf_document_map_| is successfully initialized. This @@ -244,6 +245,18 @@ document->text_store->SendOnLayoutChange(); } +void TSFBridgeImpl::SetInputPanelPolicy(bool input_panel_policy_manual) { + TSFDocument* document = GetAssociatedDocument(); + if (!document) + return; + if (!document->text_store) + return; + + document->text_store->SetInputPanelPolicy(input_panel_policy_manual); + UpdateAssociateFocus(); + thread_manager_->SetFocus(document->document_manager.Get()); +} + bool TSFBridgeImpl::CancelComposition() { DCHECK(base::MessageLoopCurrentForUI::IsSet()); DCHECK(IsInitialized());
diff --git a/ui/base/ime/win/tsf_bridge.h b/ui/base/ime/win/tsf_bridge.h index 0082f52..e9a30587 100644 --- a/ui/base/ime/win/tsf_bridge.h +++ b/ui/base/ime/win/tsf_bridge.h
@@ -91,6 +91,17 @@ // Returns the focused text input client. virtual TextInputClient* GetFocusedTextInputClient() const = 0; + // Sets the input panel policy in TSFTextStore so that input service + // could invoke the software input panel (SIP) on Windows. + // input_panel_policy_manual equals to false would make the SIP policy + // to automatic meaning TSF would raise/dismiss the SIP based on TSFTextStore + // focus and other heuristics that input service have added on Windows to + // provide a consistent behavior across all apps on Windows. + // input_panel_policy_manual equals to true would make the SIP policy to + // manual meaning TSF wouldn't raise/dismiss the SIP automatically. This is + // used to control the SIP behavior based on user interaction with the page. + virtual void SetInputPanelPolicy(bool input_panel_policy_manual) = 0; + protected: // Uses GetInstance() instead. TSFBridge();
diff --git a/ui/base/ime/win/tsf_input_policy_unittest.cc b/ui/base/ime/win/tsf_input_policy_unittest.cc new file mode 100644 index 0000000..620f7df --- /dev/null +++ b/ui/base/ime/win/tsf_input_policy_unittest.cc
@@ -0,0 +1,256 @@ +// Copyright (c) 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. + +#include "ui/base/ime/win/tsf_text_store.h" + +#include <initguid.h> // for GUID_NULL and GUID_PROP_INPUTSCOPE + +#include <InputScope.h> +#include <OleCtl.h> +#include <wrl/client.h> + +#if defined(OS_WIN) +#include <vector> +#endif + +#include "base/memory/ref_counted.h" +#include "base/stl_util.h" +#include "base/win/scoped_com_initializer.h" +#include "base/win/scoped_variant.h" +#include "build/build_config.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/base/ime/dummy_input_method.h" +#include "ui/base/ime/text_input_client.h" +#include "ui/base/ime/win/mock_tsf_bridge.h" +#include "ui/events/event.h" +#include "ui/events/event_dispatcher.h" +#include "ui/gfx/geometry/rect.h" + +using testing::_; +using testing::Invoke; +using testing::Return; + +namespace ui { +namespace { + +class MockTextInputClient : public TextInputClient { + public: + ~MockTextInputClient() {} + MOCK_METHOD1(SetCompositionText, void(const ui::CompositionText&)); + MOCK_METHOD0(ConfirmCompositionText, void()); + MOCK_METHOD0(ClearCompositionText, void()); + MOCK_METHOD1(InsertText, void(const base::string16&)); + MOCK_METHOD1(InsertChar, void(const ui::KeyEvent&)); + MOCK_CONST_METHOD0(GetTextInputType, ui::TextInputType()); + MOCK_CONST_METHOD0(GetTextInputMode, ui::TextInputMode()); + MOCK_CONST_METHOD0(GetTextDirection, base::i18n::TextDirection()); + MOCK_CONST_METHOD0(GetTextInputFlags, int()); + MOCK_CONST_METHOD0(CanComposeInline, bool()); + MOCK_CONST_METHOD0(GetCaretBounds, gfx::Rect()); + MOCK_CONST_METHOD2(GetCompositionCharacterBounds, bool(uint32_t, gfx::Rect*)); + MOCK_CONST_METHOD0(HasCompositionText, bool()); + MOCK_CONST_METHOD0(GetFocusReason, ui::TextInputClient::FocusReason()); + MOCK_METHOD0(ShouldDoLearning, bool()); + MOCK_CONST_METHOD1(GetTextRange, bool(gfx::Range*)); + MOCK_CONST_METHOD1(GetCompositionTextRange, bool(gfx::Range*)); + MOCK_CONST_METHOD1(GetEditableSelectionRange, bool(gfx::Range*)); + MOCK_METHOD1(SetEditableSelectionRange, bool(const gfx::Range&)); + MOCK_METHOD1(DeleteRange, bool(const gfx::Range&)); + MOCK_CONST_METHOD2(GetTextFromRange, + bool(const gfx::Range&, base::string16*)); + MOCK_METHOD0(OnInputMethodChanged, void()); + MOCK_METHOD1(ChangeTextDirectionAndLayoutAlignment, + bool(base::i18n::TextDirection)); + MOCK_METHOD2(ExtendSelectionAndDelete, void(size_t, size_t)); + MOCK_METHOD1(EnsureCaretNotInRect, void(const gfx::Rect&)); + MOCK_CONST_METHOD1(IsTextEditCommandEnabled, bool(TextEditCommand)); + MOCK_METHOD1(SetTextEditCommandForNextKeyEvent, void(TextEditCommand)); + MOCK_CONST_METHOD0(GetClientSourceForMetrics, ukm::SourceId()); + MOCK_METHOD2(SetCompositionFromExistingText, + bool(const gfx::Range&, const std::vector<ui::ImeTextSpan>&)); + MOCK_METHOD3(SetActiveCompositionForAccessibility, + void(const gfx::Range&, const base::string16&, bool)); +}; + +class MockInputMethodDelegate : public internal::InputMethodDelegate { + public: + ~MockInputMethodDelegate() {} + MOCK_METHOD1(DispatchKeyEventPostIME, EventDispatchDetails(KeyEvent*)); +}; + +class MockStoreACPSink : public ITextStoreACPSink { + public: + MockStoreACPSink() : ref_count_(0) {} + + // IUnknown + ULONG STDMETHODCALLTYPE AddRef() override { + return InterlockedIncrement(&ref_count_); + } + ULONG STDMETHODCALLTYPE Release() override { + const LONG count = InterlockedDecrement(&ref_count_); + if (!count) { + delete this; + return 0; + } + return static_cast<ULONG>(count); + } + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** report) override { + if (iid == IID_IUnknown || iid == IID_ITextStoreACPSink) { + *report = static_cast<ITextStoreACPSink*>(this); + } else { + *report = nullptr; + return E_NOINTERFACE; + } + AddRef(); + return S_OK; + } + + // ITextStoreACPSink + MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE, + OnTextChange, + HRESULT(DWORD, const TS_TEXTCHANGE*)); + MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, OnSelectionChange, HRESULT()); + MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE, + OnLayoutChange, + HRESULT(TsLayoutCode, TsViewCookie)); + MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, OnStatusChange, HRESULT(DWORD)); + MOCK_METHOD4_WITH_CALLTYPE(STDMETHODCALLTYPE, + OnAttrsChange, + HRESULT(LONG, LONG, ULONG, const TS_ATTRID*)); + MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, OnLockGranted, HRESULT(DWORD)); + MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, + OnStartEditTransaction, + HRESULT()); + MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, + OnEndEditTransaction, + HRESULT()); + + private: + virtual ~MockStoreACPSink() {} + + volatile LONG ref_count_; +}; + +class FakeInputMethod : public DummyInputMethod { + public: + FakeInputMethod() : client_(nullptr), count_show_ime_if_needed_(0) {} + + void SetFocusedTextInputClient(TextInputClient* client) override { + count_set_focused_text_input_client_++; + client_ = client; + } + + TextInputClient* GetTextInputClient() const override { return client_; } + + void ShowVirtualKeyboardIfEnabled() override { + count_show_ime_if_needed_++; + // Set the input policy in textstore using TSFBridge + tsf_bridge_->SetInputPanelPolicy(/*inputPanelPolicyManual*/ false); + } + + void DetachTextInputClient(TextInputClient* client) override { + if (client_ == client) + client_ = nullptr; + // Set the input policy in textstore using TSFBridge + tsf_bridge_->SetInputPanelPolicy(/*inputPanelPolicyManual*/ true); + } + + void OnTextInputTypeChanged(const TextInputClient* client) override { + count_on_text_input_type_changed_++; + } + + void SetTSFTextStoreForBridge(TSFTextStore* tsf_text_store) { + tsf_bridge_ = new MockTSFBridge(); + tsf_bridge_->SetTSFTextStoreForTesting(tsf_text_store); + } + + int count_show_ime_if_needed() const { return count_show_ime_if_needed_; } + + private: + TextInputClient* client_; + MockTSFBridge* tsf_bridge_; + int count_show_ime_if_needed_; + int count_set_focused_text_input_client_; + int count_on_text_input_type_changed_; +}; + +const HWND kWindowHandle = reinterpret_cast<HWND>(1); + +} // namespace + +class TSFInputPanelTest : public testing::Test { + protected: + void SetUp() override { + text_store_ = new TSFTextStore(); + sink_ = new MockStoreACPSink(); + EXPECT_EQ(S_OK, text_store_->AdviseSink(IID_ITextStoreACPSink, sink_.get(), + TS_AS_ALL_SINKS)); + text_store_->SetFocusedTextInputClient(kWindowHandle, &text_input_client_); + text_store_->SetInputMethodDelegate(&input_method_delegate_); + fake_input_method_ = std::make_unique<FakeInputMethod>(); + fake_input_method_->SetTSFTextStoreForBridge(text_store_.get()); + } + + void TearDown() override { + EXPECT_EQ(S_OK, text_store_->UnadviseSink(sink_.get())); + sink_ = nullptr; + text_store_ = nullptr; + } + + // Accessors to the internal state of TSFTextStore. + + base::win::ScopedCOMInitializer com_initializer_; + MockTextInputClient text_input_client_; + MockInputMethodDelegate input_method_delegate_; + scoped_refptr<TSFTextStore> text_store_; + scoped_refptr<MockStoreACPSink> sink_; + std::unique_ptr<FakeInputMethod> fake_input_method_; +}; + +namespace { + +TEST_F(TSFInputPanelTest, GetStatusTest) { + TS_STATUS status = {}; + EXPECT_EQ(S_OK, text_store_->GetStatus(&status)); + EXPECT_EQ((ULONG)TS_SD_INPUTPANEMANUALDISPLAYENABLE, status.dwDynamicFlags); + EXPECT_EQ((ULONG)(TS_SS_TRANSITORY | TS_SS_NOHIDDENTEXT), + status.dwStaticFlags); +} + +TEST_F(TSFInputPanelTest, ManualInputPaneToAutomaticPolicyTest) { + TS_STATUS status = {}; + EXPECT_EQ(S_OK, text_store_->GetStatus(&status)); + EXPECT_EQ((ULONG)TS_SD_INPUTPANEMANUALDISPLAYENABLE, status.dwDynamicFlags); + EXPECT_EQ((ULONG)(TS_SS_TRANSITORY | TS_SS_NOHIDDENTEXT), + status.dwStaticFlags); + fake_input_method_->ShowVirtualKeyboardIfEnabled(); + EXPECT_EQ(S_OK, text_store_->GetStatus(&status)); + EXPECT_NE((ULONG)TS_SD_INPUTPANEMANUALDISPLAYENABLE, status.dwDynamicFlags); + EXPECT_EQ((ULONG)(TS_SS_TRANSITORY | TS_SS_NOHIDDENTEXT), + status.dwStaticFlags); +} + +TEST_F(TSFInputPanelTest, AutomaticInputPaneToManualPolicyTest) { + TS_STATUS status = {}; + // Invoke the virtual keyboard through InputMethod + // and test if the automatic policy flag has been set or not. + EXPECT_EQ(S_OK, text_store_->GetStatus(&status)); + EXPECT_EQ((ULONG)TS_SD_INPUTPANEMANUALDISPLAYENABLE, status.dwDynamicFlags); + EXPECT_EQ((ULONG)(TS_SS_TRANSITORY | TS_SS_NOHIDDENTEXT), + status.dwStaticFlags); + fake_input_method_->ShowVirtualKeyboardIfEnabled(); + EXPECT_EQ(S_OK, text_store_->GetStatus(&status)); + EXPECT_NE((ULONG)TS_SD_INPUTPANEMANUALDISPLAYENABLE, status.dwDynamicFlags); + EXPECT_EQ((ULONG)(TS_SS_TRANSITORY | TS_SS_NOHIDDENTEXT), + status.dwStaticFlags); + fake_input_method_->DetachTextInputClient(nullptr); + EXPECT_EQ(S_OK, text_store_->GetStatus(&status)); + EXPECT_EQ((ULONG)TS_SD_INPUTPANEMANUALDISPLAYENABLE, status.dwDynamicFlags); + EXPECT_EQ((ULONG)(TS_SS_TRANSITORY | TS_SS_NOHIDDENTEXT), + status.dwStaticFlags); +} + +} // namespace +} // namespace ui
diff --git a/ui/base/ime/win/tsf_text_store.cc b/ui/base/ime/win/tsf_text_store.cc index 9711819d..6630958 100644 --- a/ui/base/ime/win/tsf_text_store.cc +++ b/ui/base/ime/win/tsf_text_store.cc
@@ -217,11 +217,10 @@ if (!status) return E_INVALIDARG; - // Setting input pane policy to manual so TryShow/TryHide APIs can function - // properly. We definitely need to think about a good solution here (i.e. - // remove TryShow/TryHide APIs if possible) and let TSF handle SIP based on - // textstore document focus. - status->dwDynamicFlags = TS_SD_INPUTPANEMANUALDISPLAYENABLE; + if (input_panel_policy_manual_) + status->dwDynamicFlags |= TS_SD_INPUTPANEMANUALDISPLAYENABLE; + else + status->dwDynamicFlags &= ~TS_SD_INPUTPANEMANUALDISPLAYENABLE; // We don't support hidden text. // TODO(IME): Remove TS_SS_TRANSITORY to support Korean reconversion status->dwStaticFlags = TS_SS_TRANSITORY | TS_SS_NOHIDDENTEXT; @@ -1208,6 +1207,10 @@ return TerminateComposition(); } +void TSFTextStore::SetInputPanelPolicy(bool input_panel_policy_manual) { + input_panel_policy_manual_ = input_panel_policy_manual; +} + void TSFTextStore::SendOnLayoutChange() { CalculateTextandSelectionDiffAndNotifyIfNeeded(); if (text_store_acp_sink_ && (text_store_acp_sink_mask_ & TS_AS_LAYOUT_CHANGE))
diff --git a/ui/base/ime/win/tsf_text_store.h b/ui/base/ime/win/tsf_text_store.h index d459f06..69941f8 100644 --- a/ui/base/ime/win/tsf_text_store.h +++ b/ui/base/ime/win/tsf_text_store.h
@@ -259,6 +259,8 @@ // Sends OnLayoutChange() via |text_store_acp_sink_|. void SendOnLayoutChange(); + void SetInputPanelPolicy(bool input_panel_policy_manual); + private: friend class TSFTextStoreTest; friend class TSFTextStoreTestCallback; @@ -424,6 +426,15 @@ Microsoft::WRL::ComPtr<ITfDisplayAttributeMgr> display_attribute_manager_; Microsoft::WRL::ComPtr<ITfContext> context_; + // input_panel_policy_manual_ equals to false would make the SIP policy + // to automatic meaning TSF would raise/dismiss the SIP based on TSFTextStore + // focus and other heuristics that input service have added on Windows to + // provide a consistent behavior across all apps on Windows. + // input_panel_policy_manual_ equals to true would make the SIP policy to + // manual meaning TSF wouldn't raise/dismiss the SIP automatically. This is + // used to control the SIP behavior based on user interaction with the page. + bool input_panel_policy_manual_ = true; + DISALLOW_COPY_AND_ASSIGN(TSFTextStore); };
diff --git a/ui/base/mojom/BUILD.gn b/ui/base/mojom/BUILD.gn index 14aa1c4..c36b9a5 100644 --- a/ui/base/mojom/BUILD.gn +++ b/ui/base/mojom/BUILD.gn
@@ -5,6 +5,7 @@ import("//mojo/public/tools/bindings/mojom.gni") mojom("mojom") { + generate_java = true sources = [ "cursor.mojom", "ui_base_types.mojom",
diff --git a/ui/base/x/x11_shm_image_pool_base.cc b/ui/base/x/x11_shm_image_pool_base.cc index 94b3de3..11d0c06 100644 --- a/ui/base/x/x11_shm_image_pool_base.cc +++ b/ui/base/x/x11_shm_image_pool_base.cc
@@ -129,7 +129,8 @@ for (FrameState& state : frame_states_) { state.shminfo_.shmid = - shmget(IPC_PRIVATE, frame_bytes_, IPC_CREAT | SHM_R | SHM_W); + shmget(IPC_PRIVATE, frame_bytes_, + IPC_CREAT | SHM_R | SHM_W | (SHM_R >> 6) | (SHM_W >> 6)); if (state.shminfo_.shmid < 0) return false; state.shminfo_.shmaddr =
diff --git a/ui/display/test/display_manager_test_api.h b/ui/display/test/display_manager_test_api.h index ce6ca3b..87bdc74c 100644 --- a/ui/display/test/display_manager_test_api.h +++ b/ui/display/test/display_manager_test_api.h
@@ -39,8 +39,8 @@ // Update the display configuration as given in |display_specs|. The format of // |display_spec| is a list of comma separated spec for each displays. Please - // refer to the comment in |ash::DisplayInfo::CreateFromSpec| for the format - // of the display spec. + // refer to the comment in |display::ManagedDisplayInfo::CreateFromSpec| for + // the format of the display spec. void UpdateDisplay(const std::string& display_specs); // Set the 1st display as an internal display and returns the display Id for
diff --git a/ui/gfx/geometry/mojom/BUILD.gn b/ui/gfx/geometry/mojom/BUILD.gn index bbb332bb..a45f5b9 100644 --- a/ui/gfx/geometry/mojom/BUILD.gn +++ b/ui/gfx/geometry/mojom/BUILD.gn
@@ -7,6 +7,7 @@ # This target does NOT depend on skia. One can depend on this target to avoid # picking up a dependency on skia. mojom("mojom") { + generate_java = true sources = [ "geometry.mojom", ]
diff --git a/ui/gfx/harfbuzz_font_skia.cc b/ui/gfx/harfbuzz_font_skia.cc index 4c3fe3f..5ef5cef 100644 --- a/ui/gfx/harfbuzz_font_skia.cc +++ b/ui/gfx/harfbuzz_font_skia.cc
@@ -89,11 +89,15 @@ FontData* font_data = reinterpret_cast<FontData*>(data); GlyphCache* cache = font_data->glyph_cache_; - bool exists = cache->count(unicode) != 0; - if (!exists) - (*cache)[unicode] = font_data->font_.unicharToGlyph(unicode); + GlyphCache::iterator iter = cache->find(unicode); + if (iter == cache->end()) { + auto result = cache->insert( + std::make_pair(unicode, font_data->font_.unicharToGlyph(unicode))); + DCHECK(result.second); + iter = result.first; + } - *glyph = (*cache)[unicode]; + *glyph = iter->second; return !!*glyph; }
diff --git a/ui/gfx/linux/fontconfig_util.cc b/ui/gfx/linux/fontconfig_util.cc index 7f0d4b9..12b268bb 100644 --- a/ui/gfx/linux/fontconfig_util.cc +++ b/ui/gfx/linux/fontconfig_util.cc
@@ -44,10 +44,16 @@ ~GlobalFontConfig() { FcConfigDestroy(fc_config_); } // Retrieve the native font-config FcConfig pointer. - FcConfig* Get() const { return fc_config_; } + FcConfig* Get() const { + DCHECK_EQ(fc_config_, FcConfigGetCurrent()); + return fc_config_; + } // Override the font-config configuration. - void OverrideForTesting(FcConfig* config) { fc_config_ = config; } + void OverrideForTesting(FcConfig* config) { + FcConfigSetCurrent(config); + fc_config_ = config; + } // Retrieve the global font-config configuration. static GlobalFontConfig* GetInstance() {
diff --git a/ui/gfx/mojom/BUILD.gn b/ui/gfx/mojom/BUILD.gn index 43f4c039..0a8a74c 100644 --- a/ui/gfx/mojom/BUILD.gn +++ b/ui/gfx/mojom/BUILD.gn
@@ -5,6 +5,7 @@ import("//mojo/public/tools/bindings/mojom.gni") mojom("mojom") { + generate_java = true sources = [ "accelerated_widget.mojom", "buffer_types.mojom",
diff --git a/ui/gl/features.gni b/ui/gl/features.gni index a90d220..f44c235 100644 --- a/ui/gl/features.gni +++ b/ui/gl/features.gni
@@ -14,5 +14,5 @@ # Should Dawn support be compiled to back the WebGPU implementation. # Also controls linking Dawn depedencies in such as SPIRV-Tools and # SPIRV-Cross - use_dawn = is_mac + use_dawn = is_mac || is_win }
diff --git a/ui/latency/mojom/BUILD.gn b/ui/latency/mojom/BUILD.gn index 4b1bb6e..5322cf97 100644 --- a/ui/latency/mojom/BUILD.gn +++ b/ui/latency/mojom/BUILD.gn
@@ -5,6 +5,7 @@ import("//mojo/public/tools/bindings/mojom.gni") mojom("mojom") { + generate_java = true sources = [ "latency_info.mojom", ]
diff --git a/ui/ozone/platform/drm/gpu/drm_thread.cc b/ui/ozone/platform/drm/gpu/drm_thread.cc index ff1e7967..c1529c7 100644 --- a/ui/ozone/platform/drm/gpu/drm_thread.cc +++ b/ui/ozone/platform/drm/gpu/drm_thread.cc
@@ -307,8 +307,8 @@ } void DrmThread::GetDeviceCursor( - ozone::mojom::DeviceCursorAssociatedRequest request) { - cursor_bindings_.AddBinding(this, std::move(request)); + mojo::PendingAssociatedReceiver<ozone::mojom::DeviceCursor> receiver) { + cursor_receivers_.Add(this, std::move(receiver)); } void DrmThread::RefreshNativeDisplays(
diff --git a/ui/ozone/platform/drm/gpu/drm_thread.h b/ui/ozone/platform/drm/gpu/drm_thread.h index 7169269..16c45bde 100644 --- a/ui/ozone/platform/drm/gpu/drm_thread.h +++ b/ui/ozone/platform/drm/gpu/drm_thread.h
@@ -13,7 +13,9 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/threading/thread.h" -#include "mojo/public/cpp/bindings/associated_binding_set.h" +#include "mojo/public/cpp/bindings/associated_receiver_set.h" +#include "mojo/public/cpp/bindings/binding_set.h" +#include "mojo/public/cpp/bindings/pending_associated_receiver.h" #include "ui/gfx/native_pixmap_handle.h" #include "ui/gfx/native_widget_types.h" #include "ui/gfx/vsync_provider.h" @@ -146,7 +148,8 @@ const OverlaySurfaceCandidateList&, const OverlayStatusList&)> callback) override; void GetDeviceCursor( - ozone::mojom::DeviceCursorAssociatedRequest cursor) override; + mojo::PendingAssociatedReceiver<ozone::mojom::DeviceCursor> receiver) + override; // ozone::mojom::DeviceCursor void SetCursor(gfx::AcceleratedWidget widget, @@ -184,9 +187,9 @@ base::OnceClosure complete_early_binding_requests_; - // The mojo implementation requires an AssociatedBindingSet because the + // The mojo implementation requires an AssociatedReceiverSet because the // DrmThread serves requests from two different client threads. - mojo::AssociatedBindingSet<ozone::mojom::DeviceCursor> cursor_bindings_; + mojo::AssociatedReceiverSet<ozone::mojom::DeviceCursor> cursor_receivers_; // This is a BindingSet because the regular Binding causes the sequence // checker in InterfaceEndpointClient to fail during teardown.
diff --git a/ui/ozone/platform/drm/host/host_cursor_proxy.cc b/ui/ozone/platform/drm/host/host_cursor_proxy.cc index 73ffc64..c0b9083 100644 --- a/ui/ozone/platform/drm/host/host_cursor_proxy.cc +++ b/ui/ozone/platform/drm/host/host_cursor_proxy.cc
@@ -13,10 +13,10 @@ // We assume that this is invoked only on the Mus/UI thread. HostCursorProxy::HostCursorProxy( - ui::ozone::mojom::DeviceCursorAssociatedPtr main_cursor_ptr, - ui::ozone::mojom::DeviceCursorAssociatedPtr evdev_cursor_ptr) - : main_cursor_ptr_(std::move(main_cursor_ptr)), - evdev_cursor_ptr_(std::move(evdev_cursor_ptr)), + mojo::PendingAssociatedRemote<ui::ozone::mojom::DeviceCursor> main_cursor, + mojo::PendingAssociatedRemote<ui::ozone::mojom::DeviceCursor> evdev_cursor) + : main_cursor_(std::move(main_cursor)), + evdev_cursor_(std::move(evdev_cursor)), ui_thread_ref_(base::PlatformThread::CurrentRef()) {} HostCursorProxy::~HostCursorProxy() {} @@ -27,9 +27,9 @@ int frame_delay_ms) { InitializeOnEvdevIfNecessary(); if (ui_thread_ref_ == base::PlatformThread::CurrentRef()) { - main_cursor_ptr_->SetCursor(widget, bitmaps, location, frame_delay_ms); + main_cursor_->SetCursor(widget, bitmaps, location, frame_delay_ms); } else { - evdev_cursor_ptr_->SetCursor(widget, bitmaps, location, frame_delay_ms); + evdev_cursor_->SetCursor(widget, bitmaps, location, frame_delay_ms); } } @@ -37,9 +37,9 @@ const gfx::Point& location) { InitializeOnEvdevIfNecessary(); if (ui_thread_ref_ == base::PlatformThread::CurrentRef()) { - main_cursor_ptr_->MoveCursor(widget, location); + main_cursor_->MoveCursor(widget, location); } else { - evdev_cursor_ptr_->MoveCursor(widget, location); + evdev_cursor_->MoveCursor(widget, location); } } @@ -56,7 +56,7 @@ if (ui_thread_ref_ != base::PlatformThread::CurrentRef()) { // Rebind the mojo pipe on the current thread. We expect this to be the // thread running EVDEV. - evdev_cursor_ptr_.Bind(evdev_cursor_ptr_.PassInterface()); + evdev_cursor_.Bind(evdev_cursor_.Unbind()); } }
diff --git a/ui/ozone/platform/drm/host/host_cursor_proxy.h b/ui/ozone/platform/drm/host/host_cursor_proxy.h index 00e9cf4..22c16f4 100644 --- a/ui/ozone/platform/drm/host/host_cursor_proxy.h +++ b/ui/ozone/platform/drm/host/host_cursor_proxy.h
@@ -5,6 +5,8 @@ #ifndef UI_OZONE_PLATFORM_DRM_HOST_HOST_CURSOR_PROXY_H_ #define UI_OZONE_PLATFORM_DRM_HOST_HOST_CURSOR_PROXY_H_ +#include "mojo/public/cpp/bindings/associated_remote.h" +#include "mojo/public/cpp/bindings/pending_associated_remote.h" #include "ui/gfx/native_widget_types.h" #include "ui/ozone/platform/drm/host/drm_cursor.h" #include "ui/ozone/public/mojom/device_cursor.mojom.h" @@ -18,8 +20,10 @@ // priviledged process. class HostCursorProxy : public DrmCursorProxy { public: - HostCursorProxy(ui::ozone::mojom::DeviceCursorAssociatedPtr main_cursor_ptr, - ui::ozone::mojom::DeviceCursorAssociatedPtr evdev_cursor_ptr); + HostCursorProxy( + mojo::PendingAssociatedRemote<ui::ozone::mojom::DeviceCursor> main_cursor, + mojo::PendingAssociatedRemote<ui::ozone::mojom::DeviceCursor> + evdev_cursor); ~HostCursorProxy() override; private: @@ -32,8 +36,8 @@ void InitializeOnEvdevIfNecessary() override; // Mojo implementation of the DrmCursorProxy. - ui::ozone::mojom::DeviceCursorAssociatedPtr main_cursor_ptr_ = nullptr; - ui::ozone::mojom::DeviceCursorAssociatedPtr evdev_cursor_ptr_ = nullptr; + mojo::AssociatedRemote<ui::ozone::mojom::DeviceCursor> main_cursor_; + mojo::AssociatedRemote<ui::ozone::mojom::DeviceCursor> evdev_cursor_; base::PlatformThreadRef ui_thread_ref_; bool evdev_bound_ = false;
diff --git a/ui/ozone/platform/drm/host/host_drm_device.cc b/ui/ozone/platform/drm/host/host_drm_device.cc index c436675..c436e2b 100644 --- a/ui/ozone/platform/drm/host/host_drm_device.cc +++ b/ui/ozone/platform/drm/host/host_drm_device.cc
@@ -12,6 +12,7 @@ #include "base/single_thread_task_runner.h" #include "base/task_runner.h" #include "base/threading/thread_task_runner_handle.h" +#include "mojo/public/cpp/bindings/pending_associated_remote.h" #include "services/service_manager/public/cpp/connector.h" #include "ui/display/types/display_snapshot.h" #include "ui/ozone/platform/drm/common/drm_util.h" @@ -368,16 +369,19 @@ // Create two DeviceCursor connections: one for the UI thread and one for the // IO thread. - ui::ozone::mojom::DeviceCursorAssociatedPtr cursor_ptr_ui, cursor_ptr_io; - drm_device_ptr_->GetDeviceCursor(mojo::MakeRequest(&cursor_ptr_ui)); - drm_device_ptr_->GetDeviceCursor(mojo::MakeRequest(&cursor_ptr_io)); + mojo::PendingAssociatedRemote<ui::ozone::mojom::DeviceCursor> cursor_ui, + cursor_io; + drm_device_ptr_->GetDeviceCursor( + cursor_ui.InitWithNewEndpointAndPassReceiver()); + drm_device_ptr_->GetDeviceCursor( + cursor_io.InitWithNewEndpointAndPassReceiver()); // The cursor is special since it will process input events on the IO thread - // and can by-pass the UI thread. As a result, it has an InterfacePtr for both - // the UI and I/O thread. cursor_ptr_io is already bound correctly to an I/O - // thread by GpuProcessHost. - cursor_proxy_ = std::make_unique<HostCursorProxy>(std::move(cursor_ptr_ui), - std::move(cursor_ptr_io)); + // and can by-pass the UI thread. As a result, it has a Remote for both the UI + // and I/O thread. cursor_io is already bound correctly to an I/O thread by + // GpuProcessHost. + cursor_proxy_ = std::make_unique<HostCursorProxy>(std::move(cursor_ui), + std::move(cursor_io)); OnDrmServiceStarted(); }
diff --git a/ui/ozone/platform/drm/host/host_drm_device.h b/ui/ozone/platform/drm/host/host_drm_device.h index 309ca0c..a93ecb7 100644 --- a/ui/ozone/platform/drm/host/host_drm_device.h +++ b/ui/ozone/platform/drm/host/host_drm_device.h
@@ -106,10 +106,6 @@ void BindInterfaceDrmDevice( ui::ozone::mojom::DrmDevicePtr* drm_device_ptr) const; - // BindInterface arranges for the cursor_ptr to be wired up. - void BindInterfaceDeviceCursor( - ui::ozone::mojom::DeviceCursorPtr* cursor_ptr) const; - void OnDrmServiceStarted(); // TODO(rjkroege): Get rid of the need for this method in a subsequent CL.
diff --git a/ui/ozone/public/mojom/drm_device.mojom b/ui/ozone/public/mojom/drm_device.mojom index ef4b631..56fdb1d 100644 --- a/ui/ozone/public/mojom/drm_device.mojom +++ b/ui/ozone/public/mojom/drm_device.mojom
@@ -90,6 +90,6 @@ // Provides a DeviceCursor interface. The provided interface needs to be // associated because the AcceleratedWidgets referenced by its methods are // registered via CreateWindow() in this interface. - GetDeviceCursor(associated DeviceCursor& cursor); + GetDeviceCursor(pending_associated_receiver<DeviceCursor> cursor); };
diff --git a/ui/shell_dialogs/selected_file_info.cc b/ui/shell_dialogs/selected_file_info.cc index 852eda6d..79691e6b 100644 --- a/ui/shell_dialogs/selected_file_info.cc +++ b/ui/shell_dialogs/selected_file_info.cc
@@ -25,4 +25,13 @@ SelectedFileInfo& SelectedFileInfo::operator=(SelectedFileInfo&& other) = default; +// Converts a list of FilePaths to a list of ui::SelectedFileInfo. +std::vector<SelectedFileInfo> FilePathListToSelectedFileInfoList( + const std::vector<base::FilePath>& paths) { + std::vector<SelectedFileInfo> selected_files; + for (const auto& path : paths) + selected_files.push_back(SelectedFileInfo(path, path)); + return selected_files; +} + } // namespace ui
diff --git a/ui/shell_dialogs/selected_file_info.h b/ui/shell_dialogs/selected_file_info.h index 89de4e2f..6f76bef 100644 --- a/ui/shell_dialogs/selected_file_info.h +++ b/ui/shell_dialogs/selected_file_info.h
@@ -49,6 +49,10 @@ SelectedFileInfo& operator=(SelectedFileInfo&& other); }; +// Converts a list of FilePaths to a list of ui::SelectedFileInfo. +SHELL_DIALOGS_EXPORT std::vector<SelectedFileInfo> +FilePathListToSelectedFileInfoList(const std::vector<base::FilePath>& paths); + } // namespace ui #endif // UI_SHELL_DIALOGS_SELECTED_FILE_INFO_H_
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc index b06c12c2..00971fc 100644 --- a/ui/views/win/hwnd_message_handler.cc +++ b/ui/views/win/hwnd_message_handler.cc
@@ -277,49 +277,6 @@ } } -void RecordDeltaBetweenTimeNowAndPerformanceCountHistogram( - base::TimeTicks event_time, - UINT64 performance_count, - POINTER_INPUT_TYPE pointer_input_type, - bool is_session_remote) { - // In remote session, sometimes |performance_count| drifts - // substantially in future compared to |TimeTicks::Now()| - enough to skew the - // histogram data. Additionally, user input over remote session already has - // lag, so user is less likely to be sensitive to the responsiveness of input - // in such case. So we are less concerned capturing the deltas in remote - // session scenario. - if (base::TimeTicks::IsHighResolution() && !is_session_remote) { - base::TimeTicks event_time_from_pointer = - base::TimeTicks::FromQPCValue(performance_count); - - double delta_between_event_timestamps = - (event_time - event_time_from_pointer).InMicrosecondsF(); - std::string pointer_type; - switch (pointer_input_type) { - case PT_PEN: - pointer_type = "Pen"; - break; - case PT_TOUCH: - pointer_type = "Touch"; - break; - default: - NOTREACHED(); - } - - std::string number_sign = - delta_between_event_timestamps >= 0 ? "Positive" : "Negative"; - base::TimeDelta delta_sample_value = base::TimeDelta::FromMicroseconds( - std::abs(delta_between_event_timestamps)); - - base::UmaHistogramCustomMicrosecondsTimes( - base::StringPrintf("Event.%s.InputEventTimeStamp." - "DeltaBetweenTimeNowAndPerformanceCount.%s", - pointer_type.c_str(), number_sign.c_str()), - delta_sample_value, base::TimeDelta::FromMicroseconds(1), - base::TimeDelta::FromMilliseconds(30), 30); - } -} - int GetFlagsFromRawInputMessage(RAWINPUT* input) { int flags = ui::EF_NONE; if (input->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_DOWN) @@ -468,8 +425,7 @@ background_fullscreen_hack_(false), pointer_events_for_touch_(::features::IsUsingWMPointerForTouch()), precision_touchpad_scroll_phase_enabled_(base::FeatureList::IsEnabled( - ::features::kPrecisionTouchpadScrollPhase)), - is_remote_session_(base::win::IsCurrentSessionRemote()) {} + ::features::kPrecisionTouchpadScrollPhase)) {} HWNDMessageHandler::~HWNDMessageHandler() { DCHECK(delegate_->GetHWNDMessageDelegateInputMethod()); @@ -2549,7 +2505,6 @@ if (flags == SPI_SETWORKAREA) delegate_->HandleWorkAreaChanged(); SetMsgHandled(FALSE); - is_remote_session_ = base::win::IsCurrentSessionRemote(); } // If the work area is changing, then it could be as a result of the taskbar @@ -3185,10 +3140,6 @@ base::WeakPtr<HWNDMessageHandler> ref(msg_handler_weak_factory_.GetWeakPtr()); delegate_->HandleTouchEvent(&event); - RecordDeltaBetweenTimeNowAndPerformanceCountHistogram( - event_time, pointer_info.PerformanceCount, pointer_info.pointerType, - is_remote_session_); - if (ref) { // Mark touch released events handled. These will usually turn into tap // gestures, and doing this avoids propagating the event to other windows. @@ -3238,16 +3189,13 @@ // window, so use the weak ptr to check if destruction occured or not. base::WeakPtr<HWNDMessageHandler> ref(msg_handler_weak_factory_.GetWeakPtr()); if (event) { - if (event->IsTouchEvent()) { + if (event->IsTouchEvent()) delegate_->HandleTouchEvent(event->AsTouchEvent()); - RecordDeltaBetweenTimeNowAndPerformanceCountHistogram( - event->time_stamp(), pointer_pen_info.pointerInfo.PerformanceCount, - pointer_pen_info.pointerInfo.pointerType, is_remote_session_); - } else if (event->IsMouseEvent()) { + else if (event->IsMouseEvent()) delegate_->HandleMouseEvent(event->AsMouseEvent()); - } else { + else NOTREACHED(); - } + last_touch_or_pen_message_time_ = ::GetMessageTime(); }
diff --git a/ui/views/win/hwnd_message_handler.h b/ui/views/win/hwnd_message_handler.h index cbc7961..8299c29 100644 --- a/ui/views/win/hwnd_message_handler.h +++ b/ui/views/win/hwnd_message_handler.h
@@ -783,9 +783,6 @@ // the first message after frame type changes. bool needs_dwm_frame_clear_ = true; - // True if user is in remote session. - bool is_remote_session_; - // True if is handling mouse WM_INPUT messages. bool using_wm_input_ = false;
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_config.js b/ui/webui/resources/cr_components/chromeos/network/network_config.js index ba1b47b..e9cd084 100644 --- a/ui/webui/resources/cr_components/chromeos/network/network_config.js +++ b/ui/webui/resources/cr_components/chromeos/network/network_config.js
@@ -663,7 +663,7 @@ identity: OncMojo.getActiveString(eap.identity), inner: OncMojo.getActiveString(eap.inner), outer: OncMojo.getActiveString(eap.outer) || 'LEAP', - password: '', + password: OncMojo.getActiveString(eap.password), saveCredentials: this.getActiveBoolean_(eap.saveCredentials), serverCaPems: this.getActiveStringList_(eap.serverCaPems), subjectMatch: OncMojo.getActiveString(eap.subjectMatch), @@ -715,11 +715,11 @@ clientCertPkcs11Id: OncMojo.getActiveString(openVpn.clientCertPkcs11Id), clientCertType: OncMojo.getActiveString(openVpn.clientCertType), extraHosts: this.getActiveStringList_(openVpn.extraHosts), + otp: OncMojo.getActiveString(openVpn.otp), + password: OncMojo.getActiveString(openVpn.password), saveCredentials: this.getActiveBoolean_(openVpn.saveCredentials), serverCaPems: this.getActiveStringList_(openVpn.serverCaPems), serverCaRefs: this.getActiveStringList_(openVpn.serverCaRefs), - otp: OncMojo.getActiveString(openVpn.otp), - password: OncMojo.getActiveString(openVpn.password), userAuthenticationType: OncMojo.getActiveString(openVpn.userAuthenticationType), username: OncMojo.getActiveString(openVpn.username), @@ -752,7 +752,7 @@ const wifi = managedProperties.typeProperties.wifi; const configWifi = configProperties.typeConfig.wifi; autoConnect = this.getActiveBoolean_(wifi.autoConnect); - configWifi.passphrase = ''; + configWifi.passphrase = OncMojo.getActiveString(wifi.passphrase); configWifi.ssid = OncMojo.getActiveString(wifi.ssid); if (wifi.eap) { configWifi.eap = this.getEAPConfigProperties_(wifi.eap);
diff --git a/ui/webui/resources/js/BUILD.gn b/ui/webui/resources/js/BUILD.gn index e765af0..55d5e43 100644 --- a/ui/webui/resources/js/BUILD.gn +++ b/ui/webui/resources/js/BUILD.gn
@@ -151,11 +151,18 @@ "web_ui_listener_behavior.js", ] deps = [ - "cr/ui:modulize", + "cr:modulize", ] } -js_type_check("closure_compile_modules") { +group("closure_compile_modules") { + deps = [ + ":js_resources_modules", + "cr:closure_compile_modules", + ] +} + +js_type_check("js_resources_modules") { deps = [ ":assert.m", ":cr.m",
diff --git a/ui/webui/resources/js/cr/BUILD.gn b/ui/webui/resources/js/cr/BUILD.gn index f785078..b566f39 100644 --- a/ui/webui/resources/js/cr/BUILD.gn +++ b/ui/webui/resources/js/cr/BUILD.gn
@@ -3,6 +3,7 @@ # found in the LICENSE file. import("//third_party/closure_compiler/compile_js.gni") +import("../../tools/js_modulizer.gni") js_type_check("closure_compile") { deps = [ @@ -11,6 +12,12 @@ ] } +js_type_check("closure_compile_modules") { + deps = [ + ":event_target.m", + ] +} + js_library("event_target") { deps = [ "..:cr", @@ -22,3 +29,17 @@ "..:cr", ] } + +js_library("event_target.m") { + sources = [ + "$root_gen_dir/ui/webui/resources/js/cr/event_target.m.js", + ] + extra_deps = [ ":modulize" ] +} + +js_modulizer("modulize") { + input_files = [ "event_target.js" ] + deps = [ + "ui:modulize", + ] +}
diff --git a/ui/webui/resources/js/cr/event_target.js b/ui/webui/resources/js/cr/event_target.js index cc889ad..86deebc 100644 --- a/ui/webui/resources/js/cr/event_target.js +++ b/ui/webui/resources/js/cr/event_target.js
@@ -14,12 +14,12 @@ * @constructor * @implements {EventTarget} */ - const NativeEventTarget = self['EventTarget']; + /* #export */ const NativeEventTarget = self['EventTarget']; /** @override */ NativeEventTarget.prototype.addEventListener; /** @override */ NativeEventTarget.prototype.dispatchEvent; /** @override */ NativeEventTarget.prototype.removeEventListener; - // Export + // #cr_define_end return {EventTarget: NativeEventTarget}; });
diff --git a/ui/webui/resources/polymer_resources.grdp b/ui/webui/resources/polymer_resources.grdp index 1411832..67506e3 100644 --- a/ui/webui/resources/polymer_resources.grdp +++ b/ui/webui/resources/polymer_resources.grdp
@@ -33,10 +33,6 @@ file="../../../third_party/polymer/v1_0/components-chromium/html-imports/html-imports.min.js" type="chrome_html" compress="gzip" /> - <structure name="IDR_POLYMER_1_0_HTML_IMPORTS_V0_HTML_IMPORTS_MIN_JS" - file="../../../third_party/polymer/v1_0/components-chromium/html-imports-v0/html-imports.min.js" - type="chrome_html" - compress="gzip" /> </if> <structure name="IDR_POLYMER_1_0_IRON_A11Y_ANNOUNCER_IRON_A11Y_ANNOUNCER_EXTRACTED_JS" file="../../../third_party/polymer/v1_0/components-chromium/iron-a11y-announcer/iron-a11y-announcer-extracted.js"
diff --git a/ui/webui/resources/webui_resources.grd b/ui/webui/resources/webui_resources.grd index a028921..d9ba072 100644 --- a/ui/webui/resources/webui_resources.grd +++ b/ui/webui/resources/webui_resources.grd
@@ -88,6 +88,9 @@ <include name="IDR_WEBUI_JS_ASSERT_M_JS" file="${root_gen_dir}/ui/webui/resources/js/assert.m.js" use_base_dir="false" type="BINDATA" compress="gzip" /> + <include name="IDR_WEBUI_JS_CR_EVENT_TARGET_M_JS" + file="${root_gen_dir}/ui/webui/resources/js/cr/event_target.m.js" + use_base_dir="false" type="BINDATA" compress="gzip" /> <include name="IDR_WEBUI_JS_CR_UI_DRAG_WRAPPER_M_JS" file="${root_gen_dir}/ui/webui/resources/js/cr/ui/drag_wrapper.m.js" use_base_dir="false" type="BINDATA" compress="gzip" />
diff --git a/url/mojom/BUILD.gn b/url/mojom/BUILD.gn index 55796a987..e60a2a90 100644 --- a/url/mojom/BUILD.gn +++ b/url/mojom/BUILD.gn
@@ -5,12 +5,14 @@ import("//mojo/public/tools/bindings/mojom.gni") mojom("url_mojom_gurl") { + generate_java = true sources = [ "url.mojom", ] } mojom("url_mojom_origin") { + generate_java = true sources = [ "origin.mojom", ]
diff --git a/weblayer/BUILD.gn b/weblayer/BUILD.gn index 88675f5..876a316d 100644 --- a/weblayer/BUILD.gn +++ b/weblayer/BUILD.gn
@@ -44,6 +44,8 @@ "browser/browser_main_parts_impl.h", "browser/content_browser_client_impl.cc", "browser/content_browser_client_impl.h", + "browser/file_select_helper.cc", + "browser/file_select_helper.h", "browser/isolated_world_ids.h", "browser/navigation_controller_impl.cc", "browser/navigation_controller_impl.h", @@ -115,6 +117,7 @@ "//ui/gfx/ipc/skia", "//ui/gl", "//ui/platform_window", + "//ui/shell_dialogs", "//ui/webui", "//url", "//v8",
diff --git a/weblayer/browser/DEPS b/weblayer/browser/DEPS index f5bed443..dad9ebcf 100644 --- a/weblayer/browser/DEPS +++ b/weblayer/browser/DEPS
@@ -14,6 +14,7 @@ "+ui/base", "+ui/events", "+ui/gfx", + "+ui/shell_dialogs", "+ui/views", "+ui/webui", "+ui/wm",
diff --git a/weblayer/browser/browser_controller_impl.cc b/weblayer/browser/browser_controller_impl.cc index 48a8652..97712877 100644 --- a/weblayer/browser/browser_controller_impl.cc +++ b/weblayer/browser/browser_controller_impl.cc
@@ -6,10 +6,12 @@ #include "base/auto_reset.h" #include "base/logging.h" +#include "content/public/browser/file_select_listener.h" #include "content/public/browser/interstitial_page.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" #include "content/public/common/browser_controls_state.h" +#include "weblayer/browser/file_select_helper.h" #include "weblayer/browser/navigation_controller_impl.h" #include "weblayer/browser/profile_impl.h" #include "weblayer/public/browser_observer.h" @@ -192,6 +194,14 @@ observer.DisplayedUrlChanged(web_contents->GetVisibleURL()); } +void BrowserControllerImpl::RunFileChooser( + content::RenderFrameHost* render_frame_host, + std::unique_ptr<content::FileSelectListener> listener, + const blink::mojom::FileChooserParams& params) { + FileSelectHelper::RunFileChooser(render_frame_host, std::move(listener), + params); +} + int BrowserControllerImpl::GetTopControlsHeight() { #if defined(OS_ANDROID) return top_controls_container_view_->GetTopControlsHeight();
diff --git a/weblayer/browser/browser_controller_impl.h b/weblayer/browser/browser_controller_impl.h index f612b504..2533db8 100644 --- a/weblayer/browser/browser_controller_impl.h +++ b/weblayer/browser/browser_controller_impl.h
@@ -80,6 +80,9 @@ double progress) override; void DidNavigateMainFramePostCommit( content::WebContents* web_contents) override; + void RunFileChooser(content::RenderFrameHost* render_frame_host, + std::unique_ptr<content::FileSelectListener> listener, + const blink::mojom::FileChooserParams& params) override; int GetTopControlsHeight() override; bool DoBrowserControlsShrinkRendererSize( const content::WebContents* web_contents) override;
diff --git a/weblayer/browser/file_select_helper.cc b/weblayer/browser/file_select_helper.cc new file mode 100644 index 0000000..7cc0a81 --- /dev/null +++ b/weblayer/browser/file_select_helper.cc
@@ -0,0 +1,184 @@ +// 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. + +#include "weblayer/browser/file_select_helper.h" + +#include <string> + +#include "build/build_config.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/web_contents.h" +#include "ui/shell_dialogs/select_file_policy.h" +#include "ui/shell_dialogs/selected_file_info.h" + +#if defined(OS_ANDROID) +#include "ui/android/view_android.h" +#else +#include "ui/aura/window.h" +#endif + +namespace weblayer { +using blink::mojom::FileChooserFileInfo; +using blink::mojom::FileChooserFileInfoPtr; +using blink::mojom::FileChooserParams; +using blink::mojom::FileChooserParamsPtr; + +// static +void FileSelectHelper::RunFileChooser( + content::RenderFrameHost* render_frame_host, + std::unique_ptr<content::FileSelectListener> listener, + const FileChooserParams& params) { + // TODO: Should we handle text/json+contacts accept type? + + // FileSelectHelper will keep itself alive until it sends the result + // message. + scoped_refptr<FileSelectHelper> file_select_helper(new FileSelectHelper()); + file_select_helper->RunFileChooser(render_frame_host, std::move(listener), + params.Clone()); +} + +FileSelectHelper::FileSelectHelper() = default; + +FileSelectHelper::~FileSelectHelper() { + // There may be pending file dialogs, we need to tell them that we've gone + // away so they don't try and call back to us. + if (select_file_dialog_) + select_file_dialog_->ListenerDestroyed(); +} + +void FileSelectHelper::RunFileChooser( + content::RenderFrameHost* render_frame_host, + std::unique_ptr<content::FileSelectListener> listener, + FileChooserParamsPtr params) { + DCHECK(!web_contents()); + DCHECK(listener); + DCHECK(!listener_); + + listener_ = std::move(listener); + Observe(content::WebContents::FromRenderFrameHost(render_frame_host)); + + select_file_dialog_ = ui::SelectFileDialog::Create(this, nullptr); + + dialog_mode_ = params->mode; + switch (params->mode) { + case FileChooserParams::Mode::kOpen: + dialog_type_ = ui::SelectFileDialog::SELECT_OPEN_FILE; + break; + case FileChooserParams::Mode::kOpenMultiple: + dialog_type_ = ui::SelectFileDialog::SELECT_OPEN_MULTI_FILE; + break; + case FileChooserParams::Mode::kUploadFolder: + // For now we don't support inputs with webkitdirectory in weblayer. + dialog_type_ = ui::SelectFileDialog::SELECT_OPEN_MULTI_FILE; + break; + case FileChooserParams::Mode::kSave: + dialog_type_ = ui::SelectFileDialog::SELECT_SAVEAS_FILE; + break; + default: + // Prevent warning. + dialog_type_ = ui::SelectFileDialog::SELECT_OPEN_FILE; + NOTREACHED(); + } + + gfx::NativeWindow owning_window; +#if defined(OS_ANDROID) + owning_window = web_contents()->GetNativeView()->GetWindowAndroid(); +#else + owning_window = web_contents()->GetNativeView()->GetToplevelWindow(); +#endif + +#if defined(OS_ANDROID) + // Android needs the original MIME types and an additional capture value. + std::pair<std::vector<base::string16>, bool> accept_types = + std::make_pair(params->accept_types, params->use_media_capture); +#endif + + // Many of these params are not used in the Android SelectFileDialog + // implementation, so we can safely pass empty values. + select_file_dialog_->SelectFile(dialog_type_, base::string16(), + base::FilePath(), nullptr, 0, + base::FilePath::StringType(), owning_window, +#if defined(OS_ANDROID) + &accept_types); +#else + nullptr); +#endif + + // Because this class returns notifications to the RenderViewHost, it is + // difficult for callers to know how long to keep a reference to this + // instance. We AddRef() here to keep the instance alive after we return + // to the caller, until the last callback is received from the file dialog. + // At that point, we must call RunFileChooserEnd(). + AddRef(); +} + +void FileSelectHelper::RunFileChooserEnd() { + if (listener_) + listener_->FileSelectionCanceled(); + Release(); +} + +void FileSelectHelper::FileSelected(const base::FilePath& path, + int index, + void* params) { + FileSelectedWithExtraInfo(ui::SelectedFileInfo(path, path), index, params); +} + +void FileSelectHelper::FileSelectedWithExtraInfo( + const ui::SelectedFileInfo& file, + int index, + void* params) { + ConvertToFileChooserFileInfoList({file}); +} + +void FileSelectHelper::MultiFilesSelected( + const std::vector<base::FilePath>& files, + void* params) { + std::vector<ui::SelectedFileInfo> selected_files = + ui::FilePathListToSelectedFileInfoList(files); + + MultiFilesSelectedWithExtraInfo(selected_files, params); +} + +void FileSelectHelper::MultiFilesSelectedWithExtraInfo( + const std::vector<ui::SelectedFileInfo>& files, + void* params) { + ConvertToFileChooserFileInfoList(files); +} + +void FileSelectHelper::FileSelectionCanceled(void* params) { + RunFileChooserEnd(); +} + +void FileSelectHelper::ConvertToFileChooserFileInfoList( + const std::vector<ui::SelectedFileInfo>& files) { + if (AbortIfWebContentsDestroyed()) + return; + + std::vector<FileChooserFileInfoPtr> chooser_files; + for (const auto& file : files) { + chooser_files.push_back( + FileChooserFileInfo::NewNativeFile(blink::mojom::NativeFileInfo::New( + file.local_path, + base::FilePath(file.display_name).AsUTF16Unsafe()))); + } + + listener_->FileSelected(std::move(chooser_files), base::FilePath(), + dialog_mode_); + listener_ = nullptr; + + // No members should be accessed from here on. + RunFileChooserEnd(); +} + +bool FileSelectHelper::AbortIfWebContentsDestroyed() { + if (web_contents() == nullptr) { + RunFileChooserEnd(); + return true; + } + + return false; +} + +} // namespace weblayer
diff --git a/weblayer/browser/file_select_helper.h b/weblayer/browser/file_select_helper.h new file mode 100644 index 0000000..a999774 --- /dev/null +++ b/weblayer/browser/file_select_helper.h
@@ -0,0 +1,106 @@ +// 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 WEBLAYER_BROWSER_FILE_SELECT_HELPER_H_ +#define WEBLAYER_BROWSER_FILE_SELECT_HELPER_H_ + +#include <memory> +#include <vector> + +#include "base/macros.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/file_select_listener.h" +#include "content/public/browser/web_contents_observer.h" +#include "ui/shell_dialogs/select_file_dialog.h" + +namespace content { +class FileSelectListener; +} // namespace content + +namespace ui { +struct SelectedFileInfo; +} + +namespace weblayer { + +// This class handles file-selection requests coming from renderer processes. +// It implements both the initialisation and listener functions for +// file-selection dialogs. +// +// Since FileSelectHelper listens to observations of a widget, it needs to live +// on and be destroyed on the UI thread. References to FileSelectHelper may be +// passed on to other threads. +class FileSelectHelper : public base::RefCountedThreadSafe< + FileSelectHelper, + content::BrowserThread::DeleteOnUIThread>, + public ui::SelectFileDialog::Listener, + public content::WebContentsObserver { + public: + // Show the file chooser dialog. + static void RunFileChooser( + content::RenderFrameHost* render_frame_host, + std::unique_ptr<content::FileSelectListener> listener, + const blink::mojom::FileChooserParams& params); + + private: + friend class base::RefCountedThreadSafe<FileSelectHelper>; + friend class base::DeleteHelper<FileSelectHelper>; + friend struct content::BrowserThread::DeleteOnThread< + content::BrowserThread::UI>; + + FileSelectHelper(); + ~FileSelectHelper() override; + + void RunFileChooser(content::RenderFrameHost* render_frame_host, + std::unique_ptr<content::FileSelectListener> listener, + blink::mojom::FileChooserParamsPtr params); + + // Cleans up and releases this instance. This must be called after the last + // callback is received from the file chooser dialog. + void RunFileChooserEnd(); + + // SelectFileDialog::Listener overrides. + void FileSelected(const base::FilePath& path, + int index, + void* params) override; + void FileSelectedWithExtraInfo(const ui::SelectedFileInfo& file, + int index, + void* params) override; + void MultiFilesSelected(const std::vector<base::FilePath>& files, + void* params) override; + void MultiFilesSelectedWithExtraInfo( + const std::vector<ui::SelectedFileInfo>& files, + void* params) override; + void FileSelectionCanceled(void* params) override; + + // This method is called after the user has chosen the file(s) in the UI in + // order to process and filter the list before returning the final result to + // the caller. + void ConvertToFileChooserFileInfoList( + const std::vector<ui::SelectedFileInfo>& files); + + // Calls RunFileChooserEnd() if the webcontents was destroyed. Returns true + // if the file chooser operation shouldn't proceed. + bool AbortIfWebContentsDestroyed(); + + // |listener_| receives the result of the FileSelectHelper. + std::unique_ptr<content::FileSelectListener> listener_; + + // Dialog box used for choosing files to upload from file form fields. + scoped_refptr<ui::SelectFileDialog> select_file_dialog_; + + // The type of file dialog last shown. + ui::SelectFileDialog::Type dialog_type_ = + ui::SelectFileDialog::SELECT_OPEN_FILE; + + // The mode of file dialog last shown. + blink::mojom::FileChooserParams::Mode dialog_mode_ = + blink::mojom::FileChooserParams::Mode::kOpen; + + DISALLOW_COPY_AND_ASSIGN(FileSelectHelper); +}; + +} // namespace weblayer + +#endif // WEBLAYER_BROWSER_FILE_SELECT_HELPER_H_
diff --git a/weblayer/browser/java/BUILD.gn b/weblayer/browser/java/BUILD.gn index 2a4edcb..1e6d5ed 100644 --- a/weblayer/browser/java/BUILD.gn +++ b/weblayer/browser/java/BUILD.gn
@@ -42,6 +42,7 @@ "//base:jni_java", "//components/embedder_support/android:application_java", "//content/public/android:content_java", + "//third_party/android_deps:com_android_support_support_compat_java", "//ui/android:ui_java", ] srcjar_deps = [ ":weblayer_locale_config" ]
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/BrowserControllerImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/BrowserControllerImpl.java index 0fec708..b5b0d23 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/BrowserControllerImpl.java +++ b/weblayer/browser/java/org/chromium/weblayer_private/BrowserControllerImpl.java
@@ -18,8 +18,8 @@ import org.chromium.base.annotations.NativeMethods; import org.chromium.content_public.browser.ViewEventSink; import org.chromium.content_public.browser.WebContents; -import org.chromium.ui.base.ActivityWindowAndroid; import org.chromium.ui.base.ViewAndroidDelegate; +import org.chromium.ui.base.WindowAndroid; import org.chromium.weblayer_private.aidl.IBrowserController; import org.chromium.weblayer_private.aidl.IBrowserControllerClient; import org.chromium.weblayer_private.aidl.IDownloadDelegateClient; @@ -32,9 +32,8 @@ public final class BrowserControllerImpl extends IBrowserController.Stub { private long mNativeBrowserController; - // TODO: move mWindowAndroid, mContentViewRenderView, mContentView, mTopControlsContainerView to + // TODO: move mContentViewRenderView, mContentView, mTopControlsContainerView to // BrowserFragmentControllerImpl. - private ActivityWindowAndroid mWindowAndroid; // This view is the main view (returned from the fragment's onCreateView()). private ContentViewRenderView mContentViewRenderView; // One of these is needed per WebContents. @@ -69,17 +68,14 @@ public void onScrollChanged(int lPix, int tPix, int oldlPix, int oldtPix) {} } - public BrowserControllerImpl(Context context, ProfileImpl profile) { + public BrowserControllerImpl( + Context context, ProfileImpl profile, WindowAndroid windowAndroid) { mProfile = profile; - // Use false to disable listening to activity state. - // TODO: this should *not* use ActivityWindowAndroid as that relies on Activity, and this - // code should not assume it is supplied an Activity. - mWindowAndroid = new ActivityWindowAndroid(context, false); mContentViewRenderView = new ContentViewRenderView(context); mContentViewRenderView.onNativeLibraryLoaded( - mWindowAndroid, ContentViewRenderView.MODE_SURFACE_VIEW); + windowAndroid, ContentViewRenderView.MODE_SURFACE_VIEW); mNativeBrowserController = BrowserControllerImplJni.get().createBrowserController(profile.getNativeProfile()); @@ -97,7 +93,7 @@ } }; mWebContents.initialize("", viewAndroidDelegate, new InternalAccessDelegateImpl(), - mWindowAndroid, WebContents.createDefaultInternalsHolder()); + windowAndroid, WebContents.createDefaultInternalsHolder()); mContentViewRenderView.setCurrentWebContents(mWebContents);
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/BrowserFragmentControllerImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/BrowserFragmentControllerImpl.java index 48f6242..c5c2434 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/BrowserFragmentControllerImpl.java +++ b/weblayer/browser/java/org/chromium/weblayer_private/BrowserFragmentControllerImpl.java
@@ -5,9 +5,11 @@ package org.chromium.weblayer_private; import android.content.Context; +import android.content.Intent; import android.os.Bundle; import android.view.View; +import org.chromium.ui.base.ActivityWindowAndroid; import org.chromium.weblayer_private.aidl.IBrowserFragmentController; import org.chromium.weblayer_private.aidl.IObjectWrapper; import org.chromium.weblayer_private.aidl.IProfile; @@ -18,19 +20,28 @@ public class BrowserFragmentControllerImpl extends IBrowserFragmentController.Stub { private final ProfileImpl mProfile; private BrowserControllerImpl mTabController; + private ActivityWindowAndroid mWindowAndroid; public BrowserFragmentControllerImpl(ProfileImpl profile, Bundle savedInstanceState) { mProfile = profile; // Restore tabs etc from savedInstanceState here. } - public void onFragmentAttached(Context context) { - mTabController = new BrowserControllerImpl(context, mProfile); + public void onFragmentAttached(Context context, ActivityWindowAndroid windowAndroid) { + mTabController = new BrowserControllerImpl(context, mProfile, windowAndroid); + mWindowAndroid = windowAndroid; } public void onFragmentDetached() { mTabController.destroy(); mTabController = null; + mWindowAndroid = null; + } + + public void onActivityResult(int requestCode, int resultCode, Intent data) { + if (mWindowAndroid != null) { + mWindowAndroid.onActivityResult(requestCode, resultCode, data); + } } @Override
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/BrowserFragmentImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/BrowserFragmentImpl.java index 1476def..58c36f2 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/BrowserFragmentImpl.java +++ b/weblayer/browser/java/org/chromium/weblayer_private/BrowserFragmentImpl.java
@@ -5,9 +5,12 @@ package org.chromium.weblayer_private; import android.content.Context; +import android.content.Intent; +import android.content.IntentSender; import android.os.Bundle; import android.view.View; +import org.chromium.ui.base.ActivityWindowAndroid; import org.chromium.weblayer_private.aidl.BrowserFragmentArgs; import org.chromium.weblayer_private.aidl.IBrowserFragment; import org.chromium.weblayer_private.aidl.IBrowserFragmentController; @@ -21,6 +24,29 @@ private BrowserFragmentControllerImpl mController; private Context mContext; + // TODO(cduvall): Factor out the logic we need from ActivityWindowAndroid so we do not inherit + // directly from it. + private static class FragmentWindowAndroid extends ActivityWindowAndroid { + private BrowserFragmentImpl mFragment; + + FragmentWindowAndroid(Context context, BrowserFragmentImpl fragment) { + // Use false to disable listening to activity state. + super(context, false); + mFragment = fragment; + } + + @Override + protected boolean startIntentSenderForResult(IntentSender intentSender, int requestCode) { + return mFragment.startIntentSenderForResult( + intentSender, requestCode, new Intent(), 0, 0, 0, null); + } + + @Override + protected boolean startActivityForResult(Intent intent, int requestCode) { + return mFragment.startActivityForResult(intent, requestCode, null); + } + } + public BrowserFragmentImpl(ProfileManager profileManager, IRemoteFragmentClient client, Bundle fragmentArgs) { super(client); @@ -33,7 +59,7 @@ super.onAttach(context); mContext = context; if (mController != null) { // On first creation, onAttach is called before onCreate - mController.onFragmentAttached(context); + mController.onFragmentAttached(context, new FragmentWindowAndroid(context, this)); } } @@ -42,7 +68,7 @@ super.onCreate(savedInstanceState); mController = new BrowserFragmentControllerImpl(mProfile, savedInstanceState); if (mContext != null) { - mController.onFragmentAttached(mContext); + mController.onFragmentAttached(mContext, new FragmentWindowAndroid(mContext, this)); } } @@ -52,6 +78,11 @@ } @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + mController.onActivityResult(requestCode, resultCode, data); + } + + @Override public void onDestroy() { super.onDestroy(); mController.destroy();
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/BrowserObserverProxy.java b/weblayer/browser/java/org/chromium/weblayer_private/BrowserObserverProxy.java index 95e37f9..3425109 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/BrowserObserverProxy.java +++ b/weblayer/browser/java/org/chromium/weblayer_private/BrowserObserverProxy.java
@@ -9,7 +9,6 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.NativeMethods; -import org.chromium.weblayer_private.aidl.APICallException; import org.chromium.weblayer_private.aidl.IBrowserControllerClient; /** @@ -34,30 +33,19 @@ } @CalledByNative - private void visibleUrlChanged(String string) { - try { - mClient.visibleUrlChanged(string); - } catch (RemoteException e) { - throw new APICallException(e); - } + private void visibleUrlChanged(String string) throws RemoteException { + mClient.visibleUrlChanged(string); } @CalledByNative - private void loadingStateChanged(boolean isLoading, boolean toDifferentDocument) { - try { - mClient.loadingStateChanged(isLoading, toDifferentDocument); - } catch (RemoteException e) { - throw new APICallException(e); - } + private void loadingStateChanged(boolean isLoading, boolean toDifferentDocument) + throws RemoteException { + mClient.loadingStateChanged(isLoading, toDifferentDocument); } @CalledByNative - private void loadProgressChanged(double progress) { - try { - mClient.loadProgressChanged(progress); - } catch (RemoteException e) { - throw new APICallException(e); - } + private void loadProgressChanged(double progress) throws RemoteException { + mClient.loadProgressChanged(progress); } @NativeMethods
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/DownloadDelegateProxy.java b/weblayer/browser/java/org/chromium/weblayer_private/DownloadDelegateProxy.java index 2bb5bc3..c8ca6ce 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/DownloadDelegateProxy.java +++ b/weblayer/browser/java/org/chromium/weblayer_private/DownloadDelegateProxy.java
@@ -9,7 +9,6 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.NativeMethods; -import org.chromium.weblayer_private.aidl.APICallException; import org.chromium.weblayer_private.aidl.IDownloadDelegateClient; /** @@ -41,12 +40,8 @@ @CalledByNative private void downloadRequested(String url, String userAgent, String contentDisposition, - String mimetype, long contentLength) { - try { - mClient.downloadRequested(url, userAgent, contentDisposition, mimetype, contentLength); - } catch (RemoteException e) { - throw new APICallException(e); - } + String mimetype, long contentLength) throws RemoteException { + mClient.downloadRequested(url, userAgent, contentDisposition, mimetype, contentLength); } @NativeMethods
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/FullscreenDelegateProxy.java b/weblayer/browser/java/org/chromium/weblayer_private/FullscreenDelegateProxy.java index 3da597a..18d4e10 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/FullscreenDelegateProxy.java +++ b/weblayer/browser/java/org/chromium/weblayer_private/FullscreenDelegateProxy.java
@@ -10,7 +10,6 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.NativeMethods; -import org.chromium.weblayer_private.aidl.APICallException; import org.chromium.weblayer_private.aidl.IFullscreenDelegateClient; import org.chromium.weblayer_private.aidl.ObjectWrapper; @@ -44,31 +43,23 @@ } @CalledByNative - private void enterFullscreen() { - try { - ValueCallback<Void> exitFullscreenCallback = new ValueCallback<Void>() { - @Override - public void onReceiveValue(Void result) { - if (mNativeFullscreenDelegateProxy == 0) { - throw new IllegalStateException("Called after destroy()"); - } - FullscreenDelegateProxyJni.get().doExitFullscreen( - mNativeFullscreenDelegateProxy, FullscreenDelegateProxy.this); + private void enterFullscreen() throws RemoteException { + ValueCallback<Void> exitFullscreenCallback = new ValueCallback<Void>() { + @Override + public void onReceiveValue(Void result) { + if (mNativeFullscreenDelegateProxy == 0) { + throw new IllegalStateException("Called after destroy()"); } - }; - mClient.enterFullscreen(ObjectWrapper.wrap(exitFullscreenCallback)); - } catch (RemoteException e) { - throw new APICallException(e); - } + FullscreenDelegateProxyJni.get().doExitFullscreen( + mNativeFullscreenDelegateProxy, FullscreenDelegateProxy.this); + } + }; + mClient.enterFullscreen(ObjectWrapper.wrap(exitFullscreenCallback)); } @CalledByNative - private void exitFullscreen() { - try { - mClient.exitFullscreen(); - } catch (RemoteException e) { - throw new APICallException(e); - } + private void exitFullscreen() throws RemoteException { + mClient.exitFullscreen(); } @NativeMethods
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/NavigationControllerImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/NavigationControllerImpl.java index 4977970..6dcb190 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/NavigationControllerImpl.java +++ b/weblayer/browser/java/org/chromium/weblayer_private/NavigationControllerImpl.java
@@ -9,7 +9,6 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.NativeMethods; -import org.chromium.weblayer_private.aidl.APICallException; import org.chromium.weblayer_private.aidl.INavigationController; import org.chromium.weblayer_private.aidl.INavigationControllerClient; @@ -98,57 +97,33 @@ } @CalledByNative - private void navigationStarted(NavigationImpl navigation) { - try { - mNavigationControllerClient.navigationStarted(navigation.getClientNavigation()); - } catch (RemoteException e) { - throw new APICallException(e); - } + private void navigationStarted(NavigationImpl navigation) throws RemoteException { + mNavigationControllerClient.navigationStarted(navigation.getClientNavigation()); } @CalledByNative - private void navigationRedirected(NavigationImpl navigation) { - try { - mNavigationControllerClient.navigationRedirected(navigation.getClientNavigation()); - } catch (RemoteException e) { - throw new APICallException(e); - } + private void navigationRedirected(NavigationImpl navigation) throws RemoteException { + mNavigationControllerClient.navigationRedirected(navigation.getClientNavigation()); } @CalledByNative - private void navigationCommitted(NavigationImpl navigation) { - try { - mNavigationControllerClient.navigationCommitted(navigation.getClientNavigation()); - } catch (RemoteException e) { - throw new APICallException(e); - } + private void navigationCommitted(NavigationImpl navigation) throws RemoteException { + mNavigationControllerClient.navigationCommitted(navigation.getClientNavigation()); } @CalledByNative - private void navigationCompleted(NavigationImpl navigation) { - try { - mNavigationControllerClient.navigationCompleted(navigation.getClientNavigation()); - } catch (RemoteException e) { - throw new APICallException(e); - } + private void navigationCompleted(NavigationImpl navigation) throws RemoteException { + mNavigationControllerClient.navigationCompleted(navigation.getClientNavigation()); } @CalledByNative - private void navigationFailed(NavigationImpl navigation) { - try { - mNavigationControllerClient.navigationFailed(navigation.getClientNavigation()); - } catch (RemoteException e) { - throw new APICallException(e); - } + private void navigationFailed(NavigationImpl navigation) throws RemoteException { + mNavigationControllerClient.navigationFailed(navigation.getClientNavigation()); } @CalledByNative - private void onFirstContentfulPaint() { - try { - mNavigationControllerClient.onFirstContentfulPaint(); - } catch (RemoteException e) { - throw new APICallException(e); - } + private void onFirstContentfulPaint() throws RemoteException { + mNavigationControllerClient.onFirstContentfulPaint(); } @NativeMethods
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/RemoteFragmentImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/RemoteFragmentImpl.java index 585e1d4..cd854a4 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/RemoteFragmentImpl.java +++ b/weblayer/browser/java/org/chromium/weblayer_private/RemoteFragmentImpl.java
@@ -6,6 +6,8 @@ import android.app.Activity; import android.content.Context; +import android.content.Intent; +import android.content.IntentSender; import android.os.Bundle; import android.os.RemoteException; import android.view.View; @@ -65,6 +67,8 @@ } } + public void onActivityResult(int requestCode, int resultCode, Intent data) {} + public void onStart() { try { mClient.superOnStart(); @@ -129,6 +133,26 @@ } } + public boolean startActivityForResult(Intent intent, int requestCode, Bundle options) { + try { + return mClient.startActivityForResult( + ObjectWrapper.wrap(intent), requestCode, ObjectWrapper.wrap(options)); + } catch (RemoteException e) { + throw new APICallException(e); + } + } + + public boolean startIntentSenderForResult(IntentSender intent, int requestCode, + Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options) { + try { + return mClient.startIntentSenderForResult(ObjectWrapper.wrap(intent), requestCode, + ObjectWrapper.wrap(fillInIntent), flagsMask, flagsValues, extraFlags, + ObjectWrapper.wrap(options)); + } catch (RemoteException e) { + throw new APICallException(e); + } + } + // IRemoteFragment implementation below. @Override @@ -190,4 +214,9 @@ public final void handleOnSaveInstanceState(IObjectWrapper outState) { onSaveInstaceState(ObjectWrapper.unwrap(outState, Bundle.class)); } + + @Override + public final void handleOnActivityResult(int requestCode, int resultCode, IObjectWrapper data) { + onActivityResult(requestCode, resultCode, ObjectWrapper.unwrap(data, Intent.class)); + } }
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java index 5221f9d9..b203cb4 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java +++ b/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java
@@ -5,11 +5,14 @@ package org.chromium.weblayer_private; import android.content.Context; +import android.net.Uri; import android.os.Bundle; import android.os.IBinder; +import android.support.v4.content.FileProvider; import android.webkit.ValueCallback; import org.chromium.base.CommandLine; +import org.chromium.base.ContentUriUtils; import org.chromium.base.ContextUtils; import org.chromium.base.PathUtils; import org.chromium.base.annotations.UsedByReflection; @@ -27,6 +30,8 @@ import org.chromium.weblayer_private.aidl.ObjectWrapper; import org.chromium.weblayer_private.aidl.WebLayerVersion; +import java.io.File; + @UsedByReflection("WebLayer") public final class WebLayerImpl extends IWebLayer.Stub { // TODO: should there be one tag for all this code? @@ -37,6 +42,17 @@ private final ProfileManager mProfileManager = new ProfileManager(); + private static class FileProviderHelper implements ContentUriUtils.FileProviderUtil { + // Keep this variable in sync with the value defined in AndroidManifest.xml. + private static final String API_AUTHORITY = "org.chromium.weblayer.client.FileProvider"; + + @Override + public Uri getContentUriFromFile(File file) { + Context appContext = ContextUtils.getApplicationContext(); + return FileProvider.getUriForFile(appContext, API_AUTHORITY, file); + } + } + @UsedByReflection("WebLayer") public static IBinder create() { return new WebLayerImpl(); @@ -78,6 +94,7 @@ } DeviceUtils.addDeviceSpecificUserAgentSwitch(); + ContentUriUtils.setFileProviderUtil(new FileProviderHelper()); LibraryLoader.getInstance().ensureInitialized(LibraryProcessType.PROCESS_WEBLAYER);
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/aidl/IRemoteFragment.aidl b/weblayer/browser/java/org/chromium/weblayer_private/aidl/IRemoteFragment.aidl index ed2eede0..7c50edd7 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/aidl/IRemoteFragment.aidl +++ b/weblayer/browser/java/org/chromium/weblayer_private/aidl/IRemoteFragment.aidl
@@ -20,4 +20,8 @@ void handleOnDetach() = 9; void handleOnDestroy() = 10; void handleOnSaveInstanceState(in IObjectWrapper outState) = 11; + // |data| is an Intent with the result returned from the activity. + void handleOnActivityResult(int requestCode, + int resultCode, + in IObjectWrapper data) = 12; }
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/aidl/IRemoteFragmentClient.aidl b/weblayer/browser/java/org/chromium/weblayer_private/aidl/IRemoteFragmentClient.aidl index fbc69cb0..82ec6b0 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/aidl/IRemoteFragmentClient.aidl +++ b/weblayer/browser/java/org/chromium/weblayer_private/aidl/IRemoteFragmentClient.aidl
@@ -18,4 +18,14 @@ void superOnSaveInstanceState(in IObjectWrapper outState) = 10; IObjectWrapper getActivity() = 11; + boolean startActivityForResult(in IObjectWrapper intent, + int requestCode, + in IObjectWrapper options) = 12; + boolean startIntentSenderForResult(in IObjectWrapper intent, + int requestCode, + in IObjectWrapper fillInIntent, + int flagsMask, + int flagsValues, + int extraFlags, + in IObjectWrapper options) = 13; }
diff --git a/weblayer/public/java/AndroidManifest.xml b/weblayer/public/java/AndroidManifest.xml index a157b2f..ae3d86d 100644 --- a/weblayer/public/java/AndroidManifest.xml +++ b/weblayer/public/java/AndroidManifest.xml
@@ -44,5 +44,13 @@ android:isolatedProcess="false" android:exported="false" /> {% endfor %} + + <provider android:name="android.support.v4.content.FileProvider" + android:authorities="org.chromium.weblayer.client.FileProvider" + android:exported="false" + android:grantUriPermissions="true"> + <meta-data android:name="android.support.FILE_PROVIDER_PATHS" + android:resource="@xml/file_paths" /> + </provider> </application> </manifest>
diff --git a/weblayer/public/java/BUILD.gn b/weblayer/public/java/BUILD.gn index 8f39bc6..7cb4a4f 100644 --- a/weblayer/public/java/BUILD.gn +++ b/weblayer/public/java/BUILD.gn
@@ -14,7 +14,7 @@ } android_resources("client_resources") { - resource_dirs = [] + resource_dirs = [ "res" ] android_manifest = weblayer_client_manifest android_manifest_dep = ":weblayer_client_manifest" } @@ -43,6 +43,8 @@ ] deps = [ + ":weblayer_client_manifest", + "//third_party/android_deps:androidx_annotation_annotation_java", "//third_party/android_deps:com_android_support_support_fragment_java", "//weblayer/browser/java:client_java", ] @@ -51,6 +53,8 @@ # Needed for android.webkit.WebViewDelegate. alternative_android_sdk_dep = "//third_party/android_sdk:public_framework_system_java" + + android_manifest_for_lint = weblayer_client_manifest } }
diff --git a/weblayer/public/java/org/chromium/weblayer/BrowserController.java b/weblayer/public/java/org/chromium/weblayer/BrowserController.java index e229ead..ea3bb7b 100644 --- a/weblayer/public/java/org/chromium/weblayer/BrowserController.java +++ b/weblayer/public/java/org/chromium/weblayer/BrowserController.java
@@ -8,6 +8,9 @@ import android.os.RemoteException; import android.webkit.ValueCallback; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import org.json.JSONException; import org.json.JSONObject; @@ -19,6 +22,10 @@ import org.chromium.weblayer_private.aidl.IObjectWrapper; import org.chromium.weblayer_private.aidl.ObjectWrapper; +/** + * Represents a web-browser. More specifically, owns a NavigationController, and allows configuring + * state of the browser, such as delegates and observers. + */ public final class BrowserController { /** The top level key of the JSON object returned by executeScript(). */ public static final String SCRIPT_RESULT_KEY = "result"; @@ -41,7 +48,7 @@ mNavigationController = NavigationController.create(mImpl); } - public void setDownloadDelegate(DownloadDelegate delegate) { + public void setDownloadDelegate(@Nullable DownloadDelegate delegate) { try { if (delegate != null) { mDownloadDelegateClient = new DownloadDelegateClientImpl(delegate); @@ -55,7 +62,7 @@ } } - public void setFullscreenDelegate(FullscreenDelegate delegate) { + public void setFullscreenDelegate(@Nullable FullscreenDelegate delegate) { try { if (delegate != null) { mFullscreenDelegateClient = new FullscreenDelegateClientImpl(delegate); @@ -78,7 +85,8 @@ * callback if provided. The object passed to the callback will have a single key * SCRIPT_RESULT_KEY which will hold the result of running the script. */ - public void executeScript(String script, ValueCallback<JSONObject> callback) { + public void executeScript( + @NonNull String script, @Nullable ValueCallback<JSONObject> callback) { try { ValueCallback<String> stringCallback = (String result) -> { if (callback == null) { @@ -99,6 +107,7 @@ } } + @Nullable public FullscreenDelegate getFullscreenDelegate() { return mFullscreenDelegateClient != null ? mFullscreenDelegateClient.getDelegate() : null; } @@ -108,15 +117,16 @@ // TODO(sky): figure out right assertion here if mProfile is non-null. } + @NonNull public NavigationController getNavigationController() { return mNavigationController; } - public void addObserver(BrowserObserver observer) { + public void addObserver(@Nullable BrowserObserver observer) { mObservers.addObserver(observer); } - public void removeObserver(BrowserObserver observer) { + public void removeObserver(@Nullable BrowserObserver observer) { mObservers.removeObserver(observer); }
diff --git a/weblayer/public/java/org/chromium/weblayer/BrowserFragment.java b/weblayer/public/java/org/chromium/weblayer/BrowserFragment.java index 05db0e2..3156d03 100644 --- a/weblayer/public/java/org/chromium/weblayer/BrowserFragment.java +++ b/weblayer/public/java/org/chromium/weblayer/BrowserFragment.java
@@ -4,7 +4,11 @@ package org.chromium.weblayer; +import android.content.ActivityNotFoundException; import android.content.Context; +import android.content.Intent; +import android.content.IntentSender; +import android.content.IntentSender.SendIntentException; import android.os.Bundle; import android.os.RemoteException; import android.support.v4.app.Fragment; @@ -12,6 +16,8 @@ import android.view.View; import android.view.ViewGroup; +import androidx.annotation.NonNull; + import org.chromium.weblayer_private.aidl.APICallException; import org.chromium.weblayer_private.aidl.IBrowserFragment; import org.chromium.weblayer_private.aidl.IObjectWrapper; @@ -96,6 +102,34 @@ public IObjectWrapper getActivity() { return ObjectWrapper.wrap(BrowserFragment.this.getActivity()); } + + @Override + public boolean startActivityForResult( + IObjectWrapper intent, int requestCode, IObjectWrapper options) { + try { + BrowserFragment.this.startActivityForResult( + ObjectWrapper.unwrap(intent, Intent.class), requestCode, + ObjectWrapper.unwrap(options, Bundle.class)); + } catch (ActivityNotFoundException e) { + return false; + } + return true; + } + + @Override + public boolean startIntentSenderForResult(IObjectWrapper intent, int requestCode, + IObjectWrapper fillInIntent, int flagsMask, int flagsValues, int extraFlags, + IObjectWrapper options) { + try { + BrowserFragment.this.startIntentSenderForResult( + ObjectWrapper.unwrap(intent, IntentSender.class), requestCode, + ObjectWrapper.unwrap(fillInIntent, Intent.class), flagsMask, flagsValues, + extraFlags, ObjectWrapper.unwrap(options, Bundle.class)); + } catch (SendIntentException e) { + return false; + } + return true; + } }; // Nonnull after first onAttach(). @@ -117,6 +151,7 @@ * Returns the {@link BrowserFragmentController} associated with this fragment. * The controller is available only between BrowserFragment's onCreate() and onDestroy(). */ + @NonNull public BrowserFragmentController getController() { if (mBrowserFragmentController == null) { throw new RuntimeException("BrowserFragmentController is available only between " @@ -125,6 +160,16 @@ return mBrowserFragmentController; } + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + try { + mImpl.asRemoteFragment().handleOnActivityResult( + requestCode, resultCode, ObjectWrapper.wrap(data)); + } catch (RemoteException e) { + throw new APICallException(e); + } + } + @SuppressWarnings("MissingSuperCall") @Override public void onAttach(Context context) {
diff --git a/weblayer/public/java/org/chromium/weblayer/BrowserFragmentController.java b/weblayer/public/java/org/chromium/weblayer/BrowserFragmentController.java index 95464fd8..ea61c7b 100644 --- a/weblayer/public/java/org/chromium/weblayer/BrowserFragmentController.java +++ b/weblayer/public/java/org/chromium/weblayer/BrowserFragmentController.java
@@ -8,6 +8,9 @@ import android.view.View; import android.webkit.ValueCallback; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import org.chromium.weblayer_private.aidl.APICallException; import org.chromium.weblayer_private.aidl.IBrowserFragmentController; import org.chromium.weblayer_private.aidl.ObjectWrapper; @@ -27,6 +30,7 @@ } // TODO(pshmakov): rename this to BrowserTabController. + @NonNull public BrowserController getBrowserController() { if (mController == null) { try { @@ -38,7 +42,7 @@ return mController; } - public void setTopView(View view) { + public void setTopView(@Nullable View view) { try { mImpl.setTopView(ObjectWrapper.wrap(view)); } catch (RemoteException e) { @@ -55,6 +59,7 @@ * @return a ListenableResult of whether the request succeeded. A request might fail if it is * subsumed by a subsequent request, or if this object is destroyed. */ + @NonNull public ListenableResult<Boolean> setSupportsEmbedding(boolean enable) { try { final ListenableResult<Boolean> listenableResult = new ListenableResult<Boolean>(); @@ -75,6 +80,7 @@ * Returns {@link Profile} associated with this Browser Fragment. Multiple fragments can share * the same Profile. */ + @NonNull public Profile getProfile() { try { return mProfileManager.getProfileFor(mImpl.getProfile());
diff --git a/weblayer/public/java/org/chromium/weblayer/BrowserObserver.java b/weblayer/public/java/org/chromium/weblayer/BrowserObserver.java index 3bf1015..cb214160 100644 --- a/weblayer/public/java/org/chromium/weblayer/BrowserObserver.java +++ b/weblayer/public/java/org/chromium/weblayer/BrowserObserver.java
@@ -6,6 +6,8 @@ import android.net.Uri; +import androidx.annotation.NonNull; + /** * Informed of interesting events that happen during the lifetime of a BrowserController. */ @@ -15,7 +17,7 @@ * * @param url The new user-visible url. */ - public void visibleUrlChanged(Uri url) {} + public void visibleUrlChanged(@NonNull Uri url) {} /** * The load state of the document has changed.
diff --git a/weblayer/public/java/org/chromium/weblayer/DownloadDelegate.java b/weblayer/public/java/org/chromium/weblayer/DownloadDelegate.java index 7ba737e..1ef6642 100644 --- a/weblayer/public/java/org/chromium/weblayer/DownloadDelegate.java +++ b/weblayer/public/java/org/chromium/weblayer/DownloadDelegate.java
@@ -4,6 +4,8 @@ package org.chromium.weblayer; +import androidx.annotation.NonNull; + /** * An interface that allows clients to handle download requests originating in the browser. */ @@ -17,6 +19,6 @@ * @param mimetype the mimetype of the content reported by the server * @param contentLength the file size reported by the server */ - public abstract void downloadRequested(String url, String userAgent, String contentDisposition, - String mimetype, long contentLength); + public abstract void downloadRequested(@NonNull String url, @NonNull String userAgent, + @NonNull String contentDisposition, @NonNull String mimetype, long contentLength); }
diff --git a/weblayer/public/java/org/chromium/weblayer/FullscreenDelegate.java b/weblayer/public/java/org/chromium/weblayer/FullscreenDelegate.java index 7de84fce..a1250c42 100644 --- a/weblayer/public/java/org/chromium/weblayer/FullscreenDelegate.java +++ b/weblayer/public/java/org/chromium/weblayer/FullscreenDelegate.java
@@ -4,6 +4,8 @@ package org.chromium.weblayer; +import androidx.annotation.NonNull; + /** * Used to configure fullscreen related state. HTML fullscreen support is only enabled if a * FullscreenDelegate is set. @@ -17,7 +19,7 @@ * * NOTE: the Runnable must not be used synchronously. */ - public abstract void enterFullscreen(Runnable exitFullscreenRunner); + public abstract void enterFullscreen(@NonNull Runnable exitFullscreenRunner); /** * The page has exited fullscreen mode and the system should be moved out of fullscreen mode.
diff --git a/weblayer/public/java/org/chromium/weblayer/ListenableResult.java b/weblayer/public/java/org/chromium/weblayer/ListenableResult.java index 037c1f3..860b3f8 100644 --- a/weblayer/public/java/org/chromium/weblayer/ListenableResult.java +++ b/weblayer/public/java/org/chromium/weblayer/ListenableResult.java
@@ -4,6 +4,8 @@ package org.chromium.weblayer; +import androidx.annotation.NonNull; + import java.util.ArrayList; /** @@ -21,7 +23,7 @@ * Call the callback with the result of computation. * Note callback may be called immediately. */ - public void addCallback(Callback<V> callback) { + public void addCallback(@NonNull Callback<V> callback) { if (mHasResult) { callback.onResult(mResult); return;
diff --git a/weblayer/public/java/org/chromium/weblayer/Navigation.java b/weblayer/public/java/org/chromium/weblayer/Navigation.java index 2c8544d..8d965ea 100644 --- a/weblayer/public/java/org/chromium/weblayer/Navigation.java +++ b/weblayer/public/java/org/chromium/weblayer/Navigation.java
@@ -7,6 +7,8 @@ import android.net.Uri; import android.os.RemoteException; +import androidx.annotation.NonNull; + import org.chromium.weblayer_private.aidl.APICallException; import org.chromium.weblayer_private.aidl.IClientNavigation; import org.chromium.weblayer_private.aidl.INavigation; @@ -58,6 +60,7 @@ * The uri the main frame is navigating to. This may change during the navigation when * encountering a server redirect. */ + @NonNull public Uri getUri() { try { return Uri.parse(mNavigationImpl.getUri()); @@ -70,6 +73,7 @@ * Returns the redirects that occurred on the way to the current page. The current page is the * last one in the list (so even when there's no redirect, there will be one entry in the list). */ + @NonNull public List<Uri> getRedirectChain() { try { List<Uri> redirects = new ArrayList<Uri>();
diff --git a/weblayer/public/java/org/chromium/weblayer/NavigationController.java b/weblayer/public/java/org/chromium/weblayer/NavigationController.java index 18ba245..98f71b4 100644 --- a/weblayer/public/java/org/chromium/weblayer/NavigationController.java +++ b/weblayer/public/java/org/chromium/weblayer/NavigationController.java
@@ -7,6 +7,8 @@ import android.net.Uri; import android.os.RemoteException; +import androidx.annotation.NonNull; + import org.chromium.weblayer_private.aidl.APICallException; import org.chromium.weblayer_private.aidl.IBrowserController; import org.chromium.weblayer_private.aidl.IClientNavigation; @@ -37,7 +39,7 @@ mObservers = new ObserverList<NavigationObserver>(); } - public void navigate(Uri uri) { + public void navigate(@NonNull Uri uri) { try { mNavigationController.navigate(uri.toString()); } catch (RemoteException e) { @@ -109,6 +111,7 @@ } } + @NonNull public Uri getNavigationEntryDisplayUri(int index) { try { return Uri.parse(mNavigationController.getNavigationEntryDisplayUri(index)); @@ -117,11 +120,11 @@ } } - public void addObserver(NavigationObserver observer) { + public void addObserver(@NonNull NavigationObserver observer) { mObservers.addObserver(observer); } - public void removeObserver(NavigationObserver observer) { + public void removeObserver(@NonNull NavigationObserver observer) { mObservers.removeObserver(observer); }
diff --git a/weblayer/public/java/org/chromium/weblayer/NavigationObserver.java b/weblayer/public/java/org/chromium/weblayer/NavigationObserver.java index ec6396c4..3698dc2 100644 --- a/weblayer/public/java/org/chromium/weblayer/NavigationObserver.java +++ b/weblayer/public/java/org/chromium/weblayer/NavigationObserver.java
@@ -4,6 +4,8 @@ package org.chromium.weblayer; +import androidx.annotation.NonNull; + /** * Informed of interesting events that happen during the lifetime of NavigationController. This * interface is only notified of main frame navigations. @@ -37,14 +39,14 @@ * * @param navigation the unique object for this navigation. */ - public void navigationStarted(Navigation navigation) {} + public void navigationStarted(@NonNull Navigation navigation) {} /** * Called when a navigation encountered a server redirect. * * @param navigation the unique object for this navigation. */ - public void navigationRedirected(Navigation navigation) {} + public void navigationRedirected(@NonNull Navigation navigation) {} /** * Called when the navigation is ready to be committed in a renderer. A navigation is considered @@ -59,7 +61,7 @@ * * @param navigation the unique object for this navigation. */ - public void navigationCommitted(Navigation navigation) {} + public void navigationCommitted(@NonNull Navigation navigation) {} /** * Called when a navigation completes successfully in the BrowserController. @@ -77,7 +79,7 @@ * * @param navigation the unique object for this navigation. */ - public void navigationCompleted(Navigation navigation) {} + public void navigationCompleted(@NonNull Navigation navigation) {} /** * Called when a navigation aborts in the BrowserController. @@ -87,7 +89,7 @@ * * @param navigation the unique object for this navigation. */ - public void navigationFailed(Navigation navigation) {} + public void navigationFailed(@NonNull Navigation navigation) {} /** * This is fired after each navigation has completed to indicate that the first paint after a
diff --git a/weblayer/public/java/org/chromium/weblayer/WebLayer.java b/weblayer/public/java/org/chromium/weblayer/WebLayer.java index 590bc40..ca19f864 100644 --- a/weblayer/public/java/org/chromium/weblayer/WebLayer.java +++ b/weblayer/public/java/org/chromium/weblayer/WebLayer.java
@@ -16,6 +16,8 @@ import android.webkit.WebViewDelegate; import android.webkit.WebViewFactory; +import androidx.annotation.NonNull; + import org.chromium.weblayer_private.aidl.APICallException; import org.chromium.weblayer_private.aidl.BrowserFragmentArgs; import org.chromium.weblayer_private.aidl.IBrowserFragment; @@ -104,6 +106,7 @@ * @return a ListenableFuture whose value will contain the WebLayer once initialization * completes */ + @NonNull public static ListenableFuture<WebLayer> create(Context appContext) throws UnsupportedVersionException { if (sFuture == null) { @@ -182,6 +185,7 @@ mImpl = iWebLayer; } + @NonNull public static BrowserFragment createBrowserFragment(String profilePath) { // TODO: use a profile id instead of the path to the actual file. Bundle args = new Bundle();
diff --git a/weblayer/public/java/res/xml/file_paths.xml b/weblayer/public/java/res/xml/file_paths.xml new file mode 100644 index 0000000..ace2112 --- /dev/null +++ b/weblayer/public/java/res/xml/file_paths.xml
@@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. --> + +<!-- The attributes in this XML file provide configuration information --> +<!-- for the ContentProvider. --> + +<paths xmlns:android="http://schemas.android.com/apk/res/android"> + <files-path name="images" path="images/"/> +</paths>
diff --git a/weblayer/shell/android/BUILD.gn b/weblayer/shell/android/BUILD.gn index f774911..ac196a9 100644 --- a/weblayer/shell/android/BUILD.gn +++ b/weblayer/shell/android/BUILD.gn
@@ -262,10 +262,12 @@ "javatests/src/org/chromium/weblayer/test/FullscreenDelegateTest.java", "javatests/src/org/chromium/weblayer/test/NavigationTest.java", "javatests/src/org/chromium/weblayer/test/SmokeTest.java", + "javatests/src/org/chromium/weblayer/test/EventUtils.java", "javatests/src/org/chromium/weblayer/test/ExecuteScriptTest.java", "javatests/src/org/chromium/weblayer/test/RenderingTest.java", "javatests/src/org/chromium/weblayer/test/WebLayerShellActivityTestRule.java", "javatests/src/org/chromium/weblayer/test/FragmentRestoreTest.java", + "javatests/src/org/chromium/weblayer/test/FileInputTest.java", "shell_apk/src/org/chromium/weblayer/shell/WebLayerShellActivity.java", ] additional_apks = [
diff --git a/weblayer/shell/android/javatests/AndroidManifest.xml b/weblayer/shell/android/javatests/AndroidManifest.xml index b53d494c..d2bdfc7 100644 --- a/weblayer/shell/android/javatests/AndroidManifest.xml +++ b/weblayer/shell/android/javatests/AndroidManifest.xml
@@ -16,6 +16,17 @@ <uses-library android:name="android.test.runner" /> <activity android:name="org.chromium.test.broker.OnDeviceInstrumentationBroker" android:exported="true"/> + <activity android:name="org.chromium.weblayer.shell.WebLayerShellActivity"> + <!-- Add these intent filters so tests can resolve these intents. --> + <intent-filter> + <action android:name="android.provider.MediaStore.RECORD_SOUND" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + <intent-filter> + <action android:name="android.media.action.IMAGE_CAPTURE" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </activity> </application> <instrumentation android:name="org.chromium.base.test.BaseChromiumAndroidJUnitRunner"
diff --git a/weblayer/shell/android/javatests/src/org/chromium/weblayer/test/FileInputTest.java b/weblayer/shell/android/javatests/src/org/chromium/weblayer/test/FileInputTest.java new file mode 100644 index 0000000..bb6e846fb --- /dev/null +++ b/weblayer/shell/android/javatests/src/org/chromium/weblayer/test/FileInputTest.java
@@ -0,0 +1,224 @@ +// 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. + +package org.chromium.weblayer.test; + +import android.app.Activity; +import android.content.ClipData; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.provider.MediaStore; +import android.support.test.InstrumentationRegistry; +import android.support.test.filters.SmallTest; +import android.support.v4.app.Fragment; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.test.BaseJUnit4ClassRunner; +import org.chromium.base.test.util.CallbackHelper; +import org.chromium.content_public.browser.test.util.CriteriaHelper; +import org.chromium.net.test.EmbeddedTestServer; +import org.chromium.weblayer.shell.WebLayerShellActivity; + +import java.io.File; + +/** + * Tests that file inputs work as expected. + */ +@RunWith(BaseJUnit4ClassRunner.class) +public class FileInputTest { + @Rule + public WebLayerShellActivityTestRule mActivityTestRule = new WebLayerShellActivityTestRule(); + + private EmbeddedTestServer mTestServer; + private File mTempFile; + + private class FileIntentInterceptor implements WebLayerShellActivity.IntentInterceptor { + public Intent mLastIntent; + + private Intent mResponseIntent; + private int mResultCode = Activity.RESULT_CANCELED; + private CallbackHelper mCallbackHelper = new CallbackHelper(); + + @Override + public void interceptIntent( + Fragment fragment, Intent intent, int requestCode, Bundle options) { + new Handler().post(() -> { + fragment.onActivityResult(requestCode, mResultCode, mResponseIntent); + mLastIntent = intent; + mCallbackHelper.notifyCalled(); + }); + } + + public void waitForIntent() { + try { + mCallbackHelper.waitForCallback(0); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public void setResponse(int resultCode, Intent response) { + mResponseIntent = response; + mResultCode = resultCode; + } + } + + private FileIntentInterceptor mIntentInterceptor = new FileIntentInterceptor(); + + @Before + public void setUp() throws Exception { + mTestServer = new EmbeddedTestServer(); + mTestServer.initializeNative(InstrumentationRegistry.getInstrumentation().getContext(), + EmbeddedTestServer.ServerHTTPSSetting.USE_HTTP); + mTestServer.addDefaultHandlers("weblayer/test/data"); + Assert.assertTrue(mTestServer.start(0)); + + WebLayerShellActivity activity = + mActivityTestRule.launchShellWithUrl(mTestServer.getURL("/file_input.html")); + mTempFile = File.createTempFile("file", null); + activity.setIntentInterceptor(mIntentInterceptor); + + Intent response = new Intent(); + response.setData(Uri.fromFile(mTempFile)); + mIntentInterceptor.setResponse(Activity.RESULT_OK, response); + } + + @After + public void tearDown() { + mTempFile.delete(); + } + + @Test + @SmallTest + public void testFileInputBasic() { + String id = "input_file"; + + openInputWithId(id); + + Assert.assertFalse(getContentIntent().hasCategory(Intent.CATEGORY_OPENABLE)); + + waitForNumFiles(id, 1); + } + + @Test + @SmallTest + public void testFileInputCancel() { + String id = "input_file"; + + // First add a file. + openInputWithId(id); + waitForNumFiles(id, 1); + + // Now cancel the intent. + mIntentInterceptor.setResponse(Activity.RESULT_CANCELED, null); + openInputWithId(id); + waitForNumFiles(id, 0); + } + + @Test + @SmallTest + public void testFileInputText() { + String id = "input_text"; + + openInputWithId(id); + + Assert.assertTrue(getContentIntent().hasCategory(Intent.CATEGORY_OPENABLE)); + + waitForNumFiles(id, 1); + } + + @Test + @SmallTest + public void testFileInputAny() { + String id = "input_any"; + + openInputWithId(id); + + Assert.assertFalse(getContentIntent().hasCategory(Intent.CATEGORY_OPENABLE)); + + waitForNumFiles(id, 1); + } + + @Test + @SmallTest + public void testFileInputMultiple() throws Exception { + Intent response = new Intent(); + ClipData clipData = ClipData.newUri(mActivityTestRule.getActivity().getContentResolver(), + "uris", Uri.fromFile(mTempFile)); + File otherTempFile = File.createTempFile("file2", null); + clipData.addItem(new ClipData.Item(Uri.fromFile(otherTempFile))); + response.setClipData(clipData); + mIntentInterceptor.setResponse(Activity.RESULT_OK, response); + String id = "input_file_multiple"; + + openInputWithId(id); + + Intent contentIntent = getContentIntent(); + Assert.assertFalse(contentIntent.hasCategory(Intent.CATEGORY_OPENABLE)); + Assert.assertTrue(contentIntent.hasExtra(Intent.EXTRA_ALLOW_MULTIPLE)); + + waitForNumFiles(id, 2); + otherTempFile.delete(); + } + + @Test + @SmallTest + public void testFileInputImage() { + String id = "input_image"; + + openInputWithId(id); + + Assert.assertEquals( + MediaStore.ACTION_IMAGE_CAPTURE, mIntentInterceptor.mLastIntent.getAction()); + + waitForNumFiles(id, 1); + } + + @Test + @SmallTest + public void testFileInputAudio() { + String id = "input_audio"; + + openInputWithId(id); + + Assert.assertEquals(MediaStore.Audio.Media.RECORD_SOUND_ACTION, + mIntentInterceptor.mLastIntent.getAction()); + + waitForNumFiles(id, 1); + } + + private void openInputWithId(String id) { + // We need to click the input after user input, otherwise it won't open due to security + // policy. + mActivityTestRule.executeScriptSync( + "document.onclick = function() {document.getElementById('" + id + "').click()}"); + EventUtils.simulateTouchCenterOfView( + mActivityTestRule.getActivity().getWindow().getDecorView()); + mIntentInterceptor.waitForIntent(); + } + + private void waitForNumFiles(String id, int num) { + CriteriaHelper.pollInstrumentationThread(() -> { + return num + == mActivityTestRule.executeScriptAndExtractInt( + "document.getElementById('" + id + "').files.length"); + }); + } + + private Intent getContentIntent() { + Assert.assertEquals(Intent.ACTION_CHOOSER, mIntentInterceptor.mLastIntent.getAction()); + Intent contentIntent = + (Intent) mIntentInterceptor.mLastIntent.getParcelableExtra(Intent.EXTRA_INTENT); + Assert.assertNotNull(contentIntent); + return contentIntent; + } +}
diff --git a/weblayer/shell/android/javatests/src/org/chromium/weblayer/test/WebLayerShellActivityTestRule.java b/weblayer/shell/android/javatests/src/org/chromium/weblayer/test/WebLayerShellActivityTestRule.java index 7238e86..ec55d3a 100644 --- a/weblayer/shell/android/javatests/src/org/chromium/weblayer/test/WebLayerShellActivityTestRule.java +++ b/weblayer/shell/android/javatests/src/org/chromium/weblayer/test/WebLayerShellActivityTestRule.java
@@ -14,6 +14,7 @@ import android.support.test.InstrumentationRegistry; import android.support.test.rule.ActivityTestRule; +import org.json.JSONException; import org.json.JSONObject; import org.junit.Assert; @@ -182,4 +183,28 @@ } return callbackHelper.getResult(); } + + public int executeScriptAndExtractInt(String script) { + try { + return executeScriptSync(script).getInt(BrowserController.SCRIPT_RESULT_KEY); + } catch (JSONException e) { + throw new RuntimeException(e); + } + } + + public String executeScriptAndExtractString(String script) { + try { + return executeScriptSync(script).getString(BrowserController.SCRIPT_RESULT_KEY); + } catch (JSONException e) { + throw new RuntimeException(e); + } + } + + public boolean executeScriptAndExtractBoolean(String script) { + try { + return executeScriptSync(script).getBoolean(BrowserController.SCRIPT_RESULT_KEY); + } catch (JSONException e) { + throw new RuntimeException(e); + } + } }
diff --git a/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/WebLayerShellActivity.java b/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/WebLayerShellActivity.java index ec9ed77..0d4e6e0 100644 --- a/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/WebLayerShellActivity.java +++ b/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/WebLayerShellActivity.java
@@ -59,6 +59,7 @@ private int mMainViewId; private ViewGroup mTopContentsContainer; private BrowserFragment mFragment; + private IntentInterceptor mIntentInterceptor; public BrowserController getBrowserController() { return mBrowserController; @@ -68,6 +69,25 @@ return mBrowserFragmentController; } + /** Interface used to intercept intents for testing. */ + public static interface IntentInterceptor { + void interceptIntent(Fragment fragment, Intent intent, int requestCode, Bundle options); + } + + public void setIntentInterceptor(IntentInterceptor interceptor) { + mIntentInterceptor = interceptor; + } + + @Override + public void startActivityFromFragment( + Fragment fragment, Intent intent, int requestCode, Bundle options) { + if (mIntentInterceptor != null) { + mIntentInterceptor.interceptIntent(fragment, intent, requestCode, options); + return; + } + super.startActivityFromFragment(fragment, intent, requestCode, options); + } + @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState);
diff --git a/weblayer/test/data/file_input.html b/weblayer/test/data/file_input.html new file mode 100644 index 0000000..4fbde3d --- /dev/null +++ b/weblayer/test/data/file_input.html
@@ -0,0 +1,12 @@ +<html> + <body hidden> + <form action="about:blank"> + <input id="input_file" type="file" /> + <input id="input_text" type="file" accept="text/plain" /> + <input id="input_any" type="file" accept="*/*" /> + <input id="input_file_multiple" type="file" multiple /> + <input id="input_image" type="file" accept="image/*" capture /> + <input id="input_audio" type="file" accept="audio/*" capture /> + </form> + </body> +</html>