home
readme
diff
tree
note
docs
0commit 5cf22848ea3b4e97961ad80f45f4a38f7a0a54ab
1Author: Mason Wright <mason@lakefox.net>
2Date: Sun Jul 13 18:41:04 2025 -0600
3
4 StyleList is tested
5
6diff --git a/include/grim.h b/include/grim.h
7index d10e9d0..744ffa5 100644
8--- a/include/grim.h
9+++ b/include/grim.h
10@@ -107,6 +107,7 @@ class Node {
11 StyleList(Node* node) : self(node) {}
12 std::string get(std::string key);
13 void set(std::string key, std::string value);
14+ void remove(std::string key);
15 std::pair<std::string, std::string> item(size_t index);
16 size_t length();
17 };
18diff --git a/src/grim.cc b/src/grim.cc
19index a6975b6..846449f 100755
20--- a/src/grim.cc
21+++ b/src/grim.cc
22@@ -306,7 +306,11 @@ void Node::StyleList::createIndex() {
23 if (keyFound) {
24 if (secondNonWhiteSpace) {
25 if (s == ';' || i >= len-1) {
26- end = i;
27+ if (i >= len-1 && s != ';') {
28+ end = i+1;
29+ } else {
30+ end = i;
31+ }
32 indexes.push_back({firstLetter, splitPoint, end});
33 firstNonWhiteSpace = false;
34 secondNonWhiteSpace = false;
35@@ -354,11 +358,11 @@ std::pair<std::string, std::string> Node::StyleList::item(size_t index) {
36
37 int f = std::get<0>(indexes[index]);
38 int s = std::get<1>(indexes[index]);
39- property.first = styles.substr(f, f-s);
40+ property.first = styles.substr(f, s-f);
41 trimSpace(property.first);
42
43 int t = std::get<2>(indexes[index]);
44- property.second = styles.substr(s, t-s);
45+ property.second = styles.substr(s+1, t-(s+1));
46 trimSpace(property.second);
47 return property;
48
49@@ -396,15 +400,48 @@ void Node::StyleList::set(std::string key, std::string value) {
50 createIndex();
51 }
52 std::string styles = self->attributes["style"];
53+
54 for (size_t i = 0; i < indexes.size(); i++) {
55 int f = std::get<0>(indexes[i]);
56 int s = std::get<1>(indexes[i]);
57- std::string slicedKey = styles.substr(f, f-s);
58+ std::string slicedKey = styles.substr(f, s-f);
59 trimSpace(slicedKey);
60 if (slicedKey == key) {
61 int t = std::get<2>(indexes[i]);
62 self->attributes["style"] = styles.substr(0, f) +" "+key+":"+value+";"+styles.substr(t);
63- break;
64+ // Return early to skip the appending value;
65+ return;
66+ }
67+ }
68+
69+ // If the property wasn't replaced then add it
70+
71+ char lastChar = styles[std::get<2>(indexes[indexes.size()-1])];
72+
73+ if (lastChar == ';') {
74+ self->attributes["style"] += " "+key+":"+value+";";
75+ } else {
76+ // If the user didn't terminate the last style
77+ // terminate it for them
78+ self->attributes["style"] += "; "+key+":"+value+";";
79+ }
80+}
81+
82+void Node::StyleList::remove(std::string key) {
83+ if (!checkIndex()) {
84+ createIndex();
85+ }
86+ std::string styles = self->attributes["style"];
87+
88+ for (size_t i = 0; i < indexes.size(); i++) {
89+ int f = std::get<0>(indexes[i]);
90+ int s = std::get<1>(indexes[i]);
91+ std::string slicedKey = styles.substr(f, s-f);
92+ trimSpace(slicedKey);
93+ if (slicedKey == key) {
94+ int t = std::get<2>(indexes[i]);
95+ self->attributes["style"] = styles.substr(0, f) + styles.substr(t);
96+ return;
97 }
98 }
99 }
100@@ -728,7 +765,6 @@ bool testSelector(Node* node, std::vector<std::vector<std::string>> selector) {
101 // By the time we get here, we know the right most selector some what matches
102 // so now if it is a compound selector we should see if the parent('s) some what match
103
104- // !TODO: Add support for *
105 if (selector.size() > 1) {
106 // If a selector is made up of several different selectors
107 // ie {{"h1"}, {"h2"}, {"h3"}}
108diff --git a/tests/html_node.cc b/tests/html_node.cc
109index bcddce2..4f5a4d6 100644
110--- a/tests/html_node.cc
111+++ b/tests/html_node.cc
112@@ -82,4 +82,56 @@ TEST_CASE("StyleList", "[html]") {
113 REQUIRE(div->style.get("background") == "white");
114 REQUIRE(div->style.get("font-size") == "12px");
115 }
116+
117+ SECTION("StyleList can change an existing property") {
118+ div->style.set("background", "red");
119+
120+ REQUIRE(div->style.get("background") == "red");
121+ }
122+
123+ SECTION("StyleList can add a new property") {
124+ div->style.set("color", "black");
125+
126+ REQUIRE(div->style.get("color") == "black");
127+ REQUIRE(div->style.get("background") == "white");
128+ REQUIRE(div->style.get("font-size") == "12px");
129+ }
130+
131+ SECTION("StyleList can add a new property without a ending ;") {
132+ div->setAttribute("style", "background: white; font-size: 12px");
133+
134+ div->style.set("color", "black");
135+
136+ REQUIRE(div->style.get("color") == "black");
137+ REQUIRE(div->style.get("background") == "white");
138+ REQUIRE(div->style.get("font-size") == "12px");
139+ }
140+
141+ SECTION("StyleList can remove a property") {
142+ div->style.remove("font-size");
143+
144+ REQUIRE(div->style.get("background") == "white");
145+ REQUIRE(div->style.get("font-size") == "");
146+ }
147+
148+ SECTION("StyleList can remove a property without a ending ;") {
149+ div->setAttribute("style", "background: white; font-size: 12px");
150+
151+ div->style.remove("font-size");
152+
153+ REQUIRE(div->style.get("background") == "white");
154+ REQUIRE(div->style.get("font-size") == "");
155+ }
156+
157+ SECTION("StyleList can itterate through all styles") {
158+ REQUIRE(div->style.length() == 2);
159+
160+ auto bg = div->style.item(0);
161+ REQUIRE(bg.first == "background");
162+ REQUIRE(bg.second == "white");
163+
164+ auto fs = div->style.item(1);
165+ REQUIRE(fs.first == "font-size");
166+ REQUIRE(fs.second == "12px");
167+ }
168 }