Commit 4d42e778 authored by Morten Stenshorne's avatar Morten Stenshorne Committed by Commit Bot

Add page-orientation descriptor.

This will be supported in @page rules to set the orientation of a page
(without affecting layout). Typically to be used together with named
pages (or @page :first, etc.)

See https://drafts.csswg.org/css-page-3/#page-orientation-prop and
https://github.com/w3c/csswg-drafts/issues/4491

The tests added have some failures, due to crbug.com/1079212 and
crbug.com/1079214

Bug: 1053768
Change-Id: I96f93e3e34beee92b4c30f65d7e46498a8110464
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2187211Reviewed-by: default avatarRune Lillesveen <futhark@chromium.org>
Reviewed-by: default avatarAnders Hartvoll Ruud <andruud@chromium.org>
Reviewed-by: default avatarChris Harrelson <chrishtr@chromium.org>
Commit-Queue: Chris Harrelson <chrishtr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#766534}
parent a893c12f
...@@ -58,6 +58,7 @@ source_set("headers") { ...@@ -58,6 +58,7 @@ source_set("headers") {
"context_menu_data/media_type.h", "context_menu_data/media_type.h",
"css/forced_colors.h", "css/forced_colors.h",
"css/navigation_controls.h", "css/navigation_controls.h",
"css/page_orientation.h",
"css/page_size_type.h", "css/page_size_type.h",
"css/preferred_color_scheme.h", "css/preferred_color_scheme.h",
"css/screen_spanning.h", "css/screen_spanning.h",
......
// Copyright 2020 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 THIRD_PARTY_BLINK_PUBLIC_COMMON_CSS_PAGE_ORIENTATION_H_
#define THIRD_PARTY_BLINK_PUBLIC_COMMON_CSS_PAGE_ORIENTATION_H_
namespace blink {
// CSS @page page-orientation descriptor values - to be used both in Blink and
// the printing implementation.
enum class PageOrientation { kUpright, kRotateLeft, kRotateRight };
} // namespace blink
#endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_CSS_PAGE_ORIENTATION_H_
...@@ -706,6 +706,7 @@ enum CSSSampleId { ...@@ -706,6 +706,7 @@ enum CSSSampleId {
kTextUnderlineOffset = 661, kTextUnderlineOffset = 661,
kContentVisibility = 662, kContentVisibility = 662,
kTextDecorationThickness = 663, kTextDecorationThickness = 663,
kPageOrientation = 664,
// 1. Add new features above this line (don't change the assigned numbers of // 1. Add new features above this line (don't change the assigned numbers of
// the existing items). // the existing items).
// 2. Run the src/tools/metrics/histograms/update_use_counter_css.py script // 2. Run the src/tools/metrics/histograms/update_use_counter_css.py script
......
...@@ -2889,6 +2889,17 @@ ...@@ -2889,6 +2889,17 @@
typedom_types: ["Keyword"], typedom_types: ["Keyword"],
runtime_flag: "NamedPages" runtime_flag: "NamedPages"
}, },
{
name: "page-orientation",
is_descriptor: true,
field_template: "primitive",
field_group: "*",
type_name: "PageOrientation",
field_size: 2,
default_value: "PageOrientation::kUpright",
include_paths: ["third_party/blink/public/common/css/page_orientation.h"],
runtime_flag: "NamedPages"
},
{ {
name: "paint-order", name: "paint-order",
property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"], property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
......
...@@ -489,6 +489,19 @@ inline CSSValueID PlatformEnumToCSSValueID(EListStyleType v) { ...@@ -489,6 +489,19 @@ inline CSSValueID PlatformEnumToCSSValueID(EListStyleType v) {
return CSSValueID::kDisc; return CSSValueID::kDisc;
} }
template <>
inline PageOrientation CssValueIDToPlatformEnum(CSSValueID v) {
if (v == CSSValueID::kUpright)
return PageOrientation::kUpright;
if (v == CSSValueID::kRotateLeft)
return PageOrientation::kRotateLeft;
if (v == CSSValueID::kRotateRight)
return PageOrientation::kRotateRight;
NOTREACHED();
return PageOrientation::kUpright;
}
} // namespace blink } // namespace blink
#endif #endif
...@@ -908,6 +908,11 @@ ...@@ -908,6 +908,11 @@
// image-orientation // image-orientation
"from-image", "from-image",
// page-orientation
// upright
"rotate-left",
"rotate-right",
// shape-outside // shape-outside
"nonzero", "nonzero",
"evenodd", "evenodd",
......
...@@ -689,6 +689,10 @@ bool CSSParserFastPaths::IsValidKeywordPropertyAndValue( ...@@ -689,6 +689,10 @@ bool CSSParserFastPaths::IsValidKeywordPropertyAndValue(
return value_id == CSSValueID::kAuto || value_id == CSSValueID::kAvoid || return value_id == CSSValueID::kAuto || value_id == CSSValueID::kAvoid ||
value_id == CSSValueID::kAvoidPage || value_id == CSSValueID::kAvoidPage ||
value_id == CSSValueID::kAvoidColumn; value_id == CSSValueID::kAvoidColumn;
case CSSPropertyID::kPageOrientation:
return value_id == CSSValueID::kUpright ||
value_id == CSSValueID::kRotateLeft ||
value_id == CSSValueID::kRotateRight;
case CSSPropertyID::kPointerEvents: case CSSPropertyID::kPointerEvents:
return value_id == CSSValueID::kVisible || return value_id == CSSValueID::kVisible ||
value_id == CSSValueID::kNone || value_id == CSSValueID::kAll || value_id == CSSValueID::kNone || value_id == CSSValueID::kAll ||
...@@ -1029,6 +1033,7 @@ bool CSSParserFastPaths::IsKeywordPropertyID(CSSPropertyID property_id) { ...@@ -1029,6 +1033,7 @@ bool CSSParserFastPaths::IsKeywordPropertyID(CSSPropertyID property_id) {
case CSSPropertyID::kBreakAfter: case CSSPropertyID::kBreakAfter:
case CSSPropertyID::kBreakBefore: case CSSPropertyID::kBreakBefore:
case CSSPropertyID::kBreakInside: case CSSPropertyID::kBreakInside:
case CSSPropertyID::kPageOrientation:
case CSSPropertyID::kPointerEvents: case CSSPropertyID::kPointerEvents:
case CSSPropertyID::kPosition: case CSSPropertyID::kPosition:
case CSSPropertyID::kResize: case CSSPropertyID::kResize:
......
This is a testharness.js-based test.
PASS contents for selector ['']
PASS contents for selector [':left']
PASS contents for selector [':right']
PASS contents for selector [':first']
PASS contents for selector ['named1']
PASS contents for selector ['named2']
PASS contents for selector ['named3']
PASS contents for selector ['named4']
PASS contents for selector ['named5']
FAIL contents for selector ['named6'] assert_equals: unexpected @page contents expected "page-orientation: rotate-right;" but got "page-orientation: initial;"
FAIL contents for selector ['h5'] assert_equals: unexpected style rule contents expected "display: block;" but got "page-orientation: rotate-right; display: block;"
Harness: the test ran to completion.
<!DOCTYPE html>
<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
<link rel="help" href="https://drafts.csswg.org/css-page-3/#page-orientation-prop">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
@page {
page-orientation: rotate-right;
}
@page :left {
page-orientation: rotate-left;
}
@page :right {
page-orientation: rotate-right;
}
@page :first {
page-orientation: rotate-left;
}
@page named1 {
page-orientation: upright;
}
@page named2 {
page-orientation: hotpink;
}
@page named3 {
page-orientation: rotate-right;
}
@page named4 {
page-orientation: rotate-right;
page-orientation: rotate-left;
}
@page named5 {
page-orientation: hotpink;
page-orientation: rotate-right;
}
@page named6 {
page-orientation: rotate-right;
page-orientation: inherit;
page-orientation: initial;
page-orientation: none;
page-orientation: hotpink;
}
h5 {
page-orientation: rotate-right;
display: block;
}
</style>
<script>
let pageRuleExpectations = {
"" : "page-orientation: rotate-right;",
":left" : "page-orientation: rotate-left;",
":right" : "page-orientation: rotate-right;",
":first" : "page-orientation: rotate-left;",
"named1" : "page-orientation: upright;",
"named2" : "",
"named3" : "page-orientation: rotate-right;",
"named4" : "page-orientation: rotate-left;",
"named5" : "page-orientation: rotate-right;",
"named6" : "page-orientation: rotate-right;",
};
let styleRuleExpectations = {
"h5" : "display: block;"
};
let styleSheets = document.styleSheets;
for (let i = 0; i < styleSheets.length; i++) {
let rules = styleSheets[i].cssRules;
for (let rule of rules) {
if (rule.type == CSSRule.PAGE_RULE) {
let expected = pageRuleExpectations[rule.selectorText];
test(function() {
assert_equals(rule.style.cssText, expected, "unexpected @page contents");
}, "contents for selector ['" + rule.selectorText + "']");
} else if (rule.type == CSSRule.STYLE_RULE) {
let expected = styleRuleExpectations[rule.selectorText];
test(function() {
assert_equals(rule.style.cssText, expected, "unexpected style rule contents");
}, "contents for selector ['" + rule.selectorText + "']");
}
}
}
</script>
<!DOCTYPE html>
<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
<link rel="help" href="https://drafts.csswg.org/css-page-3/#page-orientation-prop">
<div id="elm" style="page-orientation:rotate-right;"></div>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
test(()=> {
assert_equals(getComputedStyle(elm).pageOrientation, "");
}, "page-orientation is not a property (only a descriptor)");
</script>
This is a testharness.js-based test.
PASS e.style['page-orientation'] = "hotpink" should not set the property value
FAIL e.style['page-orientation'] = "upright" should not set the property value assert_equals: expected "" but got "upright"
FAIL e.style['page-orientation'] = "rotate-left" should not set the property value assert_equals: expected "" but got "rotate-left"
FAIL e.style['page-orientation'] = "rotate-right" should not set the property value assert_equals: expected "" but got "rotate-right"
Harness: the test ran to completion.
<!DOCTYPE html>
<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
<link rel="help" href="https://drafts.csswg.org/css-page-3/#page-orientation-prop">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/css/support/parsing-testcommon.js"></script>
<script>
// page-orientation is not a property. test_invalid_value() tries to specify
// it on an element, and this should fail, even when using a valid
// value. page-orientation is only valid as a descriptor inside an @page rule.
test_invalid_value("page-orientation", "hotpink");
test_invalid_value("page-orientation", "upright");
test_invalid_value("page-orientation", "rotate-left");
test_invalid_value("page-orientation", "rotate-right");
</script>
...@@ -293,6 +293,7 @@ page ...@@ -293,6 +293,7 @@ page
pageBreakAfter pageBreakAfter
pageBreakBefore pageBreakBefore
pageBreakInside pageBreakInside
pageOrientation
paintOrder paintOrder
parentRule parentRule
perspective perspective
......
...@@ -277,6 +277,7 @@ All changes to this list should go through Blink's feature review process: http: ...@@ -277,6 +277,7 @@ All changes to this list should go through Blink's feature review process: http:
padding-right padding-right
padding-top padding-top
page page
page-orientation
paint-order paint-order
perspective perspective
perspective-origin perspective-origin
......
...@@ -43107,6 +43107,7 @@ Called by update_use_counter_css.py.--> ...@@ -43107,6 +43107,7 @@ Called by update_use_counter_css.py.-->
<int value="661" label="text-underline-offset"/> <int value="661" label="text-underline-offset"/>
<int value="662" label="content-visibility"/> <int value="662" label="content-visibility"/>
<int value="663" label="text-decoration-thickness"/> <int value="663" label="text-decoration-thickness"/>
<int value="664" label="page-orientation"/>
</enum> </enum>
<enum name="MappedEditingCommands"> <enum name="MappedEditingCommands">
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment