comparison src/nabble/view/lib/Shared.jtp @ 0:7ecd1a4ef557

add content
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 21 Mar 2019 19:15:52 -0600
parents
children 72765b66e2c3
comparison
equal deleted inserted replaced
-1:000000000000 0:7ecd1a4ef557
1 <%
2 package nabble.view.lib;
3
4 import fschmidt.util.java.HtmlUtils;
5 import fschmidt.util.java.MD5Util;
6 import nabble.model.Init;
7 import nabble.model.ModelHome;
8 import nabble.model.Node;
9 import nabble.model.Person;
10 import nabble.model.Site;
11 import nabble.model.User;
12 import org.slf4j.Logger;
13 import org.slf4j.LoggerFactory;
14
15 import javax.servlet.ServletException;
16 import javax.servlet.http.HttpServletRequest;
17 import javax.servlet.http.HttpServletResponse;
18 import java.io.IOException;
19 import java.io.PrintWriter;
20 import java.util.ArrayList;
21 import java.util.List;
22
23
24 public final class Shared {
25 private static final Logger logger = LoggerFactory.getLogger(Shared.class);
26
27 private Shared() {} // never
28
29 public static volatile int javascriptVersion = 102;
30
31 public static final int cssVersion = 29;
32
33 public static String getCssPath() {
34 return "/nabble.css?v="+cssVersion;
35 }
36
37 public static String getJavascriptPath(HttpServletRequest request) {
38 return Jtp.getSite(request) == null? "/Javascript.jtp" : "/template/NamlServlet.jtp?macro=javascript_library";
39 }
40
41 public static String getTabsPath() {
42 return "/util/nabbletabs.js";
43 }
44
45 public static String getJQueryPath() {
46 return "/util/jquery-1.7.2.pack.js";
47 }
48
49 public static String getDropdownJsPath() {
50 return "/util/nabbledropdown-2.4.1.js";
51 }
52
53 public static void head(HttpServletRequest request,HttpServletResponse response)
54 throws IOException
55 {
56 head(request, response, true);
57 }
58
59 public static void head(HttpServletRequest request,HttpServletResponse response, boolean useSiteStyle)
60 throws IOException
61 {
62 if( request.getAttribute("head") != null )
63 return;
64 request.setAttribute("head","x");
65 PrintWriter out = response.getWriter();
66 Site site = Jtp.getSite(request);
67 boolean isApp = site != null && site.getRootNode().getKind() == Node.Kind.APP;
68 %>
69 <link rel="stylesheet" href="<%=Shared.getCssPath()%>" type="text/css" />
70 <% if (isApp && useSiteStyle) { %>
71 <link rel="stylesheet" href="/template/NamlServlet.jtp?macro=site_style" type="text/css" />
72 <% } %>
73 <% loadJavascript(request, out); %>
74 <% if (isApp) { %>
75 <script type="text/javascript">
76 Nabble.setFontSize();
77 </script>
78 <% } %>
79 <%
80 loadAnalytics(request,response);
81 }
82
83 public static void loadJavascript(HttpServletRequest request, PrintWriter out) {
84 %>
85 <script src="<%=getJQueryPath()%>" type="text/javascript"></script>
86 <script src="<%=getDropdownJsPath()%>" type="text/javascript"></script>
87 <script src="<%=getJavascriptPath(request)%>" type="text/javascript"></script>
88 <%
89 }
90
91 private static void checkHead(HttpServletRequest request) {
92 if( request.getAttribute("head") == null )
93 throw new RuntimeException("Shared.head not called");
94 }
95
96 public static void minHeader(HttpServletRequest request,HttpServletResponse response)
97 throws IOException, ServletException
98 {
99 minHeader(request,response,null);
100 }
101
102 public static void minHeader(HttpServletRequest request,HttpServletResponse response,Node node)
103 throws IOException, ServletException
104 {
105 minHeader(request, response, node, null);
106 }
107
108 public static void minHeaderGlobal(HttpServletRequest request,HttpServletResponse response)
109 throws IOException, ServletException
110 {
111 Site site = Jtp.getSite(request);
112 if (site == null) {
113 String homepageLink = "<a id=\"homelink\" href=\"" + Jtp.homePage() + "\">Nabble</a>";
114 minHeader(request, response, null, new String[] { homepageLink });
115 PrintWriter out = response.getWriter();
116 %>
117 <script type="text/javascript">
118 if (Nabble.getParent().nabbleinfo && Nabble.getParent().nabbleinfo.what) {
119 var home = Nabble.get('homelink');
120 home.setAttribute('href', '/');
121 home.innerHTML='Back to ' + Nabble.getParent().nabbleinfo.what;
122 }
123 </script>
124 <%
125 } else {
126 Node node = site.getRootNode();
127 String homepageLink = "<a href=\"" + Jtp.url(node) + "\">" + node.getSubjectHtml() + "</a>";
128 minHeader(request, response, null, new String[] { homepageLink });
129 }
130 }
131
132 public static void minHeader(HttpServletRequest request, HttpServletResponse response, Node node, String[] breadcrumbLinks)
133 throws IOException, ServletException
134 {
135 minHeader(request, response, node, breadcrumbLinks, true);
136 }
137
138 public static void minHeader(HttpServletRequest request, HttpServletResponse response, Node node, String[] breadcrumbLinks, boolean embeddedRedirect)
139 throws IOException, ServletException
140 {
141 PrintWriter out = response.getWriter();
142 checkHead(request);
143 Node app = node==null ? null : node.getApp();
144 if (embeddedRedirect)
145 embeddedRedirect(request, out, app);
146 %>
147 <div id="notice" class="notice rounded-bottom"></div>
148 <div class="nabble" id="nabble">
149 <div class="top-bar">
150 <div class="breadcrumbs" style="float:left;">
151 <%
152 if (app != null)
153 breadcrumb(request,out,app);
154 else if (breadcrumbLinks != null)
155 breadcrumb(out,breadcrumbLinks);
156 %>
157 </div>
158 <div style="text-align:right;">
159 <span style="white-space:nowrap;" id="nabble-user-header"></span>
160 <script type="text/javascript">Nabble.userHeader();</script>
161 </div>
162 </div>
163 <div style="clear:both;"></div>
164 <%
165 if (request.getAttribute("search") == null) {
166 %>
167 <script type="text/javascript">
168 Nabble.deleteCookie("query");
169 Nabble.deleteCookie("searchuser");
170 Nabble.deleteCookie("searchterms");
171 </script>
172 <%
173 }
174 }
175
176 public static void noHeader(HttpServletRequest request,HttpServletResponse response)
177 throws IOException, ServletException
178 {
179 PrintWriter out = response.getWriter();
180 %>
181 <div class="nabble" id="nabble">
182 <%
183 }
184
185 public static void editHeader(String firstText, String secondText, PrintWriter out) {
186 %>
187 <div class="second-font shaded-bg-color" style="font-size: 120%;padding: .4em;font-weight:bold">
188 <%=firstText%> <span class="weak-color"><%=secondText == null? "" : "&ndash; " + secondText%></span>
189 </div>
190 <%
191 }
192
193 public static void helpHeader(HttpServletRequest request,HttpServletResponse response)
194 throws IOException, ServletException
195 {
196 Site site = Jtp.getSite(request);
197 String homepageLink = "<a href=\"/\">" + (site == null? "Nabble":site.getRootNode().getSubjectHtml()) + "</a>";
198 String helpLink = "<a href=\"/help/Index.jtp\">Help</a>";
199 minHeader(request, response, null, new String[] { homepageLink, helpLink });
200 }
201
202 public static void footer(HttpServletRequest request,HttpServletResponse response)
203 throws ServletException, IOException
204 {
205 PrintWriter out = response.getWriter();
206 Site site = Jtp.getSite(request);
207 if( site == null ) {
208 %>
209 <table class="footer-table shaded-bg-color">
210 <tr>
211 <td class="footer-left">
212 <a href="<%=Jtp.homePage()%>" target="_top">Free Forum</a> by Nabble
213 </td>
214 </tr>
215 </table>
216 <%
217 } else {
218 %>
219 <table class="footer-table shaded-bg-color">
220 <tr>
221 <td class="footer-left">
222 <a href="<%=Jtp.homePage()%>" target="_top">Free Forum</a>
223 by Nabble
224 </td>
225 <td class="footer-right">
226 <a href="<%=Jtp.helpIndexUrl(request,response)%>">Help</a>
227 </td>
228 </tr>
229 </table>
230 <%
231 }
232 %>
233 </div>
234 <%
235 }
236
237 public static void noFooter(HttpServletRequest request,HttpServletResponse response)
238 throws ServletException, IOException
239 {
240 PrintWriter out = response.getWriter();
241 %>
242 </div>
243 <%
244 }
245
246 public static void breadcrumb(HttpServletRequest request,PrintWriter out,Node node)
247 throws ServletException, IOException
248 {
249 List<String> links = new ArrayList<String>();
250 node = node.getApp();
251 while (node != null) {
252 links.add(0, "<a href=\"" + Jtp.path(node) + "\">" + node.getSubjectHtml() + "</a>");
253 node = node.getParent();
254 }
255 String[] array = new String[links.size()];
256 links.toArray(array);
257 breadcrumb(out, array);
258 }
259
260 private static void breadcrumb(PrintWriter out, String[] links)
261 throws ServletException, IOException
262 {
263 %><span class="weak-color" style="white-space:nowrap"><%
264 for (String s : links) {
265 %><%=s%><%
266 boolean isLastString = s.equals(links[links.length-1]);
267 if (!isLastString) {
268 %>&nbsp;&rsaquo;&nbsp;<%
269 }
270 }
271 %></span><%
272 }
273
274 public static void javascriptRedirect(HttpServletRequest request,HttpServletResponse response,String url)
275 throws IOException, ServletException
276 {
277 javascriptRedirect(request,response,url,null);
278 }
279
280 public static void javascriptRedirect(HttpServletRequest request,HttpServletResponse response,String url,String script)
281 throws IOException, ServletException
282 {
283 javascriptRedirect(request, response, url, script, false);
284 }
285
286 public static void javascriptRedirect(HttpServletRequest request,HttpServletResponse response,String url,String script, boolean leaveEmbedding)
287 throws IOException, ServletException
288 {
289 PrintWriter out = response.getWriter();
290 %>
291 <html>
292 <head>
293 <script src="<%=getJQueryPath()%>" type="text/javascript"></script>
294 <script src="<%=getJavascriptPath(request)%>" type="text/javascript"></script>
295 <% loadAnalytics(request,response); %>
296 <script type="text/javascript">
297 <%=Jtp.hideNull(script)%>
298 var url = "<%=HtmlUtils.javascriptStringEncode(url)%>";
299
300 <%=leaveEmbedding? "top." : ""%>location.replace(url);
301 </script>
302 </head>
303 </html>
304 <%
305 }
306
307 /* Rebuilds the embedding iframe and reload the contents.*/
308 public static void restartEmbedding(Node node, HttpServletRequest request, HttpServletResponse response)
309 throws IOException, ServletException
310 {
311 PrintWriter out = response.getWriter();
312 %>
313 <html>
314 <head>
315 <script src="<%=getJQueryPath()%>" type="text/javascript"></script>
316 <script src="<%=getJavascriptPath(request)%>" type="text/javascript"></script>
317 <script type="text/javascript">
318 Nabble.restartEmbedding(<%=node.getId()%>,'<%=node.getSite().getBaseUrl()%>');
319 </script>
320 </head>
321 </html>
322 <%
323 }
324
325 public static void showPending(PrintWriter out, Node post) {
326 Node.MailToList mail = post.getMailToList();
327 if (mail == null || !(post.getOwner() instanceof User))
328 return;
329 showPending(out, mail.isPending());
330 }
331
332 public static void showPending(PrintWriter out, boolean isPending) {
333 if (isPending) {
334 %>
335 <img src="/images/icon_pending.png" class="image16" title="Pending - this message has not been accepted by the mailing list yet"/>
336 <%
337 }
338 }
339
340 public static void errorMessage(HttpServletRequest request,HttpServletResponse response,String errorMsg,String prompt)
341 throws ServletException, IOException
342 {
343 if( errorMsg==null )
344 return;
345 PrintWriter out = response.getWriter();
346 errorMsg = HtmlUtils.htmlEncode(errorMsg);
347 int posLinkOpen = errorMsg.indexOf("[link]");
348 if (posLinkOpen >= 0) {
349 int posLinkClose = errorMsg.indexOf("[/link]", posLinkOpen);
350 String url = errorMsg.substring(posLinkOpen+6, posLinkClose);
351 errorMsg = errorMsg.substring(0, posLinkOpen) + "<a href=\"" + url + "\">" + url + "</a>" + errorMsg.substring(posLinkClose+7);
352 }
353 %>
354 <table class="error-message" style="width:100%">
355 <tr>
356 <td style="padding: .4em; width: 40px;">
357 <img src="/images/icon_alert.png" class="image32"/>
358 </td>
359 <td style="padding: .4em;">
360 <strong><%=errorMsg%></strong>
361 <%=prompt == null? "" : "<div style=\"padding-top:.3em\">" + prompt + "</div>"%>
362 </td>
363 </tr>
364 </table>
365 <%
366 }
367
368 public static void title(HttpServletRequest request,HttpServletResponse response,String s)
369 throws ServletException, IOException
370 {
371 PrintWriter out = response.getWriter();
372 Site site = Jtp.getSite(request);
373 %>
374 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
375 <title><%=site == null?"Nabble":site.getRootNode().getSubjectHtml()%> - <%=s%></title>
376 <%
377 head(request,response);
378 }
379
380 private static void loadAnalytics(HttpServletRequest request,HttpServletResponse response)
381 throws IOException
382 {
383 PrintWriter out = response.getWriter();
384 HtmlViewUtils.googleAnalytics(out);
385 }
386
387 public static void analytics(HttpServletRequest request,HttpServletResponse response)
388 throws IOException
389 {
390 PrintWriter out = response.getWriter();
391 %>
392 <script type="text/javascript">
393 if (Nabble.analytics) Nabble.analytics();
394 </script>
395 <%
396 }
397
398 public static void postInThreadLink(HttpServletRequest request, PrintWriter out, Node post)
399 throws ServletException, IOException
400 {
401 String topicSubject = Jtp.breakUp(post.getTopic().getSubjectHtml());
402 String postSubject = Jtp.breakUp(post.getSubjectHtml());
403 if( postSubject.endsWith(topicSubject) ) {
404 %><a href="<%=Jtp.path(post)%>"><%=postSubject%></a><%
405 } else {
406 %><%=topicSubject%></a> &nbsp; (<a href="<%=Jtp.path(post)%>"><%=postSubject%></a>)<%
407 }
408 }
409
410 public static void profileHeading(HttpServletRequest request,PrintWriter out,User user,String heading)
411 {
412 %>
413 <h1><%=heading%></h1>
414 <%
415 }
416
417 public static void returnToJs(HttpServletRequest request, HttpServletResponse response)
418 throws IOException, ServletException
419 {
420 returnToJs(null, request, response);
421 }
422
423 public static void returnToJs(Node node, HttpServletRequest request, HttpServletResponse response)
424 throws IOException, ServletException
425 {
426 PrintWriter out = response.getWriter();
427 if (node == null) {
428 Site site = Jtp.getSite(request);
429 if (site != null && site.getRootNode().getKind() == Node.Kind.APP)
430 node = site.getRootNode();
431 }
432 %>
433 <div id="return-link" style="margin-top:1em">
434 <% if (node != null) { %>
435 &laquo;
436 <a href="<%=Jtp.path(node)%>">Return to <%=node.getSubject()%></a>
437 <% } %>
438 </div>
439 <%
440 }
441
442 public static void framedCss(PrintWriter out)
443 {
444 %>
445 <style>
446 body {
447 margin: .8em;
448 }
449 </style>
450 <%
451 }
452
453 public static void embeddedRedirect(HttpServletRequest request, PrintWriter out, Node forum)
454 throws IOException
455 {
456 // The embedding URL is stored in the node.embedding_url field.
457 String embeddingUrl = null;
458 for(
459 Node node = forum;
460 embeddingUrl == null && node != null;
461 node = node.getParent()
462 ) {
463 embeddingUrl = node.getEmbeddingUrl();
464 }
465
466 if (embeddingUrl == null)
467 return;
468 %>
469 <script type="text/javascript">
470 if (!Nabble.isEmbedded) {
471 var url = top.location.href;
472 var cidPos = url.indexOf(';cid=');
473 if (cidPos > 0) {
474 url = url.substring(0, cidPos);
475 }
476
477 var posHtml = url.lastIndexOf('.html');
478 var hash;
479 <%
480 /*
481 If the URL is mapped, we extract the last
482 part, which gives information about the item.
483 For example:
484 https://www.nabble.com/text-p100.html
485 We extract "p100", because we know how to
486 rebuild this URL with this information.
487
488 See JsEmbed.jtp for more details on how to
489 rebuild the URL.
490 */
491 %>
492 if (url.indexOf('?') == -1 && posHtml > 0) {
493 var posStart = url.lastIndexOf('-');
494 hash = (posStart > 0)? url.substring(posStart, posHtml):'';
495 } else {
496 <%
497 /*
498 If the URL is NOT mapped, we have to extract
499 the information after the domain.
500 For example:
501 - http://localhost/forum/NewTopic.jtp?forum=2
502 We extract "forum/NewTopic.jtp?forum=2".
503 */
504 %>
505 hash = url.replace('http://', '');
506 hash = hash.substring(hash.indexOf('/')+1);
507 hash = '+' + hash;
508 }
509 <%
510 /*
511 In order to restore the current hash, I append it to the
512 same string after a pipe separator. This will be restored
513 in the Nabble.getCurrentUrl() function in JsEmbed.jtp.
514 */
515 %>
516 if (top.location.hash) {
517 hash += '|' + top.location.hash.substring(1);
518 }
519 if (Nabble.analytics) Nabble.analytics();
520 top.location.replace('<%=embeddingUrl%>' + (hash.length==1?'':'#nabble' + encodeURIComponent(hash)));
521 }
522 </script>
523 <%
524 }
525
526 public static String getAvatarImageURL(Person visitor, boolean smallImage) {
527 String imageName = smallImage? ModelHome.AVATAR_SMALL : ModelHome.AVATAR_BIG;
528 String defaultImage = "/images/" + imageName;
529 if( visitor instanceof User ) {
530 User user = (User)visitor;
531 if( user.hasAvatar() )
532 return "/file/a" + user.getId() + '/' + imageName;
533 }
534 return defaultImage;
535 }
536
537 public static String getDefaultAvatarImageURL(boolean smallImage) {
538 String imageName = smallImage? ModelHome.AVATAR_SMALL : ModelHome.AVATAR_BIG;
539 return "/images/" + imageName;
540 }
541
542 public static String simpleBannedMessage(Node app) {
543 StringBuilder builder = new StringBuilder();
544 builder
545 .append("Sorry, but the administrators of this ")
546 .append(Jtp.viewName(app).toLowerCase())
547 .append(" have banned you.\n ");
548 return builder.toString();
549 }
550
551 public static String bannedMessage(Node app, boolean isPost) {
552 StringBuilder builder = new StringBuilder();
553 builder.append(simpleBannedMessage(app));
554 if (isPost)
555 builder.append("You can't post a message here, but you can post in other places.");
556 else
557 builder.append("You can't create a forum here, but you can create in other places.");
558 return builder.toString();
559 }
560
561
562 public static void simplePage(String pageTitle, Node node, String messageTitle, String message, HttpServletRequest request, HttpServletResponse response)
563 throws IOException, ServletException
564 {
565 PrintWriter out = response.getWriter();
566 %>
567 <html>
568 <head>
569 <META NAME="robots" CONTENT="noindex,nofollow">
570 <% title(request, response, pageTitle); %>
571 <style type="text/css">
572 div.main-title {
573 font-size:120%;
574 font-weight:bold;
575 margin:1em 0;
576 padding: .2em;
577 }
578 </style>
579 <script type="text/javascript">
580 <%/* here I set the next url for the login UI */%>
581 var loginNextUrl = '<%=node==null?"/":Jtp.url(node)%>';
582 </script>
583 </head>
584 <body>
585 <%
586 if (node == null)
587 minHeaderGlobal(request, response);
588 else
589 minHeader(request, response, node);
590 %>
591 <div class="shaded-bg-color rounded second-font main-title">
592 <%=messageTitle%>
593 </div>
594 <%=message%>
595 <% if (node != null) { %>
596 <br><br>&laquo; <a href="<%=Jtp.url(node)%>">Back to <%=node.getSubjectHtml()%></a>
597 <% } else { %>
598 <br>
599 <% } %>
600 <br/><br/>
601 <% footer(request,response); %>
602 <% analytics(request,response); %>
603 </body>
604 </html>
605 <%
606 }
607
608 public static void canonical(HttpServletRequest request, HttpServletResponse response)
609 throws IOException, ServletException
610 {
611 String canonical = Jtp.getCanonicalUrl(request);
612 if (canonical != null) {
613 PrintWriter out = response.getWriter();
614 %>
615 <link rel="canonical" href="<%=canonical%>" />
616 <%
617 }
618 }
619
620 /** (To be used by scripts)
621 * http://tablesorter.com/docs/
622 */
623 public static void tableSorter(PrintWriter out, String sortList)
624 throws IOException, ServletException
625 {
626 %>
627 <link rel="stylesheet" href="/util/tablesorter/style.css" type="text/css" />
628 <script src="/util/tablesorter/jquery.tablesorter.min.js" type="text/javascript"></script>
629 <script type="text/javascript">
630 $(document).ready(function() {
631 $("table.tablesorter").tablesorter(<%=sortList%>);
632 });
633 </script>
634 <%
635 }
636
637 /** (To be used by scripts) */
638 public static void countTableRows(PrintWriter out)
639 throws IOException, ServletException
640 {
641 %>
642 <div id="rows"></div>
643 <script type="text/javascript">
644 $(document).ready(function() {
645 var count = $('tbody tr').size();
646 $("#rows").html(count + " rows");
647 });
648 </script>
649 <%
650 }
651 }
652 %>