From 7a2ea130863bb095fa925ec0c7576b076490f0cf Mon Sep 17 00:00:00 2001 From: Alexander Alexeev Date: Sun, 20 Nov 2016 02:05:23 +0700 Subject: init juick-spring-web project --- juick-spring-www/build.gradle | 43 + juick-spring-www/package.json | 36 + juick-spring-www/src/main/webapp/WEB-INF/web.xml | 7 + .../src/main/webapp/static/dialog-close.png | Bin 0 -> 1097 bytes .../src/main/webapp/static/facebook.png | Bin 0 -> 203 bytes .../src/main/webapp/static/favicon.png | Bin 0 -> 244 bytes .../src/main/webapp/static/icon-fb.png | Bin 0 -> 203 bytes .../src/main/webapp/static/icon-gplus.png | Bin 0 -> 501 bytes .../src/main/webapp/static/icon-lj.png | Bin 0 -> 1183 bytes .../src/main/webapp/static/icon-twitter.png | Bin 0 -> 458 bytes .../src/main/webapp/static/icon-vk.png | Bin 0 -> 306 bytes juick-spring-www/src/main/webapp/static/logo.png | Bin 0 -> 2447 bytes .../src/main/webapp/static/logo@2x.png | Bin 0 -> 4822 bytes juick-spring-www/src/main/webapp/static/menu.png | Bin 0 -> 479 bytes .../main/webapp/static/photo-attachment-active.png | Bin 0 -> 267 bytes .../src/main/webapp/static/photo-attachment.png | Bin 0 -> 234 bytes juick-spring-www/src/main/webapp/static/scripts.js | 753 ++++++++++++++++++ .../src/main/webapp/static/sharesocial.png | Bin 0 -> 4474 bytes juick-spring-www/src/main/webapp/static/style.css | 874 +++++++++++++++++++++ .../src/main/webapp/static/toolbar-icons.png | Bin 0 -> 737 bytes juick-spring-www/src/main/webapp/static/vk.png | Bin 0 -> 306 bytes juick-spring-www/webpack.config.js | 37 + 22 files changed, 1750 insertions(+) create mode 100644 juick-spring-www/build.gradle create mode 100644 juick-spring-www/package.json create mode 100644 juick-spring-www/src/main/webapp/WEB-INF/web.xml create mode 100644 juick-spring-www/src/main/webapp/static/dialog-close.png create mode 100644 juick-spring-www/src/main/webapp/static/facebook.png create mode 100644 juick-spring-www/src/main/webapp/static/favicon.png create mode 100644 juick-spring-www/src/main/webapp/static/icon-fb.png create mode 100644 juick-spring-www/src/main/webapp/static/icon-gplus.png create mode 100644 juick-spring-www/src/main/webapp/static/icon-lj.png create mode 100644 juick-spring-www/src/main/webapp/static/icon-twitter.png create mode 100644 juick-spring-www/src/main/webapp/static/icon-vk.png create mode 100644 juick-spring-www/src/main/webapp/static/logo.png create mode 100644 juick-spring-www/src/main/webapp/static/logo@2x.png create mode 100644 juick-spring-www/src/main/webapp/static/menu.png create mode 100644 juick-spring-www/src/main/webapp/static/photo-attachment-active.png create mode 100644 juick-spring-www/src/main/webapp/static/photo-attachment.png create mode 100644 juick-spring-www/src/main/webapp/static/scripts.js create mode 100644 juick-spring-www/src/main/webapp/static/sharesocial.png create mode 100644 juick-spring-www/src/main/webapp/static/style.css create mode 100644 juick-spring-www/src/main/webapp/static/toolbar-icons.png create mode 100644 juick-spring-www/src/main/webapp/static/vk.png create mode 100644 juick-spring-www/webpack.config.js (limited to 'juick-spring-www') diff --git a/juick-spring-www/build.gradle b/juick-spring-www/build.gradle new file mode 100644 index 00000000..2f8c0377 --- /dev/null +++ b/juick-spring-www/build.gradle @@ -0,0 +1,43 @@ +buildscript { + repositories { + mavenCentral() + jcenter() + } +} + +plugins { + id "com.moowork.node" version "0.13" +} + +task compileFrontend(type: NpmTask) { + args = ['run', 'compile'] +} + +apply plugin: 'java' +apply plugin: 'war' +apply plugin: 'org.akhikhl.gretty' +apply plugin: 'com.github.ben-manes.versions' + +def springFrameworkVersion = '4.3.4.RELEASE' + +dependencies { + compile project(':juick-server') + compile 'com.sun.mail:javax.mail:1.5.6' + compile "org.springframework:spring-webmvc:${springFrameworkVersion}" + providedCompile 'javax.servlet:javax.servlet-api:3.1.0' + providedRuntime 'mysql:mysql-connector-java:5.1.40' +} + +compileFrontend.dependsOn 'npmInstall' +war.dependsOn 'compileFrontend' +compileJava.options.encoding = 'UTF-8' + +gretty { + httpPort = 8080 + contextPath = '' + servletContainer = 'tomcat8' +} + +configurations { + all*.exclude module: 'commons-logging' +} diff --git a/juick-spring-www/package.json b/juick-spring-www/package.json new file mode 100644 index 00000000..2eda35cd --- /dev/null +++ b/juick-spring-www/package.json @@ -0,0 +1,36 @@ +{ + "name": "juick", + "version": "1.0.0", + "private": true, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "compile": "webpack --colors -p" + }, + "repository": { + "type": "git", + "url": "https://github.com/juick/juick.git" + }, + "license": "AGPLv3", + "devDependencies": { + "css-loader": "^0.23.1", + "csslint": "^1.0.2", + "csslint-loader": "^1.0.0", + "eslint": "^3.1.1", + "eslint-loader": "^1.4.1", + "extract-text-webpack-plugin": "^1.0.1", + "file-loader": "^0.9.0", + "globby": "^4.1.0", + "script-loader": "^0.7.0", + "style-loader": "^0.13.1", + "uglify-loader": "^1.3.0", + "url-loader": "^0.5.7", + "webpack": "^1.13.1" + }, + "dependencies": { + "autosize": "^3.0.16", + "classlist.js": "^1.1.20150312", + "element-closest": "^2.0.1", + "evil-icons": "^1.8.0", + "whatwg-fetch": "^1.0.0" + } +} diff --git a/juick-spring-www/src/main/webapp/WEB-INF/web.xml b/juick-spring-www/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 00000000..a57cceb9 --- /dev/null +++ b/juick-spring-www/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/juick-spring-www/src/main/webapp/static/dialog-close.png b/juick-spring-www/src/main/webapp/static/dialog-close.png new file mode 100644 index 00000000..9c4275cc Binary files /dev/null and b/juick-spring-www/src/main/webapp/static/dialog-close.png differ diff --git a/juick-spring-www/src/main/webapp/static/facebook.png b/juick-spring-www/src/main/webapp/static/facebook.png new file mode 100644 index 00000000..5d111590 Binary files /dev/null and b/juick-spring-www/src/main/webapp/static/facebook.png differ diff --git a/juick-spring-www/src/main/webapp/static/favicon.png b/juick-spring-www/src/main/webapp/static/favicon.png new file mode 100644 index 00000000..bc7161e2 Binary files /dev/null and b/juick-spring-www/src/main/webapp/static/favicon.png differ diff --git a/juick-spring-www/src/main/webapp/static/icon-fb.png b/juick-spring-www/src/main/webapp/static/icon-fb.png new file mode 100644 index 00000000..5d111590 Binary files /dev/null and b/juick-spring-www/src/main/webapp/static/icon-fb.png differ diff --git a/juick-spring-www/src/main/webapp/static/icon-gplus.png b/juick-spring-www/src/main/webapp/static/icon-gplus.png new file mode 100644 index 00000000..d83d2520 Binary files /dev/null and b/juick-spring-www/src/main/webapp/static/icon-gplus.png differ diff --git a/juick-spring-www/src/main/webapp/static/icon-lj.png b/juick-spring-www/src/main/webapp/static/icon-lj.png new file mode 100644 index 00000000..9cde1e02 Binary files /dev/null and b/juick-spring-www/src/main/webapp/static/icon-lj.png differ diff --git a/juick-spring-www/src/main/webapp/static/icon-twitter.png b/juick-spring-www/src/main/webapp/static/icon-twitter.png new file mode 100644 index 00000000..259078f7 Binary files /dev/null and b/juick-spring-www/src/main/webapp/static/icon-twitter.png differ diff --git a/juick-spring-www/src/main/webapp/static/icon-vk.png b/juick-spring-www/src/main/webapp/static/icon-vk.png new file mode 100644 index 00000000..80b6920b Binary files /dev/null and b/juick-spring-www/src/main/webapp/static/icon-vk.png differ diff --git a/juick-spring-www/src/main/webapp/static/logo.png b/juick-spring-www/src/main/webapp/static/logo.png new file mode 100644 index 00000000..4e0f6d56 Binary files /dev/null and b/juick-spring-www/src/main/webapp/static/logo.png differ diff --git a/juick-spring-www/src/main/webapp/static/logo@2x.png b/juick-spring-www/src/main/webapp/static/logo@2x.png new file mode 100644 index 00000000..6febeaf9 Binary files /dev/null and b/juick-spring-www/src/main/webapp/static/logo@2x.png differ diff --git a/juick-spring-www/src/main/webapp/static/menu.png b/juick-spring-www/src/main/webapp/static/menu.png new file mode 100644 index 00000000..4cac2563 Binary files /dev/null and b/juick-spring-www/src/main/webapp/static/menu.png differ diff --git a/juick-spring-www/src/main/webapp/static/photo-attachment-active.png b/juick-spring-www/src/main/webapp/static/photo-attachment-active.png new file mode 100644 index 00000000..ecbf10e8 Binary files /dev/null and b/juick-spring-www/src/main/webapp/static/photo-attachment-active.png differ diff --git a/juick-spring-www/src/main/webapp/static/photo-attachment.png b/juick-spring-www/src/main/webapp/static/photo-attachment.png new file mode 100644 index 00000000..07d48517 Binary files /dev/null and b/juick-spring-www/src/main/webapp/static/photo-attachment.png differ diff --git a/juick-spring-www/src/main/webapp/static/scripts.js b/juick-spring-www/src/main/webapp/static/scripts.js new file mode 100644 index 00000000..d368cacd --- /dev/null +++ b/juick-spring-www/src/main/webapp/static/scripts.js @@ -0,0 +1,753 @@ +var autosize = require('autosize'); +require('whatwg-fetch'); +require('element-closest'); +require('classlist.js'); +if (!('remove' in Element.prototype)) { // Firefox <23 + Element.prototype.remove = function() { + if (this.parentNode) { + this.parentNode.removeChild(this); + } + }; +} + +NodeList.prototype.forEach = Array.prototype.forEach; +HTMLCollection.prototype.forEach = Array.prototype.forEach; + +var ws, + pageTitle; + +function initWS() { + var content = document.getElementById('content'); + if (!content) { return } + var pageMID = content.getAttribute('data-mid'); + if (!pageMID) { return } + + var url = (window.location.protocol === 'https:' ? 'wss' : 'ws') + ':' + + (typeof juickDebug !== 'undefined' ? + '//ws.juick.com/_replies' : ('//ws.juick.com/' + pageMID)), + hash = document.getElementById('body').getAttribute('data-hash'); + + if (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', nextReply); + document.querySelector('body').appendChild(d); + pageTitle = document.title; + } + }; + ws.onclose = function () { + console.log('offline'); + ws = false; + 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); +} + +function wsSendKeepAlive() { + if (ws) { + ws.send(' '); + } +} + +function wsShutdown() { + if (ws) { + ws.onclose = function () { }; + ws.close(); + } +} + +function isTreeMode() { + // relies on UserThread.printReplies implementation TODO keep this in cookie or something + return document.querySelector('.title2-right > a').href.match(/\?view=(\w+)/)[1] == 'list'; +} + +function wsIncomingReply(msg) { + var li = document.createElement('li'); + li.setAttribute('class', 'msg reply-new'); + li.setAttribute('id', msg.rid); + li.addEventListener('click', newReply); + li.addEventListener('mouseover', newReply); + 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); + + 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); + 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 msgNum = '/' + msg.rid; + if (msg.replyto > 0) { + msgNum += ' в ответ на /' + msg.replyto + ''; + } + msgLinks.innerHTML = msgNum + ' · '; + 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'; + msgHeader.appendChild(msgAvatar); + msgHeader.appendChild(msgMenu); + msgHeader.appendChild(msgTimestamp); + msgCont.appendChild(msgHeader); + msgCont.appendChild(msgTxt); + msgCont.appendChild(msgLinks); + msgCont.appendChild(msgComment); + li.appendChild(msgCont); + + li.querySelector('.msg-txt').textContent = msg.body; + + if (isTreeMode() && (msg.replyto > 0)) { + var p = document.getElementById(msg.replyto); + var m = parseInt(p.style.marginLeft) + 20; + while (p.nextElementSibling && (parseInt(p.nextElementSibling.style.marginLeft) >= m)) p = p.nextElementSibling; + li.style.marginLeft = m + 'px'; + p.parentNode.insertBefore(li, p.nextSibling); + } else { + document.getElementById('replies').appendChild(li); + } + + updateRepliesCounter(); +} + +function newReply(e) { + var li = e.target; + li.classList.remove('reply-new'); + li.removeEventListener('click', e); + li.removeEventListener('mouseover', e); + updateRepliesCounter(); +} + +function nextReply() { + var li = document.querySelector('#replies>li.reply-new'); + if (li) { + li.classList.remove('reply-new'); + li.removeEventListener('click', this); + li.childNodes[0].scrollIntoView(); + updateRepliesCounter(); + } +} + +function updateRepliesCounter() { + var replies = document.querySelectorAll('#replies>li.reply-new').length; + var wsthread = document.getElementById('wsthread'); + if (replies) { + wsthread.textContent = replies; + wsthread.style.display = 'block'; + document.title = '[' + replies + '] ' + pageTitle; + } else { + wsthread.style.display = 'none'; + document.title = pageTitle; + } +} + +/******************************************************************************/ +/******************************************************************************/ +/******************************************************************************/ + +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') { + document.querySelector('#newmessage>div').style.display = 'block'; + var ta = document.querySelector('#newmessage textarea'); + ta.style.minHeight = '70px'; + ta.focus(); + } +} + +function newMessage() { + if (document.querySelector('#newmessage textarea').value.length == 0) { + openDialog('

Пожалуйста, введите текст сообщения

'); + return false; + } + return true; +} + +function showMoreReplies(el, id) { + var foldedReplies = el.closest('li').querySelector('.msg-comments'); + if (!foldedReplies) { return } + foldedReplies.style.display = 'none'; + + var replies = document.querySelectorAll('#replies>li'), + flagshow = 0, + i = 0; + for (; i < replies.length; i += 1) { + if (flagshow == 1) { + if (replies[i].style.display == 'none') { + replies[i].style.display = 'block'; + } else { + break; + } + } + if (replies[i].id == id) { + flagshow = 1; + } + } + return false; +} + +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); + } + return form; +} + +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'); + att.addEventListener('click', function () { + attachCommentPhoto(this); + }); + 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'), + newNode = c.cloneNode(true), + 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(); + } + + 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), + 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 = attachInput(); + inp.addEventListener('change', function () { + inp.parentNode.classList.add('attach-photo-active'); + }); + inp.click(); + div.appendChild(inp); + } else { + div.innerHTML = null; + div.classList.add('attach-photo'); + } +} + +function attachMessagePhoto(div) { + var f = div.closest('form'), + 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.appendChild(inp); + inp.click(); + } else { + finput.remove(); + div.textContent = 'загрузить'; + } +} + +function unfoldReply() { + var anchor = window.location.hash.substring(1); + if ((0 + anchor) > 0) { + var el = document.getElementById(anchor); + if (!el) { return } + while (el.style.display === 'none') { + el = el.previousElementSibling; + } + showMoreReplies(el, el.getAttribute('id')); + window.location.replace(window.location.hash); + } +} + +function showMessageLinksDialog(mid, rid) { + var hlink = window.location.protocol + '//juick.com/' + mid, + mlink = '#' + mid; + if (rid > 0) { + hlink += '#' + rid; + mlink += '/' + rid; + } + var hlinkenc = encodeURIComponent(hlink), + html = '
Ссылка на сообщение:' + + '
' + hlink + '
' + + 'Номер сообщения:' + + '
' + mlink + '
' + + 'Поделиться:
'; + + openDialog(html); +} + +function showPhotoDialog(fname) { + var width = window.innerWidth, + height = window.innerHeight * 0.9; + if (width < 640) { + return true; + } else if (width < 1280) { + openDialog(''); + document.querySelector('#dialogw img').style.maxHeight = height + 'px'; + return false; + } else { + openDialog(''); + document.querySelector('#dialogw img').style.maxHeight = height + 'px'; + return false; + } +} + +function openDialog(html) { + var dhtml = '
' + html + '
'; + document.querySelector('body').insertAdjacentHTML('afterbegin', dhtml); + document.querySelector('#dialogb').addEventListener('click', closeDialog); + document.querySelector('#dialogc').addEventListener('click', closeDialog); +} + +function closeDialog() { + 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(); + return false; +} + +function checkUsername() { + var uname = document.querySelector('#username').textContent, + style = document.querySelector('#username').style; + fetch('//api.juick.com/users?uname=' + uname) + .then(function () { + style.background = '#FFCCCC'; + }) + .catch(function () { + style.background = '#CCFFCC'; + }); +} + +/******************************************************************************/ + +function openDialogLogin() { + var html = '

Пожалуйста, представьтесь:' + + 'Facebook ' + + 'ВКонтакте

' + + '

Уже зарегистрированы?

' + + '
' + + '
' + + '
' + + '' + + '
'; + openDialog(html); + return false; +} + +/******************************************************************************/ + +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', + credentials: 'same-origin' + }) + .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) { + fetch('//api.juick.com/messages/set_popular?mid=' + mid + + '&popular=' + popular + + '&hash=' + document.getElementById('body').getAttribute('data-hash'), { + credentials: 'same-origin' + }) + .then(function () { + e.closest('article').append(resultMessage('OK!')); + }); + return false; +} + +function setPrivacy(e, mid) { + fetch('//api.juick.com/messages/set_privacy?mid=' + mid + + '&hash=' + document.getElementById('body').getAttribute('data-hash'), { + credentials: 'same-origin' + }) + .then(function () { + e.closest('article').append(resultMessage('OK!')); + }); + return false; +} +/******************************************************************************/ + +Element.prototype.selectText = function () { + var d = document; + if (d.body.createTextRange) { + var range = d.body.createTextRange(); + range.moveToElementText(this); + range.select(); + } else if (window.getSelection) { + var selection = window.getSelection(); + var rangeSel = d.createRange(); + rangeSel.selectNodeContents(this); + selection.removeAllRanges(); + selection.addRange(rangeSel); + } +}; + +function ready(fn) { + if (document.readyState != 'loading') { + fn(); + } else { + document.addEventListener('DOMContentLoaded', fn); + } +} + +ready(function () { + autosize(document.querySelectorAll('textarea')); + + var insertButtons = function (e) { + var textarea = e.target; + textarea.classList.add('narrow'); + var att = document.createElement('div'); + att.classList.add('attach-photo'); + att.addEventListener('click', function(e) { + attachCommentPhoto(e.target); + }); + textarea.parentNode.insertBefore(att, textarea.nextSibling); + textarea.parentNode.insertAdjacentHTML('afterend', ''); + textarea.removeEventListener('click', insertButtons); + e.preventDefault(); + }; + document.querySelectorAll('textarea.reply').forEach(function(e) { + e.addEventListener('click', insertButtons); + e.addEventListener('keypress', function(e) { + postformListener(e.target, e); + }); + }); + + var insertPMButtons = function (e) { + e.target.classList.add('narrowpm'); + e.target.parentNode.insertAdjacentHTML('afterend', ''); + 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) { + e.addEventListener('click', function (e) { + var rid = e.target.closest('li').id; + showMoreReplies(e.target, rid); + e.preventDefault(); + }); + }); + document.querySelectorAll('.a-thread-comment').forEach(function(e) { + e.addEventListener('click', function (e) { + var rid = e.target.closest('li').id; + showCommentForm(pageMID, rid); + e.preventDefault(); + }); + }); + } + } + + document.querySelectorAll('.msg-menu a').forEach(function(el) { + el.addEventListener('click', function(e) { + showMessageLinksDialog( + e.target.closest('section').getAttribute('data-mid'), + parseInt(e.target.closest('li').id)); // rid + e.preventDefault(); + }); + }); + document.querySelectorAll('.l .a-comment').forEach(function(e) { + e.addEventListener('click', function (e) { + showCommentFooter( + e.target, + e.target.closest('article').getAttribute('data-mid')); + e.preventDefault(); + }); + }); + document.querySelectorAll('.l .a-privacy').forEach(function(e) { + e.addEventListener('click', function (e) { + setPrivacy( + e.target, + e.target.closest('article').getAttribute('data-mid')); + e.preventDefault(); + }); + }); + document.querySelectorAll('.l .a-popular-plus').forEach(function(e) { + e.addEventListener('click', function (e) { + setPopular( + e.target, + e.target.closest('article').getAttribute('data-mid'), + 2); + e.preventDefault(); + }); + }); + document.querySelectorAll('.l .a-popular-minus').forEach(function(e) { + e.addEventListener('click', function (e) { + setPopular( + e.target, + e.target.closest('article').getAttribute('data-mid'), + -1); + e.preventDefault(); + }); + }); + document.querySelectorAll('.l .a-popular-delete').forEach(function(e) { + e.addEventListener('click', function (e) { + setPopular( + e.target, + e.target.closest('article').getAttribute('data-mid'), + -2); + e.preventDefault(); + }); + }); + document.querySelectorAll('.ir a').forEach(function(e) { + e.addEventListener('click', function (e) { + var fname = e.target.closest('[data-fname]').getAttribute('data-fname'); + if (!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(); + }); + } + + document.querySelectorAll('.l .a-like').forEach(function(e) { + e.addEventListener('click', function (e) { + likeMessage( + e.target, + e.target.closest('article').getAttribute('data-mid')); + e.preventDefault(); + }); + }); + document.querySelectorAll('.a-login').forEach(function(el) { + el.addEventListener('click', function(e) { + openDialogLogin(); + e.preventDefault(); + }); + }); + document.querySelectorAll('.attach-photo').forEach(function(el) { + el.addEventListener('click', function(e) { + attachCommentPhoto(e.target); + }); + }); + 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', newMessage); + 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); + }); + }); + newMessageBlock.querySelector('a').addEventListener('click', function(e) { + attachMessagePhoto(e.target); + }); + } + document.querySelectorAll('article').forEach(function(article) { + if (Array.prototype.some.call( + article.querySelectorAll('.u a'), + function (a) { + return a.textContent === 'NSFW'; + } + )) { + var img = article.querySelector('.ir img'); + if (img) { + img.style.opacity = 0.05; + img.addEventListener('mouseover', function(e) { + e.target.style.opacity = 1; + }); + img.addEventListener('mouseout', function(e) { + e.target.style.opacity = 0.05; + }); + } + } + }); + + unfoldPostForm(); + unfoldReply(); + initWS(); + window.addEventListener('hashchange', unfoldPostForm); + window.addEventListener('hashchange', unfoldReply); + + window.addEventListener('pagehide', wsShutdown); +}); diff --git a/juick-spring-www/src/main/webapp/static/sharesocial.png b/juick-spring-www/src/main/webapp/static/sharesocial.png new file mode 100644 index 00000000..1031b343 Binary files /dev/null and b/juick-spring-www/src/main/webapp/static/sharesocial.png differ diff --git a/juick-spring-www/src/main/webapp/static/style.css b/juick-spring-www/src/main/webapp/static/style.css new file mode 100644 index 00000000..46af7b81 --- /dev/null +++ b/juick-spring-www/src/main/webapp/static/style.css @@ -0,0 +1,874 @@ +html,body,div,h1,h2,ul,li,p,form,input,textarea,pre { + margin: 0; + padding: 0; +} +html,input,textarea { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Droid Sans", "Helvetica Neue", sans-serif; + font-size: 12pt; + -webkit-font-smoothing: subpixel-antialiased; +} +html { + background: #EEEEE5; + color: #222; +} +body { + margin: 0 auto; + width: 1000px; +} +h1,h2 { + font-weight: normal; +} +ul { + list-style-type: none; +} +a { + color: #069; + text-decoration: none; +} +img,hr { + border: none; +} +hr { + background: #CCC; + height: 1px; + margin: 10px 0; +} +pre { + white-space: pre-wrap; + white-space: -moz-pre-wrap; + white-space: -pre-wrap; + white-space: -o-pre-wrap; + word-wrap: break-word; +} +span.u { + text-decoration: underline; +} +#content { + float: right; + margin: 25px 0 0 0; + width: 728px; +} +#topwrapper { + clear: both; + position: relative; +} +body>header { + width: 1000px; +} +body>header a { + border-bottom: 1px dotted #666; + color: #222; + font-size: 13pt; +} +#logo { + float: left; + height: 36px; + margin: 7px 25px 0 20px; + width: 110px; +} +#logo a { + background: url("logo.png") no-repeat; + border: 0; + display: block; + height: 36px; + overflow: hidden; + text-indent: 100%; + white-space: nowrap; + width: 110px; +} +@media screen and (-webkit-min-device-pixel-ratio: 2),(min-resolution: 192dpi) { + #logo a { + background: url("logo@2x.png") no-repeat; + background-size: cover; + } +} +nav#global { + float: left; +} +nav#global li { + display: inline-block; + margin: 14px 12px 0 0; +} +#search { + float: right; + margin: 12px 20px 12px 0; +} +#search input { + background: #FFF; + border: 1px solid #DDDDD5; + padding: 4px; +} +#headdiv { + background: #DDDDD5; + border-bottom: 1px solid #D5D5D0; + border-top: 1px solid #D5D5D0; + clear: both; + margin: 0 0 5px 0; + padding: 0 20px; + position: relative; +} +#headdiv li { + display: inline-block; + margin: 12px 12px 12px 0; +} +nav#actions { + position: absolute; + right: 8px; + top: 0; +} +body>header nav li:after { + color: #AAA; + content: "/"; + display: inline-block; + margin-left: 12px; +} +body>header nav li:last-child:after { + display: none; +} +body>header p { + color: #222; + font-size: 13pt; + margin: 12px 0; + text-align: center; +} +#content>p, #content>h1, #content>h2 { + margin: 1em 0; +} +#newmessage { + background: #E5E5E0; + margin-bottom: 20px; + padding: 15px; +} +#newmessage textarea { + border: 1px solid #CCC; + height: 14pt; + margin: 0 0 5px 0; + min-height: 14pt; + padding: 4px; + resize: vertical; + width: 688px; +} +#newmessage input { + border: 1px solid #CCC; + margin: 5px 0; + padding: 2px 4px; +} +#newmessage>div { + display: none; +} +#newmessage .img { + width: 500px; +} +#newmessage .tags { + width: 500px; +} +#newmessage .subm { + background: #EEEEE5; + width: 150px; +} +article { + background: #fff; + line-height: 140%; + margin-bottom: 20px; + padding: 20px; +} +article aside { + float: left; + height: 48px; + margin-right: 10px; + width: 48px; +} +article aside img { + height: 48px; + width: 48px; +} +article time { + border-bottom: 1px dotted #999; + color: #999; + font-size: 10pt; +} +article p { + clear: left; + margin: 5px 0 15px 0; +} +article p.i { + text-align: center; +} +article p.ir { + float: right; + margin-bottom: 10px; + margin-left: 10px; +} +article p.ir a { + cursor: -moz-zoom-in; + cursor: -webkit-zoom-in; +} +article p.ir img { + max-height: 200px; + max-width: 200px; +} +article .irbr { + clear: right; +} +article>nav.l { + display: inline-block; + font-size: 10pt; +} +article>nav.l a { + border-bottom: 1px dotted #AAA; + color: #888; + margin-right: 15px; +} +article>nav.s { + display: inline-block; + float: right; + text-align: right; +} +article>nav.s a { + color: #222; + font-weight: bold; + vertical-align: middle; +} +article a.likes { + padding-left: 20px; +} +article a.replies { + margin-left: 18px; +} +article footer.comm { + margin: 13px 0 0 0; +} +article textarea { + border: 0; + height: 12pt; + min-height: 12pt; + padding: 2px; + resize: vertical; + vertical-align: top; + width: 530px; +} +article input { + background: #EEE; + border: 1px solid #CCC; + color: #999; + margin-left: 6px; + min-width: 50px; + vertical-align: top; +} +article .tags { + margin-top: 3px; +} +.msg-tags { + margin-top: 5px; +} +article .tags>a, .msg-tags>a { + border: 1px dotted #ccc; + color: #888; + display: inline-block; + font-size: 10pt; + margin-bottom: 5px; + margin-right: 5px; + padding: 0 10px; +} +#geomap { + height: 300px; + margin-top: 1em; + overflow: hidden; + width: 700px; +} +.msg { + margin: 10px 0 20px 0; +} +.ads { + background: #FFF; + margin: 8px 0 16px 58px; + padding: 13px 10px 5px 10px; +} +.msgthread { + margin-bottom: 0; +} +.msg-avatar { + float: left; + height: 48px; + margin-right: 10px; + width: 48px; +} +.msg-avatar img { + height: 48px; + vertical-align: top; + width: 48px; +} +.msg-cont { + background: #FFF; + line-height: 140%; + margin-bottom: 20px; + padding: 20px; + width: 640px; +} +.msg-menu { + float: right; + height: 16px; + margin-left: 10px; + margin-top: 2.4px; + width: 16px; +} +.msg-menu>a { + background: url("menu.png") no-repeat; + display: block; + height: 16px; + vertical-align: top; + width: 16px; +} +.msg-ts, article header.t { + float: right; + font-size: small; + vertical-align: top; +} +.msg-ts, .msg-ts>a { + color: #999; +} +.msg-place { + font-size: small; +} +.msg-place>a { + color: #999; +} +.msg-txt { + clear: both; + margin: 0 0 12px; + padding-top: 10px; +} +.msg-media { + text-align: center; +} +.msg-links { + color: #999; + font-size: small; + margin: 5px 0 0 0; +} +.msg-comments { + color: #AAA; + font-size: small; + margin-top: 10px; + overflow: hidden; + text-indent: 10px; +} +.ta-wrapper { + border: 1px solid #DDD; + display: inline-block; +} +.msg-comment textarea { + border: 0; + height: 12pt; + min-height: 12pt; + padding: 2px; + resize: vertical; + vertical-align: top; + width: 634px; +} +.msg-comment .narrow { + width: 554px; +} +.msg-comment .narrowpm { + width: 580px; +} +.attach-photo { + background: url("photo-attachment.png") no-repeat 3px 4px; + cursor: pointer; + display: inline-block; + height: 13px; + overflow: hidden; + padding: 2px 4px; + width: 16px; +} +.attach-photo-active { + background: url("photo-attachment-active.png") no-repeat 3px 4px; + cursor: pointer; + display: inline-block; + height: 13px; + overflow: hidden; + padding: 2px 4px; + width: 16px; +} +.msg-comment input { + background: #EEE; + border: 1px solid #CCC; + color: #999; + margin-left: 6px; + vertical-align: top; + width: 50px; +} +.msg-recomms { + color: #AAA; + font-size: small; + margin-top: 10px; + overflow: hidden; + text-indent: 10px; +} +.reply-new .msg-cont { + border-right: 5px solid #0C0; +} +q:before, q:after { + content: ""; +} +q { + border-left: 1px dashed #CCC; + color: #666; + display: block; + margin: 10px 0 10px 10px; + padding-left: 10px; +} +#mtoolbar { + background: #E5E5DD; + border-top: 1px solid #CCC; + width: 680px; +} +#mtoolbar ul, #mtoolbar a { + padding: 5px; +} +#mtoolbar li { + display: inline; +} +#mtoolbar div { + background: url("toolbar-icons.png") no-repeat; + display: inline-block; + height: 16px; + margin: 5px; + vertical-align: middle; + width: 16px; +} +#replies .msg-txt, #private-messages .msg-txt { + margin: 0; +} +.msg-comment { + margin-top: 10px; +} +.newmessage { + border: 1px solid #DDD; + padding: 2px; + resize: vertical; + width: 695px; +} +.users { + margin: 10px 0; + width: 100%; +} +.users td { + overflow: hidden; + padding: 6px 0; + width: 33%; +} +.users img { + height: 32px; + margin-right: 6px; + vertical-align: middle; + width: 32px; +} +.title2 { + background: #DDDDD0; + margin: 20px 0; + padding: 10px 20px; +} +.title2-right { + float: right; + line-height: 24px; +} +#content .title2 h2 { + font-size: x-large; + margin: 0; +} +.page { + background: #E5E5DD; + padding: 5px; + text-align: center; +} +.signup-h1>img { + margin-right: 10px; + vertical-align: middle; +} +.signup-h1 { + font-size: x-large; + margin: 20px 0 10px 0; +} +.signup-h2 { + font-size: large; + margin: 10px 0 5px 0; +} +.signup-hr { + margin: 20px 0; +} +.newpm { + margin: 20px 60px 30px 60px; +} +.newpm textarea { + resize: vertical; + width: 100%; +} +.newpm-send input { + width: 100px; +} +#column { + float: left; + margin-left: 10px; + overflow: hidden; + padding-top: 10px; + width: 240px; +} +#column ul, #column p, #column hr { + margin: 10px 0; +} +#column li { + margin: 6px 0; +} +#column .margtop { + margin-top: 15px; +} +#column p { + font-size: 10pt; + line-height: 140%; +} +#column .tags { + text-align: justify; +} +#column .inp { + background: #F5F5E9; + border: 1px solid #CCC; + border-radius: 3px; + padding: 3px; + width: 222px; +} +#ctitle { + font-size: 14pt; +} +#ctitle img { + margin-right: 5px; + vertical-align: middle; +} +#ctoolbar { + background: #E5E5DD; + line-height: 0; + margin: 10px 0; + padding: 5px; +} +#ctoolbar li { + display: inline; +} +#ctoolbar a { + padding: 5px 10px; +} +#ctoolbar div { + background: url("toolbar-icons.png") no-repeat; + display: inline-block; + height: 16px; + margin: 5px 0; + vertical-align: middle; + width: 16px; +} +#ustats li { + font-size: 10pt; + margin: 3px 0; +} +#column table.iread { + width: 100%; +} +#column table.iread td { + text-align: center; +} +#column table.iread img { + height: 48px; + width: 48px; +} +#dialogb { + background: #222; + height: 100%; + left: 0; + opacity: 0.6; + position: fixed; + top: 0; + width: 100%; + z-index: 10; +} +#dialogt { + height: 100%; + left: 0; + position: fixed; + top: 0; + width: 100%; + z-index: 10; +} +#dialogt td { + text-align: center; + vertical-align: middle; +} +#dialogw { + display: inline-block; + position: relative; + text-align: left; + z-index: 11; +} +#dialogc { + background: url("dialog-close.png"); + cursor: pointer; + height: 30px; + position: absolute; + right: -15px; + top: -15px; + width: 30px; + z-index: 12; +} +.dialoglogin { + background: #EEEEE5; + padding: 25px; + width: 300px; +} +#signfb,#signvk { + display: block; + height: 32px; + line-height: 32px; + margin: 10px 0; + overflow: hidden; + text-decoration: none; + text-indent: 37px; + width: 100%; +} +#signfb { + background: url("facebook.png") no-repeat #3A569C; + color: #FFF; +} +#signvk { + background: url("vk.png") no-repeat #6d8fb3; + color: #FFF; + margin-bottom: 30px; +} +.dialoglogin form { + margin-top: 7px; +} +.signinput,.signsubmit { + border: 1px solid #CCC; + margin: 3px 0; + padding: 3px; +} +.signinput { + width: 292px; +} +.signsubmit { + width: 70px; +} +.dialogshare { + background: #EEEEE5; + border: 1px solid #999; + min-width: 300px; + overflow: auto; + padding: 20px; +} +.dialogl { + background: #F5F5E9; + border: 1px solid #DDD; + margin: 3px 0 20px; + padding: 5px; +} +.dialogshare li { + float: left; + margin: 5px 10px 0 0; +} +.dialogshare a { + background-image: url("sharesocial.png"); + display: block; + height: 32px; + width: 32px; +} +.dialogtxt { + background: #EEEEE5; + padding: 20px; +} +#wsthread { + background: #CCC; + bottom: 20px; + cursor: pointer; + display: none; + padding: 5px 10px; + position: fixed; + right: 20px; +} +#footer { + clear: both; + color: #999; + font-size: 10pt; + margin: 0 auto 20px 0; + padding: 10px 0; + width: 1004px; +} +#footer-social { + float: left; +} +#footer-social a { + border: 0; + display: inline-block; + height: 32px; + margin: 0 15px 0 0; + overflow: hidden; + text-indent: 100%; + white-space: nowrap; + width: 32px; +} +#footer-left { + margin-left: 286px; + margin-right: 350px; +} +#footer-right { + float: right; +} +.sharenew { + color: #FFF; + display: inline-block; + line-height: 32px; + min-height: 32px; + min-width: 200px; + padding: 0 12px 0 37px; +} +.ico32-twi { + background: #55acee url("icon-twitter.png") no-repeat; +} +.ico32-vk { + background: #6d8fb3 url("icon-vk.png") no-repeat; +} +.ico32-fb { + background: #3b579d url("icon-fb.png") no-repeat; +} +.ico32-lj { + background: #888888 url("icon-lj.png") no-repeat; +} +.ico32-gp { + background: #dc4a38 url("icon-gplus.png") no-repeat; +} +.icon { + margin-top: -2px; + vertical-align: middle; +} +.icon--ei-comment { + margin-top: -3px; +} +fieldset { + border: 1px dotted #ccc; + margin-top: 25px; +} +@media screen and (max-width: 850px) { + body { + text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; + } + body,body>header,#topwrapper,#content,#footer,#mtoolbar { + float: none; + margin: 0 auto; + min-width: 310px; + width: auto; + } + body>header { + margin-bottom: 15px; + } + body>header a { + font-size: 12pt; + } + #logo { + display: none; + } + nav#global { + margin-left: 10px; + } + nav#global li { + margin-right: 10px; + } + #search { + display: inline-block; + float: none; + margin: 10px 10px; + } + #headdiv { + padding: 0 10px; + } + #headdiv li { + margin-right: 10px; + } + nav#actions { + position: relative; + right: auto; + } + #newmessage .img, #newmessage .tags { + width: 100%; + } + #column { + float: none; + margin: 0 10px; + padding-top: 0; + width: auto; + + } + article { + margin: 8px; + overflow: auto; + } + article p { + margin: 10px 0 8px 0; + } + article>nav.l { + display: block; + float: left; + line-height: 15pt; + width: 80%; + } + article>nav.s { + display: block; + } + article textarea { + width: 205px; + } + article footer { + float: left; + } + #content textarea { + width: 100%; + } + .msg,.msg-cont { + min-width: 280px; + width: auto; + } + .msg-cont,.ads { + margin: 8px; + } + .msg-comment textarea { + width: 100%; + } + .msg-media { + overflow: auto; + } + .title2 h2 { + font-size: large; + } + #footer { + margin: 0 10px; + } + #footer div { + float: none; + margin: 10px 0; + } +} +@media screen and (max-width: 480px) { + .msg-ts { + float: none; + } + .msg-tags { + margin-top: 10px; + } + .msg-txt { + padding-top: 5px; + } + .title2 { + font-size: 11pt; + } + #content .title2 h2 { + font-size: 11pt; + } + .title2-right { + line-height: initial; + } +} diff --git a/juick-spring-www/src/main/webapp/static/toolbar-icons.png b/juick-spring-www/src/main/webapp/static/toolbar-icons.png new file mode 100644 index 00000000..cd4efd45 Binary files /dev/null and b/juick-spring-www/src/main/webapp/static/toolbar-icons.png differ diff --git a/juick-spring-www/src/main/webapp/static/vk.png b/juick-spring-www/src/main/webapp/static/vk.png new file mode 100644 index 00000000..80b6920b Binary files /dev/null and b/juick-spring-www/src/main/webapp/static/vk.png differ diff --git a/juick-spring-www/webpack.config.js b/juick-spring-www/webpack.config.js new file mode 100644 index 00000000..acefc658 --- /dev/null +++ b/juick-spring-www/webpack.config.js @@ -0,0 +1,37 @@ +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/webapp/static/*.*", + require.resolve('evil-icons/assets/evil-icons.css'), + require.resolve('evil-icons/assets/evil-icons.js') + ]) + }, + output: { + path: __dirname + "/src/main/webapp", + filename: "[name].js" + }, + module: { + preLoaders: [ + { test: /\.jsx?$/, loader: 'eslint', exclude: /node_modules/ }, + { test: /\.css$/, loader: 'csslint?failOnWarning=false', exclude: /node_modules/ } + ], + loaders: [ + { test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader") }, + { test: /\.png$/, loader: "url-loader?limit=10000000000" }, + { test: /\.svg$/, loader: "url-loader?limit=10000000000" } + ] + }, + plugins: [ + new ExtractTextPlugin("style.css", { + allChunks: true + }) + ], + eslint: { + failOnWarning: false, + failOnError: true + }, +} \ No newline at end of file -- cgit v1.2.3