Skip to content

Commit

Permalink
Implement scripting media query support
Browse files Browse the repository at this point in the history
This change adds support for parsing the scripting media query.

This change also implements the logic for matching this query.

none matches when script is disabled, enabled matches when enabled.
initial-only never matches as per
 w3c/csswg-drafts#8621.

Spec: https://drafts.csswg.org/mediaqueries-5/#scripting

Bug: 1467097
Change-Id: I7e6fba0fc4b05d133e177c7e2883b1f22fea48b1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4794549
Reviewed-by: Jeremy Roman <jbroman@chromium.org>
Commit-Queue: Luke <lukewarlow156@gmail.com>
Reviewed-by: Rune Lillesveen <futhark@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1188355}
  • Loading branch information
lukewarlow authored and Chromium LUCI CQ committed Aug 25, 2023
1 parent 46c79ed commit 844e122
Show file tree
Hide file tree
Showing 23 changed files with 255 additions and 41 deletions.
1 change: 1 addition & 0 deletions third_party/blink/public/common/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ source_set("headers") {
"css/navigation_controls.h",
"css/page_orientation.h",
"css/page_size_type.h",
"css/scripting.h",
"custom_handlers/protocol_handler_utils.h",
"device_memory/approximated_device_memory.h",
"dom_storage/session_storage_namespace_id.h",
Expand Down
24 changes: 24 additions & 0 deletions third_party/blink/public/common/css/scripting.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright 2023 The Chromium Authors
// 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_SCRIPTING_H_
#define THIRD_PARTY_BLINK_PUBLIC_COMMON_CSS_SCRIPTING_H_

namespace blink {

enum class Scripting {
// Scripting is not supported or not enabled.
kNone,
// Scripting is supported and enabled, but only for initial page load
// We will never match this value as it is intended for non-browser user
// agents, but it is part of the spec so we should still parse it.
// See https://github.com/w3c/csswg-drafts/issues/8621
kInitialOnly,
// Scripting is supported and enabled.
kEnabled,
};

} // namespace blink

#endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_CSS_SCRIPTING_H_
Original file line number Diff line number Diff line change
Expand Up @@ -354,8 +354,9 @@ class IdentifiableSurface {
kAspectRatioNormalized = 25,
kPrefersReducedTransparency = 26,
kInvertedColors = 27,
kScripting = 28,
// We can use enum values up to and including 63, see static_assert below.
kMax = kInvertedColors
kMax = kScripting
};
static_assert(static_cast<int>(MediaFeatureName::kMax) < 64,
"MediaFeatureName only allows values < 64 since we use it in "
Expand Down
5 changes: 5 additions & 0 deletions third_party/blink/renderer/core/css/css_value_keywords.json5
Original file line number Diff line number Diff line change
Expand Up @@ -1727,5 +1727,10 @@
// size,
"snap",
// sticky,

// (scripting:) media feature
"enabled",
"initial-only",
// none
],
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,6 @@
"snapped",
"stuck",
"inverted-colors",
"scripting",
],
}
29 changes: 29 additions & 0 deletions third_party/blink/renderer/core/css/media_query_evaluator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "services/device/public/mojom/device_posture_provider.mojom-blink.h"
#include "third_party/blink/public/common/css/forced_colors.h"
#include "third_party/blink/public/common/css/navigation_controls.h"
#include "third_party/blink/public/common/css/scripting.h"
#include "third_party/blink/public/common/privacy_budget/identifiability_metric_builder.h"
#include "third_party/blink/public/common/privacy_budget/identifiability_study_settings.h"
#include "third_party/blink/public/common/privacy_budget/identifiable_surface.h"
Expand Down Expand Up @@ -1525,6 +1526,34 @@ static bool InvertedColorsMediaFeatureEval(const MediaQueryExpValue& value,
return (value.Id() == CSSValueID::kNone) != media_values.InvertedColors();
}

static bool ScriptingMediaFeatureEval(const MediaQueryExpValue& value,
MediaQueryOperator,
const MediaValues& media_values) {
MaybeRecordMediaFeatureValue(
media_values, IdentifiableSurface::MediaFeatureName::kScripting,
media_values.GetScripting());

if (!value.IsValid()) {
return media_values.GetScripting() == Scripting::kEnabled;
}

if (!value.IsId()) {
return false;
}

switch (value.Id()) {
case CSSValueID::kNone:
return media_values.GetScripting() == Scripting::kNone;
case CSSValueID::kInitialOnly:
return media_values.GetScripting() == Scripting::kInitialOnly;
case CSSValueID::kEnabled:
return media_values.GetScripting() == Scripting::kEnabled;
default:
NOTREACHED();
return false;
}
}

static MediaQueryOperator ReverseOperator(MediaQueryOperator op) {
switch (op) {
case MediaQueryOperator::kNone:
Expand Down
79 changes: 79 additions & 0 deletions third_party/blink/renderer/core/css/media_query_evaluator_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,30 @@ MediaQueryEvaluatorTestCase g_invertedcolors_inverted_cases[] = {
{nullptr, false} // Do not remove the terminator line.
};

MediaQueryEvaluatorTestCase g_scripting_none_cases[] = {
{"(scripting)", false},
{"(scripting: none)", true},
{"(scripting: initial-only)", false},
{"(scripting: enabled)", false},
{nullptr, false} // Do not remove the terminator line.
};

MediaQueryEvaluatorTestCase g_scripting_initial_only_cases[] = {
{"(scripting)", false},
{"(scripting: none)", false},
{"(scripting: initial-only)", true},
{"(scripting: enabled)", false},
{nullptr, false} // Do not remove the terminator line.
};

MediaQueryEvaluatorTestCase g_scripting_enabled_cases[] = {
{"(scripting)", true},
{"(scripting: none)", false},
{"(scripting: initial-only)", false},
{"(scripting: enabled)", true},
{nullptr, false} // Do not remove the terminator line.
};

void TestMQEvaluator(MediaQueryEvaluatorTestCase* test_cases,
const MediaQueryEvaluator& media_query_evaluator,
CSSParserMode mode) {
Expand Down Expand Up @@ -872,6 +896,34 @@ TEST(MediaQueryEvaluatorTest, CachedInvertedColors) {
}
}

TEST(MediaQueryEvaluatorTest, CachedScripting) {
MediaValuesCached::MediaValuesCachedData data;

// scripting - none
{
data.scripting = Scripting::kNone;
MediaValues* media_values = MakeGarbageCollected<MediaValuesCached>(data);
MediaQueryEvaluator media_query_evaluator(media_values);
TestMQEvaluator(g_scripting_none_cases, media_query_evaluator);
}

// scripting - initial-only
{
data.scripting = Scripting::kInitialOnly;
MediaValues* media_values = MakeGarbageCollected<MediaValuesCached>(data);
MediaQueryEvaluator media_query_evaluator(media_values);
TestMQEvaluator(g_scripting_initial_only_cases, media_query_evaluator);
}

// scripting - enabled
{
data.scripting = Scripting::kEnabled;
MediaValues* media_values = MakeGarbageCollected<MediaValuesCached>(data);
MediaQueryEvaluator media_query_evaluator(media_values);
TestMQEvaluator(g_scripting_enabled_cases, media_query_evaluator);
}
}

TEST(MediaQueryEvaluatorTest, RangedValues) {
MediaValuesCached::MediaValuesCachedData data;
data.viewport_width = 500;
Expand Down Expand Up @@ -1612,4 +1664,31 @@ TEST_F(MediaQueryEvaluatorIdentifiabilityTest,
EXPECT_EQ(entry.metrics.begin()->value, IdentifiableToken(false));
}

TEST_F(MediaQueryEvaluatorIdentifiabilityTest,
MediaFeatureIdentifiableSurfaceScripting) {
GetDocument().body()->setInnerHTML(R"HTML(
<style>
@media (scripting: enabled) {
div { color: green }
}
</style>
<div id="green"></div>
<span></span>
)HTML");

UpdateAllLifecyclePhases();
EXPECT_TRUE(GetDocument().WasMediaFeatureEvaluated(
static_cast<int>(IdentifiableSurface::MediaFeatureName::kScripting)));
EXPECT_EQ(collector()->entries().size(), 1u);

auto& entry = collector()->entries().front();
EXPECT_EQ(entry.metrics.size(), 1u);
EXPECT_EQ(entry.metrics.begin()->surface,
IdentifiableSurface::FromTypeAndToken(
IdentifiableSurface::Type::kMediaFeature,
IdentifiableToken(
IdentifiableSurface::MediaFeatureName::kScripting)));
EXPECT_EQ(entry.metrics.begin()->value, IdentifiableToken(Scripting::kNone));
}

} // namespace blink
6 changes: 6 additions & 0 deletions third_party/blink/renderer/core/css/media_query_exp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,12 @@ static inline bool FeatureWithValidIdent(const String& media_feature,
return false;
}
}

if (RuntimeEnabledFeatures::ScriptingMediaFeatureEnabled() &&
media_feature == media_feature_names::kScriptingMediaFeature) {
return ident == CSSValueID::kEnabled ||
ident == CSSValueID::kInitialOnly || ident == CSSValueID::kNone;
}
}

if (RuntimeEnabledFeatures::CSSSnapContainerQueriesEnabled()) {
Expand Down
14 changes: 14 additions & 0 deletions third_party/blink/renderer/core/css/media_values.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "third_party/blink/renderer/core/css/media_values.h"

#include "third_party/blink/public/common/css/scripting.h"
#include "third_party/blink/public/platform/web_theme_engine.h"
#include "third_party/blink/renderer/core/css/css_resolution_units.h"
#include "third_party/blink/renderer/core/css/css_to_length_conversion_data.h"
Expand All @@ -16,10 +17,12 @@
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#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/layout/adjust_for_absolute_zoom.h"
#include "third_party/blink/renderer/core/media_type_names.h"
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/platform/graphics/color_space_gamut.h"
Expand Down Expand Up @@ -458,6 +461,17 @@ device::mojom::blink::DevicePostureType MediaValues::CalculateDevicePosture(
return frame->GetDevicePosture();
}

Scripting MediaValues::CalculateScripting(LocalFrame* frame) {
DCHECK(frame);
DCHECK(frame->GetDocument());
if (!frame->GetDocument()->GetExecutionContext()->CanExecuteScripts(
kNotAboutToExecuteScript)) {
return Scripting::kNone;
}

return Scripting::kEnabled;
}

bool MediaValues::ComputeLengthImpl(double value,
CSSPrimitiveValue::UnitType type,
double& result) const {
Expand Down
4 changes: 4 additions & 0 deletions third_party/blink/renderer/core/css/media_values.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ enum class CSSValueID;
enum class ColorSpaceGamut;
enum class ForcedColors;
enum class NavigationControls;
enum class Scripting;

mojom::blink::PreferredColorScheme CSSValueIDToPreferredColorScheme(
CSSValueID id);
Expand Down Expand Up @@ -130,6 +131,8 @@ class CORE_EXPORT MediaValues : public GarbageCollected<MediaValues>,
// when computing the computed value of a style() container query.
virtual Element* ContainerElement() const { return nullptr; }

virtual Scripting GetScripting() const = 0;

protected:
virtual ContainerSnappedFlags SnappedFlags() const {
return static_cast<ContainerSnappedFlags>(ContainerSnapped::kNone);
Expand Down Expand Up @@ -180,6 +183,7 @@ class CORE_EXPORT MediaValues : public GarbageCollected<MediaValues>,
static int CalculateVerticalViewportSegments(LocalFrame*);
static device::mojom::blink::DevicePostureType CalculateDevicePosture(
LocalFrame*);
static Scripting CalculateScripting(LocalFrame*);

bool ComputeLengthImpl(double value,
CSSPrimitiveValue::UnitType,
Expand Down
5 changes: 5 additions & 0 deletions third_party/blink/renderer/core/css/media_values_cached.cc
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ MediaValuesCached::MediaValuesCachedData::MediaValuesCachedData(
MediaValues::CalculateVerticalViewportSegments(frame);
device_posture = MediaValues::CalculateDevicePosture(frame);
inverted_colors = MediaValues::CalculateInvertedColors(frame);
scripting = MediaValues::CalculateScripting(frame);
}
}

Expand Down Expand Up @@ -331,4 +332,8 @@ device::mojom::blink::DevicePostureType MediaValuesCached::GetDevicePosture()
return data_.device_posture;
}

Scripting MediaValuesCached::GetScripting() const {
return data_.scripting;
}

} // namespace blink
4 changes: 4 additions & 0 deletions third_party/blink/renderer/core/css/media_values_cached.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "services/device/public/mojom/device_posture_provider.mojom-blink.h"
#include "third_party/blink/public/common/css/forced_colors.h"
#include "third_party/blink/public/common/css/navigation_controls.h"
#include "third_party/blink/public/common/css/scripting.h"
#include "third_party/blink/public/mojom/css/preferred_color_scheme.mojom-blink.h"
#include "third_party/blink/public/mojom/css/preferred_contrast.mojom-blink.h"
#include "third_party/blink/public/mojom/manifest/display_mode.mojom-blink.h"
Expand Down Expand Up @@ -78,6 +79,7 @@ class CORE_EXPORT MediaValuesCached final : public MediaValues {
int vertical_viewport_segments = 0;
device::mojom::blink::DevicePostureType device_posture =
device::mojom::blink::DevicePostureType::kContinuous;
Scripting scripting = Scripting::kNone;

MediaValuesCachedData();
explicit MediaValuesCachedData(Document&);
Expand Down Expand Up @@ -118,6 +120,7 @@ class CORE_EXPORT MediaValuesCached final : public MediaValues {
data.vertical_viewport_segments = vertical_viewport_segments;
data.device_posture = device_posture;
data.inverted_colors = inverted_colors;
data.scripting = scripting;
return data;
}
};
Expand Down Expand Up @@ -158,6 +161,7 @@ class CORE_EXPORT MediaValuesCached final : public MediaValues {
int GetHorizontalViewportSegments() const override;
int GetVerticalViewportSegments() const override;
device::mojom::blink::DevicePostureType GetDevicePosture() const override;
Scripting GetScripting() const override;

void OverrideViewportDimensions(double width, double height);

Expand Down
5 changes: 5 additions & 0 deletions third_party/blink/renderer/core/css/media_values_dynamic.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "third_party/blink/public/common/css/forced_colors.h"
#include "third_party/blink/public/common/css/navigation_controls.h"
#include "third_party/blink/public/common/css/scripting.h"
#include "third_party/blink/renderer/core/css/css_primitive_value.h"
#include "third_party/blink/renderer/core/css/css_resolution_units.h"
#include "third_party/blink/renderer/core/css/css_to_length_conversion_data.h"
Expand Down Expand Up @@ -270,6 +271,10 @@ device::mojom::blink::DevicePostureType MediaValuesDynamic::GetDevicePosture()
return CalculateDevicePosture(frame_);
}

Scripting MediaValuesDynamic::GetScripting() const {
return CalculateScripting(frame_);
}

Document* MediaValuesDynamic::GetDocument() const {
return frame_->GetDocument();
}
Expand Down
1 change: 1 addition & 0 deletions third_party/blink/renderer/core/css/media_values_dynamic.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class CORE_EXPORT MediaValuesDynamic : public MediaValues {
int GetHorizontalViewportSegments() const override;
int GetVerticalViewportSegments() const override;
device::mojom::blink::DevicePostureType GetDevicePosture() const override;
Scripting GetScripting() const override;
Document* GetDocument() const override;
bool HasValues() const override;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@ class MediaQueryFeatureSet : public MediaQueryParser::FeatureSet {
(feature == media_feature_names::kInvertedColorsMediaFeature &&
RuntimeEnabledFeatures::InvertedColorsEnabled()) ||
(CSSVariableParser::IsValidVariableName(feature) &&
RuntimeEnabledFeatures::CSSStyleQueriesBooleanEnabled());
RuntimeEnabledFeatures::CSSStyleQueriesBooleanEnabled()) ||
(feature == media_feature_names::kScriptingMediaFeature &&
RuntimeEnabledFeatures::ScriptingMediaFeatureEnabled());
}

bool IsCaseSensitive(const String& feature) const override { return false; }
Expand Down

0 comments on commit 844e122

Please sign in to comment.