lettuce
Version:
Lettuce JS, Mini Mobile Framework for Romantic with DSL.
366 lines (292 loc) • 9.21 kB
JavaScript
(function(root, undefined) {
'use strict';
var Lettuce = function() {
};
Lettuce.VERSION = '0.0.8';
root.lettuce = Lettuce;
// (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
// Underscore may be freely distributed under the MIT license.
Lettuce.isObject = function (obj) {
var type = typeof obj;
return type === 'function' || type === 'object' && !!obj;
};
Lettuce.extend = function (obj) {
if (!Lettuce.isObject(obj)) {
return obj;
}
var source, prop;
for (var i = 1, length = arguments.length; i < length; i++) {
source = arguments[i];
for (prop in source) {
if (hasOwnProperty.call(source, prop)) {
obj[prop] = source[prop];
}
}
}
return obj;
};
/**
* Lettuce Class 0.0.1
* JavaScript Class built-in inheritance system
*(c) 2015, Fengda Huang - http://www.phodal.com
*
* Copyright (c) 2011, 2012 Jeanine Adkisson.
* MIT Licensed.
* Inspired by https://github.com/munro/self, https://github.com/jneen/pjs
*/
Lettuce.prototype.Class = (function (prototype, ownProperty) {
var lettuceClass = function Klass(_superclass, definition) {
function Class() {
var self = this instanceof Class ? this : new Basic();
self.init.apply(self, arguments);
return self;
}
function Basic() {
}
Class.Basic = Basic;
var _super = Basic[prototype] = _superclass[prototype];
var proto = Basic[prototype] = Class[prototype] = new Basic();
proto.constructor = Class;
Class.extend = function (def) {
return new Klass(Class, def);
};
var open = (Class.open = function (def) {
if (typeof def === 'function') {
def = def.call(Class, proto, _super, Class, _superclass);
}
if (typeof def === 'object') {
for (var key in def) {
if (ownProperty.call(def, key)) {
proto[key] = def[key];
}
}
}
if (!('init' in proto)) {
proto.init = _superclass;
}
return Class;
});
return (open)(definition);
};
return lettuceClass;
})('prototype', ({}).hasOwnProperty);
var Parser = new Lettuce.prototype.Class(function () {
});
Parser.prototype.init = function () {
};
var DSLRunner = {
run: function(methods) {
this.methods = methods;
this.execute('first');
for (var key in this.methods) {
if (key !== 'last' && key.match(/.*Page/)) {
this.execute(key);
}
}
this.execute('last');
},
execute: function(methodName) {
var output = this.methods[methodName]();
delete(this.methods[methodName]);
return output;
}
};
Parser.prototype = Lettuce.extend(Parser.prototype, DSLRunner);
var parser = {
Parser: Parser
};
Lettuce.prototype = Lettuce.extend(Lettuce.prototype, parser);
Lettuce.get = function (url, callback) {
Lettuce.send(url, 'GET', callback);
};
Lettuce.post = function (url, data, callback) {
Lettuce.send(url, 'POST', callback, data);
};
Lettuce.send = function (url, method, callback, data) {
data = data || null;
var request = new XMLHttpRequest();
if (callback instanceof Function) {
request.onreadystatechange = function () {
if (request.readyState === 4 && (request.status === 200 || request.status === 0)) {
callback(request.responseText);
}
};
}
request.open(method, url, true);
if (data instanceof Object) {
data = JSON.stringify(data);
request.setRequestHeader('Content-Type', 'application/json');
}
request.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
request.send(data);
};
var Event = {
on: function(event, callback){
this._events = this._events || {};
this._events[event] = this._events[event] || [];
this._events[event].push(callback);
},
off: function(event, callback){
this._events = this._events || {};
if (event in this._events === false) {
return;
}
this._events[event].splice(this._events[event].indexOf(callback), 1);
},
trigger: function(event){
this._events = this._events || {};
if (event in this._events === false) {
return;
}
for (var i = 0; i < this._events[event].length; i++) {
this._events[event][i].apply(this, Array.prototype.slice.call(arguments, 1));
}
}
};
var event = {
Event: Event
};
Lettuce.prototype = Lettuce.extend(Lettuce.prototype, event);
/*
* JavaScript Templates 2.4.1
* https://github.com/blueimp/JavaScript-Templates
*
* Copyright 2011, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT
*
* Inspired by John Resig's JavaScript Micro-Templating:
* http://ejohn.org/blog/javascript-micro-templating/
*/
/*jslint evil: true, regexp: true, unparam: true */
/*global document */
var tmpl = function (str, data) {
var f = !/[^\w\-\.:]/.test(str) ? tmpl.cache[str] = tmpl.cache[str] ||
tmpl(tmpl.load(str)) :
new Function(
tmpl.arg + ',tmpl',
"var _e=tmpl.encode" + tmpl.helper + ",_s='" +
str.replace(tmpl.regexp, tmpl.func) +
"';return _s;"
);
return data ? f(data, tmpl) : function (data) {
return f(data, tmpl);
};
};
tmpl.cache = {};
tmpl.load = function (id) {
return document.getElementById(id).innerHTML;
};
tmpl.regexp = /([\s'\\])(?!(?:[^{]|\{(?!%))*%\})|(?:\{%(=|#)([\s\S]+?)%\})|(\{%)|(%\})/g;
tmpl.func = function (s, p1, p2, p3, p4, p5) {
if (p1) { // whitespace, quote and backspace in HTML context
return {
"\n": "\\n",
"\r": "\\r",
"\t": "\\t",
" " : " "
}[p1] || "\\" + p1;
}
if (p2) { // interpolation: {%=prop%}, or unescaped: {%#prop%}
if (p2 === "=") {
return "'+_e(" + p3 + ")+'";
}
return "'+(" + p3 + "==null?'':" + p3 + ")+'";
}
if (p4) { // evaluation start tag: {%
return "';";
}
if (p5) { // evaluation end tag: %}
return "_s+='";
}
};
tmpl.escapeRegexp = /[<>&"'\x00]/g;
tmpl.escapeMap = {
"<" : "<",
">" : ">",
"&" : "&",
"\"" : """,
"'" : "'"
};
tmpl.encode = function (s) {
/*jshint eqnull:true */
return (s == null ? "" : "" + s).replace(
tmpl.escapeRegexp,
function (c) {
return tmpl.escapeMap[c] || "";
}
);
};
tmpl.arg = "o";
tmpl.helper = ",print=function(s,e){_s+=e?(s==null?'':s):_e(s);}" +
",include=function(s,d){_s+=tmpl(s,d);}";
Lettuce.prototype.tmpl = Lettuce.tmpl = tmpl;
var SimpleView = new Lettuce.prototype.Class(function () {
});
SimpleView.prototype.init = function () {
};
SimpleView.prototype.render = function (tmpl, id) {
//var result = Lettuce.tmpl("<h3>{%=o."+ type +"%}" + "</h3>", data);
document.getElementById(id).innerHTML = tmpl;
};
var simpleView = {
SimpleView: SimpleView
};
Lettuce.prototype = Lettuce.extend(Lettuce.prototype, simpleView);
//Inspired by http://krasimirtsonev.com/blog/article/A-modern-JavaScript-router-in-100-lines-history-api-pushState-hash-url & Backbone
var Router = {
routes: [],
mode: null,
root: '/',
hashStrip: /^#*/,
getFragment: function(loc) {
return (loc || window.location).hash.replace(this.hashStrip, '');
},
add: function(re, handler) {
if(typeof re === 'function') {
handler = re;
re = '';
}
this.routes.push({ re: re, handler: handler});
return this;
},
check: function (current, self) {
var fragment = current || self.getFragment();
for (var i = 0; i < self.routes.length; i++) {
var newFragment = "#" + fragment;
var match = newFragment.match(self.routes[i].re);
if (match) {
match.shift();
self.routes[i].handler.apply({}, match);
}
}
},
load: function() {
var self = this;
var current = self.getFragment();
var fn = function() {
if(current !== self.getFragment()) {
current = self.getFragment();
//self.check(current);
} else {
self.check(current, self);
}
};
clearInterval(this.interval);
this.interval = setInterval(fn, 50);
return this;
},
navigate: function(path) {
path = path ? path : '';
window.location.href.match(/#(.*)$/);
window.location.href = window.location.href.replace(/#(.*)$/, '') + '#' + path;
return this;
}
};
var router = {
Router: Router
};
Lettuce.prototype = Lettuce.extend(Lettuce.prototype, router);
}(this));