holy shit

This commit is contained in:
Pachira 2015-05-25 18:18:56 +00:00
parent 03f66078e1
commit 99cbeecb38
29 changed files with 1954 additions and 1546 deletions

View file

@ -2,12 +2,4 @@
_A backend that doesn't suck_
## What this will have
- Code that doesn't suck dick.
- All the (good) features of the old backend
- Templating!
- PDO!
- Groups (different from ranks)
Now with 100% more open source!
I'll write a more descriptive readme once it's in a stable state.

View file

@ -13,7 +13,8 @@
"20150509.1",
"20150512",
"20150523",
"20150524"
"20150524",
"20150525"
]
@ -1103,6 +1104,43 @@
"change": "Made the manage footer sticky to the bottom."
}
],
"20150525": [
{
"type": "FIX",
"change": "Made the registration recaptcha refresh upon failure."
},
{
"type": "ADD",
"change": "Added a JavaScript port of the password entropy function."
},
{
"type": "FIX",
"change": "Made maximum and minimum username length configurable."
},
{
"type": "UPD",
"change": "Split Yuuno CSS up in multiple files."
},
{
"type": "UPD",
"change": "Changed the icons displayed on the side of the index when logged out."
},
{
"type": "ADD",
"change": "Added JavaScript form checking to registration form."
},
{
"type": "ADD",
"change": "Added smooth scroll to top thing."
},
{
"type": "FIX",
"change": "Fixed subnet matching causing an error."
}
]
}

View file

@ -364,7 +364,7 @@ class Main {
public static function checkCFIP($ip) {
// Get CloudFlare Subnet list
$cfhosts = file_get_contents(Configuration::getLocalConfig('etc', 'cfhosts'));
$cfhosts = file_get_contents(Configuration::getLocalConfig('etc', 'cfipv'. (self::ipVersion($ip))));
// Replace \r\n with \n
$cfhosts = str_replace("\r\n", "\n", $cfhosts);

View file

@ -211,11 +211,11 @@ class Users {
return [0, 'USER_EXISTS'];
// Username too short
if(strlen($username) < 3)
if(strlen($username) < Configuration::getConfig('username_min_length'))
return [0, 'NAME_TOO_SHORT'];
// Username too long
if(strlen($username) > 16)
if(strlen($username) > Configuration::getConfig('username_max_length'))
return [0, 'NAME_TOO_LONG'];
// Check if the given email address is formatted properly

View file

@ -11,9 +11,4 @@
198.41.128.0/17
162.158.0.0/15
104.16.0.0/12
172.64.0.0/13
2400:cb00::/32
2606:4700::/32
2803:f800::/32
2405:b500::/32
2405:8100::/32
172.64.0.0/13

View file

@ -0,0 +1,5 @@
2400:cb00::/32
2606:4700::/32
2803:f800::/32
2405:b500::/32
2405:8100::/32

View file

@ -42,20 +42,17 @@ api = api.yourdomain.com
; Content location
content = content.yourdomain.com
; Management panel location
manage = manage.yourdomain.com
; Forum location
forum = forum.yourdomain.com
; Chat location
chat = chat.yourdomain.com
; Data files relative to the _sakura directory
[data]
; File containing CloudFlare CIDRs
cfhosts = config/cloudflare.hosts
; File containing CloudFlare IPv4 CIDRs
cfipv4 = config/cloudflare.ipv4
; File containing CloudFlare IPv6 CIDRs
cfipv6 = config/cloudflare.ipv6
; JSON file containing WHOIS servers
whoisservers = config/whois.json

View file

@ -24,7 +24,8 @@ $sakuraConf['urls']['forum'] = 'forum.flashii.net'; // Forum url
// Errata
$sakuraConf['etc'] = array();
$sakuraConf['etc']['cfhosts'] = ROOT .'_sakura/config/cloudflare.hosts'; // Cloudflare IP subnets file
$sakuraConf['etc']['cfipv4'] = ROOT .'_sakura/config/cloudflare.ipv4'; // Cloudflare IPv4 subnets file
$sakuraConf['etc']['cfipv6'] = ROOT .'_sakura/config/cloudflare.ipv6'; // Cloudflare IPv6 subnets file
$sakuraConf['etc']['whoisservers'] = ROOT .'_sakura/config/whois.json'; // JSON with Whois servers
$sakuraConf['etc']['iso3166'] = ROOT .'_sakura/config/iso3166.json'; // JSON with country codes

View file

@ -8,7 +8,7 @@
namespace Sakura;
// Define Sakura version
define('SAKURA_VERSION', '20150524');
define('SAKURA_VERSION', '20150525');
define('SAKURA_VLABEL', 'Eminence');
define('SAKURA_VTYPE', 'Development');
define('SAKURA_COLOUR', '#6C3082');
@ -75,7 +75,10 @@ $renderData = array(
'sitetags' => implode(", ", json_decode(Configuration::getConfig('sitetags'), true)),
'cookieprefix' => Configuration::getConfig('cookie_prefix'),
'cookiedomain' => Configuration::getConfig('cookie_domain'),
'cookiepath' => Configuration::getConfig('cookie_path')
'cookiepath' => Configuration::getConfig('cookie_path'),
'minpwdentropy' => Configuration::getConfig('min_entropy'),
'minusernamelength' => Configuration::getConfig('username_min_length'),
'maxusernamelength' => Configuration::getConfig('username_max_length')
],
'php' => [
'sessionid' => \session_id(),

View file

@ -11,11 +11,16 @@
{% if sakura.lockauth %}
<div class="head">Whoops!</div>
You caught the site at the wrong moment! Right now registration <i>and</i> logging in is disabled for unspecified reasons. Sorry for the inconvenience but please try again later!
<div class="indexSidePanelLinks">
<a class="fa fa-lock" href="#" title="Authentication is locked"></a>
</div>
{% else %}
<div class="head">Welcome!</div>
Welcome to Flashii! This is a site for a bunch of friends to hang out, nothing special. Anyone is pretty much welcome to register so why not have a go?
<a class="button registerbutton" href="//{{ sakura.urls.main }}/register">Register!</a>
<a class="button loginbutton" href="//{{ sakura.urls.main }}/login">Login</a>
<div class="indexSidePanelLinks">
<a class="fa fa-magic" href="//{{ sakura.urls.main }}/register" title="Register" id="indexSidePanelRegister"></a>
<a class="fa fa-sign-in" href="//{{ sakura.urls.main }}/login" title="Login" id="indexSidePanelLogin"></a>
</div>
{% endif %}
{% endif %}
<div class="head">Stats</div>

View file

@ -13,7 +13,6 @@
<!-- CSS -->
<link rel="stylesheet" type="text/css" href="//{{ sakura.urls.content }}/global.css" />
<link rel="stylesheet" type="text/css" href="{{ sakura.resources }}/css/yuuno.css" />
<link rel="stylesheet" type="text/css" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" />
{% if page.style %}
<style type="text/css">
{% for element,properties in page.style %}
@ -50,7 +49,10 @@
},
"checklogin": {% if user.checklogin %}true{% else %}false{% endif %}
"minUserLen": {{ sakura.minusernamelength }},
"maxUserLen": {{ sakura.maxusernamelength }},
"minPwdEntropy": {{ sakura.minpwdentropy }},
"checklogin": {% if user.checklogin %}true{% else %}false{% endif %}
};
@ -119,6 +121,11 @@
// Space for things that need to happen onload
window.onload = function() {
// Alter the go to top button
var gotop = document.getElementById('gotop');
gotop.setAttribute('href', 'javascript:void(0);');
gotop.setAttribute('onclick', 'scrollToTop();');
// Login form under header and ajax logout
initHeaderLoginForm();
@ -148,7 +155,7 @@
form.setAttribute('onkeydown', 'formEnterCatch(event, \''+ submit.id +'\');');
submit.setAttribute('href', 'javascript:void(0);');
submit.setAttribute('onclick', 'submitPost(\''+ i +'\', true, \''+ forms[i] +'\');');
submit.setAttribute('onclick', 'submitPost(\''+ i +'\', true, \''+ forms[i] +'\', '+ (i == 'registerForm' ? 'true' : 'false') +');');
submit.setAttribute('type', 'button');
var createInput = document.createElement('input');

View file

@ -77,25 +77,25 @@
<label for="registerUserName">Username:</label>
</div>
<div class="centreAlign">
<input class="inputStyling" type="text" id="registerUserName" name="username" placeholder="Any character" />
<input class="inputStyling" type="text" id="registerUserName" name="username" onkeyup="registerVarCheck(this.id, 'username');" placeholder="Any character" />
</div>
<div class="leftAlign">
<label for="registerEmail">E-mail:</label>
</div>
<div class="centreAlign">
<input class="inputStyling" type="text" id="registerEmail" name="email" placeholder="Used for e.g. password retrieval" />
<input class="inputStyling" type="text" id="registerEmail" name="email" onkeyup="registerVarCheck(this.id, 'email');" placeholder="Used for e.g. password retrieval" />
</div>
<div class="leftAlign">
<label for="registerPassword">Password:</label>
</div>
<div class="centreAlign">
<input class="inputStyling" type="password" id="registerPassword" name="password" placeholder="Using special characters is recommended" />
<input class="inputStyling" type="password" id="registerPassword" name="password" onkeyup="registerVarCheck(this.id, 'password');" placeholder="Using special characters is recommended" />
</div>
<div class="leftAlign">
<label for="registerConfirmPassword">Confirm Password:</label>
</div>
<div class="centreAlign">
<input class="inputStyling" type="password" id="registerConfirmPassword" name="confirmpassword" placeholder="Just to make sure" />
<input class="inputStyling" type="password" id="registerConfirmPassword" name="confirmpassword" onkeyup="registerVarCheck(this.id, 'confirmpw', 'registerPassword');" placeholder="Just to make sure" />
</div>
{% if sakura.requireregcodes %}
<div class="leftAlign">
@ -119,10 +119,10 @@
<iframe src="https://www.google.com/recaptcha/api/fallback?k={{ sakura.recaptcha_public }}" frameborder="0" scrolling="no" style="width: 302px; height:352px; border-style: none;"></iframe>
</div>
<div style="width: 250px; height: 80px; position: absolute; border-style: none; bottom: 21px; left: 25px; margin: 0px; padding: 0px; right: 25px;">
<textarea id="g-recaptcha-response" name="g-recaptcha-response" class="g-recaptcha-response" style="width: 250px; height: 80px; border: 1px solid #c1c1c1; margin: 0px; padding: 0px; resize: none;" value=""></textarea>
<textarea id="g-recaptcha-response" name="g-recaptcha-response" class="g-recaptcha-response" style="width: 250px; height: 80px; border: 1px solid #c1c1c1; margin: 0px; padding: 0px; resize: none;" value=""></textarea>
</div>
</div>
</div>
</div>
</noscript>
</div>
{% endif %}

View file

@ -0,0 +1,77 @@
/*
* Authentication page Styling
*/
@charset "utf-8";
.loginPage {
margin: 0 auto;
max-width: 825px;
}
.loginPage > .registerCont > *,
.loginPage > .loginCont > * {
text-align: center;
border: 1px solid #9475B2;
margin: 10px auto;
padding: 2px 3px;
width: 400px;
border: 1px solid #9475B2;
box-shadow: 0 0 3px #9475B2;
border-radius: 3px;
background: #D3BFFF;
}
@media (max-width: 430px) {
.loginPage > .registerCont > *,
.loginPage > .loginCont > * {
width: 300px;
}
}
.loginPage > .loginCont {
float: left;
}
.loginPage > .registerCont {
float: right;
}
@media (max-width: 820px) {
.loginPage > .loginCont {
float: none;
}
.loginPage > .registerCont {
float: none;
}
}
.loginPage .head {
text-align: left;
}
.loginPage > div > form > div > input {
font-size: 16px;
}
.loginPage input[type="text"],
.loginPage input[type="password"] {
width: calc(100% - 16px);
}
.loginPage form > div > label {
font-size: 20px;
font-weight: 100;
padding: 0 5px;
line-height: 32px;
color: #222;
text-shadow: #888 0 0 3px;
}
.loginPage .subLinks {
font-size: 10px;
}

View file

@ -0,0 +1,416 @@
/*
* Standard Elements
*/
@charset "utf-8";
* {
/* Reset margin and padding */
margin: 0;
padding: 0;
}
html {
width: 100%;
height: 100%;
}
body {
font: 12px/20px Verdana, sans-serif;
background: linear-gradient(180deg, #C2AFFE, #FBEEFF) no-repeat scroll left top #FBEEFF;
background-size: cover;
color: #000;
height: 100%;
position: relative;
width: 100%;
}
#container {
min-height: 100%;
position: relative;
width: 100%;
}
#contentwrapper {
padding-bottom: 220px;
}
@media (max-width: 642px) {
#contentwrapper {
padding-bottom: 335px;
}
}
@media (max-width: 426px) {
#contentwrapper {
padding-bottom: 450px;
}
}
@media (max-width: 400px) {
#contentwrapper {
padding-bottom: 450px;
}
}
@media (max-width: 300px) {
.footer {
display: none;
}
#contentwrapper {
padding-bottom: 0;
}
}
.clear {
clear: both !important;
float: none !important;
}
.hidden {
display: none !important;
visibility: hidden !important;
}
.centreAlign {
text-align: center;
}
.leftAlign {
text-align: left;
}
.rightAlign {
text-align: right;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: "Segoe UI", sans-serif;
font-weight: 100;
margin: 5px 0;
}
h1.stylised {
text-shadow: 0 0 5px #8364A1;
color: #614390;
}
hr.default {
border: 0;
height: 1px;
color: #9475B2;
background: #9475B2;
}
img {
max-width: 100%;
max-height: 100%;
}
img.default-avatar-setting {
max-width: 200px;
max-height: 200px;
border: 3px solid #EEE;
background: #EEE;
box-shadow: 0 3px 7px #888;
border-radius: 3px;
margin: 5px;
}
img.homepage-menu-avatar {
float: right;
max-width: 100px;
max-width: 100px;
margin-top: -25px;
margin-right: 0;
}
@media (max-width: 400px) {
img.homepage-menu-avatar {
display: none;
}
}
.standalone img:not(:hover) {
max-width: 100%;
}
a.clean,
a.underline,
a.no-underline {
color: inherit !important;
text-decoration: none !important;
}
a.underline:hover {
text-decoration: underline !important;
}
a.default {
color: #22E;
text-decoration: none;
}
a.default:hover {
color: #22E;
text-decoration: underline;
}
a.default:active {
color: #E22;
text-decoration: underline;
}
a.gotop {
display: inline-block;
background: #111;
color: #FFF;
width: 60px;
height: 60px;
border-radius: 5px;
text-decoration: none;
opacity: .3;
transition: opacity .5s, box-shadow .5s;
margin: 10px 5px;
float: right;
position: fixed;
bottom: 0;
right: 5px;
z-index: 2;
line-height: 60px;
text-align: center;
font-size: 5em;
text-shadow: 0 0 5px #FFF;
}
a.gotop:hover {
opacity: .8;
box-shadow: 0 0 7px #FFF inset;
text-shadow: 0 0 7px #FFF;
}
a.gotop:active {
box-shadow: 0 0 15px #FFF inset;
text-shadow: 0 0 10px #FFF;
opacity: .9;
}
a.gotop.enter {
animation: slideInFromRight 1 .6s;
}
a.gotop.exit {
animation: slideOutToBottom 1 .6s;
}
.content {
margin: 10px auto;
padding: 2px 3px;
width: 1024px;
border: 1px solid #9475B2;
box-shadow: 0 0 3px #9475B2;
border-radius: 3px;
background: #D3BFFF;
}
.content-column {
position: relative;
min-height: 600px;
}
.content-left {
float: left;
width: 688px;
}
.content-right {
float: right;
width: 334px;
}
.content-left .head,
.news .head,
.donate .head,
.loginPage > .loginCont .head,
.messages .head {
margin: -1px -2px;
padding: 4px 5px 5px;
font-weight: 700;
font-size: 20px;
color: #306;
background: linear-gradient(90deg, rgba(148,117,178,.7), rgba(148,117,178,0)) #C2AFFE;
border-radius: 2px;
}
.content-right .head,
.loginPage > .registerCont .head {
margin: -1px -2px -1px;
padding: 4px 5px 5px;
font-weight: 700;
font-size: 20px;
color: #306;
background: linear-gradient(270deg, rgba(148,117,178,.7), rgba(148,117,178,0)) #C2AFFE;
border-radius: 2px;
}
.standalone {
background: #C2AEEE;
padding: 10px;
width: auto;
max-width: 1024px;
}
.private-message {
border-top: 1px solid #C2AEEE;
}
.ajax-busy {
background: rgba(0, 0, 0, .4);
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
z-index: 5;
text-align: center;
opacity: 1;
}
.ajax-busy .ajax-inner {
line-height: 2em;
color: #FFF;
background: #222;
background: linear-gradient(0deg, rgba(0, 0, 0, .4) 20%, transparent) rgba(0, 0, 0, .8);
display: inline-block;
margin: 10% auto 0;
padding: 10px 20px 15px;
border-radius: 10px;
box-shadow: 0 5px 1em #111;
}
.ajax-busy .ajax-inner h2 {
padding-bottom: 5px;
}
.homepage .content-right ul {
margin: 10px 0;
margin-left: 30px;
}
.dropDown {
display: inline-block;
position: relative;
}
.dropDown .dropDownInner {
display: inline-block;
background: rgba(12, 12, 12, .7);
min-width: 200px;
border: 2px solid #9475B2;
float: left;
font-family: "Segoe UI", sans-serif;
text-align: left;
margin: 0 2px;
transition: background .5s;
}
.dropDown .dropDownInner:hover {
background: rgba(21, 21, 21, .8);
}
.dropDown .dropDownInner a {
padding: 0 1px 0 4px;
display: none;
color: #FFF;
text-decoration: none;
clear: both;
transition: background .2s;
}
.dropDown .dropDownInner a:hover {
background: rgba(21, 21, 21, .5);
}
.dropDown .dropDownInner a:active {
background: rgba(21, 21, 21, .7);
}
.dropDown .dropDownInner a.dropDownSelected {
display: inline-block;
}
.dropDown .dropDownInner:hover a {
display: block;
float: none;
}
.dropDown .dropDownInner a.dropDownDesc {
display: inline-block;
}
.dropDown .dropDownInner:hover a.dropDownDesc {
display: none;
}
#headerLoginForm {
background: #9475B2;
border-bottom: 2px solid #9475B2;
box-shadow: 0 0 5px #8364A1;
text-align: center;
}
#headerLoginForm > div {
display: inline-block;
}
@media (max-width: 640px) {
#headerLoginForm > div {
display: block;
text-align: right;
padding-right: 2px;
}
}
#headerLoginForm label {
font-family: "Segoe UI", sans-serif;
font-weight: 100;
font-size: 15px;
}
.indexSidePanelLinks {
font-size: 4em;
text-align: center;
line-height: 1.3em;
}
.indexSidePanelLinks > a {
color: #8364A1;
text-decoration: none;
text-shadow: 0 0 2px #9475B2;
transition: all .2s;
}
.indexSidePanelLinks > a:hover {
text-shadow: 0 0 6px #9475B2;
}
.indexSidePanelLinks > a:active {
color: #725390;
text-shadow: 0 0 8px #8364A1;
}

View file

@ -0,0 +1,65 @@
/*
* Donation page Styling
*/
@charset "utf-8";
.donate .sectionHeader {
margin: -1px -2px;
background: linear-gradient(270deg, rgba(148, 117, 178, .7), rgba(148, 117, 178, 0), rgba(148, 117, 178, .7)) #C2AFFE;
padding: 2px;
font-weight: 700;
font-size: 15px;
color: #306;
}
.donate .featureParent {
width: 100%;
padding: 10px 0;
overflow: hidden;
text-align: center;
}
.donate .featureBox {
background: linear-gradient(180deg, #C2AFFE, #B19EED) no-repeat scroll left top / cover #C2AFFE;
margin: 7px;
border-radius: 5px;
text-align: center;
box-shadow: 0 0 .5em #000;
display: inline-block;
vertical-align: top;
transition: box-shadow .2s;
width: 320px;
padding: 5px 0;
}
.donate .featureBox:hover {
box-shadow: 0 0 1em #000;
cursor: pointer;
}
.donate .featureBox:active {
box-shadow: 0 0 1.5em #609;
}
.donate .featureBoxHeader {
font-weight: 700;
font-size: 15px;
}
.donate .featureBoxDesc {
padding: 1px 2px;
}
.donate .featureBoxDesc.donateClosed {
display: none;
}
.donate .featureBoxDesc.donateOpened {
display: block;
}
.donate .paypal-donate-form {
margin: 10px auto;
display: block;
text-align: center;
}

View file

@ -0,0 +1,53 @@
/*
* Site footer styling
*/
@charset "utf-8";
.footer {
box-shadow: 0 0 1em #9475B2;
font-size: small;
width: 100%;
padding-top: 10px;
padding-bottom: 30px;
background: linear-gradient(180deg, #9475B2 0%, #FBEEFF 20%, #C2AFFE 100%) #C2AFFE;
position: absolute;
bottom: 0;
}
.footer .ftsections a {
color: inherit;
text-decoration: none;
}
.footer .ftsections a:hover {
text-decoration: underline;
}
.footer .ftsections {
margin: auto;
text-align: center;
width: 95%;
min-height: 150px;
}
.footer .ftsections .ftsection {
vertical-align: top;
text-align: left;
display: inline-block;
width: 200px;
list-style-type: none;
}
.footer .ftsections .ftsection li {
margin: 2px;
}
.footer .ftsections .ftsection li.fthead {
margin-bottom: 5px;
font-weight: 700;
}
.footer .sections .copycentre {
text-align: center;
width: 100%;
}

View file

@ -0,0 +1,78 @@
/*
* Forum Styling
*/
@charset "utf-8";
.forum .forumList {
width: 100%;
border-spacing: 0;
margin-top: 2px;
}
.forum .forumList .forumCategory {
background: #C2AFFE;
font-weight: 700;
font-size: 17px;
color: inherit;
text-decoration: none;
}
.forum .forumList .forumCategory .forumCategoryTitleColumn {
padding: 4px;
}
.forum .forumList .forumForum {
height: 50px;
}
.forum .forumList .forumForum .forumIconColumn {
text-align: center;
width: 50px;
}
.forum .forumList .forumForum .forumIconColumn .forumIcon.read {
color: #444;
text-shadow: 0 0 5px #444;
}
.forum .forumList .forumForum .forumIconColumn .forumIcon.unread {
color: #6C5D7B;
text-shadow: 0 0 5px #9475B2;
}
.forum .forumList .forumForum .forumTitleColumn .name {
font-size: 1.2em;
line-height: 1.7em;
}
.forum .forumList .forumForum .forumTitleColumn .desc {
font-size: .8em;
line-height: 1em;
}
.forum .forumList .forumForum .forumCountColumn {
width: 70px;
text-align: center;
}
.forum .forumList .forumForum .forumCountColumn .topics {
font-size: 1.5em;
color: #111;
}
.forum .forumList .forumForum .forumCountColumn .posts {
font-size: .8em;
line-height: 1.2em;
color: #555;
}
.forum .forumList .forumForum .forumLastColumn {
width: 250px;
font-size: .9em;
line-height: 1.4em;
}
.forum .forumList .forumForum .forumLastColumn div,
.forum .forumList .forumForum .forumTitleColumn div {
padding-left: 5px;
}

View file

@ -0,0 +1,185 @@
/*
* Site header styling
*/
@charset "utf-8";
.header {
text-align: center;
background: linear-gradient(180deg, #C2AFFE, #CCBAFE);
box-shadow: 0 0 5px #8364A1;
}
.header .logo {
background: none;
height: auto;
width: auto;
display: inline-block;
text-decoration: none;
font: 100 70px/80px "Segoe UI", sans-serif;
color: #B06AC4;
transition: color .2s, text-shadow .2s;
}
.header .logo:hover {
color: #C17BD5;
text-shadow: 0 0 .1em #C17BD5;
}
.header .logo:active {
color: #A059B3;
text-shadow: 0 0 .1em #A059B3;
}
@media (max-width: 768px) {
.header .logo {
font: 100 50px/60px "Segoe UI", sans-serif;
}
}
.header .menu {
border-bottom: 2px solid #9475B2;
}
.header .menu .menu-nav {
text-align: left;
float: left;
}
.header .menu .menu-ucp {
text-align: right;
float: right;
}
.header .menu .menu-mob {
display: none;
}
.header .menu .menu-item {
margin: 0 8px -2px;
display: inline-block;
min-width: 75px;
padding: 5px;
border-bottom: 2px solid #8364A1;
color: inherit;
text-decoration: none;
text-align: center;
transition: border-color .5s, background .3s;
}
.header .menu .menu-item.avatar {
width: auto;
padding-left: 36px;
background: url('/pixel.png') no-repeat scroll left center / contain transparent;
}
.header .menu .menu-item:hover {
border-color: #503180 !important;
}
.header .menu .menu-item:active {
border-color: #503180 !important;
background-color: #503180 !important;
}
.header .menu .menu-donate:hover {
border-color: #EE9400 !important;
}
.header .menu .menu-donate:active {
border-color: #EE9400 !important;
background-color: #EE9400 !important;
}
@media (max-width: 1283px) and (min-width: 930px) {
.header .menu {
border: 0;
padding-bottom: 5px;
}
.header .menu .menu-nav {
margin-left: 32px;
}
.header .menu .menu-nav,
.header .menu .menu-ucp {
display: block;
float: none;
text-align: center;
}
.header .menu .menu-item {
min-width: 120px;
border: 0;
margin: 0 8px;
}
.header .menu .menu-nav .menu-item {
min-width: 120px;
border-bottom: 1px solid #8364A1;
}
.header .menu .menu-ucp .menu-item {
min-width: 120px;
border-top: 1px solid #8364A1;
}
}
@media (max-width: 930px) {
.header .menu .menu-nav, .header .menu .menu-ucp {
float: none;
text-align: center;
display: none;
}
.header .menu .menu-hid {
display: block;
}
.header .menu .menu-mob {
display: block;
}
.header .menu .menu-item.avatar {
padding-left: 0;
}
.header .menu .menu-mob .menu-item {
width: 100px;
}
.header .menu .menu-nav .menu-item, .header .menu .menu-ucp .menu-item {
display: block;
border-top: 0;
border-bottom: 1px solid #8364A1;
margin: 0 8px;
}
.header .menu .menu-nav:before {
content: "Navigation";
font-size: 20px;
line-height: 40px;
}
.header .menu .menu-ucp:before {
content: "User Settings";
font-size: 20px;
line-height: 40px;
}
}
.headerNotify {
margin: 10px auto;
padding: 10px;
width: auto;
max-width: 1024px;
border: 1px solid #9475B2;
box-shadow: 0 0 3px #9475B2;
border-radius: 3px;
background: #D3BFFF;
display: block;
text-align: center;
}

View file

@ -0,0 +1,74 @@
/*
* Input box Styling
*/
@charset "utf-8";
input[type="submit"].inputStyling,
input[type="button"].inputStyling,
input[type="reset"].inputStyling {
padding: 3px 10px;
cursor: pointer;
border: 0;
border-radius: 3px;
background: linear-gradient(180deg, #9475B2 0%, #9475B2 50%, #86A 50%) #9475B2;
margin: 4px 1px;
color: #FFF;
box-shadow: inset #222 0 0 1px;
text-shadow: #888 0 0 2px;
transition: text-shadow .5s, box-shadow .5s;
font-size: 22px;
min-width: 120px;
}
input[type="submit"].inputStyling.small,
input[type="button"].inputStyling.small,
input[type="reset"].inputStyling.small {
padding: 0 4px 1px;
margin: -2px 0 0;
font-size: 16px;
border-radius: 0;
min-width: 80px !important;
}
input[type="submit"].inputStyling:hover,
input[type="button"].inputStyling:hover,
input[type="reset"].inputStyling:hover {
box-shadow: inset #222 0 0 3px;
text-shadow: #F1F1F1 0 0 5px;
}
input[type="submit"].inputStyling:active,
input[type="button"].inputStyling:active,
input[type="reset"].inputStyling:active {
box-shadow: inset #222 0 0 5px;
text-shadow: #F1F1F1 0 0 3px;
transition: text-shadow .2s, box-shadow .2s;
}
input[type="text"].inputStyling,
input[type="password"].inputStyling ,
input[type="date"].inputStyling {
padding: 3px 4px;
border: 1px solid #CCC;
box-shadow: inset #DDD 0 0 5px;
background: linear-gradient(180deg, #FFF 0%, #EEE 50%, #E5E5E5 50%) #FFF;
}
input[type="text"].inputStyling.red,
input[type="password"].inputStyling.red,
input[type="date"].inputStyling.red {
box-shadow: inset 0px 0px 7px #EB5959;
}
input[type="text"].inputStyling.green,
input[type="password"].inputStyling.green,
input[type="date"].inputStyling.green {
box-shadow: inset 0px 0px 7px #A9EC8B;
}
textarea.inputStyling {
padding: 3px 4px;
border: 1px solid #CCC;
box-shadow: inset #DDD 0 0 5px;
background: linear-gradient(180deg, #FFF 0%, #EEE 50%, #E5E5E5 50%) #FFF;
}

View file

@ -0,0 +1,71 @@
/*
* Animation Keyframes
*/
@charset "utf-8";
/* Spin */
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
/* Fade out */
@keyframes fadeOut {
0% {
opacity: 1;
}
100% {
opacity: 0;
display: none;
}
}
/* Fade in */
@keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
display: block;
}
}
/* Slide in from right */
@keyframes slideInFromRight { /* Requires position: relative to be set on the element */
0% {
right: -100%;
}
100% {
right: 0%;
}
}
/* Slide out to bottom */
@keyframes slideOutToBottom { /* Read comment above */
0% {
bottom: 0%;
}
100% {
bottom: -100%;
}
}

View file

@ -0,0 +1,121 @@
/*
* Markdown Styling
*/
@charset "utf-8";
.markdown {
font: 12px/1.4 "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif;
word-wrap: break-word;
}
.markdown a {
color: #00F;
text-decoration: none;
}
.markdown a:hover {
color: #00F;
text-decoration: underline;
}
.markdown a:active {
color: #F00;
text-decoration: underline;
}
.markdown h1,
.markdown h2,
.markdown h3,
.markdown h4,
.markdown h5,
.markdown h6 {
border-bottom: 1px solid;
padding-bottom: 5px;
font-weight: 700;
}
.markdown p,
.markdown blockquote,
.markdown ul,
.markdown ol,
.markdown dl,
.markdown table,
.markdown pre {
margin-top: 0;
margin-bottom: 16px;
}
.markdown hr {
border: 0;
height: 1px;
color: #000;
background: #000;
margin: 0;
}
.markdown table {
display: block;
width: 100%;
overflow: auto;
word-break: keep-all;
border-collapse: collapse;
border-spacing: 0;
}
.markdown table tr {
border-spacing: 0;
border: 1px solid #9475B2;
}
.markdown table th,
.markdown table td {
padding: 6px 13px;
border: 1px solid #9475B2;
}
.markdown table tr:nth-child(even) {
background: #B19DDD;
}
.markdown hr {
background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAECAYAAACtBE5DAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OENDRjNBN0E2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OENDRjNBN0I2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4Q0NGM0E3ODY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4Q0NGM0E3OTY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PqqezsUAAAAfSURBVHjaYmRABcYwBiM2QSA4y4hNEKYDQxAEAAIMAHNGAzhkPOlYAAAAAElFTkSuQmCC') repeat-x scroll 0 0 transparent;
border: 0 none;
color: #CCC;
height: 4px;
padding: 0;
margin: 15px 0;
}
.markdown blockquote {
border-left: 4px solid #9475B2;
padding: 0 15px;
color: #555;
}
.markdown blockquote > blockquote {
margin-left: 0;
}
.markdown blockquote > :last-child {
margin-bottom: 0;
}
.markdown pre {
word-wrap: normal;
}
.markdown .highlight pre,
.markdown pre {
background: #B19DDD;
border: 1px solid #9475B2;
font-size: 13px;
line-height: 19px;
overflow: auto;
padding: 6px 10px;
border-radius: 3px;
}
.markdown ul,
.markdown ol {
margin-left: 40px;
}

View file

@ -0,0 +1,103 @@
/*
* Members page Styling
*/
@charset "utf-8";
.membersPage {
width: 100%;
padding: 10px 0;
overflow: hidden;
text-align: center;
}
.membersPage a {
color: inherit;
}
.membersPage .userBox {
background: linear-gradient(180deg, #C2AFFE, #B19EED) no-repeat scroll left top / cover #C2AFFE;
margin: 7px;
border-radius: 5px;
text-align: center;
box-shadow: 0 0 .5em #000;
display: inline-block;
vertical-align: top;
transition: box-shadow .2s;
}
.membersPage .userBox {
padding: 10px;
line-height: 330%;
}
.membersPage .userBox:hover {
box-shadow: 0 0 1em #000;
cursor: pointer;
}
.membersPage .userBox:active {
box-shadow: 0 0 1.5em #609;
}
.membersPage .userBox img {
margin: 0 auto;
}
.membersPage .userBox .userBoxUserName {
font-weight: 700;
}
.membersPage .boxes .userBox {
width: 200px;
height: 230px;
}
.membersPage .boxes .userBox img {
width: 200px;
height: 200px;
display: block;
}
.membersPage .rectangles .userBox {
width: 300px;
height: 100px;
text-align: left;
}
.membersPage .rectangles .userBox img {
width: 100px;
height: 100px;
display: inline-block;
}
.membersPage .rectangles .userBox .userBoxUserName {
display: inline-block;
vertical-align: top;
padding: 30px 10px;
}
.membersPage .list table {
margin: 10px auto;
background: #C2AFFE;
box-shadow: 0 0 3px #9475B2;
border: 1px solid #9475B2;
max-width: 1024px;
width: auto;
border-radius: 3px;
border-spacing: 0;
}
.membersPage .list table td,
.membersPage .list table th {
padding: 4px 8px;
}
.membersPage .list thead th {
border-bottom: 1px solid #9475B2;
background: #A586C4;
}
.membersPage .list tfoot th {
border-top: 1px solid #9475B2;
background: #A586C4;
}

View file

@ -0,0 +1,41 @@
/*
* Private Messages Styling
*/
@charset "utf-8";
.messages table {
width: 100%;
border-spacing: 0;
}
.messages table > tbody > tr.unread {
background: #C2AFFE;
font-weight: 700;
}
.messages table > tbody > tr > td {
border-bottom: 1px solid #B19EED;
border-top: 1px solid #B19EED;
}
.messages table > * > tr > td {
padding: 0 4px;
}
.messages table > * > tr > td:first-child {
width: 150px;
text-align: center;
}
.messages table > tbody > tr > td:first-child {
border-left: 1px solid #B19EED;
}
.messages table > * > tr > td:last-child {
width: 220px;
text-align: center;
}
.messages table > tbody > tr > td:last-child {
border-right: 1px solid #B19EED;
}

View file

@ -0,0 +1,74 @@
/*
* News page styling
*/
@charset "utf-8";
.news {
min-height: 0;
}
.news-head {
margin: -1px -2px;
padding: 4px;
background: #C2AFFE;
font-weight: 700;
display: block;
font-size: 17px;
color: inherit;
text-decoration: none;
}
.news-rss {
float: right;
}
.news-body {
font-size: 10pt;
padding: 2px 0 0 3px;
}
.news-post-time {
font-size: 8pt;
padding: 6px 15px;
text-align: right;
font-weight: 700;
}
.news-poster {
margin-top: -20px;
float: right;
text-align: center;
width: 140px;
}
.news-poster img {
max-width: 120px;
max-height: 120px;
}
.news-poster h1 {
line-height: 100%;
margin: 0;
margin-top: -5px;
}
@media (max-width: 768px) {
.news-poster {
margin: 0;
}
}
@media (max-width: 400px) {
.news-poster {
margin-top: 10px;
width: auto;
padding: 0 10px 0 0;
}
.news-poster img {
display: none;
}
}

View file

@ -0,0 +1,99 @@
/*
* Notification styling
*/
@charset "utf-8";
#notifications {
position: fixed;
bottom: 5px;
right: 5px;
z-index: 3;
font-family: "Segoe UI", sans-serif;
overflow-y: auto;
overflow-x: hidden;
max-height: 510px;
max-width: 600px;
text-align: right;
}
#notifications > div {
cursor: pointer;
text-align: left;
display: inline-block;
height: 80px;
background: rgba(113, 74, 150, .9);
border: 1px solid #507;
border-right-width: 5px;
color: #FFF;
padding: 2px 0 2px 2px;
margin: 5px;
position: relative;
box-shadow: 0 0 4px rgba(0, 0, 0, .9);
}
#notifications > .notification-enter {
animation: slideInFromRight 1 .4s, fadeIn 1 .4s;
}
#notifications > .notification-exit {
animation: slideOutToBottom 1 .4s, fadeOut 1 .4s;
}
#notifications > div > .notification-icon {
float: left;
width: 80px;
height: 80px;
text-align: center;
background: rgba(0, 0, 0, .5);
display: block;
}
#notifications > div > .notification-icon > img {
max-height: 80px;
max-width: 80px;
}
#notifications > div > .notification-icon > .font-icon {
margin: .34em 0;
}
#notifications > div > .notification-content {
float: left;
min-width: 350px;
max-width: 450px;
padding-right: 6px;
border-left: 1px solid rgb(85, 0, 119);
height: 80px;
margin-left: 2px;
padding-left: 8px;
}
#notifications > div > .notification-content > .notification-title {
font-weight: 300;
font-size: 1.7em;
margin-top: 1em;
}
#notifications > div > .notification-close:before {
font-family: FontAwesome;
content: "\f00d";
}
#notifications > div > .notification-close {
font-size: 2em;
float: right;
height: 80px;
width: 20px;
background: #507;
margin-top: -3px;
padding-bottom: 6px;
padding-left: 2px;
border-left: 3px solid #507;
line-height: 3.4em;
text-align: center;
display: none;
}
#notifications > div:hover > .notification-close {
display: block;
}

View file

@ -0,0 +1,49 @@
/*
* Profile page Styling
*/
@charset "utf-8";
.profile .content-left {
max-height: 800px;
overflow: auto;
}
.profile .user-actions {
font-size: 3em;
line-height: 1.4em;
}
.profile .user-actions a {
color: #8364A1;
text-decoration: none;
text-shadow: 0 0 2px #9475B2;
transition: all .2s;
}
.profile .user-actions a:hover {
text-shadow: 0 0 6px #9475B2;
}
.profile .user-actions a:active {
color: #725390;
text-shadow: 0 0 8px #8364A1;
}
@media (max-width: 1024px) {
.content {
width: auto;
}
.content .content-right {
width: 100%;
min-height: 0;
}
.content .content-left {
width: 100%;
min-height: 0;
border-top: 1px solid #9475B2;
}
}

View file

@ -0,0 +1,91 @@
/*
* Settings page styling
*/
@charset "utf-8";
.settings .right-menu-nav > div {
background: #C2AFFE;
padding: 4px;
margin: -1px -2px;
font-weight: 700;
display: block;
font-size: 17px;
}
.settings .right-menu-nav > a {
display: block;
font-size: 14px;
line-height: 25px;
color: #22E;
text-decoration: none;
padding-left: 10px;
}
.settings .right-menu-nav > a:hover {
color: #22E;
text-decoration: underline;
}
.settings .right-menu-nav > a:active {
color: #E22;
text-decoration: underline;
}
.settings .settings-explanation {
font-size: 11px;
line-height: 18px;
padding: 7px;
border-bottom: 1px solid #C2AFFE;
margin-bottom: 7px;
}
.settings .settings-table {
width: 100%;
}
.settings .settings-table tr > th {
font-size: 17px;
background: #C2AFFE;
padding: 4px;
margin: -1px -2px;
font-weight: 700;
}
.settings .settings-table tr > td {
text-align: center;
}
.settings .settings-table > tbody > tr:not(:last-child) > td {
border-bottom: 1px solid #C2AFFE;
}
.settings .settings-table tr.current-session > td {
background: #B39EED;
}
.settings .profile-field {
width: 100%;
}
.settings .profile-field > div:nth-child(2) > input {
width: calc(100% - 16px);
}
.settings .profile-save {
text-align: center;
padding: 10px;
}
.settings .background-frame {
max-width: 600px;
max-height: 400px;
border: 3px solid #EEE;
background: #EEE;
box-shadow: 0 3px 7px #888;
border-radius: 3px;
margin: 5px;
}
.settings form {
overflow: auto;
}

File diff suppressed because it is too large Load diff

View file

@ -12,10 +12,10 @@ function cookieData(action, name, data) {
case 'set':
document.cookie = name + '=' + data;
return;
return null;
default:
return;
return null;
}
@ -76,6 +76,7 @@ function notifyUI(content) {
var notifText = document.createElement('div');
var notifClose = document.createElement('div');
var notifClear = document.createElement('div');
var iconCont;
// Add ID and class on notification container
notif.className = 'notification-enter';
@ -85,12 +86,12 @@ function notifyUI(content) {
notifIcon .className = 'notification-icon';
if(content.img.substring(0, 5) == "FONT:") {
var iconCont = document.createElement('div');
iconCont = document.createElement('div');
iconCont.className = 'font-icon fa ' + content.img.replace('FONT:', '') + ' fa-4x';
} else {
var iconCont = document.createElement('img');
iconCont = document.createElement('img');
iconCont.setAttribute('alt', identifier);
iconCont.setAttribute('src', content.img);
@ -190,9 +191,12 @@ function notifyOpen(id) {
var sakuraHref = document.getElementById(id).getAttribute('sakurahref');
if(typeof sakuraHref !== 'undefined')
if(typeof sakuraHref !== 'undefined') {
window.location = sakuraHref;
}
}
// Request notifications
@ -235,9 +239,12 @@ function notifyRequest(session) {
}
// Go over every return notification and pass the object to it
for(var notifyID in notifyGet)
for(var notifyID in notifyGet) {
notifyUI(notifyGet[notifyID]);
}
} else {
// ELse tell the user there was an internal server error...
@ -256,7 +263,7 @@ function notifyRequest(session) {
}
}
};
// Make the request
notificationWatcher.open('GET', notifyURL, true);
@ -274,9 +281,12 @@ function donatePage(id) {
if(!id) {
// Go over every element and add donateClosed to the end of the class
for(var i = 0; i < featureBoxDesc.length; i++)
for(var i = 0; i < featureBoxDesc.length; i++) {
featureBoxDesc[i].className = featureBoxDesc[i].className + ' donateClosed';
}
// Then stop the execution of the function
return;
@ -309,9 +319,12 @@ function removeClass(className) {
var objectCont = document.getElementsByClassName(className);
// Use a while loop instead of a for loop (Array keys change) to remove each element
while(objectCont.length > 0)
while(objectCont.length > 0) {
objectCont[0].parentNode.removeChild(objectCont[0]);
}
}
// Removing an element by ID
@ -321,9 +334,12 @@ function removeId(id) {
var objectCont = document.getElementById(id);
// If the element exists use the parent node to remove it
if(typeof(objectCont) != "undefined" && objectCont !== null)
if(typeof(objectCont) != "undefined" && objectCont !== null) {
objectCont.parentNode.removeChild(objectCont);
}
}
// Show the full-page busy window
@ -334,19 +350,20 @@ function ajaxBusyView(show, message, type) {
var busyStat = document.getElementById('ajaxStatus');
var busyAnim = document.getElementById('ajaxAnimate');
var pageContent = document.getElementById('contentwrapper');
var busyAnimIco;
// Select the proper icon
switch(type) {
default:
case 'busy':
var busyAnimIco = 'fa fa-refresh fa-spin fa-4x';
break;
case 'ok':
var busyAnimIco = 'fa fa-check fa-4x';
busyAnimIco = 'fa fa-check fa-4x';
break;
case 'fail':
var busyAnimIco = 'fa fa-remove fa-4x';
busyAnimIco = 'fa fa-remove fa-4x';
break;
case 'busy':
default:
busyAnimIco = 'fa fa-refresh fa-spin fa-4x';
break;
}
@ -355,7 +372,7 @@ function ajaxBusyView(show, message, type) {
if(show) {
// Make sure it doesn't exist already
if(busyCont == null) {
if(busyCont === null) {
// Container
var createBusyCont = document.createElement('div');
@ -391,24 +408,27 @@ function ajaxBusyView(show, message, type) {
busyAnim.className = busyAnimIco;
// Change the message
busyStat.innerHTML = (message == null ? 'Unknown' : message)
busyStat.innerHTML = (message === null ? 'Unknown' : message);
} else { // If show is false remove the element...
// ...but just do nothing if the container doesn't exist
if(busyCont != null) {
if(busyCont !== null) {
// Create the fadeout with a 10ms interval
var fadeOut = setInterval(function() {
// Set an opacity if it doesn't exist yet
if(busyCont.style.opacity == null || busyCont.style.opacity == "")
if(busyCont.style.opacity === null || busyCont.style.opacity === "") {
busyCont.style.opacity = 1;
}
// If the value isn't 0 yet start subtract .1 from the opacity
if(busyCont.style.opacity > 0) {
busyCont.style.opacity = busyCont.style.opacity - .1;
busyCont.style.opacity = busyCont.style.opacity - 0.1;
} else { // When we've reached 0 remove the container element and clear the fadeout interval
@ -439,17 +459,17 @@ function ajaxPost(url, data) {
// Combine name and value with an = inbetween
var query = [];
for(var i in data)
for(var i in data) {
query.push(encodeURIComponent(i) +"="+ encodeURIComponent(data[i]));
}
// Join the array and submit the request
req.send(query.join("&"));
// If the HTTP resonse was 200 return the page
if(req.status === 200)
return req.responseText;
else // Else return nothing
return "";
return (req.status === 200 ? req.responseText : null);
}
@ -457,28 +477,39 @@ function ajaxPost(url, data) {
function generateForm(formId, formAttr, formData, appendTo) {
// Create form elements and assign ID
var i;
var form = document.createElement('form');
form.setAttribute('id', formId);
// Set additional attributes
if(formAttr != null) {
for(var i in formAttr)
if(formAttr !== null) {
for(i in formAttr) {
form.setAttribute(i, formAttr[i]);
}
}
// Generate input elements
for(var i in formData) {
for(i in formData) {
var disposableVar = document.createElement('input');
disposableVar.setAttribute('type', 'hidden');
disposableVar.setAttribute('name', i);
disposableVar.setAttribute('value', formData[i]);
form.appendChild(disposableVar);
}
// Append to another element if requested
if(appendTo != null)
if(appendTo !== null) {
document.getElementById(appendTo).appendChild(form);
}
// Return the completed form
return form;
@ -504,17 +535,20 @@ function formEnterCatch(key, id) {
}
// Submitting a form using an AJAX POST request
function submitPost(formId, busyView, msg) {
function submitPost(formId, busyView, msg, resetCaptchaOnFailure) {
// If requested display the busy thing
if(busyView)
if(busyView) {
ajaxBusyView(true, msg, 'busy');
}
// Get form data
var form = document.getElementById(formId);
// Make sure the form id was proper and if not report an error
if(form == null) {
if(form === null) {
if(busyView) {
ajaxBusyView(true, 'Invalid Form ID, contact the administrator.');
setTimeout(function(){ajaxBusyView(false);}, 2000);
@ -531,30 +565,190 @@ function submitPost(formId, busyView, msg) {
// Sort children and make them ready for submission
for(var i in children) {
if(typeof children[i] == 'object')
if(typeof children[i] == 'object') {
requestParts[children[i].name] = ((typeof children[i].type !== "undefined" && children[i].type.toLowerCase() == "checkbox") ? children[i].checked : children[i].value);
}
}
// Submit the AJAX request
var request = ajaxPost(form.action, requestParts).split('|');
// If using the busy view thing update the text displayed to the return of the request
if(busyView)
if(busyView) {
ajaxBusyView(true, request[1], (request[2] == '1' ? 'ok' : 'fail'));
}
// If request reset the recaptcha on failure
if(resetCaptchaOnFailure && request[2] != '1') {
grecaptcha.reset();
}
setTimeout(function(){
if(busyView)
if(busyView) {
ajaxBusyView(false);
if(request[2] == '1')
}
if(request[2] == '1') {
window.location = request[3];
}
}, 2000);
return;
}
// Encode UTF-8
function utf8_encode(str) {
return unescape(encodeURIComponent(str));
}
// Decode UTF-8
function utf8_decode(str) {
return decodeURIComponent(escape(str));
}
// Calculate the amount of unique characters in a string
function uniqueChars(str) {
// Create storage array and count var
var usedChars = new Array();
var count = 0;
// Count the amount of unique characters
for(var i = 0; i < str.length; i++) {
// Check if we already counted this character
if(usedChars.indexOf(str[i]) == -1) {
// Push the character into the used array
usedChars.push(str[i]);
// Up the count
count++;
}
}
// Return the count
return count;
}
// Alternative for Math.log2() since it's still experimental
function log2(num) {
return Math.log(num) / Math.log(2);
}
// Calculate password entropy
function pwdEntropy(pwd) {
// Decode utf-8 chars
pwd = utf8_decode(pwd);
// Count the amount of unique characters in the password and calculate the entropy
return uniqueChars(pwd) * log2(256);
}
// Check if password is within the minimum entropy value
function checkPwdEntropy(pwd) {
return (pwdEntropy(pwd) >= sakuraVars.minPwdEntropy);
}
// Check the length of a string
function checkStringLength(str, min, max) {
// Get length of string
var len = str.length;
// Check if it meets the minimum
if(len < min)
return false;
// Check if it meets the maximum
if(len > max)
return false;
// If it passes both return true
return true;
}
// Validate email address formats
function validateEmail(email) {
// The regex
var re = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
// Test it (which returns true or false)
return re.test(email);
}
// Check registration variables
function registerVarCheck(id, mode, option) {
// Get the element we're working with
var input = document.getElementById(id);
var check = null;
// Use the proper mode
switch(mode) {
case 'confirmpw':
option = document.getElementById(option);
check = input.value === option.value;
break;
case 'password':
check = checkPwdEntropy(input.value);
break;
case 'email':
check = validateEmail(input.value);
break;
case 'username':
default:
check = checkStringLength(input.value, sakuraVars.minUserLen, sakuraVars.maxUserLen);
break;
}
if(input.className.indexOf(check ? 'green' : 'red') < 0) {
input.className = input.className + ' ' + (check ? 'green' : 'red');
}
if(input.className.indexOf(check ? 'red' : 'green') > 0) {
input.className = input.className.replace(check ? 'red' : 'green', '');
}
}
// Initialising the element parallax functionality
function initialiseParallax(id) {
@ -590,16 +784,22 @@ function convertParallaxPositionValue(pos, dir, neg) {
var position = (pos / (dir ? body.clientHeight : body.clientWidth)) * 100;
// If someone decided to fuck with the inputs reset it to 0%
if(position < 0 || position > 100)
if(position < 0 || position > 100) {
position = 0;
}
// Do the first maths
position = (position / (dir ? 25 : 20)) - 2.5;
// If the negative flag is set inverse the number
if(neg)
if(neg) {
position = -position;
}
// Subtract another 2.5 to make the element not go all over the place
position = position - 2.5;
@ -609,11 +809,20 @@ function convertParallaxPositionValue(pos, dir, neg) {
}
// Smooth scrolling
function scrollTop() {
function scrollToTop() {
// Get the current position
var windowY = window.pageYOffset;
alert(windowY);
var windowY = window.pageYOffset - 100;
// Move up
window.scrollTo(0, windowY);
// Keep executing this function till we're at the top
if(windowY + 1 > 0) {
setTimeout(function(){scrollToTop();}, 10);
}
}