diff options
author | 2016-07-22 16:51:43 +0300 | |
---|---|---|
committer | 2016-07-27 13:52:02 +0300 | |
commit | d3454e70a5855164d17c563fe15e8674b5a5ae2e (patch) | |
tree | fda0c9da5e44de736f0215b3d6c63872329b0544 /juick-www | |
parent | dbc48e0d220107ac0887d21f2144665f4eea5aab (diff) |
* drop jQuery dependency
Diffstat (limited to 'juick-www')
-rw-r--r-- | juick-www/.eslintrc | 32 | ||||
-rw-r--r-- | juick-www/package.json | 8 | ||||
-rw-r--r-- | juick-www/src/main/java/com/juick/www/Discover.java | 2 | ||||
-rw-r--r-- | juick-www/src/main/java/com/juick/www/Errors.java | 2 | ||||
-rw-r--r-- | juick-www/src/main/java/com/juick/www/Help.java | 2 | ||||
-rw-r--r-- | juick-www/src/main/java/com/juick/www/Home.java | 13 | ||||
-rw-r--r-- | juick-www/src/main/java/com/juick/www/NewMessage.java | 17 | ||||
-rw-r--r-- | juick-www/src/main/java/com/juick/www/PM.java | 4 | ||||
-rw-r--r-- | juick-www/src/main/java/com/juick/www/PageTemplates.java | 37 | ||||
-rw-r--r-- | juick-www/src/main/java/com/juick/www/Settings.java | 2 | ||||
-rw-r--r-- | juick-www/src/main/java/com/juick/www/SignUp.java | 4 | ||||
-rw-r--r-- | juick-www/src/main/java/com/juick/www/User.java | 8 | ||||
-rw-r--r-- | juick-www/src/main/java/com/juick/www/UserThread.java | 30 | ||||
-rw-r--r-- | juick-www/src/main/java/ru/sape/SapePageLinks.java | 14 | ||||
-rw-r--r-- | juick-www/src/main/static/scripts.js | 1051 | ||||
-rw-r--r-- | juick-www/src/main/webapp/WEB-INF/web.xml | 8 | ||||
-rw-r--r-- | juick-www/webpack.config.js | 13 |
17 files changed, 651 insertions, 596 deletions
diff --git a/juick-www/.eslintrc b/juick-www/.eslintrc new file mode 100644 index 00000000..70f0fc89 --- /dev/null +++ b/juick-www/.eslintrc @@ -0,0 +1,32 @@ +{ + // Extend existing configuration + // from ESlint and eslint-plugin-react defaults. + "extends": [ + "eslint:recommended" + //, "plugin:react/recommended" + ], + // Enable ES6 support. If you want to use custom Babel + // features, you will need to enable a custom parser + // as described in a section below. + "parserOptions": { + "ecmaVersion": 6, + "sourceType": "module" + }, + "env": { + "browser": true, + "node": true + }, + // Enable custom plugin known as eslint-plugin-react + "plugins": [ + // "react" + ], + "rules": { + // Disable `no-console` rule + "no-console": 0, + // Give a warning if identifiers contain underscores + "no-underscore-dangle": 1, + // Default to single quotes and raise an error if something + // else is used + "quotes": [2, "single"] + } +}
\ No newline at end of file diff --git a/juick-www/package.json b/juick-www/package.json index 31bab35b..f8ab05f3 100644 --- a/juick-www/package.json +++ b/juick-www/package.json @@ -13,12 +13,18 @@ "license": "AGPLv3", "devDependencies": { "css-loader": "^0.23.1", - "expose-loader": "^0.7.1", + "eslint": "^3.1.1", + "eslint-loader": "^1.4.1", "extract-text-webpack-plugin": "^1.0.1", "globby": "^4.1.0", "script-loader": "^0.7.0", "style-loader": "^0.13.1", "uglify-loader": "^1.3.0", "webpack": "^1.13.1" + }, + "dependencies": { + "autosize": "^3.0.16", + "element-closest": "^2.0.1", + "whatwg-fetch": "^1.0.0" } } diff --git a/juick-www/src/main/java/com/juick/www/Discover.java b/juick-www/src/main/java/com/juick/www/Discover.java index e94d6e99..c1bcacc7 100644 --- a/juick-www/src/main/java/com/juick/www/Discover.java +++ b/juick-www/src/main/java/com/juick/www/Discover.java @@ -84,7 +84,7 @@ public class Discover { } else if (paramBefore > 0 || mids.size() < 5) { head = "<meta name=\"robots\" content=\"noindex\"/>"; } - PageTemplates.pageHead(out, title, head); + PageTemplates.pageHead(out, visitor, title, head); PageTemplates.pageNavigation(out, visitor, null); PageTemplates.pageHomeColumn(out, sql, visitor); diff --git a/juick-www/src/main/java/com/juick/www/Errors.java b/juick-www/src/main/java/com/juick/www/Errors.java index 45fa3d51..4ab10229 100644 --- a/juick-www/src/main/java/com/juick/www/Errors.java +++ b/juick-www/src/main/java/com/juick/www/Errors.java @@ -26,7 +26,7 @@ public class Errors { response.setStatus(404); response.setContentType("text/html; charset=UTF-8"); try (PrintWriter out = response.getWriter()) { - PageTemplates.pageHead(out, "404 Страница не найдена", null); + PageTemplates.pageHead(out, visitor, "404 Страница не найдена", null); PageTemplates.pageNavigation(out, visitor, null); PageTemplates.pageHomeColumn(out, sql, visitor); diff --git a/juick-www/src/main/java/com/juick/www/Help.java b/juick-www/src/main/java/com/juick/www/Help.java index e0ecab2b..a8bfaf3f 100644 --- a/juick-www/src/main/java/com/juick/www/Help.java +++ b/juick-www/src/main/java/com/juick/www/Help.java @@ -62,7 +62,7 @@ public class Help { response.setContentType("text/html; charset=UTF-8"); try (PrintWriter out = response.getWriter()) { - PageTemplates.pageHead(out, "Помощь", null); + PageTemplates.pageHead(out, visitor, "Помощь", null); PageTemplates.pageNavigation(out, visitor, null); out.println("<aside id=\"column\">"); diff --git a/juick-www/src/main/java/com/juick/www/Home.java b/juick-www/src/main/java/com/juick/www/Home.java index 769670c4..5a1aa6ab 100644 --- a/juick-www/src/main/java/com/juick/www/Home.java +++ b/juick-www/src/main/java/com/juick/www/Home.java @@ -106,7 +106,7 @@ public class Home { if (paramBefore > 0 || paramShow != null) { head = "<meta name=\"robots\" content=\"noindex\"/>"; } - PageTemplates.pageHead(out, title, head); + PageTemplates.pageHead(out, visitor, title, head); PageTemplates.pageNavigation(out, visitor, paramSearch); PageTemplates.pageHomeColumn(out, sql, visitor, paramShow == null && paramBefore == 0 && paramSearch == null && visitor.getUID() == 0); @@ -117,12 +117,15 @@ public class Home { } if (visitor.getUID() > 0) { - out.println("<form action=\"/post\" method=\"post\" enctype=\"multipart/form-data\" onsubmit=\"return onsubmitNewMessage()\">"); + out.println("<form action=\"/post\" method=\"post\" enctype=\"multipart/form-data\">"); out.println("<section id=\"newmessage\">"); - out.println(" <textarea name=\"body\" placeholder=\"Новое сообщение...\" onclick=\"$('#newmessage>div').css('display','block');$('#newmessage textarea').css('min-height','70px');\" onkeypress=\"postformListener(this.form,event)\"></textarea>"); + out.println(" <textarea name=\"body\" placeholder=\"Новое сообщение...\"></textarea>"); out.println(" <div>"); - out.println(" <input type=\"text\" class=\"img\" name=\"img\" placeholder=\"Ссылка на изображение (JPG/PNG, до 10Мб)\"/> или <a href=\"#\" onclick=\"return attachMessagePhoto(this)\">загрузить</a><br/>"); - out.println(" <input type=\"text\" class=\"tags\" name=\"tags\" placeholder=\"Теги (через пробел)\"/><br/>"); + out.println(" <input type=\"text\" class=\"img\" name=\"img\" " + + "placeholder=\"Ссылка на изображение (JPG/PNG, до 10Мб)\"/> " + + "или <a href=\"#\">загрузить</a><br/>"); + out.println(" <input type=\"text\" class=\"tags\" name=\"tags\" " + + "placeholder=\"Теги (через пробел)\"/><br/>"); out.println(" <input type=\"submit\" class=\"subm\" value=\"Отправить\"/>"); out.println(" </div>"); out.println("</section>"); diff --git a/juick-www/src/main/java/com/juick/www/NewMessage.java b/juick-www/src/main/java/com/juick/www/NewMessage.java index a179fac8..c6a1aae8 100644 --- a/juick-www/src/main/java/com/juick/www/NewMessage.java +++ b/juick-www/src/main/java/com/juick/www/NewMessage.java @@ -60,10 +60,11 @@ public class NewMessage { this.imgDir = imgDir; } - protected void doGetNewMessage(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response, com.juick.User visitor) throws ServletException, IOException { + protected void doGetNewMessage(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response, + com.juick.User visitor) throws ServletException, IOException { response.setContentType("text/html; charset=UTF-8"); try (PrintWriter out = response.getWriter()) { - PageTemplates.pageHead(out, "Написать", "<script src=\"//maps.google.com/maps?file=api&v=2&sensor=false&key=ABQIAAAAVVtPtxkw4soCEHg44FsNChRB4OFYjAXt73He16Zkp6a_0tPs2RTU6i6UlcMs4QvPBYvIY8rWvcxqOg\" type=\"text/javascript\"></script>" + PageTemplates.pageHead(out, visitor, "Написать", "<script src=\"//maps.google.com/maps?file=api&v=2&sensor=false&key=ABQIAAAAVVtPtxkw4soCEHg44FsNChRB4OFYjAXt73He16Zkp6a_0tPs2RTU6i6UlcMs4QvPBYvIY8rWvcxqOg\" type=\"text/javascript\"></script>" + "<script src=\"//static.juick.com/mc.js\" type=\"text/javascript\" defer=\"defer\"></script>" + "<script src=\"//static.juick.com/maps.js?2010111500\" type=\"text/javascript\" defer=\"defer\"></script>" + "<script src=\"//static.juick.com/post3.js\" type=\"text/javascript\" defer=\"defer\"></script>"); @@ -250,7 +251,7 @@ public class NewMessage { response.setContentType("text/html; charset=UTF-8"); try (PrintWriter out = response.getWriter()) { - PageTemplates.pageHead(out, "Сообщение опубликовано", null); + PageTemplates.pageHead(out, visitor, "Сообщение опубликовано", null); PageTemplates.pageNavigation(out, visitor, null); PageTemplates.pageHomeColumn(out, sql, visitor); @@ -277,14 +278,14 @@ public class NewMessage { out.println("<h1>Сообщение опубликовано</h1>"); out.println("<p>Поделитесь своим новым постом в социальных сетях:</p>"); if (CrosspostQueries.getTwitterTokens(sql, visitor.getUID()).isPresent()) { - out.println("<p><a href=\"https://twitter.com/intent/tweet?text=" + URLEncoder.encode(sharetwi, "utf-8") + "\" onclick=\"return openSocialWindow(this)\" class=\"ico32-twi sharenew\">Отправить в Twitter</a></p>"); + out.println("<p class=\"social\"><a href=\"https://twitter.com/intent/tweet?text=" + URLEncoder.encode(sharetwi, "utf-8") + "\" class=\"ico32-twi sharenew\">Отправить в Twitter</a></p>"); } - out.println("<p><a href=\"http://www.livejournal.com/update.bml?subject=" + URLEncoder.encode(hashtags, "utf-8") + "&event=" + sharelj + "&prop_taglist=" + URLEncoder.encode(tagscomma, "utf-8") + "\" target=\"_blank\" class=\"ico32-lj sharenew\">Отправить в LiveJournal</a></p>"); - out.println("<p><a href=\"https://vk.com/share.php?url=" + url + "\" onclick=\"return openSocialWindow(this)\" class=\"ico32-vk sharenew\">Отправить в ВКонтакте</a></p>"); + out.println("<p class=\"social\"><a href=\"http://www.livejournal.com/update.bml?subject=" + URLEncoder.encode(hashtags, "utf-8") + "&event=" + sharelj + "&prop_taglist=" + URLEncoder.encode(tagscomma, "utf-8") + "\" target=\"_blank\" class=\"ico32-lj sharenew\">Отправить в LiveJournal</a></p>"); + out.println("<p class=\"social\"><a href=\"https://vk.com/share.php?url=" + url + "\" class=\"ico32-vk sharenew\">Отправить в ВКонтакте</a></p>"); if (CrosspostQueries.getFacebookToken(sql, visitor.getUID()).isPresent()) { - out.println("<p><a href=\"https://www.facebook.com/sharer/sharer.php?u=" + url + "\" onclick=\"return openSocialWindow(this)\" class=\"ico32-fb sharenew\">Отправить в Facebook</a></p>"); + out.println("<p class=\"social\"><a href=\"https://www.facebook.com/sharer/sharer.php?u=" + url + "\" class=\"ico32-fb sharenew\">Отправить в Facebook</a></p>"); } - out.println("<p><a href=\"https://plus.google.com/share?url=" + url + "\" onclick=\"return openSocialWindow(this)\" class=\"ico32-gp sharenew\">Отправить в Google+</a></p>"); + out.println("<p class=\"social\"><a href=\"https://plus.google.com/share?url=" + url + "\" class=\"ico32-gp sharenew\">Отправить в Google+</a></p>"); out.println("<p>Ссылка на сообщение: <a href=\"http://juick.com/" + mid + "\">http://juick.com/" + mid + "</a></p>"); out.println("</section>"); diff --git a/juick-www/src/main/java/com/juick/www/PM.java b/juick-www/src/main/java/com/juick/www/PM.java index 5adef7b3..7c38d2a5 100644 --- a/juick-www/src/main/java/com/juick/www/PM.java +++ b/juick-www/src/main/java/com/juick/www/PM.java @@ -55,7 +55,7 @@ public class PM { response.setContentType("text/html; charset=UTF-8"); try (PrintWriter out = response.getWriter()) { - PageTemplates.pageHead(out, title, null); + PageTemplates.pageHead(out, visitor, title, null); PageTemplates.pageNavigation(out, visitor, null); PageTemplates.pageHomeColumn(out, sql, visitor); @@ -120,7 +120,7 @@ public class PM { response.setContentType("text/html; charset=UTF-8"); try (PrintWriter out = response.getWriter()) { - PageTemplates.pageHead(out, title, null); + PageTemplates.pageHead(out, visitor, title, null); PageTemplates.pageNavigation(out, visitor, null); PageTemplates.pageHomeColumn(out, sql, visitor); diff --git a/juick-www/src/main/java/com/juick/www/PageTemplates.java b/juick-www/src/main/java/com/juick/www/PageTemplates.java index c570ae7f..6e13bcc2 100644 --- a/juick-www/src/main/java/com/juick/www/PageTemplates.java +++ b/juick-www/src/main/java/com/juick/www/PageTemplates.java @@ -54,13 +54,12 @@ public class PageTemplates { private static SimpleDateFormat sdfFull = new SimpleDateFormat("d MMM yyyy"); private static String tagsHTML = null; - public static void pageHead(PrintWriter out, String title, String headers) { + public static void pageHead(PrintWriter out, com.juick.User visitor, String title, String headers) { out.println("<!DOCTYPE html>"); out.print("<html>"); out.print("<head>"); out.println("<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">"); out.print("<link rel=\"stylesheet\" href=\"/style.css\"/>"); - out.print("<script type=\"text/javascript\" src=\"//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js\"></script>"); out.print("<script type=\"text/javascript\" src=\"/scripts.js\"></script>"); if (headers != null) { out.print(headers); @@ -73,7 +72,11 @@ public class PageTemplates { out.println("<![endif]-->"); out.println("</head>"); out.flush(); - out.println("<body>"); + if (visitor.getUID() > 0) { + out.println("<body id=\"body\" data-hash=\"" + visitor.getAuthHash() + "\">"); + } else { + out.println("<body id=\"body\">"); + } } public static void pageNavigation(PrintWriter out, com.juick.User visitor, String search) { @@ -103,7 +106,7 @@ public class PageTemplates { out.print("<li><a href=\"/logout\">Выйти</a></li>"); out.println("</ul></nav>"); } else { - out.println("<p>Чтобы добавлять сообщения и комментарии, <a href=\"#\" onclick=\"return openDialogLogin()\">представьтесь</a>.</p>"); + out.println("<p>Чтобы добавлять сообщения и комментарии, <a href=\"#\" class=\"a-login\">представьтесь</a>.</p>"); } out.println(" </section>"); out.println("</header>"); @@ -158,12 +161,6 @@ public class PageTemplates { out.println("</div>"); out.println("</div>"); - if (visitor.getUID() > 0) { - out.println("<script type=\"text/javascript\">"); - out.println("var hash=\"" + visitor.getAuthHash() + "\";"); - out.println("</script>"); - } - out.println("<script>"); out.println("(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){"); out.println("(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),"); @@ -442,7 +439,7 @@ public class PageTemplates { out.println(" <header class=\"t\"><a href=\"/" + msg.getUser().getUName() + "/" + msg.getMID() + "\"><time datetime=\"" + sdfSQL.format(msg.getDate()) + "Z\" title=\"" + sdfSQL.format(msg.getDate()) + " GMT\">" + formatDate(msg.TimeAgo, msg.getDate()) + "</time></a></header>"); if (msg.AttachmentType != null) { String fname = msg.getMID() + "." + msg.AttachmentType; - out.println(" <p class=\"ir\"><a href=\"//i.juick.com/photos-512/" + fname + "\" onclick=\"return showPhotoDialog('" + fname + "')\"><img src=\"//i.juick.com/photos-512/" + fname + "\" alt=\"\"/></a></p>"); + out.println(" <p class=\"ir\"><a href=\"//i.juick.com/photos-512/" + fname + "\" data-fname=\"" + fname + "\"><img src=\"//i.juick.com/photos-512/" + fname + "\" alt=\"\"/></a></p>"); } out.println(" <p>" + txt + "</p>"); if (msg.AttachmentType != null) { @@ -450,19 +447,23 @@ public class PageTemplates { } out.print(" <nav class=\"l\">"); msg.ReadOnly |= blUIDs.contains(msg.getUser().getUID()); - out.print("<a href=\"#\" onclick=\"return likeMessage(this," + msg.getMID() + ")\">Мне нравится</a>"); + if (visitor.getUID() == 0) { + out.print("<a href=\"#\" class=\"a-login\">Мне нравится</a>"); + } else { + out.print("<a href=\"/post?body=!+%23" + msg.getMID() + "\" class=\"a-like\">Мне нравится</a>"); + } if (visitor.getUID() == 0 && !msg.ReadOnly) { - out.print("<a href=\"#\" onclick=\"return openDialogLogin()\">Комментировать</a> "); + out.print("<a href=\"/"+ msg.getMID() + "\" class=\"a-login\">Комментировать</a> "); } else if (visitor.getUID() > 0 && (!msg.ReadOnly || visitor.getUID() == msg.getUser().getUID())) { - out.print("<a href=\"#\" onclick=\"return showCommentFooter(this)\">Комментировать</a> "); + out.print("<a class=\"a-comment\" href=\"/" + msg.getMID() + "\">Комментировать</a> "); } if (visitor.getUID() > 0 && msg.Privacy < 0 && msg.getUser().getUID() == visitor.getUID()) { - out.print(" <a href=\"#\" onclick=\"return setPrivacy(this," + msg.getMID() + ")\">Открыть доступ</a>"); + out.print(" <a href=\"#\" class=\"a-privacy\">Открыть доступ</a>"); } if (visitor.getUID() > 0 && visitor.getUID() == 3694) { - out.print(" <a href=\"#\" onclick=\"return setPopular(this," + msg.getMID() + ",2)\">+</a>"); - out.print(" <a href=\"#\" onclick=\"return setPopular(this," + msg.getMID() + ",-1)\">-</a>"); - out.print(" <a href=\"#\" onclick=\"return setPopular(this," + msg.getMID() + ",-2)\">x</a>"); + out.print(" <a href=\"#\" class=\"a-popular-plus\">+</a>"); + out.print(" <a href=\"#\" class=\"a-popular-minus\">-</a>"); + out.print(" <a href=\"#\" class=\"a-popular-delete\">x</a>"); } out.println("</nav>"); diff --git a/juick-www/src/main/java/com/juick/www/Settings.java b/juick-www/src/main/java/com/juick/www/Settings.java index af1591bf..6364c869 100644 --- a/juick-www/src/main/java/com/juick/www/Settings.java +++ b/juick-www/src/main/java/com/juick/www/Settings.java @@ -37,7 +37,7 @@ public class Settings { response.setContentType("text/html; charset=UTF-8"); try (PrintWriter out = response.getWriter()) { - PageTemplates.pageHead(out, "Логин", ""); + PageTemplates.pageHead(out, visitor, "Логин", ""); PageTemplates.pageNavigation(out, visitor, null); out.println("<div id=\"topwrapper\">"); diff --git a/juick-www/src/main/java/com/juick/www/SignUp.java b/juick-www/src/main/java/com/juick/www/SignUp.java index 7dbfb6dc..865fc453 100644 --- a/juick-www/src/main/java/com/juick/www/SignUp.java +++ b/juick-www/src/main/java/com/juick/www/SignUp.java @@ -63,7 +63,7 @@ public class SignUp { response.setContentType("text/html; charset=UTF-8"); try (PrintWriter out = response.getWriter()) { - PageTemplates.pageHead(out, "Новый пользователь", null); + PageTemplates.pageHead(out, visitor, "Новый пользователь", null); PageTemplates.pageNavigation(out, visitor, null); out.println("<section id=\"content\">"); @@ -101,7 +101,7 @@ public class SignUp { out.println("<input type=\"hidden\" name=\"action\" value=\"new\"/>"); out.println("<input type=\"hidden\" name=\"type\" value=\"" + type + "\"/>"); out.println("<input type=\"hidden\" name=\"hash\" value=\"" + hash + "\"/>"); - out.println("<p>Имя пользователя: <input type=\"text\" name=\"username\" id=\"username\" onblur=\"checkUsername()\"/><br/><i>(От 2-х до 16-и латинских символов и/или цифр, дефис)</i></p>"); + out.println("<p>Имя пользователя: <input type=\"text\" name=\"username\" id=\"username\"/><br/><i>(От 2-х до 16-и латинских символов и/или цифр, дефис)</i></p>"); out.println("<p>Пароль: <input type=\"password\" name=\"password\"/><br/><i>(от 6-и до 32-х символов)</i></p>"); out.println("<p><input type=\"submit\" value=\" OK \"/></p>"); out.println("</form>"); diff --git a/juick-www/src/main/java/com/juick/www/User.java b/juick-www/src/main/java/com/juick/www/User.java index 0d0056ad..1c23864e 100644 --- a/juick-www/src/main/java/com/juick/www/User.java +++ b/juick-www/src/main/java/com/juick/www/User.java @@ -121,7 +121,7 @@ public class User { } else if (paramBefore > 0 || paramShow != null) { head += "<meta name=\"robots\" content=\"noindex\"/>"; } - PageTemplates.pageHead(out, title, head); + PageTemplates.pageHead(out, visitor, title, head); PageTemplates.pageNavigation(out, visitor, null); pageUserColumn(out, sql, user, visitor); @@ -168,7 +168,7 @@ public class User { response.setContentType("text/html; charset=UTF-8"); try (PrintWriter out = response.getWriter()) { String head = "<meta name=\"robots\" content=\"noindex,nofollow\"/>"; - PageTemplates.pageHead(out, "Теги " + user.getUName(), head); + PageTemplates.pageHead(out, visitor, "Теги " + user.getUName(), head); PageTemplates.pageNavigation(out, visitor, null); pageUserColumn(out, sql, user, visitor); @@ -191,7 +191,7 @@ public class User { response.setContentType("text/html; charset=UTF-8"); try (PrintWriter out = response.getWriter()) { String head = "<meta name=\"robots\" content=\"noindex\"/>"; - PageTemplates.pageHead(out, "Подписки " + user.getUName(), head); + PageTemplates.pageHead(out, visitor, "Подписки " + user.getUName(), head); PageTemplates.pageNavigation(out, visitor, null); pageUserColumn(out, sql, user, visitor); @@ -226,7 +226,7 @@ public class User { response.setContentType("text/html; charset=UTF-8"); try (PrintWriter out = response.getWriter()) { String head = "<meta name=\"robots\" content=\"noindex\"/>"; - PageTemplates.pageHead(out, "Читатели " + user.getUName(), head); + PageTemplates.pageHead(out, visitor, "Читатели " + user.getUName(), head); PageTemplates.pageNavigation(out, visitor, null); pageUserColumn(out, sql, user, visitor); diff --git a/juick-www/src/main/java/com/juick/www/UserThread.java b/juick-www/src/main/java/com/juick/www/UserThread.java index e3eb7186..d7193bc4 100644 --- a/juick-www/src/main/java/com/juick/www/UserThread.java +++ b/juick-www/src/main/java/com/juick/www/UserThread.java @@ -77,21 +77,16 @@ public class UserThread { if (msg.Hidden) { headers += "<meta name=\"robots\" content=\"noindex\"/>"; } - PageTemplates.pageHead(out, title, headers); + PageTemplates.pageHead(out, visitor, title, headers); PageTemplates.pageNavigation(out, visitor, null); - out.println("<section id=\"content\" style=\"margin-left: 0; width: 100%\">"); + out.println("<section id=\"content\" data-mid=\"" + msg.getMID() + "\" style=\"margin-left: 0; width: 100%\">"); printMessage(out, sql, msg, visitor); printReplies(out, sql, msg, visitor, listview); out.println("</section>"); PageTemplates.pageFooter(request, out, visitor, false); - out.println("<script type='text/javascript'>"); - out.println("var pageMID=" + msg.getMID() + ";"); - out.println("initWS();"); - out.println("</script>"); - PageTemplates.pageEnd(out); } } @@ -121,10 +116,10 @@ public class UserThread { } out.println("<ul>"); - out.println(" <li id=\"msg-" + msg.getMID() + "\" class=\"msg msgthread\">"); + out.println(" <li id=\"msg-" + msg.getMID() + "\" data-mid=\"" + msg.getMID() + "\" class=\"msg msgthread\">"); out.println(" <div class=\"msg-avatar\"><a href=\"/" + msg.getUser().getUName() + "/\"><img src=\"//i.juick.com/a/" + msg.getUser().getUID() + ".png\" alt=\"" + msg.getUser().getUName() + "\"/></a></div>"); out.println(" <div class=\"msg-cont\">"); - out.println(" <div class=\"msg-menu\"><a href=\"#\" onclick=\"showMessageLinksDialog(" + msg.getMID() + "); return false\"></a></div>"); + out.println(" <div class=\"msg-menu\"><a href=\"#\"></a></div>"); out.println(" <div class=\"msg-header\"><a href=\"/" + msg.getUser().getUName() + "/\">@" + msg.getUser().getUName() + "</a>:" + tagsStr + "</div>"); out.println(" <div class=\"msg-ts\">" + PageTemplates.formatJSLocalTime(msg.getDate()) + "</div>"); out.println(" <div class=\"msg-txt\">" + txt + "</div>"); @@ -243,7 +238,7 @@ public class UserThread { out.print("<a href=\"?view=tree\" rel=\"nofollow\">Показать деревом</a>"); } else { if (foldable) { - out.print("<span id=\"unfoldall\"><a href=\"#\" onclick=\"$('#replies>li').show(); $('#replies .msg-comments').hide(); $('#unfoldall').hide(); return false\">Раскрыть все</a> · </span>"); + out.print("<span id=\"unfoldall\"><a href=\"#\">Раскрыть все</a> · </span>"); } out.print("<a href=\"?view=list\" rel=\"nofollow\">Показать списком</a>"); } @@ -289,7 +284,7 @@ public class UserThread { out.println(" <div class=\"msg-avatar\"><img src=\"//i.juick.com/av-96.png\"/></div>"); } out.println(" <div class=\"msg-cont\">"); - out.println(" <div class=\"msg-menu\"><a href=\"#\" onclick=\"showMessageLinksDialog(" + msg.getMID() + "," + msg.getRID() + "); return false\"></a></div>"); + out.println(" <div class=\"msg-menu\"><a href=\"#\" class=\"a-thread-links\"></a></div>"); if (!msg.getUser().Banned) { out.println(" <div class=\"msg-header\"><a href=\"/" + msg.getUser().getUName() + "/\">@" + msg.getUser().getUName() + "</a>:</div>"); } else { @@ -301,16 +296,15 @@ public class UserThread { out.println(" <div class=\"msg-media\"><a href=\"//i.juick.com/p/" + msg.getMID() + "-" + msg.getRID() + "." + msg.AttachmentType + "\"><img src=\"//i.juick.com/photos-512/" + msg.getMID() + "-" + msg.getRID() + "." + msg.AttachmentType + "\" alt=\"\"/></a></div>"); } if (msg.VisitorCanComment) { - out.println(" <div class=\"msg-links\"><a href=\"#\" onclick=\"return showCommentForm(" + msg.getMID() + "," + msg.getRID() + ")\">Ответить</a></div>"); + out.println(" <div class=\"msg-links\"><a href=\"/post?body=%23" + msg.getMID() + "/" + msg.getRID() + "%20\" class=\"a-thread-comment\">Ответить</a></div>"); out.println(" <div class=\"msg-comment\" style=\"display: none\"></div>"); } else if (visitor == null) { - out.println(" <div class=\"msg-links\"><a href=\"#\" onclick=\"return openDialogLogin()\">Ответить</a></div>"); + out.println(" <div class=\"msg-links\"><a href=\"#\" class=\"a-login\">Ответить</a></div>"); } int childs = msg.getChildsCount(); if (ReplyTo == 0 && childs > 1 && replies.size() > 10) { - out.println(" <div class=\"msg-comments\"><a href=\"#\" onclick=\"return showMoreReplies(" + msg.getRID() + ")\">" + PageTemplates.formatReplies(childs) + "</a></div>"); - + out.println(" <div class=\"msg-comments\"><a href=\"#\" class=\"a-thread-comment\">" + PageTemplates.formatReplies(childs) + "</a></div>"); } out.println(" </div>"); out.println(" </li>"); @@ -333,7 +327,7 @@ public class UserThread { out.println(" <div class=\"msg-avatar\"><img src=\"//i.juick.com/av-96.png\"/></div>"); } out.println(" <div class=\"msg-cont\">"); - out.println(" <div class=\"msg-menu\"><a href=\"#\" onclick=\"showMessageLinksDialog(" + msg.getMID() + "," + msg.getRID() + "); return false\"></a></div>"); + out.println(" <div class=\"msg-menu\"><a href=\"#\" class=\"a-thread-links\"></a></div>"); if (!msg.getUser().Banned) { out.println(" <div class=\"msg-header\"><a href=\"/" + msg.getUser().getUName() + "/\">@" + msg.getUser().getUName() + "</a>:</div>"); } else { @@ -349,10 +343,10 @@ public class UserThread { out.print(" в ответ на <a href=\"#" + msg.ReplyTo + "\">/" + msg.ReplyTo + "</a>"); } if (msg.VisitorCanComment) { - out.println(" · <a href=\"#\" onclick=\"return showCommentForm(" + msg.getMID() + "," + msg.getRID() + ")\">Ответить</a></div>"); + out.println(" · <a href=\"#\" class=\"a-thread-comment\">Ответить</a></div>"); out.println(" <div class=\"msg-comment\" style=\"display: none\"></div>"); } else if (visitor.getUID() == 0) { - out.println(" <div class=\"msg-links\"><a href=\"#\" onclick=\"return openDialogLogin()\">Ответить</a></div>"); + out.println(" <div class=\"msg-links\"><a href=\"/post?body=%23" + msg.getMID() + "/" + msg.getRID() + "%20\" class=\"a-thread-comment\">Ответить</a></div>"); } out.println(" </div>"); out.println(" </li>"); diff --git a/juick-www/src/main/java/ru/sape/SapePageLinks.java b/juick-www/src/main/java/ru/sape/SapePageLinks.java index 498aeac0..458358b8 100644 --- a/juick-www/src/main/java/ru/sape/SapePageLinks.java +++ b/juick-www/src/main/java/ru/sape/SapePageLinks.java @@ -1,10 +1,6 @@ package ru.sape; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; -import java.util.Map; +import java.util.*; import javax.servlet.http.Cookie; public class SapePageLinks { @@ -28,7 +24,7 @@ public class SapePageLinks { } if (data.containsKey(requestUri)) { - pageLinks = new ArrayList<String>(((Map<Object, String>) data.get(requestUri)).values()); + pageLinks = new ArrayList<>(((Map<Object, String>) data.get(requestUri)).values()); } if (data.containsKey("__sape_new_url__")) { @@ -36,9 +32,9 @@ public class SapePageLinks { Object newUrl = data.get("__sape_new_url__"); if (newUrl instanceof Map) { - pageLinks = new ArrayList<String>(((Map<Object, String>) newUrl).values()); + pageLinks = new ArrayList<>(((Map<Object, String>) newUrl).values()); } else { - pageLinks = new ArrayList<String>(Arrays.asList((String) newUrl)); + pageLinks = new ArrayList<>(Collections.singletonList((String) newUrl)); } } } @@ -46,7 +42,7 @@ public class SapePageLinks { this.showCode = showCode; } private String linkDelimiter = "."; - private List<String> pageLinks = new ArrayList<String>(); + private List<String> pageLinks = new ArrayList<>(); public String render() { return render(-1); diff --git a/juick-www/src/main/static/scripts.js b/juick-www/src/main/static/scripts.js index 93594f71..0785325a 100644 --- a/juick-www/src/main/static/scripts.js +++ b/juick-www/src/main/static/scripts.js @@ -1,122 +1,189 @@ -var ws=null; +var autosize = require('autosize'); +require('whatwg-fetch'); +require('element-closest'); + +NodeList.prototype.forEach = Array.prototype.forEach; +HTMLCollection.prototype.forEach = Array.prototype.forEach; + +var ws = null; var pageTitle; function initWS() { - if(typeof(pageMID)!="undefined" && pageMID>0) { - var url; - var protocolPrefix = (window.location.protocol === 'https:') ? 'wss:' : 'ws:'; - if(typeof(juickDebug)!="undefined") { - url= protocolPrefix + "//ws.juick.com/_replies"; - } else { - url= protocolPrefix + "//ws.juick.com/"+pageMID; - } - if(typeof(hash)!="undefined" && hash) { - url+="?hash="+hash; + var content = document.getElementById('content'); + if (!content) { return } + var pageMID = content.getAttribute('data-mid'); + if (!pageMID) { return } + var url; + var protocolPrefix = (window.location.protocol === 'https:') ? 'wss:' : 'ws:'; + if (typeof (juickDebug) != 'undefined') { + url = protocolPrefix + '//ws.juick.com/_replies'; + } else { + url = protocolPrefix + '//ws.juick.com/' + pageMID; + } + var hash = document.getElementById('body').getAttribute('data-hash'); + if (typeof (hash) != 'undefined' && hash) { + url += '?hash=' + hash; + } + + ws = new WebSocket(url); + ws.onopen = function () { + console.log('online'); + if (!document.querySelector('#wsthread')) { + var d = document.createElement('div'); + d.id = 'wsthread'; + d.addEventListener('click', onclickNextReply); + document.querySelector('body').appendChild(d); + pageTitle = document.title; } - - ws = new WebSocket(url); - ws.onopen = function() { - console.log('online'); - if($('#wsthread').length==0) { - var d=$('<div id="wsthread"/>'); - d.on('click',onclickNextReply); - d.appendTo("body"); - pageTitle=document.title; - } - }; - ws.onclose = function() { - console.log('offline'); - ws=null; - setTimeout(function() { - initWS(); - },2000); - }; - ws.onmessage = function(msg) { - if(msg.data==' ') { - ws.send(' '); - } else { - try { - var jsonMsg=$.parseJSON(msg.data); - console.log('data: '+msg.data); - wsIncomingReply(jsonMsg); - } catch(err) { - console.log(err); - } + }; + ws.onclose = function () { + console.log('offline'); + ws = null; + setTimeout(function () { + initWS(); + }, 2000); + }; + ws.onmessage = function (msg) { + if (msg.data == ' ') { + ws.send(' '); + } else { + try { + var jsonMsg = JSON.parse(msg.data); + console.log('data: ' + msg.data); + wsIncomingReply(jsonMsg); + } catch (err) { + console.log(err); } - }; - setInterval(wsSendKeepAlive, 90000); - } + } + }; + setInterval(wsSendKeepAlive, 90000); } function wsSendKeepAlive() { - if(ws) { + if (ws) { ws.send(' '); } } function wsShutdown() { - if(ws) { - ws.onclose=function(){}; + if (ws) { + ws.onclose = function () { }; ws.close(); } } function wsIncomingReply(msg) { var p; - if(msg.replyto>0) { - p=$('#'+msg.replyto); - if(p.length==0) { - p=null; - } + if (msg.replyto > 0) { + p = document.getElementById(msg.replyto); } - - var li=$('<li class="msg reply-new" id="'+msg.rid+'" onclick="onclickNewReply(this)" onmouseover="onclickNewReply(this)">'); - li.html('<div class="msg-avatar"><a href="/'+msg.user.uname+'/"><img src="//i.juick.com/a/'+msg.user.uid+'.png"/></a></div>'+ - '<div class="msg-cont">'+ - '<div class="msg-menu"><a href="#" onclick="showMessageLinksDialog('+msg.mid+','+msg.rid+'); return false"></a></div>'+ - '<div class="msg-header"><a href="/'+msg.user.uname+'/">@'+msg.user.uname+'</a>:</div>'+ - '<div class="msg-ts"><a href="/'+msg.mid+'#'+msg.rid+'" title="'+msg.timestamp+' GMT">'+msg.timestamp+'</a></div>'+ - '<div class="msg-txt"></div>'+ - '<div class="msg-links"><a href="#" onclick="return showCommentForm('+msg.mid+','+msg.rid+')">Ответить</a></div>'+ - '<div class="msg-comment" style="display: none"></div>'+ - '</div>'); - $(li).find('.msg-txt').text(msg.body); - if(p) { - li.css('margin-left',parseInt(p.css('margin-left'))+20+'px'); - p.after(li); + var li = document.createElement('li'); + li.setAttribute('class', 'msg reply-new'); + li.setAttribute('id', msg.rid); + li.addEventListener('click', function (e) { + onclickNewReply(this); + e.preventDefault(); + }); + li.addEventListener('mouseover', function (e) { + onclickNewReply(this); + e.preventDefault(); + }); + var msgAvatar = document.createElement('div'); + msgAvatar.setAttribute('class', 'msg-avatar'); + var msgAvatarLink = document.createElement('a'); + msgAvatarLink.setAttribute('href', '/' + msg.user.uname + '/'); + var msgAvatarImg = document.createElement('img'); + msgAvatarImg.setAttribute('src', '//i.juick.com/a/' + msg.user.uid + '.png'); + msgAvatarLink.appendChild(msgAvatarImg); + msgAvatar.appendChild(msgAvatarLink); + li.appendChild(msgAvatar); + var msgCont = document.createElement('div'); + msgCont.setAttribute('class', 'msg-cont'); + var msgMenu = document.createElement('div'); + msgMenu.setAttribute('class', 'msg-menu'); + msgCont.appendChild(msgMenu); + var msgMenuLink = document.createElement('a'); + msgMenuLink.setAttribute('href', '#'); + msgMenuLink.addEventListener('click', function (e) { + showMessageLinksDialog(msg.mid, msg.rid); + e.preventDefault(); + }); + msgMenu.appendChild(msgMenuLink); + var msgHeader = document.createElement('div'); + msgHeader.setAttribute('class', 'msg-header'); + var msgHeaderLink = document.createElement('a'); + msgHeaderLink.setAttribute('href', '/' + msg.user.uname + '/'); + msgHeaderLink.textContent = '@' + msg.user.uname; + msgHeader.appendChild(msgHeaderLink); + msgHeader.textContent = msgHeaderLink.textContent + ':'; + var msgTimestamp = document.createElement('div'); + msgTimestamp.setAttribute('class', 'msg-ts'); + var msgTimestampLink = document.createElement('a'); + msgTimestampLink.setAttribute('href', '/' + msg.mid + '#' + msg.rid); + msgTimestampLink.setAttribute('title', msg.timestamp + ' GMT'); + msgTimestampLink.textContent = msg.timestamp; + msgTimestamp.appendChild(msgTimestampLink); + var msgTxt = document.createElement('div'); + msgTxt.setAttribute('class', 'msg-txt'); + var msgLinks = document.createElement('div'); + msgLinks.setAttribute('class', 'msg-links'); + var msgLinksLink = document.createElement('a'); + msgLinksLink.setAttribute('href', '#'); + msgLinksLink.textContent = 'Ответить'; + msgLinksLink.addEventListener('click', function (e) { + showCommentForm(msg.mid, msg.rid); + e.preventDefault(); + }); + msgLinks.appendChild(msgLinksLink); + var msgComment = document.createElement('div'); + msgComment.setAttribute('class', 'msg-comment'); + msgComment.style.display = 'none'; + msgCont.appendChild(msgMenu); + msgCont.appendChild(msgHeader); + msgCont.appendChild(msgTimestamp); + msgCont.appendChild(msgTxt); + msgCont.appendChild(msgLinks); + msgCont.appendChild(msgComment); + li.appendChild(msgCont); + li.querySelector('.msg-txt').textContent = msg.body; + if (p) { + li.style.marginLeft = p.style.marginLeft + '20px'; + p.parentNode.insertBefore(li, p.nextSibling); } else { - $('#replies').append(li); + document.querySelector('#replies').appendChild(li); } - + updateRepliesCounter(); } -function onclickNewReply(e) { - var li=$(e); - li.removeClass('reply-new'); - li.off('click'); - li.off('mouseover'); +function onclickNewReply(el) { + var li = el; + li.classList.remove('reply-new'); + li.removeEventListener('click'); + li.removeEventListener('mouseover'); updateRepliesCounter(); } function onclickNextReply() { - var li=$('#replies>li.reply-new:first'); - if(li.length) { - li.removeClass('reply-new'); - li.off('click'); - li.get(0).scrollIntoView(); + var li = document.querySelector('#replies>li.reply-new:first'); + if (li.length) { + li.classList.remove('reply-new'); + li.removeEventListener('click'); + li.childNodes[0].scrollIntoView(); updateRepliesCounter(); } } function updateRepliesCounter() { - var replies=$('#replies>li.reply-new').length; - if(replies>0) { - $('#wsthread').text(replies).css('display','block'); - document.title='['+replies+'] '+pageTitle; + var replies = document.querySelectorAll('#replies>li.reply-new').length; + if (replies > 0) { + var wsthread = document.querySelector('#wsthread'); + wsthread.textContent = replies; + wsthread.style.display = 'block'; + document.title = '[' + replies + '] ' + pageTitle; } else { - $('#wsthread').css('display','none'); - document.title=pageTitle; + document.querySelector('#wsthread').style.display = 'none'; + document.title = pageTitle; } } @@ -124,561 +191,501 @@ function updateRepliesCounter() { /******************************************************************************/ /******************************************************************************/ -function postformListener(formEl,ev) { - if(ev.ctrlKey && (ev.keyCode==10 || ev.keyCode==13)) { - if(!formEl.onsubmit || formEl.onsubmit()) { - formEl.submit(); +function postformListener(formEl, ev) { + var form = formEl.closest('form'); + if (ev.ctrlKey && (ev.keyCode == 10 || ev.keyCode == 13)) { + if (!form.onsubmit || form.onsubmit()) { + form.submit(); } } } function unfoldPostForm() { - if(window.location.pathname==="/" && window.location.hash==="#post") { - $('#newmessage>div').css('display','block'); - $('#newmessage textarea').css('min-height','70px'); - $('#newmessage textarea')[0].focus(); + if (window.location.pathname === '/' && window.location.hash === '#post') { + document.querySelector('#newmessage>div').style.display = 'block'; + document.querySelector('#newmessage textarea').style.minHeight = '70px'; + document.querySelector('#newmessage textarea').focus(); } } function onsubmitNewMessage() { - if($('#newmessage textarea').val().length==0) { + if (document.querySelector('#newmessage textarea').value.length == 0) { openDialog('<p class="dialogtxt">Пожалуйста, введите текст сообщения</p>'); return false; } return true; } -function showMoreReplies(id) { - $('#'+id+' .msg-comments').hide(); +function showMoreReplies(el, id) { + el.closest('li').querySelector('.msg-comments').style.display = 'none'; - var replies=$('#replies>li'); - var flagshow=0; - for(var i=0; i<replies.length; i++) { - if(flagshow==1) { - if(replies[i].style.display=="none") { - replies[i].style.display="block"; + var replies = document.querySelectorAll('#replies>li'); + var flagshow = 0; + for (var i = 0; i < replies.length; i++) { + if (flagshow == 1) { + if (replies[i].style.display == 'none') { + replies[i].style.display = 'block'; } else { break; } } - if(replies[i].id==id) { - flagshow=1; + if (replies[i].id == id) { + flagshow = 1; } } return false; } -function showCommentForm(mid,rid) { - if($('#replies #'+rid+' textarea').length==0) { - var c=$('#replies #'+rid+' .msg-comment'); - c.wrap('<form action="/comment" method="POST" enctype="multipart/form-data"/>'); - c.before('<input type="hidden" name="mid" value="'+mid+'"/><input type="hidden" name="rid" value="'+rid+'"/>'); - c.append('<div class="ta-wrapper"><textarea name="body" rows="1" class="reply narrow" placeholder="Add a comment..." onkeypress="postformListener(this.form,event)"></textarea><div class="attach-photo" onclick="attachCommentPhoto(this)"/></div><input type="submit" value="OK"/>'); +function replyForm(mid, rid) { + var form = document.createElement('form'); + form.setAttribute('action', '/comment'); + form.setAttribute('method', 'POST'); + form.setAttribute('enctype', 'multipart/form-data'); + var input = document.createElement('input'); + input.setAttribute('type', 'hidden'); + input.setAttribute('name', 'mid'); + input.setAttribute('value', mid); + form.appendChild(input); + if (rid) { + var inputRid = document.createElement('input'); + inputRid.setAttribute('type', 'hidden'); + inputRid.setAttribute('name', 'rid'); + inputRid.setAttribute('value', rid); + form.appendChild(inputRid); } - // $('#replies #'+rid+' .msg-links').hide(); - $('#replies #'+rid+' .msg-comment').show(); - $('#replies #'+rid+' textarea')[0].focus(); - $('#replies #'+rid+' textarea').autoResize({ - extraSpace: 0, - minHeight: 1 - }); - return false; + return form; } -function showCommentFooter(e) { - var a=$(e).closest("article"); - if(a.find("footer.comm").length==0) { - a.append('<form action="/comment" method="POST" enctype="multipart/form-data"><input type="hidden" name="mid" value="'+a.data('mid')+'"/><footer class="comm"><div class="ta-wrapper"><textarea name="body" rows="1" class="reply narrow" placeholder="Написать комментарий..." onkeypress="postformListener(this.form,event)"></textarea><div class="attach-photo" onclick="attachCommentPhoto(this)"/></div><input type="submit" value="OK"/></footer></form>'); - a.find('textarea').autoResize({ - extraSpace: 0, - minHeight: 1 - }); +function taWrapper() { + var txtarea = document.createElement('textarea'); + txtarea.setAttribute('name', 'body'); + txtarea.setAttribute('rows', 1); + txtarea.setAttribute('class', 'reply narrow'); + txtarea.setAttribute('placeholder', 'Написать комментарий...'); + var txtKeypress = function (e) { + postformListener(e.target, e); + + }; + txtarea.addEventListener('keypress', txtKeypress); + var wrapper = document.createElement('div'); + wrapper.setAttribute('class', 'ta-wrapper'); + wrapper.appendChild(txtarea); + var att = document.createElement('div'); + att.setAttribute('class', 'attach-photo'); + var attClick = function () { + attachCommentPhoto(this); + }; + att.addEventListener('click', attClick); + wrapper.appendChild(att); + return wrapper; +} + +function showCommentForm(mid, rid) { + var reply = document.getElementById(rid); + if (reply && !reply.querySelector('textarea')) { + var c = reply.querySelector('div.msg-cont > .msg-comment'); + var newNode = c.cloneNode(true); + var form = replyForm(mid, rid); + form.appendChild(newNode); + newNode.appendChild(taWrapper()); + var subm = document.createElement('input'); + subm.setAttribute('type', 'submit'); + subm.setAttribute('value', 'OK'); + newNode.appendChild(subm); + c.parentNode.insertBefore(form, c); + c.remove(); } - a.find('textarea')[0].focus(); - return false; + var commentBlock = reply.querySelector('div.msg-cont > form > div.msg-comment'); + commentBlock.style.display = 'block'; + var commentText = commentBlock.querySelector('textarea'); + if (commentText) { + autosize(commentText); + commentText.focus(); + } +} + +function showCommentFooter(e, mid, rid) { + var a = e.closest('article'); + if (!a.querySelector('footer.comm')) { + var form = replyForm(mid, rid); + var footer = document.createElement('footer'); + footer.setAttribute('class', 'comm'); + footer.appendChild(taWrapper()); + var subm = document.createElement('input'); + subm.setAttribute('type', 'submit'); + subm.setAttribute('value', 'OK'); + footer.appendChild(subm); + form.appendChild(footer); + a.appendChild(form); + autosize(a.querySelector('textarea')); + } + a.querySelector('textarea').focus(); +} + +function attachInput() { + var inp = document.createElement('input'); + inp.setAttribute('type', 'file'); + inp.setAttribute('name', 'attach'); + inp.setAttribute('accept', 'image/jpeg,image/png'); + inp.style.visibility = 'hidden'; + return inp; } function attachCommentPhoto(div) { - if($(div).children().length===0) { - var inp=$('<input type="file" name="attach" accept="image/jpeg,image/png" style="visibility: hidden"/>'); - inp.on('change',function() { - $(this).parent().attr('class','attach-photo-active'); + if (div.children.length === 0) { + var inp = attachInput(); + inp.addEventListener('change', function () { + inp.parentNode.classList.add('attach-photo-active'); }); - inp.trigger('click'); - $(div).append(inp); + inp.click(); + div.appendChild(inp); } else { - $(div).empty(); - $(div).attr('class','attach-photo'); + div.innerHTML = null; + div.classList.add('attach-photo'); } } function attachMessagePhoto(div) { - var f=$(div).closest('form'); - if(f.find('input:file').length===0) { - var inp=$('<input type="file" name="attach" accept="image/jpeg,image/png" style="float: left; width: 0; height: 0; visibility: hidden"/>'); - inp.on('change',function() { - $(div).text("загрузить (✓)"); + var f = div.closest('form'); + var finput = f.querySelector('input[type="file"]'); + if (!finput) { + var inp = attachInput(); + inp.style.float = 'left'; + inp.style.width = 0; + inp.style.height = 0; + inp.addEventListener('change', function () { + div.textContent = 'загрузить (✓)'; }); - f.append(inp); - inp.trigger('click'); + f.appendChild(inp); + inp.click(); } else { - f.find('input:file').remove(); - $(div).text("загрузить"); + finput.remove(); + div.textContent = 'загрузить'; } } function unfoldReply() { - if((0+window.location.hash.substring(1))>0) { - var el=$(window.location.hash); - while(el.is(":hidden")) { - el=el.prev(); + if ((0 + window.location.hash.substring(1)) > 0) { + var el = window.location.hash; + while (el.matches('[type="hidden"]')) { + el = el.previousSibling(); } - showMoreReplies(el.attr('id')); + showMoreReplies(el.getAttribute('id')); window.location.replace(window.location.hash); } } -function showMessageLinksDialog(mid,rid) { - var hlink=window.location.protocol+"//juick.com/"+mid; - var mlink="#"+mid; - if(rid>0) { - hlink+="#"+rid; - mlink+="/"+rid; +function showMessageLinksDialog(mid, rid) { + var hlink = window.location.protocol + '//juick.com/' + mid; + var mlink = '#' + mid; + if (rid > 0) { + hlink += '#' + rid; + mlink += '/' + rid; } - var hlinkenc=encodeURIComponent(hlink); - - var html="<div class=\"dialogshare\">Ссылка на сообщение:"; - html+="<div onclick=\"$(this).selectText()\" class=\"dialogl\">"+hlink+"</div>"; - html+="Номер сообщения:"; - html+="<div onclick=\"$(this).selectText()\" class=\"dialogl\">"+mlink+"</div>"; - html+="Поделиться:<ul>"; - html+="<li><a href=\"https://www.facebook.com/sharer/sharer.php?u="+hlinkenc+"\" onclick=\"return openSocialWindow(this)\"></a></li>"; - html+="<li><a href=\"https://twitter.com/intent/tweet?url="+hlinkenc+"\" onclick=\"return openSocialWindow(this)\" style=\"background-position: -32px 0;\"></a></li>"; - html+="<li><a href=\"https://vk.com/share.php?url="+hlinkenc+"\" onclick=\"return openSocialWindow(this)\" style=\"background-position: -64px 0;\"></a></li>"; - html+="<li><a href=\"https://plus.google.com/share?url="+hlinkenc+"\" onclick=\"return openSocialWindow(this)\" style=\"background-position: -96px 0;\"></a></li>"; - html+="</ul></div>"; + var hlinkenc = encodeURIComponent(hlink); + + var html = '<div class="dialogshare">Ссылка на сообщение:'; + html += '<div onclick="this.selectText()" class="dialogl">' + hlink + '</div>'; + html += 'Номер сообщения:'; + html += '<div onclick="this.selectText()" class="dialogl">' + mlink + '</div>'; + html += 'Поделиться:<ul>'; + html += '<li><a href="https://www.facebook.com/sharer/sharer.php?u=' + hlinkenc + '" onclick="return openSocialWindow(this)"></a></li>'; + html += '<li><a href="https://twitter.com/intent/tweet?url=' + hlinkenc + '" onclick="return openSocialWindow(this)" style="background-position: -32px 0;"></a></li>'; + html += '<li><a href="https://vk.com/share.php?url=' + hlinkenc + '" onclick="return openSocialWindow(this)" style="background-position: -64px 0;"></a></li>'; + html += '<li><a href="https://plus.google.com/share?url=' + hlinkenc + '" onclick="return openSocialWindow(this)" style="background-position: -96px 0;"></a></li>'; + html += '</ul></div>'; openDialog(html); } function showPhotoDialog(fname) { - var width=$(window).width(); - var height=$(window).height()*0.9; - if(width<640) { + var width = window.width; + var height = window.height * 0.9; + if (width < 640) { return true; - } else if(width<1280) { - openDialog("<a href=\"//i.juick.com/photos-1024/"+fname+"\"><img src=\"//i.juick.com/photos-512/"+fname+"\"/></a>"); - $('#dialogw img').css('max-height',height+'px'); + } else if (width < 1280) { + openDialog('<a href="//i.juick.com/photos-1024/' + fname + '"><img src="//i.juick.com/photos-512/' + fname + '"/></a>'); + document.querySelector('#dialogw img').style.maxHeight = height + 'px'; return false; } else { - openDialog("<a href=\"//i.juick.com/p/"+fname+"\"><img src=\"//i.juick.com/photos-1024/"+fname+"\"/></a>"); - $('#dialogw img').css('max-height',height+'px'); + openDialog('<a href="//i.juick.com/p/' + fname + '"><img src="//i.juick.com/photos-1024/' + fname + '"/></a>'); + document.querySelector('#dialogw img').style.maxHeight = height + 'px'; return false; } } function openDialog(html) { - var dhtml="<table id=\"dialogt\"><tr><td><div id=\"dialogb\" onclick=\"closeDialog()\"></div><div id=\"dialogw\"><div id=\"dialogc\" onclick=\"closeDialog()\"></div>"; - dhtml+=html; - dhtml+="</div></td></tr></table>"; - $('body').append(dhtml); + var dhtml = '<table id="dialogt"><tr><td><div id="dialogb"></div><div id="dialogw"><div id="dialogc"></div>'; + dhtml += html; + dhtml += '</div></td></tr></table>'; + document.querySelector('body').insertAdjacentHTML('afterbegin', dhtml); + document.querySelector('#dialogb').addEventListener('click', closeDialog); + document.querySelector('#dialogc').addEventListener('click', closeDialog); } function closeDialog() { - $('#dialogb').remove(); - $('#dialogt').remove(); + document.querySelector('#dialogb').remove(); + document.querySelector('#dialogt').remove(); } function openSocialWindow(a) { - var w=window.open(a.href,'juickshare','width=640,height=400'); - if(window.focus) w.focus(); + var w = window.open(a.href, 'juickshare', 'width=640,height=400'); + if (window.focus) w.focus(); return false; } function checkUsername() { - var uname=$('#username').val(); - $.ajax('//api.juick.com/users?uname='+uname).done(function() { - $('#username').css('background','#FFCCCC'); - }).fail(function() { - $('#username').css('background','#CCFFCC'); - }); + var uname = document.querySelector('#username').textContent; + fetch('//api.juick.com/users?uname=' + uname) + .then(function () { + document.querySelector('#username').style.background = '#FFCCCC'; + }) + .catch(function () { + document.querySelector('#username').style.background = '#CCFFCC'; + }); } /******************************************************************************/ function openDialogLogin() { - var html='<div class="dialoglogin"><p>Пожалуйста, представьтесь:' - +'<a href="/_fblogin" id="signfb">Facebook</a> ' - +'<a href="/_vklogin" id="signvk">ВКонтакте</a></p>' - +'<p>Уже зарегистрированы?</p>' - +'<form action="/login" method="POST">' - +'<input class="signinput" type="text" name="username" placeholder="Имя пользователя"/><br/>' - +'<input class="signinput" type="password" name="password" placeholder="Пароль"/><br/>' - +'<input class="signsubmit" type="submit" value="OK"/>' - +'</form></div>'; + var html = '<div class="dialoglogin"><p>Пожалуйста, представьтесь:' + + '<a href="/_fblogin" id="signfb">Facebook</a> ' + + '<a href="/_vklogin" id="signvk">ВКонтакте</a></p>' + + '<p>Уже зарегистрированы?</p>' + + '<form action="/login" method="POST">' + + '<input class="signinput" type="text" name="username" placeholder="Имя пользователя"/><br/>' + + '<input class="signinput" type="password" name="password" placeholder="Пароль"/><br/>' + + '<input class="signsubmit" type="submit" value="OK"/>' + + '</form></div>'; openDialog(html); return false; } /******************************************************************************/ -function likeMessage(e,mid) { - if (confirm("Are you sure?")) { - $.ajax({ - url: '//juick.com/like?mid='+mid, - type: 'POST' - }).done(function() { - $(e).closest("article").append("<p>OK!</p>"); - }).fail(function() { - $(e).closest("article").append("<p>Ошибка</p>"); - }); +function resultMessage(str) { + var result = document.createElement('p'); + result.textContent = str; + return result; +} + +function likeMessage(e, mid) { + if (confirm('Are you sure?')) { + fetch('//juick.com/like?mid=' + mid, { + method: 'POST' + }) + .then(function (response) { + if (response.ok) { + e.closest('article').appendChild(resultMessage('OK!')); + } + }) + .catch(function () { + e.closest('article').appendChild(resultMessage('Ошибка')); + }); } return false; } /******************************************************************************/ -function setPopular(e,mid,popular) { - $.ajax('//api.juick.com/messages/set_popular?mid='+mid+'&popular='+popular+'&hash='+hash).done(function() { - var a=$(e).closest("article"); - a.append("<p>OK!</p>"); - }); +function setPopular(e, mid, popular) { + var hash = document.getElementById('body').getAttribute('data-hash'); + fetch('//api.juick.com/messages/set_popular?mid=' + mid + '&popular=' + popular + '&hash=' + hash) + .then(function () { + var a = e.closest('article'); + a.append(resultMessage('OK!')); + }); return false; } -function setPrivacy(e,mid) { - $.ajax('//api.juick.com/messages/set_privacy?mid='+mid+'&hash='+hash).done(function() { - var a=$(e).closest("article"); - a.append("<p>OK!</p>"); - }); +function setPrivacy(e, mid) { + var hash = document.getElementById('body').getAttribute('data-hash'); + fetch('//api.juick.com/messages/set_privacy?mid=' + mid + '&hash=' + hash) + .then(function () { + var a = e.closest('article'); + a.append(resultMessage('OK!')); + }); return false; } /******************************************************************************/ -function readerLinkReplace(e) { - var a=$(e); - a.attr('href','/_out?lid='+a.data('lid')); -} - -/******************************************************************************/ - -jQuery.fn.selectText = function(){ +Element.prototype.selectText = function () { var d = document; if (d.body.createTextRange) { var range = d.body.createTextRange(); - range.moveToElementText(this[0]); + range.moveToElementText(this); range.select(); } else if (window.getSelection) { - var selection = window.getSelection(); - var range = d.createRange(); - range.selectNodeContents(this[0]); + var selection = window.getSelection(); + var rangeSel = d.createRange(); + rangeSel.selectNodeContents(this); selection.removeAllRanges(); - selection.addRange(range); + selection.addRange(rangeSel); } }; -/* - * jQuery.fn.autoResize 1.14 - */ - -(function($){ - - var uid = 'ar' + +new Date, - - defaults = autoResize.defaults = { - onResize: function(){}, - onBeforeResize: function(){ - return 123 - }, - onAfterResize: function(){ - return 555 - }, - animate: { - duration: 200, - complete: function(){} - }, - extraSpace: 50, - minHeight: 'original', - maxHeight: 500, - minWidth: 'original', - maxWidth: 500 - }; - - autoResize.cloneCSSProperties = [ - 'lineHeight', 'textDecoration', 'letterSpacing', - 'fontSize', 'fontFamily', 'fontStyle', 'fontWeight', - 'textTransform', 'textAlign', 'direction', 'wordSpacing', 'fontSizeAdjust', - 'paddingTop', 'paddingLeft', 'paddingBottom', 'paddingRight', 'width' - ]; - - autoResize.cloneCSSValues = { - position: 'absolute', - top: -9999, - left: -9999, - opacity: 0, - overflow: 'hidden' - }; - - autoResize.resizableFilterSelector = [ - 'textarea:not(textarea.' + uid + ')', - 'input:not(input[type])', - 'input[type=text]', - 'input[type=password]', - 'input[type=email]', - 'input[type=url]' - ].join(','); - - autoResize.AutoResizer = AutoResizer; - - $.fn.autoResize = autoResize; - - function autoResize(config) { - this.filter(autoResize.resizableFilterSelector).each(function(){ - new AutoResizer( $(this), config ); - }); - return this; - } - - function AutoResizer(el, config) { - - if (el.data('AutoResizer')) { - el.data('AutoResizer').destroy(); - } - - config = this.config = $.extend({}, autoResize.defaults, config); - this.el = el; - - this.nodeName = el[0].nodeName.toLowerCase(); - - this.originalHeight = el.height(); - this.previousScrollTop = null; - - this.value = el.val(); - - if (config.maxWidth === 'original') config.maxWidth = el.width(); - if (config.minWidth === 'original') config.minWidth = el.width(); - if (config.maxHeight === 'original') config.maxHeight = el.height(); - if (config.minHeight === 'original') config.minHeight = el.height(); - - if (this.nodeName === 'textarea') { - el.css({ - resize: 'none', - overflowY: 'hidden' - }); - } - - el.data('AutoResizer', this); - - // Make sure onAfterResize is called upon animation completion - config.animate.complete = (function(f){ - return function() { - config.onAfterResize.call(el); - return f.apply(this, arguments); - }; - }(config.animate.complete)); - - this.bind(); - +function ready(fn) { + if (document.readyState != 'loading') { + fn(); + } else { + document.addEventListener('DOMContentLoaded', fn); } +} - AutoResizer.prototype = { - - bind: function() { - - var check = $.proxy(function(){ - this.check(); - return true; - }, this); - - this.unbind(); - - this.el - .bind('keyup.autoResize', check) - //.bind('keydown.autoResize', check) - .bind('change.autoResize', check) - .bind('paste.autoResize', function() { - setTimeout(function() { - check(); - }, 0); - }); - - if (!this.el.is(':hidden')) { - this.check(null, true); - } - - }, - - unbind: function() { - this.el.unbind('.autoResize'); - }, - - createClone: function() { - - var el = this.el, - clone = this.nodeName === 'textarea' ? el.clone() : $('<span/>'); - - this.clone = clone; - - $.each(autoResize.cloneCSSProperties, function(i, p){ - clone[0].style[p] = el.css(p); +ready(function () { + autosize(document.querySelectorAll('textarea')); + var insertButtons = function (e) { + var textarea = e.target; + textarea.classList.add('narrow'); + textarea.insertAdjacentHTML('afterend', '<div class="attach-photo" onclick="attachCommentPhoto(this)"/>'); + textarea.parentNode.insertAdjacentHTML('afterend', '<input type="submit" value="OK"/>'); + textarea.removeEventListener('click', insertButtons); + e.preventDefault(); + }; + + document.querySelectorAll('textarea.reply').forEach(function(e) { + e.addEventListener('click', insertButtons); + }); + var insertPMButtons = function (e) { + e.target.classList.add('narrowpm'); + e.target.parentNode.insertAdjacentHTML('afterend', '<input type="submit" value="OK"/>'); + e.target.removeEventListener('click', insertPMButtons); + e.preventDefault(); + }; + document.querySelectorAll('textarea.replypm').forEach(function(e) { + e.addEventListener('click', insertPMButtons); + }); + var content = document.getElementById('content'); + if (content) { + var pageMID = content.getAttribute('data-mid'); + if (pageMID > 0) { + document.querySelectorAll('.msg-comments').forEach(function(e) { + var rid = e.parentNode.parentNode.id; + e.addEventListener('click', function (e) { + showMoreReplies(e.target, rid); + e.preventDefault(); + }); }); - - clone - .removeAttr('name') - .removeAttr('id') - .addClass(uid) - .attr('tabIndex', -1) - .css(autoResize.cloneCSSValues); - - if (this.nodeName === 'textarea') { - clone.height('auto'); - } else { - clone.width('auto').css({ - whiteSpace: 'nowrap' + document.querySelectorAll('.a-thread-comment').forEach(function(e) { + var rid = e.closest('li').id; + e.addEventListener('click', function (e) { + showCommentForm(pageMID, rid); + e.preventDefault(); }); - } - - }, - - check: function(e, immediate) { - - if (!this.clone) { - this.createClone(); - this.injectClone(); - } - - var config = this.config, - clone = this.clone, - el = this.el, - value = el.val(); - - // Do nothing if value hasn't changed - if (value === this.prevValue) { - return true; - } - this.prevValue = value; - - if (this.nodeName === 'input') { - - clone.text(value); - - // Calculate new width + whether to change - var cloneWidth = clone.width(), - newWidth = (cloneWidth + config.extraSpace) >= config.minWidth ? - cloneWidth + config.extraSpace : config.minWidth, - currentWidth = el.width(); - - newWidth = Math.min(newWidth, config.maxWidth); - - if ( - (newWidth < currentWidth && newWidth >= config.minWidth) || - (newWidth >= config.minWidth && newWidth <= config.maxWidth) - ) { - - config.onBeforeResize.call(el); - config.onResize.call(el); - - el.scrollLeft(0); - - if (config.animate && !immediate) { - el.stop(1,1).animate({ - width: newWidth - }, config.animate); - } else { - el.width(newWidth); - config.onAfterResize.call(el); - } - - } - - return; - - } - - // TEXTAREA - - clone.width(el.width()).height(0).val(value).scrollTop(10000); - - var scrollTop = clone[0].scrollTop; - - // Don't do anything if scrollTop hasen't changed: - if (this.previousScrollTop === scrollTop) { - return; - } - - this.previousScrollTop = scrollTop; - - if (scrollTop + config.extraSpace >= config.maxHeight) { - el.css('overflowY', ''); - scrollTop = config.maxHeight; - immediate = true; - } else if (scrollTop <= config.minHeight) { - scrollTop = config.minHeight; - } else { - el.css('overflowY', 'hidden'); - scrollTop += config.extraSpace; - } - - config.onBeforeResize.call(el); - config.onResize.call(el); - - // Either animate or directly apply height: - if (config.animate && !immediate) { - el.stop(1,1).animate({ - height: scrollTop - }, config.animate); - } else { - el.height(scrollTop); - config.onAfterResize.call(el); - } - - }, - - destroy: function() { - this.unbind(); - this.el.removeData('AutoResizer'); - this.clone.remove(); - delete this.el; - delete this.clone; - }, - - injectClone: function() { - ( - autoResize.cloneContainer || - (autoResize.cloneContainer = $('<arclones/>').appendTo('body')) - ).append(this.clone); + }); } + } - }; - -})(jQuery); - -/******************************************************************************/ - -$(document).ready(function() { - $('textarea').autoResize({ - extraSpace: 0, - minHeight: 1 + document.querySelectorAll('.msg-menu a').forEach(function(e) { + var mid = e.closest('section').getAttribute('data-mid'); + var rid = parseInt(e.closest('li').id); + e.addEventListener('click', function(e) { + showMessageLinksDialog(mid, rid); + e.preventDefault(); + }); + }); + document.querySelectorAll('.l .a-comment').forEach(function(e) { + e.addEventListener('click', function (e) { + var mid = e.target.closest('article').getAttribute('data-mid'); + showCommentFooter(e.target, mid); + e.preventDefault(); + }); + }); + document.querySelectorAll('.l .a-privacy').forEach(function(e) { + e.addEventListener('click', function (e) { + var mid = e.target.closest('article').getAttribute('data-mid'); + setPrivacy(e.target, mid); + e.preventDefault(); + }); }); + document.querySelectorAll('.l .a-popular-plus').forEach(function(e) { + e.addEventListener('click', function (e) { + var mid = e.target.closest('article').getAttribute('data-mid'); + setPopular(e.target, mid, 2); + e.preventDefault(); + }); + }); + document.querySelectorAll('.l .a-popular-minus').forEach(function(e) { + e.addEventListener('click', function (e) { + var mid = e.target.closest('article').getAttribute('data-mid'); + setPopular(e.target, mid, -1); + e.preventDefault(); + }); + }); + document.querySelectorAll('.l .a-popular-delete').forEach(function(e) { + e.addEventListener('click', function (e) { + var mid = e.target.closest('article').getAttribute('data-mid'); + setPopular(e.target, mid, -2); + e.preventDefault(); + }); + }); + document.querySelectorAll('.ir a').forEach(function(e) { + e.addEventListener('click', function (e) { + var fname = e.target.parentNode.getAttribute('data-fname'); + showPhotoDialog(fname); + e.preventDefault(); + }); + }); + document.querySelectorAll('.social a').forEach(function(e) { + e.addEventListener('click', function (e) { + openSocialWindow(e.target); + e.preventDefault(); + }); + }); + var username = document.getElementById('username'); + if (username) { + username.addEventListener('blur', function () { + checkUsername(); + }); + } - $('textarea.reply').click(function () { - $(this).addClass("narrow"); - $(this).after('<div class="attach-photo" onclick="attachCommentPhoto(this)"/>'); - $(this).parent().after('<input type="submit" value="OK"/>'); - $(this).off('click'); + document.querySelectorAll('.l .a-like').forEach(function(e) { + e.addEventListener('click', function (e) { + var mid = e.target.closest('article').getAttribute('data-mid'); + likeMessage(e.target, mid); + e.preventDefault(); + }); }); - - $('textarea.replypm').click(function () { - $(this).addClass("narrowpm"); - $(this).parent().after('<input type="submit" value="OK"/>'); - $(this).off('click'); + document.querySelectorAll('.a-login').forEach(function(el) { + el.addEventListener('click', function(e) { + openDialogLogin(); + e.preventDefault(); + }); }); - + var unfoldall = document.getElementById('unfoldall'); + if (unfoldall) { + unfoldall.addEventListener('click', function(e) { + document.querySelectorAll('#replies>li').forEach(function(e) { + e.style.display = 'block'; + }); + document.querySelectorAll('#replies .msg-comments').forEach(function(e) { + e.style.display = 'none'; + }); + e.preventDefault(); + }); + } + var newMessageBlock = document.getElementById('newmessage'); + if (newMessageBlock) { + var form = newMessageBlock.parentNode; + form.addEventListener('submit', onsubmitNewMessage); + newMessageBlock.querySelector('textarea').addEventListener('click', function(e) { + var parent = e.target.parentNode; + parent.querySelector('div').style.display = 'block'; + e.target.style.minHeight = '70px'; + e.target.addEventListener('keypress', function(e) { + postformListener(e.target, e); + }); + parent.querySelector('a').addEventListener('click', function(e) { + attachMessagePhoto(e.target); + }); + }); + } unfoldPostForm(); unfoldReply(); - $(window).bind('hashchange',unfoldPostForm); - $(window).bind('hashchange',unfoldReply); - - $(window).on('pagehide',wsShutdown); + initWS(); + window.addEventListener('hashchange', unfoldPostForm); + window.addEventListener('hashchange', unfoldReply); + + window.addEventListener('pagehide', wsShutdown); }); diff --git a/juick-www/src/main/webapp/WEB-INF/web.xml b/juick-www/src/main/webapp/WEB-INF/web.xml index 4db19af6..fe07d696 100644 --- a/juick-www/src/main/webapp/WEB-INF/web.xml +++ b/juick-www/src/main/webapp/WEB-INF/web.xml @@ -19,6 +19,14 @@ <servlet-name>default</servlet-name> <url-pattern>/style.css</url-pattern> </servlet-mapping> + <servlet-mapping> + <servlet-name>default</servlet-name> + <url-pattern>/scripts.js.map</url-pattern> + </servlet-mapping> + <servlet-mapping> + <servlet-name>default</servlet-name> + <url-pattern>/style.css.map</url-pattern> + </servlet-mapping> <mime-mapping> <extension>js</extension> <mime-type>application/javascript;charset=UTF-8</mime-type> diff --git a/juick-www/webpack.config.js b/juick-www/webpack.config.js index 3a689a28..ed041ee6 100644 --- a/juick-www/webpack.config.js +++ b/juick-www/webpack.config.js @@ -2,6 +2,7 @@ var webpack = require("webpack") var globby = require("globby") var ExtractTextPlugin = require("extract-text-webpack-plugin") module.exports = { + devtool: 'source-map', entry: { "scripts" : globby.sync([ __dirname + "/src/main/static/*.*" @@ -12,14 +13,20 @@ module.exports = { filename: "[name].js" }, module: { + preLoaders: [ + { test: /\.jsx?$/, loader: 'eslint', exclude: /node_modules/ } + ], loaders: [ - { test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader") }, - { test: /scripts\.js$/, exclude: /node_modules/, loader: "script!uglify" }, + { test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader") } ] }, plugins: [ new ExtractTextPlugin("style.css", { allChunks: true }) - ] + ], + eslint: { + failOnWarning: false, + failOnError: true + }, }
\ No newline at end of file |