Skip to content

Commit ed624fe

Browse files
authored
Merge pull request #110 from glmars/glmars-custom-tag
Special syntax to disable tag name checking
2 parents 0c8a7da + bf30d21 commit ed624fe

File tree

2 files changed

+46
-15
lines changed

2 files changed

+46
-15
lines changed

dom/src/main/scala/com/thoughtworks/binding/dom.scala

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ package com.thoughtworks.binding
2727
import Binding.{BindingSeq, Constants, MultiMountPoint, SingletonBindingSeq}
2828
import dom.Runtime.NodeSeqMountPoint
2929
import com.thoughtworks.Extractor._
30-
import com.thoughtworks.binding.XmlExtractor.{PrefixedName, UnprefixedName}
30+
import com.thoughtworks.binding.XmlExtractor.{PrefixedName, QName, UnprefixedName}
3131
import com.thoughtworks.sde.core.Preprocessor
3232
import macrocompat.bundle
3333
import org.scalajs.dom.raw._
@@ -39,6 +39,8 @@ import scala.language.experimental.macros
3939
import scalatags.JsDom
4040
import scalatags.jsdom
4141
import org.scalajs.dom.document
42+
import scalatags.JsDom.TypedTag
43+
import scalatags.generic.Namespace
4244

4345
import scala.collection.immutable.Queue
4446
import scala.reflect.NameTransformer
@@ -140,7 +142,21 @@ object dom {
140142

141143
}
142144

143-
object TagsAndTags2 extends JsDom.Cap with jsdom.Tags with jsdom.Tags2
145+
object TagsAndTags2 extends JsDom.Cap with jsdom.Tags with jsdom.Tags2 {
146+
147+
import scala.language.dynamics
148+
149+
final class DynamicDataTag private[TagsAndTags2] ()
150+
extends TypedTag[HTMLElement]("data", Nil, false, Namespace.htmlNamespaceConfig)
151+
with Dynamic {
152+
final def selectDynamic(tagName: String): ConcreteHtmlTag[Element] = {
153+
TagsAndTags2.tag(tagName)
154+
}
155+
}
156+
157+
override lazy val data = new DynamicDataTag()
158+
159+
}
144160

145161
@inline
146162
def domBindingSeq(bindingSeq: BindingSeq[Node]) = bindingSeq
@@ -308,7 +324,7 @@ object dom {
308324
private def transformedWithValDefs: PartialFunction[Tree, (Queue[ValDef], Tree)] = {
309325
case tree @ NodeBuffer(children) =>
310326
nodeSeq(children)
311-
case tree @ Elem(UnprefixedName(label), attributes, _, children) =>
327+
case tree @ Elem(tag, attributes, _, children) =>
312328
val idOption = findTextAttribute("local-id", attributes).orElse(findTextAttribute("id", attributes))
313329
val elementName = idOption match {
314330
case None => TermName(c.freshName("element"))
@@ -323,16 +339,7 @@ object dom {
323339
}
324340
}
325341
} yield {
326-
val attributeAccess = key match {
327-
case UnprefixedName(localPart) =>
328-
val keyName = TermName(NameTransformer.encode(localPart))
329-
q"""$elementName.$keyName"""
330-
case PrefixedName(prefix, localPart) =>
331-
localPart.split(':').foldLeft(q"""$elementName.${TermName(NameTransformer.encode(prefix))}""") {
332-
(prefixExpr, propertyName) =>
333-
q"""$prefixExpr.${TermName(NameTransformer.encode(propertyName))}"""
334-
}
335-
}
342+
val attributeAccess = propertyAccess(key, q"$elementName")
336343

337344
atPos(value.pos) {
338345
value match {
@@ -381,8 +388,10 @@ object dom {
381388
"""
382389
})
383390
}
384-
val elementDef =
385-
q"val $elementName = _root_.com.thoughtworks.binding.dom.Runtime.TagsAndTags2.${TermName(label)}.render"
391+
392+
val tagAccess = propertyAccess(tag, q"_root_.com.thoughtworks.binding.dom.Runtime.TagsAndTags2")
393+
394+
val elementDef = q"val $elementName = $tagAccess.render"
386395
idOption match {
387396
case None =>
388397
valDefs -> q"""
@@ -405,6 +414,18 @@ object dom {
405414
attributes.collectFirst { case (UnprefixedName(`unprefixedName`), Text(text)) => text }
406415
}
407416

417+
private def propertyAccess(xmlName: QName, objectAccess: RefTree): Select = {
418+
xmlName match {
419+
case UnprefixedName(localPart) =>
420+
q"$objectAccess.${TermName(NameTransformer.encode(localPart))}"
421+
case PrefixedName(prefix, localPart) =>
422+
localPart.split(':').foldLeft(q"$objectAccess.${TermName(NameTransformer.encode(prefix))}") {
423+
(prefixExpr, segmentName) =>
424+
q"$prefixExpr.${TermName(NameTransformer.encode(segmentName))}"
425+
}
426+
}
427+
}
428+
408429
private def transformed: PartialFunction[Tree, Tree] = {
409430
case Block(stats, expr) =>
410431
super.transform(Block(stats.flatMap {

dom/src/test/scala/com/thoughtworks/binding/domTest.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,5 +437,15 @@ final class domTest extends FreeSpec with Matchers {
437437
assert(div.value.className == "DIV-1")
438438
}
439439

440+
"CustomTag" in {
441+
@dom def tag = {
442+
<data:custom-tag local-id="customTag" id="custom" data:custom-key="value"><data id="123">{customTag.tagName}</data></data:custom-tag>
443+
}
444+
val div = document.createElement("div")
445+
dom.render(div, tag)
446+
447+
assert(div.outerHTML == """<div><custom-tag custom-key="value" id="custom"><data id="123">CUSTOM-TAG</data></custom-tag></div>""")
448+
}
449+
440450
}
441451

0 commit comments

Comments
 (0)