Skip to content

Commit

Permalink
- Remove LatestHTMLEvents
Browse files Browse the repository at this point in the history
- Port to Scala 3
- Add helps for UI Events
  • Loading branch information
Yang, Bo committed Jan 23, 2023
1 parent 604c43b commit 48fe015
Show file tree
Hide file tree
Showing 11 changed files with 199 additions and 103 deletions.
8 changes: 6 additions & 2 deletions .github/workflows/scala.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
name: Scala CI

on:
- push
- pull_request
push:
branches:
- main
pull_request:

jobs:
build:
Expand All @@ -21,6 +23,8 @@ jobs:
include:
- scala: 2.13.7
sbt-args: ''
- scala: 3.2.2
sbt-args: ''

steps:
- uses: actions/checkout@v2
Expand Down
3 changes: 3 additions & 0 deletions .scalafmt.conf
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
version = "3.7.0"
maxColumn = 120
align.inInterpolation = true
newlines.inInterpolation = "oneline"
runner.dialect = scala3
10 changes: 8 additions & 2 deletions LatestEvent/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,17 @@ enablePlugins(ScalaJSPlugin)

import Ordering.Implicits._

libraryDependencies += "org.scala-js" %%% "scalajs-dom" % "1.2.0"
libraryDependencies += {
if (VersionNumber(scalaJSVersion).numbers >= Seq(1L)) {
"org.scala-js" %%% "scalajs-dom" % "2.3.0"
} else {
"org.scala-js" %%% "scalajs-dom" % "1.2.0"
}
}

libraryDependencies += {
if (VersionNumber(scalaVersion.value).numbers >= Seq(2L, 13L)) {
"com.thoughtworks.binding" %%% "binding" % "12.1.0"
"com.thoughtworks.binding" %%% "binding" % "12.1.0+110-53fd3428"
} else {
"com.thoughtworks.binding" %%% "binding" % "11.9.0"
}
Expand Down
82 changes: 82 additions & 0 deletions LatestEvent/code-generator.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@

val generateUIEventDefinitions =
taskKey[File]("Generate UIEventDefinitions.scala file from UI Events (W3C Working Draft)")
generateUIEventDefinitions := {
import com.gargoylesoftware.htmlunit.WebClient
import com.gargoylesoftware.htmlunit.html.{HtmlPage, HtmlTable}
import org.portablescala.sbtplatformdeps.PlatformDepsPlugin
import org.portablescala.sbtplatformdeps.PlatformDepsPlugin.autoImport._

import scala.collection.JavaConverters._
import scala.meta._
val generatedAst = {
val webClient = new WebClient()
try {
webClient.getOptions.setJavaScriptEnabled(false)
webClient.getOptions.setCssEnabled(false)
val document = webClient.getPage[HtmlPage](
"https://www.w3.org/TR/uievents/"
)
try {

q"""
package com.thoughtworks.binding {
import ScalaJsDomMissingTypes._

private[binding] trait UIEventDefinitions {
import org.scalajs.dom._
import org.scalajs.dom.raw._
..${
(for {
eventDefinition <- document.querySelectorAll("table.event-definition").asScala.view
definitionRows = (for {
row <- eventDefinition.asInstanceOf[HtmlTable].getRows().asScala.view
} yield {
val Seq(th, td) = row.getCells().asScala
th.asNormalizedText() -> td
}).toMap
eventType = definitionRows("Type").asNormalizedText()
lastEventType = (for {
interfaceCode <- definitionRows("Interface")
.querySelectorAll("""code[class="idl"]""")
.asScala
text = interfaceCode.asNormalizedText()
if text.endsWith("Event")
} yield Type.Name(text)).last
targetName <- definitionRows("Trusted Targets")
.querySelectorAll("code")
.asScala
.map(_.asNormalizedText())
.distinct
if targetName.headOption.exists(_.isUpper)
} yield {
q"""
def ${Term.Name(eventType)}(
eventTarget: ${Type.Name(targetName)}
) =
new LatestEvent[$lastEventType](
eventTarget,
${Lit.String(eventType)}
)
"""
}).toList
}
}
}
"""
} finally {
document.cleanUp()
}
} finally {
webClient.close()
}
}
val file =
(Compile / scalaSource).value / "com" / "thoughtworks" / "binding" / "UIEventDefinitions.scala"
val fileContent = Seq(
"// Don't edit this file, because it is generated by `sbt generateUIEventDefinitions`",
generatedAst.syntax
)
IO.writeLines(file, fileContent)
file
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.thoughtworks.binding
import com.thoughtworks.binding.Binding.{ChangedEvent, ChangedListener}
import org.scalajs.dom._
import org.scalajs.dom.raw._

import scala.scalajs.js
Expand All @@ -18,7 +19,7 @@ class LatestEvent[E <: Event](eventTarget: EventTarget, eventType: String) exten
}
}

private val eventListener: js.Function1[E, _] = { upstreamEvent: E =>
private val eventListener: js.Function1[E, _] = { (upstreamEvent: E) =>
cache = Some(upstreamEvent)
val changedEvent = new ChangedEvent(this, cache)
for (listener <- publisher) {
Expand All @@ -36,7 +37,7 @@ class LatestEvent[E <: Event](eventTarget: EventTarget, eventType: String) exten
protected def value: Option[E] = cache
}

object LatestEvent {
object LatestEvent extends UIEventDefinitions {
def hashchange(eventTarget: EventTarget) = {
new LatestEvent[Event](eventTarget, "hashchange")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.thoughtworks.binding

import org.scalajs.dom._
import org.scalajs.dom.raw._

private[binding] object ScalaJsDomMissingTypes {
type InputEvent <: UIEvent
type MutationEvent <: Event
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Don't edit this file, because it is generated by `sbt generateUIEventDefinitions`
package com.thoughtworks.binding
import ScalaJsDomMissingTypes._
private[binding] trait UIEventDefinitions {
import org.scalajs.dom._
import org.scalajs.dom.raw._
def load(eventTarget: Window) = new LatestEvent[Event](eventTarget, "load")
def load(eventTarget: Document) = new LatestEvent[Event](eventTarget, "load")
def load(eventTarget: Element) = new LatestEvent[Event](eventTarget, "load")
def unload(eventTarget: Window) = new LatestEvent[Event](eventTarget, "unload")
def unload(eventTarget: Document) = new LatestEvent[Event](eventTarget, "unload")
def unload(eventTarget: Element) = new LatestEvent[Event](eventTarget, "unload")
def abort(eventTarget: Window) = new LatestEvent[Event](eventTarget, "abort")
def abort(eventTarget: Element) = new LatestEvent[Event](eventTarget, "abort")
def error(eventTarget: Window) = new LatestEvent[Event](eventTarget, "error")
def error(eventTarget: Element) = new LatestEvent[Event](eventTarget, "error")
def select(eventTarget: Element) = new LatestEvent[Event](eventTarget, "select")
def blur(eventTarget: Window) = new LatestEvent[FocusEvent](eventTarget, "blur")
def blur(eventTarget: Element) = new LatestEvent[FocusEvent](eventTarget, "blur")
def focus(eventTarget: Window) = new LatestEvent[FocusEvent](eventTarget, "focus")
def focus(eventTarget: Element) = new LatestEvent[FocusEvent](eventTarget, "focus")
def focusin(eventTarget: Window) = new LatestEvent[FocusEvent](eventTarget, "focusin")
def focusin(eventTarget: Element) = new LatestEvent[FocusEvent](eventTarget, "focusin")
def focusout(eventTarget: Window) = new LatestEvent[FocusEvent](eventTarget, "focusout")
def focusout(eventTarget: Element) = new LatestEvent[FocusEvent](eventTarget, "focusout")
def auxclick(eventTarget: Element) = new LatestEvent[PointerEvent](eventTarget, "auxclick")
def click(eventTarget: Element) = new LatestEvent[PointerEvent](eventTarget, "click")
def contextmenu(eventTarget: Element) = new LatestEvent[PointerEvent](eventTarget, "contextmenu")
def dblclick(eventTarget: Element) = new LatestEvent[MouseEvent](eventTarget, "dblclick")
def mousedown(eventTarget: Element) = new LatestEvent[MouseEvent](eventTarget, "mousedown")
def mouseenter(eventTarget: Element) = new LatestEvent[MouseEvent](eventTarget, "mouseenter")
def mouseleave(eventTarget: Element) = new LatestEvent[MouseEvent](eventTarget, "mouseleave")
def mousemove(eventTarget: Element) = new LatestEvent[MouseEvent](eventTarget, "mousemove")
def mouseout(eventTarget: Element) = new LatestEvent[MouseEvent](eventTarget, "mouseout")
def mouseover(eventTarget: Element) = new LatestEvent[MouseEvent](eventTarget, "mouseover")
def mouseup(eventTarget: Element) = new LatestEvent[MouseEvent](eventTarget, "mouseup")
def wheel(eventTarget: Element) = new LatestEvent[WheelEvent](eventTarget, "wheel")
def beforeinput(eventTarget: Element) = new LatestEvent[InputEvent](eventTarget, "beforeinput")
def beforeinput(eventTarget: HTMLInputElement) = new LatestEvent[InputEvent](eventTarget, "beforeinput")
def input(eventTarget: Element) = new LatestEvent[InputEvent](eventTarget, "input")
def input(eventTarget: HTMLInputElement) = new LatestEvent[InputEvent](eventTarget, "input")
def keydown(eventTarget: Element) = new LatestEvent[KeyboardEvent](eventTarget, "keydown")
def keyup(eventTarget: Element) = new LatestEvent[KeyboardEvent](eventTarget, "keyup")
def compositionstart(eventTarget: Element) = new LatestEvent[CompositionEvent](eventTarget, "compositionstart")
def compositionupdate(eventTarget: Element) = new LatestEvent[CompositionEvent](eventTarget, "compositionupdate")
def compositionend(eventTarget: Element) = new LatestEvent[CompositionEvent](eventTarget, "compositionend")
def DOMActivate(eventTarget: Element) = new LatestEvent[UIEvent](eventTarget, "DOMActivate")
def DOMFocusIn(eventTarget: Window) = new LatestEvent[FocusEvent](eventTarget, "DOMFocusIn")
def DOMFocusIn(eventTarget: Element) = new LatestEvent[FocusEvent](eventTarget, "DOMFocusIn")
def DOMFocusOut(eventTarget: Window) = new LatestEvent[FocusEvent](eventTarget, "DOMFocusOut")
def DOMFocusOut(eventTarget: Element) = new LatestEvent[FocusEvent](eventTarget, "DOMFocusOut")
def keypress(eventTarget: Element) = new LatestEvent[KeyboardEvent](eventTarget, "keypress")
def DOMAttrModified(eventTarget: Element) = new LatestEvent[MutationEvent](eventTarget, "DOMAttrModified")
def DOMCharacterDataModified(eventTarget: Text) = new LatestEvent[MutationEvent](eventTarget, "DOMCharacterDataModified")
def DOMCharacterDataModified(eventTarget: Comment) = new LatestEvent[MutationEvent](eventTarget, "DOMCharacterDataModified")
def DOMCharacterDataModified(eventTarget: ProcessingInstruction) = new LatestEvent[MutationEvent](eventTarget, "DOMCharacterDataModified")
def DOMNodeInserted(eventTarget: Element) = new LatestEvent[MutationEvent](eventTarget, "DOMNodeInserted")
def DOMNodeInserted(eventTarget: Attr) = new LatestEvent[MutationEvent](eventTarget, "DOMNodeInserted")
def DOMNodeInserted(eventTarget: Text) = new LatestEvent[MutationEvent](eventTarget, "DOMNodeInserted")
def DOMNodeInserted(eventTarget: Comment) = new LatestEvent[MutationEvent](eventTarget, "DOMNodeInserted")
def DOMNodeInserted(eventTarget: DocumentType) = new LatestEvent[MutationEvent](eventTarget, "DOMNodeInserted")
def DOMNodeInserted(eventTarget: ProcessingInstruction) = new LatestEvent[MutationEvent](eventTarget, "DOMNodeInserted")
def DOMNodeInsertedIntoDocument(eventTarget: Element) = new LatestEvent[MutationEvent](eventTarget, "DOMNodeInsertedIntoDocument")
def DOMNodeInsertedIntoDocument(eventTarget: Attr) = new LatestEvent[MutationEvent](eventTarget, "DOMNodeInsertedIntoDocument")
def DOMNodeInsertedIntoDocument(eventTarget: Text) = new LatestEvent[MutationEvent](eventTarget, "DOMNodeInsertedIntoDocument")
def DOMNodeInsertedIntoDocument(eventTarget: Comment) = new LatestEvent[MutationEvent](eventTarget, "DOMNodeInsertedIntoDocument")
def DOMNodeInsertedIntoDocument(eventTarget: DocumentType) = new LatestEvent[MutationEvent](eventTarget, "DOMNodeInsertedIntoDocument")
def DOMNodeInsertedIntoDocument(eventTarget: ProcessingInstruction) = new LatestEvent[MutationEvent](eventTarget, "DOMNodeInsertedIntoDocument")
def DOMNodeRemoved(eventTarget: Element) = new LatestEvent[MutationEvent](eventTarget, "DOMNodeRemoved")
def DOMNodeRemoved(eventTarget: Attr) = new LatestEvent[MutationEvent](eventTarget, "DOMNodeRemoved")
def DOMNodeRemoved(eventTarget: Text) = new LatestEvent[MutationEvent](eventTarget, "DOMNodeRemoved")
def DOMNodeRemoved(eventTarget: Comment) = new LatestEvent[MutationEvent](eventTarget, "DOMNodeRemoved")
def DOMNodeRemoved(eventTarget: DocumentType) = new LatestEvent[MutationEvent](eventTarget, "DOMNodeRemoved")
def DOMNodeRemoved(eventTarget: ProcessingInstruction) = new LatestEvent[MutationEvent](eventTarget, "DOMNodeRemoved")
def DOMNodeRemovedFromDocument(eventTarget: Element) = new LatestEvent[MutationEvent](eventTarget, "DOMNodeRemovedFromDocument")
def DOMNodeRemovedFromDocument(eventTarget: Attr) = new LatestEvent[MutationEvent](eventTarget, "DOMNodeRemovedFromDocument")
def DOMNodeRemovedFromDocument(eventTarget: Text) = new LatestEvent[MutationEvent](eventTarget, "DOMNodeRemovedFromDocument")
def DOMNodeRemovedFromDocument(eventTarget: Comment) = new LatestEvent[MutationEvent](eventTarget, "DOMNodeRemovedFromDocument")
def DOMNodeRemovedFromDocument(eventTarget: DocumentType) = new LatestEvent[MutationEvent](eventTarget, "DOMNodeRemovedFromDocument")
def DOMNodeRemovedFromDocument(eventTarget: ProcessingInstruction) = new LatestEvent[MutationEvent](eventTarget, "DOMNodeRemovedFromDocument")
def DOMSubtreeModified(eventTarget: Window) = new LatestEvent[MutationEvent](eventTarget, "DOMSubtreeModified")
def DOMSubtreeModified(eventTarget: Document) = new LatestEvent[MutationEvent](eventTarget, "DOMSubtreeModified")
def DOMSubtreeModified(eventTarget: DocumentFragment) = new LatestEvent[MutationEvent](eventTarget, "DOMSubtreeModified")
def DOMSubtreeModified(eventTarget: Element) = new LatestEvent[MutationEvent](eventTarget, "DOMSubtreeModified")
def DOMSubtreeModified(eventTarget: Attr) = new LatestEvent[MutationEvent](eventTarget, "DOMSubtreeModified")
}
35 changes: 0 additions & 35 deletions LatestHTMLEvents/build.sbt

This file was deleted.

This file was deleted.

2 changes: 0 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ ThisBuild / evictionErrorLevel := Level.Info

lazy val LatestEvent = project

lazy val LatestHTMLEvents = project.dependsOn(LatestEvent)

publish / skip := true

enablePlugins(ScalaUnidocPlugin)
2 changes: 2 additions & 0 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@ addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.12.0")
addSbtPlugin("com.thoughtworks.sbt-scala-js-map" % "sbt-scala-js-map" % "4.1.1")

addSbtPlugin("ch.epfl.scala" % "sbt-scalajs-bundler" % "0.21.1")

libraryDependencies += "net.sourceforge.htmlunit" % "htmlunit" % "2.70.0"

0 comments on commit 48fe015

Please sign in to comment.