0 | module Text.CSS.Selector
  1 |
  2 | import Data.List
  3 | import Data.String
  4 | import Text.CSS.Property
  5 | import Web.Dom
  6 |
  7 | %default total
  8 |
  9 | public export
 10 | data Combinator : Type where
 11 |   Descendant      : Combinator
 12 |   Child           : Combinator
 13 |   GeneralSibling  : Combinator
 14 |   AdjacentSibling : Combinator
 15 |
 16 | export
 17 | Interpolation Combinator where
 18 |   interpolate Descendant      = ""
 19 |   interpolate Child           = ">"
 20 |   interpolate GeneralSibling  = "~"
 21 |   interpolate AdjacentSibling = "+"
 22 |
 23 | public export
 24 | data Selector : Type where
 25 |   Star    : Selector
 26 |   Id      : String -> Selector
 27 |   Class   : String -> Selector
 28 |   Elem    : {str : _} -> (0 tpe : ElementType str t) -> Selector
 29 |   Complex : Selector -> Combinator -> Selector -> Selector
 30 |   Nil     : Selector
 31 |   (::)    : Selector -> Selector -> Selector
 32 |
 33 |   ||| Matches when the user activates (for example clicks on) an element.
 34 |   Active : Selector
 35 |   ||| Matches both the :link and :visited states of a link.
 36 |   AnyLink : Selector
 37 |   ||| Matches an <input> element whose input value is empty.
 38 |   Blank : Selector
 39 |   ||| Matches a radio button or checkbox in the selected state.
 40 |   Checked : Selector
 41 |   ||| Matches the element, or an ancestor of the element, that is currently being displayed.
 42 |   Current : Selector
 43 |   ||| Matches the one or more UI elements that are the default among a set of similar elements.
 44 |   Default : Selector
 45 |   ||| Select an element based on its directionality (value of the HTML dir attribute or CSS direction property).
 46 |   Dir : Direction -> Selector
 47 |   ||| Matches user interface elements that are in an disabled state.
 48 |   Disabled : Selector
 49 |   ||| Matches an element that has no children except optionally white space.
 50 |   Empty : Selector
 51 |   ||| Matches user interface elements that are in an enabled state.
 52 |   Enabled : Selector
 53 |   ||| In Paged Media, matches the first page.
 54 |   First : Selector
 55 |   ||| Matches an element that is first among its siblings.
 56 |   FirstChild : Selector
 57 |   ||| Matches an element which is first of a certain type among its siblings.
 58 |   FirstOfType : Selector
 59 |   ||| Matches when an element has focus.
 60 |   Focus : Selector
 61 |   ||| Matches when an element has focus and the focus should be visible to the user.
 62 |   FocusVisible : Selector
 63 |   ||| Matches an element with focus plus an element with a descendent that has focus.
 64 |   FocusWithin : Selector
 65 |   ||| Matches the elements after the current element.
 66 |   Future : Selector
 67 |   ||| Matches when the user hovers over an element.
 68 |   Hover : Selector
 69 |   ||| Matches UI elements whose value is in an indeterminate state, usually checkboxes.
 70 |   Indeterminate : Selector
 71 |   ||| Matches an element with a range when its value is in-range.
 72 |   InRange : Selector
 73 |   ||| Matches an element, such as an <input>, in an invalid state.
 74 |   Invalid : Selector
 75 |   ||| Matches an element based on language (value of the HTML lang attribute).
 76 |   Lang : String -> Selector
 77 |   ||| Matches an element which is last among its siblings.
 78 |   LastChild : Selector
 79 |   ||| Matches an element of a certain type that is last among its siblings.
 80 |   LastOfType : Selector
 81 |   ||| In Paged Media, matches left-hand pages.
 82 |   Left : Selector
 83 |   ||| Matches unvisited links.
 84 |   Link : Selector
 85 |   ||| Matches links pointing to pages that are in the same site as the current document.
 86 |   LocalLink : Selector
 87 |   |||Matches elements from a list of siblings — the siblings are matched by a formula of the form an+b (e.g. 2n + 1 would match elements 1, 3, 5, 7, etc. All the odd ones.)
 88 |   NthChild : String -> Selector
 89 |   |||Matches elements from a list of siblings — the siblings are matched by a formula of the form an+b (e.g. 2n + 1 would match elements 1, 3, 5, 7, etc. All the odd ones.)
 90 |   NthOfType : String -> Selector
 91 |   ||| Matches elements from a list of siblings, counting backwards from the end. The siblings are matched by a formula of the form an+b (e.g. 2n + 1 would match the last element in the sequence, then two elements before that, then two elements before that, etc. All the odd ones, counting from the end.)
 92 |   NthLastChild : String -> Selector
 93 |   ||| Matches elements from a list of siblings that are of a certain type (e.g. <p> elements), counting backwards from the end. The siblings are matched by a formula of the form an+b (e.g. 2n + 1 would match the last element of that type in the sequence, then two elements before that, then two elements before that, etc. All the odd ones, counting from the end.)
 94 |   NthLastOfType : String -> Selector
 95 |   ||| Matches an element that has no siblings.
 96 |   OnlyChild : Selector
 97 |   ||| Matches an element that is the only one of its type among its siblings.
 98 |   OnlyOfType : Selector
 99 |   ||| Matches form elements that are not required.
100 |   Optional : Selector
101 |   ||| Matches an element with a range when its value is out of range.
102 |   OutOfRange : Selector
103 |   ||| Matches the elements before the current element.
104 |   Past : Selector
105 |   ||| Matches an input element that is showing placeholder text.
106 |   PlaceholderShown : Selector
107 |   ||| Matches an element representing an audio, video, or similar resource that is capable of being “played” or “paused”, when that element is “playing”.
108 |   Playing : Selector
109 |   ||| Matches an element representing an audio, video, or similar resource that is capable of being “played” or “paused”, when that element is “paused”.
110 |   Paused : Selector
111 |   ||| Matches an element if it is not user-alterable.
112 |   ReadOnly : Selector
113 |   ||| Matches an element if it is user-alterable.
114 |   ReadWrite : Selector
115 |   ||| Matches form elements that are required.
116 |   Required : Selector
117 |   ||| In Paged Media, matches right-hand pages.
118 |   Right : Selector
119 |   ||| Matches an element that is the root of the document.
120 |   Root : Selector
121 |   ||| Matches any element that is a scope element.
122 |   Scope : Selector
123 |   ||| Matches an element such as an <input> element, in a valid state.
124 |   Valid : Selector
125 |   ||| Matches an element if it is the target of the current URL (i.e. if it has an ID matching the current URL fragment).
126 |   Target : Selector
127 |   ||| Matches visited links.
128 |   Visited : Selector
129 |
130 |   After : Selector
131 |   Backdrop : Selector
132 |   Before : Selector
133 |   Cue : Selector
134 |   CueRegion : Selector
135 |   FirstLetter : Selector
136 |   FirstLine : Selector
137 |   FileSelectorButton : Selector
138 |   Marker : Selector
139 |   Placeholder : Selector
140 |   Selection : Selector
141 |
142 |
143 | export
144 | Interpolation Selector where
145 |   interpolate Star                        = "*"
146 |   interpolate (Id s)                      = "#\{s}"
147 |   interpolate (Class s)                   = ".\{s}"
148 |   interpolate (Elem {str} _)              = str
149 |   interpolate []                          = ""
150 |   interpolate (h::t)                      = interpolate h ++ interpolate t
151 |   interpolate (Complex  s1 Descendant s2) = "\{s1} \{s2}"
152 |   interpolate (Complex  s1 c s2)          = "\{s1} \{c} \{s2}"
153 |   interpolate Active                      = ":active"
154 |   interpolate AnyLink                     = ":any-link"
155 |   interpolate Blank                       = ":blank"
156 |   interpolate Checked                     = ":checked"
157 |   interpolate Current                     = ":current"
158 |   interpolate Default                     = ":default"
159 |   interpolate (Dir x)                     = ":dir(\{x})"
160 |   interpolate Disabled                    = ":disabled"
161 |   interpolate Empty                       = ":empty"
162 |   interpolate Enabled                     = ":enabled"
163 |   interpolate First                       = ":first"
164 |   interpolate FirstChild                  = ":first-child"
165 |   interpolate FirstOfType                 = ":first-of-type"
166 |   interpolate Focus                       = ":focus"
167 |   interpolate FocusVisible                = ":focus-visible"
168 |   interpolate FocusWithin                 = ":focus-within"
169 |   interpolate Future                      = ":future"
170 |   interpolate Hover                       = ":hover"
171 |   interpolate Indeterminate               = ":indeterminate"
172 |   interpolate InRange                     = ":in-range"
173 |   interpolate Invalid                     = ":invalid"
174 |   interpolate (Lang x)                    = ":lang(\{x})"
175 |   interpolate LastChild                   = ":last-child"
176 |   interpolate LastOfType                  = ":last-of-type"
177 |   interpolate Left                        = ":left"
178 |   interpolate Link                        = ":link"
179 |   interpolate LocalLink                   = ":local-link"
180 |   interpolate (NthChild x)                = ":nth-child(\{x})"
181 |   interpolate (NthOfType x)               = ":nth-of-type(\#{x})"
182 |   interpolate (NthLastChild x)            = ":nth-last-child(\#{x})"
183 |   interpolate (NthLastOfType x)           = ":nth-last-of-type(\#{x})"
184 |   interpolate OnlyChild                   = ":only-child"
185 |   interpolate OnlyOfType                  = ":only-of-type"
186 |   interpolate Optional                    = ":optional"
187 |   interpolate OutOfRange                  = ":out-of-range"
188 |   interpolate Past                        = ":past"
189 |   interpolate PlaceholderShown            = ":placeholder-shown"
190 |   interpolate Playing                     = ":playing"
191 |   interpolate Paused                      = ":paused"
192 |   interpolate ReadOnly                    = ":read-only"
193 |   interpolate ReadWrite                   = ":read-write"
194 |   interpolate Required                    = ":required"
195 |   interpolate Right                       = ":right"
196 |   interpolate Root                        = ":root"
197 |   interpolate Scope                       = ":scope"
198 |   interpolate Valid                       = ":valid"
199 |   interpolate Target                      = ":target"
200 |   interpolate Visited                     = ":visited"
201 |   interpolate After                       = "::after"
202 |   interpolate Backdrop                    = "::backdrop"
203 |   interpolate Before                      = "::before"
204 |   interpolate Cue                         = "::cue"
205 |   interpolate CueRegion                   = "::cue-region"
206 |   interpolate FirstLetter                 = "::first-letter"
207 |   interpolate FirstLine                   = "::first-line"
208 |   interpolate FileSelectorButton          = "::file-selector-button"
209 |   interpolate Marker                      = "::marker"
210 |   interpolate Placeholder                 = "::placeholder"
211 |   interpolate Selection                   = "::selection"
212 |
213 | export %inline
214 | class : String -> Selector
215 | class = Class
216 |
217 | export
218 | classes : List String -> Selector
219 | classes []        = []
220 | classes (x :: xs) = class x :: classes xs
221 |
222 | export %inline
223 | elem : {str : _} -> (0 tpe : ElementType str t) -> Selector
224 | elem = Elem
225 |
226 | export %inline
227 | id : String -> Selector
228 | id = Id
229 |