Packages

macro class html extends Annotation with StaticAnnotation

An annotation to convert XHTML literals to data-bindable DOM nodes.

Author:

杨博 (Yang Bo) <[email protected]>

Annotations
@compileTimeOnly("enable macro paradise to expand macro annotations")
Source
html.scala
Examples:
  1. XHTML literals with text attributes

    @html
    val mySpan = <span class="my-class" tabindex="42"></span>
    mySpan.value.nodeName should be("SPAN")
    mySpan.value.className should be("my-class")
    mySpan.value.tabIndex should be(42)

    Nested XHTML literals with interpolation:

    @html
    val mySpan2 = <span style="color: red;" tabIndex={99999} title="my title" class={"my-class"}><span>text</span><i style={"color: blue;"} tabIndex={99}></i><span innerHTML={"html"}></span><span></span>{mySpan.bind}</span>
    mySpan2.watch()
    mySpan2.value.outerHTML should be("""<span style="color: red;" tabindex="99999" title="my title" class="my-class"><span>text</span><i style="color: blue;" tabindex="99"></i><span>html</span><span></span><span class="my-class" tabindex="42"></span></span>""")
  2. ,
  3. Special character in attribute names

    @html
    val myMeta = <meta http-equiv="refresh" content="30"/>
    myMeta.watch()
    myMeta.value.outerHTML should be("""<meta http-equiv="refresh" content="30">""")
  4. ,
  5. Opaque type aliases of HTMLInputElement

    @html
    val myMeta = <input name="myInput" type="radio"/>
    myMeta.watch()
    myMeta.value.outerHTML should be("""<input name="myInput" type="radio">""")
  6. ,
  7. Element list of XHTML literals

    @html
    val mySpans = <span></span><span title={"my title"} class=""></span><span class="my-class"></span>
    mySpans.watch()
    import org.scalajs.dom.html.Span
    inside(mySpans.value) {
      case collection.Seq(span1: Span, span2: Span, span3: Span) =>
        span1.nodeName should be("SPAN")
        span1.hasAttribute("class") should be(false)
        span1.className should be("")
        span2.title should be("my title")
        span2.hasAttribute("class") should be(true)
        span2.className should be("")
        span3.className should be("my-class")
    }
  8. ,
  9. Text interpolation in an element

    @html val monadicSpan = <span>{"text"}</span>
    monadicSpan.watch()
    assert(monadicSpan.value.outerHTML == "<span>text</span>")
  10. ,
  11. Changing text

    import com.thoughtworks.binding.Binding.Var
    val v0 = Var("original text")
    @html val monadicSpan = <span> <i> {v0.bind} </i> </span>
    monadicSpan.watch()
    assert(monadicSpan.value.outerHTML == "<span> <i> original text </i> </span>")
    v0.value = "changed"
    assert(monadicSpan.value.outerHTML == "<span> <i> changed </i> </span>")
  12. ,
  13. for / yield expressions in XHTML interpolation

    import com.thoughtworks.binding.Binding.Vars
    val v0 = Vars("original text 0","original text 1")
    @html val monadicSpan = <span> <i> { for (s <- v0) yield <b>{s}</b> } </i> </span>
    monadicSpan.watch()
    val span = monadicSpan.value
    assert(monadicSpan.value.outerHTML == "<span> <i> <b>original text 0</b><b>original text 1</b> </i> </span>")
    v0.value.prepend("prepended")
    assert(span eq monadicSpan.value)
    assert(monadicSpan.value.outerHTML == "<span> <i> <b>prepended</b><b>original text 0</b><b>original text 1</b> </i> </span>")
    v0.value.remove(1)
    assert(span eq monadicSpan.value)
    assert(monadicSpan.value.outerHTML == "<span> <i> <b>prepended</b><b>original text 1</b> </i> </span>")
  14. ,
  15. for / yield / if expressions in XHTML interpolation

    import com.thoughtworks.binding.Binding
    import com.thoughtworks.binding.Binding.Var
    import com.thoughtworks.binding.Binding.Vars
    final case class User(firstName: Var[String], lastName: Var[String], age: Var[Int])
    val filterPattern = Var("")
    val users = Vars(
      User(Var("Steve"), Var("Jobs"), Var(10)),
      User(Var("Tim"), Var("Cook"), Var(12)),
      User(Var("Jeff"), Var("Lauren"), Var(13))
    )
    def shouldShow(user: User): Binding[Boolean] = Binding {
      val pattern = filterPattern.bind
      if (pattern == "") {
        true
      } else if (user.firstName.bind.toLowerCase.contains(pattern)) {
        true
      } else if (user.lastName.bind.toLowerCase.contains(pattern)) {
        true
      } else {
        false
      }
    }
    
    @html
    def tbodyBinding = {
      <tbody>{
        for {
          user <- users
          if shouldShow(user).bind
        } yield <tr><td>{user.firstName.bind}</td><td>{user.lastName.bind}</td><td>{user.age.bind.toString}</td></tr>
      }</tbody>
    }
    
    @html
    val tableBinding = {
      <table class="my-table" title="My Tooltip"><thead><tr><td>First Name</td><td>Second Name</td><td>Age</td></tr></thead>{tbodyBinding.bind}</table>
    }
    tableBinding.watch()
    assert(tableBinding.value.outerHTML == """<table class="my-table" title="My Tooltip"><thead><tr><td>First Name</td><td>Second Name</td><td>Age</td></tr></thead><tbody><tr><td>Steve</td><td>Jobs</td><td>10</td></tr><tr><td>Tim</td><td>Cook</td><td>12</td></tr><tr><td>Jeff</td><td>Lauren</td><td>13</td></tr></tbody></table>""")
    filterPattern.value = "o"
    assert(tableBinding.value.outerHTML == """<table class="my-table" title="My Tooltip"><thead><tr><td>First Name</td><td>Second Name</td><td>Age</td></tr></thead><tbody><tr><td>Steve</td><td>Jobs</td><td>10</td></tr><tr><td>Tim</td><td>Cook</td><td>12</td></tr></tbody></table>""")
  16. ,
  17. Dynamc attributes

    @html
    val myBr = <br data:toString="+©" data:applyDynamic="value"/>
    myBr.watch()
    myBr.value.outerHTML should be("""<br tostring="+©" applydynamic="value">""")
  18. ,
  19. Changing attribute values

    import com.thoughtworks.binding.Binding.Var
    val id = Var("oldId")
    @html val myInput = <input data:applyDynamic={id.bind} data:custom={id.bind} name={id.bind} id={id.bind} onclick={ _: Any => id.value = "newId" }/>
    myInput.watch()
    assert(myInput.value.outerHTML == """<input applydynamic="oldId" custom="oldId" name="oldId" id="oldId">""")
    myInput.value.onclick(null)
    assert(myInput.value.outerHTML == """<input applydynamic="newId" custom="newId" name="newId" id="newId">""")
  20. ,
  21. A child node must not be inserted more than once

    an[IllegalStateException] should be thrownBy {
      @html
      val child = <hr/>
      @html
      val parent = <span><i>{child.bind}</i><i>{child.bind}</i></span>
      parent.watch()
    }
  22. ,
  23. Seq in DOM

    import org.scalajs.dom.document
    @html def mySelect = {
      <select>{Seq(<option>data1</option>, <option>data2</option>)}</select>
    }
    val span = document.createElement("span")
    html.render(span, mySelect)
    span.firstChild.childNodes.length should be(2)
  24. ,
  25. XHTML comments

    import org.scalajs.dom.document
    @html def comment = <span></span>
    val span = document.createElement("span")
    html.render(span, comment)
    assert(span.innerHTML == "<span></span>")
  26. ,
  27. Escape

    import org.scalajs.dom.document
    @html def escaped = <span>&#32;$minus</span>
    val span = document.createElement("span")
    html.render(span, escaped)
    assert(span.innerHTML == "<span> $minus</span>")
  28. ,
  29. Entity references

    import org.scalajs.dom.document
    @html def entity = <span class="< > © λ my-class">my text &lt; &gt; &copy; &lambda;</span>
    val span = document.createElement("span")
    html.render(span, entity)
    assert(span.innerHTML == """<span class="< > © λ my-class">my text < > © λ</span>""")
  30. ,
  31. Process instructions

    @html val myXmlStylesheet = <?my-instruction my data?>
    myXmlStylesheet.watch()
    myXmlStylesheet.value.target should be("my-instruction")
    myXmlStylesheet.value.data should be("my data")
  32. ,
  33. CDATA sections are not supported in HTML documents

    import scala.scalajs.js
    a[js.JavaScriptException] should be thrownBy {
      @html val myCData = <![CDATA[my data]]>
      myCData.watch()
    }
  34. ,
  35. XML namespaces

    import scala.language.dynamics
    import org.scalajs.dom.document
    import org.scalajs.dom.raw._
    import com.thoughtworks.binding.Binding
    import com.thoughtworks.binding.Binding.BindingInstances.monadSyntax._
    object svg {
      object texts extends Dynamic {
        @inline def selectDynamic(data: String) = new html.NodeBinding.Constant.TextBuilder(data)
      }
      object elements {
        object svg extends Curried {
          @inline def applyBegin = new html.NodeBinding.Constant.ElementBuilder(document.createElementNS("http://www.w3.org/2000/svg", "svg").asInstanceOf[SVGSVGElement])
        }
        object text extends Curried {
          @inline def applyBegin = new html.NodeBinding.Constant.ElementBuilder(document.createElementNS("http://www.w3.org/2000/svg", "text").asInstanceOf[SVGTextElement])
        }
      }
      @inline def interpolation = Binding
      object values {
        sealed trait FontStyle
        case object normal extends FontStyle
        case object italic extends FontStyle
        case object oblique extends FontStyle
      }
      object attributes {
        def font$minusstyle(value: values.FontStyle) = {
          new html.NodeBinding.Constant.AttributeBuilder.Untyped(_.setAttribute("font-style", value.toString))
        }
        def font$minusstyle(binding: Binding[values.FontStyle]) = {
          new html.NodeBinding.Interpolated.AttributeBuilder( element =>
            binding.map { value =>
              element.setAttribute("font-style", value.toString)
            }
          )
        }
      }
    }
    implicit final class SvgUriOps(uriFactory: html.autoImports.xml.uris.type) {
      @inline def http$colon$div$divwww$u002Ew3$u002Eorg$div2000$divsvg = svg
    }
    @html
    val mySvg1 = <svg xmlns="http://www.w3.org/2000/svg"><text font-style="normal">my text</text></svg>
    mySvg1.watch()
    mySvg1.value.outerHTML should be("""<svg><text font-style="normal">my text</text></svg>""")
    
    import svg.values.normal
    @html
    val mySvg2 = <svg:svg xmlns:svg="http://www.w3.org/2000/svg"><svg:text font-style={normal}>my text</svg:text></svg:svg>
    mySvg2.watch()
    mySvg2.value.outerHTML should be("""<svg><text font-style="normal">my text</text></svg>""")
Type Hierarchy
Ordering
  1. Alphabetic
  2. By Inheritance
Inherited
  1. html
  2. StaticAnnotation
  3. Annotation
  4. AnyRef
  5. Any
Implicitly
  1. by any2stringadd
  2. by StringFormat
  3. by Ensuring
  4. by ArrowAssoc
  1. Hide All
  2. Show All
Visibility
  1. Public
  2. Protected

Instance Constructors

  1. new html()

Value Members

  1. final def !=(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  2. final def ##: Int
    Definition Classes
    AnyRef → Any
  3. def +(other: String): String
    Implicit
    This member is added by an implicit conversion from html toany2stringadd[html] performed by method any2stringadd in scala.Predef.
    Definition Classes
    any2stringadd
  4. def ->[B](y: B): (html, B)
    Implicit
    This member is added by an implicit conversion from html toArrowAssoc[html] performed by method ArrowAssoc in scala.Predef.
    Definition Classes
    ArrowAssoc
    Annotations
    @inline()
  5. final def ==(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  6. final def asInstanceOf[T0]: T0
    Definition Classes
    Any
  7. def clone(): AnyRef
    Attributes
    protected[lang]
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.CloneNotSupportedException]) @native() @HotSpotIntrinsicCandidate()
  8. def ensuring(cond: (html) => Boolean, msg: => Any): html
    Implicit
    This member is added by an implicit conversion from html toEnsuring[html] performed by method Ensuring in scala.Predef.
    Definition Classes
    Ensuring
  9. def ensuring(cond: (html) => Boolean): html
    Implicit
    This member is added by an implicit conversion from html toEnsuring[html] performed by method Ensuring in scala.Predef.
    Definition Classes
    Ensuring
  10. def ensuring(cond: Boolean, msg: => Any): html
    Implicit
    This member is added by an implicit conversion from html toEnsuring[html] performed by method Ensuring in scala.Predef.
    Definition Classes
    Ensuring
  11. def ensuring(cond: Boolean): html
    Implicit
    This member is added by an implicit conversion from html toEnsuring[html] performed by method Ensuring in scala.Predef.
    Definition Classes
    Ensuring
  12. final def eq(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  13. def equals(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef → Any
  14. def formatted(fmtstr: String): String
    Implicit
    This member is added by an implicit conversion from html toStringFormat[html] performed by method StringFormat in scala.Predef.
    Definition Classes
    StringFormat
    Annotations
    @inline()
  15. final def getClass(): Class[_ <: AnyRef]
    Definition Classes
    AnyRef → Any
    Annotations
    @native() @HotSpotIntrinsicCandidate()
  16. def hashCode(): Int
    Definition Classes
    AnyRef → Any
    Annotations
    @native() @HotSpotIntrinsicCandidate()
  17. final def isInstanceOf[T0]: Boolean
    Definition Classes
    Any
  18. macro def macroTransform(annottees: Any*): Any
  19. final def ne(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  20. final def notify(): Unit
    Definition Classes
    AnyRef
    Annotations
    @native() @HotSpotIntrinsicCandidate()
  21. final def notifyAll(): Unit
    Definition Classes
    AnyRef
    Annotations
    @native() @HotSpotIntrinsicCandidate()
  22. final def synchronized[T0](arg0: => T0): T0
    Definition Classes
    AnyRef
  23. def toString(): String
    Definition Classes
    AnyRef → Any
  24. final def wait(arg0: Long, arg1: Int): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.InterruptedException])
  25. final def wait(arg0: Long): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.InterruptedException]) @native()
  26. final def wait(): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.InterruptedException])

Deprecated Value Members

  1. def finalize(): Unit
    Attributes
    protected[lang]
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.Throwable]) @Deprecated
    Deprecated
  2. def [B](y: B): (html, B)
    Implicit
    This member is added by an implicit conversion from html toArrowAssoc[html] performed by method ArrowAssoc in scala.Predef.
    Definition Classes
    ArrowAssoc
    Annotations
    @deprecated
    Deprecated

    (Since version 2.13.0) Use -> instead. If you still wish to display it as one character, consider using a font with programming ligatures such as Fira Code.

Inherited from StaticAnnotation

Inherited from Annotation

Inherited from AnyRef

Inherited from Any

Inherited by implicit conversion any2stringadd fromhtml to any2stringadd[html]

Inherited by implicit conversion StringFormat fromhtml to StringFormat[html]

Inherited by implicit conversion Ensuring fromhtml to Ensuring[html]

Inherited by implicit conversion ArrowAssoc fromhtml to ArrowAssoc[html]

Ungrouped