1// Package dom provides GopherJS bindings for the JavaScript DOM APIs. 2// 3// This package is an in progress effort of providing idiomatic Go 4// bindings for the DOM, wrapping the JavaScript DOM APIs. The API is 5// neither complete nor frozen yet, but a great amount of the DOM is 6// already useable. 7// 8// While the package tries to be idiomatic Go, it also tries to stick 9// closely to the JavaScript APIs, so that one does not need to learn 10// a new set of APIs if one is already familiar with it. 11// 12// One decision that hasn't been made yet is what parts exactly should 13// be part of this package. It is, for example, possible that the 14// canvas APIs will live in a separate package. On the other hand, 15// types such as StorageEvent (the event that gets fired when the 16// HTML5 storage area changes) will be part of this package, simply 17// due to how the DOM is structured – even if the actual storage APIs 18// might live in a separate package. This might require special care 19// to avoid circular dependencies. 20// 21// The documentation for some of the identifiers is based on the 22// MDN Web Docs by Mozilla Contributors (https://developer.mozilla.org/en-US/docs/Web/API), 23// licensed under CC-BY-SA 2.5 (https://creativecommons.org/licenses/by-sa/2.5/). 24// 25// 26// Getting started 27// 28// The usual entry point of using the dom package is by using the 29// GetWindow() function which will return a Window, from which you can 30// get things such as the current Document. 31// 32// 33// Interfaces 34// 35// The DOM has a big amount of different element and event types, but 36// they all follow three interfaces. All functions that work on or 37// return generic elements/events will return one of the three 38// interfaces Element, HTMLElement or Event. In these interface values 39// there will be concrete implementations, such as 40// HTMLParagraphElement or FocusEvent. It's also not unusual that 41// values of type Element also implement HTMLElement. In all cases, 42// type assertions can be used. 43// 44// Example: 45// el := dom.GetWindow().Document().QuerySelector(".some-element") 46// htmlEl := el.(dom.HTMLElement) 47// pEl := el.(*dom.HTMLParagraphElement) 48// 49// 50// Live collections 51// 52// Several functions in the JavaScript DOM return "live" 53// collections of elements, that is collections that will be 54// automatically updated when elements get removed or added to the 55// DOM. Our bindings, however, return static slices of elements that, 56// once created, will not automatically reflect updates to the DOM. 57// This is primarily done so that slices can actually be used, as 58// opposed to a form of iterator, but also because we think that 59// magically changing data isn't Go's nature and that snapshots of 60// state are a lot easier to reason about. 61// 62// This does not, however, mean that all objects are snapshots. 63// Elements, events and generally objects that aren't slices or maps 64// are simple wrappers around JavaScript objects, and as such 65// attributes as well as method calls will always return the most 66// current data. To reflect this behaviour, these bindings use 67// pointers to make the semantics clear. Consider the following 68// example: 69// 70// d := dom.GetWindow().Document() 71// e1 := d.GetElementByID("my-element") 72// e2 := d.GetElementByID("my-element") 73// 74// e1.Class().SetString("some-class") 75// println(e1.Class().String() == e2.Class().String()) 76// 77// The above example will print `true`. 78// 79// 80// DOMTokenList 81// 82// Some objects in the JS API have two versions of attributes, one 83// that returns a string and one that returns a DOMTokenList to ease 84// manipulation of string-delimited lists. Some other objects only 85// provide DOMTokenList, sometimes DOMSettableTokenList. To simplify 86// these bindings, only the DOMTokenList variant will be made 87// available, by the type TokenList. In cases where the string 88// attribute was the only way to completely replace the value, our 89// TokenList will provide Set([]string) and SetString(string) methods, 90// which will be able to accomplish the same. Additionally, our 91// TokenList will provide methods to convert it to strings and slices. 92// 93// 94// Backwards compatibility 95// 96// This package has a relatively stable API. However, there will be 97// backwards incompatible changes from time to time. This is because 98// the package isn't complete yet, as well as because the DOM is a 99// moving target, and APIs do change sometimes. 100// 101// While an attempt is made to reduce changing function signatures to 102// a minimum, it can't always be guaranteed. Sometimes mistakes in the 103// bindings are found that require changing arguments or return 104// values. 105// 106// Interfaces defined in this package may also change on a 107// semi-regular basis, as new methods are added to them. This happens 108// because the bindings aren't complete and can never really be, as 109// new features are added to the DOM. 110// 111// If you depend on none of the APIs changing unexpectedly, you're 112// advised to vendor this package. 113package dom // import "honnef.co/go/js/dom" 114 115import ( 116 "image" 117 "image/color" 118 "strings" 119 "time" 120 121 "github.com/gopherjs/gopherjs/js" 122) 123 124// toString returns the string representation of o. If o is nil or 125// undefined, the empty string will be returned instead. 126func toString(o *js.Object) string { 127 if o == nil || o == js.Undefined { 128 return "" 129 } 130 return o.String() 131} 132 133func callRecover(o *js.Object, fn string, args ...interface{}) (err error) { 134 defer func() { 135 e := recover() 136 if e == nil { 137 return 138 } 139 if panicErr, ok := e.(error); ok && panicErr != nil { 140 err = panicErr 141 } else { 142 panic(e) 143 } 144 }() 145 o.Call(fn, args...) 146 return nil 147} 148 149func elementConstructor(o *js.Object) *js.Object { 150 if n := o.Get("node"); n != js.Undefined { 151 // Support elements wrapped in Polymer's DOM APIs. 152 return n.Get("constructor") 153 } 154 return o.Get("constructor") 155} 156 157func arrayToObjects(o *js.Object) []*js.Object { 158 var out []*js.Object 159 for i := 0; i < o.Length(); i++ { 160 out = append(out, o.Index(i)) 161 } 162 return out 163} 164 165func nodeListToObjects(o *js.Object) []*js.Object { 166 if o.Get("constructor") == js.Global.Get("Array") { 167 // Support Polymer's DOM APIs, which uses Arrays instead of 168 // NodeLists 169 return arrayToObjects(o) 170 } 171 var out []*js.Object 172 length := o.Get("length").Int() 173 for i := 0; i < length; i++ { 174 out = append(out, o.Call("item", i)) 175 } 176 return out 177} 178 179func nodeListToNodes(o *js.Object) []Node { 180 var out []Node 181 for _, obj := range nodeListToObjects(o) { 182 out = append(out, wrapNode(obj)) 183 } 184 return out 185} 186 187func nodeListToElements(o *js.Object) []Element { 188 var out []Element 189 for _, obj := range nodeListToObjects(o) { 190 out = append(out, wrapElement(obj)) 191 } 192 return out 193} 194 195func nodeListToHTMLElements(o *js.Object) []HTMLElement { 196 var out []HTMLElement 197 for _, obj := range nodeListToObjects(o) { 198 out = append(out, wrapHTMLElement(obj)) 199 } 200 return out 201} 202 203func WrapDocument(o *js.Object) Document { 204 return wrapDocument(o) 205} 206 207func WrapDocumentFragment(o *js.Object) DocumentFragment { 208 return wrapDocumentFragment(o) 209} 210 211func WrapNode(o *js.Object) Node { 212 return wrapNode(o) 213} 214 215func WrapElement(o *js.Object) Element { 216 return wrapElement(o) 217} 218 219func WrapHTMLElement(o *js.Object) HTMLElement { 220 return wrapHTMLElement(o) 221} 222 223func wrapDocument(o *js.Object) Document { 224 switch elementConstructor(o) { 225 case js.Global.Get("HTMLDocument"): 226 return &htmlDocument{&document{&BasicNode{o}}} 227 default: 228 return &document{&BasicNode{o}} 229 } 230} 231 232func wrapDocumentFragment(o *js.Object) DocumentFragment { 233 switch elementConstructor(o) { 234 // TODO: do we have any other stuff we want to check 235 default: 236 return &documentFragment{&BasicNode{o}} 237 } 238} 239 240func wrapNode(o *js.Object) Node { 241 if o == nil || o == js.Undefined { 242 return nil 243 } 244 switch elementConstructor(o) { 245 // TODO all the non-element cases 246 case js.Global.Get("Text"): 247 return &Text{&BasicNode{o}} 248 default: 249 return wrapElement(o) 250 } 251} 252 253func wrapElement(o *js.Object) Element { 254 if o == nil || o == js.Undefined { 255 return nil 256 } 257 switch elementConstructor(o) { 258 // TODO all the non-HTML cases 259 default: 260 return wrapHTMLElement(o) 261 } 262} 263 264func wrapHTMLElement(o *js.Object) HTMLElement { 265 if o == nil || o == js.Undefined { 266 return nil 267 } 268 el := &BasicHTMLElement{&BasicElement{&BasicNode{o}}} 269 c := elementConstructor(o) 270 switch c { 271 case js.Global.Get("HTMLAnchorElement"): 272 return &HTMLAnchorElement{BasicHTMLElement: el, URLUtils: &URLUtils{Object: o}} 273 case js.Global.Get("HTMLAppletElement"): 274 return &HTMLAppletElement{BasicHTMLElement: el} 275 case js.Global.Get("HTMLAreaElement"): 276 return &HTMLAreaElement{BasicHTMLElement: el, URLUtils: &URLUtils{Object: o}} 277 case js.Global.Get("HTMLAudioElement"): 278 return &HTMLAudioElement{HTMLMediaElement: &HTMLMediaElement{BasicHTMLElement: el}} 279 case js.Global.Get("HTMLBaseElement"): 280 return &HTMLBaseElement{BasicHTMLElement: el} 281 case js.Global.Get("HTMLBodyElement"): 282 return &HTMLBodyElement{BasicHTMLElement: el} 283 case js.Global.Get("HTMLBRElement"): 284 return &HTMLBRElement{BasicHTMLElement: el} 285 case js.Global.Get("HTMLButtonElement"): 286 return &HTMLButtonElement{BasicHTMLElement: el} 287 case js.Global.Get("HTMLCanvasElement"): 288 return &HTMLCanvasElement{BasicHTMLElement: el} 289 case js.Global.Get("HTMLDataElement"): 290 return &HTMLDataElement{BasicHTMLElement: el} 291 case js.Global.Get("HTMLDataListElement"): 292 return &HTMLDataListElement{BasicHTMLElement: el} 293 case js.Global.Get("HTMLDirectoryElement"): 294 return &HTMLDirectoryElement{BasicHTMLElement: el} 295 case js.Global.Get("HTMLDivElement"): 296 return &HTMLDivElement{BasicHTMLElement: el} 297 case js.Global.Get("HTMLDListElement"): 298 return &HTMLDListElement{BasicHTMLElement: el} 299 case js.Global.Get("HTMLEmbedElement"): 300 return &HTMLEmbedElement{BasicHTMLElement: el} 301 case js.Global.Get("HTMLFieldSetElement"): 302 return &HTMLFieldSetElement{BasicHTMLElement: el} 303 case js.Global.Get("HTMLFontElement"): 304 return &HTMLFontElement{BasicHTMLElement: el} 305 case js.Global.Get("HTMLFormElement"): 306 return &HTMLFormElement{BasicHTMLElement: el} 307 case js.Global.Get("HTMLFrameElement"): 308 return &HTMLFrameElement{BasicHTMLElement: el} 309 case js.Global.Get("HTMLFrameSetElement"): 310 return &HTMLFrameSetElement{BasicHTMLElement: el} 311 case js.Global.Get("HTMLHeadElement"): 312 return &HTMLHeadElement{BasicHTMLElement: el} 313 case js.Global.Get("HTMLHeadingElement"): 314 return &HTMLHeadingElement{BasicHTMLElement: el} 315 case js.Global.Get("HTMLHtmlElement"): 316 return &HTMLHtmlElement{BasicHTMLElement: el} 317 case js.Global.Get("HTMLHRElement"): 318 return &HTMLHRElement{BasicHTMLElement: el} 319 case js.Global.Get("HTMLIFrameElement"): 320 return &HTMLIFrameElement{BasicHTMLElement: el} 321 case js.Global.Get("HTMLImageElement"): 322 return &HTMLImageElement{BasicHTMLElement: el} 323 case js.Global.Get("HTMLInputElement"): 324 return &HTMLInputElement{BasicHTMLElement: el} 325 case js.Global.Get("HTMLKeygenElement"): 326 return &HTMLKeygenElement{BasicHTMLElement: el} 327 case js.Global.Get("HTMLLabelElement"): 328 return &HTMLLabelElement{BasicHTMLElement: el} 329 case js.Global.Get("HTMLLegendElement"): 330 return &HTMLLegendElement{BasicHTMLElement: el} 331 case js.Global.Get("HTMLLIElement"): 332 return &HTMLLIElement{BasicHTMLElement: el} 333 case js.Global.Get("HTMLLinkElement"): 334 return &HTMLLinkElement{BasicHTMLElement: el} 335 case js.Global.Get("HTMLMapElement"): 336 return &HTMLMapElement{BasicHTMLElement: el} 337 case js.Global.Get("HTMLMediaElement"): 338 return &HTMLMediaElement{BasicHTMLElement: el} 339 case js.Global.Get("HTMLMenuElement"): 340 return &HTMLMenuElement{BasicHTMLElement: el} 341 case js.Global.Get("HTMLMetaElement"): 342 return &HTMLMetaElement{BasicHTMLElement: el} 343 case js.Global.Get("HTMLMeterElement"): 344 return &HTMLMeterElement{BasicHTMLElement: el} 345 case js.Global.Get("HTMLModElement"): 346 return &HTMLModElement{BasicHTMLElement: el} 347 case js.Global.Get("HTMLObjectElement"): 348 return &HTMLObjectElement{BasicHTMLElement: el} 349 case js.Global.Get("HTMLOListElement"): 350 return &HTMLOListElement{BasicHTMLElement: el} 351 case js.Global.Get("HTMLOptGroupElement"): 352 return &HTMLOptGroupElement{BasicHTMLElement: el} 353 case js.Global.Get("HTMLOptionElement"): 354 return &HTMLOptionElement{BasicHTMLElement: el} 355 case js.Global.Get("HTMLOutputElement"): 356 return &HTMLOutputElement{BasicHTMLElement: el} 357 case js.Global.Get("HTMLParagraphElement"): 358 return &HTMLParagraphElement{BasicHTMLElement: el} 359 case js.Global.Get("HTMLParamElement"): 360 return &HTMLParamElement{BasicHTMLElement: el} 361 case js.Global.Get("HTMLPreElement"): 362 return &HTMLPreElement{BasicHTMLElement: el} 363 case js.Global.Get("HTMLProgressElement"): 364 return &HTMLProgressElement{BasicHTMLElement: el} 365 case js.Global.Get("HTMLQuoteElement"): 366 return &HTMLQuoteElement{BasicHTMLElement: el} 367 case js.Global.Get("HTMLScriptElement"): 368 return &HTMLScriptElement{BasicHTMLElement: el} 369 case js.Global.Get("HTMLSelectElement"): 370 return &HTMLSelectElement{BasicHTMLElement: el} 371 case js.Global.Get("HTMLSourceElement"): 372 return &HTMLSourceElement{BasicHTMLElement: el} 373 case js.Global.Get("HTMLSpanElement"): 374 return &HTMLSpanElement{BasicHTMLElement: el} 375 case js.Global.Get("HTMLStyleElement"): 376 return &HTMLStyleElement{BasicHTMLElement: el} 377 case js.Global.Get("HTMLTableElement"): 378 return &HTMLTableElement{BasicHTMLElement: el} 379 case js.Global.Get("HTMLTableCaptionElement"): 380 return &HTMLTableCaptionElement{BasicHTMLElement: el} 381 case js.Global.Get("HTMLTableCellElement"): 382 return &HTMLTableCellElement{BasicHTMLElement: el} 383 case js.Global.Get("HTMLTableDataCellElement"): 384 return &HTMLTableDataCellElement{BasicHTMLElement: el} 385 case js.Global.Get("HTMLTableHeaderCellElement"): 386 return &HTMLTableHeaderCellElement{BasicHTMLElement: el} 387 case js.Global.Get("HTMLTableColElement"): 388 return &HTMLTableColElement{BasicHTMLElement: el} 389 case js.Global.Get("HTMLTableRowElement"): 390 return &HTMLTableRowElement{BasicHTMLElement: el} 391 case js.Global.Get("HTMLTableSectionElement"): 392 return &HTMLTableSectionElement{BasicHTMLElement: el} 393 case js.Global.Get("HTMLTextAreaElement"): 394 return &HTMLTextAreaElement{BasicHTMLElement: el} 395 case js.Global.Get("HTMLTimeElement"): 396 return &HTMLTimeElement{BasicHTMLElement: el} 397 case js.Global.Get("HTMLTitleElement"): 398 return &HTMLTitleElement{BasicHTMLElement: el} 399 case js.Global.Get("HTMLTrackElement"): 400 return &HTMLTrackElement{BasicHTMLElement: el} 401 case js.Global.Get("HTMLUListElement"): 402 return &HTMLUListElement{BasicHTMLElement: el} 403 case js.Global.Get("HTMLUnknownElement"): 404 return &HTMLUnknownElement{BasicHTMLElement: el} 405 case js.Global.Get("HTMLVideoElement"): 406 return &HTMLVideoElement{HTMLMediaElement: &HTMLMediaElement{BasicHTMLElement: el}} 407 case js.Global.Get("HTMLElement"): 408 return el 409 default: 410 return el 411 } 412} 413 414func getForm(o *js.Object) *HTMLFormElement { 415 form := wrapHTMLElement(o.Get("form")) 416 if form == nil { 417 return nil 418 } 419 return form.(*HTMLFormElement) 420} 421 422func getLabels(o *js.Object) []*HTMLLabelElement { 423 labels := nodeListToElements(o.Get("labels")) 424 out := make([]*HTMLLabelElement, len(labels)) 425 for i, label := range labels { 426 out[i] = label.(*HTMLLabelElement) 427 } 428 return out 429} 430 431func getOptions(o *js.Object, attr string) []*HTMLOptionElement { 432 options := nodeListToElements(o.Get(attr)) 433 out := make([]*HTMLOptionElement, len(options)) 434 for i, option := range options { 435 out[i] = option.(*HTMLOptionElement) 436 } 437 return out 438} 439 440func GetWindow() Window { 441 return &window{js.Global} 442} 443 444type TokenList struct { 445 dtl *js.Object // the underlying DOMTokenList 446 o *js.Object // the object to which the DOMTokenList belongs 447 sa string // the name of the corresponding string attribute, empty if there isn't one 448 449 Length int `js:"length"` 450} 451 452func (tl *TokenList) Item(idx int) string { 453 o := tl.dtl.Call("item", idx) 454 return toString(o) 455} 456 457func (tl *TokenList) Contains(token string) bool { 458 return tl.dtl.Call("contains", token).Bool() 459} 460 461func (tl *TokenList) Add(token string) { 462 tl.dtl.Call("add", token) 463} 464 465func (tl *TokenList) Remove(token string) { 466 tl.dtl.Call("remove", token) 467} 468 469func (tl *TokenList) Toggle(token string) { 470 tl.dtl.Call("toggle", token) 471} 472 473func (tl *TokenList) String() string { 474 if tl.sa != "" { 475 return tl.o.Get(tl.sa).String() 476 } 477 if tl.dtl.Get("constructor") == js.Global.Get("DOMSettableTokenList") { 478 return tl.dtl.Get("value").String() 479 } 480 // We could manually construct the string, but I am not aware of 481 // any case where we have neither a string attribute nor 482 // DOMSettableTokenList. 483 return "" 484} 485 486func (tl *TokenList) Slice() []string { 487 var out []string 488 length := tl.dtl.Get("length").Int() 489 for i := 0; i < length; i++ { 490 out = append(out, tl.dtl.Call("item", i).String()) 491 } 492 return out 493} 494 495// SetString sets the TokenList's value to the space-separated list of 496// tokens in s. 497func (tl *TokenList) SetString(s string) { 498 if tl.sa != "" { 499 tl.o.Set(tl.sa, s) 500 return 501 } 502 if tl.dtl.Get("constructor") == js.Global.Get("DOMSettableTokenList") { 503 tl.dtl.Set("value", s) 504 return 505 } 506 // This shouldn't be possible 507 panic("no way to SetString on this TokenList") 508} 509 510// Set sets the TokenList's value to the list of tokens in s. 511// 512// Individual tokens in s shouldn't countain spaces. 513func (tl *TokenList) Set(s []string) { 514 tl.SetString(strings.Join(s, " ")) 515} 516 517type Document interface { 518 Node 519 ParentNode 520 521 Async() bool 522 SetAsync(bool) 523 Doctype() DocumentType 524 DocumentElement() Element 525 DocumentURI() string 526 Implementation() DOMImplementation 527 LastStyleSheetSet() string 528 PreferredStyleSheetSet() string // TODO correct type? 529 SelectedStyleSheetSet() string // TODO correct type? 530 StyleSheets() []StyleSheet // TODO s/StyleSheet/Stylesheet/ ? 531 StyleSheetSets() []StyleSheet // TODO correct type? 532 AdoptNode(node Node) Node 533 ImportNode(node Node, deep bool) Node 534 CreateElement(name string) Element 535 CreateElementNS(namespace, name string) Element 536 CreateTextNode(s string) *Text 537 ElementFromPoint(x, y int) Element 538 EnableStyleSheetsForSet(name string) 539 GetElementsByClassName(name string) []Element 540 GetElementsByTagName(name string) []Element 541 GetElementsByTagNameNS(ns, name string) []Element 542 GetElementByID(id string) Element 543 QuerySelector(sel string) Element 544 QuerySelectorAll(sel string) []Element 545 546 CreateDocumentFragment() DocumentFragment 547} 548 549type DocumentFragment interface { 550 Node 551 ParentNode 552 QuerySelector(sel string) Element 553 QuerySelectorAll(sel string) []Element 554 GetElementByID(id string) Element 555} 556 557type HTMLDocument interface { 558 Document 559 560 ActiveElement() HTMLElement 561 Body() HTMLElement 562 Cookie() string 563 SetCookie(string) 564 DefaultView() Window 565 DesignMode() bool 566 SetDesignMode(bool) 567 Domain() string 568 SetDomain(string) 569 Forms() []*HTMLFormElement 570 Head() *HTMLHeadElement 571 Images() []*HTMLImageElement 572 LastModified() time.Time 573 Links() []HTMLElement 574 Location() *Location 575 Plugins() []*HTMLEmbedElement 576 ReadyState() string 577 Referrer() string 578 Scripts() []*HTMLScriptElement 579 Title() string 580 SetTitle(string) 581 URL() string 582 583 // TODO HTMLDocument methods 584} 585 586type documentFragment struct { 587 *BasicNode 588} 589 590func (d documentFragment) GetElementByID(id string) Element { 591 return wrapElement(d.Call("getElementById", id)) 592} 593 594func (d documentFragment) QuerySelector(sel string) Element { 595 return (&BasicElement{&BasicNode{d.Object}}).QuerySelector(sel) 596} 597 598func (d documentFragment) QuerySelectorAll(sel string) []Element { 599 return (&BasicElement{&BasicNode{d.Object}}).QuerySelectorAll(sel) 600} 601 602type document struct { 603 *BasicNode 604} 605 606type htmlDocument struct { 607 *document 608} 609 610func (d *htmlDocument) ActiveElement() HTMLElement { 611 return wrapHTMLElement(d.Get("activeElement")) 612} 613 614func (d *htmlDocument) Body() HTMLElement { 615 return wrapHTMLElement(d.Get("body")) 616} 617 618func (d *htmlDocument) Cookie() string { 619 return d.Get("cookie").String() 620} 621 622func (d *htmlDocument) SetCookie(s string) { 623 d.Set("cookie", s) 624} 625 626func (d *htmlDocument) DefaultView() Window { 627 return &window{d.Get("defaultView")} 628} 629 630func (d *htmlDocument) DesignMode() bool { 631 s := d.Get("designMode").String() 632 return s != "off" 633} 634 635func (d *htmlDocument) SetDesignMode(b bool) { 636 s := "off" 637 if b { 638 s = "on" 639 } 640 d.Set("designMode", s) 641} 642 643func (d *htmlDocument) Domain() string { 644 return d.Get("domain").String() 645} 646 647func (d *htmlDocument) SetDomain(s string) { 648 d.Set("domain", s) 649} 650 651func (d *htmlDocument) Forms() []*HTMLFormElement { 652 var els []*HTMLFormElement 653 forms := d.Get("forms") 654 length := forms.Get("length").Int() 655 for i := 0; i < length; i++ { 656 els = append(els, wrapHTMLElement(forms.Call("item", i)).(*HTMLFormElement)) 657 } 658 return els 659} 660 661func (d *htmlDocument) Head() *HTMLHeadElement { 662 head := wrapElement(d.Get("head")) 663 if head == nil { 664 return nil 665 } 666 return head.(*HTMLHeadElement) 667} 668 669func (d *htmlDocument) Images() []*HTMLImageElement { 670 var els []*HTMLImageElement 671 images := d.Get("images") 672 length := images.Get("length").Int() 673 for i := 0; i < length; i++ { 674 els = append(els, wrapHTMLElement(images.Call("item", i)).(*HTMLImageElement)) 675 } 676 return els 677} 678 679func (d *htmlDocument) LastModified() time.Time { 680 return d.Get("lastModified").Interface().(time.Time) 681} 682 683func (d *htmlDocument) Links() []HTMLElement { 684 var els []HTMLElement 685 links := d.Get("links") 686 length := links.Get("length").Int() 687 for i := 0; i < length; i++ { 688 els = append(els, wrapHTMLElement(links.Call("item", i))) 689 } 690 return els 691} 692 693func (d *htmlDocument) Location() *Location { 694 o := d.Get("location") 695 return &Location{Object: o, URLUtils: &URLUtils{Object: o}} 696} 697 698func (d *htmlDocument) Plugins() []*HTMLEmbedElement { 699 var els []*HTMLEmbedElement 700 forms := d.Get("plugins") 701 length := forms.Get("length").Int() 702 for i := 0; i < length; i++ { 703 els = append(els, wrapHTMLElement(forms.Call("item", i)).(*HTMLEmbedElement)) 704 } 705 return els 706} 707 708func (d *htmlDocument) ReadyState() string { 709 return d.Get("readyState").String() 710} 711 712func (d *htmlDocument) Referrer() string { 713 return d.Get("referrer").String() 714} 715 716func (d *htmlDocument) Scripts() []*HTMLScriptElement { 717 var els []*HTMLScriptElement 718 forms := d.Get("scripts") 719 length := forms.Get("length").Int() 720 for i := 0; i < length; i++ { 721 els = append(els, wrapHTMLElement(forms.Call("item", i)).(*HTMLScriptElement)) 722 } 723 return els 724} 725 726func (d *htmlDocument) Title() string { 727 return d.Get("title").String() 728} 729 730func (d *htmlDocument) SetTitle(s string) { 731 d.Set("title", s) 732} 733 734func (d *htmlDocument) URL() string { 735 return d.Get("URL").String() 736} 737 738func (d document) Async() bool { 739 return d.Get("async").Bool() 740} 741 742func (d document) SetAsync(b bool) { 743 d.Set("async", b) 744} 745 746func (d document) Doctype() DocumentType { 747 // FIXME implement 748 panic("not implemented") 749} 750 751func (d document) DocumentElement() Element { 752 return wrapElement(d.Get("documentElement")) 753} 754 755func (d document) DocumentURI() string { 756 return d.Get("documentURI").String() 757} 758 759func (d document) Implementation() DOMImplementation { 760 // FIXME implement 761 panic("not implemented") 762} 763 764func (d document) LastStyleSheetSet() string { 765 return d.Get("lastStyleSheetSet").String() 766} 767 768func (d document) PreferredStyleSheetSet() string { 769 return d.Get("preferredStyleSheetSet").String() 770} 771 772func (d document) SelectedStyleSheetSet() string { 773 return d.Get("selectedStyleSheetSet").String() 774} 775 776func (d document) StyleSheets() []StyleSheet { 777 // FIXME implement 778 panic("not implemented") 779} 780 781func (d document) StyleSheetSets() []StyleSheet { 782 // FIXME implement 783 panic("not implemented") 784} 785 786func (d document) AdoptNode(node Node) Node { 787 return wrapNode(d.Call("adoptNode", node.Underlying())) 788} 789 790func (d document) ImportNode(node Node, deep bool) Node { 791 return wrapNode(d.Call("importNode", node.Underlying(), deep)) 792} 793 794func (d document) CreateDocumentFragment() DocumentFragment { 795 return wrapDocumentFragment(d.Call("createDocumentFragment")) 796} 797 798func (d document) CreateElement(name string) Element { 799 return wrapElement(d.Call("createElement", name)) 800} 801 802func (d document) CreateElementNS(ns string, name string) Element { 803 return wrapElement(d.Call("createElementNS", ns, name)) 804} 805 806func (d document) CreateTextNode(s string) *Text { 807 return wrapNode(d.Call("createTextNode", s)).(*Text) 808} 809 810func (d document) ElementFromPoint(x, y int) Element { 811 return wrapElement(d.Call("elementFromPoint", x, y)) 812} 813 814func (d document) EnableStyleSheetsForSet(name string) { 815 d.Call("enableStyleSheetsForSet", name) 816} 817 818func (d document) GetElementsByClassName(name string) []Element { 819 return (&BasicElement{&BasicNode{d.Object}}).GetElementsByClassName(name) 820} 821 822func (d document) GetElementsByTagName(name string) []Element { 823 return (&BasicElement{&BasicNode{d.Object}}).GetElementsByTagName(name) 824} 825 826func (d document) GetElementsByTagNameNS(ns, name string) []Element { 827 return (&BasicElement{&BasicNode{d.Object}}).GetElementsByTagNameNS(ns, name) 828} 829 830func (d document) GetElementByID(id string) Element { 831 return wrapElement(d.Call("getElementById", id)) 832} 833 834func (d document) QuerySelector(sel string) Element { 835 return (&BasicElement{&BasicNode{d.Object}}).QuerySelector(sel) 836} 837 838func (d document) QuerySelectorAll(sel string) []Element { 839 return (&BasicElement{&BasicNode{d.Object}}).QuerySelectorAll(sel) 840} 841 842type URLUtils struct { 843 *js.Object 844 845 Href string `js:"href"` 846 Protocol string `js:"protocol"` 847 Host string `js:"host"` 848 Hostname string `js:"hostname"` 849 Port string `js:"port"` 850 Pathname string `js:"pathname"` 851 Search string `js:"search"` 852 Hash string `js:"hash"` 853 Username string `js:"username"` 854 Password string `js:"password"` 855 Origin string `js:"origin"` 856} 857 858// TODO Location methods 859 860type Location struct { 861 *js.Object 862 *URLUtils 863} 864 865type HTMLElement interface { 866 Element 867 GlobalEventHandlers 868 869 AccessKey() string 870 Dataset() map[string]string 871 SetAccessKey(string) 872 AccessKeyLabel() string 873 SetAccessKeyLabel(string) 874 ContentEditable() string 875 SetContentEditable(string) 876 IsContentEditable() bool 877 Dir() string 878 SetDir(string) 879 Draggable() bool 880 SetDraggable(bool) 881 Lang() string 882 SetLang(string) 883 OffsetHeight() float64 884 OffsetLeft() float64 885 OffsetParent() HTMLElement 886 OffsetTop() float64 887 OffsetWidth() float64 888 Style() *CSSStyleDeclaration 889 Title() string 890 SetTitle(string) 891 Blur() 892 Click() 893 Focus() 894} 895type SVGElement interface { 896 Element 897 // TODO 898} 899 900type GlobalEventHandlers interface{} 901 902type Window interface { 903 EventTarget 904 905 Console() *Console 906 Document() Document 907 FrameElement() Element 908 Location() *Location 909 Name() string 910 SetName(string) 911 InnerHeight() int 912 InnerWidth() int 913 Length() int 914 Opener() Window 915 OuterHeight() int 916 OuterWidth() int 917 ScrollX() int 918 ScrollY() int 919 Parent() Window 920 ScreenX() int 921 ScreenY() int 922 ScrollMaxX() int 923 ScrollMaxY() int 924 Top() Window 925 History() History 926 Navigator() Navigator 927 Screen() *Screen 928 Alert(string) 929 Back() 930 Blur() 931 CancelAnimationFrame(int) 932 ClearInterval(int) 933 ClearTimeout(int) 934 Close() 935 Confirm(string) bool 936 Focus() 937 Forward() 938 GetComputedStyle(el Element, pseudoElt string) *CSSStyleDeclaration 939 GetSelection() Selection 940 Home() 941 MoveBy(dx, dy int) 942 MoveTo(x, y int) 943 Open(url, name, features string) Window 944 OpenDialog(url, name, features string, args []interface{}) Window 945 PostMessage(message string, target string, transfer []interface{}) 946 Print() 947 Prompt(prompt string, initial string) string 948 RequestAnimationFrame(callback func(time.Duration)) int 949 ResizeBy(dw, dh int) 950 ResizeTo(w, h int) 951 Scroll(x, y int) 952 ScrollBy(dx, dy int) 953 ScrollByLines(int) 954 ScrollTo(x, y int) 955 SetCursor(name string) 956 SetInterval(fn func(), delay int) int 957 SetTimeout(fn func(), delay int) int 958 Stop() 959 // TODO constructors 960} 961 962type window struct { 963 // TODO EventTarget 964 *js.Object 965} 966 967func (w *window) Console() *Console { 968 return &Console{w.Get("console")} 969} 970 971func (w *window) Document() Document { 972 return wrapDocument(w.Get("document")) 973} 974 975func (w *window) FrameElement() Element { 976 return wrapElement(w.Get("frameElement")) 977} 978 979func (w *window) Location() *Location { 980 o := w.Get("location") 981 return &Location{Object: o, URLUtils: &URLUtils{Object: o}} 982} 983 984func (w *window) Name() string { 985 return w.Get("name").String() 986} 987 988func (w *window) SetName(s string) { 989 w.Set("name", s) 990} 991 992func (w *window) InnerHeight() int { 993 return w.Get("innerHeight").Int() 994} 995 996func (w *window) InnerWidth() int { 997 return w.Get("innerWidth").Int() 998} 999 1000func (w *window) Length() int { 1001 return w.Get("length").Int() 1002} 1003 1004func (w *window) Opener() Window { 1005 return &window{w.Get("opener")} 1006} 1007 1008func (w *window) OuterHeight() int { 1009 return w.Get("outerHeight").Int() 1010} 1011 1012func (w *window) OuterWidth() int { 1013 return w.Get("outerWidth").Int() 1014} 1015 1016func (w *window) ScrollX() int { 1017 return w.Get("scrollX").Int() 1018} 1019 1020func (w *window) ScrollY() int { 1021 return w.Get("scrollY").Int() 1022} 1023 1024func (w *window) Parent() Window { 1025 return &window{w.Get("parent")} 1026} 1027 1028func (w *window) ScreenX() int { 1029 return w.Get("screenX").Int() 1030} 1031 1032func (w *window) ScreenY() int { 1033 return w.Get("screenY").Int() 1034} 1035 1036func (w *window) ScrollMaxX() int { 1037 return w.Get("scrollMaxX").Int() 1038} 1039 1040func (w *window) ScrollMaxY() int { 1041 return w.Get("scrollMaxY").Int() 1042} 1043 1044func (w *window) Top() Window { 1045 return &window{w.Get("top")} 1046} 1047 1048func (w *window) History() History { 1049 // FIXME implement 1050 return nil 1051} 1052 1053func (w *window) Navigator() Navigator { 1054 // FIXME implement 1055 panic("not implemented") 1056} 1057 1058func (w *window) Screen() *Screen { 1059 return &Screen{Object: w.Get("screen")} 1060} 1061 1062func (w *window) Alert(msg string) { 1063 w.Call("alert", msg) 1064} 1065 1066func (w *window) Back() { 1067 w.Call("back") 1068} 1069 1070func (w *window) Blur() { 1071 w.Call("blur") 1072} 1073 1074func (w *window) ClearInterval(id int) { 1075 w.Call("clearInterval", id) 1076} 1077 1078func (w *window) ClearTimeout(id int) { 1079 w.Call("clearTimeout", id) 1080} 1081 1082func (w *window) Close() { 1083 w.Call("close") 1084} 1085 1086func (w *window) Confirm(prompt string) bool { 1087 return w.Call("confirm", prompt).Bool() 1088} 1089 1090func (w *window) Focus() { 1091 w.Call("focus") 1092} 1093 1094func (w *window) Forward() { 1095 w.Call("forward") 1096} 1097 1098// GetComputedStyle returns the values of all CSS properties of an 1099// element after applying the active stylesheets. pseudoElt specifies 1100// the pseudo-element to match. For normal elements, it must be the 1101// empty string. 1102func (w *window) GetComputedStyle(el Element, pseudoElt string) *CSSStyleDeclaration { 1103 var optArg interface{} 1104 if pseudoElt != "" { 1105 optArg = pseudoElt 1106 } 1107 return &CSSStyleDeclaration{w.Call("getComputedStyle", el.Underlying(), optArg)} 1108} 1109 1110func (w *window) GetSelection() Selection { 1111 // FIXME implement 1112 panic("not implemented") 1113} 1114 1115func (w *window) Home() { 1116 w.Call("home") 1117} 1118 1119func (w *window) MoveBy(dx, dy int) { 1120 w.Call("moveBy", dx, dy) 1121} 1122 1123func (w *window) MoveTo(x, y int) { 1124 w.Call("moveTo", x, y) 1125} 1126 1127func (w *window) Open(url, name, features string) Window { 1128 return &window{w.Call("open", url, name, features)} 1129} 1130 1131func (w *window) OpenDialog(url, name, features string, args []interface{}) Window { 1132 return &window{w.Call("openDialog", url, name, features, args)} 1133} 1134 1135func (w *window) PostMessage(message string, target string, transfer []interface{}) { 1136 w.Call("postMessage", message, target, transfer) 1137} 1138 1139func (w *window) Print() { 1140 w.Call("print") 1141} 1142 1143func (w *window) Prompt(prompt string, initial string) string { 1144 return w.Call("prompt", prompt, initial).String() 1145} 1146 1147func (w *window) ResizeBy(dw, dh int) { 1148 w.Call("resizeBy", dw, dh) 1149} 1150 1151func (w *window) ResizeTo(width, height int) { 1152 w.Call("resizeTo", width, height) 1153} 1154 1155func (w *window) Scroll(x, y int) { 1156 w.Call("scroll", x, y) 1157} 1158 1159func (w *window) ScrollBy(dx, dy int) { 1160 w.Call("scrollBy", dx, dy) 1161} 1162 1163func (w *window) ScrollByLines(i int) { 1164 w.Call("scrollByLines", i) 1165} 1166 1167func (w *window) ScrollTo(x, y int) { 1168 w.Call("scrollTo", x, y) 1169} 1170 1171func (w *window) SetCursor(name string) { 1172 w.Call("setCursor", name) 1173} 1174 1175func (w *window) SetInterval(fn func(), delay int) int { 1176 return w.Call("setInterval", fn, delay).Int() 1177} 1178 1179func (w *window) SetTimeout(fn func(), delay int) int { 1180 return w.Call("setTimeout", fn, delay).Int() 1181} 1182 1183func (w *window) Stop() { 1184 w.Call("stop") 1185} 1186 1187// TODO reuse util.EventTarget 1188 1189func (w *window) AddEventListener(typ string, useCapture bool, listener func(Event)) func(o *js.Object) { 1190 wrapper := func(o *js.Object) { listener(wrapEvent(o)) } 1191 w.Call("addEventListener", typ, wrapper, useCapture) 1192 return wrapper 1193} 1194 1195func (w *window) RemoveEventListener(typ string, useCapture bool, listener func(*js.Object)) { 1196 w.Call("removeEventListener", typ, listener, useCapture) 1197} 1198 1199func (w *window) DispatchEvent(event Event) bool { 1200 return w.Call("dispatchEvent", event).Bool() 1201} 1202 1203func wrapDOMHighResTimeStamp(o *js.Object) time.Duration { 1204 return time.Duration(o.Float() * float64(time.Millisecond)) 1205} 1206 1207func (w *window) RequestAnimationFrame(callback func(time.Duration)) int { 1208 wrapper := func(o *js.Object) { callback(wrapDOMHighResTimeStamp(o)) } 1209 return w.Call("requestAnimationFrame", wrapper).Int() 1210} 1211 1212func (w *window) CancelAnimationFrame(requestID int) { 1213 w.Call("cancelAnimationFrame", requestID) 1214} 1215 1216// TODO all the other window methods 1217 1218type Selection interface { 1219 // TODO 1220} 1221 1222type Screen struct { 1223 *js.Object 1224 AvailTop int `js:"availTop"` 1225 AvailLeft int `js:"availLeft"` 1226 AvailHeight int `js:"availHeight"` 1227 AvailWidth int `js:"availWidth"` 1228 ColorDepth int `js:"colorDepth"` 1229 Height int `js:"height"` 1230 Left int `js:"left"` 1231 PixelDepth int `js:"pixelDepth"` 1232 Top int `js:"top"` 1233 Width int `js:"width"` 1234} 1235 1236type Navigator interface { 1237 NavigatorID 1238 NavigatorLanguage 1239 NavigatorOnLine 1240 NavigatorGeolocation 1241 // NavigatorPlugins 1242 // NetworkInformation 1243 CookieEnabled() bool 1244 DoNotTrack() string 1245 RegisterProtocolHandler(protocol, uri, title string) 1246} 1247 1248type NavigatorID interface { 1249 AppName() string 1250 AppVersion() string 1251 Platform() string 1252 Product() string 1253 UserAgent() string 1254} 1255 1256type NavigatorLanguage interface { 1257 Language() string 1258} 1259 1260type NavigatorOnLine interface { 1261 Online() bool 1262} 1263 1264type NavigatorGeolocation interface { 1265 Geolocation() Geolocation 1266} 1267 1268type Geolocation interface { 1269 // TODO wrap PositionOptions into something that uses the JS 1270 // object 1271 CurrentPosition(success func(Position), err func(PositionError), opts PositionOptions) Position 1272 WatchPosition(success func(Position), err func(PositionError), opts PositionOptions) int 1273 ClearWatch(int) 1274} 1275 1276type PositionError struct { 1277 *js.Object 1278 Code int `js:"code"` 1279} 1280 1281func (err *PositionError) Error() string { 1282 return err.Call("message").String() 1283} 1284 1285type PositionOptions struct { 1286 EnableHighAccuracy bool 1287 Timeout time.Duration 1288 MaximumAge time.Duration 1289} 1290 1291type Position struct { 1292 Coords *Coordinates 1293 Timestamp time.Time 1294} 1295 1296type Coordinates struct { 1297 *js.Object 1298 Latitude float64 `js:"latitude"` 1299 Longitude float64 `js:"longitude"` 1300 Altitude float64 `js:"altitude"` 1301 Accuracy float64 `js:"accuracy"` 1302 AltitudeAccuracy float64 `js:"altitudeAccuracy"` 1303 Heading float64 `js:"heading"` 1304 Speed float64 `js:"speed"` 1305} 1306 1307type History interface { 1308 Length() int 1309 State() interface{} 1310 Back() 1311 Forward() 1312 Go(offset int) 1313 PushState(state interface{}, title string, url string) 1314 ReplaceState(state interface{}, title string, url string) 1315} 1316 1317type Console struct { 1318 *js.Object 1319 // TODO will replace the js/console package 1320} 1321 1322type SVGDocument interface{} 1323type DocumentType interface{} 1324type DOMImplementation interface{} 1325type StyleSheet interface{} 1326type CSSStyleSheet interface{} 1327 1328type Node interface { 1329 EventTarget 1330 1331 Underlying() *js.Object 1332 BaseURI() string 1333 ChildNodes() []Node 1334 FirstChild() Node 1335 LastChild() Node 1336 NextSibling() Node 1337 NodeName() string 1338 NodeType() int 1339 NodeValue() string 1340 SetNodeValue(string) 1341 OwnerDocument() Document 1342 ParentNode() Node 1343 ParentElement() Element 1344 PreviousSibling() Node 1345 TextContent() string 1346 SetTextContent(string) 1347 AppendChild(Node) 1348 CloneNode(deep bool) Node 1349 CompareDocumentPosition(Node) int 1350 Contains(Node) bool 1351 HasChildNodes() bool 1352 InsertBefore(which Node, before Node) 1353 IsDefaultNamespace(string) bool 1354 IsEqualNode(Node) bool 1355 LookupPrefix() string 1356 LookupNamespaceURI(string) string 1357 Normalize() 1358 RemoveChild(Node) 1359 ReplaceChild(newChild, oldChild Node) 1360} 1361 1362// Type BasicNode implements the Node interface and is embedded by 1363// concrete node types and element types. 1364type BasicNode struct { 1365 *js.Object 1366} 1367 1368func (n *BasicNode) Underlying() *js.Object { 1369 return n.Object 1370} 1371 1372func (n *BasicNode) AddEventListener(typ string, useCapture bool, listener func(Event)) func(*js.Object) { 1373 wrapper := func(o *js.Object) { listener(wrapEvent(o)) } 1374 n.Call("addEventListener", typ, wrapper, useCapture) 1375 return wrapper 1376} 1377 1378func (n *BasicNode) RemoveEventListener(typ string, useCapture bool, listener func(*js.Object)) { 1379 n.Call("removeEventListener", typ, listener, useCapture) 1380} 1381 1382func (n *BasicNode) DispatchEvent(event Event) bool { 1383 return n.Call("dispatchEvent", event).Bool() 1384} 1385 1386func (n *BasicNode) BaseURI() string { 1387 return n.Get("baseURI").String() 1388} 1389 1390func (n *BasicNode) ChildNodes() []Node { 1391 return nodeListToNodes(n.Get("childNodes")) 1392} 1393 1394func (n *BasicNode) FirstChild() Node { 1395 return wrapNode(n.Get("firstChild")) 1396} 1397 1398func (n *BasicNode) LastChild() Node { 1399 return wrapNode(n.Get("lastChild")) 1400} 1401 1402func (n *BasicNode) NextSibling() Node { 1403 return wrapNode(n.Get("nextSibling")) 1404} 1405 1406func (n *BasicNode) NodeName() string { 1407 return n.Get("nodeName").String() 1408} 1409 1410func (n *BasicNode) NodeType() int { 1411 return n.Get("nodeType").Int() 1412} 1413 1414func (n *BasicNode) NodeValue() string { 1415 return toString(n.Get("nodeValue")) 1416} 1417 1418func (n *BasicNode) SetNodeValue(s string) { 1419 n.Set("nodeValue", s) 1420} 1421 1422func (n *BasicNode) OwnerDocument() Document { 1423 // FIXME implement 1424 panic("not implemented") 1425} 1426 1427func (n *BasicNode) ParentNode() Node { 1428 return wrapNode(n.Get("parentNode")) 1429} 1430 1431func (n *BasicNode) ParentElement() Element { 1432 return wrapElement(n.Get("parentElement")) 1433} 1434 1435func (n *BasicNode) PreviousSibling() Node { 1436 return wrapNode(n.Get("previousSibling")) 1437} 1438 1439func (n *BasicNode) TextContent() string { 1440 return toString(n.Get("textContent")) 1441} 1442 1443func (n *BasicNode) SetTextContent(s string) { 1444 n.Set("textContent", s) 1445} 1446 1447func (n *BasicNode) AppendChild(newchild Node) { 1448 n.Call("appendChild", newchild.Underlying()) 1449} 1450 1451func (n *BasicNode) CloneNode(deep bool) Node { 1452 return wrapNode(n.Call("cloneNode", deep)) 1453} 1454 1455const ( 1456 DocumentPositionDisconnected = 1 1457 DocumentPositionPreceding = 2 1458 DocumentPositionFollowing = 4 1459 DocumentPositionContains = 8 1460 DocumentPositionContainedBy = 16 1461 DocumentPositionImplementationSpecific = 32 1462) 1463 1464func (n *BasicNode) CompareDocumentPosition(other Node) int { 1465 return n.Call("compareDocumentPosition", other.Underlying()).Int() 1466} 1467 1468func (n *BasicNode) Contains(other Node) bool { 1469 return n.Call("contains", other.Underlying()).Bool() 1470} 1471 1472func (n *BasicNode) HasChildNodes() bool { 1473 return n.Call("hasChildNodes").Bool() 1474} 1475 1476func (n *BasicNode) InsertBefore(which Node, before Node) { 1477 var o interface{} 1478 if before != nil { 1479 o = before.Underlying() 1480 } 1481 n.Call("insertBefore", which.Underlying(), o) 1482} 1483 1484func (n *BasicNode) IsDefaultNamespace(s string) bool { 1485 return n.Call("isDefaultNamespace", s).Bool() 1486} 1487 1488func (n *BasicNode) IsEqualNode(other Node) bool { 1489 return n.Call("isEqualNode", other.Underlying()).Bool() 1490} 1491 1492func (n *BasicNode) LookupPrefix() string { 1493 return n.Call("lookupPrefix").String() 1494} 1495 1496func (n *BasicNode) LookupNamespaceURI(s string) string { 1497 return toString(n.Call("lookupNamespaceURI", s)) 1498} 1499 1500func (n *BasicNode) Normalize() { 1501 n.Call("normalize") 1502} 1503 1504func (n *BasicNode) RemoveChild(other Node) { 1505 n.Call("removeChild", other.Underlying()) 1506} 1507 1508func (n *BasicNode) ReplaceChild(newChild, oldChild Node) { 1509 n.Call("replaceChild", newChild.Underlying(), oldChild.Underlying()) 1510} 1511 1512type Element interface { 1513 Node 1514 ParentNode 1515 ChildNode 1516 1517 Attributes() map[string]string 1518 Class() *TokenList 1519 ID() string 1520 SetID(string) 1521 TagName() string 1522 GetAttribute(string) string // TODO can attributes only be strings? 1523 GetAttributeNS(ns string, name string) string // can attributes only be strings? 1524 GetBoundingClientRect() ClientRect 1525 GetElementsByClassName(string) []Element 1526 GetElementsByTagName(string) []Element 1527 GetElementsByTagNameNS(ns string, name string) []Element 1528 HasAttribute(string) bool 1529 HasAttributeNS(ns string, name string) bool 1530 QuerySelector(string) Element 1531 QuerySelectorAll(string) []Element 1532 RemoveAttribute(string) 1533 RemoveAttributeNS(ns string, name string) 1534 SetAttribute(name string, value string) 1535 SetAttributeNS(ns string, name string, value string) 1536 InnerHTML() string 1537 SetInnerHTML(string) 1538 OuterHTML() string 1539 SetOuterHTML(string) 1540} 1541 1542type ClientRect struct { 1543 *js.Object 1544 Height float64 `js:"height"` 1545 Width float64 `js:"width"` 1546 Left float64 `js:"left"` 1547 Right float64 `js:"right"` 1548 Top float64 `js:"top"` 1549 Bottom float64 `js:"bottom"` 1550} 1551 1552type ParentNode interface { 1553 // No properties/methods that aren't experimental 1554} 1555 1556type ChildNode interface { 1557 PreviousElementSibling() Element 1558 NextElementSibling() Element 1559} 1560 1561// Type BasicHTMLElement implements the HTMLElement interface and is 1562// embedded by concrete HTML element types. 1563type BasicHTMLElement struct { 1564 *BasicElement 1565 // TODO globalEventHandlers 1566} 1567 1568func (e *BasicHTMLElement) AccessKey() string { 1569 return e.Get("accessKey").String() 1570} 1571 1572func (e *BasicHTMLElement) Dataset() map[string]string { 1573 o := e.Get("dataset") 1574 data := map[string]string{} 1575 keys := js.Keys(o) 1576 for _, key := range keys { 1577 data[key] = o.Get(key).String() 1578 } 1579 return data 1580} 1581 1582func (e *BasicHTMLElement) SetAccessKey(s string) { 1583 e.Set("accessKey", s) 1584} 1585 1586func (e *BasicHTMLElement) AccessKeyLabel() string { 1587 return e.Get("accessKeyLabel").String() 1588} 1589 1590func (e *BasicHTMLElement) SetAccessKeyLabel(s string) { 1591 e.Set("accessKeyLabel", s) 1592} 1593 1594func (e *BasicHTMLElement) ContentEditable() string { 1595 return e.Get("contentEditable").String() 1596} 1597 1598func (e *BasicHTMLElement) SetContentEditable(s string) { 1599 e.Set("contentEditable", s) 1600} 1601 1602func (e *BasicHTMLElement) IsContentEditable() bool { 1603 return e.Get("isContentEditable").Bool() 1604} 1605 1606func (e *BasicHTMLElement) Dir() string { 1607 return e.Get("dir").String() 1608} 1609 1610func (e *BasicHTMLElement) SetDir(s string) { 1611 e.Set("dir", s) 1612} 1613 1614func (e *BasicHTMLElement) Draggable() bool { 1615 return e.Get("draggable").Bool() 1616} 1617 1618func (e *BasicHTMLElement) SetDraggable(b bool) { 1619 e.Set("draggable", b) 1620} 1621 1622func (e *BasicHTMLElement) Lang() string { 1623 return e.Get("lang").String() 1624} 1625 1626func (e *BasicHTMLElement) SetLang(s string) { 1627 e.Set("lang", s) 1628} 1629 1630func (e *BasicHTMLElement) OffsetHeight() float64 { 1631 return e.Get("offsetHeight").Float() 1632} 1633 1634func (e *BasicHTMLElement) OffsetLeft() float64 { 1635 return e.Get("offsetLeft").Float() 1636} 1637 1638func (e *BasicHTMLElement) OffsetParent() HTMLElement { 1639 return wrapHTMLElement(e.Get("offsetParent")) 1640} 1641 1642func (e *BasicHTMLElement) OffsetTop() float64 { 1643 return e.Get("offsetTop").Float() 1644} 1645 1646func (e *BasicHTMLElement) OffsetWidth() float64 { 1647 return e.Get("offsetWidth").Float() 1648} 1649 1650func (e *BasicHTMLElement) Style() *CSSStyleDeclaration { 1651 return &CSSStyleDeclaration{e.Get("style")} 1652} 1653 1654func (e *BasicHTMLElement) TabIndex() int { 1655 return e.Get("tabIndex").Int() 1656} 1657 1658func (e *BasicHTMLElement) SetTabIndex(i int) { 1659 e.Set("tabIndex", i) 1660} 1661 1662func (e *BasicHTMLElement) Title() string { 1663 return e.Get("title").String() 1664} 1665 1666func (e *BasicHTMLElement) SetTitle(s string) { 1667 e.Set("title", s) 1668} 1669 1670func (e *BasicHTMLElement) Blur() { 1671 e.Call("blur") 1672} 1673 1674func (e *BasicHTMLElement) Click() { 1675 e.Call("click") 1676} 1677 1678func (e *BasicHTMLElement) Focus() { 1679 e.Call("focus") 1680} 1681 1682// Type BasicElement implements the Element interface and is embedded 1683// by concrete element types and HTML element types. 1684type BasicElement struct { 1685 *BasicNode 1686} 1687 1688func (e *BasicElement) Attributes() map[string]string { 1689 o := e.Get("attributes") 1690 attrs := map[string]string{} 1691 length := o.Get("length").Int() 1692 for i := 0; i < length; i++ { 1693 item := o.Call("item", i) 1694 attrs[item.Get("name").String()] = item.Get("value").String() 1695 } 1696 return attrs 1697} 1698 1699func (e *BasicElement) GetBoundingClientRect() ClientRect { 1700 obj := e.Call("getBoundingClientRect") 1701 return ClientRect{Object: obj} 1702} 1703 1704func (e *BasicElement) PreviousElementSibling() Element { 1705 return wrapElement(e.Get("previousElementSibling")) 1706} 1707 1708func (e *BasicElement) NextElementSibling() Element { 1709 return wrapElement(e.Get("nextElementSibling")) 1710} 1711 1712func (e *BasicElement) Class() *TokenList { 1713 return &TokenList{dtl: e.Get("classList"), o: e.Object, sa: "className"} 1714} 1715 1716// SetClass sets the element's className attribute to s. Consider 1717// using the Class method instead. 1718func (e *BasicElement) SetClass(s string) { 1719 e.Set("className", s) 1720} 1721 1722func (e *BasicElement) ID() string { 1723 return e.Get("id").String() 1724} 1725 1726func (e *BasicElement) SetID(s string) { 1727 e.Set("id", s) 1728} 1729 1730func (e *BasicElement) TagName() string { 1731 return e.Get("tagName").String() 1732} 1733 1734func (e *BasicElement) GetAttribute(name string) string { 1735 return toString(e.Call("getAttribute", name)) 1736} 1737 1738func (e *BasicElement) GetAttributeNS(ns string, name string) string { 1739 return toString(e.Call("getAttributeNS", ns, name)) 1740} 1741 1742func (e *BasicElement) GetElementsByClassName(s string) []Element { 1743 return nodeListToElements(e.Call("getElementsByClassName", s)) 1744} 1745 1746func (e *BasicElement) GetElementsByTagName(s string) []Element { 1747 return nodeListToElements(e.Call("getElementsByTagName", s)) 1748} 1749 1750func (e *BasicElement) GetElementsByTagNameNS(ns string, name string) []Element { 1751 return nodeListToElements(e.Call("getElementsByTagNameNS", ns, name)) 1752} 1753 1754func (e *BasicElement) HasAttribute(s string) bool { 1755 return e.Call("hasAttribute", s).Bool() 1756} 1757 1758func (e *BasicElement) HasAttributeNS(ns string, name string) bool { 1759 return e.Call("hasAttributeNS", ns, name).Bool() 1760} 1761 1762func (e *BasicElement) QuerySelector(s string) Element { 1763 return wrapElement(e.Call("querySelector", s)) 1764} 1765 1766func (e *BasicElement) QuerySelectorAll(s string) []Element { 1767 return nodeListToElements(e.Call("querySelectorAll", s)) 1768} 1769 1770func (e *BasicElement) RemoveAttribute(s string) { 1771 e.Call("removeAttribute", s) 1772} 1773 1774func (e *BasicElement) RemoveAttributeNS(ns string, name string) { 1775 e.Call("removeAttributeNS", ns, name) 1776} 1777 1778func (e *BasicElement) SetAttribute(name string, value string) { 1779 e.Call("setAttribute", name, value) 1780} 1781 1782func (e *BasicElement) SetAttributeNS(ns string, name string, value string) { 1783 e.Call("setAttributeNS", ns, name, value) 1784} 1785 1786func (e *BasicElement) InnerHTML() string { 1787 return e.Get("innerHTML").String() 1788} 1789 1790func (e *BasicElement) SetInnerHTML(s string) { 1791 e.Set("innerHTML", s) 1792} 1793 1794func (e *BasicElement) OuterHTML() string { 1795 return e.Get("outerHTML").String() 1796} 1797 1798func (e *BasicElement) SetOuterHTML(s string) { 1799 e.Set("outerHTML", s) 1800} 1801 1802type HTMLAnchorElement struct { 1803 *BasicHTMLElement 1804 *URLUtils 1805 HrefLang string `js:"hreflang"` 1806 Media string `js:"media"` 1807 TabIndex int `js:"tabIndex"` 1808 Target string `js:"target"` 1809 Text string `js:"text"` 1810 Type string `js:"type"` 1811} 1812 1813func (e *HTMLAnchorElement) Rel() *TokenList { 1814 return &TokenList{dtl: e.Get("relList"), o: e.Object, sa: "rel"} 1815} 1816 1817type HTMLAppletElement struct { 1818 *BasicHTMLElement 1819 Alt string `js:"alt"` 1820 Coords string `js:"coords"` 1821 HrefLang string `js:"hreflang"` 1822 Media string `js:"media"` 1823 Search string `js:"search"` 1824 Shape string `js:"shape"` 1825 TabIndex int `js:"tabIndex"` 1826 Target string `js:"target"` 1827 Type string `js:"type"` 1828} 1829 1830func (e *HTMLAppletElement) Rel() *TokenList { 1831 return &TokenList{dtl: e.Get("relList"), o: e.Object, sa: "rel"} 1832} 1833 1834type HTMLAreaElement struct { 1835 *BasicHTMLElement 1836 *URLUtils 1837 Alt string `js:"alt"` 1838 Coords string `js:"coords"` 1839 HrefLang string `js:"hreflang"` 1840 Media string `js:"media"` 1841 Search string `js:"search"` 1842 Shape string `js:"shape"` 1843 TabIndex int `js:"tabIndex"` 1844 Target string `js:"target"` 1845 Type string `js:"type"` 1846} 1847 1848func (e *HTMLAreaElement) Rel() *TokenList { 1849 return &TokenList{dtl: e.Get("relList"), o: e.Object, sa: "rel"} 1850} 1851 1852type HTMLAudioElement struct{ *HTMLMediaElement } 1853 1854type HTMLBRElement struct{ *BasicHTMLElement } 1855 1856type HTMLBaseElement struct{ *BasicHTMLElement } 1857 1858func (e *HTMLBaseElement) Href() string { 1859 return e.Get("href").String() 1860} 1861 1862func (e *HTMLBaseElement) Target() string { 1863 return e.Get("target").String() 1864} 1865 1866type HTMLBodyElement struct{ *BasicHTMLElement } 1867 1868type HTMLButtonElement struct { 1869 *BasicHTMLElement 1870 AutoFocus bool `js:"autofocus"` 1871 Disabled bool `js:"disabled"` 1872 FormAction string `js:"formAction"` 1873 FormEncType string `js:"formEncType"` 1874 FormMethod string `js:"formMethod"` 1875 FormNoValidate bool `js:"formNoValidate"` 1876 FormTarget string `js:"formTarget"` 1877 Name string `js:"name"` 1878 TabIndex int `js:"tabIndex"` 1879 Type string `js:"type"` 1880 ValidationMessage string `js:"validationMessage"` 1881 Value string `js:"value"` 1882 WillValidate bool `js:"willValidate"` 1883} 1884 1885func (e *HTMLButtonElement) Form() *HTMLFormElement { 1886 return getForm(e.Object) 1887} 1888 1889func (e *HTMLButtonElement) Labels() []*HTMLLabelElement { 1890 return getLabels(e.Object) 1891} 1892 1893func (e *HTMLButtonElement) Validity() *ValidityState { 1894 // TODO replace with a field once GopherJS supports that 1895 return &ValidityState{Object: e.Get("validity")} 1896} 1897 1898func (e *HTMLButtonElement) CheckValidity() bool { 1899 return e.Call("checkValidity").Bool() 1900} 1901 1902func (e *HTMLButtonElement) SetCustomValidity(s string) { 1903 e.Call("setCustomValidity", s) 1904} 1905 1906type HTMLCanvasElement struct { 1907 *BasicHTMLElement 1908 Height int `js:"height"` 1909 Width int `js:"width"` 1910} 1911 1912type CanvasRenderingContext2D struct { 1913 *js.Object 1914 1915 // Colors, Styles, and Shadows 1916 1917 FillStyle string `js:"fillStyle"` 1918 StrokeStyle string `js:"strokeStyle"` 1919 ShadowColor string `js:"shadowColor"` 1920 ShadowBlur int `js:"shadowBlur"` 1921 ShadowOffsetX int `js:"shadowOffsetX"` 1922 ShadowOffsetY int `js:"shadowOffsetY"` 1923 1924 // Line Styles 1925 1926 LineCap string `js:"lineCap"` 1927 LineJoin string `js:"lineJoin"` 1928 LineWidth int `js:"lineWidth"` 1929 MiterLimit int `js:"miterLimit"` 1930 1931 // Text 1932 1933 Font string `js:"font"` 1934 TextAlign string `js:"textAlign"` 1935 TextBaseline string `js:"textBaseline"` 1936 1937 // Compositing 1938 1939 GlobalAlpha float64 `js:"globalAlpha"` 1940 GlobalCompositeOperation string `js:"globalCompositeOperation"` 1941} 1942 1943type ImageData struct { 1944 *js.Object 1945 1946 Width int `js:"width"` 1947 Height int `js:"height"` 1948 Data *js.Object `js:"data"` 1949} 1950 1951func (m *ImageData) ColorModel() color.Model { return color.NRGBAModel } 1952 1953func (m *ImageData) Bounds() image.Rectangle { 1954 return image.Rect(0, 0, m.Width, m.Height) 1955} 1956 1957func (m *ImageData) At(x, y int) color.Color { 1958 return m.NRGBAAt(x, y) 1959} 1960 1961func (m *ImageData) NRGBAAt(x, y int) color.NRGBA { 1962 if x < 0 || x >= m.Width || 1963 y < 0 || y >= m.Height { 1964 return color.NRGBA{} 1965 } 1966 i := (y*m.Width + x) * 4 1967 return color.NRGBA{ 1968 R: uint8(m.Data.Index(i + 0).Int()), 1969 G: uint8(m.Data.Index(i + 1).Int()), 1970 B: uint8(m.Data.Index(i + 2).Int()), 1971 A: uint8(m.Data.Index(i + 3).Int()), 1972 } 1973} 1974 1975func (m *ImageData) Set(x, y int, c color.Color) { 1976 if x < 0 || x >= m.Width || 1977 y < 0 || y >= m.Height { 1978 return 1979 } 1980 c1 := color.NRGBAModel.Convert(c).(color.NRGBA) 1981 i := (y*m.Width + x) * 4 1982 m.Data.SetIndex(i+0, c1.R) 1983 m.Data.SetIndex(i+1, c1.G) 1984 m.Data.SetIndex(i+2, c1.B) 1985 m.Data.SetIndex(i+3, c1.A) 1986} 1987 1988func (m *ImageData) SetNRGBA(x, y int, c color.NRGBA) { 1989 if x < 0 || x >= m.Width || 1990 y < 0 || y >= m.Height { 1991 return 1992 } 1993 i := (y*m.Width + x) * 4 1994 m.Data.SetIndex(i+0, c.R) 1995 m.Data.SetIndex(i+1, c.G) 1996 m.Data.SetIndex(i+2, c.B) 1997 m.Data.SetIndex(i+3, c.A) 1998} 1999 2000// CanvasGradient represents an opaque object describing a gradient. 2001// It is returned by the methods CanvasRenderingContext2D.CreateLinearGradient 2002// or CanvasRenderingContext2D.CreateRadialGradient. 2003// 2004// Reference: https://developer.mozilla.org/en-US/docs/Web/API/CanvasGradient. 2005type CanvasGradient struct { 2006 *js.Object 2007} 2008 2009// AddColorStop adds a new stop, defined by an offset and a color, to the gradient. 2010// It panics with *js.Error if the offset is not between 0 and 1, or if the color 2011// can't be parsed as a CSS <color>. 2012// 2013// Reference: https://developer.mozilla.org/en-US/docs/Web/API/CanvasGradient/addColorStop. 2014func (cg *CanvasGradient) AddColorStop(offset float64, color string) { 2015 cg.Call("addColorStop", offset, color) 2016} 2017 2018// CanvasPattern represents an opaque object describing a pattern. 2019// It is based on an image, a canvas or a video, created by the 2020// CanvasRenderingContext2D.CreatePattern method. 2021// 2022// Reference: https://developer.mozilla.org/en-US/docs/Web/API/CanvasPattern. 2023type CanvasPattern struct { 2024 *js.Object 2025} 2026 2027type TextMetrics struct { 2028 *js.Object 2029 2030 Width float64 `js:"width"` 2031 ActualBoundingBoxLeft float64 `js:"actualBoundingBoxLeft"` 2032 ActualBoundingBoxRight float64 `js:"actualBoundingBoxRight"` 2033 FontBoundingBoxAscent float64 `js:"fontBoundingBoxAscent"` 2034 FontBoundingBoxDescent float64 `js:"fontBoundingBoxDescent"` 2035 ActualBoundingBoxAscent float64 `js:"actualBoundingBoxAscent"` 2036 ActualBoundingBoxDescent float64 `js:"actualBoundingBoxDescent"` 2037 EmHeightAscent float64 `js:"emHeightAscent"` 2038 EmHeightDescent float64 `js:"emHeightDescent"` 2039 HangingBaseline float64 `js:"hangingBaseline"` 2040 AlphabeticBaseline float64 `js:"alphabeticBaseline"` 2041 IdeographicBaseline float64 `js:"ideographicBaseline"` 2042} 2043 2044// Creating canvas 2d context 2045 2046func (e *HTMLCanvasElement) GetContext2d() *CanvasRenderingContext2D { 2047 ctx := e.GetContext("2d") 2048 return &CanvasRenderingContext2D{Object: ctx} 2049} 2050 2051func (e *HTMLCanvasElement) GetContext(param string) *js.Object { 2052 return e.Call("getContext", param) 2053} 2054 2055// Drawing Rectangles 2056 2057func (ctx *CanvasRenderingContext2D) ClearRect(x, y, width, height float64) { 2058 ctx.Call("clearRect", x, y, width, height) 2059} 2060 2061func (ctx *CanvasRenderingContext2D) FillRect(x, y, width, height float64) { 2062 ctx.Call("fillRect", x, y, width, height) 2063} 2064 2065func (ctx *CanvasRenderingContext2D) StrokeRect(x, y, width, height float64) { 2066 ctx.Call("strokeRect", x, y, width, height) 2067} 2068 2069// Drawing Text 2070 2071// FillText fills a given text at the given (x, y) position. 2072// If the optional maxWidth parameter is not -1, 2073// the text will be scaled to fit that width. 2074func (ctx *CanvasRenderingContext2D) FillText(text string, x, y, maxWidth float64) { 2075 if maxWidth == -1 { 2076 ctx.Call("fillText", text, x, y) 2077 return 2078 } 2079 2080 ctx.Call("fillText", text, x, y, maxWidth) 2081} 2082 2083// StrokeText strokes a given text at the given (x, y) position. 2084// If the optional maxWidth parameter is not -1, 2085// the text will be scaled to fit that width. 2086func (ctx *CanvasRenderingContext2D) StrokeText(text string, x, y, maxWidth float64) { 2087 if maxWidth == -1 { 2088 ctx.Call("strokeText", text, x, y) 2089 return 2090 } 2091 2092 ctx.Call("strokeText", text, x, y, maxWidth) 2093} 2094func (ctx *CanvasRenderingContext2D) MeasureText(text string) *TextMetrics { 2095 textMetrics := ctx.Call("measureText", text) 2096 return &TextMetrics{Object: textMetrics} 2097} 2098 2099// Line styles 2100 2101func (ctx *CanvasRenderingContext2D) GetLineDash() []float64 { 2102 var dashes []float64 2103 for _, dash := range ctx.Call("getLineDash").Interface().([]interface{}) { 2104 dashes = append(dashes, dash.(float64)) 2105 } 2106 return dashes 2107} 2108 2109func (ctx *CanvasRenderingContext2D) SetLineDash(dashes []float64) { 2110 ctx.Call("setLineDash", dashes) 2111} 2112 2113// Gradients and patterns 2114 2115// CreateLinearGradient creates a linear gradient along the line given 2116// by the coordinates represented by the parameters. 2117// 2118// Reference: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/createLinearGradient. 2119func (ctx *CanvasRenderingContext2D) CreateLinearGradient(x0, y0, x1, y1 float64) *CanvasGradient { 2120 return &CanvasGradient{Object: ctx.Call("createLinearGradient", x0, y0, x1, y1)} 2121} 2122 2123// CreateRadialGradient creates a radial gradient given by the coordinates of the two circles 2124// represented by the parameters. 2125// 2126// Reference: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/createRadialGradient. 2127func (ctx *CanvasRenderingContext2D) CreateRadialGradient(x0, y0, r0, x1, y1, r1 float64) *CanvasGradient { 2128 return &CanvasGradient{Object: ctx.Call("createRadialGradient", x0, y0, r0, x1, y1, r1)} 2129} 2130 2131// CreatePattern creates a pattern using the specified image (a CanvasImageSource). 2132// It repeats the source in the directions specified by the repetition argument. 2133// 2134// Reference: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/createPattern. 2135func (ctx *CanvasRenderingContext2D) CreatePattern(image Element, repetition string) *CanvasPattern { 2136 return &CanvasPattern{Object: ctx.Call("createPattern", image, repetition)} 2137} 2138 2139// Paths 2140 2141func (ctx *CanvasRenderingContext2D) BeginPath() { 2142 ctx.Call("beginPath") 2143} 2144 2145func (ctx *CanvasRenderingContext2D) ClosePath() { 2146 ctx.Call("closePath") 2147} 2148 2149func (ctx *CanvasRenderingContext2D) MoveTo(x, y float64) { 2150 ctx.Call("moveTo", x, y) 2151} 2152 2153func (ctx *CanvasRenderingContext2D) LineTo(x, y float64) { 2154 ctx.Call("lineTo", x, y) 2155} 2156 2157func (ctx *CanvasRenderingContext2D) BezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y float64) { 2158 ctx.Call("bezierCurveTo", cp1x, cp1y, cp2x, cp2y, x, y) 2159} 2160 2161func (ctx *CanvasRenderingContext2D) QuadraticCurveTo(cpx, cpy, x, y float64) { 2162 ctx.Call("quadraticCurveTo", cpx, cpy, x, y) 2163} 2164 2165func (ctx *CanvasRenderingContext2D) Arc(x, y, r, sAngle, eAngle float64, counterclockwise bool) { 2166 ctx.Call("arc", x, y, r, sAngle, eAngle, counterclockwise) 2167} 2168 2169func (ctx *CanvasRenderingContext2D) ArcTo(x1, y1, x2, y2, r float64) { 2170 ctx.Call("arcTo", x1, y1, x2, y2, r) 2171} 2172 2173func (ctx *CanvasRenderingContext2D) Ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle float64, anticlockwise bool) { 2174 ctx.Call("ellipse", x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise) 2175} 2176 2177func (ctx *CanvasRenderingContext2D) Rect(x, y, width, height float64) { 2178 ctx.Call("rect", x, y, width, height) 2179} 2180 2181// Drawing paths 2182 2183func (ctx *CanvasRenderingContext2D) Fill() { 2184 ctx.Call("fill") 2185} 2186 2187func (ctx *CanvasRenderingContext2D) Stroke() { 2188 ctx.Call("stroke") 2189} 2190 2191func (ctx *CanvasRenderingContext2D) DrawFocusIfNeeded(element HTMLElement, path *js.Object) { 2192 ctx.Call("drawFocusIfNeeded", element, path) 2193} 2194 2195func (ctx *CanvasRenderingContext2D) ScrollPathIntoView(path *js.Object) { 2196 ctx.Call("scrollPathIntoView", path) 2197} 2198 2199func (ctx *CanvasRenderingContext2D) Clip() { 2200 ctx.Call("clip") 2201} 2202 2203func (ctx *CanvasRenderingContext2D) IsPointInPath(x, y float64) bool { 2204 return ctx.Call("isPointInPath", x, y).Bool() 2205} 2206 2207func (ctx *CanvasRenderingContext2D) IsPointInStroke(path *js.Object, x, y float64) bool { 2208 return ctx.Call("isPointInStroke", path, x, y).Bool() 2209} 2210 2211// Transformations 2212 2213func (ctx *CanvasRenderingContext2D) Rotate(angle float64) { 2214 ctx.Call("rotate", angle) 2215} 2216 2217func (ctx *CanvasRenderingContext2D) Scale(scaleWidth, scaleHeight float64) { 2218 ctx.Call("scale", scaleWidth, scaleHeight) 2219} 2220 2221func (ctx *CanvasRenderingContext2D) Translate(x, y float64) { 2222 ctx.Call("translate", x, y) 2223} 2224 2225func (ctx *CanvasRenderingContext2D) Transform(a, b, c, d, e, f float64) { 2226 ctx.Call("transform", a, b, c, d, e, f) 2227} 2228 2229func (ctx *CanvasRenderingContext2D) SetTransform(a, b, c, d, e, f float64) { 2230 ctx.Call("setTransform", a, b, c, d, e, f) 2231} 2232 2233func (ctx *CanvasRenderingContext2D) ResetTransform() { 2234 ctx.Call("resetTransform") 2235} 2236 2237// Drawing images 2238 2239func (ctx *CanvasRenderingContext2D) DrawImage(image Element, dx, dy float64) { 2240 ctx.Call("drawImage", image, dx, dy) 2241} 2242 2243func (ctx *CanvasRenderingContext2D) DrawImageWithDst(image Element, dx, dy, dWidth, dHeight float64) { 2244 ctx.Call("drawImage", image, dx, dy, dWidth, dHeight) 2245} 2246 2247func (ctx *CanvasRenderingContext2D) DrawImageWithSrcAndDst(image Element, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight float64) { 2248 ctx.Call("drawImage", image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) 2249} 2250 2251// Pixel manipulation 2252 2253func (ctx *CanvasRenderingContext2D) CreateImageData(width, height int) *ImageData { 2254 return &ImageData{Object: ctx.Call("createImageData", width, height)} 2255} 2256 2257func (ctx *CanvasRenderingContext2D) GetImageData(sx, sy, sw, sh int) *ImageData { 2258 return &ImageData{Object: ctx.Call("getImageData", sx, sy, sw, sh)} 2259} 2260 2261func (ctx *CanvasRenderingContext2D) PutImageData(imageData *ImageData, dx, dy float64) { 2262 ctx.Call("putImageData", imageData, dx, dy) 2263} 2264 2265func (ctx *CanvasRenderingContext2D) PutImageDataDirty(imageData *ImageData, dx, dy float64, dirtyX, dirtyY, dirtyWidth, dirtyHeight int) { 2266 ctx.Call("putImageData", imageData, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight) 2267} 2268 2269// State 2270 2271func (ctx *CanvasRenderingContext2D) Save() { 2272 ctx.Call("save") 2273} 2274 2275func (ctx *CanvasRenderingContext2D) Restore() { 2276 ctx.Call("restore") 2277} 2278 2279// TODO Hit regions: 2280// addHitRegion 2281// removeHitRegion 2282// clearHitRegions 2283 2284type HTMLDListElement struct{ *BasicHTMLElement } 2285 2286type HTMLDataElement struct { 2287 *BasicHTMLElement 2288 Value string `js:"value"` 2289} 2290 2291type HTMLDataListElement struct{ *BasicHTMLElement } 2292 2293func (e *HTMLDataListElement) Options() []*HTMLOptionElement { 2294 return getOptions(e.Object, "options") 2295} 2296 2297type HTMLDirectoryElement struct{ *BasicHTMLElement } 2298type HTMLDivElement struct{ *BasicHTMLElement } 2299 2300type HTMLEmbedElement struct { 2301 *BasicHTMLElement 2302 Src string `js:"src"` 2303 Type string `js:"type"` 2304 Width string `js:"width"` 2305} 2306 2307type HTMLFieldSetElement struct { 2308 *BasicHTMLElement 2309 Disabled bool `js:"disabled"` 2310 Name string `js:"name"` 2311 Type string `js:"type"` 2312 ValidationMessage string `js:"validationMessage"` 2313 WillValidate bool `js:"willValidate"` 2314} 2315 2316func (e *HTMLFieldSetElement) Elements() []HTMLElement { 2317 return nodeListToHTMLElements(e.Get("elements")) 2318} 2319 2320func (e *HTMLFieldSetElement) Form() *HTMLFormElement { 2321 return getForm(e.Object) 2322} 2323 2324func (e *HTMLFieldSetElement) Validity() *ValidityState { 2325 // TODO replace with a field once GopherJS supports that 2326 return &ValidityState{Object: e.Get("validity")} 2327} 2328 2329func (e *HTMLFieldSetElement) CheckValidity() bool { 2330 return e.Call("checkValidity").Bool() 2331} 2332 2333func (e *HTMLFieldSetElement) SetCustomValidity(s string) { 2334 e.Call("setCustomValidity", s) 2335} 2336 2337type HTMLFontElement struct{ *BasicHTMLElement } 2338 2339type HTMLFormElement struct { 2340 *BasicHTMLElement 2341 AcceptCharset string `js:"acceptCharset"` 2342 Action string `js:"action"` 2343 Autocomplete string `js:"autocomplete"` 2344 Encoding string `js:"encoding"` 2345 Enctype string `js:"enctype"` 2346 Length int `js:"length"` 2347 Method string `js:"method"` 2348 Name string `js:"name"` 2349 NoValidate bool `js:"noValidate"` 2350 Target string `js:"target"` 2351} 2352 2353func (e *HTMLFormElement) Elements() []HTMLElement { 2354 return nodeListToHTMLElements(e.Get("elements")) 2355} 2356 2357func (e *HTMLFormElement) CheckValidity() bool { 2358 return e.Call("checkValidity").Bool() 2359} 2360 2361func (e *HTMLFormElement) Submit() { 2362 e.Call("submit") 2363} 2364 2365func (e *HTMLFormElement) Reset() { 2366 e.Call("reset") 2367} 2368 2369func (e *HTMLFormElement) Item(index int) HTMLElement { 2370 return wrapHTMLElement(e.Call("item", index)) 2371} 2372 2373func (e *HTMLFormElement) NamedItem(name string) HTMLElement { 2374 return wrapHTMLElement(e.Call("namedItem", name)) 2375} 2376 2377type HTMLFrameElement struct{ *BasicHTMLElement } 2378type HTMLFrameSetElement struct{ *BasicHTMLElement } 2379type HTMLHRElement struct{ *BasicHTMLElement } 2380type HTMLHeadElement struct{ *BasicHTMLElement } 2381type HTMLHeadingElement struct{ *BasicHTMLElement } 2382type HTMLHtmlElement struct{ *BasicHTMLElement } 2383 2384type HTMLIFrameElement struct { 2385 *BasicHTMLElement 2386 Width string `js:"width"` 2387 Height string `js:"height"` 2388 Name string `js:"name"` 2389 Src string `js:"src"` 2390 SrcDoc string `js:"srcdoc"` 2391 Seamless bool `js:"seamless"` 2392 // TODO sandbox attribute 2393} 2394 2395func (e *HTMLIFrameElement) ContentDocument() Document { 2396 return wrapDocument(e.Get("contentDocument")) 2397} 2398 2399func (e *HTMLIFrameElement) ContentWindow() Window { 2400 return &window{e.Get("contentWindow")} 2401} 2402 2403type HTMLImageElement struct { 2404 *BasicHTMLElement 2405 Complete bool `js:"complete"` 2406 CrossOrigin string `js:"crossOrigin"` 2407 Height int `js:"height"` 2408 IsMap bool `js:"isMap"` 2409 NaturalHeight int `js:"naturalHeight"` 2410 NaturalWidth int `js:"naturalWidth"` 2411 Src string `js:"src"` 2412 UseMap string `js:"useMap"` 2413 Width int `js:"width"` 2414 // TODO constructor 2415} 2416 2417type HTMLInputElement struct { 2418 *BasicHTMLElement 2419 Accept string `js:"accept"` 2420 Alt string `js:"alt"` 2421 Autocomplete string `js:"autocomplete"` 2422 Autofocus bool `js:"autofocus"` 2423 Checked bool `js:"checked"` 2424 DefaultChecked bool `js:"defaultChecked"` 2425 DefaultValue string `js:"defaultValue"` 2426 DirName string `js:"dirName"` 2427 Disabled bool `js:"disabled"` 2428 FormAction string `js:"formAction"` 2429 FormEncType string `js:"formEncType"` 2430 FormMethod string `js:"formMethod"` 2431 FormNoValidate bool `js:"formNoValidate"` 2432 FormTarget string `js:"formTarget"` 2433 Height string `js:"height"` 2434 Indeterminate bool `js:"indeterminate"` 2435 Max string `js:"max"` 2436 MaxLength int `js:"maxLength"` 2437 Min string `js:"min"` 2438 Multiple bool `js:"multiple"` 2439 Name string `js:"name"` 2440 Pattern string `js:"pattern"` 2441 Placeholder string `js:"placeholder"` 2442 ReadOnly bool `js:"readOnly"` 2443 Required bool `js:"required"` 2444 SelectionDirection string `js:"selectionDirection"` 2445 SelectionEnd int `js:"selectionEnd"` 2446 SelectionStart int `js:"selectionStart"` 2447 Size int `js:"size"` 2448 Src string `js:"src"` 2449 Step string `js:"step"` 2450 TabIndex int `js:"tabIndex"` 2451 Type string `js:"type"` 2452 ValidationMessage string `js:"validationMessage"` 2453 Value string `js:"value"` 2454 ValueAsDate time.Time `js:"valueAsDate"` 2455 ValueAsNumber float64 `js:"valueAsNumber"` 2456 Width string `js:"width"` 2457 WillValidate bool `js:"willValidate"` 2458} 2459 2460// File represents files as can be obtained from file choosers or drag 2461// and drop. The dom package does not define any methods on File nor 2462// does it provide access to the blob or a way to read it. 2463type File struct { 2464 *js.Object 2465} 2466 2467func (e *HTMLInputElement) Files() []*File { 2468 files := e.Get("files") 2469 out := make([]*File, files.Get("length").Int()) 2470 for i := range out { 2471 out[i] = &File{files.Call("item", i)} 2472 } 2473 return out 2474} 2475 2476func (e *HTMLInputElement) List() *HTMLDataListElement { 2477 list := wrapHTMLElement(e.Get("list")) 2478 if list == nil { 2479 return nil 2480 } 2481 return list.(*HTMLDataListElement) 2482} 2483 2484func (e *HTMLInputElement) Labels() []*HTMLLabelElement { 2485 return getLabels(e.Object) 2486} 2487 2488func (e *HTMLInputElement) Form() *HTMLFormElement { 2489 return getForm(e.Object) 2490} 2491 2492func (e *HTMLInputElement) Validity() *ValidityState { 2493 // TODO replace with a field once GopherJS supports that 2494 return &ValidityState{Object: e.Get("validity")} 2495} 2496 2497func (e *HTMLInputElement) CheckValidity() bool { 2498 return e.Call("checkValidity").Bool() 2499} 2500 2501func (e *HTMLInputElement) SetCustomValidity(s string) { 2502 e.Call("setCustomValidity", s) 2503} 2504 2505func (e *HTMLInputElement) Select() { 2506 e.Call("select") 2507} 2508 2509func (e *HTMLInputElement) SetSelectionRange(start, end int, direction string) { 2510 e.Call("setSelectionRange", start, end, direction) 2511} 2512 2513func (e *HTMLInputElement) StepDown(n int) error { 2514 return callRecover(e.Object, "stepDown", n) 2515} 2516 2517func (e *HTMLInputElement) StepUp(n int) error { 2518 return callRecover(e.Object, "stepUp", n) 2519} 2520 2521type HTMLKeygenElement struct { 2522 *BasicHTMLElement 2523 Autofocus bool `js:"autofocus"` 2524 Challenge string `js:"challenge"` 2525 Disabled bool `js:"disabled"` 2526 Keytype string `js:"keytype"` 2527 Name string `js:"name"` 2528 Type string `js:"type"` 2529 ValidationMessage string `js:"validationMessage"` 2530 WillValidate bool `js:"willValidate"` 2531} 2532 2533func (e *HTMLKeygenElement) Form() *HTMLFormElement { 2534 return getForm(e.Object) 2535} 2536 2537func (e *HTMLKeygenElement) Labels() []*HTMLLabelElement { 2538 return getLabels(e.Object) 2539} 2540 2541func (e *HTMLKeygenElement) Validity() *ValidityState { 2542 // TODO replace with a field once GopherJS supports that 2543 return &ValidityState{Object: e.Get("validity")} 2544} 2545 2546func (e *HTMLKeygenElement) CheckValidity() bool { 2547 return e.Call("checkValidity").Bool() 2548} 2549 2550func (e *HTMLKeygenElement) SetCustomValidity(s string) { 2551 e.Call("setCustomValidity", s) 2552} 2553 2554type HTMLLIElement struct { 2555 *BasicHTMLElement 2556 Value int `js:"value"` 2557} 2558 2559type HTMLLabelElement struct { 2560 *BasicHTMLElement 2561 For string `js:"htmlFor"` 2562} 2563 2564func (e *HTMLLabelElement) Control() HTMLElement { 2565 return wrapHTMLElement(e.Get("control")) 2566} 2567 2568func (e *HTMLLabelElement) Form() *HTMLFormElement { 2569 return getForm(e.Object) 2570} 2571 2572type HTMLLegendElement struct{ *BasicHTMLElement } 2573 2574func (e *HTMLLegendElement) Form() *HTMLFormElement { 2575 return getForm(e.Object) 2576} 2577 2578type HTMLLinkElement struct { 2579 *BasicHTMLElement 2580 Disabled bool `js:"disabled"` 2581 Href string `js:"href"` 2582 HrefLang string `js:"hrefLang"` 2583 Media string `js:"media"` 2584 Type string `js:"type"` 2585} 2586 2587func (e *HTMLLinkElement) Rel() *TokenList { 2588 return &TokenList{dtl: e.Get("relList"), o: e.Object, sa: "rel"} 2589} 2590 2591func (e *HTMLLinkElement) Sizes() *TokenList { 2592 return &TokenList{dtl: e.Get("sizes"), o: e.Object} 2593} 2594 2595func (e *HTMLLinkElement) Sheet() StyleSheet { 2596 // FIXME implement 2597 panic("not implemented") 2598} 2599 2600type HTMLMapElement struct { 2601 *BasicHTMLElement 2602 Name string `js:"name"` 2603} 2604 2605func (e *HTMLMapElement) Areas() []*HTMLAreaElement { 2606 areas := nodeListToElements(e.Get("areas")) 2607 out := make([]*HTMLAreaElement, len(areas)) 2608 for i, area := range areas { 2609 out[i] = area.(*HTMLAreaElement) 2610 } 2611 return out 2612} 2613 2614func (e *HTMLMapElement) Images() []HTMLElement { 2615 return nodeListToHTMLElements(e.Get("areas")) 2616} 2617 2618type HTMLMediaElement struct { 2619 *BasicHTMLElement 2620 Paused bool `js:"paused"` 2621} 2622 2623func (e *HTMLMediaElement) Play() { 2624 e.Call("play") 2625} 2626 2627func (e *HTMLMediaElement) Pause() { 2628 e.Call("pause") 2629} 2630 2631type HTMLMenuElement struct{ *BasicHTMLElement } 2632 2633type HTMLMetaElement struct { 2634 *BasicHTMLElement 2635 Content string `js:"content"` 2636 HTTPEquiv string `js:"httpEquiv"` 2637 Name string `js:"name"` 2638} 2639 2640type HTMLMeterElement struct { 2641 *BasicHTMLElement 2642 High float64 `js:"high"` 2643 Low float64 `js:"low"` 2644 Max float64 `js:"max"` 2645 Min float64 `js:"min"` 2646 Optimum float64 `js:"optimum"` 2647} 2648 2649func (e HTMLMeterElement) Labels() []*HTMLLabelElement { 2650 return getLabels(e.Object) 2651} 2652 2653type HTMLModElement struct { 2654 *BasicHTMLElement 2655 Cite string `js:"cite"` 2656 DateTime string `js:"dateTime"` 2657} 2658 2659type HTMLOListElement struct { 2660 *BasicHTMLElement 2661 Reversed bool `js:"reversed"` 2662 Start int `js:"start"` 2663 Type string `js:"type"` 2664} 2665 2666type HTMLObjectElement struct { 2667 *BasicHTMLElement 2668 Data string `js:"data"` 2669 Height string `js:"height"` 2670 Name string `js:"name"` 2671 TabIndex int `js:"tabIndex"` 2672 Type string `js:"type"` 2673 TypeMustMatch bool `js:"typeMustMatch"` 2674 UseMap string `js:"useMap"` 2675 ValidationMessage string `js:"validationMessage"` 2676 With string `js:"with"` 2677 WillValidate bool `js:"willValidate"` 2678} 2679 2680func (e *HTMLObjectElement) Form() *HTMLFormElement { 2681 return getForm(e.Object) 2682} 2683 2684func (e *HTMLObjectElement) ContentDocument() Document { 2685 return wrapDocument(e.Get("contentDocument")) 2686} 2687 2688func (e *HTMLObjectElement) ContentWindow() Window { 2689 return &window{e.Get("contentWindow")} 2690} 2691 2692func (e *HTMLObjectElement) Validity() *ValidityState { 2693 // TODO replace with a field once GopherJS supports that 2694 return &ValidityState{Object: e.Get("validity")} 2695} 2696 2697func (e *HTMLObjectElement) CheckValidity() bool { 2698 return e.Call("checkValidity").Bool() 2699} 2700 2701func (e *HTMLObjectElement) SetCustomValidity(s string) { 2702 e.Call("setCustomValidity", s) 2703} 2704 2705type HTMLOptGroupElement struct { 2706 *BasicHTMLElement 2707 Disabled bool `js:"disabled"` 2708 Label string `js:"label"` 2709} 2710 2711type HTMLOptionElement struct { 2712 *BasicHTMLElement 2713 DefaultSelected bool `js:"defaultSelected"` 2714 Disabled bool `js:"disabled"` 2715 Index int `js:"index"` 2716 Label string `js:"label"` 2717 Selected bool `js:"selected"` 2718 Text string `js:"text"` 2719 Value string `js:"value"` 2720} 2721 2722func (e *HTMLOptionElement) Form() *HTMLFormElement { 2723 return getForm(e.Object) 2724} 2725 2726type HTMLOutputElement struct { 2727 *BasicHTMLElement 2728 DefaultValue string `js:"defaultValue"` 2729 Name string `js:"name"` 2730 Type string `js:"type"` 2731 ValidationMessage string `js:"validationMessage"` 2732 Value string `js:"value"` 2733 WillValidate bool `js:"willValidate"` 2734} 2735 2736func (e *HTMLOutputElement) Form() *HTMLFormElement { 2737 return getForm(e.Object) 2738} 2739 2740func (e *HTMLOutputElement) Labels() []*HTMLLabelElement { 2741 return getLabels(e.Object) 2742} 2743 2744func (e *HTMLOutputElement) Validity() *ValidityState { 2745 // TODO replace with a field once GopherJS supports that 2746 return &ValidityState{Object: e.Get("validity")} 2747} 2748 2749func (e *HTMLOutputElement) For() *TokenList { 2750 return &TokenList{dtl: e.Get("htmlFor"), o: e.Object} 2751} 2752 2753func (e *HTMLOutputElement) CheckValidity() bool { 2754 return e.Call("checkValidity").Bool() 2755} 2756 2757func (e *HTMLOutputElement) SetCustomValidity(s string) { 2758 e.Call("setCustomValidity", s) 2759} 2760 2761type HTMLParagraphElement struct{ *BasicHTMLElement } 2762 2763type HTMLParamElement struct { 2764 *BasicHTMLElement 2765 Name string `js:"name"` 2766 Value string `js:"value"` 2767} 2768 2769type HTMLPreElement struct{ *BasicHTMLElement } 2770 2771type HTMLProgressElement struct { 2772 *BasicHTMLElement 2773 Max float64 `js:"max"` 2774 Position float64 `js:"position"` 2775 Value float64 `js:"value"` 2776} 2777 2778func (e HTMLProgressElement) Labels() []*HTMLLabelElement { 2779 return getLabels(e.Object) 2780} 2781 2782type HTMLQuoteElement struct { 2783 *BasicHTMLElement 2784 Cite string `js:"cite"` 2785} 2786 2787type HTMLScriptElement struct { 2788 *BasicHTMLElement 2789 Type string `js:"type"` 2790 Src string `js:"src"` 2791 Charset string `js:"charset"` 2792 Async bool `js:"async"` 2793 Defer bool `js:"defer"` 2794 Text string `js:"text"` 2795} 2796 2797type HTMLSelectElement struct { 2798 *BasicHTMLElement 2799 Autofocus bool `js:"autofocus"` 2800 Disabled bool `js:"disabled"` 2801 Length int `js:"length"` 2802 Multiple bool `js:"multiple"` 2803 Name string `js:"name"` 2804 Required bool `js:"required"` 2805 SelectedIndex int `js:"selectedIndex"` 2806 Size int `js:"size"` 2807 Type string `js:"type"` 2808 ValidationMessage string `js:"validationMessage"` 2809 Value string `js:"value"` 2810 WillValidate bool `js:"willValidate"` 2811} 2812 2813func (e *HTMLSelectElement) Labels() []*HTMLLabelElement { 2814 return getLabels(e.Object) 2815} 2816 2817func (e *HTMLSelectElement) Form() *HTMLFormElement { 2818 return getForm(e.Object) 2819} 2820 2821func (e *HTMLSelectElement) Options() []*HTMLOptionElement { 2822 return getOptions(e.Object, "options") 2823} 2824 2825func (e *HTMLSelectElement) SelectedOptions() []*HTMLOptionElement { 2826 return getOptions(e.Object, "selectedOptions") 2827} 2828 2829func (e *HTMLSelectElement) Item(index int) *HTMLOptionElement { 2830 el := wrapHTMLElement(e.Call("item", index)) 2831 if el == nil { 2832 return nil 2833 } 2834 return el.(*HTMLOptionElement) 2835} 2836 2837func (e *HTMLSelectElement) NamedItem(name string) *HTMLOptionElement { 2838 el := wrapHTMLElement(e.Call("namedItem", name)) 2839 if el == nil { 2840 return nil 2841 } 2842 return el.(*HTMLOptionElement) 2843} 2844 2845// TODO(dominikh): Not implementing Add or Remove for now. For one, 2846// Add with "before" behaves weird when dealing with optgroups. Also, 2847// there's already InsertBefore and RemoveChild which can be used 2848// instead. 2849 2850func (e *HTMLSelectElement) Validity() *ValidityState { 2851 return &ValidityState{Object: e.Get("validity")} 2852} 2853 2854func (e *HTMLSelectElement) CheckValidity() bool { 2855 return e.Call("checkValidity").Bool() 2856} 2857 2858func (e *HTMLSelectElement) SetCustomValidity(s string) { 2859 e.Call("setCustomValidity", s) 2860} 2861 2862type HTMLSourceElement struct { 2863 *BasicHTMLElement 2864 Media string `js:"media"` 2865 Src string `js:"src"` 2866 Type string `js:"type"` 2867} 2868 2869type HTMLSpanElement struct{ *BasicHTMLElement } 2870type HTMLStyleElement struct{ *BasicHTMLElement } 2871type HTMLTableCaptionElement struct{ *BasicHTMLElement } 2872 2873type HTMLTableCellElement struct { 2874 *BasicHTMLElement 2875 ColSpan int `js:"colSpan"` 2876 RowSpan int `js:"rowSpan"` 2877 CellIndex int `js:"cellIndex"` 2878 // TODO headers 2879} 2880 2881type HTMLTableColElement struct { 2882 *BasicHTMLElement 2883 Span int `js:"span"` 2884} 2885 2886type HTMLTableDataCellElement struct{ *BasicHTMLElement } 2887type HTMLTableElement struct{ *BasicHTMLElement } 2888 2889type HTMLTableHeaderCellElement struct { 2890 *BasicHTMLElement 2891 Abbr string `js:"abbr"` 2892 Scope string `js:"scope"` 2893} 2894 2895type HTMLTableRowElement struct { 2896 *BasicHTMLElement 2897 RowIndex int `js:"rowIndex"` 2898 SectionRowIndex int `js:"sectionRowIndex"` 2899} 2900 2901func (e *HTMLTableRowElement) Cells() []*HTMLTableCellElement { 2902 cells := nodeListToElements(e.Get("cells")) 2903 out := make([]*HTMLTableCellElement, len(cells)) 2904 for i, cell := range cells { 2905 out[i] = cell.(*HTMLTableCellElement) 2906 } 2907 return out 2908} 2909 2910func (e *HTMLTableRowElement) InsertCell(index int) *HTMLTableCellElement { 2911 return wrapHTMLElement(e.Call("insertCell", index)).(*HTMLTableCellElement) 2912} 2913 2914func (e *HTMLTableRowElement) DeleteCell(index int) { 2915 // FIXME exception handling/check that index is in bounds 2916 e.Call("deleteCell", index) 2917} 2918 2919type HTMLTableSectionElement struct{ *BasicHTMLElement } 2920 2921func (e *HTMLTableSectionElement) Rows() []*HTMLTableRowElement { 2922 rows := nodeListToElements(e.Get("rows")) 2923 out := make([]*HTMLTableRowElement, len(rows)) 2924 for i, row := range rows { 2925 out[i] = row.(*HTMLTableRowElement) 2926 } 2927 return out 2928} 2929 2930func (e *HTMLTableSectionElement) DeleteRow(index int) { 2931 // FIXME exception handling/check that index is in bounds 2932 e.Call("deleteRow", index) 2933} 2934 2935func (e *HTMLTableSectionElement) InsertRow(index int) *HTMLTableRowElement { 2936 return wrapHTMLElement(e.Call("insertRow", index)).(*HTMLTableRowElement) 2937} 2938 2939type HTMLTextAreaElement struct { 2940 *BasicHTMLElement 2941 Autocomplete string `js:"autocomplete"` 2942 Autofocus bool `js:"autofocus"` 2943 Cols int `js:"cols"` 2944 DefaultValue string `js:"defaultValue"` 2945 DirName string `js:"dirName"` 2946 Disabled bool `js:"disabled"` 2947 MaxLength int `js:"maxLength"` 2948 Name string `js:"name"` 2949 Placeholder string `js:"placeholder"` 2950 ReadOnly bool `js:"readOnly"` 2951 Required bool `js:"required"` 2952 Rows int `js:"rows"` 2953 SelectionDirection string `js:"selectionDirection"` 2954 SelectionStart int `js:"selectionStart"` 2955 SelectionEnd int `js:"selectionEnd"` 2956 TabIndex int `js:"tabIndex"` 2957 TextLength int `js:"textLength"` 2958 Type string `js:"type"` 2959 ValidationMessage string `js:"validationMessage"` 2960 Value string `js:"value"` 2961 WillValidate bool `js:"willValidate"` 2962 Wrap string `js:"wrap"` 2963} 2964 2965func (e *HTMLTextAreaElement) Form() *HTMLFormElement { 2966 return getForm(e.Object) 2967} 2968 2969func (e *HTMLTextAreaElement) Labels() []*HTMLLabelElement { 2970 return getLabels(e.Object) 2971} 2972 2973func (e *HTMLTextAreaElement) Validity() *ValidityState { 2974 // TODO replace with a field once GopherJS supports that 2975 return &ValidityState{Object: e.Get("validity")} 2976} 2977 2978func (e *HTMLTextAreaElement) CheckValidity() bool { 2979 return e.Call("checkValidity").Bool() 2980} 2981 2982func (e *HTMLTextAreaElement) SetCustomValidity(s string) { 2983 e.Call("setCustomValidity", s) 2984} 2985 2986func (e *HTMLTextAreaElement) Select() { 2987 e.Call("select") 2988} 2989 2990func (e *HTMLTextAreaElement) SetSelectionRange(start, end int, direction string) { 2991 e.Call("setSelectionRange", start, end, direction) 2992} 2993 2994type HTMLTimeElement struct { 2995 *BasicHTMLElement 2996 DateTime string `js:"dateTime"` 2997} 2998 2999type HTMLTitleElement struct { 3000 *BasicHTMLElement 3001 Text string `js:"text"` 3002} 3003 3004// TextTrack represents text track data for <track> elements. It does 3005// not currently provide any methods or attributes and it hasn't been 3006// decided yet whether they will be added to this package or a 3007// separate package. 3008type TextTrack struct{ *js.Object } 3009 3010type HTMLTrackElement struct { 3011 *BasicHTMLElement 3012 Kind string `js:"kind"` 3013 Src string `js:"src"` 3014 Srclang string `js:"srclang"` 3015 Label string `js:"label"` 3016 Default bool `js:"default"` 3017 ReadyState int `js:"readyState"` 3018} 3019 3020func (e *HTMLTrackElement) Track() *TextTrack { 3021 return &TextTrack{e.Get("track")} 3022} 3023 3024type HTMLUListElement struct{ *BasicHTMLElement } 3025type HTMLUnknownElement struct{ *BasicHTMLElement } 3026 3027type HTMLVideoElement struct{ *HTMLMediaElement } 3028 3029type ValidityState struct { 3030 *js.Object 3031 CustomError bool `js:"customError"` 3032 PatternMismatch bool `js:"patternMismatch"` 3033 RangeOverflow bool `js:"rangeOverflow"` 3034 RangeUnderflow bool `js:"rangeUnderflow"` 3035 StepMismatch bool `js:"stepMismatch"` 3036 TooLong bool `js:"tooLong"` 3037 TypeMismatch bool `js:"typeMismatch"` 3038 Valid bool `js:"valid"` 3039 ValueMissing bool `js:"valueMissing"` 3040} 3041 3042type CSSStyleDeclaration struct{ *js.Object } 3043 3044func (css *CSSStyleDeclaration) ToMap() map[string]string { 3045 m := make(map[string]string) 3046 N := css.Get("length").Int() 3047 for i := 0; i < N; i++ { 3048 name := css.Call("item", i).String() 3049 value := css.Call("getPropertyValue", name).String() 3050 m[name] = value 3051 } 3052 3053 return m 3054} 3055 3056func (css *CSSStyleDeclaration) RemoveProperty(name string) { 3057 css.Call("removeProperty", name) 3058} 3059 3060func (css *CSSStyleDeclaration) GetPropertyValue(name string) string { 3061 return toString(css.Call("getPropertyValue", name)) 3062} 3063 3064func (css *CSSStyleDeclaration) GetPropertyPriority(name string) string { 3065 return toString(css.Call("getPropertyPriority", name)) 3066} 3067 3068func (css *CSSStyleDeclaration) SetProperty(name, value, priority string) { 3069 css.Call("setProperty", name, value, priority) 3070} 3071 3072func (css *CSSStyleDeclaration) Index(idx int) string { 3073 return css.Call("index", idx).String() 3074} 3075 3076func (css *CSSStyleDeclaration) Length() int { 3077 return css.Get("length").Int() 3078} 3079 3080type Text struct { 3081 *BasicNode 3082} 3083