home readme diff tree note docs

0commit 38d3205d7cb200d013e4ac4404bb67959e0d3549
1Author: lakefox <mason@lakefox.net>
2Date:   Mon Jan 12 20:38:04 2026 -0700
3
4    attr() untested
5
6diff --git a/cat b/cat
7new file mode 100644
8index 0000000..d72af31
9--- /dev/null
10+++ b/cat
11@@ -0,0 +1 @@
12+asd
13diff --git a/include/grim.h b/include/grim.h
14index 07e5ce3..7b1c532 100755
15--- a/include/grim.h
16+++ b/include/grim.h
17@@ -154,7 +154,6 @@ struct StyleList {
18 	public:
19 		StyleList(std::string* sS) : styleString(sS) {}
20 		std::string get(std::string key);
21-		std::vector<Unit> getUnit(std::string key);
22 		void set(std::string key, std::string value);
23 		void remove(std::string key);
24 		std::pair<std::string, std::string> item(size_t index);
25@@ -301,6 +300,10 @@ class IndexedMap {
26 			return map[i].second;
27 		}
28 
29+		std::string key(size_t i) {
30+			return map[i].first;
31+		}
32+
33 		size_t set(std::string key, std::vector<Unit> value) {
34 			for (size_t i = 0; i < map.size(); i++) {
35 				if (map[i].first == key) {
36@@ -503,6 +506,6 @@ For the adapter, it will take a window as a argument to set the adapters capabil
37 Window createWindow();
38 
39 
40-float UnitLengthValue(Node*, const std::vector<Unit>&, size_t, size_t);
41+float UnitLengthValue(Node*, Style*, const std::vector<Unit>&, size_t, size_t);
42 
43 #endif // NODE_H
44diff --git a/playground/css_unit.cc b/playground/css_unit.cc
45index 640ae55..20d759c 100644
46--- a/playground/css_unit.cc
47+++ b/playground/css_unit.cc
48@@ -5,7 +5,7 @@
49 
50 int main() {
51 	Style style{};
52-	std::vector<Unit> test = getUnit(&style, "\"test\"");
53+	std::vector<Unit> test = getUnit(&style, "attr(size type(px), 10)");
54 
55 	std::cout << "Done" << std::endl;
56 }
57diff --git a/playground/unitlengthvalue.cc b/playground/unitlengthvalue.cc
58new file mode 100644
59index 0000000..d8a79a5
60--- /dev/null
61+++ b/playground/unitlengthvalue.cc
62@@ -0,0 +1,53 @@
63+#include "../include/grim.h"
64+#include "../include/parser.h" 
65+#include <string>
66+#include <sstream>
67+#include <vector>
68+#include <iostream>
69+
70+int main() {
71+	std::string html = "<!DOCTYPE html>"
72+			"<html>"
73+				"<head>"
74+					"<title>This is a simple test</title>"
75+					"<link rel=\"stylesheet\" href=\'tests/style.css\'/>"
76+					"<style>h1 {background: red;}</style>"
77+				"</head>"
78+				"<body>"
79+					"<h1 id=\"h1Tag\">Header</h1>"
80+					"<p id=\"paragraph\" class=\"class1 class2\">This is some text for a simple test</p>"
81+					"<div contenteditable=\"true\">"
82+						"<p>this is a only child</p>"
83+					"</div>"
84+					"<input type=\"text\" checked required/>"
85+					"<ul>"
86+						"<li>one</li>"
87+						"<li>two</li>"
88+						"<li>three</li>"
89+						"<li>four</li>"
90+					"</ul>"
91+					"<input type=\"radio\" checked required/>"
92+					"<input type=\"text\" readonly/>"
93+					"<input type=\"text\" disabled/>"
94+					"<textarea></textarea>"
95+					"<textarea readonly></textarea>"
96+					"<textarea disabled></textarea>"
97+				"</body>"
98+			"</html>";
99+
100+
101+	std::stringstream ss(html);
102+
103+	Window window = createWindow();
104+	window.parseHTML(ss);
105+
106+	Node document = window.document;
107+
108+	document.cacheWidth(1000);
109+	document.cacheHeight(700);
110+	document.cacheEM(16);
111+
112+	std::vector<Unit> units = getUnit("mod(13px, 5px)");
113+
114+	std::cout << UnitLengthValue(&document, units, 0, units.size()) << std::endl;
115+}
116diff --git a/playground/window.cc b/playground/window.cc
117index d8a79a5..ed43569 100644
118--- a/playground/window.cc
119+++ b/playground/window.cc
120@@ -7,7 +7,7 @@
121 
122 int main() {
123 	std::string html = "<!DOCTYPE html>"
124-			"<html>"
125+			"<html width=\"100\">"
126 				"<head>"
127 					"<title>This is a simple test</title>"
128 					"<link rel=\"stylesheet\" href=\'tests/style.css\'/>"
129@@ -47,7 +47,7 @@ int main() {
130 	document.cacheHeight(700);
131 	document.cacheEM(16);
132 
133-	std::vector<Unit> units = getUnit("mod(13px, 5px)");
134+	std::vector<Unit> units = getUnit(&window.CSS, "attr(width vw, 10px)");
135 
136-	std::cout << UnitLengthValue(&document, units, 0, units.size()) << std::endl;
137+	std::cout << UnitLengthValue(&document.children[0], &window.CSS, units, 0, units.size()) << std::endl;
138 }
139diff --git a/src/grim.cc b/src/grim.cc
140index 556b914..a2bbff7 100755
141--- a/src/grim.cc
142+++ b/src/grim.cc
143@@ -328,9 +328,6 @@ void ClassList::toggle(std::string value) {
144 // contain the true value of the inline style and still have an
145 // easy to use API for .style. To get all styles, call .length()
146 // and itterate through all items using .item(<size_t>).
147-//
148-// getUnit is a interal method to get styles from the stylelist
149-// as parsed units for rendering
150 
151 void StyleList::createIndex() {
152 	// Update the stored length
153@@ -447,26 +444,6 @@ std::string StyleList::get(std::string key) {
154 	return "";
155 }
156 
157-std::vector<Unit> StyleList::getUnit(std::string key) {
158-	if (!checkIndex()) {
159-		createIndex();
160-	}
161-	for (size_t i = 0; i < indexes.size(); i++) {
162-		int f = std::get<0>(indexes[i]);
163-		int s = std::get<1>(indexes[i]);
164-		std::string slicedKey = styleString->substr(f, s-f);
165-		trimSpace(slicedKey);
166-		if (slicedKey == key) {
167-			int t = std::get<2>(indexes[i]);
168-			std::string value = styleString->substr(s+1, t-(s+1));
169-			trimSpace(value);
170-			return getUnit(value);
171-		}
172-	}
173-	std::vector<Unit> empty;
174-	return empty;
175-}
176-
177 void StyleList::set(std::string key, std::string value) {
178 	if (!checkIndex()) {
179 		createIndex();
180@@ -966,10 +943,12 @@ std::vector<Range> extractUnits(const std::vector<Unit>& units, size_t start, si
181 /*
182 	CAUTION: These values are only correct for top level media queries
183 */
184-float UnitLengthValue(Node* n, const std::vector<Unit>& units, size_t start, size_t end) {
185+float UnitLengthValue(Node* n, Style* style, const std::vector<Unit>& units, size_t start, size_t end) {
186 	float sum = 0;
187 	UnitType op = UnitType::ADD;
188 
189+	std::cout << "CALL START: " << start << " END: " << end << std::endl;
190+
191 	for (size_t i = start; i < end; i++) {
192 		Unit unit = units[i];
193 		UnitType type = unit.type;
194@@ -982,6 +961,7 @@ float UnitLengthValue(Node* n, const std::vector<Unit>& units, size_t start, siz
195 		float v3 = 0;
196 		std::vector<Range> extracted;
197 		UnitType ut;
198+		std::string s = "";
199 
200 		switch (type) {
201 			case UnitType::ADD:
202@@ -1069,7 +1049,7 @@ float UnitLengthValue(Node* n, const std::vector<Unit>& units, size_t start, siz
203 				value = unit.value.FLOAT*n->getWidth();
204 				break;
205 			case UnitType::CALC:
206-				value = UnitLengthValue(n, units, i+1, i+1+unit.value.INT);
207+				value = UnitLengthValue(n, style, units, i+1, i+1+unit.value.INT);
208 				i += unit.value.INT;
209 				break;
210 			case UnitType::MIN:
211@@ -1078,7 +1058,7 @@ float UnitLengthValue(Node* n, const std::vector<Unit>& units, size_t start, siz
212 				v1 = std::numeric_limits<float>::max(); // Store of the min value
213 
214 				for (size_t j = 0; j < extracted.size(); j++) {
215-					v2 = UnitLengthValue(n, units, extracted[j].start, extracted[j].end);
216+					v2 = UnitLengthValue(n, style, units, extracted[j].start, extracted[j].end);
217 
218 					if (v2 < v1) {
219 						v1 = v2;
220@@ -1095,7 +1075,7 @@ float UnitLengthValue(Node* n, const std::vector<Unit>& units, size_t start, siz
221 				v1 = std::numeric_limits<float>::min(); // Store of the max value
222 
223 				for (size_t j = 0; j < extracted.size(); j++) {
224-					v2 = UnitLengthValue(n, units, extracted[j].start, extracted[j].end);
225+					v2 = UnitLengthValue(n, style, units, extracted[j].start, extracted[j].end);
226 
227 					if (v2 > v1) {
228 						v1 = v2;
229@@ -1110,9 +1090,9 @@ float UnitLengthValue(Node* n, const std::vector<Unit>& units, size_t start, siz
230 				extracted = extractUnits(units, i+1, i+1+unit.value.INT);
231 
232 				if (extracted.size() >= 3) {
233-					v1 = UnitLengthValue(n, units, extracted[0].start, extracted[0].end);
234-					v2 = UnitLengthValue(n, units, extracted[1].start, extracted[1].end);
235-					v3 = UnitLengthValue(n, units, extracted[2].start, extracted[2].end);
236+					v1 = UnitLengthValue(n, style, units, extracted[0].start, extracted[0].end);
237+					v2 = UnitLengthValue(n, style, units, extracted[1].start, extracted[1].end);
238+					v3 = UnitLengthValue(n, style, units, extracted[2].start, extracted[2].end);
239 
240 					if (v2 < v1) {
241 						v2 = v1;
242@@ -1134,17 +1114,17 @@ float UnitLengthValue(Node* n, const std::vector<Unit>& units, size_t start, siz
243 				if (extracted.size() == 3) {
244 					ut = units[extracted[0].start].type;
245 
246-					v1 = UnitLengthValue(n, units, extracted[1].start, extracted[1].end);
247-					v2 = UnitLengthValue(n, units, extracted[2].start, extracted[2].end);
248+					v1 = UnitLengthValue(n, style, units, extracted[1].start, extracted[1].end);
249+					v2 = UnitLengthValue(n, style, units, extracted[2].start, extracted[2].end);
250 				} else if (extracted.size() == 2) {
251 					ut = UnitType::NEAREST;
252 
253-					v1 = UnitLengthValue(n, units, extracted[0].start, extracted[0].end);
254-					v2 = UnitLengthValue(n, units, extracted[1].start, extracted[1].end);
255+					v1 = UnitLengthValue(n, style, units, extracted[0].start, extracted[0].end);
256+					v2 = UnitLengthValue(n, style, units, extracted[1].start, extracted[1].end);
257 				} else if (extracted.size() == 1) {
258 					ut = UnitType::NEAREST;
259 
260-					v1 = UnitLengthValue(n, units, extracted[0].start, extracted[0].end);
261+					v1 = UnitLengthValue(n, style, units, extracted[0].start, extracted[0].end);
262 					v2 = 1.0f;
263 				}
264 
265@@ -1165,8 +1145,8 @@ float UnitLengthValue(Node* n, const std::vector<Unit>& units, size_t start, siz
266 				extracted = extractUnits(units, i+1, i+1+unit.value.INT);
267 
268 				if (extracted.size() == 2) {
269-					v1 = UnitLengthValue(n, units, extracted[0].start, extracted[0].end);
270-					v2 = UnitLengthValue(n, units, extracted[1].start, extracted[1].end);
271+					v1 = UnitLengthValue(n, style, units, extracted[0].start, extracted[0].end);
272+					v2 = UnitLengthValue(n, style, units, extracted[1].start, extracted[1].end);
273 
274 					value = std::fmod(v1, v2);
275 				}
276@@ -1177,9 +1157,9 @@ float UnitLengthValue(Node* n, const std::vector<Unit>& units, size_t start, siz
277 				extracted = extractUnits(units, i+1, i+1+unit.value.INT);
278 
279 				if (extracted.size() >= 3) {
280-					v1 = UnitLengthValue(n, units, extracted[0].start, extracted[0].end);
281-					v2 = UnitLengthValue(n, units, extracted[1].start, extracted[1].end);
282-					v3 = UnitLengthValue(n, units, extracted[2].start, extracted[2].end);
283+					v1 = UnitLengthValue(n, style, units, extracted[0].start, extracted[0].end);
284+					v2 = UnitLengthValue(n, style, units, extracted[1].start, extracted[1].end);
285+					v3 = UnitLengthValue(n, style, units, extracted[2].start, extracted[2].end);
286 
287 					// (progress - progress start) / (progress end - progress start)
288 					value = (v1-v2)/(v3-v2);
289@@ -1192,8 +1172,8 @@ float UnitLengthValue(Node* n, const std::vector<Unit>& units, size_t start, siz
290 				extracted = extractUnits(units, i+1, i+1+unit.value.INT);
291 
292 				if (extracted.size() == 2) {
293-					v1 = UnitLengthValue(n, units, extracted[0].start, extracted[0].end);
294-					v2 = UnitLengthValue(n, units, extracted[1].start, extracted[1].end);
295+					v1 = UnitLengthValue(n, style, units, extracted[0].start, extracted[0].end);
296+					v2 = UnitLengthValue(n, style, units, extracted[1].start, extracted[1].end);
297 
298 					value = std::fmodf(v1, v2);
299 				}
300@@ -1201,32 +1181,32 @@ float UnitLengthValue(Node* n, const std::vector<Unit>& units, size_t start, siz
301 				i += unit.value.INT;
302 				break;
303 			case UnitType::SIN:
304-				v1 = UnitLengthValue(n, units, i+1, i+1+unit.value.INT);
305+				v1 = UnitLengthValue(n, style, units, i+1, i+1+unit.value.INT);
306 				value = std::sinf(v1);
307 				i += unit.value.INT;
308 				break;
309 			case UnitType::COS:
310-				v1 = UnitLengthValue(n, units, i+1, i+1+unit.value.INT);
311+				v1 = UnitLengthValue(n, style, units, i+1, i+1+unit.value.INT);
312 				value = std::cosf(v1);
313 				i += unit.value.INT;
314 				break;
315 			case UnitType::TAN:
316-				v1 = UnitLengthValue(n, units, i+1, i+1+unit.value.INT);
317+				v1 = UnitLengthValue(n, style, units, i+1, i+1+unit.value.INT);
318 				value = std::tanf(v1);
319 				i += unit.value.INT;
320 				break;
321 			case UnitType::ASIN:
322-				v1 = UnitLengthValue(n, units, i+1, i+1+unit.value.INT);
323+				v1 = UnitLengthValue(n, style, units, i+1, i+1+unit.value.INT);
324 				value = std::asinf(v1);
325 				i += unit.value.INT;
326 				break;
327 			case UnitType::ACOS:
328-				v1 = UnitLengthValue(n, units, i+1, i+1+unit.value.INT);
329+				v1 = UnitLengthValue(n, style, units, i+1, i+1+unit.value.INT);
330 				value = std::acosf(v1);
331 				i += unit.value.INT;
332 				break;
333 			case UnitType::ATAN:
334-				v1 = UnitLengthValue(n, units, i+1, i+1+unit.value.INT);
335+				v1 = UnitLengthValue(n, style, units, i+1, i+1+unit.value.INT);
336 				value = std::atanf(v1);
337 				i += unit.value.INT;
338 				break;
339@@ -1234,8 +1214,8 @@ float UnitLengthValue(Node* n, const std::vector<Unit>& units, size_t start, siz
340 				extracted = extractUnits(units, i+1, i+1+unit.value.INT);
341 
342 				if (extracted.size() == 2) {
343-					v1 = UnitLengthValue(n, units, extracted[0].start, extracted[0].end);
344-					v2 = UnitLengthValue(n, units, extracted[1].start, extracted[1].end);
345+					v1 = UnitLengthValue(n, style, units, extracted[0].start, extracted[0].end);
346+					v2 = UnitLengthValue(n, style, units, extracted[1].start, extracted[1].end);
347 
348 					value = std::atan2f(v1, v2);
349 				}
350@@ -1245,15 +1225,15 @@ float UnitLengthValue(Node* n, const std::vector<Unit>& units, size_t start, siz
351 				extracted = extractUnits(units, i+1, i+1+unit.value.INT);
352 
353 				if (extracted.size() == 2) {
354-					v1 = UnitLengthValue(n, units, extracted[0].start, extracted[0].end);
355-					v2 = UnitLengthValue(n, units, extracted[1].start, extracted[1].end);
356+					v1 = UnitLengthValue(n, style, units, extracted[0].start, extracted[0].end);
357+					v2 = UnitLengthValue(n, style, units, extracted[1].start, extracted[1].end);
358 
359 					value = std::powf(v1, v2);
360 				}
361 				i += unit.value.INT;
362 				break;
363 			case UnitType::SQRT:
364-				v1 = UnitLengthValue(n, units, i+1, i+1+unit.value.INT);
365+				v1 = UnitLengthValue(n, style, units, i+1, i+1+unit.value.INT);
366 				value = std::sqrtf(v1);
367 				i += unit.value.INT;
368 				break;
369@@ -1262,7 +1242,7 @@ float UnitLengthValue(Node* n, const std::vector<Unit>& units, size_t start, siz
370 
371 				v2 = 0;
372 				for (size_t j = 0; j < extracted.size(); j++) {
373-					v1 = UnitLengthValue(n, units, extracted[j].start, extracted[j].end);
374+					v1 = UnitLengthValue(n, style, units, extracted[j].start, extracted[j].end);
375 
376 					v2 += std::powf(v1, 2);
377 				}
378@@ -1275,12 +1255,12 @@ float UnitLengthValue(Node* n, const std::vector<Unit>& units, size_t start, siz
379 				extracted = extractUnits(units, i+1, i+1+unit.value.INT);
380 
381 				if (extracted.size() == 2) {
382-					v1 = UnitLengthValue(n, units, extracted[0].start, extracted[0].end);
383-					v2 = UnitLengthValue(n, units, extracted[1].start, extracted[1].end);
384+					v1 = UnitLengthValue(n, style, units, extracted[0].start, extracted[0].end);
385+					v2 = UnitLengthValue(n, style, units, extracted[1].start, extracted[1].end);
386 
387 					value = std::logf(v1) / std::logf(v2);
388 				} else if (extracted.size() == 1) {
389-					v1 = UnitLengthValue(n, units, extracted[0].start, extracted[0].end);
390+					v1 = UnitLengthValue(n, style, units, extracted[0].start, extracted[0].end);
391 
392 					value = std::logf(v1);
393 				}
394@@ -1288,12 +1268,12 @@ float UnitLengthValue(Node* n, const std::vector<Unit>& units, size_t start, siz
395 				i += unit.value.INT;
396 				break;
397 			case UnitType::EXP:
398-				v1 = UnitLengthValue(n, units, i+1, i+1+unit.value.INT);
399+				v1 = UnitLengthValue(n, style, units, i+1, i+1+unit.value.INT);
400 				value = std::expf(v1);
401 				i += unit.value.INT;
402 				break;
403 			case UnitType::ABS:
404-				v1 = UnitLengthValue(n, units, i+1, i+1+unit.value.INT);
405+				v1 = UnitLengthValue(n, style, units, i+1, i+1+unit.value.INT);
406 
407 				if (v1 < 0) v1 *= -1;
408 				value = v1;
409@@ -1301,7 +1281,7 @@ float UnitLengthValue(Node* n, const std::vector<Unit>& units, size_t start, siz
410 				i += unit.value.INT;
411 				break;
412 			case UnitType::SIGN:
413-				v1 = UnitLengthValue(n, units, i+1, i+1+unit.value.INT);
414+				v1 = UnitLengthValue(n, style, units, i+1, i+1+unit.value.INT);
415 
416 				if (v1 > 0) {
417 					value = 1;
418@@ -1313,6 +1293,35 @@ float UnitLengthValue(Node* n, const std::vector<Unit>& units, size_t start, siz
419 
420 				i += unit.value.INT;
421 				break;
422+			case UnitType::ATTR:
423+				extracted = extractUnits(units, i+1, i+1+unit.value.INT);
424+
425+				if (extracted.size() == 3) {
426+					if (units[extracted[0].start].type == UnitType::VAR) {
427+						s = n->getAttribute(style->variables.key(units[extracted[0].start].value.INT));
428+
429+						if (!s.empty()) {
430+							// attr(size px, 10)
431+							// s = n->getAttribute(size) size="20"
432+							std::vector<Unit> us = getUnit(style, s);
433+							// us = {NUMBER, 20}
434+							// extracted[1] == {type: PX} || {type::TYPE}
435+							// Add the type of the next if the type is inside of type(px) or just add the type px
436+							if (units[extracted[1].start].type == UnitType::TYPE && extracted[1].end-extracted[1].start >= 2) {
437+								us[0].type = units[extracted[1].start+1].type;
438+							} else {
439+								us[0].type = units[extracted[1].start].type;
440+							}
441+
442+							i = extracted[1].end;
443+							value = UnitLengthValue(n, style, us, 0, us.size());
444+						} else {
445+							// Default value
446+							value = UnitLengthValue(n, style, units, extracted[2].start, extracted[2].end);
447+							i = extracted[2].end;
448+						}
449+					}
450+				}
451 
452 			// Need to add variable injection and group handling
453 		}
454@@ -1335,6 +1344,7 @@ float UnitLengthValue(Node* n, const std::vector<Unit>& units, size_t start, siz
455 		}
456 	}
457 	
458+	std::cout << "SUM: " << sum << std::endl;
459 	return sum;
460 }
461