Implement JSDoc and embedding into our navbar without obvious CSS conflicts
[ndcode_site.git] / navbar.jst
1 let XDate = require('xdate')
2
3 return async (env, head, body) => {
4   let feedback_form = await _require('/feedback_form.jst')
5   let globals = await env.site.get_json('/_config/globals.json')
6   let icon_search = await env.site.get_min_svg('/_svg/icon_search.svg')
7   let logo_large = await env.site.get_min_svg('/_svg/logo_large.svg')
8   let page = await _require('/page.jst')
9
10   await page(
11     env,
12     // head
13     async _out => {
14       title {
15         _out.push(
16           globals.site_title +
17           ": " +
18           (globals.page_to_title[env.parsed_url.pathname] || env.parsed_url.pathname)
19         )
20       }
21
22       await head(_out)
23     },
24     // body
25     async _out => {
26       div(style="padding-left: calc(100vw - 100%);") {
27         div.container(style="margin-top: 15px; margin-bottom: 15px;") {
28           //div.row {
29           //  div.col-sm-12(style="text-align: right;") {
30           //    a(href="/login.html") {'Login'}
31           //  }
32           //}
33           div.row {
34             div.'col-sm-8'.vbottom {
35               _out.push(logo_large)
36             }
37             div.'col-sm-4'.vbottom(style="padding-bottom: 15px;") {
38               form(action="/search.html") {
39                 div.input-group {
40                   input.form-control(name="query" type="text" placeholder="Search") {}
41                   span.input-group-btn {
42                     button.btn.btn-default(type="submit") {
43                       _out.push(icon_search)
44                     }
45                   }
46                 }
47               }
48             }
49           }
50         }
51       }
52       nav.navbar.navbar-default(style="margin-top: 0px; margin-bottom: 0px;") {
53         div(style="padding-left: calc(100vw - 100%);") {
54           div.container { //-fluid") {
55             //  Brand and toggle get grouped for better mobile display 
56             div.navbar-header {
57               button.navbar-toggle.collapsed(type="button" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false") {
58                 span.sr-only {'Toggle navigation'}
59                 span.icon-bar {}
60                 span.icon-bar {}
61                 span.icon-bar {}
62               }
63               //a.navbar-brand(href="#") {'Brand'}
64             }
65
66             //  Collect the nav links, forms, and other content for toggling 
67             div.collapse.navbar-collapse#bs-example-navbar-collapse-1 {
68               ul.nav.navbar-nav {
69                 let navigation = globals.navigation
70                 for (let i = 0; i < navigation.length; ++i) {
71                   let page = navigation[i]
72                   let title = globals.page_to_title[page] || page
73                   if (page === env.parsed_url.pathname)
74                     li.active {
75                       a(href=page) {
76                         `${title}`
77                         span.sr-only {'(current)'}
78                       }
79                     }
80                   else
81                     li {
82                       a(href=page) {`${title}`}
83                     }
84                 }
85               }
86               ul.nav.navbar-nav.navbar-right {
87                 li {
88                   a#give-feedback {'Give feedback'}
89                 }
90               } 
91             }
92           }
93         }
94       }
95       div(style="padding-left: calc(100vw - 100%);") {
96         div.container {
97           await body(_out)
98         }
99       }
100       br {}
101       div.footer(style="padding-left: calc(100vw - 100%);") {
102         div.container { //-fluid") {
103           div(style="height: 16px;") {}
104           a(rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/") {
105             img(alt="Creative Commons License" style="border-width:0" src="/images/by-sa_3.0_88x31.png") {}
106           }
107           p {
108             'This work is licensed under a '
109             a(rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/") {
110               'Creative Commons Attribution-ShareAlike 3.0 Unported License'
111             }
112             '.'
113           }
114
115           p {'Code samples within the page are placed in the public domain unless otherwise noted.'}
116
117           p {`Copyright © ${new XDate().getUTCFullYear()} Integration Logic Pty Ltd trading as NDCODE and contributors.`}
118         }
119       }
120
121       // hidden part
122       div#feedback-modal.modal.fade(role="dialog") {
123         div.modal-dialog {
124           div.modal-content {
125             div.modal-header {
126               button.close(type="button" data-dismiss="modal") {
127                 '×'
128               }
129               h4.modal-title {
130                 'Give feedback'
131               }
132             }
133             div.modal-body {
134               p {
135                 'Did you notice something not quite right, or just want to share your impression of this page?'
136               }
137               await feedback_form(env, _out)
138             }
139             div.modal-footer {
140               button.btn.btn-primary(type="submit" form="feedback-form") {
141                 'Submit'
142               }
143               button.btn.btn-default(type="button" data-dismiss="modal") {
144                 'Close'
145               }
146             }
147           }
148         }
149       }
150
151       div#message-modal.modal.fade(role="dialog") {
152         div.modal-dialog {
153           div.modal-content {
154             div.modal-header {
155               button.close(type="button" data-dismiss="modal") {
156                 '×'
157               }
158               h4.modal-title {
159                 'Message'
160               }
161             }
162             div.modal-body {
163               p#message-modal-message {}
164             }
165             div.modal-footer {
166               button.btn.btn-default(type="button" data-dismiss="modal") {
167                 'Close'
168               }
169             }
170           }
171         }
172       }
173     },
174     // scripts
175     async _out => {
176       // when feedback form is submitted, do not reload the page
177       script {
178         $(document).ready(function() {
179           $('#give-feedback').click(function() {
180             $('#feedback-modal').modal('show')
181             $('#feedback-form-message').text('')
182           })
183           $('#feedback-modal').on('shown.bs.modal', function() {
184             $('#feedback-form-message').focus()
185           })
186           $(document).on('submit', '#feedback-form', function(e) {
187             e.preventDefault()
188             $.ajax({
189               url: '/feedback.html',
190               type: 'POST',
191               data: {
192                 page: window.location.href,
193                 message: $('#feedback-form-message').val()
194               },
195               success: function(data, textStatus, jqXHR) {
196                 $('#feedback-modal').modal('hide')
197                 $('#message-modal-message').text(data)
198                 $('#message-modal').modal('show')
199               },
200               error: function(jqXHR, textStatus, errorThrown) {
201                 $('#feedback-modal').modal('hide')
202                 $('#message-modal-message').text(errorThrown)
203                 $('#message-modal').modal('show')
204               }               
205             })
206           })
207         })
208       }
209     }
210   )
211 }