Skip to content

Commit 66d1048

Browse files
committed
Parse grid and gap CSS properties
grid grid-auto-flow grid-auto-columns grid-auto-rows gap row-gap column-gap
1 parent af645b1 commit 66d1048

File tree

6 files changed

+190
-13
lines changed

6 files changed

+190
-13
lines changed

include/litehtml/grid.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@
77

88
namespace litehtml
99
{
10+
enum grid_auto_flow
11+
{
12+
grid_auto_flow_row = 0x1,
13+
grid_auto_flow_column = 0x2,
14+
grid_auto_flow_dense = 0x10
15+
};
16+
1017
// <grid-line> =
1118
// auto |
1219
// <custom-ident> |
@@ -267,6 +274,12 @@ namespace litehtml
267274

268275
bool from_tokens(const css_token_vector& tokens);
269276
};
277+
278+
struct css_grid_auto_row_columns
279+
{
280+
std::vector<css_grid_template::track_size> value;
281+
bool from_tokens(const css_token_vector& tokens);
282+
};
270283
}
271284

272285
#endif //LITEHTML_GRID_H

include/litehtml/html.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ namespace litehtml
3030
string index_value(int index, const string& strings, char delim = ';');
3131
bool value_in_list(const string& val, const string& strings, char delim = ';');
3232
string::size_type find_close_bracket(const string& s, string::size_type off, char open_b = '(', char close_b = ')');
33-
void split_string(const string& str, string_vector& tokens, const string& delims = whitespace, const string& delims_preserve = "", const string& quote = "\"");
34-
string_vector split_string(const string& str, const string& delims = whitespace, const string& delims_preserve = "", const string& quote = "\"");
33+
void split_string(const string& str, string_vector& tokens, const string& delims = whitespace, const string& delims_preserve = "", const string& quote = "\"", const string& chars_to_trim = "");
34+
string_vector split_string(const string& str, const string& delims = whitespace, const string& delims_preserve = "", const string& quote = "\"", const string& chars_to_trim = "");
3535
void join_string(string& str, const string_vector& tokens, const string& delims);
3636
double t_strtod(const char* string, char** endPtr = nullptr);
3737
string get_escaped_string(const string& in_str);

include/litehtml/string_id.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,13 @@ STRING_ID(
353353
_grid_template_rows_,
354354
_grid_template_columns_,
355355
_grid_template_,
356+
_grid_,
357+
_grid_auto_flow_,
358+
_grid_auto_rows_,
359+
_grid_auto_columns_,
360+
_gap_,
361+
_row_gap_,
362+
_column_gap_
356363
)
357364
#undef STRING_ID
358365
extern const string_id empty_id; // _id("")

include/litehtml/style.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ namespace litehtml
2626
css_token_vector,
2727
css_grid_line,
2828
css_grid_template_areas,
29-
css_grid_template
29+
css_grid_template,
30+
css_grid_auto_row_columns
3031
>
3132
{
3233
bool m_important = false;
@@ -94,7 +95,9 @@ namespace litehtml
9495

9596
void parse_grid_row_col(string_id name, const css_token_vector& tokens, bool important);
9697
void parse_grid_area(const css_token_vector& tokens, bool important);
97-
void parse_grid_template(const css_token_vector& tokens, bool important);
98+
bool parse_grid_template(const css_token_vector& tokens, bool important);
99+
void parse_grid(const css_token_vector& tokens, bool important);
100+
void parse_grid_auto_flow(const css_token_vector& tokens, bool important);
98101

99102
void add_parsed_property(string_id name, const property_value& propval);
100103
void add_length_property(string_id name, css_token val, string keywords, int options, bool important);

src/grid.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,3 +522,17 @@ bool litehtml::css_grid_template::fit_content::parse(const litehtml::css_token &
522522
}
523523
return false;
524524
}
525+
526+
bool litehtml::css_grid_auto_row_columns::from_tokens(const litehtml::css_token_vector &tokens)
527+
{
528+
for(auto iter = tokens.cbegin(); iter != tokens.cend(); ++iter)
529+
{
530+
css_grid_template::track_size ts;
531+
if(ts.parse(iter, tokens.cend()))
532+
{
533+
value.emplace_back(ts);
534+
} else
535+
return false;
536+
}
537+
return true;
538+
}

src/style.cpp

Lines changed: 149 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,56 @@ void style::add_property(string_id name, const css_token_vector& value, const st
529529
parse_grid_template(value, important);
530530
break;
531531

532+
case _grid_auto_flow_:
533+
parse_grid_auto_flow(value, important);
534+
break;
535+
536+
case _grid_:
537+
parse_grid(value, important);
538+
break;
539+
540+
case _grid_auto_columns_:
541+
case _grid_auto_rows_:
542+
{
543+
css_grid_auto_row_columns auto_rc;
544+
if(auto_rc.from_tokens(value))
545+
{
546+
add_parsed_property(name, property_value(auto_rc, important));
547+
}
548+
}
549+
break;
550+
551+
case _row_gap_:
552+
case _column_gap_:
553+
add_length_property(name, val, "normal", f_number|f_length_percentage|f_positive, important);
554+
break;
555+
556+
case _gap_:
557+
{
558+
if(value.size() == 1)
559+
{
560+
css_length length;
561+
if (length.from_token(value[0], f_number|f_length_percentage|f_positive, "normal"))
562+
{
563+
add_parsed_property(_row_gap_, property_value(length, important));
564+
add_parsed_property(_column_gap_, property_value(length, important));
565+
}
566+
} else if(value.size() == 2)
567+
{
568+
css_length row_gap;
569+
css_length column_gap;
570+
if (row_gap.from_token(value[0], f_number|f_length_percentage|f_positive, "normal"))
571+
{
572+
if (column_gap.from_token(value[1], f_number|f_length_percentage|f_positive, "normal"))
573+
{
574+
add_parsed_property(_row_gap_, property_value(row_gap, important));
575+
add_parsed_property(_column_gap_, property_value(column_gap, important));
576+
}
577+
}
578+
}
579+
}
580+
break;
581+
532582
// ============================= CUSTOM PROPERTY =============================
533583

534584
// https://drafts.csswg.org/css-variables-2/#defining-variables
@@ -1627,18 +1677,18 @@ void style::parse_grid_area(const css_token_vector &tokens, bool important)
16271677
// none |
16281678
// [ <'grid-template-rows'> / <'grid-template-columns'> ] |
16291679
// [ <line-names>? <string> <track-size>? <line-names>? ]+ [ / <explicit-track-list> ]?
1630-
void style::parse_grid_template(const css_token_vector &tokens, bool important)
1680+
bool style::parse_grid_template(const css_token_vector &tokens, bool important)
16311681
{
16321682
if(tokens.size() == 1 && tokens[0].type == IDENT && tokens[0].name == "none")
16331683
{
16341684
add_parsed_property(_grid_template_columns_, property_value(css_grid_template(), important));
16351685
add_parsed_property(_grid_template_rows_, property_value(css_grid_template(), important));
16361686
add_parsed_property(_grid_template_areas_, property_value(css_grid_template_areas(), important));
1637-
return;
1687+
return false;
16381688
}
16391689

16401690
auto parts = parse_slash_separated_list(tokens);
1641-
if(parts.empty() || parts.size() > 2) return;
1691+
if(parts.empty() || parts.size() > 2) return false;
16421692

16431693
if(parts.size() == 2)
16441694
{
@@ -1651,7 +1701,7 @@ void style::parse_grid_template(const css_token_vector &tokens, bool important)
16511701
add_parsed_property(_grid_template_columns_, property_value(cols, important));
16521702
add_parsed_property(_grid_template_rows_, property_value(rows, important));
16531703
add_parsed_property(_grid_template_areas_, property_value(css_grid_template_areas(), important));
1654-
return;
1704+
return false;
16551705
}
16561706
}
16571707
}
@@ -1686,33 +1736,123 @@ void style::parse_grid_template(const css_token_vector &tokens, bool important)
16861736
}
16871737
tl.value.emplace_back(ln);
16881738
} else
1689-
return;
1739+
return false;
16901740
} else if((*p_iter).type == STRING)
16911741
{
1692-
if(!areas.from_token((*p_iter))) return;
1742+
if(!areas.from_token((*p_iter))) return false;
16931743
} else
16941744
{
16951745
css_grid_template::track_size ts;
16961746
if(ts.parse(p_iter, parts[0].cend()))
16971747
{
16981748
tl.value.emplace_back(ts);
16991749
} else
1700-
return;
1750+
return false;
17011751
}
17021752
}
17031753

1704-
if(areas.is_none()) return;
1754+
if(areas.is_none()) return false;
17051755

17061756
css_grid_template rows;
17071757
rows.value = tl;
17081758
css_grid_template cols;
17091759
if(parts.size() == 2)
17101760
{
1711-
if(!cols.from_tokens(parts[1])) return;
1761+
if(!cols.from_tokens(parts[1])) return false;
17121762
}
17131763
add_parsed_property(_grid_template_columns_, property_value(cols, important));
17141764
add_parsed_property(_grid_template_rows_, property_value(rows, important));
17151765
add_parsed_property(_grid_template_areas_, property_value(areas, important));
1766+
return true;
1767+
}
1768+
1769+
// <'grid-template'> |
1770+
// <'grid-template-rows'> / [ auto-flow && dense? ] <'grid-auto-columns'>? |
1771+
// [ auto-flow && dense? ] <'grid-auto-rows'>? / <'grid-template-columns'>
1772+
void style::parse_grid(const css_token_vector &tokens, bool important)
1773+
{
1774+
if(parse_grid_template(tokens, important)) return;
1775+
1776+
auto parts = parse_slash_separated_list(tokens);
1777+
if(parts.size() != 2) return;
1778+
1779+
// [ auto-flow && dense? ] <'grid-auto-rows'>? / <'grid-template-columns'>
1780+
if(parts[0][0].type == IDENT && is_one_of(parts[0][0].name, "auto-flow", "dense"))
1781+
{
1782+
css_grid_template cols;
1783+
if(!cols.from_tokens(parts[1])) return;
1784+
int auto_flow = 0;
1785+
if(parts[0][0].name == "auto-flow")
1786+
{
1787+
parts[0].erase(parts[0].begin());
1788+
auto_flow = grid_auto_flow_row;
1789+
}
1790+
if(parts[0][0].type == IDENT && parts[0][0].name == "dense")
1791+
{
1792+
parts[0].erase(parts[0].begin());
1793+
auto_flow = grid_auto_flow_dense;
1794+
}
1795+
if(!(auto_flow & grid_auto_flow_row)) return;
1796+
1797+
css_grid_auto_row_columns auto_rows;
1798+
if(!auto_rows.from_tokens(parts[0])) return;
1799+
1800+
add_parsed_property(_grid_auto_flow_, property_value(auto_flow, important));
1801+
add_parsed_property(_grid_auto_rows_, property_value(auto_rows, important));
1802+
add_parsed_property(_grid_template_columns_, property_value(cols, important));
1803+
}
1804+
// <'grid-template-rows'> / [ auto-flow && dense? ] <'grid-auto-columns'>?
1805+
else if(parts[1][0].type == IDENT && is_one_of(parts[1][0].name, "auto-flow", "dense"))
1806+
{
1807+
css_grid_template rows;
1808+
if(!rows.from_tokens(parts[0])) return;
1809+
int auto_flow = 0;
1810+
if(parts[1][0].name == "auto-flow")
1811+
{
1812+
parts[1].erase(parts[0].begin());
1813+
auto_flow = grid_auto_flow_column;
1814+
}
1815+
if(parts[1][0].type == IDENT && parts[1][0].name == "dense")
1816+
{
1817+
parts[1].erase(parts[1].begin());
1818+
auto_flow = grid_auto_flow_dense;
1819+
}
1820+
if(!(auto_flow & grid_auto_flow_column)) return;
1821+
1822+
css_grid_auto_row_columns auto_cols;
1823+
if(!auto_cols.from_tokens(parts[1])) return;
1824+
1825+
add_parsed_property(_grid_auto_flow_, property_value(auto_flow, important));
1826+
add_parsed_property(_grid_auto_columns_, property_value(auto_cols, important));
1827+
add_parsed_property(_grid_template_rows_, property_value(rows, important));
1828+
}
1829+
}
1830+
1831+
// [ row | column ] || dense
1832+
void style::parse_grid_auto_flow(const css_token_vector &tokens, bool important)
1833+
{
1834+
if(tokens.empty() || tokens.size() > 2) return;
1835+
int auto_flow = 0;
1836+
for(const auto& item : tokens)
1837+
{
1838+
if(item.type == IDENT)
1839+
{
1840+
if(item.name == "row")
1841+
{
1842+
if(auto_flow & (grid_auto_flow_row | grid_auto_flow_column)) return;
1843+
auto_flow |= grid_auto_flow_row;
1844+
} else if(item.name == "column")
1845+
{
1846+
if(auto_flow & (grid_auto_flow_row | grid_auto_flow_column)) return;
1847+
auto_flow |= grid_auto_flow_column;
1848+
} else if(item.name == "dense")
1849+
{
1850+
if(auto_flow & grid_auto_flow_dense) return;
1851+
auto_flow |= grid_auto_flow_dense;
1852+
}
1853+
}
1854+
}
1855+
add_parsed_property(_grid_auto_flow_, property_value(auto_flow, important));
17161856
}
17171857

17181858
} // namespace litehtml

0 commit comments

Comments
 (0)