Bug 257133 - Changing the dir attribute of documentElement doesn't update a child element matching :dir pseudo class
Summary: Changing the dir attribute of documentElement doesn't update a child element ...
Status: VERIFIED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: DOM (show other bugs)
Version: Safari 16
Hardware: All Unspecified
: P2 Normal
Assignee: Ryosuke Niwa
URL: https://github.com/thetaPC/safari-dyn...
Keywords: BrowserCompat, InRadar
Depends on: 64861
Blocks:
  Show dependency treegraph
 
Reported: 2023-05-22 10:36 PDT by maria
Modified: 2023-06-20 14:12 PDT (History)
6 users (show)

See Also:


Attachments
Displays the bug (589 bytes, text/html)
2023-05-22 11:03 PDT, maria
no flags Details
rendering in safari, firefox, chrome (88.49 KB, image/png)
2023-05-23 04:49 PDT, Karl Dubost
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description maria 2023-05-22 10:36:48 PDT
# Safari Dynamic HTML bug

## Reproduction URL

https://github.com/thetaPC/safari-dynamic-html

## Description

Safari does not update when changing the HTML through Javascript. It uses the old HTML to determine the direction of the element. This is a problem when using `:dir()` to apply different styles to RTL and LTR languages.

## Steps to reproduce

1. Set the `dir` attribute of the `html` element to `ltr` in the HTML file.
2. Create a script that changes the `dir` attribute of the `html` element to `rtl` when the page is loaded.
3. Create a CSS file that applies different styles to an element based on the `dir` attribute.
4. Open the HTML file in Safari.

## Expected behavior

The element should be styled according to the `dir` attribute of the `html` element regardless of the initial value.

## Actual behavior

The element is styled according to the initial value of the `dir` attribute of the `html` element.

## Other information

This works as expected in Chrome and Firefox. The bug is present in Safari 16.4+. I have not tested older versions.
Comment 1 maria 2023-05-22 11:03:43 PDT
Created attachment 466450 [details]
Displays the bug

This file is the same `html` file that is provided in the given repo.
Comment 2 Karl Dubost 2023-05-23 04:49:35 PDT
Created attachment 466462 [details]
rendering in safari, firefox, chrome

Tested on macOS 13.5
---
Safari Technology Preview  170           18616.1.14.5
Firefox Nightly            115.0a1       11523.5.11
Google Chrome Canary       115.0.5788.0  5788.0

All browsers display a different results. 

# CSS dir() 
The three browsers returns: rtl 
window.getComputedStyle(document.querySelector('p')).direction

# CSS Background Color
On the other hand:
window.getComputedStyle(document.querySelector('p')).backgroundColor 

safari:  rgb(0, 0, 255)
firefox: rgb(255, 0, 0)
chrome:  rgba(0, 0, 0, 0)

# HTML dir
The three browsers returns: null
document.querySelector('p').getAttribute('dir')


If I set the dir to rtl with 
document.querySelector('p').setAttribute('dir', 'rtl')
and check the color again:
window.getComputedStyle(document.querySelector('p')).backgroundColor 

safari:  rgb(255, 0, 0)   - from blue to red
firefox: rgb(255, 0, 0)   - no changes
chrome:  rgba(0, 0, 0, 0) - no changes


chrome doesn't seem to react at all to rtl 
I believe this is https://bugs.chromium.org/p/chromium/issues/detail?id=576815


# Specifications side.
The HTML spec says:

https://html.spec.whatwg.org/multipage/semantics-other.html#selector-ltr

:dir(ltr)
    The :dir(ltr) pseudo-class must match all elements 
    whose directionality is 'ltr'.

:dir(rtl)
    The :dir(rtl) pseudo-class must match all elements 
    whose directionality is 'rtl'

which seems to imply that :dir() should not apply if dir='' is not set. 


BUT https://html.spec.whatwg.org/multipage/dom.html#the-directionality

If the element has a parent element 
   and the dir attribute is NOT in a defined state 
   (i.e. it is not present or has an invalid value)
  
THEN The directionality of the element is the same 
     as the element's parent element's directionality.

Going up we get document.documentElement.getAttribute('dir') => "rtl"


In the CSS specification
https://drafts.csswg.org/selectors/#the-dir-pseudo

> The difference between :dir(C) and ''[dir=C]'' is that ''[dir=C]'' 
> only performs a comparison against a given attribute on the element, 
> while the :dir(C) pseudo-class uses the UAs knowledge of the 
> document’s semantics to perform the comparison. For example, in 
> HTML, the directionality of an element inherits so that a child 
> without a dir attribute will have the same directionality as its 
> closest ancestor with a valid dir attribute. As another example, 
> in HTML, an element that matches ''[dir=auto]'' will match either 
> :dir(ltr) or :dir(rtl) depending on the resolved directionality of 
> the elements as determined by its contents. [HTML5]


So Firefox gets it right
And Safari needs to be fixed.
Comment 3 Karl Dubost 2023-05-23 04:52:23 PDT
Probably there are missing tests on WPT for this. 
https://wpt.fyi/results/css/selectors?label=master&label=experimental&aligned&q=dir
Comment 4 Ryosuke Niwa 2023-05-25 23:36:19 PDT
Pull request: https://github.com/WebKit/WebKit/pull/14383
Comment 5 Radar WebKit Bug Importer 2023-05-29 10:37:16 PDT
<rdar://problem/109976294>
Comment 6 EWS 2023-06-20 13:26:24 PDT
Committed 265332@main (62b42f584e0a): <https://commits.webkit.org/265332@main>

Reviewed commits have been landed. Closing PR #14383 and removing active labels.
Comment 7 maria 2023-06-20 14:03:30 PDT
I've verified that the issue has been fixed. Verification was done through [attachment](https://bug-257133-attachments.webkit.org/attachment.cgi?id=466450). Prior to the fix, the attachment would have a blue background. With the fix, it has the correct background color.