Skip to content

Commit f8bbb1e

Browse files
committed
css: refactor the computed style impl (#62)
1 parent f21393e commit f8bbb1e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

94 files changed

+7718
-1921
lines changed

crates/jsbindings/bindings.layout.hpp

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ namespace crates::layout2
9191

9292
protected:
9393
virtual std::optional<T> parse(const std::string &input) = 0;
94-
virtual std::string stringify() { return ""; }
94+
virtual std::string stringify() const { return ""; }
9595

9696
protected:
9797
T handle_;
@@ -438,7 +438,9 @@ namespace crates::layout2
438438
#undef XX
439439
return std::nullopt;
440440
}
441-
std::string stringify() override
441+
442+
public:
443+
std::string stringify() const override
442444
{
443445
switch (this->handle_)
444446
{
@@ -451,8 +453,6 @@ namespace crates::layout2
451453
return "";
452454
}
453455
}
454-
455-
public:
456456
friend std::ostream &operator<<(std::ostream &os, const T &value)
457457
{
458458
return os << value.stringify();
@@ -478,7 +478,9 @@ namespace crates::layout2
478478
return holocron::layout::AlignSelf::Auto;
479479
return BoxAlignmentProperty::parse(input);
480480
}
481-
std::string stringify() override
481+
482+
public:
483+
std::string stringify() const override
482484
{
483485
if (handle_ == holocron::layout::AlignSelf::Auto)
484486
return "auto";
@@ -971,18 +973,42 @@ namespace crates::layout2
971973
public:
972974
friend std::ostream &operator<<(std::ostream &os, const LayoutStyle &style)
973975
{
974-
os << "LayoutStyle {" << std::endl;
975-
os << " display: " << style.display() << "," << std::endl;
976-
os << " boxSizing: " << style.boxSizing() << "," << std::endl;
977-
os << " overflowX: " << style.overflow().x() << "," << std::endl;
978-
os << " overflowY: " << style.overflow().y() << "," << std::endl;
979-
os << " position: " << style.position() << "," << std::endl;
980-
os << " size: " << "(" << style.width() << ", " << style.height() << ")," << std::endl;
981-
os << " [min]size: " << "(" << style.minWidth() << ", " << style.minHeight() << ")," << std::endl;
982-
os << " [max]size: " << "(" << style.maxWidth() << ", " << style.maxHeight() << ")," << std::endl;
983-
os << " margin: " << style.margin() << "," << std::endl;
984-
os << " padding: " << style.padding() << "," << std::endl;
985-
os << "}";
976+
std::ostringstream flex_descriptor;
977+
flex_descriptor << "direction=" << style.flexDirection()
978+
<< ", wrap=" << style.flexWrap()
979+
<< ", basis=" << style.flexBasis()
980+
<< ", grow=" << style.flexGrow()
981+
<< ", shrink=" << style.flexShrink();
982+
983+
os << "LayoutStyle {" << std::endl
984+
<< " display: " << style.display() << std::endl
985+
<< " box-sizing: " << style.boxSizing() << std::endl
986+
<< " overflow-x: " << style.overflow().x() << std::endl
987+
<< " overflow-y: " << style.overflow().y() << std::endl
988+
<< " position: " << style.position() << std::endl
989+
<< " size: " << "(" << style.width() << ", " << style.height() << ")" << std::endl
990+
<< " [min]size: " << "(" << style.minWidth() << ", " << style.minHeight() << ")" << std::endl
991+
<< " [max]size: " << "(" << style.maxWidth() << ", " << style.maxHeight() << ")" << std::endl
992+
<< " margin: " << style.margin() << std::endl
993+
<< " padding: " << style.padding() << std::endl
994+
<< " border: " << style.border() << std::endl
995+
<< " flex: " << flex_descriptor.str() << std::endl
996+
<< " align-items: " << style.alignItems() << std::endl
997+
<< " align-self: " << style.alignSelf() << std::endl
998+
<< " align-content: " << style.alignContent() << std::endl
999+
<< " justify-items: " << style.justifyItems() << std::endl
1000+
<< " justify-self: " << style.justifySelf() << std::endl
1001+
<< " justify-content: " << style.justifyContent() << std::endl
1002+
<< " grid-template-rows: " << std::string(style.style_.gridAutoColumns) << std::endl
1003+
<< "grid-template-columns: " << std::string(style.style_.gridTemplateColumns) << std::endl
1004+
<< " grid-auto-rows: " << std::string(style.style_.gridAutoRows) << std::endl
1005+
<< " grid-auto-columns: " << std::string(style.style_.gridAutoColumns) << std::endl
1006+
<< " grid-auto-flow: " << std::string(style.style_.gridAutoFlow) << std::endl
1007+
<< " grid-row-start: " << std::string(style.style_.gridRowStart) << std::endl
1008+
<< " grid-row-end: " << std::string(style.style_.gridRowEnd) << std::endl
1009+
<< " grid-column-start: " << std::string(style.style_.gridColumnStart) << std::endl
1010+
<< " grid-column-end: " << std::string(style.style_.gridColumnEnd) << std::endl
1011+
<< "}";
9861012
return os;
9871013
}
9881014
operator holocron::layout::Style() const { return style_; }

docs/development-zh.md

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,7 @@ $ make android CLEAN=yes RELEASE=yes
3636

3737
### 应用进程
3838

39-
JSAR 会将每个应用进程的日志也打印到 `jsar` 中,比如:
40-
41-
```
42-
07-12 22:12:23.326 9826 9850 D jsar : client(9957): Detected a long frame(#135) takes 341ms in session(2)
43-
```
44-
45-
它的格式表示为 `client(<进程ID>): <日志内容>`
39+
JSAR 的应用日志不会在 `jsar` 通道中出现,需要开发者在 `${运行时目录}/logs/${应用进程ID}.(out|err).log` 中查看。
4640

4741
### 文档事件
4842

fixtures/html/layout-grid-example.html

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,11 @@
4040
.grid-container {
4141
display: grid;
4242
border: none;
43-
background-color: #c9d4df30;
43+
box-sizing: border-box;
44+
background-color: #c9d4df5f;
4445
grid-template-columns: repeat(auto-fit, minmax(30%, 1fr));
4546
gap: 20px;
46-
padding: 20px 0;
47+
padding: 20px;
4748
width: 100%;
4849
}
4950

@@ -52,7 +53,6 @@
5253
background: rgba(0, 81, 255, 0.85);
5354
border-radius: 20px;
5455
padding: 50px;
55-
margin: 20px;
5656
transform: translateZ(10px);
5757
}
5858

@@ -78,57 +78,57 @@
7878
<h1>Grid Layout Example</h1>
7979
</header>
8080

81-
<div class="grid-container">
82-
<div class="grid-item">
81+
<main class="grid-container">
82+
<section class="grid-item">
8383
<img src="images/jsar-logo-00.png" />
8484
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
85-
</div>
85+
</section>
8686

87-
<div class="grid-item">
87+
<section class="grid-item">
8888
<h3>Grid Item 1</h3>
8989
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
90-
</div>
90+
</section>
9191

92-
<div class="grid-item">
92+
<section class="grid-item">
9393
<h3>Grid Item 2</h3>
9494
<p>Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
95-
</div>
95+
</section>
9696

97-
<div class="grid-item">
97+
<section class="grid-item">
9898
<h3>Grid Item 3</h3>
9999
<p>Ut enim ad minim veniam, quis nostrud exercitation ullamco.</p>
100-
</div>
100+
</section>
101101

102-
<div class="grid-item">
102+
<section class="grid-item">
103103
<h3>Grid Item 4</h3>
104104
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum.</p>
105-
</div>
105+
</section>
106106

107-
<div class="grid-item">
107+
<section class="grid-item">
108108
<h3>Grid Item 5</h3>
109109
<p>Excepteur sint occaecat cupidatat non proident.</p>
110-
</div>
110+
</section>
111111

112-
<div class="grid-item">
112+
<section class="grid-item">
113113
<h3>Grid Item 6</h3>
114114
<p>Excepteur sint occaecat cupidatat non proident.</p>
115-
</div>
115+
</section>
116116

117-
<div class="grid-item">
117+
<section class="grid-item">
118118
<h3>Grid Item 7</h3>
119119
<p>Excepteur sint occaecat cupidatat non proident.</p>
120-
</div>
120+
</section>
121121

122-
<div class="grid-item">
122+
<section class="grid-item">
123123
<h3>Grid Item 8</h3>
124124
<p>Excepteur sint occaecat cupidatat non proident.</p>
125-
</div>
125+
</section>
126126

127-
<div class="grid-item">
127+
<section class="grid-item">
128128
<h3>Grid Item 9</h3>
129129
<p>Excepteur sint occaecat cupidatat non proident.</p>
130-
</div>
131-
</div>
130+
</section>
131+
</main>
132132
</body>
133133

134134
</html>

fixtures/html/simple.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
<style>
88
body {
99
background-color: #fff;
10+
font-size: 40px;
11+
color: #6d172e;
1012
}
1113

1214
img {

fixtures/html/simple.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ const image = document.querySelector('img');
1212
// }, 16);
1313

1414
const div = document.getElementById('header');
15-
// setInterval(() => {
16-
// const zAxis = Math.floor(15 + Math.sin(Date.now() / 500) * 10);
17-
// div.style.transform = `translate3d(0, 0, ${zAxis}px)`;
18-
// }, 16);
15+
setInterval(() => {
16+
const zAxis = Math.floor(15 + Math.sin(Date.now() / 500) * 10);
17+
div.style.transform = `translate3d(0, 0, ${zAxis}px)`;
18+
}, 16);
1919

2020
console.info('querySelector() =>', document.querySelector('.first'));
2121
{
@@ -28,8 +28,11 @@ console.info('querySelector() =>', document.querySelector('.first'));
2828

2929
const main = document.querySelector('main');
3030
console.info('main.lastChild should be comment node', main.lastElementChild);
31-
main.addEventListener('click', (event) => {
32-
console.info('main click', event);
31+
main.addEventListener('mouseenter', (event) => {
32+
console.info('main mouseenter', event);
33+
});
34+
main.addEventListener('mouseleave', (event) => {
35+
console.info('main mouseleave', event);
3336
});
3437

3538
async function sleep(ms) {

fixtures/html/text-in-flexbox.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@
1010
display: flex;
1111
align-items: center;
1212
justify-content: space-between;
13+
gap: 10px;
1314
}
1415

1516
p {
1617
font-size: 80px;
1718
font-weight: bold;
19+
background-color: rgba(255,0,0,0.2);
1820
}
1921
</style>
2022
</head>

src/client/browser/window.cpp

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <client/dom/document.hpp>
33
#include <client/cssom/rules/css_style_rule.hpp>
44
#include <client/cssom/selectors/matching.hpp>
5+
#include <client/cssom/values/computed/context.hpp>
56
#include <client/html/html_element.hpp>
67

78
#include "./window.hpp"
@@ -11,27 +12,37 @@ namespace browser
1112
using namespace std;
1213
using namespace client_cssom;
1314
using namespace client_cssom::rules;
15+
using namespace client_cssom::values;
1416

15-
Window::Window(TrClientContextPerProcess *clientContext)
17+
Window::Window(TrClientContextPerProcess *client_context)
1618
: dom::DOMEventTarget(),
17-
clientContext_(clientContext)
19+
client_context_(client_context)
1820
{
19-
assert(clientContext_ != nullptr);
2021
}
2122

22-
const CSSStyleDeclaration &Window::getComputedStyle(shared_ptr<dom::Element> element,
23-
optional<string> pseudoElt) const
23+
const ComputedStyle &Window::getComputedStyle(shared_ptr<dom::Node> elementOrTextNode,
24+
optional<string> pseudoElt) const
2425
{
25-
auto htmlElement = dynamic_pointer_cast<dom::HTMLElement>(element);
26-
if (TR_UNLIKELY(htmlElement == nullptr))
27-
throw invalid_argument("The element must be an HTMLElement");
26+
assert(elementOrTextNode != nullptr && elementOrTextNode->isElementOrText() &&
27+
"The element or text node must not be null and must be an element or text node.");
2828

29-
auto computedStyle = document_->styleCache().findStyle(htmlElement);
29+
shared_ptr<ComputedStyle> computedStyle = document_->styleCache().findStyle(elementOrTextNode);
3030
if (computedStyle != nullptr)
3131
return *computedStyle;
3232

33-
computedStyle = document_->styleCache().createStyle(htmlElement, false);
34-
const auto &stylesheets = htmlElement->getOwnerDocumentChecked().styleSheets();
33+
computed::Context context = computed::Context::From(elementOrTextNode);
34+
computedStyle = document_->styleCache().createStyle(elementOrTextNode, false);
35+
computedStyle->update(context);
36+
37+
if (elementOrTextNode->isText())
38+
return *computedStyle; // If it's a text node, return the computed style directly.
39+
40+
// Get the HTML element from the node.
41+
auto htmlElement = dynamic_pointer_cast<dom::HTMLElement>(elementOrTextNode);
42+
assert(htmlElement != nullptr && "The node must be an HTMLElement.");
43+
44+
// Update the style from the stylesheets.
45+
const auto &stylesheets = elementOrTextNode->getOwnerDocumentChecked().styleSheets();
3546
for (auto stylesheet : stylesheets)
3647
{
3748
for (auto rule : stylesheet->cssRules())
@@ -40,14 +51,15 @@ namespace browser
4051
if (styleRule != nullptr)
4152
{
4253
if (selectors::matchesSelectorList(styleRule->selectors(), htmlElement))
43-
computedStyle->update(styleRule->style());
54+
computedStyle->update(styleRule->style(), context);
4455
}
4556
// TODO: handle other types of rules, such as `CSSImportRule`, `CSSMediaRule`, etc.
4657
}
4758
}
4859

49-
auto inlineStyle = htmlElement->style();
50-
computedStyle->update(inlineStyle); // Override the style from the element's.
60+
// Update the style from the element's inline style.
61+
auto elementStyle = htmlElement->style();
62+
computedStyle->update(elementStyle, context); // Override the style from the element's.
5163
return *computedStyle;
5264
}
5365
}

0 commit comments

Comments
 (0)