summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Haoyi <haoyi@dropbox.com>2014-11-15 15:59:38 -0800
committerLi Haoyi <haoyi@dropbox.com>2014-11-15 15:59:38 -0800
commit70f9164e167398d75f99130a5325a3411215feb5 (patch)
tree544264debe08e4d1bb363935f86aa63889727084
parent50595f9e1b05d33f47e540c24e33e50bd1625315 (diff)
downloadhands-on-scala-js-70f9164e167398d75f99130a5325a3411215feb5.tar.gz
hands-on-scala-js-70f9164e167398d75f99130a5325a3411215feb5.tar.bz2
hands-on-scala-js-70f9164e167398d75f99130a5325a3411215feb5.zip
works
-rwxr-xr-xbook/src/main/resources/css/side-menu.css18
-rw-r--r--book/src/main/scala/book/Utils.scala36
-rw-r--r--examples/demos/src/main/scala/scrollmenu/Controller.scala49
-rw-r--r--examples/demos/src/main/scala/scrollmenu/ScrollMenu.scala74
-rw-r--r--scalatexApi/src/test/scala/torimatomeru/SyntaxTest.scala18
5 files changed, 110 insertions, 85 deletions
diff --git a/book/src/main/resources/css/side-menu.css b/book/src/main/resources/css/side-menu.css
index 00b351d..fbb2b26 100755
--- a/book/src/main/resources/css/side-menu.css
+++ b/book/src/main/resources/css/side-menu.css
@@ -32,13 +32,6 @@ Add transition to containers so they can push in and out.
-o-transition: all 0.2s ease-out;
transition: all 0.2s ease-out;
}
-.menu-item-list li > ul{
- -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;
-}
/*
This is the parent `<div>` that contains the menu and the content area.
@@ -319,14 +312,19 @@ code{
overflow: hidden;
}
-
#menu .menu-item-list li.selected > a{
border-left: 2px solid white;
}
-#menu .menu-item-list li.lined > a{
- border-left: 2px solid white;
+
+.menu-item-list li > a{
+ -webkit-transition: background-color 0.2s ease-out;
+ -moz-transition: background-color 0.2s ease-out;
+ -ms-transition: background-color 0.2s ease-out;
+ -o-transition: background-color 0.2s ease-out;
+ transition: background-color 0.2s ease-out;
}
+/*Override stuff from pure =/ it's not doing what I want*/
.pure-menu li > ul{
position:relative;
visibility:visible;
diff --git a/book/src/main/scala/book/Utils.scala b/book/src/main/scala/book/Utils.scala
index ad41d18..6770e31 100644
--- a/book/src/main/scala/book/Utils.scala
+++ b/book/src/main/scala/book/Utils.scala
@@ -83,27 +83,21 @@ object lnk{
a(name, href:=url)
}
object dom{
- class MdnThing(name: String = toString) extends Frag{
- def render = lnk.apply(name, "https://developer.mozilla.org/en-US/docs/Web/API/" + name).render
- def applyTo(t: Builder) = t.addChild(render)
- }
- class MdnEvent extends Frag {
- def render = lnk.apply(toString, "https://developer.mozilla.org/en-US/docs/Web/Events/" + toString).render
- def applyTo(t: Builder) = t.addChild(render)
- }
- object CanvasRenderingContext2D extends MdnThing()
- object HTMLCanvasElement extends MdnThing()
- object Element extends MdnThing()
- object HTMLElement extends MdnThing()
- object HTMLInputElement extends MdnThing()
- object HTMLSpanElement extends MdnThing()
- object XMLHttpRequest extends MdnThing()
- object getElementById extends MdnThing("document.getElementById")
- object setInterval extends MdnThing("WindowTimers.setInterval")
- object mousedown extends MdnThing
- object mouseup extends MdnThing
- object onclick extends MdnThing
- object onkeyup extends MdnThing
+ def mdnThing(name: String) = lnk(name, "https://developer.mozilla.org/en-US/docs/Web/API/" + name)
+ def mdnEvent(name: String) = lnk(name, "https://developer.mozilla.org/en-US/docs/Web/Events/" + name)
+ val CanvasRenderingContext2D = mdnThing("CanvasRenderingContext2D")
+ val HTMLCanvasElement = mdnThing("HTMLCanvasElement")
+ val Element = mdnThing("Element")
+ val HTMLElement = mdnThing("HTMLElement")
+ val HTMLInputElement = mdnThing("HTMLInputElement")
+ val HTMLSpanElement = mdnThing("HTMLSpanElement")
+ val XMLHttpRequest = mdnThing("XMLHttpRequest")
+ val getElementById = mdnThing("document.getElementById")
+ val setInterval = mdnThing("WindowTimers.setInterval")
+ val mousedown = mdnEvent("mousedown")
+ val mouseup = mdnEvent("mouseup")
+ val onclick = mdnEvent("onclick")
+ val onkeyup = mdnEvent("onkeyup")
val JSONparse = lnk("Json.parse", "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse")
}
object scala{
diff --git a/examples/demos/src/main/scala/scrollmenu/Controller.scala b/examples/demos/src/main/scala/scrollmenu/Controller.scala
index 1fcb68c..de120c6 100644
--- a/examples/demos/src/main/scala/scrollmenu/Controller.scala
+++ b/examples/demos/src/main/scala/scrollmenu/Controller.scala
@@ -20,28 +20,6 @@ object Controller{
def main(data: scala.scalajs.js.Any) = {
val structure = upickle.readJs[Tree[String]](upickle.json.readJs(data))
- var i = 0
- def recurse(t: Tree[String], depth: Int): Tree[MenuNode] = {
- val curr =
- li(
- a(
- t.value,
- href:="#"+munge(t.value),
- cls:="menu-item"
- )
- )
- val originalI = i
- i += 1
- val children = t.children.map(recurse(_, depth + 1))
- Tree(
- MenuNode(
- curr(ul(paddingLeft := "15px",children.map(_.value.frag))).render,
- originalI,
- if (children.length > 0) children.map(_.value.end).max else originalI + 1
- ),
- children
- )
- }
val Seq(main, menu, layout, menuLink) = Seq(
"main", "menu", "layout", "menuLink"
@@ -50,26 +28,8 @@ 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 = {
-
- val menuItems = {
- def rec(current: Tree[String]): Seq[String] = {
- current.value +: current.children.flatMap(rec)
- }
- rec(structure).tail
- }
- menuItems.map(munge)
- .map(dom.document.getElementById)
- .map(offset(_, main))
- .toVector
- }
- val domTrees = structure.children.map(recurse(_, 0))
- val scrollSpy = new ScrollSpy(headers, domTrees)
+ val scrollSpy = new ScrollSpy(structure, main)
menu.appendChild(
div(cls:="pure-menu pure-menu-open")(
@@ -77,7 +37,7 @@ object Controller{
"Contents"
),
ul(cls:="menu-item-list")(
- domTrees.map(_.value.frag)
+ scrollSpy.domTrees.map(_.value.frag)
)
).render
)
@@ -92,8 +52,5 @@ object Controller{
scrollSpy(main.scrollTop + main.clientHeight)
}
}
- def isElementInViewport(el: dom.HTMLElement) = {
- val rect = el.getBoundingClientRect()
- rect.top >= 0 && rect.bottom <= dom.innerHeight
- }
+
}
diff --git a/examples/demos/src/main/scala/scrollmenu/ScrollMenu.scala b/examples/demos/src/main/scala/scrollmenu/ScrollMenu.scala
index 9c0fbd2..7b238f4 100644
--- a/examples/demos/src/main/scala/scrollmenu/ScrollMenu.scala
+++ b/examples/demos/src/main/scala/scrollmenu/ScrollMenu.scala
@@ -2,6 +2,8 @@ package scrollmenu
import org.scalajs.dom
+import scalatags.JsDom.all._
+
case class Tree[T](value: T, children: Vector[Tree[T]])
case class MenuNode(frag: dom.HTMLElement, start: Int, end: Int)
@@ -10,18 +12,69 @@ case class MenuNode(frag: dom.HTMLElement, start: Int, end: Int)
* High performance scrollspy to work keep the left menu bar in sync.
* Lots of sketchy imperative code in order to maximize performance.
*/
-class ScrollSpy(headers: Vector[Double], domTrees: Seq[Tree[MenuNode]]){
- var scrolling = false
- def apply(threshold: Double) = if (!scrolling){
+class ScrollSpy(structure: Tree[String], main: dom.HTMLElement){
+ val (headers, domTrees) = {
+ var i = 0
+ def recurse(t: Tree[String], depth: Int): Tree[MenuNode] = {
+ val curr =
+ li(
+ a(
+ t.value,
+ href:="#"+Controller.munge(t.value),
+ cls:="menu-item"
+ )
+ )
+ val originalI = i
+ i += 1
+ val children = t.children.map(recurse(_, depth + 1))
+ Tree(
+ MenuNode(
+ curr(ul(paddingLeft := "15px",children.map(_.value.frag))).render,
+ originalI,
+ if (children.length > 0) children.map(_.value.end).max else originalI + 1
+ ),
+ children
+ )
+ }
+ 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 = {
+ val menuItems = {
+ def rec(current: Tree[String]): Seq[String] = {
+ current.value +: current.children.flatMap(rec)
+ }
+ rec(structure).tail
+ }
+ menuItems.map(Controller.munge)
+ .map(dom.document.getElementById)
+ .map(offset(_, main))
+ .toVector
+ }
+ val domTrees = structure.children.map(recurse(_, 0))
+ (headers, domTrees)
+ }
+
+
+ private[this] var scrolling = false
+ def apply(threshold: => Double) = if (!scrolling){
scrolling = true
- dom.requestAnimationFrame((d: Double) => start(threshold))
+ dom.setTimeout(() => start(threshold), 200)
}
- def start(threshold: Double) = {
+ private[this] def start(threshold: Double) = {
scrolling = false
+ def scroll(el: dom.HTMLElement) = {
+ val rect = el.getBoundingClientRect()
+ if (rect.top <= 0)
+ el.scrollIntoView(true)
+ else if (rect.bottom > dom.innerHeight)
+ el.scrollIntoView(false)
+ }
def walkTree(tree: Tree[MenuNode]): Boolean = {
- val Tree(MenuNode(menuItem, index, next), children) = tree
- val before = headers(index) < threshold
- val after = (next >= headers.length) || headers(next) > threshold
+ val Tree(MenuNode(menuItem, start, end), children) = tree
+ val before = headers(start) < threshold
+ val after = (end >= headers.length) || headers(end) > threshold
val win = before && after
if (win){
menuItem.classList.remove("hide")
@@ -34,7 +87,10 @@ class ScrollSpy(headers: Vector[Double], domTrees: Seq[Tree[MenuNode]]){
winFound = winFound | newWinFound
}
if (!winFound) {
+ // This means it's the leaf element, because it won but there
+ // aren't any children which won, so it must be the actual leaf
tree.children.foreach(_.value.frag.classList.remove("selected"))
+ scroll(menuItem)
}
menuItem.children(0).classList.add("pure-menu-selected")
}else{
@@ -46,4 +102,6 @@ class ScrollSpy(headers: Vector[Double], domTrees: Seq[Tree[MenuNode]]){
}
domTrees.map(walkTree)
}
+
+
} \ No newline at end of file
diff --git a/scalatexApi/src/test/scala/torimatomeru/SyntaxTest.scala b/scalatexApi/src/test/scala/torimatomeru/SyntaxTest.scala
new file mode 100644
index 0000000..8d5a0d8
--- /dev/null
+++ b/scalatexApi/src/test/scala/torimatomeru/SyntaxTest.scala
@@ -0,0 +1,18 @@
+package torimatomeru
+import utest._
+import utest.framework.Test
+import utest.util.Tree
+
+object SyntaxTest extends TestSuite{
+ def check[T](input: String, parse: ScalaSyntax => scala.util.Try[T], expected: T) = {
+ val parsed = parse(new ScalaSyntax(input)).get
+ assert(parsed == expected)
+ }
+ def tests = TestSuite{
+
+ "omg" - check(
+ """if (true) () else ()""",
+ _.IfCFlow.run(), ()
+ )
+ }
+}