зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1469108: Propagate directionality to the shadow tree. r=smaug
Make it so that directionality of the ShadowRoot descendants is computed based on the host and it's ancestors, but don't touch the dir=auto code, since I don't think anybody agrees with what needs to happen there, and I think in general it shouldn't be accounted for. MozReview-Commit-ID: AZMBZ5m1SQf
This commit is contained in:
Родитель
c43cef31fc
Коммит
b20d01787e
|
@ -213,6 +213,7 @@
|
|||
#include "mozilla/AutoRestore.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/ShadowRoot.h"
|
||||
#include "nsUnicodeProperties.h"
|
||||
#include "nsTextFragment.h"
|
||||
#include "nsAttrValue.h"
|
||||
|
@ -222,6 +223,7 @@
|
|||
namespace mozilla {
|
||||
|
||||
using mozilla::dom::Element;
|
||||
using mozilla::dom::ShadowRoot;
|
||||
|
||||
/**
|
||||
* Returns true if aElement is one of the elements whose text content should not
|
||||
|
@ -276,6 +278,8 @@ GetDirectionFromChar(uint32_t ch)
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME(bug 1100912): Should ShadowRoot children affect the host if it's
|
||||
// dir=auto? Probably not at least in closed mode.
|
||||
inline static bool
|
||||
NodeAffectsDirAutoAncestor(nsINode* aTextNode)
|
||||
{
|
||||
|
@ -625,51 +629,69 @@ RecomputeDirectionality(Element* aElement, bool aNotify)
|
|||
MOZ_ASSERT(!aElement->HasDirAuto(),
|
||||
"RecomputeDirectionality called with dir=auto");
|
||||
|
||||
Directionality dir = eDir_LTR;
|
||||
|
||||
if (aElement->HasValidDir()) {
|
||||
dir = aElement->GetDirectionality();
|
||||
} else {
|
||||
Element* parent = aElement->GetParentElement();
|
||||
if (parent) {
|
||||
// If the element doesn't have an explicit dir attribute with a valid
|
||||
// value, the directionality is the same as the parent element (but
|
||||
// don't propagate the parent directionality if it isn't set yet).
|
||||
Directionality parentDir = parent->GetDirectionality();
|
||||
return aElement->GetDirectionality();
|
||||
}
|
||||
|
||||
Directionality dir = eDir_LTR;
|
||||
if (nsINode* parent = aElement->GetParentNode()) {
|
||||
if (ShadowRoot* shadow = ShadowRoot::FromNode(parent)) {
|
||||
parent = shadow->GetHost();
|
||||
}
|
||||
|
||||
if (parent && parent->IsElement()) {
|
||||
// If the node doesn't have an explicit dir attribute with a valid value,
|
||||
// the directionality is the same as the parent element (but don't propagate
|
||||
// the parent directionality if it isn't set yet).
|
||||
Directionality parentDir = parent->AsElement()->GetDirectionality();
|
||||
if (parentDir != eDir_NotSet) {
|
||||
dir = parentDir;
|
||||
}
|
||||
} else {
|
||||
// If there is no parent element and no dir attribute, the directionality
|
||||
// is LTR.
|
||||
dir = eDir_LTR;
|
||||
}
|
||||
|
||||
aElement->SetDirectionality(dir, aNotify);
|
||||
}
|
||||
|
||||
aElement->SetDirectionality(dir, aNotify);
|
||||
return dir;
|
||||
}
|
||||
|
||||
void
|
||||
SetDirectionalityOnDescendants(Element* aElement, Directionality aDir,
|
||||
bool aNotify)
|
||||
static void
|
||||
SetDirectionalityOnDescendantsInternal(nsINode* aNode,
|
||||
Directionality aDir,
|
||||
bool aNotify)
|
||||
{
|
||||
for (nsIContent* child = aElement->GetFirstChild(); child; ) {
|
||||
if (Element* element = Element::FromNode(aNode)) {
|
||||
if (ShadowRoot* shadow = element->GetShadowRoot()) {
|
||||
SetDirectionalityOnDescendantsInternal(shadow, aDir, aNotify);
|
||||
}
|
||||
}
|
||||
|
||||
for (nsIContent* child = aNode->GetFirstChild(); child; ) {
|
||||
if (!child->IsElement()) {
|
||||
child = child->GetNextNode(aElement);
|
||||
child = child->GetNextNode(aNode);
|
||||
continue;
|
||||
}
|
||||
|
||||
Element* element = child->AsElement();
|
||||
if (element->HasValidDir() || element->HasDirAuto()) {
|
||||
child = child->GetNextNonChildNode(aElement);
|
||||
child = child->GetNextNonChildNode(aNode);
|
||||
continue;
|
||||
}
|
||||
if (ShadowRoot* shadow = element->GetShadowRoot()) {
|
||||
SetDirectionalityOnDescendantsInternal(shadow, aDir, aNotify);
|
||||
}
|
||||
element->SetDirectionality(aDir, aNotify);
|
||||
child = child->GetNextNode(aElement);
|
||||
child = child->GetNextNode(aNode);
|
||||
}
|
||||
}
|
||||
|
||||
// We want the public version of this only to acc
|
||||
void
|
||||
SetDirectionalityOnDescendants(Element* aElement, Directionality aDir,
|
||||
bool aNotify)
|
||||
{
|
||||
return SetDirectionalityOnDescendantsInternal(aElement, aDir, aNotify);
|
||||
}
|
||||
|
||||
/**
|
||||
* Walk the parent chain of a text node whose dir attribute has been removed and
|
||||
* reset the direction of any of its ancestors which have dir=auto and whose
|
||||
|
|
|
@ -129331,6 +129331,30 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"css/css-scoping/shadow-directionality-001.tentative.html": [
|
||||
[
|
||||
"/css/css-scoping/shadow-directionality-001.tentative.html",
|
||||
[
|
||||
[
|
||||
"/css/css-scoping/reference/green-box.html",
|
||||
"=="
|
||||
]
|
||||
],
|
||||
{}
|
||||
]
|
||||
],
|
||||
"css/css-scoping/shadow-directionality-002.tentative.html": [
|
||||
[
|
||||
"/css/css-scoping/shadow-directionality-002.tentative.html",
|
||||
[
|
||||
[
|
||||
"/css/css-scoping/reference/green-box.html",
|
||||
"=="
|
||||
]
|
||||
],
|
||||
{}
|
||||
]
|
||||
],
|
||||
"css/css-scoping/shadow-disabled-sheet-001.html": [
|
||||
[
|
||||
"/css/css-scoping/shadow-disabled-sheet-001.html",
|
||||
|
@ -182915,6 +182939,18 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"shadow-dom/directionality-001.tentative.html": [
|
||||
[
|
||||
"/shadow-dom/directionality-001.tentative.html",
|
||||
[
|
||||
[
|
||||
"/shadow-dom/directionality-001-ref.html",
|
||||
"=="
|
||||
]
|
||||
],
|
||||
{}
|
||||
]
|
||||
],
|
||||
"shadow-dom/layout-slot-no-longer-assigned.html": [
|
||||
[
|
||||
"/shadow-dom/layout-slot-no-longer-assigned.html",
|
||||
|
@ -295386,6 +295422,11 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"shadow-dom/directionality-001-ref.html": [
|
||||
[
|
||||
{}
|
||||
]
|
||||
],
|
||||
"shadow-dom/reference/empty.html": [
|
||||
[
|
||||
{}
|
||||
|
@ -522941,6 +522982,14 @@
|
|||
"46913ea7e47811b11be898de5c3bd0a330ea6637",
|
||||
"testharness"
|
||||
],
|
||||
"css/css-scoping/shadow-directionality-001.tentative.html": [
|
||||
"51cf8c6780bb66f64082a0054f24f64c09b0258f",
|
||||
"reftest"
|
||||
],
|
||||
"css/css-scoping/shadow-directionality-002.tentative.html": [
|
||||
"c5cc9738b5b81a728c7cc16569360bd65b857ab3",
|
||||
"reftest"
|
||||
],
|
||||
"css/css-scoping/shadow-disabled-sheet-001.html": [
|
||||
"3de2d23c1b3339b964ec2c009832a3207a3b9dc4",
|
||||
"reftest"
|
||||
|
@ -523378,7 +523427,7 @@
|
|||
"reftest"
|
||||
],
|
||||
"css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-004.html": [
|
||||
"1e5377c120916557dc1525b38c9cf7eb86ae0151",
|
||||
"3740c52d7bd26a3353721931ae2a6299db395968",
|
||||
"reftest"
|
||||
],
|
||||
"css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-005.html": [
|
||||
|
@ -539602,7 +539651,7 @@
|
|||
"reftest"
|
||||
],
|
||||
"css/css-values/calc-rounding-001.html": [
|
||||
"c3071454184ca1bd97443cfb6298447d16d79b2f",
|
||||
"a74b631cd97db18ef120a0a5e7132c9e14b67f81",
|
||||
"testharness"
|
||||
],
|
||||
"css/css-values/calc-serialization.html": [
|
||||
|
@ -547362,7 +547411,7 @@
|
|||
"testharness"
|
||||
],
|
||||
"css/cssom/getComputedStyle-detached-subtree.html": [
|
||||
"01978ca7ea08cbf61b28e9d77753fe5852bcbff9",
|
||||
"886f72b4eaa82d3aeb4de5c5b27f71369dbe0186",
|
||||
"testharness"
|
||||
],
|
||||
"css/cssom/getComputedStyle-dynamic-subdoc.html": [
|
||||
|
@ -610377,6 +610426,14 @@
|
|||
"61f7da763fa4eb6f21077868caf0a07a4a9e44ae",
|
||||
"testharness"
|
||||
],
|
||||
"shadow-dom/directionality-001-ref.html": [
|
||||
"818d966e37de205936380fd47605f13b5aa505d7",
|
||||
"support"
|
||||
],
|
||||
"shadow-dom/directionality-001.tentative.html": [
|
||||
"763fd90e8ed83fb616379997735a5c283f0bd869",
|
||||
"reftest"
|
||||
],
|
||||
"shadow-dom/event-composed-path-after-dom-mutation.html": [
|
||||
"69ea3efc8230a0ed31968f24379289c6691d77d1",
|
||||
"testharness"
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
<!doctype html>
|
||||
<title>CSS Test: directionality propagation in Shadow DOM.</title>
|
||||
<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
|
||||
<link rel="help" href="https://html.spec.whatwg.org/#the-dir-attribute">
|
||||
<link rel="help" href="https://github.com/whatwg/html/issues/3699">
|
||||
<link rel="match" href="reference/green-box.html">
|
||||
<style>
|
||||
div { width: 100px; }
|
||||
</style>
|
||||
<p>Test passes if you see a single 100px by 100px green box below.</p>
|
||||
<div id="host1"></div>
|
||||
<div id="host2" dir="rtl"></div>
|
||||
<div id="host3"></div>
|
||||
<div id="host4" dir="rtl"></div>
|
||||
<script>
|
||||
host1.attachShadow({ mode: "open" }).innerHTML = `
|
||||
<style>:dir(ltr) { background: green; height: 25px; }</style>
|
||||
<div></div>
|
||||
`;
|
||||
host2.attachShadow({ mode: "open" }).innerHTML = `
|
||||
<style>:dir(rtl) { background: green; height: 25px; }</style>
|
||||
<div></div>
|
||||
`;
|
||||
host3.attachShadow({ mode: "open" }).innerHTML = `
|
||||
<style>:dir(rtl) { background: green; height: 25px; }</style>
|
||||
<div></div>
|
||||
`;
|
||||
host4.attachShadow({ mode: "open" }).innerHTML = `
|
||||
<style>span:dir(ltr) { display: block; background: green; height: 25px; }</style>
|
||||
<div dir="ltr"><span></span></div>
|
||||
`;
|
||||
document.body.offsetTop;
|
||||
host3.setAttribute("dir", "rtl");
|
||||
</script>
|
|
@ -0,0 +1,19 @@
|
|||
<!doctype html>
|
||||
<title>CSS Test: directionality propagation in Shadow DOM, appending a shadow host.</title>
|
||||
<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
|
||||
<link rel="help" href="https://html.spec.whatwg.org/#the-dir-attribute">
|
||||
<link rel="help" href="https://github.com/whatwg/html/issues/3699">
|
||||
<link rel="match" href="reference/green-box.html">
|
||||
<p>Test passes if you see a single 100px by 100px green box below.</p>
|
||||
<style>
|
||||
div { width: 100px; }
|
||||
</style>
|
||||
<div id="host-parent" dir="rtl"></div>
|
||||
<script>
|
||||
let host = document.createElement("div");
|
||||
host.attachShadow({ mode: "open" }).innerHTML = `
|
||||
<style>:dir(rtl) { background: green; height: 100px; width: 100px; }</style>
|
||||
<div></div>
|
||||
`;
|
||||
document.getElementById("host-parent").appendChild(host);
|
||||
</script>
|
|
@ -0,0 +1,6 @@
|
|||
<!doctype html>
|
||||
<title>CSS Test Reference</title>
|
||||
<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
|
||||
<div dir="rtl"> 123 456 <span><span> 789 101112 </span></span></div>
|
||||
<div dir="rtl"> 123 456 <span dir="ltr"><span> 789 101112 </span></span></div>
|
||||
<div dir="rtl"> 123 456 <span><span> 789 101112 </span></span></div>
|
|
@ -0,0 +1,19 @@
|
|||
<!doctype html>
|
||||
<title>Test: directionality propagation in Shadow DOM.</title>
|
||||
<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
|
||||
<link rel="help" href="https://html.spec.whatwg.org/#the-dir-attribute">
|
||||
<link rel="help" href="https://github.com/whatwg/html/issues/3699">
|
||||
<link rel="match" href="directionality-001-ref.html">
|
||||
<div id="host0" dir="rtl"><span> 789 101112 </span></div>
|
||||
<div id="host1" dir="rtl"><span> 789 101112 </span></div>
|
||||
<div id="host2" dir="rtl"><span> 789 101112 </span></div>
|
||||
<script>
|
||||
host0.attachShadow({mode: 'closed'}).innerHTML =
|
||||
'<div> 123 456 <span><slot></slot></span></div>';
|
||||
|
||||
host1.attachShadow({mode: 'closed'}).innerHTML =
|
||||
'<div> 123 456 <span dir="ltr"><slot></slot></span></div>';
|
||||
|
||||
host2.attachShadow({mode: 'closed'}).innerHTML =
|
||||
'<div> 123 456 <span><slot dir="ltr"></slot></span></div>';
|
||||
</script>
|
Загрузка…
Ссылка в новой задаче