Skip to content

Commit 98da3c7

Browse files
authored
Merge pull request #108 from jasalt/master
Add back to top button & `binding` example
2 parents ce7df43 + 7b0d8b5 commit 98da3c7

File tree

4 files changed

+69
-1
lines changed

4 files changed

+69
-1
lines changed

content/documentation/global-and-local-bindings.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,29 @@ To update a variable with a function the `swap!` function can be used.
6969
(swap! foo + 2) # Evaluates to 12
7070
(deref foo) # Evaluates to 12
7171
```
72+
73+
## Binding
74+
75+
While writing tests on code depending on external state can be challenging, `binding` function allows to remap existing bindings which can be used for mocking functions or values during tests. As example, code depending on runtime environment:
76+
77+
```phel
78+
(ns my-app\tests\demo
79+
(:require phel\test :refer [deftest is]))
80+
81+
# Function that would return e.g. "x86_64", depending on the environment:
82+
(defn get-system-architecture [] (php/php_uname "m"))
83+
84+
(defn greet-user-by-architecture []
85+
(print "Hello" (get-system-architecture) "user!"))
86+
87+
# With binding, a mock function can be used in place of the original one
88+
# allowing to write tests for cases that depend on system state:
89+
(deftest greeting-test
90+
(binding [get-system-architecture |(str "i386")] # <- mock function
91+
(let [greeting-out (with-output-buffer (greet-user-by-architecture))]
92+
(is (= "Hello i386 user!" greeting-out)
93+
"i386 system user is greeted accordingly"))))
94+
95+
# Test is successful:
96+
# ✔ greet-test: i386 system user is greeted accordingly
97+
```

sass/site.scss

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,27 @@
1313
@import 'post-list';
1414

1515
body {
16-
padding-top: $header-height;
16+
padding-top: $header-height;
17+
18+
#back-to-top-button {
19+
display: none;
20+
position: fixed;
21+
bottom: 20px;
22+
right: 30px;
23+
z-index: 99;
24+
border: none;
25+
outline: none;
26+
background-color: $color-base-primary;
27+
color: $color-text-inverted;
28+
cursor: pointer;
29+
padding: 15px;
30+
border-radius: 2px;
31+
font-size: 18px;
32+
33+
&:hover {
34+
background-color: $color-base-hover;
35+
}
36+
}
1737
}
1838

1939
footer {

static/back_to_top.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Get the button:
2+
let mybutton = document.getElementById("back-to-top-button");
3+
4+
// When the user scrolls down 20px from the top of the document, show the button
5+
window.onscroll = function() {scrollFunction()};
6+
7+
function scrollFunction() {
8+
if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
9+
mybutton.style.display = "block";
10+
} else {
11+
mybutton.style.display = "none";
12+
}
13+
}
14+
15+
// When the user clicks on the button, scroll to the top of the document
16+
function backToTop() {
17+
document.body.scrollTop = 0; // For Safari
18+
document.documentElement.scrollTop = 0; // For Chrome, Firefox, IE and Opera
19+
}

templates/base.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,12 @@
2929
<body>
3030
{% block body %} {% endblock %}
3131

32+
<button onclick="backToTop()" id="back-to-top-button" title="Go to top">Top</button>
33+
3234
<script type="text/javascript" src="{{ get_url(path='elasticlunr.min.js') }}" defer></script>
3335
<script type="text/javascript" src="{{ get_url(path='api_search.js') }}" defer></script>
3436
<script type="text/javascript" src="{{ get_url(path='search.js') }}" defer></script>
37+
<script type="text/javascript" src="{{ get_url(path='back_to_top.js') }}" defer></script>
3538
</body>
3639

3740
</html>

0 commit comments

Comments
 (0)