Packages

p

org.lrng

binding

package binding

Ordering
  1. Alphabetic
Visibility
  1. Public
  2. Protected

Type Members

  1. macro class html extends Annotation with StaticAnnotation

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

    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")
    Examples:
    1. XHTML literals with text attributes

      @html
      val myDiv =
      
      
      myDiv.value.nodeName should be("DIV")
      myDiv.value.className should be("my-class")
      myDiv.value.tabIndex should be(42)

      Nested XHTML literals with interpolation:

      @html
      val myDiv2 =
      
      
      
      text<span style={"color: blue;"} tabIndex={99}></span>
      
      
      
      {myDiv.bind}
      myDiv2.watch()
      myDiv2.value.outerHTML should be("""
      
      
      
      text<span style="color: blue;" tabindex="99"></span>
      
      html
      
      
      
      """)
    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 myDivs =
      
      
      
      
      
      
      myDivs.watch()
      import org.scalajs.dom.html.Div
      inside(myDivs.value) {
        case collection.Seq(div1: Div, div2: Div, div3: Div) =>
          div1.nodeName should be("DIV")
          div1.hasAttribute("class") should be(false)
          div1.className should be("")
          div2.title should be("my title")
          div2.hasAttribute("class") should be(true)
          div2.className should be("")
          div3.className should be("my-class")
      }
    8. ,
    9. Text interpolation in an element

      @html val monadicDiv =
      
      {"text"}
      monadicDiv.watch()
      assert(monadicDiv.value.outerHTML == "
      
      text")
    10. ,
    11. Changing text

      import com.thoughtworks.binding.Binding.Var
      val v0 = Var("original text")
      @html val monadicDiv =
      
       <span> {v0.bind} </span>
      monadicDiv.watch()
      assert(monadicDiv.value.outerHTML == "
      
       <span> original text </span> ")
      v0.value = "changed"
      assert(monadicDiv.value.outerHTML == "
      
       <span> changed </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 monadicDiv =
      
       <span> { for (s <- v0) yield <b>{s}</b> } </span>
      monadicDiv.watch()
      val div = monadicDiv.value
      assert(monadicDiv.value.outerHTML == "
      
       <span> <b>original text 0</b><b>original text 1</b> </span> ")
      v0.value.prepend("prepended")
      assert(div eq monadicDiv.value)
      assert(monadicDiv.value.outerHTML == "
      
       <span> <b>prepended</b><b>original text 0</b><b>original text 1</b> </span> ")
      v0.value.remove(1)
      assert(div eq monadicDiv.value)
      assert(monadicDiv.value.outerHTML == "
      
       <span> <b>prepended</b><b>original text 1</b> </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>{child.bind}</span><span>{child.bind}</span>
        parent.watch()
      }
    22. ,
    23. Seq in DOM

      import org.scalajs.dom.document
      @html def myUl = {
        {Seq(
       - data1,
       - data2)}
      }
      val div = document.createElement("div")
      html.render(div, myUl)
      div.firstChild.childNodes.length should be(2)
    24. ,
    25. XHTML comments

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

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

      import org.scalajs.dom.document
      @html def entity =
      
      my text &lt; &gt; &copy; &lambda;
      val div = document.createElement("div")
      html.render(div, entity)
      assert(div.innerHTML == """
      
       © λ my-class">my text < > © λ""")
    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>""")

Value Members

  1. object html

Ungrouped