typescript because fuck rubberscript

seriously why is javascript so globally loved
This commit is contained in:
Pachira 2015-12-06 02:52:35 +01:00
parent fd6baecb7d
commit 3b3b6f1c3e
7 changed files with 301 additions and 146 deletions

View file

@ -47,11 +47,11 @@ class BBcode
self::$bbcode->addCodeDefinition($builder->build());
// Box tag
$builder = new CodeDefinitionBuilder('box', '<div class="spoiler-box-container"><div class="spoiler-box-title" onclick="toggleClass(this.parentNode.children[1], \'hidden\');">Click to open</div><div class="spoiler-box-content hidden">{param}</div></div>');
$builder = new CodeDefinitionBuilder('box', '<div class="spoiler-box-container"><div class="spoiler-box-title" onclick="Sakura.toggleClass(this.parentNode.children[1], \'hidden\');">Click to open</div><div class="spoiler-box-content hidden">{param}</div></div>');
self::$bbcode->addCodeDefinition($builder->build());
// Box tag
$builder = new CodeDefinitionBuilder('box', '<div class="spoiler-box-container"><div class="spoiler-box-title" onclick="toggleClass(this.parentNode.children[1], \'hidden\');">{option}</div><div class="spoiler-box-content hidden">{param}</div></div>');
$builder = new CodeDefinitionBuilder('box', '<div class="spoiler-box-container"><div class="spoiler-box-title" onclick="Sakura.toggleClass(this.parentNode.children[1], \'hidden\');">{option}</div><div class="spoiler-box-content hidden">{param}</div></div>');
$builder->setUseOption(true);
self::$bbcode->addCodeDefinition($builder->build());

14
libraries/Router.php Normal file
View file

@ -0,0 +1,14 @@
<?php
/*
* Router class
*/
namespace Sakura;
/**
* Class Router
* @package Sakura
*/
class Router
{
}

View file

@ -2,26 +2,6 @@
* Sakura Yuuno JavaScript
*/
// Get or set cookies
function cookieData(action, name, data) {
switch(action) {
case 'get':
return (result = new RegExp('(^|; )' + encodeURIComponent(name) + '=([^;]*)').exec(document.cookie)) ? result[2] : '';
case 'set':
document.cookie = name + '=' + data + '; path=/';
return null;
default:
return null;
}
}
// Get the current unix/epoch timestamp
function epochTime() {
return Math.floor(Date.now() / 1000);
}
// Create a notification box
function notifyUI(content) {
// Grab the container and create an ID
@ -133,7 +113,7 @@ function notifyClose(id) {
// Remove the element after 500 milliseconds (animation takes 400)
setTimeout(function() {
// Use the later defined removeId function
removeId(id);
Sakura.removeId(id);
}, 410);
}
@ -155,7 +135,7 @@ function notifyRequest(session) {
// Create XMLHttpRequest and notifyURL
var notificationWatcher = new XMLHttpRequest();
var notifyURL = '//' + sakuraVars.urlMain + '/settings.php?request-notifications=true&time=' + epochTime() + '&session=' + session;
var notifyURL = '//' + sakuraVars.urlMain + '/settings.php?request-notifications=true&time=' + Sakura.epoch() + '&session=' + session;
// Wait for the ready state to change
notificationWatcher.onreadystatechange = function() {
@ -203,40 +183,6 @@ function notifyRequest(session) {
notificationWatcher.send();
}
// Toggle a class on an element
function toggleClass(element, name) {
// Attempt to get the index
var indexOf = element.className.indexOf(name);
if (indexOf < 0) {
element.className += ' ' + name;
} else {
element.className = element.className.replace(name, '').trim();
}
}
// Removing all elements with a certain class
function removeClass(className) {
// Get the elements
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) {
objectCont[0].parentNode.removeChild(objectCont[0]);
}
}
// Removing an element by ID
function removeId(id) {
// Get the element
var objectCont = document.getElementById(id);
// If the element exists use the parent node to remove it
if(typeof(objectCont) != "undefined" && objectCont !== null) {
objectCont.parentNode.removeChild(objectCont);
}
}
// Show the full-page busy window
function ajaxBusyView(show, message, type) {
// Get elements
@ -312,7 +258,7 @@ function ajaxBusyView(show, message, type) {
if(busyCont.style.opacity > 0) {
busyCont.style.opacity = busyCont.style.opacity - 0.1;
} else { // When we've reached 0 remove the container element and clear the fadeout interval
removeId('ajaxBusy');
Sakura.removeId('ajaxBusy');
clearInterval(fadeOut);
}
}, 10);
@ -519,84 +465,9 @@ function submitPostHandler(result, busyView, resetCaptchaOnFailure) {
}
// 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 = [];
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{2,48})+$/;
// is of fix
// Test it (which returns true or false)
return re.test(email);
return (Sakura.pwdEntropy(pwd) >= sakuraVars.minPwdEntropy);
}
// Check registration variables
@ -617,12 +488,12 @@ function registerVarCheck(id, mode, option) {
break;
case 'email':
check = validateEmail(input.value);
check = Sakura.validateEmail(input.value);
break;
case 'username':
default:
check = checkStringLength(input.value, sakuraVars.minUserLen, sakuraVars.maxUserLen);
check = Sakura.stringLength(input.value, sakuraVars.minUserLen, sakuraVars.maxUserLen);
break;
}
@ -722,7 +593,7 @@ function commentReply(id, session, category, action, avatar) {
// Remove it if it already exists
if(replyBox) {
removeId('comment-reply-container-' + id);
Sakura.removeId('comment-reply-container-' + id);
return false;
}

View file

@ -0,0 +1,126 @@
/*
* Shared client side code
*/
// Meta functions
var Sakura = (function () {
function Sakura() {
}
// Get or set a cookie value
Sakura.cookie = function (name, value) {
if (value === void 0) { value = null; }
// If value is null only get the cookie's value
if (value) {
// Delete the old instance
document.cookie = this.cookiePrefix + name + '=;expires=Thu, 01 Jan 1970 00:00:01 GMT; path=' + this.cookiePath;
// Assign the cookie
document.cookie = this.cookiePrefix + name + '=' + value + '; path=' + this.cookiePath;
// Pass the value through
return value;
}
else {
// Perform a regex on document.cookie
var get = new RegExp('(^|; )' + encodeURIComponent(this.cookiePrefix + name) + '=([^;]*)').exec(document.cookie);
// If anything was returned return it (professional phrasing)
return get ? get[2] : '';
}
};
// Unix timestamp
Sakura.epoch = function () {
return Math.floor(Date.now() / 1000);
};
// Toggle a class
Sakura.toggleClass = function (element, name) {
// Check if the class already exists and if not add it
if (element.className.indexOf(name) < 0) {
element.className += ' ' + name;
}
else {
element.className = element.className.replace(name, '').trim();
}
};
// Remove every element with a specific class name
Sakura.removeByClass = function (name) {
// Get the elements
var objs = document.getElementsByClassName(name);
// Use a while loop to remove each element
while (objs.length > 0) {
objs[0].parentNode.removeChild(objs[0]);
}
};
// Remove a single element with a specific id
Sakura.removeById = function (id) {
// Get the element
var obj = document.getElementById(id);
// If the element exists use the parent node to remove it
if (typeof (obj) != "undefined" && obj !== null) {
obj.parentNode.removeChild(obj);
}
};
// Alternative for Math.log2() since it's still experimental
Sakura.log2 = function (num) {
return Math.log(num) / Math.log(2);
};
// Get the number of unique characters in a string
Sakura.unique = function (string) {
// Store the already found character
var used = [];
// The amount of characters we've already found
var count = 0;
// Count the amount of unique characters
for (var i = 0; i < string.length; i++) {
// Check if we already counted this character
if (used.indexOf(string[i]) == -1) {
// Push the character into the used array
used.push(string[i]);
// Up the count
count++;
}
}
// Return the count
return count;
};
// Calculate password entropy
Sakura.entropy = function (string) {
// Decode utf-8 encoded characters
string = utf8.decode(string);
// Count the unique characters in the string
var unique = this.unique(string);
// Do the entropy calculation
return unique * this.log2(256);
};
// Validate string lengths
Sakura.stringLength = function (string, minimum, maximum) {
// Get length of string
var length = string.length;
// Check if it meets the minimum/maximum
if (length < minimum || length > maximum) {
return false;
}
// If it passes both return true
return true;
};
// Validate email address formats
Sakura.validateEmail = function (email) {
// RFC compliant e-mail address regex
var re = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,48})+$/;
// Test it on the email var which'll return a boolean
return re.test(email);
};
Sakura.cookiePrefix = ""; // Cookie prefix, gets prepended to cookie names
Sakura.cookiePath = "/"; // Cookie path, can in most cases be left untouched
return Sakura;
})();
// UTF-8 functions
var utf8 = (function () {
function utf8() {
}
// Encode a utf-8 string
utf8.encode = function (string) {
return unescape(encodeURIComponent(string));
};
// Decode a utf-8 string
utf8.decode = function (string) {
return decodeURIComponent(escape(string));
};
return utf8;
})();

View file

@ -0,0 +1,144 @@
/*
* Shared client side code
*/
// Meta functions
class Sakura {
public static cookiePrefix: string = ""; // Cookie prefix, gets prepended to cookie names
public static cookiePath: string = "/"; // Cookie path, can in most cases be left untouched
// Get or set a cookie value
public static cookie(name: string, value: string = null): string {
// If value is null only get the cookie's value
if (value) {
// Delete the old instance
document.cookie = this.cookiePrefix + name + '=;expires=Thu, 01 Jan 1970 00:00:01 GMT; path=' + this.cookiePath;
// Assign the cookie
document.cookie = this.cookiePrefix + name + '=' + value + '; path=' + this.cookiePath;
// Pass the value through
return value;
} else {
// Perform a regex on document.cookie
var get = new RegExp('(^|; )' + encodeURIComponent(this.cookiePrefix + name) + '=([^;]*)').exec(document.cookie);
// If anything was returned return it (professional phrasing)
return get ? get[2] : '';
}
}
// Unix timestamp
public static epoch(): number {
return Math.floor(Date.now() / 1000);
}
// Toggle a class
public static toggleClass(element: HTMLElement, name: string): void {
// Check if the class already exists and if not add it
if (element.className.indexOf(name) < 0) {
element.className += ' ' + name;
} else { // If so remove it and kill additional spaces
element.className = element.className.replace(name, '').trim();
}
}
// Remove every element with a specific class name
public static removeByClass(name: string): void {
// Get the elements
var objs = document.getElementsByClassName(name);
// Use a while loop to remove each element
while (objs.length > 0) {
objs[0].parentNode.removeChild(objs[0]);
}
}
// Remove a single element with a specific id
public static removeById(id: string): void {
// Get the element
var obj = document.getElementById(id);
// If the element exists use the parent node to remove it
if (typeof (obj) != "undefined" && obj !== null) {
obj.parentNode.removeChild(obj);
}
}
// Alternative for Math.log2() since it's still experimental
public static log2(num: number): number {
return Math.log(num) / Math.log(2);
}
// Get the number of unique characters in a string
public static unique(string: string): number {
// Store the already found character
var used: string[] = [];
// The amount of characters we've already found
var count: number = 0;
// Count the amount of unique characters
for (var i = 0; i < string.length; i++) {
// Check if we already counted this character
if (used.indexOf(string[i]) == -1) {
// Push the character into the used array
used.push(string[i]);
// Up the count
count++;
}
}
// Return the count
return count;
}
// Calculate password entropy
public static entropy(string: string): number {
// Decode utf-8 encoded characters
string = utf8.decode(string);
// Count the unique characters in the string
var unique: number = this.unique(string);
// Do the entropy calculation
return unique * this.log2(256);
}
// Validate string lengths
public static stringLength(string: string, minimum: number, maximum: number): boolean {
// Get length of string
var length = string.length;
// Check if it meets the minimum/maximum
if (length < minimum || length > maximum) {
return false;
}
// If it passes both return true
return true;
}
// Validate email address formats
public static validateEmail(email: string): boolean {
// RFC compliant e-mail address regex
var re = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,48})+$/;
// Test it on the email var which'll return a boolean
return re.test(email);
}
}
// UTF-8 functions
class utf8 {
// Encode a utf-8 string
public static encode(string): string {
return unescape(encodeURIComponent(string));
}
// Decode a utf-8 string
public static decode(string): string {
return decodeURIComponent(escape(string));
}
}

View file

@ -8,7 +8,7 @@
namespace Sakura;
// Define Sakura version
define('SAKURA_VERSION', '20151204');
define('SAKURA_VERSION', '20151206');
define('SAKURA_VLABEL', 'Eminence');
define('SAKURA_COLOUR', '#6C3082');

View file

@ -32,18 +32,15 @@
<link rel="stylesheet" type="text/css" href="{{ sakura.resources }}/css/yuuno.css" />
{{ block('css') }}
<!-- JS -->
<script type="text/javascript" src="{{ sakura.contentPath }}/scripts/sakura.js"></script>
<script type="text/javascript" src="{{ sakura.resources }}/js/yuuno.js"></script>
<script type="text/javascript">
// Create an object so we can access certain settings from remote JavaScript files
var sakuraVars = {
"cookie": {
"prefix": "{{ sakura.cookie.prefix }}",
"domain": "{{ sakura.cookie.domain }}",
"path": "{{ sakura.cookie.path }}"
},
"siteName": "{{ sakura.siteName }}",
@ -56,9 +53,12 @@
"maxUserLen": {{ sakura.maxUsernameLength }},
"minPwdEntropy": {{ sakura.minPwdEntropy }},
"checkLogin": {% if session.checkLogin %}true{% else %}false{% endif %}
};
// Set cookie prefix and path
Sakura.cookiePrefix = "{{ sakura.cookie.prefix }}";
Sakura.cookiePath = "{{ sakura.cookie.path }}";
// Space for things that need to happen onload
window.addEventListener("load", function() {
@ -123,13 +123,13 @@
{% endif %}
if(!cookieData('get', sakuraVars.cookie.prefix +'accept_cookies')) {
if(!Sakura.cookie('accept_cookies')) {
notifyUI({
"title": sakuraVars.siteName + " uses cookies!",
"text": "Click this if you're OK with that and want to hide this message.",
"img": "FONT:fa-asterisk",
"link": "javascript:cookieData('set', '" + sakuraVars.cookie.prefix + "accept_cookies', 'true; expires=" + (new Date(2147483647000)).toUTCString() + "');notifyClose(this.parentNode.id);"
"link": "javascript:Sakura.cookie('accept_cookies', 'true; expires=" + (new Date(2147483647000)).toUTCString() + "');notifyClose(this.parentNode.id);"
});
}