0

[Blink] Propagate lang attribute changes to child elements

It is not possible for elements to know if the lang attribute has
changed for one of its ancestors. This change propagates lang attribute
updates down the tree.
The Permission Element listens to this change and updates the text
accordingly.

Bug: 374677445
Change-Id: Ic41c90a13f3fbb1faecc8298993bc74cb185137e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6003767
Auto-Submit: Ravjit Uppal <ravjit@chromium.org>
Reviewed-by: Peter Kvitek <kvitekp@chromium.org>
Commit-Queue: Peter Kvitek <kvitekp@chromium.org>
Reviewed-by: Mason Freed <masonf@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1391078}
This commit is contained in:
Ravjit
2024-12-03 17:45:31 +00:00
committed by Chromium LUCI CQ
parent 83f3940c11
commit 5fb6afaa58
7 changed files with 69 additions and 5 deletions
content/shell
headless
third_party/blink
renderer
web_tests
external
wpt
html
semantics
permission-element

@ -540,6 +540,7 @@ repack("pak") {
"$root_gen_dir/third_party/blink/public/resources/blink_scaled_resources_100_percent.pak",
"$root_gen_dir/third_party/blink/public/resources/inspector_overlay_resources.pak",
"$root_gen_dir/third_party/blink/public/strings/blink_strings_en-US.pak",
"$root_gen_dir/third_party/blink/public/strings/permission_element_generated_strings.pak",
"$root_gen_dir/third_party/blink/public/strings/permission_element_strings_en-US.pak",
"$root_gen_dir/ui/resources/ui_resources_100_percent.pak",
"$root_gen_dir/ui/resources/webui_resources.pak",
@ -564,6 +565,7 @@ repack("pak") {
"//third_party/blink/public:resources",
"//third_party/blink/public:scaled_resources_100_percent",
"//third_party/blink/public/strings",
"//third_party/blink/public/strings:permission_element_generated_strings",
"//third_party/blink/public/strings:permission_element_strings",
"//ui/resources",
"//ui/strings",

@ -102,6 +102,7 @@ repack("resource_pack_strings") {
sources = [
"$root_gen_dir/components/strings/components_strings_en-US.pak",
"$root_gen_dir/third_party/blink/public/strings/blink_strings_en-US.pak",
"$root_gen_dir/third_party/blink/public/strings/permission_element_generated_strings.pak",
"$root_gen_dir/third_party/blink/public/strings/permission_element_strings_en-US.pak",
"$root_gen_dir/ui/strings/app_locale_settings_en-US.pak",
"$root_gen_dir/ui/strings/auto_image_annotation_strings_en-US.pak",
@ -114,6 +115,7 @@ repack("resource_pack_strings") {
deps = [
"//components/strings",
"//third_party/blink/public/strings",
"//third_party/blink/public/strings:permission_element_generated_strings",
"//third_party/blink/public/strings:permission_element_strings",
"//ui/strings",
]

@ -6053,6 +6053,13 @@ Attr* Element::removeAttributeNode(Attr* attr,
}
void Element::LangAttributeChanged() {
// Propagate the change to all descendants.
for (Element& child : ElementTraversal::ChildrenOf(*this)) {
if (child.hasAttribute(html_names::kLangAttr)) {
continue;
}
child.LangAttributeChanged();
}
SetNeedsStyleRecalc(
kSubtreeStyleChange,
StyleChangeReasonForTracing::Create(style_change_reason::kPseudoClass));

@ -1636,7 +1636,7 @@ class CORE_EXPORT Element : public ContainerNode, public Animatable {
// Mark for style invalidation/recalc for :lang() selectors to pick up the
// changes.
void LangAttributeChanged();
virtual void LangAttributeChanged();
TextDirection ParentDirectionality() const;
bool RecalcSelfOrAncestorHasDirAuto();

@ -705,6 +705,11 @@ bool HTMLPermissionElement::MaybeRegisterPageEmbeddedPermissionControl() {
return true;
}
void HTMLPermissionElement::LangAttributeChanged() {
UpdateText();
HTMLElement::LangAttributeChanged();
}
void HTMLPermissionElement::AttributeChanged(
const AttributeModificationParams& params) {
if (params.name == html_names::kTypeAttr) {
@ -741,10 +746,6 @@ void HTMLPermissionElement::AttributeChanged(
UpdateText();
}
if (params.name == html_names::kLangAttr) {
UpdateText();
}
HTMLElement::AttributeChanged(params);
}

@ -309,6 +309,7 @@ class CORE_EXPORT HTMLPermissionElement final
void DidAddUserAgentShadowRoot(ShadowRoot&) override;
void AdjustStyle(ComputedStyleBuilder& builder) override;
void DidRecalcStyle(const StyleRecalcChange change) override;
void LangAttributeChanged() override;
// blink::Node override.
void DefaultEventHandler(Event&) override;

@ -0,0 +1,51 @@
<!DOCTYPE html>
<html>
<meta charset=utf-8>
<link rel="help" href="https://github.com/WICG/PEPC/blob/main/explainer.md#locking-the-pepc-style">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<body>
<div id="el1" lang="en">
<div id="el2" lang="en">
<div>
<permission id="permission-element" type="geolocation" style="width:fit-content"/>
</div>
</div>
</div>
<script>
// Since the `lang` attribute is inherited, but the actual inherited value
// isn't available via IDL, there's no direct way to check that it gets
// invalidated and updated when changes are made. As such, this test looks
// for side-effects of changing the language, such as changing the rendered
// size of the element.
promise_test(async() => {
var permission_element = document.getElementById("permission-element");
const initial_width = permission_element.offsetWidth;
let widths = new Set();
widths.add(initial_width);
const outer_lang_div = document.getElementById("el1");
const inner_lang_div = document.getElementById("el2");
// Changing the lang of the outer div should not have any effect as it is
// shadowed by the inner div.
outer_lang_div.lang = "de";
assert_equals(permission_element.offsetWidth, initial_width);
// The width of the permission element should change due to the changed
// language of the inner element. Try a couple languages to make sure one
// of them has a different size.
['de','hu','fr-AG','es'].forEach(lang => {
inner_lang_div.lang = lang;
widths.add(permission_element.offsetWidth);
});
assert_true(widths.size > 1);
}, "Permission element should dynamically change text when the lang \
attribute changes")
</script>
</body>
</html>