summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Haoyi <haoyi@dropbox.com>2014-11-14 14:28:51 -0800
committerLi Haoyi <haoyi@dropbox.com>2014-11-14 14:28:51 -0800
commitc7a6380fdf37010d43d62a7db0a882d7ccc68d96 (patch)
tree912bd744b3a37855a62667d8de6dc03140a6b3ce
parent64f9b0b4625298d1b78d1991636c2d32fe1f422f (diff)
downloadhands-on-scala-js-c7a6380fdf37010d43d62a7db0a882d7ccc68d96.tar.gz
hands-on-scala-js-c7a6380fdf37010d43d62a7db0a882d7ccc68d96.tar.bz2
hands-on-scala-js-c7a6380fdf37010d43d62a7db0a882d7ccc68d96.zip
WIP after getting rid of react.js, still doesn't work
-rwxr-xr-xbook/src/main/resources/css/side-menu.css19
-rw-r--r--book/src/main/scala/book/Book.scala2
-rw-r--r--build.sbt4
-rw-r--r--examples/demos/Controller.scala144
4 files changed, 72 insertions, 97 deletions
diff --git a/book/src/main/resources/css/side-menu.css b/book/src/main/resources/css/side-menu.css
index e5d014c..c9babca 100755
--- a/book/src/main/resources/css/side-menu.css
+++ b/book/src/main/resources/css/side-menu.css
@@ -310,19 +310,26 @@ code{
.header-link{
opacity: 0.05;
}
-.menu-item-list > li {
- height: 43px;
-}
-.menu-item-list > li.hide{
+.menu-item-list li.hide > ul{
height: 0px;
overflow: hidden;
+ opacity: 0;
}
-#menu .menu-item-list > li.pure-menu-selected > a{
+
+#menu .menu-item-list li.selected > a{
border-left: 2px solid white;
}
-#menu .menu-item-list > li.lined > a{
+#menu .menu-item-list li.lined > a{
border-left: 2px solid white;
}
+
+.pure-menu li > ul{
+ position:relative;
+ visibility:visible;
+ left: 0px;
+ top: 0px;
+}
+
/*Workaround for bug in highlight.js IDEA theme*/
.hljs-tag, .hljs-symbol{
background: none;
diff --git a/book/src/main/scala/book/Book.scala b/book/src/main/scala/book/Book.scala
index 857bf37..cd10205 100644
--- a/book/src/main/scala/book/Book.scala
+++ b/book/src/main/scala/book/Book.scala
@@ -26,7 +26,7 @@ object Book {
"META-INF/resources/webjars/font-awesome/4.2.0/fonts/fontawesome-webfont.woff",
"META-INF/resources/webjars/react/0.11.1/react.min.js",
"css/side-menu.css",
- "example-opt.js",
+ "example-fastopt.js",
"webpage/weather.js",
"favicon.svg",
"favicon.png"
diff --git a/build.sbt b/build.sbt
index 8bb2856..e0b9f22 100644
--- a/build.sbt
+++ b/build.sbt
@@ -44,8 +44,8 @@ lazy val book = Project(
"com.lihaoyi" %%% "upickle" % "0.2.5"
),
(resources in Compile) += {
- (fullOptJS in (demos, Compile)).value
- (artifactPath in (demos, Compile, fullOptJS)).value
+ (fastOptJS in (demos, Compile)).value
+ (artifactPath in (demos, Compile, fastOptJS)).value
},
(unmanagedResourceDirectories in Compile) ++=
(unmanagedResourceDirectories in (demos, Compile)).value,
diff --git a/examples/demos/Controller.scala b/examples/demos/Controller.scala
index 6e7df42..b9d8d56 100644
--- a/examples/demos/Controller.scala
+++ b/examples/demos/Controller.scala
@@ -4,12 +4,10 @@ import scala.scalajs.js.annotation.JSExport
import org.scalajs.dom
import org.scalajs.dom.extensions._
import scala.collection.mutable
-import japgolly.scalajs.react._ // React
-
-import vdom.ReactVDom.all._ // Scalatags html & css (div, h1, textarea, etc.)
-
+import scalatags.JsDom.all._
case class Tree[T](name: T, children: Vector[Tree[T]])
+
@JSExport
object Controller{
@@ -21,7 +19,10 @@ object Controller{
el.className = el.className + " " + cls
}
def removeClass(el: dom.HTMLElement, cls: String) = {
- el.className = el.className.split(' ').filter(_ != cls).mkString(" ")
+ el.className = el.className.split(' ')
+ .iterator
+ .filter(_ != cls)
+ .mkString(" ")
}
def toggleClass(el: dom.HTMLElement, cls: String) = {
val frags = el.className.split(' ')
@@ -33,19 +34,25 @@ object Controller{
val structure = upickle.readJs[Tree[String]](upickle.json.readJs(data))
var i = 0
- def recurse(t: Tree[String], depth: Int): Tree[(Tag, Int)] = {
+ def recurse(t: Tree[String], depth: Int): Tree[(dom.HTMLElement, Int)] = {
val curr =
- li(paddingLeft := s"${depth * 15}px")(
+ li(paddingLeft := "15px")(
a(
t.name,
- href:=munge("#"+t.name),
+ href:="#"+munge(t.name),
cls:="menu-item"
)
)
val originalI = i
i += 1
val children = t.children.map(recurse(_, depth + 1))
- Tree(curr -> originalI, children)
+ Tree(
+ (
+ curr(ul(children.map(_.name._1))).render,
+ originalI
+ ),
+ children
+ )
}
val Seq(main, menu, layout, menuLink) = Seq(
@@ -55,12 +62,12 @@ object Controller{
val snippets = dom.document.getElementsByClassName("highlight-me")
snippets.foreach(js.Dynamic.global.hljs.highlightBlock(_))
-
+ def offset(el: dom.HTMLElement, parent: dom.HTMLElement): Double = {
+ if (el == parent) 0
+ else el.offsetTop + offset(el.offsetParent.asInstanceOf[dom.HTMLElement], parent)
+ }
val headers = {
- def offset(el: dom.HTMLElement, parent: dom.HTMLElement): Double = {
- if (el == parent) 0
- else el.offsetTop + offset(el.offsetParent.asInstanceOf[dom.HTMLElement], parent)
- }
+
val menuItems = {
def rec(current: Tree[String]): Seq[String] = {
current.name +: current.children.flatMap(rec)
@@ -73,10 +80,17 @@ object Controller{
.toVector
}
+ val domTrees = recurse(structure, 0).children
- val menuBar = React.renderComponent(
- Menu(recurse(structure, 0)),
- menu
+ menu.appendChild(
+ div(cls:="pure-menu pure-menu-open")(
+ a(cls:="pure-menu-heading", href:="#")(
+ "Contents"
+ ),
+ ul(cls:="menu-item-list")(
+ domTrees.map(_.name._1)
+ )
+ ).render
)
menuLink.onclick = (e: dom.MouseEvent) => {
toggleClass(layout, "active")
@@ -84,28 +98,35 @@ object Controller{
toggleClass(menuLink, "active")
}
- var x = -1
- def start() =
- x = dom.setTimeout(() => {
- x = -1
- val threshold = main.scrollTop + main.clientHeight
+ var scrolling = false
- var index = 0
- while(index < headers.length && index >= 0){
- index += 1
- if (headers(index) > threshold) index *= -1
- }
- index = -index
- menuBar.setState(index)
+ def start() ={
+ scrolling = false
+ val threshold = main.scrollTop + main.clientHeight
+ println("")
+ def walkTree(tree: Tree[(dom.HTMLElement, Int)]): Unit = {
+ val Tree((menuItem, index), children) = tree
+ val before = headers(index) < threshold
- }, 100)
+ val next = children.lastOption
+ .fold(index)(_.name._2)
- main.onscroll = (e: dom.UIEvent) => {
- if (x != -1){
- dom.clearTimeout(x)
- s
+ val win = before && headers.lift(next + 1).getOrElse(999999.0) > threshold
+
+ if (win){
+ removeClass(menuItem, "hide")
+ addClass(menuItem, "selected")
+ tree.children.foreach(walkTree)
+ }else{
+ addClass(menuItem, "hide")
+ removeClass(menuItem, "selected")
+ }
}
- start()
+ domTrees.map(walkTree)
+ }
+ main.onscroll = (e: dom.UIEvent) => if (!scrolling){
+ scrolling = true
+ dom.requestAnimationFrame((d: Double) => start())
}
}
def isElementInViewport(el: dom.HTMLElement) = {
@@ -114,57 +135,4 @@ object Controller{
}
-
- val Menu = ReactComponentB[Tree[(Tag, Int)]]("Menu")
- .getInitialState(_ => 0)
- .render{ (structure, _, index) =>
-
- val contentList = {
- var i = 0
- val winArray = new js.Array[Boolean](0)
- def rec1(current: Tree[(Tag, Int)]): Unit = {
- val initialI = i
- i += 1
- current.children.foreach(rec1)
- winArray(current.name._2) = i >= index && initialI < index
- }
-
- val output = new js.Array[Tag](0)
- def rec(current: Tree[(Tag, Int)],
- classes: String): Unit = {
-
-
- val winIndex = current.children.indexWhere { x =>
- winArray(x.name._2)
- }
- val (before, after) = current.children.splitAt(winIndex)
-
- val (tag, currIndex) = current.name
-
- val win = winArray(currIndex)
-
- val frag = tag(
- cls:=classes + (if (win) " pure-menu-selected" else "")
- )
-
- output.push(frag)
-
- before.foreach(rec(_, "lined"))
- after.foreach(rec(_, if (!win) "hide" else ""))
- }
- rec1(structure)
- rec(structure, "")
- output
- }
-
- val frag = div(cls:="pure-menu pure-menu-open")(
- a(cls:="pure-menu-heading", href:="#")(
- "Contents"
- ),
- ul(cls:="menu-item-list")(
- contentList.drop(1):_*
- )
- )
- frag
- }.build
} \ No newline at end of file