summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Haoyi <haoyi@dropbox.com>2014-11-12 22:22:16 -0800
committerLi Haoyi <haoyi@dropbox.com>2014-11-12 22:22:16 -0800
commit7f33cb682200a501e0a48ab2fbad688317d80754 (patch)
treed968c1bc9c2308b3d1e449164acf620087b8d4a3
parent278f7809f2442227f77491f1da4437fb6e6e4095 (diff)
downloadhands-on-scala-js-7f33cb682200a501e0a48ab2fbad688317d80754.tar.gz
hands-on-scala-js-7f33cb682200a501e0a48ab2fbad688317d80754.tar.bz2
hands-on-scala-js-7f33cb682200a501e0a48ab2fbad688317d80754.zip
Commit before trying out scala-js-react
-rwxr-xr-xbook/src/main/resources/css/side-menu.css26
-rw-r--r--examples/demos/Controller.scala110
-rw-r--r--examples/demos/build.sbt6
3 files changed, 108 insertions, 34 deletions
diff --git a/book/src/main/resources/css/side-menu.css b/book/src/main/resources/css/side-menu.css
index 8bded91..8a9e25e 100755
--- a/book/src/main/resources/css/side-menu.css
+++ b/book/src/main/resources/css/side-menu.css
@@ -25,13 +25,21 @@ Add transition to containers so they can push in and out.
*/
#layout,
#menu,
-.menu-link {
+.menu-link,{
-webkit-transition: all 0.2s ease-out;
-moz-transition: all 0.2s ease-out;
-ms-transition: all 0.2s ease-out;
-o-transition: all 0.2s ease-out;
transition: all 0.2s ease-out;
}
+.hide,
+.menu-item-list > li{
+ -webkit-transition: height 0.2s ease-out;
+ -moz-transition: height 0.2s ease-out;
+ -ms-transition: height 0.2s ease-out;
+ -o-transition: height 0.2s ease-out;
+ transition: height 0.2s ease-out;
+}
/*
This is the parent `<div>` that contains the menu and the content area.
@@ -302,11 +310,19 @@ code{
.header-link{
opacity: 0.05;
}
-.hide{
- display: none;
+.menu-item-list > li {
+ height: 43px;
+}
+.menu-item-list > li.hide{
+ height: 0px;
+ overflow: hidden;
+}
+#menu .menu-item-list > li.pure-menu-selected > a{
+ border-left: 2px solid white;
+}
+#menu .menu-item-list > li.lined > a{
+ border-left: 2px solid white;
}
-
-
/*Workaround for bug in highlight.js IDEA theme*/
.hljs-tag, .hljs-symbol{
background: none;
diff --git a/examples/demos/Controller.scala b/examples/demos/Controller.scala
index 81bcdb4..0936776 100644
--- a/examples/demos/Controller.scala
+++ b/examples/demos/Controller.scala
@@ -6,7 +6,16 @@ import org.scalajs.dom.extensions._
import scala.collection.mutable
import scalatags.JsDom.all._
-case class Tree[T](name: T, children: Seq[Tree[T]])
+object Renderer{
+ import japgolly.scalajs.react._ // React
+ import vdom.ReactVDom._ // Scalatags → React virtual DOM
+ import vdom.ReactVDom.all._ // Scalatags html & css (div, h1, textarea, etc.)
+
+ val Menu = ReactComponentB[Int]("Menu").render{ p =>
+
+ }.build
+}
+case class Tree[T](name: T, children: Vector[Tree[T]])
@JSExport
object Controller{
@@ -14,7 +23,6 @@ object Controller{
name.replace(" ", "")
}
def addClass(el: dom.HTMLElement, cls: String) = {
- println("Adding Class " + cls)
removeClass(el, cls)
el.className = el.className + " " + cls
}
@@ -47,10 +55,10 @@ object Controller{
val frag =
li(
+ paddingLeft := s"${depth * 15}px",
a(
current.name,
href:="#"+munge(current.name),
- paddingLeft := s"${depth * 15}px",
cls:=myCls
)
).render
@@ -90,7 +98,7 @@ object Controller{
menuItems.map(munge)
.map(dom.document.getElementById)
.map(offset(_, main))
- .toArray
+ .toVector
}
scrollSpy(main, headers, contentList, contentTree)
@@ -108,14 +116,11 @@ object Controller{
* noticeable jerky
*/
def scrollSpy(main: dom.HTMLElement,
- headers: Seq[Double],
- contentList: Seq[dom.HTMLElement],
+ headers: Vector[Double],
+ contentList: Vector[dom.HTMLElement],
contentTree: Tree[dom.HTMLElement]) = {
- def isElementInViewport(el: dom.HTMLElement) = {
- val rect = el.getBoundingClientRect()
- rect.top >= 0 && rect.bottom <= dom.innerHeight
- }
+
var scrolling = false
var lastIndex = -1
@@ -128,25 +133,10 @@ object Controller{
index += 1
if (headers(index) > threshold) index *= -1
}
- index = -index - 1
- if (index != lastIndex){
- if (!isElementInViewport(contentList(index))) {
- contentList(index).scrollIntoView(lastIndex > index)
- }
- def rec(curr: Tree[dom.HTMLElement]): Boolean = {
- if (curr.children.map(rec).contains(true) ||
- curr.name == contentList(index)){
- addClass(curr.name, "pure-menu-selected")
- curr.children.map(_.name).foreach(removeClass(_, "hide"))
- true
- }else{
- removeClass(curr.name, "pure-menu-selected")
- addClass(curr.name, "hide")
- false
- }
- }
- rec(contentTree)
+ index = -index
+ if (index != lastIndex){
+ updateSideBar(lastIndex, index, contentList, contentTree)
lastIndex = index
}
}
@@ -158,4 +148,68 @@ object Controller{
}
}
}
+ def isElementInViewport(el: dom.HTMLElement) = {
+ val rect = el.getBoundingClientRect()
+ rect.top >= 0 && rect.bottom <= dom.innerHeight
+ }
+ val lastShown = new js.Array[dom.HTMLElement](0)
+ val lastLined = new js.Array[dom.HTMLElement](0)
+ def updateSideBar(lastIndex: Int,
+ index: Int,
+ contentList: Vector[dom.HTMLElement],
+ contentTree: Tree[dom.HTMLElement]) = {
+
+ println(s"MOVING $lastIndex -> $index")
+ if (!isElementInViewport(contentList(index))) {
+ contentList(index).scrollIntoView(lastIndex > index)
+ }
+ val shown = new js.Array[dom.HTMLElement](0)
+ val lined = new js.Array[dom.HTMLElement](0)
+ /**
+ * Makes two passes over the children list; once to determine if
+ * the current element is a parent of the current header, and another
+ * to mark all the children of the current element with the correct
+ * CSS classes.
+ */
+ def rec(curr: Tree[dom.HTMLElement]): Boolean = {
+
+ var found = false
+ var i = 0
+ var j = 0
+ while (j < curr.children.length){
+ val x = curr.children(j)
+ j+= 1
+ val f = rec(x)
+ found |= f
+ if (!found) i += 1
+ }
+
+ if (found || curr.name == contentList(index)){
+ var j = 0
+ while (j < curr.children.length){
+ val x = curr.children(j)
+ if (found && i > 0){
+ lined.push(x.name)
+ i -= 1
+ }
+
+ j+= 1
+ shown.push(x.name)
+ }
+ lined.push(curr.name)
+ true
+ }else false
+
+ }
+ rec(contentTree)
+ for(el <- contentList){
+ if (shown.indexOf(el) != -1) removeClass(el, "hide")
+ else addClass(el, "hide")
+
+ if (lined.indexOf(el) == -1) removeClass(el, "lined")
+ else addClass(el, "lined")
+ }
+ if (lastIndex != -1) removeClass(contentList(lastIndex), "pure-menu-selected")
+ addClass(contentList(index), "pure-menu-selected")
+ }
}
diff --git a/examples/demos/build.sbt b/examples/demos/build.sbt
index 5374c30..9be4d4d 100644
--- a/examples/demos/build.sbt
+++ b/examples/demos/build.sbt
@@ -1,3 +1,5 @@
+import scala.scalajs.sbtplugin.ScalaJSPlugin.ScalaJSKeys.jsDependencies
+
scalaJSSettings
name := "Example"
@@ -6,7 +8,9 @@ version := "0.1-SNAPSHOT"
scalaVersion := "2.11.4"
-libraryDependencies += "com.scalarx" %%% "scalarx" % "0.2.6"
+libraryDependencies += "com.github.japgolly.scalajs-react" %%% "core" % "0.5.1"
+
+jsDependencies += "org.webjars" % "react" % "0.11.1" / "react-with-addons.js" commonJSName "React"
libraryDependencies += "com.lihaoyi" %%% "upickle" % "0.2.5"