Display Cutout: Parse the 'viewport-fit' key
Parse the 'viewport-fit' key in the <meta> element and
store it on ViewportDescription.
BUG=838400
Change-Id: I0a037175791d4cfaadaa12dffa694eb92a60077d
Reviewed-on: https://chromium-review.googlesource.com/1036532
Reviewed-by: Stefan Zager <szager@chromium.org>
Commit-Queue: Becca Hughes <beccahughes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#555562}
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn
index 6aa98f9..3860c06 100644
--- a/third_party/blink/renderer/core/BUILD.gn
+++ b/third_party/blink/renderer/core/BUILD.gn
@@ -1835,6 +1835,7 @@
"html/html_image_element_test.cc",
"html/html_link_element_sizes_attribute_test.cc",
"html/html_link_element_test.cc",
+ "html/html_meta_element_test.cc",
"html/html_slot_element_test.cc",
"html/html_table_row_element_test.cc",
"html/image_document_test.cc",
diff --git a/third_party/blink/renderer/core/dom/viewport_description.h b/third_party/blink/renderer/core/dom/viewport_description.h
index f5ca6fc..44b0281 100644
--- a/third_party/blink/renderer/core/dom/viewport_description.h
+++ b/third_party/blink/renderer/core/dom/viewport_description.h
@@ -66,6 +66,20 @@
kTypeCount = 7
};
+ // Stores the different possible |viewport-fit| configurations.
+ enum class ViewportFit {
+ // No effect - the whole web page is viewable (default).
+ kAuto = 0,
+
+ // The initial layout viewport and the visual viewport are set to the
+ // largest rectangle which is inscribed in the display of the device.
+ kContain,
+
+ // The initial layout viewport and the visual viewport are set to the
+ // circumscribed rectangle of the physical screen of the device.
+ kCover,
+ };
+
enum {
kValueAuto = -1,
kValueDeviceWidth = -2,
@@ -118,6 +132,8 @@
bool max_zoom_is_explicit;
bool user_zoom_is_explicit;
+ ViewportFit viewport_fit = ViewportFit::kAuto;
+
bool operator==(const ViewportDescription& other) const {
// Used for figuring out whether to reset the viewport or not,
// thus we are not taking type into account.
@@ -131,7 +147,8 @@
zoom_is_explicit == other.zoom_is_explicit &&
min_zoom_is_explicit == other.min_zoom_is_explicit &&
max_zoom_is_explicit == other.max_zoom_is_explicit &&
- user_zoom_is_explicit == other.user_zoom_is_explicit;
+ user_zoom_is_explicit == other.user_zoom_is_explicit &&
+ viewport_fit == other.viewport_fit;
}
bool operator!=(const ViewportDescription& other) const {
diff --git a/third_party/blink/renderer/core/html/html_meta_element.cc b/third_party/blink/renderer/core/html/html_meta_element.cc
index 4f4bf2e..6dfa9b9a 100644
--- a/third_party/blink/renderer/core/html/html_meta_element.cc
+++ b/third_party/blink/renderer/core/html/html_meta_element.cc
@@ -304,6 +304,20 @@
return value;
}
+ViewportDescription::ViewportFit HTMLMetaElement::ParseViewportFitValueAsEnum(
+ bool& unknown_value,
+ const String& value_string) {
+ if (DeprecatedEqualIgnoringCase(value_string, "auto"))
+ return ViewportDescription::ViewportFit::kAuto;
+ if (DeprecatedEqualIgnoringCase(value_string, "contain"))
+ return ViewportDescription::ViewportFit::kContain;
+ if (DeprecatedEqualIgnoringCase(value_string, "cover"))
+ return ViewportDescription::ViewportFit::kCover;
+
+ unknown_value = true;
+ return ViewportDescription::ViewportFit::kAuto;
+}
+
void HTMLMetaElement::ProcessViewportKeyValuePair(
Document* document,
bool report_warnings,
@@ -352,7 +366,17 @@
} else if (key_string == "minimal-ui") {
// Ignore vendor-specific argument.
} else if (key_string == "viewport-fit") {
- // Ignore vendor-specific argument.
+ if (RuntimeEnabledFeatures::DisplayCutoutViewportFitEnabled()) {
+ bool unknown_value = false;
+ description->viewport_fit =
+ ParseViewportFitValueAsEnum(unknown_value, value_string);
+
+ // If we got an unknown value then report a warning.
+ if (unknown_value) {
+ ReportViewportWarning(document, kViewportFitUnsupported, value_string,
+ String());
+ }
+ }
} else if (key_string == "shrink-to-fit") {
// Ignore vendor-specific argument.
} else if (report_warnings) {
@@ -371,6 +395,7 @@
"The value for key \"maximum-scale\" is out of bounds and the value has "
"been clamped.",
"The key \"target-densitydpi\" is not supported.",
+ "The value \"%replacement1\" for key \"viewport-fit\" is not supported.",
};
return kErrors[error_code];
@@ -383,6 +408,7 @@
case kUnrecognizedViewportArgumentKeyError:
case kUnrecognizedViewportArgumentValueError:
case kMaximumScaleTooLargeError:
+ case kViewportFitUnsupported:
return kWarningMessageLevel;
}
diff --git a/third_party/blink/renderer/core/html/html_meta_element.h b/third_party/blink/renderer/core/html/html_meta_element.h
index be4132e..9303f6e 100644
--- a/third_party/blink/renderer/core/html/html_meta_element.h
+++ b/third_party/blink/renderer/core/html/html_meta_element.h
@@ -35,7 +35,8 @@
kUnrecognizedViewportArgumentValueError,
kTruncatedViewportArgumentValueError,
kMaximumScaleTooLargeError,
- kTargetDensityDpiUnsupported
+ kTargetDensityDpiUnsupported,
+ kViewportFitUnsupported
};
class CORE_EXPORT HTMLMetaElement final : public HTMLElement {
@@ -104,6 +105,10 @@
const String& key,
const String& value);
+ static ViewportDescription::ViewportFit ParseViewportFitValueAsEnum(
+ bool& unknown_value,
+ const String& value);
+
static void ReportViewportWarning(Document*,
ViewportErrorCode,
const String& replacement1,
diff --git a/third_party/blink/renderer/core/html/html_meta_element_test.cc b/third_party/blink/renderer/core/html/html_meta_element_test.cc
new file mode 100644
index 0000000..7f14a0a
--- /dev/null
+++ b/third_party/blink/renderer/core/html/html_meta_element_test.cc
@@ -0,0 +1,61 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/html/html_meta_element.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/frame/settings.h"
+#include "third_party/blink/renderer/core/testing/page_test_base.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+
+namespace blink {
+
+class HTMLMetaElementTest : public PageTestBase {
+ public:
+ void SetUp() override {
+ PageTestBase::SetUp();
+
+ RuntimeEnabledFeatures::SetDisplayCutoutViewportFitEnabled(true);
+ GetDocument().GetSettings()->SetViewportMetaEnabled(true);
+ }
+
+ ViewportDescription::ViewportFit LoadTestPageAndReturnViewportFit(
+ const String& value) {
+ LoadTestPageWithViewportFitValue(value);
+ return GetDocument().GetViewportDescription().viewport_fit;
+ }
+
+ private:
+ void LoadTestPageWithViewportFitValue(const String& value) {
+ GetDocument().documentElement()->SetInnerHTMLFromString(
+ "<head>"
+ "<meta name='viewport' content='viewport-fit=" +
+ value +
+ "'>"
+ "</head>");
+ }
+};
+
+TEST_F(HTMLMetaElementTest, ViewportFit_Auto) {
+ EXPECT_EQ(ViewportDescription::ViewportFit::kAuto,
+ LoadTestPageAndReturnViewportFit("auto"));
+}
+
+TEST_F(HTMLMetaElementTest, ViewportFit_Contain) {
+ EXPECT_EQ(ViewportDescription::ViewportFit::kContain,
+ LoadTestPageAndReturnViewportFit("contain"));
+}
+
+TEST_F(HTMLMetaElementTest, ViewportFit_Cover) {
+ EXPECT_EQ(ViewportDescription::ViewportFit::kCover,
+ LoadTestPageAndReturnViewportFit("cover"));
+}
+
+TEST_F(HTMLMetaElementTest, ViewportFit_Invalid) {
+ EXPECT_EQ(ViewportDescription::ViewportFit::kAuto,
+ LoadTestPageAndReturnViewportFit("invalid"));
+}
+
+} // namespace blink
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 19def019..ab2c7b9 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -395,6 +395,10 @@
name: "DisableRasterInvalidation",
},
{
+ name: "DisplayCutoutViewportFit",
+ settable_from_internals: true,
+ },
+ {
name: "DisplayNoneIFrameCreatesNoLayoutObject",
status: "stable",
},