/* version: 0.2.80 */
var Absurd = (function(w) {
var lib = {
api: {},
helpers: {},
plugins: {},
processors: {
css: { plugins: {}},
html: {
plugins: {},
helpers: {}
},
component: { plugins: {}}
}
};
var require = function(v) {
// css preprocessor
if(v.indexOf('css/CSS.js') > 0 || v == '/../CSS.js') {
return lib.processors.css.CSS;
} else if(v.indexOf('html/HTML.js') > 0) {
return lib.processors.html.HTML;
} else if(v.indexOf('component/Component.js') > 0) {
return lib.processors.component.Component;
} else if(v == 'js-beautify') {
return {
html: function(html) {
return html;
}
}
} else if(v == './helpers/PropAnalyzer') {
return lib.processors.html.helpers.PropAnalyzer;
} else if(v == '../../helpers/TransformUppercase') {
return lib.helpers.TransformUppercase;
} else if(v == './helpers/TemplateEngine') {
return lib.processors.html.helpers.TemplateEngine;
} else if(v == '../helpers/Extend') {
return lib.helpers.Extend;
} else if(v == '../helpers/Clone') {
return lib.helpers.Clone;
} else if(v == '../helpers/Prefixes' || v == '/../../../helpers/Prefixes') {
return lib.helpers.Prefixes;
} else {
return function() {}
}
};
var __dirname = "";
var queue = function(funcs, scope) {
(function next() {
if(funcs.length > 0) {
funcs.shift().apply(scope || {}, [next].concat(Array.prototype.slice.call(arguments, 0)));
}
})();
}
var select = function(selector, parent) {
var result;
try {
result = (parent || document).querySelectorAll(selector);
} catch(err) {
result = document.querySelectorAll(selector);
}
return result;
}
var str2DOMElement = function(html) {
/* code taken from jQuery */
var wrapMap = {
option: [ 1, "", " " ],
legend: [ 1, "
", " " ],
area: [ 1, "", " " ],
param: [ 1, "", " " ],
thead: [ 1, "" ],
tr: [ 2, "" ],
col: [ 2, "" ],
td: [ 3, "" ],
// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
// unless wrapped in a div with non-breaking characters in front of it.
_default: [ 1, "", "
" ]
};
wrapMap.optgroup = wrapMap.option;
wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
wrapMap.th = wrapMap.td;
var element = document.createElement('div');
var match = /<\s*\w.*?>/g.exec(html);
if(match != null) {
var tag = match[0].replace(//g, '');
var map = wrapMap[tag] || wrapMap._default, element;
html = map[1] + html + map[2];
element.innerHTML = html;
// Descend through wrappers to the right content
var j = map[0]+1;
while(j--) {
element = element.lastChild;
}
} else {
element.innerHTML = html;
element = element.lastChild;
}
return element;
}
var addEventListener = function(obj, evt, fnc) {
if (obj.addEventListener) { // W3C model
obj.addEventListener(evt, fnc, false);
return true;
} else if (obj.attachEvent) { // Microsoft model
return obj.attachEvent('on' + evt, fnc);
}
}
var removeEmptyTextNodes = function(elem) {
var children = elem.childNodes;
var child;
var len = children.length;
var i = 0;
var whitespace = /^\s*$/;
for(; i < len; i++){
child = children[i];
if(child.nodeType == 3){
if(whitespace.test(child.nodeValue)){
elem.removeChild(child);
i--;
len--;
}
}
}
return elem;
}
var createNode = function(type, attrs, content) {
var node = document.createElement(type);
for(var i=0; i= e2.childNodes.length) {
for(var i=0; i 0) {
this.el = element[0];
HTMLSource = {'': this.el.outerHTML.replace(/</g, '<').replace(/>/g, '>') };
}
}
compile();
} else if(typeof this.html === 'object') {
HTMLSource = extend({}, this.html);
compile();
} else {
next();
}
} else {
next();
}
return this;
};
var appended = false
api.__append = function(next) {
if(!appended && this.el && this.get("parent")) {
appended = true;
this.get("parent").appendChild(this.el);
}
next();
return this;
}
var cache = { events: {} };
api.__handleEvents = function(next) {
if(this.el) {
var self = this;
var registerEvent = function(el) {
var attrValue = el.getAttribute('data-absurd-event');
attrValue = attrValue.split(":");
if(attrValue.length >= 2) {
var eventType = attrValue[0];
var methodName = attrValue[1];
attrValue.splice(0, 2);
var args = attrValue;
if(!cache.events[eventType] || cache.events[eventType].indexOf(el) < 0) {
if(!cache.events[eventType]) cache.events[eventType] = [];
cache.events[eventType].push(el);
addEventListener(el, eventType, function(e) {
if(typeof self[methodName] === 'function') {
var f = self[methodName];
f.apply(self, [e].concat(args));
}
});
}
}
}
if(this.el.hasAttribute && this.el.hasAttribute('data-absurd-event')) {
registerEvent(this.el);
}
var els = this.el.querySelectorAll ? this.el.querySelectorAll('[data-absurd-event]') : [];
for(var i=0; i';
};
api.child = function() {
var args = Array.prototype.slice.call(arguments, 0),
children = this.get("children"),
component = children && children[args.shift()],
index = '_' + (async.index++);
async.funcs[index] = {args: args, func: function(callback) {
component.populate({callback: function(data) {
callback(data.html.element);
}});
}};
return '';
};
api.wire = function(event) {
absurd.components.events.on(event, this[event] || function() {}, this);
return this;
};
api.populate = function(options) {
queue([
api.__handleCSS,
api.__handleHTML,
api.__append,
api.__handleEvents,
api.__handleAsyncFunctions,
function() {
async = { funcs: {}, index: 0 }
var data = {
css: CSS,
html: {
element: this.el
}
};
this.dispatch("populated", data);
if(options && typeof options.callback === 'function') { options.callback(data); }
}
], this);
return this;
};
api.str2DOMElement = str2DOMElement;
api.addEventListener = addEventListener;
api.queue = queue;
api.compileHTML = function(HTML, callback, data) {
absurd.flush().morph("html").add(HTML).compile(callback, data);
};
api.compileCSS = function(CSS, callback, options) {
absurd.flush().add(CSS).compile(callback, options);
};
api.qs = function(selector, parent) {
if(parent === false) { parent = document; }
else { parent = parent || this.el || document; }
return parent.querySelector(selector);
};
api.qsa = function(selector, parent) {
if(parent === false) { parent = document; }
else { parent = parent || this.el || document; }
return parent.querySelectorAll(selector);
};
api.getStyle = function(styleProp, el) {
el = el || this.el;
if(el && el.currentStyle) {
return el.currentStyle[styleProp];
} else if (window.getComputedStyle) {
return document.defaultView.getComputedStyle(el, null).getPropertyValue(styleProp);
}
return null;
};
api.addClass = function(className, el) {
el = el || this.el;
if(el.classList) {
el.classList.add(className);
} else {
var current = el.className;
if(current.indexOf(className) < 0) {
if(current == '') el.className = className;
else el.className += ' ' + className;
}
}
return api;
};
api.removeClass = function(className, el) {
el = el || this.el;
if (el.classList) {
el.classList.remove(className);
} else {
var current = el.className.split(' ');
var newClasses = [];
for(var i=0; i= 0)
classes.splice(existingIndex, 1);
else
classes.push(className);
el.className = classes.join(' ');
}
return api;
}
return api;
};
var client = function() {
return function(arg) {
/******************************************* Copied directly from /lib/API.js */
var extend = function(destination, source) {
for (var key in source) {
if (hasOwnProperty.call(source, key)) {
destination[key] = source[key];
}
}
return destination;
};
var _api = {
defaultProcessor: lib.processors.css.CSS()
},
_rules = {},
_storage = {},
_plugins = {},
_hooks = {};
_api.getRules = function(stylesheet) {
if(typeof stylesheet === 'undefined') {
return _rules;
} else {
if(typeof _rules[stylesheet] === 'undefined') {
_rules[stylesheet] = [];
}
return _rules[stylesheet];
}
}
_api.getPlugins = function() {
return _plugins;
}
_api.getStorage = function() {
return _storage;
}
_api.flush = function() {
_rules = {};
_storage = [];
_hooks = {};
_api.defaultProcessor = lib.processors.css.CSS();
return _api;
}
_api.import = function() {
if(_api.callHooks("import", arguments)) return _api;
return _api;
}
// hooks
_api.addHook = function(method, callback) {
if(!_hooks[method]) _hooks[method] = [];
var isAlreadyAdded = false;
for(var i=0; c=_hooks[method][i]; i++) {
if(c === callback) {
isAlreadyAdded = true;
}
}
isAlreadyAdded === false ? _hooks[method].push(callback) : null;
}
_api.callHooks = function(method, args) {
if(_hooks[method]) {
for(var i=0; c=_hooks[method][i]; i++) {
if(c.apply(_api, args) === true) return true;
}
}
return false;
}
// internal variables
_api.numOfAddedRules = 0;
// absurd.components API
_api.components = (function(api) {
var extend = lib.helpers.Extend,
clone = lib.helpers.Clone,
comps = {},
instances = [],
events = extend({}, Component()),
exports = {};
(function(fn) {
if (document.addEventListener) {
document.addEventListener('DOMContentLoaded', fn);
} else {
document.attachEvent('onreadystatechange', function() {
if (document.readyState === 'interactive') {
fn();
}
});
}
})(function() {
exports.broadcast("ready");
})
return exports = {
events: events,
register: function(name, cls) {
return comps[name] = function() {
var c = extend({}, Component(name, api, events, clone(cls)));
api.di.resolveObject(c);
instances.push(c);
if(typeof c.constructor === 'function') {
c.constructor.apply(c, Array.prototype.slice.call(arguments, 0));
}
return c;
};
},
get: function(name) {
if(comps[name]) { return comps[name]; }
else { throw new Error("There is no component with name '" + name + "'."); }
},
remove: function(name) {
if(comps[name]) { delete comps[name]; return true; }
return false;
},
list: function() {
var l = [];
for(var name in comps) l.push(name);
return l;
},
flush: function() {
comps = {};
instances = [];
return this;
},
broadcast: function(event, data) {
for(var i=0; i>> ' + selector, "\n", props);
stylesheet = stylesheet || "mainstream";
// multiple selectors
if(/, ?/g.test(selector) && options.combineSelectors) {
var parts = selector.replace(/, /g, ',').split(',');
for(var i=0; i= 0) {
addRule(p.replace(/&/g, selector), _objects[prop], stylesheet, parentSelector);
} else {
addRule(p, _objects[prop], stylesheet, typeof parentSelector !== "undefined" ? parentSelector + " " + selector : selector);
}
}
} else {
addRule(prop.replace(/&/g, selector), _objects[prop], stylesheet, parentSelector);
}
// check for media query
} else if(prop.indexOf("@media") === 0 || prop.indexOf("@supports") === 0) {
addRule(selector, _objects[prop], prop, parentSelector);
// check for media query
} else if(selector.indexOf("@media") === 0 || prop.indexOf("@supports") === 0) {
addRule(prop, _objects[prop], selector, parentSelector);
// moving the selector to the top of the chain
} else if(selector.indexOf("^") === 0) {
// selector, props, stylesheet, parentSelector
addRule(
selector.substr(1, selector.length-1) + (typeof parentSelector !== "undefined" ? " " + parentSelector : '') + " " + prop,
_objects[prop],
stylesheet
);
// check for plugins
} else if(checkAndExecutePlugin(selector, prop, _objects[prop], stylesheet, parentSelector) === false) {
addRule(prop, _objects[prop], stylesheet, (parentSelector ? parentSelector + " " : "") + selector);
}
}
for(var prop in _functions) {
var o = {};
o[prop] = _functions[prop]();
addRule(selector, o, stylesheet, parentSelector);
}
}
var add = function(rules, stylesheet, opts) {
toRegister = [];
API.numOfAddedRules += 1;
if(typeof stylesheet === 'object' && typeof opts === 'undefined') {
options = stylesheet;
stylesheet = null;
}
if(typeof opts != 'undefined') {
options = opts;
}
var typeOfPreprocessor = API.defaultProcessor.type;
for(var selector in rules) {
addRule(selector, rules[selector], stylesheet || "mainstream");
}
// looping through the rules for registering
for(var i=0; i") {
if(current && current[propNew]) {
current[propNew] = current[propNew] + " " + value.substr(1, value.length-1);
} else {
current[propNew] = value.substr(1, value.length-1);
}
} else {
current[propNew] = value;
}
} else {
current[propNew] = value;
}
}
}
allRules[selector] = current;
}
return API;
}
return add;
}
var extend = require("../helpers/Extend");
lib.api.compile = function(api) {
return function() {
var path = null, callback = null, options = null;
for(var i=0; i= 0)
obj['-webkit-' + p.prop] = value;
if(p.prefix === '' || p.prefix.indexOf('m') >= 0)
obj['-moz-' + p.prop] = value;
if(p.prefix === '' || p.prefix.indexOf('s') >= 0)
obj['-ms-' + p.prop] = value;
if(p.prefix === '' || p.prefix.indexOf('o') >= 0)
obj['-o-' + p.prop] = value;
}
},
nonPrefixProp: function(prop) {
var p = prefixExtract(prop);
if(p.prefix !== false) {
if(p.prefix == '') {
p.prefix = '-';
} else {
p.prefix = '-' + p.prefix + '-';
}
}
return p;
}
}
lib.helpers.RequireUncached = function(module) {
delete require.cache[require.resolve(module)]
return require(module);
}
lib.helpers.TransformUppercase = function(prop, options) {
var transformed = "";
for(var i=0; c=prop.charAt(i); i++) {
if(c === c.toUpperCase() && c.toLowerCase() !== c.toUpperCase()) {
transformed += "-" + c.toLowerCase();
} else {
transformed += c;
}
}
return transformed;
}
var compileComponent = function(input, callback, options) {
var css = "",
html = "",
all = [],
api = options.api;
cssPreprocessor = require(__dirname + "/../css/CSS.js")(),
htmlPreprocessor = require(__dirname + "/../html/HTML.js")();
var processCSS = function(clb) {
for(var i=0; i input.length-1) {
clb(error);
return;
}
var c = input[index];
if(typeof c === "function") { c = c(); }
api.morph("html").add(c.html ? c.html : {});
htmlPreprocessor(api.getRules(), function(err, result) {
html += result;
index += 1;
error = err;
processComponent();
}, options);
}
processComponent();
}
var checkForNesting = function(o) {
for(var key in o) {
if(key === "_include") {
if(o[key] instanceof Array) {
for(var i=0; i', 'g');
if(typeof storage[prop] != 'function') {
css = css.replace(re, storage[prop]);
} else {
css = css.replace(re, storage[prop]());
}
}
}
return css;
}
lib.processors.css.CSS = function() {
var processor = function(rules, callback, options) {
options = options || defaultOptions;
var css = '';
for(var stylesheet in rules) {
var r = rules[stylesheet];
r = options.combineSelectors ? combineSelectors(r) : r;
if(stylesheet === "mainstream") {
css += toCSS(r, options);
} else {
css += stylesheet + " {" + newline + toCSS(r, options) + "}" + newline;
}
}
css = replaceDefined(css, options);
// Minification
if(options.minify) {
css = minimize(css);
if(callback) callback(null, css);
} else {
if(callback) callback(null, css);
}
return css;
}
processor.type = "css";
return processor;
}
lib.processors.css.plugins.charset = function() {
return function(api, charsetValue) {
if(typeof charsetValue === "string") {
api.raw("@charset: \"" + charsetValue + "\";");
} else if(typeof charsetValue === "object") {
charsetValue = charsetValue.charset.replace(/:/g, '').replace(/'/g, '').replace(/"/g, '').replace(/ /g, '');
api.raw("@charset: \"" + charsetValue + "\";");
}
}
}
lib.processors.css.plugins.document = function() {
return function(api, value) {
if(typeof value === "object") {
var stylesheet = '';
stylesheet += '@' + value.vendor + 'document';
stylesheet += ' ' + value.document;
if(value.rules && value.rules.length) {
for(var i=0; rule=value.rules[i]; i++) {
api.handlecssrule(rule, stylesheet);
}
} else if(typeof value.styles != "undefined") {
api.add(value.styles, stylesheet);
}
}
}
}
lib.processors.css.plugins.keyframes = function() {
return function(api, value) {
var processor = require(__dirname + "/../CSS.js")();
var prefixes = require(__dirname + "/../../../helpers/Prefixes");
if(typeof value === "object") {
// js or json
if(typeof value.frames != "undefined") {
for(var frame in value.frames) {
for(var prop in value.frames[frame]) {
prefixes.addPrefixes(prop, value.frames[frame]);
}
}
var content = '@keyframes ' + value.name + " {\n";
content += processor({mainstream: value.frames});
content += "}";
api.raw(content + "\n" + content.replace("@keyframes", "@-webkit-keyframes"));
// css
} else if(typeof value.keyframes != "undefined") {
var content = '@keyframes ' + value.name + " {\n";
var frames = {};
for(var i=0; rule=value.keyframes[i]; i++) {
if(rule.type === "keyframe") {
var f = frames[rule.values] = {};
for(var j=0; declaration=rule.declarations[j]; j++) {
if(declaration.type === "declaration") {
f[declaration.property] = declaration.value;
}
}
}
}
content += processor({mainstream: frames});
content += "}";
api.raw(content + "\n" + content.replace("@keyframes", "@-webkit-keyframes"));
}
}
}
}
lib.processors.css.plugins.media = function() {
return function(api, value) {
var processor = require(__dirname + "/../CSS.js")();
if(typeof value === "object") {
var content = '@media ' + value.media + " {\n";
var rules = {};
for(var i=0; rule=value.rules[i]; i++) {
var r = rules[rule.selectors.toString()] = {};
if(rule.type === "rule") {
for(var j=0; declaration=rule.declarations[j]; j++) {
if(declaration.type === "declaration") {
r[declaration.property] = declaration.value;
}
}
}
}
content += processor({mainstream: rules});
content += "}";
api.raw(content);
}
}
}
lib.processors.css.plugins.namespace = function() {
return function(api, value) {
if(typeof value === "string") {
api.raw("@namespace: \"" + value + "\";");
} else if(typeof value === "object") {
value = value.namespace.replace(/: /g, '').replace(/'/g, '').replace(/"/g, '').replace(/ /g, '').replace(/:h/g, 'h');
api.raw("@namespace: \"" + value + "\";");
}
}
}
lib.processors.css.plugins.page = function() {
return function(api, value) {
if(typeof value === "object") {
var content = "";
if(value.selectors.length > 0) {
content += "@page " + value.selectors.join(", ") + " {\n";
} else {
content += "@page {\n";
}
for(var i=0; declaration=value.declarations[i]; i++) {
if(declaration.type == "declaration") {
content += " " + declaration.property + ": " + declaration.value + ";\n";
}
}
content += "}";
api.raw(content);
}
}
}
lib.processors.css.plugins.supports = function() {
return function(api, value) {
var processor = require(__dirname + "/../CSS.js")();
if(typeof value === "object") {
var content = '@supports ' + value.supports + " {\n";
var rules = {};
for(var i=0; rule=value.rules[i]; i++) {
var r = rules[rule.selectors.toString()] = {};
if(rule.type === "rule") {
for(var j=0; declaration=rule.declarations[j]; j++) {
if(declaration.type === "declaration") {
r[declaration.property] = declaration.value;
}
}
}
}
content += processor({mainstream: rules});
content += "}";
api.raw(content);
}
}
}
var data = null,
newline = '\n',
defaultOptions = {},
tags = [],
beautifyHTML = require('js-beautify').html,
tu = require("../../helpers/TransformUppercase"),
passedOptions = {};
var processTemplate = function(templateName) {
var html = '';
for(var template in data) {
if(template == templateName) {
var numOfRules = data[template].length;
for(var i=0; i", obj);
var html = '', attrs = '', childs = '';
var tagAnalized = require("./helpers/PropAnalyzer")(tagName);
tagName = tagAnalized.tag;
if(tagAnalized.attrs != "") {
attrs += " " + tagAnalized.attrs;
}
if(typeof obj === "string") {
return packTag(tagName, attrs, obj);
}
var addToChilds = function(value) {
if(childs != '') { childs += newline; }
childs += value;
}
// process directives
for(var directiveName in obj) {
var value = obj[directiveName];
switch(directiveName) {
case "_attrs":
for(var attrName in value) {
if(typeof value[attrName] === "function") {
attrs += " " + prepareProperty(attrName, passedOptions) + "=\"" + value[attrName]() + "\"";
} else {
attrs += " " + prepareProperty(attrName, passedOptions) + "=\"" + value[attrName] + "\"";
}
}
break;
case "_":
addToChilds(value);
break;
case "_tpl":
if(typeof value == "string") {
addToChilds(processTemplate(value));
} else if(value instanceof Array) {
var tmp = '';
for(var i=0; tpl=value[i]; i++) {
tmp += processTemplate(tpl)
if(i < value.length-1) tmp += newline;
}
addToChilds(tmp);
}
break;
case "_include":
var tmp = '';
var add = function(o) {
if(typeof o === "function") { o = o(); }
if(o.css && o.html) { o = o.html; } // catching a component
tmp += process('', o);
}
if(value instanceof Array) {
for(var i=0; i 0) {
var tmp = '';
for(var i=0; v=value[i]; i++) {
tmp += process('', typeof v == "function" ? v() : v);
if(i < value.length-1) tmp += newline;
}
addToChilds(process(directiveName, tmp));
} else {
addToChilds(process(directiveName, value));
}
break;
case "function": addToChilds(process(directiveName, value())); break;
}
break;
}
}
if(tagName != '') {
html += packTag(tagName, attrs, childs);
} else {
html += childs;
}
return html;
}
var packTag = function(tagName, attrs, childs) {
var html = '';
if(tagName == '' && attrs == '' && childs != '') {
return childs;
}
tagName = tagName == '' ? 'div' : tagName;
if(childs !== '') {
html += '<' + prepareProperty(tagName, passedOptions) + attrs + '>' + newline + childs + newline + '' + prepareProperty(tagName, passedOptions) + '>';
} else {
html += '<' + prepareProperty(tagName, passedOptions) + attrs + '/>';
}
return html;
}
var prepareHTML = function(html) {
html = require("./helpers/TemplateEngine")(html.replace(/[\r\t\n]/g, ''), passedOptions);
if(passedOptions.minify) {
return html;
} else {
return beautifyHTML(html, {indent_size: passedOptions.indentSize || 4});
}
}
lib.processors.html.HTML = function() {
var processor = function(rules, callback, options) {
data = rules;
callback = callback || function() {};
options = passedOptions = options || defaultOptions;
var html = prepareHTML(processTemplate("mainstream"));
callback(null, html);
return html;
}
processor.type = "html";
return processor;
}
lib.processors.html.helpers.PropAnalyzer = function(prop) {
var res = {
tag: '',
attrs: ''
},
numOfChars = prop.length,
tagName = "",
className = "", readingClass = false, classes = [],
idName = "", readingId = false, ids = [],
attributes = "", readingAttributes = false;
if(/(#|\.|\[|\])/gi.test(prop) === false) {
return {
tag: prop,
attrs: ''
};
}
for(var i=0; i/g, reExp = /(^( )?(if|for|else|switch|case|break|{|}|;))(.*)?/g, code = 'var r=[];\n', cursor = 0, result;
var add = function(line, js) {
js? (code += line.match(reExp) ? line + '\n' : 'r.push(' + line + ');\n') :
(code += line != '' ? 'r.push("' + line.replace(/"/g, '\\"') + '");\n' : '');
return add;
}
while(match = re.exec(html)) {
add(html.slice(cursor, match.index))(match[1], true);
cursor = match.index + match[0].length;
}
add(html.substr(cursor, html.length - cursor));
code = (code + 'return r.join("");').replace(/[\r\t\n]/g, '');
try { result = new Function(code).apply(options); }
catch(err) { console.error("'" + err.message + "'", " in \n\nCode:\n", code, "\n"); }
return result;
};
return client();
})(window);