1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
package scrollmenu
import org.scalajs.dom
import org.scalajs.dom.extensions._
import scala.scalajs.js
import scala.scalajs.js.annotation.JSExport
import scalatags.JsDom.all._
@JSExport
object Controller{
def munge(name: String) = {
name.replace(" ", "")
}
@JSExport
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"
).map(dom.document.getElementById)
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)
menu.appendChild(
div(cls:="pure-menu pure-menu-open")(
a(cls:="pure-menu-heading", href:="#")(
"Contents"
),
ul(cls:="menu-item-list")(
domTrees.map(_.value.frag)
)
).render
)
menuLink.onclick = (e: dom.MouseEvent) => {
layout.classList.toggle("active")
menu.classList.toggle("active")
menuLink.classList.toggle("active")
}
main.onscroll = (e: dom.UIEvent) => {
scrollSpy(main.scrollTop + main.clientHeight)
}
}
def isElementInViewport(el: dom.HTMLElement) = {
val rect = el.getBoundingClientRect()
rect.top >= 0 && rect.bottom <= dom.innerHeight
}
}
|