mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-29 04:09:13 +00:00
LibWeb: Parse and propagate touch-action CSS property
Co-authored-by: Sam Atkins <sam@ladybird.org>
This commit is contained in:
parent
b3713db4ab
commit
6cbb5d2785
Notes:
github-actions[bot]
2025-05-06 11:23:01 +00:00
Author: https://github.com/stravant 🔰
Commit: 6cbb5d2785
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3837
Reviewed-by: https://github.com/AtkinsSJ ✅
21 changed files with 364 additions and 19 deletions
|
@ -1580,6 +1580,54 @@ Isolation ComputedProperties::isolation() const
|
||||||
return keyword_to_isolation(value.to_keyword()).release_value();
|
return keyword_to_isolation(value.to_keyword()).release_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TouchActionData ComputedProperties::touch_action() const
|
||||||
|
{
|
||||||
|
auto const& touch_action = property(PropertyID::TouchAction);
|
||||||
|
if (touch_action.is_keyword()) {
|
||||||
|
switch (touch_action.to_keyword()) {
|
||||||
|
case Keyword::Auto:
|
||||||
|
return TouchActionData {};
|
||||||
|
case Keyword::None:
|
||||||
|
return TouchActionData::none();
|
||||||
|
case Keyword::Manipulation:
|
||||||
|
return TouchActionData { .allow_other = false };
|
||||||
|
default:
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (touch_action.is_value_list()) {
|
||||||
|
TouchActionData touch_action_data = TouchActionData::none();
|
||||||
|
for (auto const& value : touch_action.as_value_list().values()) {
|
||||||
|
switch (value->as_keyword().keyword()) {
|
||||||
|
case Keyword::PanX:
|
||||||
|
touch_action_data.allow_right = true;
|
||||||
|
touch_action_data.allow_left = true;
|
||||||
|
break;
|
||||||
|
case Keyword::PanLeft:
|
||||||
|
touch_action_data.allow_left = true;
|
||||||
|
break;
|
||||||
|
case Keyword::PanRight:
|
||||||
|
touch_action_data.allow_right = true;
|
||||||
|
break;
|
||||||
|
case Keyword::PanY:
|
||||||
|
touch_action_data.allow_up = true;
|
||||||
|
touch_action_data.allow_down = true;
|
||||||
|
break;
|
||||||
|
case Keyword::PanUp:
|
||||||
|
touch_action_data.allow_up = true;
|
||||||
|
break;
|
||||||
|
case Keyword::PanDown:
|
||||||
|
touch_action_data.allow_down = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return touch_action_data;
|
||||||
|
}
|
||||||
|
return TouchActionData {};
|
||||||
|
}
|
||||||
|
|
||||||
Containment ComputedProperties::contain() const
|
Containment ComputedProperties::contain() const
|
||||||
{
|
{
|
||||||
Containment containment = {};
|
Containment containment = {};
|
||||||
|
|
|
@ -166,6 +166,7 @@ public:
|
||||||
WritingMode writing_mode() const;
|
WritingMode writing_mode() const;
|
||||||
UserSelect user_select() const;
|
UserSelect user_select() const;
|
||||||
Isolation isolation() const;
|
Isolation isolation() const;
|
||||||
|
TouchActionData touch_action() const;
|
||||||
Containment contain() const;
|
Containment contain() const;
|
||||||
MixBlendMode mix_blend_mode() const;
|
MixBlendMode mix_blend_mode() const;
|
||||||
Optional<FlyString> view_transition_name() const;
|
Optional<FlyString> view_transition_name() const;
|
||||||
|
|
|
@ -309,6 +309,29 @@ public:
|
||||||
bool operator==(BorderData const&) const = default;
|
bool operator==(BorderData const&) const = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TouchActionData {
|
||||||
|
bool allow_left : 1 { true };
|
||||||
|
bool allow_right : 1 { true };
|
||||||
|
bool allow_up : 1 { true };
|
||||||
|
bool allow_down : 1 { true };
|
||||||
|
bool allow_pinch_zoom : 1 { true };
|
||||||
|
|
||||||
|
// Other touch interactions which aren't pan or pinch to zoom. E.g.: Double tap to zoom.
|
||||||
|
bool allow_other : 1 { true };
|
||||||
|
|
||||||
|
static TouchActionData none()
|
||||||
|
{
|
||||||
|
return TouchActionData {
|
||||||
|
.allow_left = false,
|
||||||
|
.allow_right = false,
|
||||||
|
.allow_up = false,
|
||||||
|
.allow_down = false,
|
||||||
|
.allow_pinch_zoom = false,
|
||||||
|
.allow_other = false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct TransformOrigin {
|
struct TransformOrigin {
|
||||||
CSS::LengthPercentage x { Percentage(50) };
|
CSS::LengthPercentage x { Percentage(50) };
|
||||||
CSS::LengthPercentage y { Percentage(50) };
|
CSS::LengthPercentage y { Percentage(50) };
|
||||||
|
@ -456,6 +479,7 @@ public:
|
||||||
CSS::Containment const& contain() const { return m_noninherited.contain; }
|
CSS::Containment const& contain() const { return m_noninherited.contain; }
|
||||||
CSS::MixBlendMode mix_blend_mode() const { return m_noninherited.mix_blend_mode; }
|
CSS::MixBlendMode mix_blend_mode() const { return m_noninherited.mix_blend_mode; }
|
||||||
Optional<FlyString> view_transition_name() const { return m_noninherited.view_transition_name; }
|
Optional<FlyString> view_transition_name() const { return m_noninherited.view_transition_name; }
|
||||||
|
TouchActionData touch_action() const { return m_noninherited.touch_action; }
|
||||||
|
|
||||||
CSS::LengthBox const& inset() const { return m_noninherited.inset; }
|
CSS::LengthBox const& inset() const { return m_noninherited.inset; }
|
||||||
const CSS::LengthBox& margin() const { return m_noninherited.margin; }
|
const CSS::LengthBox& margin() const { return m_noninherited.margin; }
|
||||||
|
@ -713,6 +737,7 @@ protected:
|
||||||
CSS::Containment contain { InitialValues::contain() };
|
CSS::Containment contain { InitialValues::contain() };
|
||||||
CSS::MixBlendMode mix_blend_mode { InitialValues::mix_blend_mode() };
|
CSS::MixBlendMode mix_blend_mode { InitialValues::mix_blend_mode() };
|
||||||
Optional<FlyString> view_transition_name;
|
Optional<FlyString> view_transition_name;
|
||||||
|
TouchActionData touch_action;
|
||||||
|
|
||||||
Optional<CSS::Transformation> rotate;
|
Optional<CSS::Transformation> rotate;
|
||||||
Optional<CSS::Transformation> translate;
|
Optional<CSS::Transformation> translate;
|
||||||
|
@ -891,6 +916,7 @@ public:
|
||||||
void set_contain(CSS::Containment value) { m_noninherited.contain = move(value); }
|
void set_contain(CSS::Containment value) { m_noninherited.contain = move(value); }
|
||||||
void set_mix_blend_mode(CSS::MixBlendMode value) { m_noninherited.mix_blend_mode = value; }
|
void set_mix_blend_mode(CSS::MixBlendMode value) { m_noninherited.mix_blend_mode = value; }
|
||||||
void set_view_transition_name(Optional<FlyString> value) { m_noninherited.view_transition_name = value; }
|
void set_view_transition_name(Optional<FlyString> value) { m_noninherited.view_transition_name = value; }
|
||||||
|
void set_touch_action(TouchActionData value) { m_noninherited.touch_action = value; }
|
||||||
|
|
||||||
void set_fill(SVGPaint value) { m_inherited.fill = move(value); }
|
void set_fill(SVGPaint value) { m_inherited.fill = move(value); }
|
||||||
void set_stroke(SVGPaint value) { m_inherited.stroke = move(value); }
|
void set_stroke(SVGPaint value) { m_inherited.stroke = move(value); }
|
||||||
|
|
|
@ -605,6 +605,17 @@
|
||||||
"none",
|
"none",
|
||||||
"uppercase"
|
"uppercase"
|
||||||
],
|
],
|
||||||
|
"touch-action": [
|
||||||
|
"auto",
|
||||||
|
"manipulation",
|
||||||
|
"none",
|
||||||
|
"pan-down",
|
||||||
|
"pan-left",
|
||||||
|
"pan-right",
|
||||||
|
"pan-up",
|
||||||
|
"pan-x",
|
||||||
|
"pan-y"
|
||||||
|
],
|
||||||
"transform-box": [
|
"transform-box": [
|
||||||
"content-box",
|
"content-box",
|
||||||
"border-box",
|
"border-box",
|
||||||
|
|
|
@ -279,6 +279,7 @@
|
||||||
"ltr",
|
"ltr",
|
||||||
"luminance",
|
"luminance",
|
||||||
"luminosity",
|
"luminosity",
|
||||||
|
"manipulation",
|
||||||
"mark",
|
"mark",
|
||||||
"marktext",
|
"marktext",
|
||||||
"match-parent",
|
"match-parent",
|
||||||
|
@ -344,6 +345,12 @@
|
||||||
"padding-box",
|
"padding-box",
|
||||||
"paged",
|
"paged",
|
||||||
"paint",
|
"paint",
|
||||||
|
"pan-down",
|
||||||
|
"pan-left",
|
||||||
|
"pan-right",
|
||||||
|
"pan-up",
|
||||||
|
"pan-x",
|
||||||
|
"pan-y",
|
||||||
"paused",
|
"paused",
|
||||||
"petite-caps",
|
"petite-caps",
|
||||||
"pi",
|
"pi",
|
||||||
|
|
|
@ -434,6 +434,7 @@ private:
|
||||||
RefPtr<CSSStyleValue const> parse_grid_template_areas_value(TokenStream<ComponentValue>&);
|
RefPtr<CSSStyleValue const> parse_grid_template_areas_value(TokenStream<ComponentValue>&);
|
||||||
RefPtr<CSSStyleValue const> parse_grid_area_shorthand_value(TokenStream<ComponentValue>&);
|
RefPtr<CSSStyleValue const> parse_grid_area_shorthand_value(TokenStream<ComponentValue>&);
|
||||||
RefPtr<CSSStyleValue const> parse_grid_shorthand_value(TokenStream<ComponentValue>&);
|
RefPtr<CSSStyleValue const> parse_grid_shorthand_value(TokenStream<ComponentValue>&);
|
||||||
|
RefPtr<CSSStyleValue const> parse_touch_action_value(TokenStream<ComponentValue>&);
|
||||||
|
|
||||||
RefPtr<CSSStyleValue const> parse_list_of_time_values(PropertyID, TokenStream<ComponentValue>&);
|
RefPtr<CSSStyleValue const> parse_list_of_time_values(PropertyID, TokenStream<ComponentValue>&);
|
||||||
|
|
||||||
|
|
|
@ -664,6 +664,10 @@ Parser::ParseErrorOr<NonnullRefPtr<CSSStyleValue const>> Parser::parse_css_value
|
||||||
if (auto parsed_value = parse_shadow_value(tokens, AllowInsetKeyword::No); parsed_value && !tokens.has_next_token())
|
if (auto parsed_value = parse_shadow_value(tokens, AllowInsetKeyword::No); parsed_value && !tokens.has_next_token())
|
||||||
return parsed_value.release_nonnull();
|
return parsed_value.release_nonnull();
|
||||||
return ParseError::SyntaxError;
|
return ParseError::SyntaxError;
|
||||||
|
case PropertyID::TouchAction:
|
||||||
|
if (auto parsed_value = parse_touch_action_value(tokens); parsed_value && !tokens.has_next_token())
|
||||||
|
return parsed_value.release_nonnull();
|
||||||
|
return ParseError::SyntaxError;
|
||||||
case PropertyID::Transform:
|
case PropertyID::Transform:
|
||||||
if (auto parsed_value = parse_transform_value(tokens); parsed_value && !tokens.has_next_token())
|
if (auto parsed_value = parse_transform_value(tokens); parsed_value && !tokens.has_next_token())
|
||||||
return parsed_value.release_nonnull();
|
return parsed_value.release_nonnull();
|
||||||
|
@ -3528,6 +3532,67 @@ RefPtr<CSSStyleValue const> Parser::parse_text_decoration_line_value(TokenStream
|
||||||
return StyleValueList::create(move(style_values), StyleValueList::Separator::Space);
|
return StyleValueList::create(move(style_values), StyleValueList::Separator::Space);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://www.w3.org/TR/pointerevents/#the-touch-action-css-property
|
||||||
|
RefPtr<CSSStyleValue const> Parser::parse_touch_action_value(TokenStream<ComponentValue>& tokens)
|
||||||
|
{
|
||||||
|
// auto | none | [ [ pan-x | pan-left | pan-right ] || [ pan-y | pan-up | pan-down ] ] | manipulation
|
||||||
|
|
||||||
|
if (auto value = parse_all_as_single_keyword_value(tokens, Keyword::Auto))
|
||||||
|
return value;
|
||||||
|
if (auto value = parse_all_as_single_keyword_value(tokens, Keyword::None))
|
||||||
|
return value;
|
||||||
|
if (auto value = parse_all_as_single_keyword_value(tokens, Keyword::Manipulation))
|
||||||
|
return value;
|
||||||
|
|
||||||
|
StyleValueVector parsed_values;
|
||||||
|
auto transaction = tokens.begin_transaction();
|
||||||
|
|
||||||
|
// We will verify that we have up to one vertical and one horizontal value
|
||||||
|
bool has_horizontal = false;
|
||||||
|
bool has_vertical = false;
|
||||||
|
|
||||||
|
// Were the values specified in y/x order? (we need to store them in canonical x/y order)
|
||||||
|
bool swap_order = false;
|
||||||
|
|
||||||
|
while (auto parsed_value = parse_css_value_for_property(PropertyID::TouchAction, tokens)) {
|
||||||
|
switch (parsed_value->as_keyword().keyword()) {
|
||||||
|
case Keyword::PanX:
|
||||||
|
case Keyword::PanLeft:
|
||||||
|
case Keyword::PanRight:
|
||||||
|
if (has_horizontal)
|
||||||
|
return {};
|
||||||
|
if (has_vertical)
|
||||||
|
swap_order = true;
|
||||||
|
has_horizontal = true;
|
||||||
|
break;
|
||||||
|
case Keyword::PanY:
|
||||||
|
case Keyword::PanUp:
|
||||||
|
case Keyword::PanDown:
|
||||||
|
if (has_vertical)
|
||||||
|
return {};
|
||||||
|
has_vertical = true;
|
||||||
|
break;
|
||||||
|
case Keyword::Auto:
|
||||||
|
case Keyword::None:
|
||||||
|
case Keyword::Manipulation:
|
||||||
|
// Not valid as part of a list
|
||||||
|
return {};
|
||||||
|
default:
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
parsed_values.append(parsed_value.release_nonnull());
|
||||||
|
if (!tokens.has_next_token())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (swap_order)
|
||||||
|
swap(parsed_values[0], parsed_values[1]);
|
||||||
|
|
||||||
|
transaction.commit();
|
||||||
|
return StyleValueList::create(move(parsed_values), StyleValueList::Separator::Space);
|
||||||
|
}
|
||||||
|
|
||||||
// https://www.w3.org/TR/css-transforms-1/#transform-property
|
// https://www.w3.org/TR/css-transforms-1/#transform-property
|
||||||
RefPtr<CSSStyleValue const> Parser::parse_transform_value(TokenStream<ComponentValue>& tokens)
|
RefPtr<CSSStyleValue const> Parser::parse_transform_value(TokenStream<ComponentValue>& tokens)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2954,6 +2954,15 @@
|
||||||
"unitless-length"
|
"unitless-length"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"touch-action": {
|
||||||
|
"animation-type": "discrete",
|
||||||
|
"inherited": false,
|
||||||
|
"initial": "auto",
|
||||||
|
"max-values": 2,
|
||||||
|
"valid-types": [
|
||||||
|
"touch-action"
|
||||||
|
]
|
||||||
|
},
|
||||||
"transform": {
|
"transform": {
|
||||||
"animation-type": "custom",
|
"animation-type": "custom",
|
||||||
"inherited": false,
|
"inherited": false,
|
||||||
|
|
|
@ -933,6 +933,8 @@ void NodeWithStyle::apply_style(CSS::ComputedProperties const& computed_style)
|
||||||
computed_values.set_aspect_ratio({ false, aspect_ratio.as_ratio().ratio() });
|
computed_values.set_aspect_ratio({ false, aspect_ratio.as_ratio().ratio() });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
computed_values.set_touch_action(computed_style.touch_action());
|
||||||
|
|
||||||
auto const& math_shift_value = computed_style.property(CSS::PropertyID::MathShift);
|
auto const& math_shift_value = computed_style.property(CSS::PropertyID::MathShift);
|
||||||
if (auto math_shift = keyword_to_math_shift(math_shift_value.to_keyword()); math_shift.has_value())
|
if (auto math_shift = keyword_to_math_shift(math_shift_value.to_keyword()); math_shift.has_value())
|
||||||
computed_values.set_math_shift(math_shift.value());
|
computed_values.set_math_shift(math_shift.value());
|
||||||
|
|
|
@ -217,23 +217,24 @@ All properties associated with getComputedStyle(document.body):
|
||||||
"214": "text-decoration-thickness",
|
"214": "text-decoration-thickness",
|
||||||
"215": "text-overflow",
|
"215": "text-overflow",
|
||||||
"216": "top",
|
"216": "top",
|
||||||
"217": "transform",
|
"217": "touch-action",
|
||||||
"218": "transform-box",
|
"218": "transform",
|
||||||
"219": "transform-origin",
|
"219": "transform-box",
|
||||||
"220": "transition-behavior",
|
"220": "transform-origin",
|
||||||
"221": "transition-delay",
|
"221": "transition-behavior",
|
||||||
"222": "transition-duration",
|
"222": "transition-delay",
|
||||||
"223": "transition-property",
|
"223": "transition-duration",
|
||||||
"224": "transition-timing-function",
|
"224": "transition-property",
|
||||||
"225": "translate",
|
"225": "transition-timing-function",
|
||||||
"226": "unicode-bidi",
|
"226": "translate",
|
||||||
"227": "user-select",
|
"227": "unicode-bidi",
|
||||||
"228": "vertical-align",
|
"228": "user-select",
|
||||||
"229": "view-transition-name",
|
"229": "vertical-align",
|
||||||
"230": "width",
|
"230": "view-transition-name",
|
||||||
"231": "x",
|
"231": "width",
|
||||||
"232": "y",
|
"232": "x",
|
||||||
"233": "z-index"
|
"233": "y",
|
||||||
|
"234": "z-index"
|
||||||
}
|
}
|
||||||
All properties associated with document.body.style by default:
|
All properties associated with document.body.style by default:
|
||||||
{}
|
{}
|
||||||
|
|
|
@ -616,6 +616,8 @@ All supported properties and their default values exposed from CSSStylePropertie
|
||||||
'textTransform': 'none'
|
'textTransform': 'none'
|
||||||
'text-transform': 'none'
|
'text-transform': 'none'
|
||||||
'top': 'auto'
|
'top': 'auto'
|
||||||
|
'touchAction': 'auto'
|
||||||
|
'touch-action': 'auto'
|
||||||
'transform': 'none'
|
'transform': 'none'
|
||||||
'transformBox': 'view-box'
|
'transformBox': 'view-box'
|
||||||
'transform-box': 'view-box'
|
'transform-box': 'view-box'
|
||||||
|
|
|
@ -215,6 +215,7 @@ text-decoration-style: solid
|
||||||
text-decoration-thickness: auto
|
text-decoration-thickness: auto
|
||||||
text-overflow: clip
|
text-overflow: clip
|
||||||
top: auto
|
top: auto
|
||||||
|
touch-action: auto
|
||||||
transform: none
|
transform: none
|
||||||
transform-box: view-box
|
transform-box: view-box
|
||||||
transform-origin: 50% 50%
|
transform-origin: 50% 50%
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
Harness status: OK
|
Harness status: OK
|
||||||
|
|
||||||
Found 198 tests
|
Found 199 tests
|
||||||
|
|
||||||
188 Pass
|
189 Pass
|
||||||
10 Fail
|
10 Fail
|
||||||
Pass accent-color
|
Pass accent-color
|
||||||
Pass border-collapse
|
Pass border-collapse
|
||||||
|
@ -186,6 +186,7 @@ Pass text-decoration-style
|
||||||
Pass text-decoration-thickness
|
Pass text-decoration-thickness
|
||||||
Pass text-overflow
|
Pass text-overflow
|
||||||
Pass top
|
Pass top
|
||||||
|
Pass touch-action
|
||||||
Fail transform
|
Fail transform
|
||||||
Pass transform-box
|
Pass transform-box
|
||||||
Pass transition-behavior
|
Pass transition-behavior
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
Harness status: OK
|
||||||
|
|
||||||
|
Found 6 tests
|
||||||
|
|
||||||
|
6 Pass
|
||||||
|
Pass Property touch-action value 'auto'
|
||||||
|
Pass Property touch-action value 'none'
|
||||||
|
Pass Property touch-action value 'manipulation'
|
||||||
|
Pass Property touch-action value 'pan-x'
|
||||||
|
Pass Property touch-action value 'pan-y'
|
||||||
|
Pass Property touch-action value 'pan-x pan-y'
|
|
@ -0,0 +1,8 @@
|
||||||
|
Harness status: OK
|
||||||
|
|
||||||
|
Found 3 tests
|
||||||
|
|
||||||
|
3 Pass
|
||||||
|
Pass e.style['touch-action'] = "auto none" should not set the property value
|
||||||
|
Pass e.style['touch-action'] = "manipulation pan-x" should not set the property value
|
||||||
|
Pass e.style['touch-action'] = "pan-y pan-x pan-y" should not set the property value
|
|
@ -0,0 +1,11 @@
|
||||||
|
Harness status: OK
|
||||||
|
|
||||||
|
Found 6 tests
|
||||||
|
|
||||||
|
6 Pass
|
||||||
|
Pass e.style['touch-action'] = "auto" should set the property value
|
||||||
|
Pass e.style['touch-action'] = "none" should set the property value
|
||||||
|
Pass e.style['touch-action'] = "manipulation" should set the property value
|
||||||
|
Pass e.style['touch-action'] = "pan-x" should set the property value
|
||||||
|
Pass e.style['touch-action'] = "pan-y" should set the property value
|
||||||
|
Pass e.style['touch-action'] = "pan-y pan-x" should set the property value
|
|
@ -0,0 +1,8 @@
|
||||||
|
Harness status: OK
|
||||||
|
|
||||||
|
Found 3 tests
|
||||||
|
|
||||||
|
3 Pass
|
||||||
|
Pass 'pan-x none' is corrected properly
|
||||||
|
Pass 'pan-y none' is corrected properly
|
||||||
|
Pass 'auto none' is corrected properly
|
|
@ -0,0 +1,24 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Pointer Events: getComputedStyle().touchAction</title>
|
||||||
|
<link rel="help" href="https://w3c.github.io/pointerevents/#the-touch-action-css-property">
|
||||||
|
<meta name="assert" content="touch-action computed value is as specified.">
|
||||||
|
<script src="../../resources/testharness.js"></script>
|
||||||
|
<script src="../../resources/testharnessreport.js"></script>
|
||||||
|
<script src="../../css/support/computed-testcommon.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="target"></div>
|
||||||
|
<script>
|
||||||
|
test_computed_value("touch-action", "auto");
|
||||||
|
test_computed_value("touch-action", "none");
|
||||||
|
test_computed_value("touch-action", "manipulation");
|
||||||
|
|
||||||
|
test_computed_value("touch-action", "pan-x");
|
||||||
|
test_computed_value("touch-action", "pan-y");
|
||||||
|
test_computed_value("touch-action", "pan-x pan-y");
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,18 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Pointer Events: parsing touch-action with invalid values</title>
|
||||||
|
<link rel="help" href="https://w3c.github.io/pointerevents/#the-touch-action-css-property">
|
||||||
|
<meta name="assert" content="touch-action supports only the grammar 'auto | none | [ pan-x || pan-y ] | manipulation'.">
|
||||||
|
<script src="../../resources/testharness.js"></script>
|
||||||
|
<script src="../../resources/testharnessreport.js"></script>
|
||||||
|
<script src="../../css/support/parsing-testcommon.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
test_invalid_value("touch-action", "auto none");
|
||||||
|
test_invalid_value("touch-action", "manipulation pan-x");
|
||||||
|
test_invalid_value("touch-action", "pan-y pan-x pan-y");
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,23 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Pointer Events: parsing touch-action with valid values</title>
|
||||||
|
<link rel="help" href="https://w3c.github.io/pointerevents/#the-touch-action-css-property">
|
||||||
|
<meta name="assert" content="touch-action supports the full grammar 'auto | none | [ pan-x || pan-y ] | manipulation'.">
|
||||||
|
<script src="../../resources/testharness.js"></script>
|
||||||
|
<script src="../../resources/testharnessreport.js"></script>
|
||||||
|
<script src="../../css/support/parsing-testcommon.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
test_valid_value("touch-action", "auto");
|
||||||
|
test_valid_value("touch-action", "none");
|
||||||
|
test_valid_value("touch-action", "manipulation");
|
||||||
|
|
||||||
|
// [ pan-x || pan-y ]
|
||||||
|
test_valid_value("touch-action", "pan-x");
|
||||||
|
test_valid_value("touch-action", "pan-y");
|
||||||
|
test_valid_value("touch-action", "pan-y pan-x", "pan-x pan-y");
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,67 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>touch-action: illegal</title>
|
||||||
|
<meta name="viewport" content="width=device-width">
|
||||||
|
<link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
|
||||||
|
<script src="../resources/testharness.js"></script>
|
||||||
|
<script src="../resources/testharnessreport.js"></script>
|
||||||
|
<script src="pointerevent_support.js"></script>
|
||||||
|
<style>
|
||||||
|
#target0 {
|
||||||
|
width: 700px;
|
||||||
|
height: 50px;
|
||||||
|
touch-action: pan-x none;
|
||||||
|
}
|
||||||
|
#target1 {
|
||||||
|
width: 700px;
|
||||||
|
height: 50px;
|
||||||
|
background: black;
|
||||||
|
margin-top: 5px;
|
||||||
|
touch-action: pan-y none;
|
||||||
|
}
|
||||||
|
#target2 {
|
||||||
|
width: 700px;
|
||||||
|
height: 50px;
|
||||||
|
background: black;
|
||||||
|
margin-top: 5px;
|
||||||
|
touch-action: auto none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body onload="run()">
|
||||||
|
<h1>Pointer Events touch-action attribute support</h1>
|
||||||
|
<h4 id="desc">Test Description: Test will automatically check behaviour of following combinations: 'pan-x none', 'pan-y none', 'auto none'</h4>
|
||||||
|
<div id="target0"></div>
|
||||||
|
<div id="target1"></div>
|
||||||
|
<div id="target2"></div>
|
||||||
|
<script type='text/javascript'>
|
||||||
|
var detected_pointertypes = {};
|
||||||
|
|
||||||
|
setup({ explicit_done: true });
|
||||||
|
add_completion_callback(showPointerTypes);
|
||||||
|
|
||||||
|
function run() {
|
||||||
|
var target0 = document.getElementById('target0');
|
||||||
|
var target1 = document.getElementById('target1');
|
||||||
|
var target2 = document.getElementById('target2');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
assert_true(getComputedStyle(target0).touchAction == 'auto', "'pan-x none' is corrected properly");
|
||||||
|
}, "'pan-x none' is corrected properly");
|
||||||
|
test(function() {
|
||||||
|
assert_true(getComputedStyle(target1).touchAction == 'auto', "'pan-y none' is corrected properly");
|
||||||
|
}, "'pan-y none' is corrected properly");
|
||||||
|
test(function() {
|
||||||
|
assert_true(getComputedStyle(target2).touchAction == 'auto', "'auto none' is corrected properly");
|
||||||
|
}, "'auto none' is corrected properly");
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<h1>touch-action: none</h1>
|
||||||
|
<div id="complete-notice">
|
||||||
|
<p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
|
||||||
|
</div>
|
||||||
|
<div id="log"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Add table
Add a link
Reference in a new issue