github.com/jgarto/itcv@v0.0.0-20180826224514-4eea09c1aa0d/cmd/coreGen/elements.go (about) 1 package main 2 3 import "fmt" 4 5 type Elem struct { 6 // The myitcv.io/react Name of the element - not set directly, taken from 7 // the key of the elements map. 8 Name string 9 10 // React is an override for the React name of the element if it is otherwise 11 // not equal to the lowercase version of .Name 12 React string 13 14 // Dom is the name used by honnef.co/go/js/dom when referring to the underlying 15 // HTML element. Default is HTML{{.Name}}Element 16 Dom string 17 18 // HTML is an override for the HTML 5 spec name of the element if it is otherwise 19 // not equal to the lowercase version of .Name 20 HTML string 21 22 // Attributes maps the name of an attribute to the definition of an 23 // attribute. 24 Attributes map[string]*Attr 25 26 // NonBasic is true if honnef.co/go/js/dom does not declare a specific 27 // Element type. 28 NonBasic bool 29 30 // Templates lists the attribute templates this element should use as a 31 // base. 32 Templates []string 33 34 // NonHTML indicates this element should not automatically inherit the html 35 // attribute template 36 NonHTML bool 37 38 // Child indicates this element can take a single child of the provided type. 39 // Its use is exclusive with Children. No default value. 40 Child string 41 42 // Children indicates this element can take a multiple children of the provided 43 // type. Its use is exclusive with Child. Default is Element. 44 Children string 45 46 // EmptyElement indicates the element may not have any children 47 EmptyElement bool 48 49 // Implements is the list of special interface methods this element implements. 50 Implements []string 51 52 // SkipTests is an override on whether to not generate the boilerplate tests. 53 SkipTests bool 54 } 55 56 func (e *Elem) ChildParam() string { 57 if e.Child != "" { 58 return "child " + e.Child 59 } else if e.Children != "" { 60 return "children ..." + e.Children 61 } 62 63 return "" 64 } 65 66 func (e *Elem) ChildConvert() string { 67 if e.Children != "" && e.Children != "Element" { 68 return ` 69 var elems []Element 70 for _, v := range children { 71 elems = append(elems, v) 72 } 73 ` 74 } 75 76 return "" 77 } 78 79 func (e *Elem) ChildArg() string { 80 if e.Child != "" { 81 return "child" 82 } else if e.Children != "" { 83 if e.Children == "Element" { 84 return "children..." 85 } else { 86 return "elems..." 87 } 88 } 89 90 return "" 91 } 92 93 func (e *Elem) ChildrenReactType() string { 94 if e.Children[0] == '*' { 95 return "*react." + e.Children[1:] 96 } 97 98 return "react." + e.Children 99 } 100 101 func (e *Elem) HTMLAttributes() map[string]*Attr { 102 res := make(map[string]*Attr) 103 104 for n, a := range e.Attributes { 105 if a.NoHTML || a.NoReact || a.IsEvent || a.Name == "Ref" { 106 continue 107 } 108 109 res[n] = a 110 } 111 112 return res 113 } 114 115 type Attr struct { 116 // The myitcv.io/react Name of the attribute - not set directly, taken from 117 // the key of the elements map. 118 Name string 119 120 // React is an override for the React name of the attribute if it is otherwise 121 // not equal to the lower-initial version of .Name 122 React string 123 124 // HTML is an override for the HTML attribute name if it is otherwise not equal 125 // to the lowercase version of .Name 126 HTML string 127 128 // HTMLConvert is a function that must be called on a JSX-parsed value before 129 // assignment. Default is nothing. 130 HTMLConvert string 131 132 // Type is an override for the type of the attribute. The zero value implies 133 // string 134 Type string 135 136 // OmitEmpty indicates that no attribute should be set on the underlying React 137 // element if the zero value of the attribute is set. 138 OmitEmpty bool 139 140 // NoReact indicates that this attribute should not attempt to be mapped directly 141 // to an underlying React attribute. 142 NoReact bool 143 144 // NoHTML indicates this attribute does not have an HTML equivalent, and hence 145 // should not appear during parsing. 146 NoHTML bool 147 148 // IsEvent indicates that the attribute is an event. 149 IsEvent bool 150 } 151 152 func (a *Attr) Tag() string { 153 omitEmpty := "" 154 if a.OmitEmpty { 155 omitEmpty = ` react:"omitempty"` 156 } 157 return fmt.Sprintf("`js:\"%v\"%v`", a.React, omitEmpty) 158 } 159 160 func (a *Attr) HTMLConvertor(s string) string { 161 if a.HTMLConvert == "" { 162 return s 163 } 164 165 return fmt.Sprintf("%v(%v)", a.HTMLConvert, s) 166 } 167 168 // templates are the attribute templates to which elements can refer 169 var templates = map[string]map[string]*Attr{ 170 "html": { 171 "AriaHasPopup": &Attr{React: "aria-haspopup", Type: "bool", HTML: "aria-haspopup"}, 172 "AriaExpanded": &Attr{React: "aria-expanded", Type: "bool", HTML: "aria-expanded"}, 173 "AriaLabelledBy": &Attr{React: "aria-labelledby", HTML: "aria-labelledby"}, 174 "ClassName": &Attr{HTML: "class"}, 175 "DangerouslySetInnerHTML": &Attr{Type: "*DangerousInnerHTML", NoHTML: true}, 176 "DataSet": &Attr{Type: "DataSet", NoReact: true}, 177 "ID": &Attr{OmitEmpty: true, React: "id"}, 178 "Key": &Attr{OmitEmpty: true}, 179 "Ref": &Attr{Type: "Ref"}, 180 "Role": &Attr{}, 181 "Style": &Attr{Type: "*CSS", HTMLConvert: "parseCSS"}, 182 183 // Events 184 "OnChange": &Attr{Type: "OnChange", IsEvent: true}, 185 "OnClick": &Attr{Type: "OnClick", IsEvent: true}, 186 }, 187 } 188 189 // elements is a map from the Go element name to the definition 190 var elements = map[string]*Elem{ 191 "A": &Elem{ 192 Dom: "HTMLAnchorElement", 193 Attributes: map[string]*Attr{ 194 "Href": &Attr{}, 195 "Target": &Attr{}, 196 "Title": &Attr{}, 197 }, 198 }, 199 "Abbr": &Elem{ 200 Dom: "BasicHTMLElement", 201 }, 202 "Article": &Elem{ 203 Dom: "BasicHTMLElement", 204 }, 205 "Aside": &Elem{ 206 Dom: "BasicHTMLElement", 207 }, 208 "B": &Elem{ 209 Dom: "BasicHTMLElement", 210 }, 211 "Br": &Elem{ 212 Dom: "HTMLBRElement", 213 }, 214 "Button": &Elem{ 215 Attributes: map[string]*Attr{ 216 "Type": &Attr{}, 217 }, 218 }, 219 "Caption": &Elem{ 220 SkipTests: true, 221 Dom: "BasicHTMLElement", 222 }, 223 "Code": &Elem{ 224 Dom: "BasicHTMLElement", 225 }, 226 "Div": &Elem{}, 227 "Em": &Elem{ 228 Dom: "BasicHTMLElement", 229 }, 230 "Footer": &Elem{ 231 Dom: "BasicHTMLElement", 232 }, 233 "Form": &Elem{}, 234 "H1": &Elem{ 235 Dom: "HTMLHeadingElement", 236 }, 237 "H2": &Elem{ 238 Dom: "HTMLHeadingElement", 239 }, 240 "H3": &Elem{ 241 Dom: "HTMLHeadingElement", 242 }, 243 "H4": &Elem{ 244 Dom: "HTMLHeadingElement", 245 }, 246 "H5": &Elem{ 247 Dom: "HTMLHeadingElement", 248 }, 249 "H6": &Elem{ 250 Dom: "HTMLHeadingElement", 251 }, 252 "Header": &Elem{ 253 Dom: "BasicHTMLElement", 254 }, 255 "Hr": &Elem{ 256 Dom: "HTMLHRElement", 257 EmptyElement: true, 258 }, 259 "I": &Elem{ 260 Dom: "BasicHTMLElement", 261 }, 262 "IFrame": &Elem{ 263 Attributes: map[string]*Attr{ 264 "SrcDoc": &Attr{}, 265 }, 266 }, 267 "Img": &Elem{ 268 Dom: "HTMLImageElement", 269 Attributes: map[string]*Attr{ 270 "Src": &Attr{}, 271 "Alt": &Attr{}, 272 }, 273 }, 274 "Input": &Elem{ 275 Attributes: map[string]*Attr{ 276 "Placeholder": &Attr{}, 277 "Type": &Attr{}, 278 "Value": &Attr{}, 279 }, 280 }, 281 "Label": &Elem{ 282 Attributes: map[string]*Attr{ 283 "For": &Attr{ 284 React: "htmlFor", 285 }, 286 }, 287 }, 288 "Li": &Elem{ 289 Dom: "HTMLLIElement", 290 Implements: []string{"RendersLi(*LiElem)"}, 291 }, 292 "Main": &Elem{ 293 Dom: "BasicHTMLElement", 294 }, 295 "Nav": &Elem{ 296 Dom: "BasicHTMLElement", 297 }, 298 "Option": &Elem{ 299 Attributes: map[string]*Attr{ 300 "Value": &Attr{}, 301 }, 302 }, 303 "P": &Elem{ 304 Dom: "HTMLParagraphElement", 305 }, 306 "Pre": &Elem{}, 307 "Select": &Elem{ 308 Attributes: map[string]*Attr{ 309 "Value": &Attr{}, 310 }, 311 Children: "*OptionElem", 312 }, 313 "Span": &Elem{}, 314 "Strike": &Elem{ 315 Dom: "BasicHTMLElement", 316 React: "s", 317 HTML: "s", 318 }, 319 "Sup": &Elem{ 320 Dom: "BasicHTMLElement", 321 }, 322 "Table": &Elem{}, 323 "Tbody": &Elem{ 324 SkipTests: true, 325 Dom: "BasicHTMLElement", 326 }, 327 "Td": &Elem{ 328 SkipTests: true, 329 Dom: "BasicHTMLElement", 330 }, 331 "TextArea": &Elem{ 332 Attributes: map[string]*Attr{ 333 "Placeholder": &Attr{}, 334 "Value": &Attr{}, 335 }, 336 }, 337 "Th": &Elem{ 338 SkipTests: true, 339 Dom: "BasicHTMLElement", 340 }, 341 "Thead": &Elem{ 342 SkipTests: true, 343 Dom: "BasicHTMLElement", 344 }, 345 "Tr": &Elem{ 346 SkipTests: true, 347 Dom: "BasicHTMLElement", 348 }, 349 "Ul": &Elem{ 350 Dom: "HTMLUListElement", 351 Children: "RendersLi", 352 }, 353 }