From c7a6380fdf37010d43d62a7db0a882d7ccc68d96 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Fri, 14 Nov 2014 14:28:51 -0800 Subject: WIP after getting rid of react.js, still doesn't work --- examples/demos/Controller.scala | 144 ++++++++++++++++------------------------ 1 file changed, 56 insertions(+), 88 deletions(-) (limited to 'examples') 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 -- cgit v1.2.3