Added files

This commit is contained in:
Timothy Warren 2011-07-26 10:56:55 -04:00
parent c5367eedfd
commit c52724e325
14 changed files with 2246 additions and 0 deletions

View File

@ -0,0 +1,116 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/*
| -------------------------------------------------------------------
| AUTO-LOADER
| -------------------------------------------------------------------
| This file specifies which systems should be loaded by default.
|
| In order to keep the framework as light-weight as possible only the
| absolute minimal resources are loaded by default. For example,
| the database is not connected to automatically since no assumption
| is made regarding whether you intend to use it. This file lets
| you globally define which systems you would like loaded with every
| request.
|
| -------------------------------------------------------------------
| Instructions
| -------------------------------------------------------------------
|
| These are the things you can load automatically:
|
| 1. Packages
| 2. Libraries
| 3. Helper files
| 4. Custom config files
| 5. Language files
| 6. Models
|
*/
/*
| -------------------------------------------------------------------
| Auto-load Packges
| -------------------------------------------------------------------
| Prototype:
|
| $autoload['packages'] = array(APPPATH.'third_party', '/usr/local/shared');
|
*/
$autoload['packages'] = array(APPPATH.'third_party');
/*
| -------------------------------------------------------------------
| Auto-load Libraries
| -------------------------------------------------------------------
| These are the classes located in the system/libraries folder
| or in your application/libraries folder.
|
| Prototype:
|
| $autoload['libraries'] = array('database', 'session', 'xmlrpc');
*/
$autoload['libraries'] = array('page');
/*
| -------------------------------------------------------------------
| Auto-load Helper Files
| -------------------------------------------------------------------
| Prototype:
|
| $autoload['helper'] = array('url', 'file');
*/
$autoload['helper'] = array('html', 'url', 'form');
/*
| -------------------------------------------------------------------
| Auto-load Config files
| -------------------------------------------------------------------
| Prototype:
|
| $autoload['config'] = array('config1', 'config2');
|
| NOTE: This item is intended for use ONLY if you have created custom
| config files. Otherwise, leave it blank.
|
*/
$autoload['config'] = array('sites');
/*
| -------------------------------------------------------------------
| Auto-load Language files
| -------------------------------------------------------------------
| Prototype:
|
| $autoload['language'] = array('lang1', 'lang2');
|
| NOTE: Do not include the "_lang" part of your file. For example
| "codeigniter_lang.php" would be referenced as array('codeigniter');
|
*/
$autoload['language'] = array();
/*
| -------------------------------------------------------------------
| Auto-load Models
| -------------------------------------------------------------------
| Prototype:
|
| $autoload['model'] = array('model1', 'model2');
|
*/
$autoload['model'] = array();
/* End of file autoload.php */
/* Location: ./application/config/autoload.php */

View File

@ -0,0 +1,87 @@
<?php
/*
|--------------------------------------------------------------------------
| Content Domain
|--------------------------------------------------------------------------
|
| This is the domain used for serving content, such as css, javascript.
|
*/
$config['content_domain'] = '';
/*
|--------------------------------------------------------------------------
| Content Domain
|--------------------------------------------------------------------------
|
| This is the domain/subdomain used for serving images.
|
*/
$config['image_domain'] = '';
/*
|--------------------------------------------------------------------------
| Static Lib Path
|--------------------------------------------------------------------------
|
| This is the path where the css.php and js.php files are on the static domain.
|
*/
$config['static_lib_path'] = '';
/*
|--------------------------------------------------------------------------
| Group Style Path
|--------------------------------------------------------------------------
|
| This is the path that is used to determine the relative path to the
| stylesheet minifier. This should not need to be changed.
|
*/
$config['group_style_path'] = $config['static_lib_path'] . '/css.php/g/';
/*
|--------------------------------------------------------------------------
| Group JS Path
|--------------------------------------------------------------------------
|
| This is the path that is used to determine the relative path to the
| stylesheet minifier. This should not need to be changed.
|
*/
$config['group_js_path'] = $config['static_lib_path'] . '/js.php/g/';
/*
|--------------------------------------------------------------------------
| Password Salt
|--------------------------------------------------------------------------
|
| This is the string used as a password salt for checking passwords. This
| should never be changed once it is set. This must be 12 characters
| long, and start with '$1$'
|
*/
$config['salt'] = '$1$3f6iuhj89';
/*
|--------------------------------------------------------------------------
| Default title
|--------------------------------------------------------------------------
|
| Default title for webpages
|
*/
$config['default_title'] = "";
/*
|--------------------------------------------------------------------------
| Default css group
|--------------------------------------------------------------------------
|
| Default css group
|
*/
$config['default_css_group'] = "css";

View File

@ -0,0 +1,529 @@
<?php (defined('BASEPATH')) OR exit('No direct script access allowed');
/**
* Class for building pages
*
* All methods are chainable, with the exception of the constructor,
* build_header(), build_footer(), build_page() and _headers() methods.
*/
class Page {
private static $meta, $head_js, $foot_js, $css, $title,
$head_tags, $body_class, $body_id, $base;
private $CI;
public function __construct()
{
$this->meta = "";
$this->head_js = "";
$this->foot_js = "";
$this->css = "";
$this->title = "";
$this->head_tags = "";
$this->body_class = "";
$this->body_id = "";
$this->base = "";
$this->CI =& get_instance();
//Define some constants for formatting
define('NL', "\n");
define('T1', "\t");
define('T2', T1.T1);
define('T3', T2.T1);
define('T4', T2.T2);
define('T5', T3.T2);
define('T6', T3.T3);
}
// --------------------------------------------------------------------------
/**
* Sets server headers and doctype
*
* Also sets page mime type, based on if sent as
* html or xhtml, and what the target browser
* supports
*
* @param bool $xhtml
* @param bool $html5
* @return Page
*/
private function _headers($xhtml, $html5)
{
$this->CI->output->set_header("Cache-Control: must-revalidate, public");
$this->CI->output->set_header("Vary: Accept");
$mime = "";
//Variable for accept keyword
$accept = (!empty($_SERVER['HTTP_ACCEPT'])) ? $_SERVER['HTTP_ACCEPT'] : "";
//Predefine doctype
$doctype_string = ($html5 == TRUE) ? doctype('html5') : doctype('xhtml11');
//Predefine charset
$charset = "UTF-8";
//If xhtml flag is false, set html4 header
if($xhtml == TRUE)
{
//Check that the user agent accepts application/xhtml+xml, or if it's the W3C Validator
if(stristr($accept,"application/xhtml+xml") || stristr($_SERVER["HTTP_USER_AGENT"],"W3C_Validator"))
{
$mime = "application/xhtml+xml";
}
//Or if it supports application/xml
else if(stristr($accept,"application/xml"))
{
$mime = "application/xml";
}
//Or if it supports text/xml
else if(stristr($accept,"text/xml"))
{
$mime = "text/xml";
}
else //Otherwise, it's tag soup
{
$mime = "text/html";
if($html5 == FALSE) //If it's not HTML5, it's HTML4
{
$doctype_string = doctype('html4-strict');
}
}
}
else
{
$mime = "text/html";
if($html5 == FALSE)
{
$doctype_string = doctype('html4-strict');
}
}
// set the doctype according to the mime type which was determined
if($mime == "application/xhtml+xml" || $mime == "text/xml" || $mime == "application/xml")
{
if($html5 == TRUE)
{
$doctype_string = '';
}
$doctype_string = "<?xml version='1.0' encoding='$charset' ?>\n" .
$doctype_string . "\n<html xmlns='http://www.w3.org/1999/xhtml'" .
" xml:lang='en'>";
}
else
{
$doctype_string .= "\n<html lang='en'>";
}
// finally, output the mime type and prolog type
$this->CI->output->set_header("Content-Type: $mime;charset=$charset");
$this->CI->output->set_header("X-UA-Compatible: chrome=1, IE=edge");
$this->CI->output->set_output($doctype_string);
return $this;
}
// --------------------------------------------------------------------------
/**
* Set Meta
*
* Sets meta tags, with codeigniter native meta tag helper
*
* @param array $meta
* @return Page
*/
public function set_meta($meta)
{
$this->meta .= T1.meta($meta).NL;
return $this;
}
// --------------------------------------------------------------------------
/**
* Sets minified javascript group in header
* @param string $group
* @param bool $debug
* @return Page
*/
public function set_head_js_group($group, $debug=FALSE)
{
if($group === FALSE)
{
return $this;
}
$file = $this->CI->config->item('group_js_path') . $group;
$file .= ($debug == TRUE) ? "/debug/1" : "";
$this->head_js .= $this->script_tag($file, FALSE);
return $this;
}
// --------------------------------------------------------------------------
/**
* Set an individual js file in header
* @param string $js
* @param bool $domain
* @return Page
*/
public function set_head_js($js, $domain=TRUE)
{
$this->head_js .= $this->script_tag($js, $domain);
return $this;
}
// --------------------------------------------------------------------------
/**
* Sets a minified css group
* @param string $group
* @return Page
*/
public function set_css_group($group)
{
$link = array(
'href' => $this->CI->config->item('group_style_path') . $group,
'rel' => 'stylesheet',
'type' => 'text/css',
);
$this->css .= T1.link_tag($link).NL;
return $this;
}
// --------------------------------------------------------------------------
/**
* Sets a minified javascript group for the page footer
* @param string $group
* @return Page
*/
public function set_foot_js_group($group, $debug=FALSE)
{
$file = $this->CI->config->item('group_js_path') . $group;
$file .= ($debug == TRUE) ? "?debug=1" : "";
$this->foot_js .= $this->script_tag($file, FALSE);
return $this;
}
// --------------------------------------------------------------------------
/**
* Sets js in footer; multiple files are combined and minified.
* @param array $args
* @return Page
*/
public function set_foot_js($js, $domain)
{
$this->foot_js .= $this->script_tag($js, $domain);
return $this;
}
// --------------------------------------------------------------------------
/**
* Sets html title string
* @param string $title
* @return Page
*/
public function set_title($title="")
{
$title = ($title == "") ?
$this->CI->config->item('default_title') : $title;
$this->title = $title;
return $this;
}
// --------------------------------------------------------------------------
/**
* Sets custom body class
* @param string $class
* @return Page
*/
public function set_body_class($class="")
{
$this->body_class = $class;
return $this;
}
// --------------------------------------------------------------------------
/**
* Sets custom body id
* @param string $id
* @return Page
*/
public function set_body_id($id="")
{
$this->body_id = $id;
return $this;
}
// --------------------------------------------------------------------------
/**
* Sets custom base href
* @param string href
* @return Page
*/
public function set_base($href)
{
$this->base = $href;
return $this;
}
// --------------------------------------------------------------------------
/**
* Sets custom css tags
* @param string $name
* @param string $media
* @return Page
*/
public function set_css_tag($name, $domain=TRUE, $media="all")
{
$path = $this->CI->config->item('content_domain');
$css_file = $path . "/css/" . $name . ".css";
if ($domain == FALSE)
$css_file = $name;
$this->css_tags .= T1.link_tag($name, "stylesheet", "text/css", "", $media).NL;
return $this;
}
// --------------------------------------------------------------------------
/**
* Sets uncompressed js file in footer
* @param string $name
* @param bool $domain
* @return Page
*/
public function set_foot_js_tag($name, $domain=TRUE)
{
$this->foot_js .= $this->script_tag($name, $domain);
return $this;
}
// --------------------------------------------------------------------------
/**
* Sets a custom tag in the header
* @param string $tag
* @return Page
*/
public function set_head_tag($tag)
{
$this->head_tags .= $tag . "\n";
return $this;
}
// --------------------------------------------------------------------------
/**
* Sets custom page header
* @param mixed $xhtml
* @param bool $html5
* @param bool $fbml
* @return $this
*/
public function build_header($xhtml = FALSE, $html5 = TRUE)
{
$data = array();
//Set Meta Tags
$this->meta = ($html5 == TRUE) ?
T1.'<meta charset="utf-8" />'.NL. $this->meta :
T1.meta('content-type', 'text/html; charset=utf-8', 'equiv').NL.$this->meta;
$data['meta'] = $this->meta;
//Set CSS
if ($this->css != "")
{
$data['css'] = $this->css;
}
else
{
//Set default CSS group
$this->set_css_group($this->CI->config->item('default_css_group'));
$data['css'] = $this->css;
}
//Set head javascript
if($this->head_js != "")
{
$data['head_js'] = $this->head_js;
}
else
{
$this->set_head_js_group($this->CI->config->item('default_head_js_group'));
$data['head_js'] = $this->head_js;
}
//Set Page Title
$data['title'] = ($this->title != '') ? $this->title : $this->CI->config->item('default_title');
//Set Body Class
$data['body_class'] = $this->body_class;
//Set Body Id
$data['body_id'] = $this->body_id;
//Set Base HREF
$data['base'] = $this->base;
//Set individual head tags
$data['head_tags'] = $this->head_tags;
//Set Server Headers and Doctype
$this->_headers($xhtml, $html5);
//Output Header
$this->CI->load->view('header', $data);
flush();
return $this;
}
// --------------------------------------------------------------------------
/**
* Builds common footer with any additional js
*/
public function build_footer()
{
$data = array();
$data['foot_js'] = ($this->foot_js != "") ?
$this->foot_js : '';
$this->CI->load->view('footer', $data);
}
// --------------------------------------------------------------------------
/**
* Script Tag
*
* Helper function for making script tags
*
* @param string $js
* @param bool $domain
* @return string
*/
private function script_tag($js, $domain=TRUE)
{
$path = $this->CI->config->item('content_domain');
$js_file = $path . "/js/" . $js . ".js";
if ($domain == FALSE)
$js_file = $js;
$tag = T1.'<script src="' .
$js_file .
'"></script>'.NL;
return $tag;
}
// --------------------------------------------------------------------------
/**
* Quick Build
*
* A function to make building pages faster
* @param mixed $view
* @param mixed $data
* @param bool $xhtml
* @param bool $html5
*/
public function quick_build($view, $data, $xhtml=TRUE, $html5=TRUE)
{
//Set up header
if ($title != '')
{
$this->set_title($title);
}
else
{
$this->set_title($this->CI->config->item('default_title'));
}
$this->build_header($xhtml, $html5);
//Load view(s)
if (is_array($view))
{
foreach ($view as $v)
{
$this->CI->load->view($v, $data);
}
}
else
{
$this->CI->load->view($view, $data);
}
//Create footer
$this->build_footer();
}
// --------------------------------------------------------------------------
/**
* Num Queries
*
* Returns number of queries run on a page
*
* @return int
*/
public function num_queries()
{
return (isset($this->CI->db)) ? count($this->CI->db->queries) : 0;
}
// --------------------------------------------------------------------------
/**
* Set Message
*
* Adds a message to the page
* @param string $type
* @param string $message
* @return void
*/
public function set_message($type, $message)
{
$data['stat_class'] = $type;
$data['message'] = $message;
$this->CI->load->view('message', $data);
}
// --------------------------------------------------------------------------
/**
* Redirect 303
*
* Shortcut function for 303 redirect
* @param string $url
*/
function redirect_303($url)
{
$this->CI->output->set_header("HTTP/1.1 303 See Other");
$this->CI->output->set_header("Location:" . $url);
}
}

View File

@ -0,0 +1,9 @@
<? $q_num = $this->page->num_queries() ?>
<footer class="footer">
Generated in <?= $this->benchmark->elapsed_time();?> seconds, <?= $q_num ?> quer<?= ($q_num == 1) ? "y": "ies" ?>
<? if($foot_js != ""): ?>
<?= $foot_js ?>
<? endif ?>
</footer>
</body>
</html>

View File

@ -0,0 +1,11 @@
<head>
<?= $meta ?>
<?= $css ?>
<?= $head_tags ?>
<title><?= $title ?></title>
<? if(!empty($base)) { ?><base href="<?=$base ?>" /><? } ?>
<?= $head_tags ?>
<?= $head_js ?>
</head>
<body<?= (!empty($body_class)) ? "class=\"" . $body_class . "\"" : ""; ?><?= (!empty($body_id)) ? " id=\"" . $body_id . "\"" : ""; ?>>

View File

@ -0,0 +1,5 @@
<section class="message <?= $stat_class ?>">
<span class="icon"></span>
<?= $message ?>
<span class="close"></span>
</section>

36
assets/css/message.css Normal file
View File

@ -0,0 +1,36 @@
.message{
position:relative;
margin:0.5em auto;
padding:0.5em;
width:95%;
}
.message .close{
width:1em;
height:1em;
border:1px solid #000;
position:absolute;
right:0.5em;
top:0.5em;
}
.message .icon{
left:0.5em;
top:0.5em;
margin-right:1em;
}
.error{
border:1px solid #924949;
background: #f3e6e6;
}
.success{
border:1px solid #1f8454;
background: #70dda9;
}
.info{
border:1px solid #bfbe3a;
background: #d6d578;
}

926
assets/js/kis-all.js Normal file
View File

@ -0,0 +1,926 @@
/**
Kis JS Keep It Simple JS Library
Copyright Timothy J. Warren
License Public Domain
Version 0.2.0
*/
(function (){
"use strict";
//Browser requirements check
if (!document.querySelectorAll)
{
return;
}
var $_, $, dcopy, sel;
/**
* $
*
* Simple DOM selector function
*/
$ = function (a)
{
var x;
if (typeof a !== "string" || typeof a === "undefined"){ return a;}
//Pick the quickest method for each kind of selector
if(a.match(/^#([\w\-]+$)/))
{
return document.getElementById(a.split('#')[1]);
}
else if(a.match(/^([\w\-]+)$/))
{
x = document.getElementsByTagName(a);
}
else
{
x = document.querySelectorAll(a);
}
//Return the single object if applicable
return (x.length === 1) ? x[0] : x;
};
/**
* $_
*
* Constructor function
*/
$_ = function(s)
{
//Have documentElement be default selector, just in case
if(typeof s == "undefined")
{
sel = (typeof $_.el !== "undefined")
? $_.el
: document.documentElement;
}
else
{
sel = $(s);
}
// Make a copy before adding properties
var self = dcopy($_);
// Give sel to each extension.
for(var i in self)
{
if(typeof self[i] === "object")
{
self[i].el = sel;
}
}
self.el = sel;
return self;
};
/**
* Deep copy/prototypical constructor function
*/
dcopy = function(obj)
{
var type, F;
if(typeof obj === "undefined")
{
return;
}
if(typeof Object.create !== "undefined")
{
return Object.create(obj);
}
type = typeof obj;
if(type !== "object" && type !== "function")
{
return;
}
F = function(){};
F.prototype = obj;
return new F();
};
//Function to add to $_ object, and get sel
$_.ext = function(name, obj)
{
$_[name] = obj;
obj.el = sel;
};
//Selector iteration
$_.ext('each', function (callback)
{
if(typeof sel.length !== "undefined" && sel !== window)
{
var len = sel.length;
if (len === 0)
{
return;
}
var selx;
for (var x = 0; x < len; x++)
{
selx = (sel.item(x)) ? sel.item(x) : sel[x];
callback(selx);
}
}
else
{
callback(sel);
}
});
//Set global variables
$_ = window.$_ = window.$_ || $_;
$_.$ = $;
//console.log polyfill
if(typeof window.console === "undefined")
{
window.console = {
log:function(){}
};
}
/**
* String trim function polyfill
*/
if(typeof String.prototype.trim === "undefined")
{
String.prototype.trim = function(){
return this.replace(/^\s+|\s+$/g, "");
};
}
}());
// --------------------------------------------------------------------------
//Function to maintain module scope
(function(){
"use strict";
//Fix $_ is not defined errors
var $_ = $_ || window.$_;
// --------------------------------------------------------------------------
/**
* Dom manipulation object
*
*/
(function (){
var d;
/*
* classList.js: Cross-browser full element.classList implementation.
* 2011-06-15
*
* By Eli Grey, http://eligrey.com
* Public Domain.
* NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
*/
if (typeof document !== "undefined" && !("classList" in document.createElement("a")))
{
(function (view){
var classListProp = "classList",
protoProp = "prototype",
elemCtrProto = (view.HTMLElement || view.Element)[protoProp],
objCtr = Object,
strTrim = String[protoProp].trim ||
function ()
{
return this.replace(/^\s+|\s+$/g, "");
},
arrIndexOf = Array[protoProp].indexOf ||
function (item)
{
var
i = 0,
len = this.length;
for (; i < len; i++)
{
if (i in this && this[i] === item)
{
return i;
}
}
return -1;
}
// Vendors: please allow content code to instantiate DOMExceptions
,
DOMEx = function (type, message)
{
this.name = type;
this.code = DOMException[type];
this.message = message;
},
checkTokenAndGetIndex = function (classList, token)
{
if (token === "")
{
throw new DOMEx("SYNTAX_ERR", "An invalid or illegal string was specified");
}
if (/\s/.test(token))
{
throw new DOMEx("INVALID_CHARACTER_ERR", "String contains an invalid character");
}
return arrIndexOf.call(classList, token);
},
ClassList = function (elem)
{
var
trimmedClasses = strTrim.call(elem.className),
classes = trimmedClasses ? trimmedClasses.split(/\s+/) : [],
i = 0,
len = classes.length;
for (; i < len; i++)
{
this.push(classes[i]);
}
this._updateClassName = function ()
{
elem.className = this.toString();
};
},
classListProto = ClassList[protoProp] = [],
classListGetter = function ()
{
return new ClassList(this);
};
// Most DOMException implementations don't allow calling DOMException's toString()
// on non-DOMExceptions. Error's toString() is sufficient here.
DOMEx[protoProp] = Error[protoProp];
classListProto.item = function (i)
{
return this[i] || null;
};
classListProto.contains = function (token)
{
token += "";
return checkTokenAndGetIndex(this, token) !== -1;
};
classListProto.add = function (token)
{
token += "";
if (checkTokenAndGetIndex(this, token) === -1)
{
this.push(token);
this._updateClassName();
}
};
classListProto.remove = function (token)
{
token += "";
var index = checkTokenAndGetIndex(this, token);
if (index !== -1)
{
this.splice(index, 1);
this._updateClassName();
}
};
classListProto.toggle = function (token)
{
token += "";
if (checkTokenAndGetIndex(this, token) === -1)
{
this.add(token);
}
else
{
this.remove(token);
}
};
classListProto.toString = function ()
{
return this.join(" ");
};
if (objCtr.defineProperty)
{
var classListPropDesc = {
get: classListGetter,
enumerable: true,
configurable: true
};
try
{
objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
}
catch (ex)
{ // IE 8 doesn't support enumerable:true
if (ex.number === -0x7FF5EC54)
{
classListPropDesc.enumerable = false;
objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
}
}
}
else if (objCtr[protoProp].__defineGetter__)
{
elemCtrProto.__defineGetter__(classListProp, classListGetter);
}
}(self));
}
// --------------------------------------------------------------------------
//Private function for getting/setting attributes
function _attr(sel, name, value)
{
var oldVal, doAttr;
//Get the value of the attribute, if it exists
if (typeof sel.hasAttribute !== "undefined")
{
if (sel.hasAttribute(name))
{
oldVal = sel.getAttribute(name);
}
doAttr = true;
}
else if (typeof sel[name] !== "undefined")
{
oldVal = sel[name];
doAttr = false;
}
else if (name === "class" && typeof sel.className !== "undefined") //className attribute
{
name = "className";
oldVal = sel.className;
doAttr = false;
}
//Well, I guess that attribute doesn't exist
if (typeof oldVal === "undefined" && (typeof value === "undefined" || value === null))
{
console.log(value);
console.log(sel);
console.log("Element does not have the selected attribute");
return;
}
//No value to set? Return the current value
if (typeof value === "undefined")
{
return oldVal;
}
//Determine what to do with the attribute
if (typeof value !== "undefined" && value !== null)
{
if(doAttr === true)
{
sel.setAttribute(name, value);
}
else
{
sel[name] = value;
}
}
else if (value === null)
{
if(doAttr === true)
{
sel.removeAttribute(name);
}
else
{
delete sel[name];
}
}
return (typeof value !== "undefined") ? value : oldVal;
}
function _toCamel(s)
{
return s.replace(/(\-[a-z])/g, function($1){
return $1.toUpperCase().replace('-','');
});
}
function _css(sel, prop, val)
{
var equi;
//Camel-case
prop = _toCamel(prop);
//Equivalent properties for 'special' browsers
equi = {
outerHeight: "offsetHeight",
outerWidth: "offsetWidth",
top: "posTop"
}
//If you don't define a value, try returning the existing value
if(typeof val === "undefined" && sel.style[prop] !== "undefined")
{
return sel.style[prop];
}
else if(typeof val === "undefined" && sel.style[equi[prop]] !== "undefined")
{
return sel.style[equi[prop]];
}
//Let's try the easy way first
if(typeof sel.style[prop] !== "undefined")
{
sel.style[prop] = val;
//Short circuit
return;
}
else if(sel.style[equi[prop]])
{
sel.style[equi[prop]] = val;
return;
}
//No matches? Well, lets log it for now
console.log("Property " + prop + " nor an equivalent seems to exist");
}
// --------------------------------------------------------------------------
d = {
addClass: function (c)
{
$_.each(function (e){
e.classList.add(c);
});
},
removeClass: function (c)
{
$_.each(function (e){
e.classList.remove(c);
});
},
hide: function ()
{
this.css('display', 'none');
},
show: function (type)
{
if (typeof type === "undefined")
{
type = "block";
}
this.css("display", type);
},
attr: function (name, value)
{
var sel = this.el;
//Make sure you don't try to get a bunch of elements
if (sel.length > 1 && typeof value === "undefined")
{
console.log(sel);
console.log("Must be a singular element");
return;
}
else if (sel.length > 1 && typeof value !== "undefined") //You can set a bunch, though
{
$_.each(function (e){
return _attr(e, name, value);
});
}
else //Normal behavior
{
return _attr(sel, name, value);
}
},
text: function (value)
{
var oldValue, set, type, sel;
sel = this.el;
set = (typeof value !== "undefined") ? true : false;
type = (typeof sel.innerText !== "undefined")
? "innerText"
: (typeof sel.textContent !== "undefined")
? "textContent"
: "innerHTML";
oldValue = sel[type];
if(set)
{
sel[type] = value;
return value;
}
else
{
return oldValue;
}
},
css: function (prop, val)
{
if(typeof val === "undefined")
{
return _css(this.el, prop);
}
$_.each(function (e){
_css(e, prop, val);
});
}
};
$_.ext('dom', d);
}());
// --------------------------------------------------------------------------
/**
* Store object
*
* Wrapper for localstorage data serialization
*/
(function (){
var store = {
get: function (key)
{
return JSON.parse(localStorage.getItem(key));
},
set: function (key, value)
{
if (typeof value !== "string")
{
value = JSON.stringify(value);
}
localStorage.setItem(key, value);
},
getAll: function ()
{
var i,
len,
data;
len = localStorage.length;
data = {};
for (i = 0; i < len; i++)
{
var name = localStorage.key(i);
var value = localStorage.getItem(name);
data[name] = value;
}
return data;
}
};
$_.ext('store', store);
}());
// --------------------------------------------------------------------------
/**
* Qs
*
* Object for encoding and decoding querystrings and hashbang strings
*/
(function (){
$_.hb = (history.pushState) ? false : true;
var qs = {
parse: function (hb)
{
hb = hb || $_.hb;
var h, i, hString, pairs, pLen, data, y;
data = {};
if (hb === true)
{
h = location.hash.split('#!/');
hString = (h.length > 1) ? h[1] : '';
}
else if (hb === false || hb === undefined)
{
hString = window.location.search.substring(1);
}
else
{
return false;
}
pairs = hString.split('&');
pLen = pairs.length;
for (i = 0; i < pLen; i++)
{
y = pairs[i].split('=');
if (y.length < 2)
{
return data;
}
data[y[0]] = y[1];
}
return data;
},
set: function (key, value, hb)
{
hb = hb || $_.hb;
var pairs = this.parse(hb);
if (key !== undefined && value !== undefined)
{
pairs[key] = value;
}
var vars = [];
for (var x in pairs)
{
if (pairs.hasOwnProperty(x))
{
vars.push(x + '=' + pairs[x]);
}
}
var qs = vars.join('&');
if (hb === true)
{
qs = '!/' + qs;
location.hash = qs;
}
return qs;
},
get: function (key, hb)
{
hb = hb || $_.hb;
var pairs = this.parse(hb);
return (pairs[key]) ? pairs[key] : '';
}
};
$_.ext('qs', qs);
}());
// --------------------------------------------------------------------------
/**
* Ajax
*
* Object for making ajax requests
*/
(function (){
var ajax = {
_do: function (url, data, callback, isPost)
{
if (typeof callback === "undefined")
{
callback = function (){};
}
var request = (typeof window.XMLHttpRequest !== "undefined")
? new XMLHttpRequest()
: false;
var type = (isPost) ? "POST" : "GET";
url += (type === "GET") ? "?"+this._serialize(data, true) : '';
request.open(type, url);
request.onreadystatechange = function ()
{
if (request.readyState === 4)
{
callback(request.responseText);
}
};
if (type === "POST")
{
request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
request.send(this._serialize(data));
}
else
{
request.send(null);
}
},
_serialize: function (data, encode)
{
var pairs = [];
for (var name in data)
{
if (!data.hasOwnProperty(name))
{
continue;
}
if (typeof data[name] === "function")
{
continue;
}
var value = data[name].toString();
if (encode === true)
{
name = encodeURIComponent(name.replace(" ", "+"));
value = encodeURIComponent(value.replace(" ", "+"));
}
pairs.push(name + "=" + value);
}
return pairs.join("&");
}
};
$_.ext('get', function (url, data, callback){
ajax._do(url, data, callback, false);
});
$_.ext('post', function (url, data, callback){
ajax._do(url, data, callback, true);
});
}());
// --------------------------------------------------------------------------
/**
* Event object
*
* Event api wrapper
*/
(function (){
// Property name for expandos on DOM objects
var kis_expando = "KIS_0_2_0";
var attach, remove, add_remove, e;
// Define the proper attach and remove functions
// based on browser support
if(typeof document.addEventListener !== "undefined")
{
attach = function (sel, event, callback)
{
if (typeof sel.addEventListener !== "undefined")
{
sel.addEventListener(event, callback, false);
}
};
remove = function (sel, event, callback)
{
if (typeof sel.removeEventListener !== "undefined")
{
sel.removeEventListener(event, callback, false);
}
};
}
//typeof function doesn't work in IE where attachEvent is available: brute force it
else if(typeof document.attachEvent !== "undefined")
{
attach = function (sel, event, callback)
{
function listener () {
// Internet Explorer fails to correctly set the 'this' object
// for event listeners, so we need to set it ourselves.
callback.apply(arguments);
}
if (typeof sel.attachEvent !== "undefined")
{
remove(event, callback); // Make sure we don't have duplicate listeners
sel.attachEvent("on" + event, listener);
// Store our listener so we can remove it later
var expando = sel[kis_expando] = sel[kis_expando] || {};
expando.listeners = expando.listeners || {};
expando.listeners[event] = expando.listeners[event] || [];
expando.listeners[event].push({
callback: callback,
listener: listener
});
}
else
{
console.log("Failed to attach event:"+event+" on "+sel);
}
};
remove = function (sel, event, callback)
{
if(typeof sel.detachEvent !== "undefined")
{
var expando = sel[kis_expando];
if (expando && expando.listeners
&& expando.listeners[event])
{
var listeners = expando.listeners[event];
var len = listeners.length;
for (var i=0; i<len; i++)
{
if (listeners[i].callback === callback)
{
sel.detachEvent("on" + event, listeners[i].listener);
listeners.splice(i, 1);
if(listeners.length === 0)
{
delete expando.listeners[event];
}
return;
}
}
}
}
};
}
add_remove = function (sel, event, callback, add)
{
var i, len;
if(typeof sel === "undefined")
{
console.log(arguments);
console.log(event);
return false;
}
//Multiple events? Run recursively!
if (!event.match(/^([\w\-]+)$/))
{
event = event.split(" ");
len = event.length;
for (i = 0; i < len; i++)
{
add_remove(sel, event[i], callback, add);
}
return;
}
if(add === true)
{
attach(sel, event, callback);
}
else
{
remove(sel, event, callback);
}
};
e = {
add: function (event, callback)
{
$_.each(function(e){
add_remove(e, event, callback, true);
});
},
remove: function (event, callback)
{
$_.each(function(e){
add_remove(e, event, callback, false);
});
}
};
$_.ext('event', e);
}());
}());

3
assets/js/message.js Normal file
View File

@ -0,0 +1,3 @@
$_(".message .close").event.add("click", function(){
$_(this.parentNode).dom.hide();
});

19
config/css_groups.php Normal file
View File

@ -0,0 +1,19 @@
<?php
return array(
/*-----
Css
-----*/
/*
For each group create an array like so
'my_group' => array(
'path/to/css/file1.css',
'path/to/css/file2.css'
),
*/
'css' => array(
'assets/css/message.css',
),
);

16
config/js_groups.php Normal file
View File

@ -0,0 +1,16 @@
<?php
return array(
/*
For each group create an array like so
'my_group' => array(
'path/to/css/file1.css',
'path/to/css/file2.css'
),
*/
'js' => array(
'assets/js/kis-all.js',
'assets/js/message.js',
)
);

333
config/jshrink.php Normal file
View File

@ -0,0 +1,333 @@
<?php
/*
JShrink
Copyright (c) 2009, Robert Hafner
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following
disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* JShrink
*
* Usage - JShrink::minify($js);
* Usage - JShrink::minify($js, $options);
* Usage - JShrink::minify($js, array('flaggedComments' => false));
*
* @version 0.2
* @package JShrink
* @author Robert Hafner <tedivm@tedivm.com>
* @license http://www.opensource.org/licenses/bsd-license.php
*/
class JShrink
{
protected $input;
protected $index = 0;
protected $a = '';
protected $b = '';
protected $c;
protected $options;
static protected $defaultOptions = array('flaggedComments' => true);
static public function minify($js, $options = array())
{
try{
$currentOptions = array_merge(self::$defaultOptions, $options);
ob_start();
$currentOptions = array_merge(self::$defaultOptions, $options);
$me = new JShrink();
$me->breakdownScript($js, $currentOptions);
$output = ob_get_clean();
return $output;
}catch(Exception $e){
ob_end_clean();
throw $e;
}
}
protected function breakdownScript($js, $currentOptions)
{
$this->options = $currentOptions;
$js = str_replace("\r\n", "\n", $js);
$this->input = str_replace("\r", "\n", $js);
$this->a = $this->getReal();
// the only time the length can be higher than 1 is if a conditional comment needs to be displayed
// and the only time that can happen for $a is on the very first run
while(strlen($this->a) > 1)
{
echo $this->a;
$this->a = $this->getReal();
}
$this->b = $this->getReal();
while($this->a !== false && !is_null($this->a) && $this->a !== '')
{
// now we give $b the same check for conditional comments we gave $a before we began looping
if(strlen($this->b) > 1)
{
echo $this->a . $this->b;
$this->a = $this->getReal();
$this->b = $this->getReal();
continue;
}
switch($this->a)
{
// new lines
case "\n":
// if the next line is something that can't stand alone preserver the newline
if(strpos('(-+{[@', $this->b) !== false)
{
echo $this->a;
$this->saveString();
break;
}
// if its a space we move down to the string test below
if($this->b === ' ')
break;
// otherwise we treat the newline like a space
case ' ':
if(self::isAlphaNumeric($this->b))
echo $this->a;
$this->saveString();
break;
default:
switch($this->b)
{
case "\n":
if(strpos('}])+-"\'', $this->a) !== false)
{
echo $this->a;
$this->saveString();
break;
}else{
if(self::isAlphaNumeric($this->a))
{
echo $this->a;
$this->saveString();
}
}
break;
case ' ':
if(!self::isAlphaNumeric($this->a))
break;
default:
// check for some regex that breaks stuff
if($this->a == '/' && ($this->b == '\'' || $this->b == '"'))
{
$this->saveRegex();
continue;
}
echo $this->a;
$this->saveString();
break;
}
}
// do reg check of doom
$this->b = $this->getReal();
if(($this->b == '/' && strpos('(,=:[!&|?', $this->a) !== false))
$this->saveRegex();
}
}
protected function getChar()
{
if(isset($this->c))
{
$char = $this->c;
unset($this->c);
}else{
if(isset($this->input[$this->index]))
{
$char = $this->input[$this->index];
$this->index++;
}else{
return false;
}
}
if($char === "\n" || ord($char) >= 32)
return $char;
return ' ';
}
protected function getReal()
{
$startIndex = $this->index;
$char = $this->getChar();
if($char == '/')
{
$this->c = $this->getChar();
if($this->c == '/')
{
$thirdCommentString = $this->input[$this->index];
// kill rest of line
$char = $this->getNext("\n");
if($thirdCommentString == '@')
{
$endPoint = ($this->index) - $startIndex;
unset($this->c);
$char = "\n" . substr($this->input, $startIndex, $endPoint);// . "\n";
}else{
$char = $this->getChar();
$char = $this->getChar();
}
}elseif($this->c == '*'){
$this->getChar(); // current C
$thirdCommentString = $this->getChar();
if($thirdCommentString == '@')
{
// we're gonna back up a bit and and send the comment back, where the first
// char will be echoed and the rest will be treated like a string
$this->index = $this->index-2;
return '/';
}elseif($this->getNext('*/')){
// kill everything up to the next */
$this->getChar(); // get *
$this->getChar(); // get /
$char = $this->getChar(); // get next real charactor
// if YUI-style comments are enabled we reinsert it into the stream
if($this->options['flaggedComments'] && $thirdCommentString == '!')
{
$endPoint = ($this->index - 1) - $startIndex;
echo "\n" . substr($this->input, $startIndex, $endPoint) . "\n";
}
}else{
$char = false;
}
if($char === false)
throw new JShrinkException('Stray comment. ' . $this->index);
// if we're here c is part of the comment and therefore tossed
if(isset($this->c))
unset($this->c);
}
}
return $char;
}
protected function getNext($string)
{
$pos = strpos($this->input, $string, $this->index);
if($pos === false)
return false;
$this->index = $pos ;
return $this->input[$this->index];
}
protected function saveString()
{
$this->a = $this->b;
if($this->a == '\'' || $this->a == '"')
{
// save literal string
$stringType = $this->a;
while(1)
{
echo $this->a;
$this->a = $this->getChar();
switch($this->a)
{
case $stringType:
break 2;
case "\n":
throw new JShrinkException('Unclosed string. ' . $this->index);
break;
case '\\':
echo $this->a;
$this->a = $this->getChar();
}
}
}
}
protected function saveRegex()
{
echo $this->a . $this->b;
while(($this->a = $this->getChar()) !== false)
{
if($this->a == '/')
break;
if($this->a == '\\')
{
echo $this->a;
$this->a = $this->getChar();
}
if($this->a == "\n")
throw new JShrinkException('Stray regex pattern. ' . $this->index);
echo $this->a;
}
$this->b = $this->getReal();
}
static protected function isAlphaNumeric($char)
{
return preg_match('/^[\w\$]$/', $char) === 1 || $char == '/';
}
}
// Adding a custom exception handler for your own projects just means changing this line
class JShrinkException extends Exception {}
?>

82
css.php Normal file
View File

@ -0,0 +1,82 @@
<?php
//Change as needed
$base_path = $_SERVER['DOCUMENT_ROOT'];
//This GZIPs the CSS for transmission to the user
//making file size smaller and transfer rate quicker
ob_start("ob_gzhandler");
//Function for compressing the CSS as tightly as possible
function compress($buffer) {
//Remove CSS comments
$buffer = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $buffer);
//Remove tabs, spaces, newlines, etc.
$buffer = str_replace(array("\r\n", "\r", "\n", "\t", ' ', ' ', ' '), '', $buffer);
$buffer = preg_replace('`\s+`', ' ', $buffer);
return $buffer;
}
//Creative rewriting
$pi = $_SERVER['PATH_INFO'];
$pia = explode('/', $pi);
$pia_len = count($pia);
$i = 1;
while($i < $pia_len)
{
$j = $i+1;
$j = (isset($pia[$j])) ? $j : $i;
$_GET[$pia[$i]] = $pia[$j];
$i = $j + 1;
};
//Include the css groups
$groups = require("./config/css_groups.php");
$css = '';
$modified = array();
if(isset($groups[$_GET['g']]))
{
foreach($groups[$_GET['g']] as $file)
{
$new_file = realpath($base_path.$file);
$css .= file_get_contents($new_file);
$modified[] = filemtime($new_file);
}
}
//Add this page too
$modified[] = filemtime($base_path."css.php");
//Get the latest modified date
rsort($modified);
$last_modified = $modified[0];
if(!isset($_GET['debug']))
{
$css = compress($css);
}
$requested_time=(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']))
? strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])
: time();
if($last_modified === $requested_time)
{
header("HTTP/1.1 304 Not Modified");
exit();
}
header("Content-Type: text/css; charset=utf8");
header("Cache-control: public, max-age=691200, must-revalidate");
header("Last-Modified: ".gmdate('D, d M Y H:i:s', $last_modified)." GMT");
header("Expires: ".gmdate('D, d M Y H:i:s', (filemtime($base_path.'css.php') + 691200))." GMT");
echo $css;
ob_end_flush();
//End of css.php

74
js.php Normal file
View File

@ -0,0 +1,74 @@
<?php
//Change as needed
$base_path = $_SERVER['DOCUMENT_ROOT'];
require('./config/jshrink.php');
//This GZIPs the js for transmission to the user
//making file size smaller and transfer rate quicker
ob_start("ob_gzhandler");
//Creative rewriting
$pi = $_SERVER['PATH_INFO'];
$pia = explode('/', $pi);
$pia_len = count($pia);
$i = 1;
while($i < $pia_len)
{
$j = $i+1;
$j = (isset($pia[$j])) ? $j : $i;
$_GET[$pia[$i]] = $pia[$j];
$i = $j + 1;
};
//Include the js groups
$groups = require("./config/js_groups.php");
$js = '';
$modified = array();
if(isset($groups[$_GET['g']]))
{
foreach($groups[$_GET['g']] as $file)
{
$new_file = realpath($base_path.$file);
$js .= file_get_contents($new_file);
$modified[] = filemtime($new_file);
}
}
//Add this page too
$modified[] = filemtime($base_path."js.php");
//Get the latest modified date
rsort($modified);
$last_modified = $modified[0];
if(!isset($_GET['debug']))
{
$js = JShrink::minify($js, array('flaggedComments' => false));
}
$requested_time=(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']))
? strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])
: time();
if($last_modified === $requested_time)
{
header("HTTP/1.1 304 Not Modified");
exit();
}
header("Content-Type: application/x-javascript; charset=utf8");
header("Cache-control: public, max-age=691200, must-revalidate");
header("Last-Modified: ".gmdate('D, d M Y H:i:s', $last_modified)." GMT");
header("Expires: ".gmdate('D, d M Y H:i:s', (filemtime($base_path.'js.php') + 691200))." GMT");
echo $js;
ob_end_flush();
//end of js.php