mirror of
https://github.com/Eggbertx/gochan.git
synced 2025-08-02 02:36:24 -07:00
Add HTML, JS, and JSON minification
Also remove that stupid filter for password input fields that Firefox (and maybe other browsers) adds
This commit is contained in:
parent
267a5eeb6f
commit
e361223084
18 changed files with 127 additions and 1177 deletions
3
build.sh
3
build.sh
|
@ -204,7 +204,8 @@ while [ -n "$1" ]; do
|
|||
github.com/aquilax/tripcode \
|
||||
golang.org/x/crypto/bcrypt \
|
||||
github.com/frustra/bbcode \
|
||||
github.com/mattn/go-sqlite3
|
||||
github.com/mattn/go-sqlite3 \
|
||||
github.com/tdewolff/minify
|
||||
;;
|
||||
docker-image)
|
||||
# echo "Docker image creation not yet implemented"
|
||||
|
|
|
@ -1,120 +1 @@
|
|||
h1#board-title {
|
||||
font-family: serif !important;
|
||||
font-size: 24pt;
|
||||
color: #AF0A0F;
|
||||
}
|
||||
|
||||
.postblock {
|
||||
background: #9988EE;
|
||||
}
|
||||
|
||||
div.file-info {
|
||||
font-size: 12px;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
.postername {
|
||||
font-size: 12px;
|
||||
font-family: serif;
|
||||
color: #117743;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.reply, .thread-ddown-menu {
|
||||
background: #D6DAF0;
|
||||
}
|
||||
|
||||
.thread-ddown-menu {
|
||||
border: 1px solid #9295a4;
|
||||
}
|
||||
|
||||
#site-title {
|
||||
font-family: sans-serif;
|
||||
padding-top: 88px;
|
||||
}
|
||||
|
||||
#site-slogan {
|
||||
font-size: 9pt;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.tab {
|
||||
background-color: #dfdffe;
|
||||
border: 1px solid #9295a4;
|
||||
}
|
||||
|
||||
#current-tab {
|
||||
margin-top: 16px;
|
||||
border-bottom: 0px;
|
||||
}
|
||||
|
||||
#current-tab, div.section-title-block {
|
||||
background-color: #bfc6e7;
|
||||
}
|
||||
|
||||
.loginbox input {
|
||||
height: 20%;
|
||||
}
|
||||
|
||||
.manage-header {
|
||||
background-color: #EEF2FF;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
body {
|
||||
font: sans-serif 12pt;
|
||||
background: #EEF2FF;
|
||||
margin: 8px;
|
||||
}
|
||||
|
||||
a, a:visited {
|
||||
color: #34345C;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 0px 0px 0px 0px;
|
||||
font-size: 140%;
|
||||
}
|
||||
|
||||
h2 a {
|
||||
text-decoration: none;
|
||||
color: #550;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0px;
|
||||
text-align: center;
|
||||
font-size: medium;
|
||||
}
|
||||
|
||||
h1, h2 {
|
||||
font-family: Verdana, Tahoma, sans-serif;
|
||||
}
|
||||
|
||||
h1, h2, h3 {
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
div#topbar {
|
||||
-moz-box-shadow: 3px 3px 5px 6px #555555;
|
||||
-ms-box-shadow: 3px 3px 5px 6px #555555;
|
||||
-webkit-box-shadow: 3px 3px 5px 6px #555555;
|
||||
box-shadow: 3px 3px 5px 6px #555555;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
div#topbar, .topbar-item, .topbar-item:visited, .dropdown-button, .dropdown-menu, .dropdown-menu a {
|
||||
background-color: #000A89;
|
||||
color: #EEF2FF !important;
|
||||
}
|
||||
|
||||
div#footer {
|
||||
font-size: 8pt;
|
||||
}
|
||||
h1#board-title{font-family:serif !important;font-size:24pt;color:#af0a0f}.postblock{background:#98e}div.file-info{font-size:12px;font-family:sans-serif}.postername{font-size:12px;font-family:serif;color:#117743;font-weight:800}.reply,.thread-ddown-menu{background:#d6daf0}.thread-ddown-menu{border:1px solid #9295a4}#site-title{font-family:sans-serif;padding-top:88px}#site-slogan{font-size:9pt;font-style:italic}.tab{background-color:#dfdffe;border:1px solid #9295a4}#current-tab{margin-top:16px;border-bottom:0px}#current-tab,div.section-title-block{background-color:#bfc6e7}.loginbox input{height:20%}.manage-header{background-color:#eef2ff;border-radius:8px}body{font:sans-serif 12pt;background:#eef2ff;margin:8px}a,a:visited{color:#34345c;text-decoration:none}h1{margin:0;text-align:center}h2{margin:0px 0px 0px 0px;font-size:140%}h2 a{text-decoration:none;color:#550}h3{margin:0px;text-align:center;font-size:medium}h1,h2{font-family:Verdana,Tahoma,sans-serif}h1,h2,h3{font-weight:bold;color:#333}div#topbar{-moz-box-shadow:3px 3px 5px 6px #555;-ms-box-shadow:3px 3px 5px 6px #555;-webkit-box-shadow:3px 3px 5px 6px #555;box-shadow:3px 3px 5px 6px #555;height:30px}div#topbar,.topbar-item,.topbar-item:visited,.dropdown-button,.dropdown-menu,.dropdown-menu a{background-color:#000a89;color:#eef2ff !important}div#footer{font-size:8pt}
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,217 +1 @@
|
|||
@import url(http://fonts.googleapis.com/css?family=Walter+Turncoat);
|
||||
#site-title {
|
||||
color: #ff0;
|
||||
font-size: 50px;
|
||||
}
|
||||
|
||||
#top-pane {
|
||||
height: 75px;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#topmenu {
|
||||
left: 16%;
|
||||
position: absolute;
|
||||
top: 76px;
|
||||
}
|
||||
|
||||
#topmenu li {
|
||||
background-color: #F0E0D6;
|
||||
border: 1px solid #9295a4;
|
||||
border-left: none;
|
||||
color: maroon;
|
||||
display: block;
|
||||
float: left;
|
||||
margin-top: -7px;
|
||||
padding: 3px 10px 2px;
|
||||
}
|
||||
|
||||
#topmenu li.current {
|
||||
background-color: #d0c0c6;
|
||||
border-bottom: none;
|
||||
margin-top: -8px;
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
#topmenu li.first {
|
||||
border-left: 1px solid #F0E0D6;
|
||||
}
|
||||
|
||||
.content {
|
||||
margin-left: 0 !important;
|
||||
padding-left: 0 !important;
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
.newssub {
|
||||
background-color: #D0C0C6;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.permalink {
|
||||
display: block;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.permalink a {
|
||||
color: blue;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
ul.boardmenu li:hover, ul.modmenulink li:hover {
|
||||
background: #C6DAF0;
|
||||
}
|
||||
|
||||
ul.boardmenu, ul.modmenulink, div#topmenu ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.file-info {
|
||||
background: inherit;
|
||||
color: #CC1105;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
#board-title {
|
||||
color: maroon;
|
||||
font-size: 2em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.manage-header {
|
||||
background: #AA6;
|
||||
color: #400000;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.omittedposts {
|
||||
color: #707070;
|
||||
}
|
||||
|
||||
.passvalid {
|
||||
background: #000;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.postblock {
|
||||
background: #000;
|
||||
color: #fff;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.postername {
|
||||
color: #117743;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.postertrip {
|
||||
color: #228854;
|
||||
}
|
||||
|
||||
.postlists {
|
||||
background: #FFF;
|
||||
color: maroon;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.reply {
|
||||
background: #F0E0D6;
|
||||
color: maroon;
|
||||
}
|
||||
|
||||
.replytitle {
|
||||
color: #CC1105;
|
||||
font-size: 1.2em;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.theader {
|
||||
background: #E04000;
|
||||
color: #FFF;
|
||||
padding: 2px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.file-deleted-box {
|
||||
color: maroon;
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
.greentext {
|
||||
background: inert;
|
||||
color: #789922;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #D00;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: #135;
|
||||
color: #fff;
|
||||
font-family: "comic sans ms", "Walter Turncoat", cursive;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #000;
|
||||
font-size: 150%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h1, h2 {
|
||||
color: white;
|
||||
}
|
||||
|
||||
h1, h3, .menu {
|
||||
font-family: Verdana, Tahoma, sans-serif;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 100%;
|
||||
margin: 1em 0 0;
|
||||
}
|
||||
|
||||
h2 a {
|
||||
color: #550;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
h3 {
|
||||
color: #800;
|
||||
font-size: medium;
|
||||
font-weight: 400;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #ff0;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
li {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
li a {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.footer {
|
||||
font-family: serif;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
@import"http://fonts.googleapis.com/css?family=Walter+Turncoat";#site-title{color:#ff0;font-size:50px}#top-pane{height:75px;left:0;position:absolute;text-align:center;top:0;width:100%}#topmenu{left:16%;position:absolute;top:76px}#topmenu li{background-color:#f0e0d6;border:1px solid #9295a4;border-left:none;color:maroon;display:block;float:left;margin-top:-7px;padding:3px 10px 2px}#topmenu li.current{background-color:#d0c0c6;border-bottom:none;margin-top:-8px;padding-top:5px}#topmenu li.first{border-left:1px solid #f0e0d6}.content{margin-left:0 !important;padding-left:0 !important;text-align:justify}.newssub{background-color:#d0c0c6;position:absolute}.permalink{display:block;text-align:right}.permalink a{color:blue;text-decoration:none}ul.boardmenu li:hover,ul.modmenulink li:hover{background:#c6daf0}ul.boardmenu,ul.modmenulink,div#topmenu ul{list-style:none;margin:0;padding-left:0}.file-info{background:inherit;color:#cc1105;font-weight:800}#board-title{color:maroon;font-size:2em;text-align:center}.manage-header{background:#aa6;color:#400000;padding:0}.omittedposts{color:#707070}.passvalid{background:#000;color:#fff;text-align:center;width:100%}.postblock{background:#000;color:#fff;font-weight:800}.postername{color:#117743;font-weight:700}.postertrip{color:#228854}.postlists{background:#fff;color:maroon;padding:0;width:100%}.reply{background:#f0e0d6;color:maroon}.replytitle{color:#cc1105;font-size:1.2em;font-weight:800}.theader{background:#e04000;color:#fff;padding:2px;text-align:center;width:100%}.file-deleted-box{color:maroon;font-size:small}.greentext{background:inert;color:#789922}a:hover{color:#d00}body{margin:0;padding:0;background:#135;color:#fff;font-family:"comic sans ms","Walter Turncoat",cursive}h1{color:#000;font-size:150%;margin:0}h1,h2{color:#fff}h1,h3,.menu{font-family:Verdana,Tahoma,sans-serif}h2{font-size:100%;margin:1em 0 0}h2 a{color:#550;text-decoration:none}h3{color:#800;font-size:medium;font-weight:400;margin:0;text-align:center}a{color:#ff0;text-decoration:none}li{margin:0}li a{display:block;width:100%}.footer{font-family:serif;font-size:12px;text-align:center}
|
||||
|
|
|
@ -1,59 +1 @@
|
|||
div.reply {
|
||||
background-color: #ddd;
|
||||
border: 1px solid #ccc;
|
||||
-moz-border-radius: 5px;
|
||||
-ms-border-radius: 5px;
|
||||
-webkit-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
span.subject {
|
||||
color: #024;
|
||||
}
|
||||
|
||||
div.section-title-block {
|
||||
background-color: #ccc;
|
||||
}
|
||||
|
||||
div.section-block {
|
||||
-moz-border-radius: 5px;
|
||||
-ms-border-radius: 5px;
|
||||
-webkit-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
background-color: #FCFCFC;
|
||||
border: 1px solid #D7D7D7;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #eee;
|
||||
font: 15px "Trebuchet MS", Trebuchet, sans-serif;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
div#topbar, div.dropdown-menu {
|
||||
background-color: #000;
|
||||
opacity: 0.7;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
div#topbar {
|
||||
-moz-box-shadow: 0px 2px 2px 2px #292929;
|
||||
-ms-box-shadow: 0px 2px 2px 2px #292929;
|
||||
-webkit-box-shadow: 0px 2px 2px 2px #292929;
|
||||
box-shadow: 0px 2px 2px 2px #292929;
|
||||
}
|
||||
|
||||
div.dropdown-menu {
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
header, div#top-pane, a {
|
||||
color: #f60;
|
||||
}
|
||||
|
||||
span#site-title, div#board-title {
|
||||
font-weight: 800;
|
||||
}
|
||||
div.reply{background-color:#ddd;border:1px solid #ccc;-moz-border-radius:5px;-ms-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}span.subject{color:#024}div.section-title-block{background-color:#ccc}div.section-block{-moz-border-radius:5px;-ms-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;background-color:#fcfcfc;border:1px solid #d7d7d7}body{background-color:#eee;font:15px "Trebuchet MS",Trebuchet,sans-serif}a{text-decoration:none}div#topbar,div.dropdown-menu{background-color:#000;opacity:.7;padding:2px}div#topbar{-moz-box-shadow:0px 2px 2px 2px #292929;-ms-box-shadow:0px 2px 2px 2px #292929;-webkit-box-shadow:0px 2px 2px 2px #292929;box-shadow:0px 2px 2px 2px #292929}div.dropdown-menu{color:#fff}header,div#top-pane,a{color:#f60}span#site-title,div#board-title{font-weight:800}
|
||||
|
|
|
@ -1,172 +1 @@
|
|||
.dropdown-button:hover {
|
||||
background-color: #404040;
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
background-color: #202020;
|
||||
box-shadow: 2px 2px 2px 3px #101010;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.section-body {
|
||||
background-color: #606060;
|
||||
}
|
||||
|
||||
.section-title-block {
|
||||
background-color: #202020;
|
||||
border-radius: 4px 8px 4px 8px;
|
||||
}
|
||||
|
||||
.tab {
|
||||
background-color: #404040 !important;
|
||||
border: 1px solid #202020;
|
||||
}
|
||||
|
||||
#current-tab {
|
||||
background-color: #202020 !important;
|
||||
}
|
||||
|
||||
div#recent-posts-header {
|
||||
-moz-box-shadow: 0px 2px 2px 3px #101010;
|
||||
-ms-box-shadow: 0px 2px 2px 3px #101010;
|
||||
-webkit-box-shadow: 0px 2px 2px 3px #101010;
|
||||
box-shadow: 0px 2px 2px 3px #101010;
|
||||
margin-bottom: 8px;
|
||||
padding: 4px 8px 4px 8px;
|
||||
}
|
||||
|
||||
.postblock {
|
||||
background-color: #202020;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.loginbox input {
|
||||
height: 20%;
|
||||
}
|
||||
|
||||
.manage-header {
|
||||
background-color: #202020;
|
||||
-moz-box-shadow: 2px 2px 3px 4px #101010;
|
||||
-ms-box-shadow: 2px 2px 3px 4px #101010;
|
||||
-webkit-box-shadow: 2px 2px 3px 4px #101010;
|
||||
box-shadow: 2px 2px 3px 4px #101010;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.dropdown-button:hover {
|
||||
background-color: #404040;
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
background-color: #202020;
|
||||
-moz-box-shadow: 2px 2px 2px 3px #101010;
|
||||
-ms-box-shadow: 2px 2px 2px 3px #101010;
|
||||
-webkit-box-shadow: 2px 2px 2px 3px #101010;
|
||||
box-shadow: 2px 2px 2px 3px #101010;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
ul.staffmenu li:hover {
|
||||
background: #404040;
|
||||
}
|
||||
|
||||
img.thumbnail {
|
||||
float: left;
|
||||
max-width: 100%;
|
||||
margin: 5px 10px 10px 0px;
|
||||
}
|
||||
|
||||
.reply, .inlinepostprev, .postprev {
|
||||
background-color: #25272D;
|
||||
border: 1px solid #8C94AB;
|
||||
}
|
||||
|
||||
.postblock {
|
||||
background-color: #25272D;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.postername {
|
||||
color: #FC0;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.postername a {
|
||||
color: #ffcc00 !important;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.subject {
|
||||
color: #F90;
|
||||
}
|
||||
|
||||
.thread-ddown a {
|
||||
font-size: 75%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.tripcode {
|
||||
color: #FC0;
|
||||
}
|
||||
|
||||
form#postform input[type=text], form#postform input[type=password], form#postform input[type=file], form#postform textarea, form#postform .thread-ddown-menu {
|
||||
background-color: #25272D;
|
||||
border: 1px solid #8C94AB;
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
.thread-ddown-menu, input#reason, input#password {
|
||||
background-color: #25272D;
|
||||
border: 1px solid #8C94AB;
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
.thread-ddown-menu li:hover {
|
||||
background-color: #404040;
|
||||
}
|
||||
|
||||
* {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #363942;
|
||||
background-image: url(res/pipes_bg.png);
|
||||
color: #d8d0b9;
|
||||
font: 12pt sans-serif;
|
||||
}
|
||||
|
||||
header h1, span#site-title {
|
||||
color: #e1b400;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #f90;
|
||||
font: 12pt sans-serif;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
background: inherit;
|
||||
color: #ffd43f;
|
||||
}
|
||||
|
||||
a.topbar-item:hover {
|
||||
background-color: #404040;
|
||||
}
|
||||
|
||||
div#footer, div#footer * {
|
||||
font-size: 9pt;
|
||||
}
|
||||
|
||||
div#topbar {
|
||||
background-color: #202020;
|
||||
-moz-box-shadow: 0px 2px 2px 3px #101010;
|
||||
-ms-box-shadow: 0px 2px 2px 3px #101010;
|
||||
-webkit-box-shadow: 0px 2px 2px 3px #101010;
|
||||
box-shadow: 0px 2px 2px 3px #101010;
|
||||
z-index: 9001;
|
||||
}
|
||||
div#topbar li:hover {
|
||||
background-color: #404040;
|
||||
}
|
||||
.dropdown-button:hover{background-color:#404040}.dropdown-menu{background-color:#202020;box-shadow:2px 2px 2px 3px #101010;z-index:0}.section-body{background-color:#606060}.section-title-block{background-color:#202020;border-radius:4px 8px 4px 8px}.tab{background-color:#404040 !important;border:1px solid #202020}#current-tab{background-color:#202020 !important}div#recent-posts-header{-moz-box-shadow:0px 2px 2px 3px #101010;-ms-box-shadow:0px 2px 2px 3px #101010;-webkit-box-shadow:0px 2px 2px 3px #101010;box-shadow:0px 2px 2px 3px #101010;margin-bottom:8px;padding:4px 8px 4px 8px}.postblock{background-color:#202020;font-weight:700}.loginbox input{height:20%}.manage-header{background-color:#202020;-moz-box-shadow:2px 2px 3px 4px #101010;-ms-box-shadow:2px 2px 3px 4px #101010;-webkit-box-shadow:2px 2px 3px 4px #101010;box-shadow:2px 2px 3px 4px #101010;border-radius:8px}.dropdown-button:hover{background-color:#404040}.dropdown-menu{background-color:#202020;-moz-box-shadow:2px 2px 2px 3px #101010;-ms-box-shadow:2px 2px 2px 3px #101010;-webkit-box-shadow:2px 2px 2px 3px #101010;box-shadow:2px 2px 2px 3px #101010;z-index:0}ul.staffmenu li:hover{background:#404040}img.thumbnail{float:left;max-width:100%;margin:5px 10px 10px 0px}.reply,.inlinepostprev,.postprev{background-color:#25272d;border:1px solid #8c94ab}.postblock{background-color:#25272d;font-weight:700}.postername{color:#fc0;font-weight:700}.postername a{color:#fc0 !important;text-decoration:underline}.subject{color:#f90}.thread-ddown a{font-size:75%;vertical-align:middle}.tripcode{color:#fc0}input:not([type=submit]):not([type=button]),textarea,select,.thread-ddown-menu{background-color:#25272d;border:1px solid #8c94ab;color:#fff;filter:none}.thread-ddown-menu{background-color:#25272d;border:1px solid #8c94ab;color:#fff}.thread-ddown-menu li:hover{background-color:#404040}*{outline:none}body{background-color:#363942;background-image:url(res/pipes_bg.png);color:#d8d0b9;font:12pt sans-serif}header h1,span#site-title{color:#e1b400}a{color:#f90;font:12pt sans-serif;text-decoration:none}a:hover{background:inherit;color:#ffd43f}a.topbar-item:hover{background-color:#404040}div#footer,div#footer *{font-size:9pt}div#topbar{background-color:#202020;-moz-box-shadow:0px 2px 2px 3px #101010;-ms-box-shadow:0px 2px 2px 3px #101010;-webkit-box-shadow:0px 2px 2px 3px #101010;box-shadow:0px 2px 2px 3px #101010;z-index:9001}div#topbar li:hover{background-color:#404040}
|
||||
|
|
|
@ -7,6 +7,6 @@
|
|||
<h1>404: File not found</h1>
|
||||
<img src="/error/lol 404.gif" border="0" alt="">
|
||||
<p>The requested file could not be found on this server. Are you just typing random stuff in the address bar? If you followed a link from this site here, then post <a href="/site">here</a></p>
|
||||
<hr><address>http://gochan.org powered by Gochan v2.9.0</address>
|
||||
<hr><address>http://gochan.org powered by Gochan v2.11.0</address>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -7,6 +7,6 @@
|
|||
<h1>500: Internal Server error</h1>
|
||||
<img src="/error/derpy server.gif" border="0" alt="">
|
||||
<p>The server encountered an error while trying to serve the page, and we apologize for the inconvenience. The <a href="https://en.wikipedia.org/wiki/Idiot">system administrator</a> will try to fix things as soon has he/she/it can.</p>
|
||||
<hr><address>http://gochan.org powered by Gochan v2.9.0</address>
|
||||
<hr><address>http://gochan.org powered by Gochan v2.11.0</address>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -4,6 +4,6 @@ If you want, you can install [Sass](https://sass-lang.com/install) to streamline
|
|||
To use sass, run `sass --style expanded --no-source-map sass:html/css`.
|
||||
To have sass watch the input directory for changes as you edit and save the files, run `sass --style expanded --no-source-map --watch sass:html/css`
|
||||
|
||||
In either case, `--style expanded` is optional. Run `sass -h` for more info about it.
|
||||
In either case, `--style expanded` is optional. If you replace expanded with compressed, it will minify the generated CSS files. Run `sass -h` for more info about it.
|
||||
|
||||
If you are upgading from gochan 2.2, delete your html/css directory unless you have made themes that you want to keep. Then rebuild the pages. (/manage?action=rebuildall)
|
|
@ -54,15 +54,14 @@ img.thumbnail {
|
|||
color: #FC0;
|
||||
}
|
||||
|
||||
form#postform {
|
||||
input[type=text], input[type=password], input[type=file], textarea, .thread-ddown-menu {
|
||||
background-color: #25272D;
|
||||
border: 1px solid #8C94AB;
|
||||
color: #FFF;
|
||||
}
|
||||
input:not([type=submit]):not([type=button]), textarea, select, .thread-ddown-menu {
|
||||
background-color: #25272D;
|
||||
border: 1px solid #8C94AB;
|
||||
color: #FFF;
|
||||
filter: none;
|
||||
}
|
||||
|
||||
.thread-ddown-menu, input#reason, input#password {
|
||||
.thread-ddown-menu {
|
||||
background-color: #25272D;
|
||||
border: 1px solid #8C94AB;
|
||||
color: #FFF;
|
||||
|
|
|
@ -5,13 +5,60 @@ package main
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/tdewolff/minify"
|
||||
minifyHTML "github.com/tdewolff/minify/html"
|
||||
minifyJS "github.com/tdewolff/minify/js"
|
||||
minifyJSON "github.com/tdewolff/minify/json"
|
||||
)
|
||||
|
||||
var minifier *minify.M
|
||||
|
||||
func initMinifier() {
|
||||
if !config.MinifyHTML && !config.MinifyJS {
|
||||
return
|
||||
}
|
||||
minifier = minify.New()
|
||||
if config.MinifyHTML {
|
||||
minifier.AddFunc("text/html", minifyHTML.Minify)
|
||||
}
|
||||
if config.MinifyJS {
|
||||
minifier.AddFunc("text/javascript", minifyJS.Minify)
|
||||
minifier.AddFunc("application/json", minifyJSON.Minify)
|
||||
}
|
||||
}
|
||||
|
||||
func canMinify(mediaType string) bool {
|
||||
return (mediaType == "text/html" && config.MinifyHTML) || ((mediaType == "application/json" || mediaType == "text/javascript") && config.MinifyJS)
|
||||
}
|
||||
|
||||
func minifyTemplate(tmpl *template.Template, data interface{}, writer io.Writer, mediaType string) error {
|
||||
if !canMinify(mediaType) {
|
||||
return tmpl.Execute(writer, data)
|
||||
}
|
||||
|
||||
minWriter := minifier.Writer(mediaType, writer)
|
||||
defer minWriter.Close()
|
||||
return tmpl.Execute(minWriter, data)
|
||||
}
|
||||
|
||||
func minifyWriter(writer io.Writer, data []byte, mediaType string) (int, error) {
|
||||
if !canMinify(mediaType) {
|
||||
return writer.Write(data)
|
||||
}
|
||||
|
||||
minWriter := minifier.Writer(mediaType, writer)
|
||||
defer minWriter.Close()
|
||||
return minWriter.Write(data)
|
||||
}
|
||||
|
||||
// build front page using templates/front.html
|
||||
func buildFrontPage() string {
|
||||
err := initTemplates("front")
|
||||
|
@ -71,12 +118,12 @@ func buildFrontPage() string {
|
|||
}
|
||||
}
|
||||
|
||||
if err = frontPageTmpl.Execute(frontFile, map[string]interface{}{
|
||||
if err = minifyTemplate(frontPageTmpl, map[string]interface{}{
|
||||
"config": config,
|
||||
"sections": allSections,
|
||||
"boards": allBoards,
|
||||
"recent_posts": recentPostsArr,
|
||||
}); err != nil {
|
||||
}, frontFile, "text/html"); err != nil {
|
||||
return handleError(1, "Failed executing front page template: "+err.Error())
|
||||
}
|
||||
return "Front page rebuilt successfully."
|
||||
|
@ -105,7 +152,8 @@ func buildBoardListJSON() (html string) {
|
|||
if err != nil {
|
||||
return handleError(1, "Failed marshal to JSON: "+err.Error()) + "<br />\n"
|
||||
}
|
||||
if _, err = boardListFile.Write(boardJSON); err != nil {
|
||||
|
||||
if _, err = minifyWriter(boardListFile, boardJSON, "application/json"); err != nil {
|
||||
return handleError(1, "Failed writing boards.json file: "+err.Error()) + "<br />\n"
|
||||
}
|
||||
return "Board list JSON rebuilt successfully.<br />"
|
||||
|
@ -237,13 +285,13 @@ func buildBoardPages(board *Board) (html string) {
|
|||
|
||||
// Render board page template to the file,
|
||||
// packaging the board/section list, threads, and board info
|
||||
if err = boardpageTmpl.Execute(boardPageFile, map[string]interface{}{
|
||||
if err = minifyTemplate(boardpageTmpl, map[string]interface{}{
|
||||
"config": config,
|
||||
"boards": allBoards,
|
||||
"sections": allSections,
|
||||
"threads": threads,
|
||||
"board": board,
|
||||
}); err != nil {
|
||||
}, boardPageFile, "text/html"); err != nil {
|
||||
html += handleError(1, "Failed building /"+board.Dir+"/: "+err.Error()) + "<br />"
|
||||
return
|
||||
}
|
||||
|
@ -280,8 +328,8 @@ func buildBoardPages(board *Board) (html string) {
|
|||
continue
|
||||
}
|
||||
|
||||
// Render the boardpage template, don't forget config
|
||||
if err = boardpageTmpl.Execute(currentPageFile, map[string]interface{}{
|
||||
// Render the boardpage template
|
||||
if err = minifyTemplate(boardpageTmpl, map[string]interface{}{
|
||||
"config": config,
|
||||
"boards": allBoards,
|
||||
"sections": allSections,
|
||||
|
@ -290,7 +338,7 @@ func buildBoardPages(board *Board) (html string) {
|
|||
"posts": []interface{}{
|
||||
Post{BoardID: board.ID},
|
||||
},
|
||||
}); err != nil {
|
||||
}, currentPageFile, "text/html"); err != nil {
|
||||
html += handleError(1, "Failed building /"+board.Dir+"/ boardpage: "+err.Error()) + "<br />"
|
||||
return
|
||||
}
|
||||
|
@ -382,7 +430,7 @@ func buildJSConstants() string {
|
|||
return handleError(1, "Error opening '"+jsPath+"' for writing: "+err.Error())
|
||||
}
|
||||
|
||||
if err = jsTmpl.Execute(jsFile, config); err != nil {
|
||||
if err = minifyTemplate(jsTmpl, config, jsFile, "text/javascript"); err != nil {
|
||||
return handleError(1, "Error building '"+jsPath+"': "+err.Error())
|
||||
}
|
||||
return "Built '" + jsPath + "' successfully."
|
||||
|
@ -416,13 +464,13 @@ func buildCatalog(which int) string {
|
|||
}
|
||||
threadPages := paginate(config.PostsPerThreadPage, threadInterfaces)
|
||||
|
||||
if err = catalogTmpl.Execute(catalogFile, map[string]interface{}{
|
||||
if err = minifyTemplate(catalogTmpl, map[string]interface{}{
|
||||
"boards": allBoards,
|
||||
"config": config,
|
||||
"board": board,
|
||||
"sections": allSections,
|
||||
"threadPages": threadPages,
|
||||
}); err != nil {
|
||||
}, catalogFile, "text/html"); err != nil {
|
||||
return handleError(1, "Error building catalog for /%s/: %s", board.Dir, err.Error())
|
||||
}
|
||||
return fmt.Sprintf("Built catalog for /%s/ successfully", board.Dir)
|
||||
|
@ -471,14 +519,14 @@ func buildThreadPages(op *Post) (html string) {
|
|||
}
|
||||
|
||||
// render main page
|
||||
if err = threadpageTmpl.Execute(currentPageFile, map[string]interface{}{
|
||||
if err = minifyTemplate(threadpageTmpl, map[string]interface{}{
|
||||
"config": config,
|
||||
"boards": allBoards,
|
||||
"board": board,
|
||||
"sections": allSections,
|
||||
"posts": replies,
|
||||
"op": op,
|
||||
}); err != nil {
|
||||
}, currentPageFile, "text/html"); err != nil {
|
||||
html += handleError(1, "Failed building /%s/res/%d threadpage: %s", board.Dir, op.ID, err.Error()) + "<br />\n"
|
||||
return
|
||||
}
|
||||
|
@ -520,14 +568,14 @@ func buildThreadPages(op *Post) (html string) {
|
|||
return
|
||||
}
|
||||
|
||||
if err = threadpageTmpl.Execute(currentPageFile, map[string]interface{}{
|
||||
if err = minifyTemplate(threadpageTmpl, map[string]interface{}{
|
||||
"config": config,
|
||||
"boards": allBoards,
|
||||
"board": board,
|
||||
"sections": allSections,
|
||||
"posts": pagePosts,
|
||||
"op": op,
|
||||
}); err != nil {
|
||||
}, currentPageFile, "text/html"); err != nil {
|
||||
html += handleError(1, "<br />Failed building /%s/%d: %s", board.Dir, op.ID, err.Error())
|
||||
return
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ func serveCaptcha(writer http.ResponseWriter, request *http.Request) {
|
|||
if useJSON {
|
||||
writer.Header().Add("Content-Type", "application/json")
|
||||
str, _ := marshalJSON("", captchaStruct, false)
|
||||
writer.Write([]byte(str))
|
||||
minifyWriter(writer, []byte(str), "application/json")
|
||||
return
|
||||
}
|
||||
if request.FormValue("reload") == "Reload" {
|
||||
|
@ -93,7 +93,7 @@ func serveCaptcha(writer http.ResponseWriter, request *http.Request) {
|
|||
captchaStruct.Result = "Incorrect CAPTCHA"
|
||||
}
|
||||
}
|
||||
if err = captchaTmpl.Execute(writer, captchaStruct); err != nil {
|
||||
if err = minifyTemplate(captchaTmpl, captchaStruct, writer, "text/html"); err != nil {
|
||||
handleError(0, customError(err))
|
||||
fmt.Fprintf(writer, "Error executing captcha template")
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ func main() {
|
|||
}
|
||||
}()
|
||||
initConfig()
|
||||
initMinifier()
|
||||
printf(0, "Starting gochan v%s.%s, using verbosity level %d\n", versionStr, buildtimeString, config.Verbosity)
|
||||
connectToSQLServer()
|
||||
parseCommandLine()
|
||||
|
|
|
@ -373,7 +373,8 @@ var manageFunctions = map[string]ManageFunction{
|
|||
config.ImagesOpenNewTab = (request.PostFormValue("ImagesOpenNewTab") == "on")
|
||||
config.MakeURLsHyperlinked = (request.PostFormValue("MakeURLsHyperlinked") == "on")
|
||||
config.NewTabOnOutlinks = (request.PostFormValue("NewTabOnOutlinks") == "on")
|
||||
config.EnableQuickReply = (request.PostFormValue("EnableQuickReply") == "on")
|
||||
config.MinifyHTML = (request.PostFormValue("MinifyHTML") == "on")
|
||||
config.MinifyJS = (request.PostFormValue("MinifyJS") == "on")
|
||||
config.DateTimeFormat = request.PostFormValue("DateTimeFormat")
|
||||
AkismetAPIKey := request.PostFormValue("AkismetAPIKey")
|
||||
|
||||
|
@ -383,6 +384,20 @@ var manageFunctions = map[string]ManageFunction{
|
|||
config.AkismetAPIKey = AkismetAPIKey
|
||||
}
|
||||
|
||||
config.UseCaptcha = (request.PostFormValue("UseCaptcha") == "on")
|
||||
CaptchaWidth, err := strconv.Atoi(request.PostFormValue("CaptchaWidth"))
|
||||
if err != nil {
|
||||
status += err.Error() + "<br />\n"
|
||||
} else {
|
||||
config.CaptchaWidth = CaptchaWidth
|
||||
}
|
||||
CaptchaHeight, err := strconv.Atoi(request.PostFormValue("CaptchaHeight"))
|
||||
if err != nil {
|
||||
status += err.Error() + "<br />\n"
|
||||
} else {
|
||||
config.CaptchaHeight = CaptchaHeight
|
||||
}
|
||||
|
||||
config.EnableGeoIP = (request.PostFormValue("EnableGeoIP") == "on")
|
||||
config.GeoIPDBlocation = request.PostFormValue("GeoIPDBlocation")
|
||||
|
||||
|
|
|
@ -583,10 +583,9 @@ func makePost(writer http.ResponseWriter, request *http.Request) {
|
|||
if isBanned(banStatus, boards[post.BoardID-1].Dir) {
|
||||
var banpageBuffer bytes.Buffer
|
||||
|
||||
banpageBuffer.Write([]byte(""))
|
||||
if err = banpageTmpl.Execute(&banpageBuffer, map[string]interface{}{
|
||||
if err = minifyTemplate(banpageTmpl, map[string]interface{}{
|
||||
"config": config, "ban": banStatus, "banBoards": boards[post.BoardID-1].Dir,
|
||||
}); err != nil {
|
||||
}, writer, "text/html"); err != nil {
|
||||
writer.Write([]byte(handleError(1, err.Error())))
|
||||
return
|
||||
}
|
||||
|
@ -748,14 +747,10 @@ func banHandler(writer http.ResponseWriter, request *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
var banpageBuffer bytes.Buffer
|
||||
|
||||
banpageBuffer.Write([]byte(""))
|
||||
if err = banpageTmpl.Execute(&banpageBuffer, map[string]interface{}{
|
||||
if err = minifyTemplate(banpageTmpl, map[string]interface{}{
|
||||
"config": config, "ban": banStatus, "banBoards": banStatus.Boards, "post": Post{},
|
||||
}); err != nil {
|
||||
}, writer, "text/html"); err != nil {
|
||||
fmt.Fprintf(writer, handleError(1, err.Error())+"\n</body>\n</html>")
|
||||
return
|
||||
}
|
||||
writer.Write(banpageBuffer.Bytes())
|
||||
}
|
||||
|
|
|
@ -38,19 +38,26 @@ func (s GochanServer) serveFile(writer http.ResponseWriter, request *http.Reques
|
|||
}
|
||||
|
||||
//the file exists, or there is a folder here
|
||||
var extension string
|
||||
if results.IsDir() {
|
||||
//check to see if one of the specified index pages exists
|
||||
var found bool
|
||||
for _, value := range config.FirstPage {
|
||||
newPath := path.Join(filePath, value)
|
||||
_, err := os.Stat(newPath)
|
||||
if err == nil {
|
||||
filePath = newPath
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
serveNotFound(writer, request)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
//the file exists, and is not a folder
|
||||
extension := strings.ToLower(getFileExtension(request.URL.Path))
|
||||
extension = strings.ToLower(getFileExtension(request.URL.Path))
|
||||
switch extension {
|
||||
case "png":
|
||||
writer.Header().Add("Content-Type", "image/png")
|
||||
|
@ -88,7 +95,15 @@ func (s GochanServer) serveFile(writer http.ResponseWriter, request *http.Reques
|
|||
writer.Header().Add("Cache-Control", "max-age=5, must-revalidate")
|
||||
fileBytes, _ = ioutil.ReadFile(filePath)
|
||||
writer.Header().Add("Cache-Control", "max-age=86400")
|
||||
writer.Write(fileBytes)
|
||||
if extension == "html" {
|
||||
minifyWriter(writer, fileBytes, "text/html")
|
||||
} else if extension == "js" {
|
||||
minifyWriter(writer, fileBytes, "text/javascript")
|
||||
} else if extension == "json" {
|
||||
minifyWriter(writer, fileBytes, "application/json")
|
||||
} else {
|
||||
writer.Write(fileBytes)
|
||||
}
|
||||
}
|
||||
|
||||
func serveNotFound(writer http.ResponseWriter, request *http.Request) {
|
||||
|
@ -96,21 +111,21 @@ func serveNotFound(writer http.ResponseWriter, request *http.Request) {
|
|||
writer.WriteHeader(404)
|
||||
errorPage, err := ioutil.ReadFile(config.DocumentRoot + "/error/404.html")
|
||||
if err != nil {
|
||||
_, _ = writer.Write([]byte("Requested page not found, and 404 error page not found"))
|
||||
writer.Write([]byte("Requested page not found, and 404 error page not found"))
|
||||
} else {
|
||||
_, _ = writer.Write(errorPage)
|
||||
minifyWriter(writer, errorPage, "text/html")
|
||||
}
|
||||
errorLog.Print("Error: 404 Not Found from " + getRealIP(request) + " @ " + request.URL.Path)
|
||||
}
|
||||
|
||||
func serveErrorPage(writer http.ResponseWriter, err string) {
|
||||
errorpageTmpl.Execute(writer, map[string]interface{}{
|
||||
minifyTemplate(errorpageTmpl, map[string]interface{}{
|
||||
"config": config,
|
||||
"ErrorTitle": "Error :c",
|
||||
// "ErrorImage": "/error/lol 404.gif",
|
||||
"ErrorHeader": "Error",
|
||||
"ErrorText": err,
|
||||
})
|
||||
}, writer, "text/html")
|
||||
}
|
||||
|
||||
func (s GochanServer) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
|
||||
|
|
|
@ -337,7 +337,9 @@ type GochanConfig struct {
|
|||
ImagesOpenNewTab bool `description:"If checked, thumbnails will open the respective image/video in a new tab instead of expanding them." default:"unchecked"`
|
||||
MakeURLsHyperlinked bool `description:"If checked, URLs in posts will be turned into a hyperlink. If unchecked, ExpandButton and NewTabOnOutlinks are ignored." default:"checked"`
|
||||
NewTabOnOutlinks bool `description:"If checked, links to external sites will open in a new tab." default:"checked"`
|
||||
EnableQuickReply bool `description:"If checked, an optional quick reply box is used. This may end up being removed." default:"checked"`
|
||||
|
||||
MinifyHTML bool `description:"If checked, gochan will minify html files when building" default:"checked"`
|
||||
MinifyJS bool `description:"If checked, gochan will minify js and json files when building" default:"checked"`
|
||||
|
||||
DateTimeFormat string `description:"The format used for dates. See <a href=\"https://golang.org/pkg/time/#Time.Format\">here</a> for more info." default:"Mon, January 02, 2006 15:04 PM"`
|
||||
AkismetAPIKey string `description:"The API key to be sent to Akismet for post spam checking. If the key is invalid, Akismet won't be used."`
|
||||
|
|
2
version
2
version
|
@ -1 +1 @@
|
|||
2.10.0
|
||||
2.11.0
|
Loading…
Add table
Add a link
Reference in a new issue