Skip to content

Commit

Permalink
link handler back to listening document click events
Browse files Browse the repository at this point in the history
  • Loading branch information
yurique committed Jan 2, 2021
1 parent b766b2b commit dcf003e
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 45 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

### 0.11.5

Fixing `LinkHandler`.

### 0.11.4

* New: LinkHandler
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Built on top of:
`frontroute` is available for [Scala.js](http://www.scala-js.org/) v1.3.1+ (published for Scala 2.12 and 2.13).

```scala
libraryDependencies += "io.frontroute" %%% "frontroute" % "0.11.4"
libraryDependencies += "io.frontroute" %%% "frontroute" % "0.11.5"
```

```scala
Expand Down
59 changes: 16 additions & 43 deletions src/main/scala/io/frontroute/LinkHandler.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package io.frontroute

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

import scala.scalajs.js
Expand All @@ -15,67 +14,41 @@ object LinkHandler {
var routeTo: js.UndefOr[js.Function1[String, Unit]] = js.native
}

private val clickListener: js.Function1[Event, Boolean] = event => {
findParent("a", event.currentTarget.asInstanceOf[Node]).fold(true) { element =>
val anchor = element.asInstanceOf[HTMLAnchorElement]
private val clickListener: js.Function1[Event, Unit] = event => {
findParent("A", event.target.asInstanceOf[dom.Node]).foreach { aParent =>
val anchor = aParent.asInstanceOf[HTMLAnchorElement]
val rel = anchor.rel
if (js.isUndefined(rel) || rel == null || rel == "") {
event.preventDefault()
BrowserNavigation.pushState(url = anchor.href)
false
} else {
rel match {
case "external" =>
event.preventDefault()
dom.window.open(anchor.href)
false
case _ =>
true
}
} else if (rel == "external") {
event.preventDefault()
dom.window.open(anchor.href)
}
}
}

private val observer = new MutationObserver((records, _) => {
records.foreach { record =>
record.addedNodes.foreach { node =>
node.addEventListener("click", clickListener)
}
record.removedNodes.foreach { node =>
node.removeEventListener("click", clickListener)
}
}
})

def uninstall(): Unit = {
observer.disconnect()
WindowWithRouteTo.routeTo = js.undefined
}

private val routeTo: js.Function1[String, Unit] = (path: String) => BrowserNavigation.pushState(null, null, path)

def install(): Unit = {
WindowWithRouteTo.routeTo = routeTo
observer.observe(dom.document, js.Dynamic.literal(childList = true).asInstanceOf[MutationObserverInit])
dom.document.querySelectorAll("a").foreach(_.addEventListener("click", clickListener))
dom.document.addEventListener("click", clickListener)
}

def uninstall(): Unit = {
WindowWithRouteTo.routeTo = js.undefined
dom.document.removeEventListener("click", clickListener)
}

@scala.annotation.tailrec
private def findParent(tagName: String, element: Node): js.UndefOr[Node] = {
private def findParent(nodeName: String, element: Node): js.UndefOr[Node] = {
if (js.isUndefined(element) || element == null) {
js.undefined
} else {
val tagMatched =
element.nodeName
.asInstanceOf[js.UndefOr[String]]
.orElse(
element.asInstanceOf[Element].tagName.asInstanceOf[js.UndefOr[String]]
)
.map(_.toLowerCase())
.contains(tagName.toLowerCase())
if (tagMatched) {
if (element.nodeName == nodeName) {
element
} else {
findParent(tagName, element.parentNode)
findParent(nodeName, element.parentNode)
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion version.sbt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version in ThisBuild := "0.11.4"
version in ThisBuild := "0.11.5"

0 comments on commit dcf003e

Please sign in to comment.