1package css
2
3// Keyword is a computed CSS enumerated value. The documented property grammar
4// supplies the possible values for each field.
5type Keyword uint8
6
7const (
8 KeywordNone Keyword = iota
9 KeywordAuto
10 KeywordBlock
11 KeywordFlex
12 KeywordContentBox
13 KeywordBorderBox
14 KeywordRow
15 KeywordColumn
16 KeywordNowrap
17 KeywordWrap
18 KeywordFlexStart
19 KeywordFlexEnd
20 KeywordCenter
21 KeywordSpaceBetween
22 KeywordSpaceAround
23 KeywordSpaceEvenly
24 KeywordStretch
25 KeywordVisible
26 KeywordHidden
27 KeywordScroll
28 KeywordNormal
29 KeywordItalic
30 KeywordOblique
31 KeywordStart
32 KeywordEnd
33 KeywordLeft
34 KeywordRight
35 KeywordDefault
36 KeywordPointer
37 KeywordText
38 KeywordNotAllowed
39 KeywordSolid
40 KeywordNumber
41)
42
43var keywordNames = []string{"none", "auto", "block", "flex", "content-box", "border-box", "row", "column", "nowrap", "wrap", "flex-start", "flex-end", "center", "space-between", "space-around", "space-evenly", "stretch", "visible", "hidden", "scroll", "normal", "italic", "oblique", "start", "end", "left", "right", "default", "pointer", "text", "not-allowed", "solid", "number"}
44
45func keyword(s string) Keyword {
46 for i, k := range keywordNames {
47 if k == s {
48 return Keyword(i)
49 }
50 }
51 return KeywordNone
52}
53
54// Sides and Corners follow clockwise CSS order.
55type LengthSides struct{ Top, Right, Bottom, Left Length }
56type ColorSides struct{ Top, Right, Bottom, Left Color }
57type KeywordSides struct{ Top, Right, Bottom, Left Keyword }
58type Radii struct{ TopLeft, TopRight, BottomRight, BottomLeft Length }
59
60// Style is a computed, immutable value. Slice backing arrays are shared: do not
61// mutate a returned Style or any of its slices.
62type Style struct {
63 Color Color
64 Opacity float64
65 BackgroundColor Color
66 BorderWidth LengthSides
67 BorderStyle KeywordSides
68 BorderColor ColorSides
69 BorderRadius Radii
70 OutlineWidth Length
71 OutlineStyle Keyword
72 OutlineColor Color
73 OutlineOffset Length
74 BoxShadow []Shadow
75 Margin, Padding LengthSides
76 Width, Height, MinWidth, MinHeight, MaxWidth, MaxHeight Length
77 BoxSizing, Display, FlexDirection, FlexWrap Keyword
78 FlexGrow, FlexShrink float64
79 FlexBasis, RowGap, ColumnGap Length
80 JustifyContent, AlignItems, AlignSelf, OverflowX, OverflowY Keyword
81 FontFamily []string
82 FontSize Length
83 FontWeight float64
84 FontStyle Keyword
85 LineHeight Length
86 LineHeightNumber float64
87 LineHeightKind Keyword
88 TextAlign Keyword
89 LetterSpacing Length
90 LetterSpacingNormal bool
91 Cursor Keyword
92 AccentColor Color // checkbox, radio and slider indicators
93}
94
95// propertyID indexes the fixed cascade winner array.
96type propertyID uint8
97
98const (
99 p_color propertyID = iota
100 p_opacity
101 p_background_color
102 p_outline_width
103 p_outline_style
104 p_outline_color
105 p_outline_offset
106 p_box_shadow
107 p_width
108 p_height
109 p_min_width
110 p_min_height
111 p_max_width
112 p_max_height
113 p_box_sizing
114 p_display
115 p_flex_direction
116 p_flex_wrap
117 p_flex_grow
118 p_flex_shrink
119 p_flex_basis
120 p_row_gap
121 p_column_gap
122 p_justify_content
123 p_align_items
124 p_align_self
125 p_overflow_x
126 p_overflow_y
127 p_font_family
128 p_font_size
129 p_font_weight
130 p_font_style
131 p_line_height
132 p_text_align
133 p_letter_spacing
134 p_cursor
135 p_margin_top
136 p_padding_top
137 p_border_top_width
138 p_border_top_style
139 p_border_top_color
140 p_margin_right
141 p_padding_right
142 p_border_right_width
143 p_border_right_style
144 p_border_right_color
145 p_margin_bottom
146 p_padding_bottom
147 p_border_bottom_width
148 p_border_bottom_style
149 p_border_bottom_color
150 p_margin_left
151 p_padding_left
152 p_border_left_width
153 p_border_left_style
154 p_border_left_color
155 p_border_top_left_radius
156 p_border_top_right_radius
157 p_border_bottom_right_radius
158 p_border_bottom_left_radius
159 p_accent_color
160 propertyCount
161)
162
163var propertyNames = [...]string{"color", "opacity", "background-color", "outline-width", "outline-style", "outline-color", "outline-offset", "box-shadow", "width", "height", "min-width", "min-height", "max-width", "max-height", "box-sizing", "display", "flex-direction", "flex-wrap", "flex-grow", "flex-shrink", "flex-basis", "row-gap", "column-gap", "justify-content", "align-items", "align-self", "overflow-x", "overflow-y", "font-family", "font-size", "font-weight", "font-style", "line-height", "text-align", "letter-spacing", "cursor", "margin-top", "padding-top", "border-top-width", "border-top-style", "border-top-color", "margin-right", "padding-right", "border-right-width", "border-right-style", "border-right-color", "margin-bottom", "padding-bottom", "border-bottom-width", "border-bottom-style", "border-bottom-color", "margin-left", "padding-left", "border-left-width", "border-left-style", "border-left-color", "border-top-left-radius", "border-top-right-radius", "border-bottom-right-radius", "border-bottom-left-radius", "accent-color"}
164
165func propertyIndex(n string) (propertyID, bool) {
166 switch n {
167 case "color":
168 return p_color, true
169 case "opacity":
170 return p_opacity, true
171 case "background-color":
172 return p_background_color, true
173 case "outline-width":
174 return p_outline_width, true
175 case "outline-style":
176 return p_outline_style, true
177 case "outline-color":
178 return p_outline_color, true
179 case "outline-offset":
180 return p_outline_offset, true
181 case "box-shadow":
182 return p_box_shadow, true
183 case "width":
184 return p_width, true
185 case "height":
186 return p_height, true
187 case "min-width":
188 return p_min_width, true
189 case "min-height":
190 return p_min_height, true
191 case "max-width":
192 return p_max_width, true
193 case "max-height":
194 return p_max_height, true
195 case "box-sizing":
196 return p_box_sizing, true
197 case "display":
198 return p_display, true
199 case "flex-direction":
200 return p_flex_direction, true
201 case "flex-wrap":
202 return p_flex_wrap, true
203 case "flex-grow":
204 return p_flex_grow, true
205 case "flex-shrink":
206 return p_flex_shrink, true
207 case "flex-basis":
208 return p_flex_basis, true
209 case "row-gap":
210 return p_row_gap, true
211 case "column-gap":
212 return p_column_gap, true
213 case "justify-content":
214 return p_justify_content, true
215 case "align-items":
216 return p_align_items, true
217 case "align-self":
218 return p_align_self, true
219 case "overflow-x":
220 return p_overflow_x, true
221 case "overflow-y":
222 return p_overflow_y, true
223 case "font-family":
224 return p_font_family, true
225 case "font-size":
226 return p_font_size, true
227 case "font-weight":
228 return p_font_weight, true
229 case "font-style":
230 return p_font_style, true
231 case "line-height":
232 return p_line_height, true
233 case "text-align":
234 return p_text_align, true
235 case "letter-spacing":
236 return p_letter_spacing, true
237 case "cursor":
238 return p_cursor, true
239 case "margin-top":
240 return p_margin_top, true
241 case "padding-top":
242 return p_padding_top, true
243 case "border-top-width":
244 return p_border_top_width, true
245 case "border-top-style":
246 return p_border_top_style, true
247 case "border-top-color":
248 return p_border_top_color, true
249 case "margin-right":
250 return p_margin_right, true
251 case "padding-right":
252 return p_padding_right, true
253 case "border-right-width":
254 return p_border_right_width, true
255 case "border-right-style":
256 return p_border_right_style, true
257 case "border-right-color":
258 return p_border_right_color, true
259 case "margin-bottom":
260 return p_margin_bottom, true
261 case "padding-bottom":
262 return p_padding_bottom, true
263 case "border-bottom-width":
264 return p_border_bottom_width, true
265 case "border-bottom-style":
266 return p_border_bottom_style, true
267 case "border-bottom-color":
268 return p_border_bottom_color, true
269 case "margin-left":
270 return p_margin_left, true
271 case "padding-left":
272 return p_padding_left, true
273 case "border-left-width":
274 return p_border_left_width, true
275 case "border-left-style":
276 return p_border_left_style, true
277 case "border-left-color":
278 return p_border_left_color, true
279 case "border-top-left-radius":
280 return p_border_top_left_radius, true
281 case "border-top-right-radius":
282 return p_border_top_right_radius, true
283 case "border-bottom-right-radius":
284 return p_border_bottom_right_radius, true
285 case "border-bottom-left-radius":
286 return p_border_bottom_left_radius, true
287 case "accent-color":
288 return p_accent_color, true
289 }
290 return 0, false
291}
292func (s *Style) set(n propertyID, v Value) {
293 switch n {
294 case p_color:
295 s.Color = v.Color
296 case p_opacity:
297 s.Opacity = v.Number
298 case p_background_color:
299 s.BackgroundColor = v.Color
300 case p_outline_width:
301 s.OutlineWidth = v.Length
302 case p_outline_style:
303 s.OutlineStyle = keyword(v.Keyword)
304 case p_outline_color:
305 s.OutlineColor = v.Color
306 case p_outline_offset:
307 s.OutlineOffset = v.Length
308 case p_box_shadow:
309 s.BoxShadow = v.Shadows
310 case p_width:
311 s.Width = v.Length
312 case p_height:
313 s.Height = v.Length
314 case p_min_width:
315 s.MinWidth = v.Length
316 case p_min_height:
317 s.MinHeight = v.Length
318 case p_max_width:
319 s.MaxWidth = v.Length
320 case p_max_height:
321 s.MaxHeight = v.Length
322 case p_box_sizing:
323 s.BoxSizing = keyword(v.Keyword)
324 case p_display:
325 s.Display = keyword(v.Keyword)
326 case p_flex_direction:
327 s.FlexDirection = keyword(v.Keyword)
328 case p_flex_wrap:
329 s.FlexWrap = keyword(v.Keyword)
330 case p_flex_grow:
331 s.FlexGrow = v.Number
332 case p_flex_shrink:
333 s.FlexShrink = v.Number
334 case p_flex_basis:
335 s.FlexBasis = v.Length
336 case p_row_gap:
337 s.RowGap = v.Length
338 case p_column_gap:
339 s.ColumnGap = v.Length
340 case p_justify_content:
341 s.JustifyContent = keyword(v.Keyword)
342 case p_align_items:
343 s.AlignItems = keyword(v.Keyword)
344 case p_align_self:
345 s.AlignSelf = keyword(v.Keyword)
346 case p_overflow_x:
347 s.OverflowX = keyword(v.Keyword)
348 case p_overflow_y:
349 s.OverflowY = keyword(v.Keyword)
350 case p_font_family:
351 s.FontFamily = v.Families
352 case p_font_size:
353 s.FontSize = v.Length
354 case p_font_weight:
355 s.FontWeight = v.Number
356 case p_font_style:
357 s.FontStyle = keyword(v.Keyword)
358 case p_line_height:
359 s.LineHeight = v.Length
360 s.LineHeightKind = keyword(v.Keyword)
361 s.LineHeightNumber = v.Number
362 case p_text_align:
363 s.TextAlign = keyword(v.Keyword)
364 case p_letter_spacing:
365 s.LetterSpacing = v.Length
366 s.LetterSpacingNormal = v.Keyword == "normal"
367 case p_cursor:
368 s.Cursor = keyword(v.Keyword)
369 case p_margin_top:
370 s.Margin.Top = v.Length
371 case p_padding_top:
372 s.Padding.Top = v.Length
373 case p_border_top_width:
374 s.BorderWidth.Top = v.Length
375 case p_border_top_style:
376 s.BorderStyle.Top = keyword(v.Keyword)
377 case p_border_top_color:
378 s.BorderColor.Top = v.Color
379 case p_margin_right:
380 s.Margin.Right = v.Length
381 case p_padding_right:
382 s.Padding.Right = v.Length
383 case p_border_right_width:
384 s.BorderWidth.Right = v.Length
385 case p_border_right_style:
386 s.BorderStyle.Right = keyword(v.Keyword)
387 case p_border_right_color:
388 s.BorderColor.Right = v.Color
389 case p_margin_bottom:
390 s.Margin.Bottom = v.Length
391 case p_padding_bottom:
392 s.Padding.Bottom = v.Length
393 case p_border_bottom_width:
394 s.BorderWidth.Bottom = v.Length
395 case p_border_bottom_style:
396 s.BorderStyle.Bottom = keyword(v.Keyword)
397 case p_border_bottom_color:
398 s.BorderColor.Bottom = v.Color
399 case p_margin_left:
400 s.Margin.Left = v.Length
401 case p_padding_left:
402 s.Padding.Left = v.Length
403 case p_border_left_width:
404 s.BorderWidth.Left = v.Length
405 case p_border_left_style:
406 s.BorderStyle.Left = keyword(v.Keyword)
407 case p_border_left_color:
408 s.BorderColor.Left = v.Color
409 case p_border_top_left_radius:
410 s.BorderRadius.TopLeft = v.Length
411 case p_border_top_right_radius:
412 s.BorderRadius.TopRight = v.Length
413 case p_border_bottom_right_radius:
414 s.BorderRadius.BottomRight = v.Length
415 case p_border_bottom_left_radius:
416 s.BorderRadius.BottomLeft = v.Length
417 case p_accent_color:
418 s.AccentColor = v.Color
419 }
420}
421func (s *Style) value(n propertyID) Value {
422 var v Value
423 switch n {
424 case p_color:
425 v.Color = s.Color
426 case p_opacity:
427 v.Number = s.Opacity
428 case p_background_color:
429 v.Color = s.BackgroundColor
430 case p_outline_width:
431 v.Length = s.OutlineWidth
432 case p_outline_style:
433 v.Keyword = keywordNames[s.OutlineStyle]
434 case p_outline_color:
435 v.Color = s.OutlineColor
436 case p_outline_offset:
437 v.Length = s.OutlineOffset
438 case p_box_shadow:
439 v.Shadows = s.BoxShadow
440 case p_width:
441 v.Length = s.Width
442 case p_height:
443 v.Length = s.Height
444 case p_min_width:
445 v.Length = s.MinWidth
446 case p_min_height:
447 v.Length = s.MinHeight
448 case p_max_width:
449 v.Length = s.MaxWidth
450 case p_max_height:
451 v.Length = s.MaxHeight
452 case p_box_sizing:
453 v.Keyword = keywordNames[s.BoxSizing]
454 case p_display:
455 v.Keyword = keywordNames[s.Display]
456 case p_flex_direction:
457 v.Keyword = keywordNames[s.FlexDirection]
458 case p_flex_wrap:
459 v.Keyword = keywordNames[s.FlexWrap]
460 case p_flex_grow:
461 v.Number = s.FlexGrow
462 case p_flex_shrink:
463 v.Number = s.FlexShrink
464 case p_flex_basis:
465 v.Length = s.FlexBasis
466 case p_row_gap:
467 v.Length = s.RowGap
468 case p_column_gap:
469 v.Length = s.ColumnGap
470 case p_justify_content:
471 v.Keyword = keywordNames[s.JustifyContent]
472 case p_align_items:
473 v.Keyword = keywordNames[s.AlignItems]
474 case p_align_self:
475 v.Keyword = keywordNames[s.AlignSelf]
476 case p_overflow_x:
477 v.Keyword = keywordNames[s.OverflowX]
478 case p_overflow_y:
479 v.Keyword = keywordNames[s.OverflowY]
480 case p_font_family:
481 v.Families = s.FontFamily
482 case p_font_size:
483 v.Length = s.FontSize
484 case p_font_weight:
485 v.Number = s.FontWeight
486 case p_font_style:
487 v.Keyword = keywordNames[s.FontStyle]
488 case p_line_height:
489 v.Length = s.LineHeight
490 v.Keyword = keywordNames[s.LineHeightKind]
491 v.Number = s.LineHeightNumber
492 case p_text_align:
493 v.Keyword = keywordNames[s.TextAlign]
494 case p_letter_spacing:
495 v.Length = s.LetterSpacing
496 if s.LetterSpacingNormal {
497 v.Keyword = "normal"
498 }
499 case p_cursor:
500 v.Keyword = keywordNames[s.Cursor]
501 case p_margin_top:
502 v.Length = s.Margin.Top
503 case p_padding_top:
504 v.Length = s.Padding.Top
505 case p_border_top_width:
506 v.Length = s.BorderWidth.Top
507 case p_border_top_style:
508 v.Keyword = keywordNames[s.BorderStyle.Top]
509 case p_border_top_color:
510 v.Color = s.BorderColor.Top
511 case p_margin_right:
512 v.Length = s.Margin.Right
513 case p_padding_right:
514 v.Length = s.Padding.Right
515 case p_border_right_width:
516 v.Length = s.BorderWidth.Right
517 case p_border_right_style:
518 v.Keyword = keywordNames[s.BorderStyle.Right]
519 case p_border_right_color:
520 v.Color = s.BorderColor.Right
521 case p_margin_bottom:
522 v.Length = s.Margin.Bottom
523 case p_padding_bottom:
524 v.Length = s.Padding.Bottom
525 case p_border_bottom_width:
526 v.Length = s.BorderWidth.Bottom
527 case p_border_bottom_style:
528 v.Keyword = keywordNames[s.BorderStyle.Bottom]
529 case p_border_bottom_color:
530 v.Color = s.BorderColor.Bottom
531 case p_margin_left:
532 v.Length = s.Margin.Left
533 case p_padding_left:
534 v.Length = s.Padding.Left
535 case p_border_left_width:
536 v.Length = s.BorderWidth.Left
537 case p_border_left_style:
538 v.Keyword = keywordNames[s.BorderStyle.Left]
539 case p_border_left_color:
540 v.Color = s.BorderColor.Left
541 case p_border_top_left_radius:
542 v.Length = s.BorderRadius.TopLeft
543 case p_border_top_right_radius:
544 v.Length = s.BorderRadius.TopRight
545 case p_border_bottom_right_radius:
546 v.Length = s.BorderRadius.BottomRight
547 case p_border_bottom_left_radius:
548 v.Length = s.BorderRadius.BottomLeft
549 case p_accent_color:
550 v.Color = s.AccentColor
551 }
552 return v
553}