Commit f79d2a8a authored by Kostantinos  Margaritis's avatar Kostantinos Margaritis Committed by Sindre Sorhus

Close #1143 PR: Atmajs: New ui & upgrade to NPM. Fixes #1110

parent bfbefb12
node_modules/atma-class/*
!node_modules/atma-class/lib/class.js
node_modules/includejs/*
!node_modules/includejs/lib/include.js
node_modules/jquery/*
!node_modules/jquery/dist
node_modules/jquery/dist/*
!node_modules/jquery/dist/jquery.js
node_modules/maskjs/*
!node_modules/maskjs/lib/mask.js
node_modules/ruta/*
!node_modules/ruta/lib/ruta.js
node_modules/todomvc-app-css/*
!node_modules/todomvc-app-css/index.css
node_modules/todomvc-common/*
!node_modules/todomvc-common/base.css
!node_modules/todomvc-common/base.js
{
"name": "todomvc-atmajs",
"version": "0.1.0",
"dependencies": {
"todomvc-common": "~0.3.0",
"jquery": "~2.0.2",
"maskjs": "~0.10.1",
"includejs": "~0.9.10",
"ruta": "~0.1.11",
"atma-class": "~1.0.68"
}
}
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Atma.js • TodoMVC</title> <title>Atma.js • TodoMVC</title>
<link rel="stylesheet" href="bower_components/todomvc-common/base.css"> <link rel="stylesheet" href="node_modules/todomvc-common/base.css">
<link rel="stylesheet" href="node_modules/todomvc-app-css/index.css">
</head> </head>
<body> <body>
<!-- <!--
...@@ -39,13 +40,13 @@ ...@@ -39,13 +40,13 @@
_If the controller loads a template, do not forget to review that._ _If the controller loads a template, do not forget to review that._
--> -->
<script src="bower_components/todomvc-common/base.js"></script> <script src="node_modules/todomvc-common/base.js"></script>
<script src="bower_components/jquery/jquery.js"></script> <script src="node_modules/jquery/dist/jquery.js"></script>
<script src="bower_components/includejs/lib/include.js"></script> <script src="node_modules/includejs/lib/include.js"></script>
<script src="bower_components/atma-class/lib/class.js"></script> <script src="node_modules/atma-class/lib/class.js"></script>
<script src="bower_components/maskjs/lib/mask.js"></script> <script src="node_modules/maskjs/lib/mask.js"></script>
<script src="bower_components/ruta/lib/ruta.js"></script> <script src="node_modules/ruta/lib/ruta.js"></script>
<script src="js/app.js"></script> <script src="js/app.js"></script>
......
...@@ -21,42 +21,42 @@ ...@@ -21,42 +21,42 @@
_exports _exports
; ;
_exports = root || _global; _exports = root || _global;
function construct(){ function construct(){
return factory(_global, _exports); return factory(_global, _exports);
}; };
if (typeof define === 'function' && define.amd) { if (typeof define === 'function' && define.amd) {
return define(construct); return define(construct);
} }
// Browser OR Node // Browser OR Node
construct(); construct();
if (typeof module !== 'undefined') if (typeof module !== 'undefined')
module.exports = _exports.Class; module.exports = _exports.Class;
}(this, function(global, exports){ }(this, function(global, exports){
"use strict"; "use strict";
// end:source /src/umd.js // end:source /src/umd.js
// source /src/vars.js // source /src/vars.js
var _Array_slice = Array.prototype.slice, var _Array_slice = Array.prototype.slice,
_Array_sort = Array.prototype.sort, _Array_sort = Array.prototype.sort,
_cfg = { _cfg = {
ModelHost: null, // @default: Class.Model ModelHost: null, // @default: Class.Model
}; };
var str_CLASS_IDENTITY = '__$class__'; var str_CLASS_IDENTITY = '__$class__';
// end:source /src/vars.js // end:source /src/vars.js
// source /src/util/is.js // source /src/util/is.js
var is_Function, var is_Function,
is_Object, is_Object,
...@@ -68,7 +68,7 @@ ...@@ -68,7 +68,7 @@
is_rawObject, is_rawObject,
is_NullOrGlobal; is_NullOrGlobal;
(function(){ (function(){
is_Function = function(x) { is_Function = function(x) {
return typeof x === 'function'; return typeof x === 'function';
}; };
...@@ -87,59 +87,59 @@ ...@@ -87,59 +87,59 @@
&& typeof x.slice === 'function'; && typeof x.slice === 'function';
}; };
is_ArrayLike = is_Array; is_ArrayLike = is_Array;
is_String = function(x) { is_String = function(x) {
return typeof x === 'string'; return typeof x === 'string';
}; };
is_notEmptyString = function(x) { is_notEmptyString = function(x) {
return typeof x === 'string' return typeof x === 'string'
&& x !== ''; && x !== '';
}; };
is_rawObject = function(obj) { is_rawObject = function(obj) {
if (obj == null) if (obj == null)
return false; return false;
if (typeof obj !== 'object') if (typeof obj !== 'object')
return false; return false;
return obj.constructor === Object; return obj.constructor === Object;
}; };
is_NullOrGlobal = function(ctx){ is_NullOrGlobal = function(ctx){
return ctx === void 0 || ctx === global; return ctx === void 0 || ctx === global;
}; };
}()); }());
// end:source /src/util/is.js // end:source /src/util/is.js
// source /src/util/array.js // source /src/util/array.js
var arr_each, var arr_each,
arr_isArray, arr_isArray,
arr_remove arr_remove
; ;
(function(){ (function(){
arr_each = function(array, callback) { arr_each = function(array, callback) {
if (arr_isArray(array)) { if (arr_isArray(array)) {
for (var i = 0, imax = array.length; i < imax; i++){ for (var i = 0, imax = array.length; i < imax; i++){
callback(array[i], i); callback(array[i], i);
} }
return; return;
} }
callback(array); callback(array);
}; };
arr_isArray = function(array) { arr_isArray = function(array) {
return array != null return array != null
&& typeof array === 'object' && typeof array === 'object'
&& typeof array.length === 'number' && typeof array.length === 'number'
&& typeof array.splice === 'function'; && typeof array.splice === 'function';
}; };
arr_remove = function(array, fn){ arr_remove = function(array, fn){
var imax = array.length, var imax = array.length,
i = -1; i = -1;
...@@ -151,150 +151,150 @@ ...@@ -151,150 +151,150 @@
} }
} }
}; };
/* polyfill */ /* polyfill */
if (typeof Array.isArray !== 'function') { if (typeof Array.isArray !== 'function') {
Array.isArray = function(array){ Array.isArray = function(array){
if (array instanceof Array){ if (array instanceof Array){
return true; return true;
} }
if (array == null || typeof array !== 'object') { if (array == null || typeof array !== 'object') {
return false; return false;
} }
return array.length !== void 0 && typeof array.slice === 'function'; return array.length !== void 0 && typeof array.slice === 'function';
}; };
} }
}()); }());
// end:source /src/util/array.js // end:source /src/util/array.js
// source /src/util/class.js // source /src/util/class.js
var class_register, var class_register,
class_get, class_get,
class_patch, class_patch,
class_stringify, class_stringify,
class_parse, class_parse,
class_properties class_properties
; ;
(function(){ (function(){
class_register = function(namespace, class_){ class_register = function(namespace, class_){
obj_setProperty( obj_setProperty(
_cfg.ModelHost || Class.Model, _cfg.ModelHost || Class.Model,
namespace, namespace,
class_ class_
); );
}; };
class_get = function(namespace){ class_get = function(namespace){
return obj_getProperty( return obj_getProperty(
_cfg.ModelHost || Class.Model, _cfg.ModelHost || Class.Model,
namespace namespace
); );
}; };
class_patch = function(mix, Proto){ class_patch = function(mix, Proto){
var class_ = is_String(mix) var class_ = is_String(mix)
? class_get(mix) ? class_get(mix)
: mix : mix
; ;
// if DEBUG // if DEBUG
!is_Function(class_) !is_Function(class_)
&& console.error('<class:patch> Not a Function', mix); && console.error('<class:patch> Not a Function', mix);
// endif // endif
Proto.Base = class_; Proto.Base = class_;
class_ = Class(Proto); class_ = Class(Proto);
if (is_String(mix)) if (is_String(mix))
class_register(mix, class_); class_register(mix, class_);
return class_; return class_;
}; };
class_stringify = function(class_){ class_stringify = function(class_){
return JSON.stringify(class_, stringify); return JSON.stringify(class_, stringify);
}; };
class_parse = function(str){ class_parse = function(str){
return JSON.parse(str, parse); return JSON.parse(str, parse);
}; };
class_properties = function(Ctor) { class_properties = function(Ctor) {
return getProperties(Ctor); return getProperties(Ctor);
}; };
// private // private
function stringify(key, val) { function stringify(key, val) {
if (val == null || typeof val !== 'object') if (val == null || typeof val !== 'object')
return val; return val;
var current = this, var current = this,
obj = current[key] obj = current[key]
; ;
if (obj[str_CLASS_IDENTITY] && obj.toJSON) { if (obj[str_CLASS_IDENTITY] && obj.toJSON) {
return stringifyMetaJSON(obj[str_CLASS_IDENTITY], val) return stringifyMetaJSON(obj[str_CLASS_IDENTITY], val)
////val[str_CLASS_IDENTITY] = obj[str_CLASS_IDENTITY]; ////val[str_CLASS_IDENTITY] = obj[str_CLASS_IDENTITY];
////return val; ////return val;
} }
return val; return val;
} }
function stringifyMetaJSON(className, json){ function stringifyMetaJSON(className, json){
var out = {}; var out = {};
out['json'] = json; out['json'] = json;
out[str_CLASS_IDENTITY] = className; out[str_CLASS_IDENTITY] = className;
return out; return out;
} }
function parse(key, val) { function parse(key, val) {
var Ctor; var Ctor;
if (val != null && typeof val === 'object' && val[str_CLASS_IDENTITY]) { if (val != null && typeof val === 'object' && val[str_CLASS_IDENTITY]) {
Ctor = Class(val[str_CLASS_IDENTITY]); Ctor = Class(val[str_CLASS_IDENTITY]);
if (typeof Ctor === 'function') { if (typeof Ctor === 'function') {
val = new Ctor(val.json); val = new Ctor(val.json);
} else { } else {
console.error('<class:parse> Class was not registered', val[str_CLASS_IDENTITY]); console.error('<class:parse> Class was not registered', val[str_CLASS_IDENTITY]);
} }
} }
return val; return val;
} }
function getProperties(proto, out){ function getProperties(proto, out){
if (typeof proto === 'function') if (typeof proto === 'function')
proto = proto.prototype; proto = proto.prototype;
if (out == null) if (out == null)
out = {}; out = {};
var type, var type,
key, key,
val; val;
...@@ -304,43 +304,43 @@ ...@@ -304,43 +304,43 @@
? null ? null
: typeof val : typeof val
; ;
if (type === 'function') if (type === 'function')
continue; continue;
var c = key.charCodeAt(0); var c = key.charCodeAt(0);
if (c === 95 && key !== '_id') if (c === 95 && key !== '_id')
// _ // _
continue; continue;
if (c >= 65 && c <= 90) if (c >= 65 && c <= 90)
// A-Z // A-Z
continue; continue;
if (type === 'object') { if (type === 'object') {
var ctor = val.constructor, var ctor = val.constructor,
ctor_name = ctor && ctor.name ctor_name = ctor && ctor.name
; ;
if (ctor_name !== 'Object' && ctor_name && global[ctor_name] === ctor) { if (ctor_name !== 'Object' && ctor_name && global[ctor_name] === ctor) {
// built-in objects // built-in objects
out[key] = ctor_name; out[key] = ctor_name;
continue; continue;
} }
out[key] = getProperties(val); out[key] = getProperties(val);
continue; continue;
} }
out[key] = type; out[key] = type;
} }
if (proto.__proto__) if (proto.__proto__)
getProperties(proto.__proto__, out); getProperties(proto.__proto__, out);
return out; return out;
} }
}()); }());
// end:source /src/util/class.js // end:source /src/util/class.js
// source /src/util/proto.js // source /src/util/proto.js
...@@ -348,26 +348,26 @@ ...@@ -348,26 +348,26 @@
class_inheritStatics, class_inheritStatics,
class_extendProtoObjects class_extendProtoObjects
; ;
(function(){ (function(){
var PROTO = '__proto__'; var PROTO = '__proto__';
var _toString = Object.prototype.toString, var _toString = Object.prototype.toString,
_isArguments = function(args){ _isArguments = function(args){
return _toString.call(args) === '[object Arguments]'; return _toString.call(args) === '[object Arguments]';
}; };
class_inherit = PROTO in Object.prototype class_inherit = PROTO in Object.prototype
? inherit ? inherit
: inherit_protoLess : inherit_protoLess
; ;
class_inheritStatics = function(_class, mix){ class_inheritStatics = function(_class, mix){
if (mix == null) if (mix == null)
return; return;
if (is_ArrayLike(mix)) { if (is_ArrayLike(mix)) {
var i = mix.length; var i = mix.length;
while ( --i > -1 ) { while ( --i > -1 ) {
...@@ -375,237 +375,237 @@ ...@@ -375,237 +375,237 @@
} }
return; return;
} }
var Static; var Static;
if (is_Function(mix)) if (is_Function(mix))
Static = mix; Static = mix;
else if (is_Object(mix.Static)) else if (is_Object(mix.Static))
Static = mix.Static; Static = mix.Static;
if (Static == null) if (Static == null)
return; return;
obj_extendDescriptorsDefaults(_class, Static); obj_extendDescriptorsDefaults(_class, Static);
}; };
class_extendProtoObjects = function(proto, _base, _extends){ class_extendProtoObjects = function(proto, _base, _extends){
var key, var key,
protoValue; protoValue;
for (key in proto) { for (key in proto) {
protoValue = proto[key]; protoValue = proto[key];
if (!is_rawObject(protoValue)) if (!is_rawObject(protoValue))
continue; continue;
if (_base != null){ if (_base != null){
if (is_rawObject(_base.prototype[key])) if (is_rawObject(_base.prototype[key]))
obj_defaults(protoValue, _base.prototype[key]); obj_defaults(protoValue, _base.prototype[key]);
} }
if (_extends != null) { if (_extends != null) {
arr_each(_extends, function(x){ arr_each(_extends, function(x){
x = proto_getProto(x); x = proto_getProto(x);
if (is_rawObject(x[key])) if (is_rawObject(x[key]))
obj_defaults(protoValue, x[key]); obj_defaults(protoValue, x[key]);
}); });
} }
} }
} }
// PRIVATE // PRIVATE
function proto_extend(proto, source) { function proto_extend(proto, source) {
if (source == null) if (source == null)
return; return;
if (typeof proto === 'function') if (typeof proto === 'function')
proto = proto.prototype; proto = proto.prototype;
if (typeof source === 'function') if (typeof source === 'function')
source = source.prototype; source = source.prototype;
var key, val; var key, val;
for (key in source) { for (key in source) {
val = source[key]; val = source[key];
if (val != null) if (val != null)
proto[key] = val; proto[key] = val;
} }
} }
function proto_override(super_, fn) { function proto_override(super_, fn) {
var proxy; var proxy;
if (super_) { if (super_) {
proxy = function(mix){ proxy = function(mix){
var args = arguments.length === 1 && _isArguments(mix) var args = arguments.length === 1 && _isArguments(mix)
? mix ? mix
: arguments : arguments
; ;
return fn_apply(super_, this, args); return fn_apply(super_, this, args);
} }
} else{ } else{
proxy = fn_doNothing; proxy = fn_doNothing;
} }
return function(){ return function(){
this['super'] = proxy; this['super'] = proxy;
return fn_apply(fn, this, arguments); return fn_apply(fn, this, arguments);
}; };
} }
function inherit(_class, _base, _extends, original, _overrides, defaults) { function inherit(_class, _base, _extends, original, _overrides, defaults) {
var prototype = original, var prototype = original,
proto = original; proto = original;
prototype.constructor = _class.prototype.constructor; prototype.constructor = _class.prototype.constructor;
if (_extends != null) { if (_extends != null) {
proto[PROTO] = {}; proto[PROTO] = {};
arr_each(_extends, function(x) { arr_each(_extends, function(x) {
proto_extend(proto[PROTO], x); proto_extend(proto[PROTO], x);
}); });
proto = proto[PROTO]; proto = proto[PROTO];
} }
if (_base != null) if (_base != null)
proto[PROTO] = _base.prototype; proto[PROTO] = _base.prototype;
for (var key in defaults) { for (var key in defaults) {
if (prototype[key] == null) if (prototype[key] == null)
prototype[key] = defaults[key]; prototype[key] = defaults[key];
} }
for (var key in _overrides) { for (var key in _overrides) {
prototype[key] = proto_override(prototype[key], _overrides[key]); prototype[key] = proto_override(prototype[key], _overrides[key]);
} }
_class.prototype = prototype; _class.prototype = prototype;
} }
// browser that doesnt support __proto__ // browser that doesnt support __proto__
function inherit_protoLess(_class, _base, _extends, original, _overrides, defaults) { function inherit_protoLess(_class, _base, _extends, original, _overrides, defaults) {
if (_base != null) { if (_base != null) {
var tmp = function() {}; var tmp = function() {};
tmp.prototype = _base.prototype; tmp.prototype = _base.prototype;
_class.prototype = new tmp(); _class.prototype = new tmp();
_class.prototype.constructor = _class; _class.prototype.constructor = _class;
} }
if (_extends != null) { if (_extends != null) {
arr_each(_extends, function(x) { arr_each(_extends, function(x) {
delete x.constructor; delete x.constructor;
proto_extend(_class, x); proto_extend(_class, x);
}); });
} }
var prototype = _class.prototype; var prototype = _class.prototype;
obj_defaults(prototype, defaults); obj_defaults(prototype, defaults);
for (var key in _overrides) { for (var key in _overrides) {
prototype[key] = proto_override(prototype[key], _overrides[key]); prototype[key] = proto_override(prototype[key], _overrides[key]);
} }
proto_extend(_class, original); proto_extend(_class, original);
} }
function proto_getProto(mix) { function proto_getProto(mix) {
return is_Function(mix) return is_Function(mix)
? mix.prototype ? mix.prototype
: mix : mix
; ;
} }
}()); }());
// end:source /src/util/proto.js // end:source /src/util/proto.js
// source /src/util/json.js // source /src/util/json.js
// Create from Complex Class Instance a lightweight json object // Create from Complex Class Instance a lightweight json object
var json_key_SER = '__$serialization', var json_key_SER = '__$serialization',
json_proto_toJSON, json_proto_toJSON,
json_proto_arrayToJSON json_proto_arrayToJSON
; ;
(function(){ (function(){
json_proto_toJSON = function(serialization){ json_proto_toJSON = function(serialization){
var object = this, var object = this,
json = {}, json = {},
key, val, s; key, val, s;
if (serialization == null) if (serialization == null)
serialization = object[json_key_SER]; serialization = object[json_key_SER];
var asKey; var asKey;
for(key in object){ for(key in object){
asKey = key; asKey = key;
if (serialization != null && serialization.hasOwnProperty(key)) { if (serialization != null && serialization.hasOwnProperty(key)) {
s = serialization[key]; s = serialization[key];
if (s != null && typeof s === 'object') { if (s != null && typeof s === 'object') {
if (s.key) if (s.key)
asKey = s.key; asKey = s.key;
if (s.hasOwnProperty('serialize')) { if (s.hasOwnProperty('serialize')) {
if (s.serialize == null) if (s.serialize == null)
continue; continue;
json[asKey] = s.serialize(object[key]); json[asKey] = s.serialize(object[key]);
continue; continue;
} }
} }
} }
// _ (private) // _ (private)
if (key.charCodeAt(0) === 95) if (key.charCodeAt(0) === 95)
continue; continue;
if ('Static' === key || 'Validate' === key) if ('Static' === key || 'Validate' === key)
continue; continue;
val = object[key]; val = object[key];
if (val == null) if (val == null)
continue; continue;
if ('_id' === key) { if ('_id' === key) {
json[asKey] = val; json[asKey] = val;
continue; continue;
} }
switch (typeof val) { switch (typeof val) {
case 'function': case 'function':
continue; continue;
case 'object': case 'object':
if (is_Date(val)) if (is_Date(val))
break; break;
var toJSON = val.toJSON; var toJSON = val.toJSON;
if (toJSON == null) if (toJSON == null)
break; break;
json[asKey] = val.toJSON(); json[asKey] = val.toJSON();
continue; continue;
//@removed - serialize any if toJSON is implemented //@removed - serialize any if toJSON is implemented
...@@ -613,58 +613,58 @@ ...@@ -613,58 +613,58 @@
// json[asKey] = val.toJSON(); // json[asKey] = val.toJSON();
// continue; // continue;
//} //}
break; break;
} }
json[asKey] = val; json[asKey] = val;
} }
// make mongodb's _id property not private // make mongodb's _id property not private
if (object._id != null) if (object._id != null)
json._id = object._id; json._id = object._id;
return json; return json;
}; };
json_proto_arrayToJSON = function() { json_proto_arrayToJSON = function() {
var array = this, var array = this,
imax = array.length, imax = array.length,
i = 0, i = 0,
output = new Array(imax), output = new Array(imax),
x; x;
for (; i < imax; i++) { for (; i < imax; i++) {
x = array[i]; x = array[i];
if (x != null && typeof x === 'object') { if (x != null && typeof x === 'object') {
var toJSON = x.toJSON; var toJSON = x.toJSON;
if (toJSON === json_proto_toJSON || toJSON === json_proto_arrayToJSON) { if (toJSON === json_proto_toJSON || toJSON === json_proto_arrayToJSON) {
output[i] = x.toJSON(); output[i] = x.toJSON();
continue; continue;
} }
if (toJSON == null) { if (toJSON == null) {
output[i] = json_proto_toJSON.call(x); output[i] = json_proto_toJSON.call(x);
continue; continue;
} }
} }
output[i] = x; output[i] = x;
} }
return output; return output;
}; };
}()); }());
// end:source /src/util/json.js // end:source /src/util/json.js
// source /src/util/object.js // source /src/util/object.js
var obj_inherit, var obj_inherit,
obj_getProperty, obj_getProperty,
obj_setProperty, obj_setProperty,
...@@ -674,103 +674,103 @@ ...@@ -674,103 +674,103 @@
obj_extendDescriptorsDefaults, obj_extendDescriptorsDefaults,
obj_validate obj_validate
; ;
(function(){ (function(){
obj_inherit = function(target /* source, ..*/ ) { obj_inherit = function(target /* source, ..*/ ) {
if (is_Function(target)) if (is_Function(target))
target = target.prototype; target = target.prototype;
var i = 1, var i = 1,
imax = arguments.length, imax = arguments.length,
source, key; source, key;
for (; i < imax; i++) { for (; i < imax; i++) {
source = is_Function(arguments[i]) source = is_Function(arguments[i])
? arguments[i].prototype ? arguments[i].prototype
: arguments[i] : arguments[i]
; ;
for (key in source) { for (key in source) {
if ('Static' === key) { if ('Static' === key) {
if (target.Static != null) { if (target.Static != null) {
for (key in source.Static) { for (key in source.Static) {
target.Static[key] = source.Static[key]; target.Static[key] = source.Static[key];
} }
continue; continue;
} }
} }
target[key] = source[key]; target[key] = source[key];
} }
} }
return target; return target;
}; };
obj_getProperty = function(obj, property) { obj_getProperty = function(obj, property) {
var chain = property.split('.'), var chain = property.split('.'),
imax = chain.length, imax = chain.length,
i = -1; i = -1;
while ( ++i < imax ) { while ( ++i < imax ) {
if (obj == null) if (obj == null)
return null; return null;
obj = obj[chain[i]]; obj = obj[chain[i]];
} }
return obj; return obj;
}; };
obj_setProperty = function(obj, property, value) { obj_setProperty = function(obj, property, value) {
var chain = property.split('.'), var chain = property.split('.'),
imax = chain.length, imax = chain.length,
i = -1, i = -1,
key; key;
while ( ++i < imax - 1) { while ( ++i < imax - 1) {
key = chain[i]; key = chain[i];
if (obj[key] == null) if (obj[key] == null)
obj[key] = {}; obj[key] = {};
obj = obj[key]; obj = obj[key];
} }
obj[chain[i]] = value; obj[chain[i]] = value;
}; };
obj_defaults = function(target, defaults) { obj_defaults = function(target, defaults) {
for (var key in defaults) { for (var key in defaults) {
if (target[key] == null) if (target[key] == null)
target[key] = defaults[key]; target[key] = defaults[key];
} }
return target; return target;
}; };
obj_extend = function(target, source) { obj_extend = function(target, source) {
if (target == null) if (target == null)
target = {}; target = {};
if (source == null) if (source == null)
return target; return target;
var val, var val,
key; key;
for(key in source) { for(key in source) {
val = source[key]; val = source[key];
if (val != null) if (val != null)
target[key] = val; target[key] = val;
} }
return target; return target;
}; };
(function(){ (function(){
var getDescr = Object.getOwnPropertyDescriptor, var getDescr = Object.getOwnPropertyDescriptor,
define = Object.defineProperty; define = Object.defineProperty;
if (getDescr == null) { if (getDescr == null) {
obj_extendDescriptors = obj_extend; obj_extendDescriptors = obj_extend;
obj_extendDescriptorsDefaults = obj_defaults; obj_extendDescriptorsDefaults = obj_defaults;
...@@ -783,17 +783,17 @@ ...@@ -783,17 +783,17 @@
return _extendDescriptors(target, source, true); return _extendDescriptors(target, source, true);
}; };
function _extendDescriptors (target, source, defaultsOnly) { function _extendDescriptors (target, source, defaultsOnly) {
if (target == null) if (target == null)
return {}; return {};
if (source == null) if (source == null)
return source; return source;
var descr, var descr,
key; key;
for(key in source){ for(key in source){
if (defaultsOnly === true && target[key] != null) if (defaultsOnly === true && target[key] != null)
continue; continue;
descr = getDescr(source, key); descr = getDescr(source, key);
if (descr == null) { if (descr == null) {
obj_extendDescriptors(target, source['__proto__']); obj_extendDescriptors(target, source['__proto__']);
...@@ -808,24 +808,24 @@ ...@@ -808,24 +808,24 @@
return target; return target;
}; };
}()); }());
(function(){ (function(){
obj_validate = function(a /*, b , ?isStrict, ?property, ... */) { obj_validate = function(a /*, b , ?isStrict, ?property, ... */) {
if (a == null) if (a == null)
return Err_Invalid('object'); return Err_Invalid('object');
_props = null; _props = null;
_strict = false; _strict = false;
var i = arguments.length, var i = arguments.length,
validator, x; validator, x;
while (--i > 0) { while (--i > 0) {
x = arguments[i]; x = arguments[i];
switch(typeof x){ switch(typeof x){
case 'string': case 'string':
if (_props == null) if (_props == null)
_props = {}; _props = {};
_props[x] = 1; _props[x] = 1;
continue; continue;
...@@ -842,106 +842,106 @@ ...@@ -842,106 +842,106 @@
continue; continue;
} }
} }
if (validator == null) if (validator == null)
validator = a.Validate; validator = a.Validate;
if (validator == null) if (validator == null)
// if no validation object - accept any. // if no validation object - accept any.
return null; return null;
return checkObject(a, validator, a); return checkObject(a, validator, a);
}; };
// private // private
// unexpect in `a` if not in `b` // unexpect in `a` if not in `b`
var _strict = false, var _strict = false,
// validate only specified properties // validate only specified properties
_props = null; _props = null;
// a** - payload // a** - payload
// b** - expect // b** - expect
// strict - // strict -
function checkObject(a, b, ctx) { function checkObject(a, b, ctx) {
var error, var error,
optional, optional,
key, aVal, aKey; key, aVal, aKey;
for(key in b){ for(key in b){
if (_props != null && a === ctx && _props.hasOwnProperty(key) === false) { if (_props != null && a === ctx && _props.hasOwnProperty(key) === false) {
continue; continue;
} }
switch(key.charCodeAt(0)) { switch(key.charCodeAt(0)) {
case 63: case 63:
// ? (optional) // ? (optional)
aKey = key.substring(1); aKey = key.substring(1);
aVal = a[aKey]; aVal = a[aKey];
//! accept falsy value //! accept falsy value
if (!aVal) if (!aVal)
continue; continue;
error = checkProperty(aVal, b[key], ctx); error = checkProperty(aVal, b[key], ctx);
if (error != null) { if (error != null) {
error.setInvalidProperty(aKey); error.setInvalidProperty(aKey);
return error; return error;
} }
continue; continue;
case 45: case 45:
// - (unexpect) // - (unexpect)
aKey = key.substring(1); aKey = key.substring(1);
if (typeof a === 'object' && aKey in a) if (typeof a === 'object' && aKey in a)
return Err_Unexpect(aKey); return Err_Unexpect(aKey);
continue; continue;
} }
aVal = a[key]; aVal = a[key];
if (aVal == null) if (aVal == null)
return Err_Expect(key); return Err_Expect(key);
error = checkProperty(aVal, b[key], ctx); error = checkProperty(aVal, b[key], ctx);
if (error != null) { if (error != null) {
error.setInvalidProperty(key); error.setInvalidProperty(key);
return error; return error;
} }
} }
if (_strict) { if (_strict) {
for(key in a){ for(key in a){
if (key in b || '?' + key in b) if (key in b || '?' + key in b)
continue; continue;
return Err_Unexpect(key); return Err_Unexpect(key);
} }
} }
} }
function checkProperty(aVal, bVal, ctx) { function checkProperty(aVal, bVal, ctx) {
if (bVal == null) if (bVal == null)
return null; return null;
if (typeof bVal === 'function') { if (typeof bVal === 'function') {
var error = bVal.call(ctx, aVal); var error = bVal.call(ctx, aVal);
if (error == null || error === true) if (error == null || error === true)
return null; return null;
if (error === false) if (error === false)
return Err_Invalid(); return Err_Invalid();
return Err_Custom(error); return Err_Custom(error);
} }
if (aVal == null) if (aVal == null)
return Err_Expect(); return Err_Expect();
if (typeof bVal === 'string') { if (typeof bVal === 'string') {
var str = 'string', var str = 'string',
num = 'number', num = 'number',
bool = 'boolean' bool = 'boolean'
; ;
switch(bVal) { switch(bVal) {
case str: case str:
return typeof aVal !== str || aVal.length === 0 return typeof aVal !== str || aVal.length === 0
...@@ -957,42 +957,42 @@ ...@@ -957,42 +957,42 @@
: null; : null;
} }
} }
if (bVal instanceof RegExp) { if (bVal instanceof RegExp) {
return bVal.test(aVal) === false return bVal.test(aVal) === false
? Err_Invalid() ? Err_Invalid()
: null; : null;
} }
if (Array.isArray(bVal)) { if (Array.isArray(bVal)) {
if (Array.isArray(aVal) === false) if (Array.isArray(aVal) === false)
return Err_Type('array'); return Err_Type('array');
var i = -1, var i = -1,
imax = aVal.length, imax = aVal.length,
error; error;
while ( ++i < imax ){ while ( ++i < imax ){
error = checkObject(aVal[i], bVal[0]) error = checkObject(aVal[i], bVal[0])
if (error) { if (error) {
error.setInvalidProperty(i); error.setInvalidProperty(i);
return error; return error;
} }
} }
return null; return null;
} }
if (typeof aVal !== typeof bVal) if (typeof aVal !== typeof bVal)
return Err_Type(typeof aVal); return Err_Type(typeof aVal);
if (typeof aVal === 'object') if (typeof aVal === 'object')
return checkObject(aVal, bVal); return checkObject(aVal, bVal);
return null; return null;
} }
var Err_Type, var Err_Type,
Err_Expect, Err_Expect,
Err_Unexpect, Err_Unexpect,
...@@ -1000,7 +1000,7 @@ ...@@ -1000,7 +1000,7 @@
Err_Invalid Err_Invalid
; ;
(function(){ (function(){
Err_Type = create('type', Err_Type = create('type',
function TypeErr(expect) { function TypeErr(expect) {
this.expect = expect; this.expect = expect;
...@@ -1077,12 +1077,12 @@ ...@@ -1077,12 +1077,12 @@
} }
} }
); );
function create(type, Ctor, proto) { function create(type, Ctor, proto) {
proto.type = type; proto.type = type;
proto.property = null; proto.property = null;
proto.setInvalidProperty = setInvalidProperty; proto.setInvalidProperty = setInvalidProperty;
Ctor.prototype = proto; Ctor.prototype = proto;
return function(mix){ return function(mix){
return new Ctor(mix); return new Ctor(mix);
...@@ -1096,54 +1096,54 @@ ...@@ -1096,54 +1096,54 @@
this.property = prop + '.' + this.property; this.property = prop + '.' + this.property;
} }
}()); /*< Errors */ }()); /*< Errors */
}()); }());
}()); }());
// end:source /src/util/object.js // end:source /src/util/object.js
// source /src/util/patchObject.js // source /src/util/patchObject.js
var obj_patch, var obj_patch,
obj_patchValidate; obj_patchValidate;
(function(){ (function(){
obj_patch = function(obj, patch){ obj_patch = function(obj, patch){
for(var key in patch){ for(var key in patch){
var patcher = patches[key]; var patcher = patches[key];
if (patcher) if (patcher)
patcher[fn_WALKER](obj, patch[key], patcher[fn_MODIFIER]); patcher[fn_WALKER](obj, patch[key], patcher[fn_MODIFIER]);
else else
console.error('Unknown or not implemented patcher', key); console.error('Unknown or not implemented patcher', key);
} }
return obj; return obj;
}; };
obj_patchValidate = function(patch){ obj_patchValidate = function(patch){
if (patch == null) if (patch == null)
return 'Undefined'; return 'Undefined';
var has = false; var has = false;
for(var key in patch){ for(var key in patch){
has = true; has = true;
if (patches[key] == null) if (patches[key] == null)
return 'Unsupported patcher: ' + key; return 'Unsupported patcher: ' + key;
} }
if (has === false) if (has === false)
return 'No data'; return 'No data';
return null; return null;
}; };
// === private // === private
function walk_mutator(obj, data, fn) { function walk_mutator(obj, data, fn) {
for (var key in data) for (var key in data)
fn(obj_getProperty(obj, key), data[key], key); fn(obj_getProperty(obj, key), data[key], key);
} }
function walk_modifier(obj, data, fn){ function walk_modifier(obj, data, fn){
for(var key in data) for(var key in data)
obj_setProperty( obj_setProperty(
...@@ -1152,18 +1152,18 @@ ...@@ -1152,18 +1152,18 @@
fn(obj_getProperty(obj, key), data[key], key) fn(obj_getProperty(obj, key), data[key], key)
); );
} }
function fn_IoC(){ function fn_IoC(){
var fns = arguments; var fns = arguments;
return function(val, mix, prop){ return function(val, mix, prop){
for (var i = 0, fn, imax = fns.length; i < imax; i++){ for (var i = 0, fn, imax = fns.length; i < imax; i++){
fn = fns[i]; fn = fns[i];
if (fn(val, mix, prop) === false) if (fn(val, mix, prop) === false)
return; return;
} }
} }
} }
function arr_checkArray(val, mix, prop) { function arr_checkArray(val, mix, prop) {
if (arr_isArray(val) === false) { if (arr_isArray(val) === false) {
// if DEBUG // if DEBUG
...@@ -1172,7 +1172,7 @@ ...@@ -1172,7 +1172,7 @@
return false; return false;
} }
} }
function arr_push(val, mix, prop){ function arr_push(val, mix, prop){
if (mix.hasOwnProperty('$each')) { if (mix.hasOwnProperty('$each')) {
for (var i = 0, imax = mix.$each.length; i < imax; i++){ for (var i = 0, imax = mix.$each.length; i < imax; i++){
...@@ -1182,7 +1182,7 @@ ...@@ -1182,7 +1182,7 @@
} }
val.push(mix); val.push(mix);
} }
function arr_pop(val, mix, prop){ function arr_pop(val, mix, prop){
val[mix > 0 ? 'pop' : 'shift'](); val[mix > 0 ? 'pop' : 'shift']();
} }
...@@ -1191,7 +1191,7 @@ ...@@ -1191,7 +1191,7 @@
return query_match(item, mix); return query_match(item, mix);
}); });
} }
function val_inc(val, mix, key){ function val_inc(val, mix, key){
return val + mix; return val + mix;
} }
...@@ -1201,47 +1201,47 @@ ...@@ -1201,47 +1201,47 @@
function val_unset(){ function val_unset(){
return void 0; return void 0;
} }
function val_bit(val, mix){ function val_bit(val, mix){
if (mix.or) if (mix.or)
return val | mix.or; return val | mix.or;
if (mix.and) if (mix.and)
return val & mix.and; return val & mix.and;
return val; return val;
} }
var query_match; var query_match;
(function(){ (function(){
/** @TODO improve object matcher */ /** @TODO improve object matcher */
query_match = function(obj, mix){ query_match = function(obj, mix){
for (var key in mix) { for (var key in mix) {
if (obj[key] !== mix[key]) if (obj[key] !== mix[key])
return false; return false;
} }
return true; return true;
}; };
}()); }());
var fn_WALKER = 0, var fn_WALKER = 0,
fn_MODIFIER = 1 fn_MODIFIER = 1
; ;
var patches = { var patches = {
'$push': [walk_mutator, fn_IoC(arr_checkArray, arr_push)], '$push': [walk_mutator, fn_IoC(arr_checkArray, arr_push)],
'$pop': [walk_mutator, fn_IoC(arr_checkArray, arr_pop)], '$pop': [walk_mutator, fn_IoC(arr_checkArray, arr_pop)],
'$pull': [walk_mutator, fn_IoC(arr_checkArray, arr_pull)], '$pull': [walk_mutator, fn_IoC(arr_checkArray, arr_pull)],
'$inc': [walk_modifier, val_inc], '$inc': [walk_modifier, val_inc],
'$set': [walk_modifier, val_set], '$set': [walk_modifier, val_set],
'$unset': [walk_modifier, val_unset], '$unset': [walk_modifier, val_unset],
'$bit': [walk_modifier, val_unset], '$bit': [walk_modifier, val_unset],
}; };
}()); }());
// end:source /src/util/patchObject.js // end:source /src/util/patchObject.js
// source /src/util/function.js // source /src/util/function.js
...@@ -1251,15 +1251,15 @@ ...@@ -1251,15 +1251,15 @@
fn_doNothing, fn_doNothing,
fn_argsId fn_argsId
; ;
(function(){ (function(){
fn_proxy = function(fn, ctx) { fn_proxy = function(fn, ctx) {
return function() { return function() {
return fn_apply(fn, ctx, arguments); return fn_apply(fn, ctx, arguments);
}; };
}; };
fn_apply = function(fn, ctx, _arguments){ fn_apply = function(fn, ctx, _arguments){
switch (_arguments.length) { switch (_arguments.length) {
case 0: case 0:
...@@ -1292,23 +1292,23 @@ ...@@ -1292,23 +1292,23 @@
}; };
return fn.apply(ctx, _arguments); return fn.apply(ctx, _arguments);
}; };
fn_createDelegate = function(fn /* args */) { fn_createDelegate = function(fn /* args */) {
var args = _Array_slice.call(arguments, 1); var args = _Array_slice.call(arguments, 1);
return function(){ return function(){
if (arguments.length > 0) if (arguments.length > 0)
args = args.concat(_Array_slice.call(arguments)); args = args.concat(_Array_slice.call(arguments));
return fn_apply(fn, null, args); return fn_apply(fn, null, args);
}; };
}; };
fn_doNothing = function(){}; fn_doNothing = function(){};
fn_argsId = function(args, cache){ fn_argsId = function(args, cache){
if (args.length === 0) if (args.length === 0)
return 0; return 0;
var imax = cache.length, var imax = cache.length,
i = -1; i = -1;
while( ++i < imax ){ while( ++i < imax ){
...@@ -1318,13 +1318,13 @@ ...@@ -1318,13 +1318,13 @@
cache.push(args); cache.push(args);
return cache.length; return cache.length;
}; };
// === private // === private
function args_match(a, b){ function args_match(a, b){
if (a.length !== b.length) if (a.length !== b.length)
return false; return false;
var imax = a.length, var imax = a.length,
i = 0; i = 0;
for (; i < imax; i++){ for (; i < imax; i++){
...@@ -1334,35 +1334,35 @@ ...@@ -1334,35 +1334,35 @@
return true; return true;
} }
}()); }());
// end:source /src/util/function.js // end:source /src/util/function.js
// source /src/xhr/XHR.js // source /src/xhr/XHR.js
var XHR = {}; var XHR = {};
(function(){ (function(){
// source promise.js // source promise.js
/* /*
* Copyright 2012-2013 (c) Pierre Duquesne <stackp@online.fr> * Copyright 2012-2013 (c) Pierre Duquesne <stackp@online.fr>
* Licensed under the New BSD License. * Licensed under the New BSD License.
* https://github.com/stackp/promisejs * https://github.com/stackp/promisejs
*/ */
(function(exports) { (function(exports) {
var ct_URL_ENCODED = 'application/x-www-form-urlencoded', var ct_URL_ENCODED = 'application/x-www-form-urlencoded',
ct_JSON = 'application/json'; ct_JSON = 'application/json';
var e_NO_XHR = 1, var e_NO_XHR = 1,
e_TIMEOUT = 2, e_TIMEOUT = 2,
e_PRAPAIR_DATA = 3; e_PRAPAIR_DATA = 3;
function Promise() { function Promise() {
this._callbacks = []; this._callbacks = [];
} }
Promise.prototype.then = function(func, context) { Promise.prototype.then = function(func, context) {
var p; var p;
if (this._isdone) { if (this._isdone) {
...@@ -1377,7 +1377,7 @@ ...@@ -1377,7 +1377,7 @@
} }
return p; return p;
}; };
Promise.prototype.done = function() { Promise.prototype.done = function() {
this.result = arguments; this.result = arguments;
this._isdone = true; this._isdone = true;
...@@ -1386,19 +1386,19 @@ ...@@ -1386,19 +1386,19 @@
} }
this._callbacks = []; this._callbacks = [];
}; };
function join(promises) { function join(promises) {
var p = new Promise(); var p = new Promise();
var results = []; var results = [];
if (!promises || !promises.length) { if (!promises || !promises.length) {
p.done(results); p.done(results);
return p; return p;
} }
var numdone = 0; var numdone = 0;
var total = promises.length; var total = promises.length;
function notifier(i) { function notifier(i) {
return function() { return function() {
numdone += 1; numdone += 1;
...@@ -1408,14 +1408,14 @@ ...@@ -1408,14 +1408,14 @@
} }
}; };
} }
for (var i = 0; i < total; i++) { for (var i = 0; i < total; i++) {
promises[i].then(notifier(i)); promises[i].then(notifier(i));
} }
return p; return p;
} }
function chain(funcs, args) { function chain(funcs, args) {
var p = new Promise(); var p = new Promise();
if (funcs.length === 0) { if (funcs.length === 0) {
...@@ -1430,11 +1430,11 @@ ...@@ -1430,11 +1430,11 @@
} }
return p; return p;
} }
/* /*
* AJAX requests * AJAX requests
*/ */
function _encode(data) { function _encode(data) {
var result = ""; var result = "";
if (typeof data === "string") { if (typeof data === "string") {
...@@ -1449,7 +1449,7 @@ ...@@ -1449,7 +1449,7 @@
} }
return result; return result;
} }
function new_xhr() { function new_xhr() {
var xhr; var xhr;
if (window.XMLHttpRequest) { if (window.XMLHttpRequest) {
...@@ -1463,16 +1463,16 @@ ...@@ -1463,16 +1463,16 @@
} }
return xhr; return xhr;
} }
function ajax(method, url, data, headers) { function ajax(method, url, data, headers) {
var p = new Promise(), var p = new Promise(),
contentType = headers && headers['Content-Type'] || promise.contentType; contentType = headers && headers['Content-Type'] || promise.contentType;
var xhr, var xhr,
payload; payload;
try { try {
xhr = new_xhr(); xhr = new_xhr();
} catch (e) { } catch (e) {
...@@ -1480,14 +1480,14 @@ ...@@ -1480,14 +1480,14 @@
return p; return p;
} }
if (data) { if (data) {
if ('GET' === method) { if ('GET' === method) {
url += '?' + _encode(data); url += '?' + _encode(data);
data = null; data = null;
} else { } else {
switch (contentType) { switch (contentType) {
case ct_URL_ENCODED: case ct_URL_ENCODED:
data = _encode(data); data = _encode(data);
...@@ -1496,7 +1496,7 @@ ...@@ -1496,7 +1496,7 @@
try { try {
data = JSON.stringify(data); data = JSON.stringify(data);
} catch(error){ } catch(error){
p.done(e_PRAPAIR_DATA, ''); p.done(e_PRAPAIR_DATA, '');
return p; return p;
} }
...@@ -1507,30 +1507,30 @@ ...@@ -1507,30 +1507,30 @@
break; break;
} }
} }
} }
xhr.open(method, url); xhr.open(method, url);
if (data) if (data)
xhr.setRequestHeader('Content-Type', contentType); xhr.setRequestHeader('Content-Type', contentType);
for (var h in headers) { for (var h in headers) {
if (headers.hasOwnProperty(h)) { if (headers.hasOwnProperty(h)) {
xhr.setRequestHeader(h, headers[h]); xhr.setRequestHeader(h, headers[h]);
} }
} }
function onTimeout() { function onTimeout() {
xhr.abort(); xhr.abort();
p.done(e_TIMEOUT, "", xhr); p.done(e_TIMEOUT, "", xhr);
} }
var timeout = promise.ajaxTimeout; var timeout = promise.ajaxTimeout;
if (timeout) { if (timeout) {
var tid = setTimeout(onTimeout, timeout); var tid = setTimeout(onTimeout, timeout);
} }
xhr.onreadystatechange = function() { xhr.onreadystatechange = function() {
if (timeout) { if (timeout) {
clearTimeout(tid); clearTimeout(tid);
...@@ -1542,17 +1542,17 @@ ...@@ -1542,17 +1542,17 @@
p.done(err, xhr.responseText, xhr); p.done(err, xhr.responseText, xhr);
} }
}; };
xhr.send(data); xhr.send(data);
return p; return p;
} }
function _ajaxer(method) { function _ajaxer(method) {
return function(url, data, headers) { return function(url, data, headers) {
return ajax(method, url, data, headers); return ajax(method, url, data, headers);
}; };
} }
var promise = { var promise = {
Promise: Promise, Promise: Promise,
join: join, join: join,
...@@ -1563,7 +1563,7 @@ ...@@ -1563,7 +1563,7 @@
put: _ajaxer('PUT'), put: _ajaxer('PUT'),
del: _ajaxer('DELETE'), del: _ajaxer('DELETE'),
patch: _ajaxer('PATCH'), patch: _ajaxer('PATCH'),
/* Error codes */ /* Error codes */
ENOXHR: e_NO_XHR, ENOXHR: e_NO_XHR,
ETIMEOUT: e_TIMEOUT, ETIMEOUT: e_TIMEOUT,
...@@ -1578,11 +1578,11 @@ ...@@ -1578,11 +1578,11 @@
* code. * code.
*/ */
ajaxTimeout: 0, ajaxTimeout: 0,
contentType: ct_JSON contentType: ct_JSON
}; };
if (typeof define === 'function' && define.amd) { if (typeof define === 'function' && define.amd) {
/* AMD support */ /* AMD support */
define(function() { define(function() {
...@@ -1591,31 +1591,31 @@ ...@@ -1591,31 +1591,31 @@
} else { } else {
exports.promise = promise; exports.promise = promise;
} }
})(this); })(this);
// end:source promise.js // end:source promise.js
}.call(XHR)); }.call(XHR));
arr_each(['get'], function(key){ arr_each(['get'], function(key){
XHR[key] = function(path, sender){ XHR[key] = function(path, sender){
this this
.promise[key](path) .promise[key](path)
.then(function(errored, response, xhr){ .then(function(errored, response, xhr){
if (errored) { if (errored) {
sender.onError(errored, response, xhr); sender.onError(errored, response, xhr);
return; return;
} }
sender.onSuccess(response); sender.onSuccess(response);
}); });
}; };
}); });
arr_each(['del', 'post', 'put', 'patch'], function(key){ arr_each(['del', 'post', 'put', 'patch'], function(key){
XHR[key] = function(path, data, cb){ XHR[key] = function(path, data, cb){
this this
...@@ -1625,50 +1625,50 @@ ...@@ -1625,50 +1625,50 @@
}); });
}; };
}); });
// end:source /src/xhr/XHR.js // end:source /src/xhr/XHR.js
// source /src/business/Serializable.js // source /src/business/Serializable.js
var Serializable; var Serializable;
(function(){ (function(){
Serializable = function($serialization) { Serializable = function($serialization) {
if (this === Class || this == null || this === global) { if (this === Class || this == null || this === global) {
var Ctor = function(data){ var Ctor = function(data){
this[json_key_SER] = obj_extend(this[json_key_SER], $serialization); this[json_key_SER] = obj_extend(this[json_key_SER], $serialization);
Serializable.call(this, data); Serializable.call(this, data);
}; };
return Ctor; return Ctor;
} }
if ($serialization != null) { if ($serialization != null) {
if (this.deserialize) if (this.deserialize)
this.deserialize($serialization); this.deserialize($serialization);
else else
Serializable.deserialize(this, $serialization); Serializable.deserialize(this, $serialization);
} }
} }
Serializable.serialize = function(instance) { Serializable.serialize = function(instance) {
if (is_Function(instance.toJSON)) if (is_Function(instance.toJSON))
return instance.toJSON(); return instance.toJSON();
return json_proto_toJSON.call(instance, instance[json_key_SER]); return json_proto_toJSON.call(instance, instance[json_key_SER]);
}; };
Serializable.deserialize = function(instance, json) { Serializable.deserialize = function(instance, json) {
if (is_String(json)) { if (is_String(json)) {
try { try {
json = JSON.parse(json); json = JSON.parse(json);
...@@ -1677,7 +1677,7 @@ ...@@ -1677,7 +1677,7 @@
return instance; return instance;
} }
} }
if (is_Array(json) && is_Function(instance.push)) { if (is_Array(json) && is_Function(instance.push)) {
instance.length = 0; instance.length = 0;
for (var i = 0, imax = json.length; i < imax; i++){ for (var i = 0, imax = json.length; i < imax; i++){
...@@ -1685,48 +1685,48 @@ ...@@ -1685,48 +1685,48 @@
} }
return instance; return instance;
} }
var props = instance[json_key_SER], var props = instance[json_key_SER],
asKeys, asKey, asKeys, asKey,
key, key,
val, val,
Mix; Mix;
if (props != null) { if (props != null) {
var pname = '__desAsKeys'; var pname = '__desAsKeys';
asKeys = props[pname]; asKeys = props[pname];
if (asKeys == null) { if (asKeys == null) {
asKeys = props[pname] = {}; asKeys = props[pname] = {};
for (key in props) { for (key in props) {
if (key !== '__desAsKeys' && props[key].hasOwnProperty('key') === true) if (key !== '__desAsKeys' && props[key].hasOwnProperty('key') === true)
asKeys[props[key].key] = key; asKeys[props[key].key] = key;
} }
} }
} }
for (key in json) { for (key in json) {
val = json[key]; val = json[key];
asKey = key; asKey = key;
if (props != null) { if (props != null) {
Mix = props.hasOwnProperty(key) Mix = props.hasOwnProperty(key)
? props[key] ? props[key]
: null : null
; ;
if (asKeys[key]) { if (asKeys[key]) {
asKey = asKeys[key]; asKey = asKeys[key];
} }
if (Mix != null) { if (Mix != null) {
if (is_Object(Mix)) if (is_Object(Mix))
Mix = Mix.deserialize; Mix = Mix.deserialize;
if (is_String(Mix)) if (is_String(Mix))
Mix = class_get(Mix); Mix = class_get(Mix);
if (is_Function(Mix)) { if (is_Function(Mix)) {
instance[asKey] = val instanceof Mix instance[asKey] = val instanceof Mix
? val ? val
...@@ -1736,15 +1736,15 @@ ...@@ -1736,15 +1736,15 @@
} }
} }
} }
instance[asKey] = val; instance[asKey] = val;
} }
return instance; return instance;
} }
}()); }());
// end:source /src/business/Serializable.js // end:source /src/business/Serializable.js
// source /src/business/Route.js // source /src/business/Route.js
/** /**
...@@ -1753,162 +1753,162 @@ ...@@ -1753,162 +1753,162 @@
* route.create({id:5}) // -> '/user/5' * route.create({id:5}) // -> '/user/5'
*/ */
var Route = (function(){ var Route = (function(){
function Route(route){ function Route(route){
this.route = route_parse(route); this.route = route_parse(route);
} }
Route.prototype = { Route.prototype = {
constructor: Route, constructor: Route,
create: function(object){ create: function(object){
var path, query; var path, query;
path = route_interpolate(this.route.path, object, '/'); path = route_interpolate(this.route.path, object, '/');
if (path == null) { if (path == null) {
return null; return null;
} }
if (this.route.query) { if (this.route.query) {
query = route_interpolate(this.route.query, object, '&'); query = route_interpolate(this.route.query, object, '&');
if (query == null) { if (query == null) {
return null; return null;
} }
} }
return path + (query ? '?' + query : ''); return path + (query ? '?' + query : '');
}, },
hasAliases: function(object){ hasAliases: function(object){
var i = 0, var i = 0,
imax = this.route.path.length, imax = this.route.path.length,
alias alias
; ;
for (; i < imax; i++){ for (; i < imax; i++){
alias = this.route.path[i].parts[1]; alias = this.route.path[i].parts[1];
if (alias && object[alias] == null) { if (alias && object[alias] == null) {
return false; return false;
} }
} }
return true; return true;
} }
}; };
var regexp_pathByColon = /^([^:\?]*)(\??):(\??)([\w]+)$/, var regexp_pathByColon = /^([^:\?]*)(\??):(\??)([\w]+)$/,
regexp_pathByBraces = /^([^\{\?]*)(\{(\??)([\w]+)\})?([^\s]*)?$/; regexp_pathByBraces = /^([^\{\?]*)(\{(\??)([\w]+)\})?([^\s]*)?$/;
function parse_single(string) { function parse_single(string) {
var match = regexp_pathByColon.exec(string); var match = regexp_pathByColon.exec(string);
if (match) { if (match) {
return { return {
optional: (match[2] || match[3]) === '?', optional: (match[2] || match[3]) === '?',
parts: [match[1], match[4]] parts: [match[1], match[4]]
}; };
} }
match = regexp_pathByBraces.exec(string); match = regexp_pathByBraces.exec(string);
if (match) { if (match) {
return { return {
optional: match[3] === '?', optional: match[3] === '?',
parts: [match[1], match[4], match[5]] parts: [match[1], match[4], match[5]]
}; };
} }
console.error('Paths breadcrumbs should be matched by regexps'); console.error('Paths breadcrumbs should be matched by regexps');
return { parts: [string] }; return { parts: [string] };
} }
function parse_path(path, delimiter) { function parse_path(path, delimiter) {
var parts = path.split(delimiter); var parts = path.split(delimiter);
for (var i = 0, imax = parts.length; i < imax; i++){ for (var i = 0, imax = parts.length; i < imax; i++){
parts[i] = parse_single(parts[i]); parts[i] = parse_single(parts[i]);
} }
return parts; return parts;
} }
function route_parse(route) { function route_parse(route) {
var question = /[^\:\{]\?[^:]/.exec(route), var question = /[^\:\{]\?[^:]/.exec(route),
query = null; query = null;
if (question){ if (question){
question = question.index + 1; question = question.index + 1;
query = route.substring(question + 1); query = route.substring(question + 1);
route = route.substring(0, question); route = route.substring(0, question);
} }
return { return {
path: parse_path(route, '/'), path: parse_path(route, '/'),
query: query == null ? null : parse_path(query, '&') query: query == null ? null : parse_path(query, '&')
}; };
} }
/** - route - [] */ /** - route - [] */
function route_interpolate(breadcrumbs, object, delimiter) { function route_interpolate(breadcrumbs, object, delimiter) {
var route = [], var route = [],
key, key,
parts; parts;
for (var i = 0, x, imax = breadcrumbs.length; i < imax; i++){ for (var i = 0, x, imax = breadcrumbs.length; i < imax; i++){
x = breadcrumbs[i]; x = breadcrumbs[i];
parts = x.parts.slice(0); parts = x.parts.slice(0);
if (parts[1] == null) { if (parts[1] == null) {
// is not an interpolated breadcrumb // is not an interpolated breadcrumb
route.push(parts[0]); route.push(parts[0]);
continue; continue;
} }
key = parts[1]; key = parts[1];
parts[1] = object[key]; parts[1] = object[key];
if (parts[1] == null){ if (parts[1] == null){
if (!x.optional) { if (!x.optional) {
console.error('Object has no value, for not optional part - ', key); console.error('Object has no value, for not optional part - ', key);
return null; return null;
} }
continue; continue;
} }
route.push(parts.join('')); route.push(parts.join(''));
} }
return route.join(delimiter); return route.join(delimiter);
} }
return Route; return Route;
}()); }());
// end:source /src/business/Route.js // end:source /src/business/Route.js
// source /src/business/Deferred.js // source /src/business/Deferred.js
var Deferred; var Deferred;
(function(){ (function(){
Deferred = function(){}; Deferred = function(){};
Deferred.prototype = { Deferred.prototype = {
_isAsync: true, _isAsync: true,
_done: null, _done: null,
_fail: null, _fail: null,
_always: null, _always: null,
_resolved: null, _resolved: null,
_rejected: null, _rejected: null,
defer: function(){ defer: function(){
this._rejected = null; this._rejected = null;
this._resolved = null; this._resolved = null;
}, },
isResolved: function(){ isResolved: function(){
return this._resolved != null; return this._resolved != null;
}, },
...@@ -1918,49 +1918,49 @@ ...@@ -1918,49 +1918,49 @@
isBusy: function(){ isBusy: function(){
return this._resolved == null && this._rejected == null; return this._resolved == null && this._rejected == null;
}, },
resolve: function() { resolve: function() {
var done = this._done, var done = this._done,
always = this._always always = this._always
; ;
this._resolved = arguments; this._resolved = arguments;
dfr_clearListeners(this); dfr_clearListeners(this);
arr_callOnce(done, this, arguments); arr_callOnce(done, this, arguments);
arr_callOnce(always, this, [ this ]); arr_callOnce(always, this, [ this ]);
return this; return this;
}, },
reject: function() { reject: function() {
var fail = this._fail, var fail = this._fail,
always = this._always always = this._always
; ;
this._rejected = arguments; this._rejected = arguments;
dfr_clearListeners(this); dfr_clearListeners(this);
arr_callOnce(fail, this, arguments); arr_callOnce(fail, this, arguments);
arr_callOnce(always, this, [ this ]); arr_callOnce(always, this, [ this ]);
return this; return this;
}, },
resolveDelegate: function(){ resolveDelegate: function(){
return fn_proxy(this.resolve, this); return fn_proxy(this.resolve, this);
}, },
rejectDelegate: function(){ rejectDelegate: function(){
return fn_proxy(this.reject, this); return fn_proxy(this.reject, this);
}, },
then: function(filterSuccess, filterError){ then: function(filterSuccess, filterError){
return this.pipe(filterSuccess, filterError); return this.pipe(filterSuccess, filterError);
}, },
done: function(callback) { done: function(callback) {
if (this._rejected != null) if (this._rejected != null)
return this; return this;
return dfr_bind( return dfr_bind(
this, this,
...@@ -1969,9 +1969,9 @@ ...@@ -1969,9 +1969,9 @@
callback callback
); );
}, },
fail: function(callback) { fail: function(callback) {
if (this._resolved != null) if (this._resolved != null)
return this; return this;
return dfr_bind( return dfr_bind(
this, this,
...@@ -1980,7 +1980,7 @@ ...@@ -1980,7 +1980,7 @@
callback callback
); );
}, },
always: function(callback) { always: function(callback) {
return dfr_bind( return dfr_bind(
this, this,
...@@ -1989,7 +1989,7 @@ ...@@ -1989,7 +1989,7 @@
callback callback
); );
}, },
pipe: function(mix /* ..methods */){ pipe: function(mix /* ..methods */){
var dfr; var dfr;
if (typeof mix === 'function') { if (typeof mix === 'function') {
...@@ -1998,14 +1998,14 @@ ...@@ -1998,14 +1998,14 @@
fail_ = arguments.length > 1 fail_ = arguments.length > 1
? arguments[1] ? arguments[1]
: null; : null;
this this
.done(delegate(dfr, 'resolve', done_)) .done(delegate(dfr, 'resolve', done_))
.fail(delegate(dfr, 'reject', fail_)) .fail(delegate(dfr, 'reject', fail_))
; ;
return dfr; return dfr;
} }
dfr = mix; dfr = mix;
var imax = arguments.length, var imax = arguments.length,
done = imax === 1, done = imax === 1,
...@@ -2027,14 +2027,14 @@ ...@@ -2027,14 +2027,14 @@
} }
done && this.done(dfr.resolveDelegate()); done && this.done(dfr.resolveDelegate());
fail && this.fail(dfr.rejectDelegate()); fail && this.fail(dfr.rejectDelegate());
function pipe(dfr, method) { function pipe(dfr, method) {
return function(){ return function(){
dfr[method].apply(dfr, arguments); dfr[method].apply(dfr, arguments);
}; };
} }
function delegate(dfr, name, fn) { function delegate(dfr, name, fn) {
return function(){ return function(){
if (fn != null) { if (fn != null) {
var override = fn.apply(this, arguments); var override = fn.apply(this, arguments);
...@@ -2043,7 +2043,7 @@ ...@@ -2043,7 +2043,7 @@
override.pipe(dfr); override.pipe(dfr);
return; return;
} }
dfr[name](override) dfr[name](override)
return; return;
} }
...@@ -2051,7 +2051,7 @@ ...@@ -2051,7 +2051,7 @@
dfr[name].apply(dfr, arguments); dfr[name].apply(dfr, arguments);
}; };
} }
return this; return this;
}, },
pipeCallback: function(){ pipeCallback: function(){
...@@ -2066,12 +2066,12 @@ ...@@ -2066,12 +2066,12 @@
}; };
} }
}; };
Deferred.run = function(fn, ctx){ Deferred.run = function(fn, ctx){
var dfr = new Deferred(); var dfr = new Deferred();
if (ctx == null) if (ctx == null)
ctx = dfr; ctx = dfr;
fn.call(ctx, dfr.resolveDelegate(), dfr.rejectDelegate(), dfr); fn.call(ctx, dfr.resolveDelegate(), dfr.rejectDelegate(), dfr);
return dfr; return dfr;
}; };
...@@ -2084,7 +2084,7 @@ ...@@ -2084,7 +2084,7 @@
var args = _Array_slice.call(arguments), var args = _Array_slice.call(arguments),
dfr = new Deferred; dfr = new Deferred;
args.unshift(dfr); args.unshift(dfr);
fn_apply(fn, this, args); fn_apply(fn, this, args);
return dfr; return dfr;
}; };
...@@ -2104,70 +2104,70 @@ ...@@ -2104,70 +2104,70 @@
return function(){ return function(){
var args = _Array_slice.call(arguments), var args = _Array_slice.call(arguments),
id = fn_argsId(args_store, args); id = fn_argsId(args_store, args);
if (dfrs[id] != null) if (dfrs[id] != null)
return dfrs[id]; return dfrs[id];
var dfr = dfrs[id] = new Deferred; var dfr = dfrs[id] = new Deferred;
args.unshift(dfr); args.unshift(dfr);
fn_apply(fn, this, args); fn_apply(fn, this, args);
return dfr; return dfr;
}; };
}; };
// PRIVATE // PRIVATE
function dfr_bind(dfr, arguments_, listeners, callback){ function dfr_bind(dfr, arguments_, listeners, callback){
if (callback == null) if (callback == null)
return dfr; return dfr;
if ( arguments_ != null) if ( arguments_ != null)
fn_apply(callback, dfr, arguments_); fn_apply(callback, dfr, arguments_);
else else
listeners.push(callback); listeners.push(callback);
return dfr; return dfr;
} }
function dfr_clearListeners(dfr) { function dfr_clearListeners(dfr) {
dfr._done = null; dfr._done = null;
dfr._fail = null; dfr._fail = null;
dfr._always = null; dfr._always = null;
} }
function arr_callOnce(arr, ctx, args) { function arr_callOnce(arr, ctx, args) {
if (arr == null) if (arr == null)
return; return;
var imax = arr.length, var imax = arr.length,
i = -1, i = -1,
fn; fn;
while ( ++i < imax ) { while ( ++i < imax ) {
fn = arr[i]; fn = arr[i];
if (fn) if (fn)
fn_apply(fn, ctx, args); fn_apply(fn, ctx, args);
} }
arr.length = 0; arr.length = 0;
} }
function isDeferred(x){ function isDeferred(x){
if (x == null || typeof x !== 'object') if (x == null || typeof x !== 'object')
return false; return false;
if (x instanceof Deferred) if (x instanceof Deferred)
return true; return true;
return typeof x.done === 'function' return typeof x.done === 'function'
&& typeof x.fail === 'function' && typeof x.fail === 'function'
; ;
} }
}()); }());
// end:source /src/business/Deferred.js // end:source /src/business/Deferred.js
// source /src/business/EventEmitter.js // source /src/business/EventEmitter.js
var EventEmitter; var EventEmitter;
(function(){ (function(){
EventEmitter = function() { EventEmitter = function() {
this._listeners = {}; this._listeners = {};
}; };
...@@ -2177,7 +2177,7 @@ ...@@ -2177,7 +2177,7 @@
if (callback != null){ if (callback != null){
(this._listeners[event] || (this._listeners[event] = [])).push(callback); (this._listeners[event] || (this._listeners[event] = [])).push(callback);
} }
return this; return this;
}, },
once: function(event, callback){ once: function(event, callback){
...@@ -2185,98 +2185,98 @@ ...@@ -2185,98 +2185,98 @@
callback._once = true; callback._once = true;
(this._listeners[event] || (this._listeners[event] = [])).push(callback); (this._listeners[event] || (this._listeners[event] = [])).push(callback);
} }
return this; return this;
}, },
pipe: function(event){ pipe: function(event){
var that = this, var that = this,
args; args;
return function(){ return function(){
args = _Array_slice.call(arguments); args = _Array_slice.call(arguments);
args.unshift(event); args.unshift(event);
fn_apply(that.trigger, that, args); fn_apply(that.trigger, that, args);
}; };
}, },
emit: event_trigger, emit: event_trigger,
trigger: event_trigger, trigger: event_trigger,
off: function(event, callback) { off: function(event, callback) {
var listeners = this._listeners[event]; var listeners = this._listeners[event];
if (listeners == null) if (listeners == null)
return this; return this;
if (arguments.length === 1) { if (arguments.length === 1) {
listeners.length = 0; listeners.length = 0;
return this; return this;
} }
var imax = listeners.length, var imax = listeners.length,
i = -1; i = -1;
while (++i < imax) { while (++i < imax) {
if (listeners[i] === callback) { if (listeners[i] === callback) {
listeners.splice(i, 1); listeners.splice(i, 1);
i--; i--;
imax--; imax--;
} }
} }
return this; return this;
} }
}; };
function event_trigger() { function event_trigger() {
var args = _Array_slice.call(arguments), var args = _Array_slice.call(arguments),
event = args.shift(), event = args.shift(),
fns = this._listeners[event], fns = this._listeners[event],
fn, imax, i = 0; fn, imax, i = 0;
if (fns == null) if (fns == null)
return this; return this;
for (imax = fns.length; i < imax; i++) { for (imax = fns.length; i < imax; i++) {
fn = fns[i]; fn = fns[i];
fn_apply(fn, this, args); fn_apply(fn, this, args);
if (fn._once === true){ if (fn._once === true){
fns.splice(i, 1); fns.splice(i, 1);
i--; i--;
imax--; imax--;
} }
} }
return this; return this;
} }
}()); }());
// end:source /src/business/EventEmitter.js // end:source /src/business/EventEmitter.js
// source /src/Class.js // source /src/Class.js
var Class = function(mix) { var Class = function(mix) {
var namespace, var namespace,
data; data;
if (is_String(mix)) { if (is_String(mix)) {
namespace = mix; namespace = mix;
if (arguments.length === 1) if (arguments.length === 1)
return class_get(mix); return class_get(mix);
data = arguments[1]; data = arguments[1];
data[str_CLASS_IDENTITY] = namespace; data[str_CLASS_IDENTITY] = namespace;
} else { } else {
data = mix; data = mix;
} }
var _base = data.Base, var _base = data.Base,
_extends = data.Extends, _extends = data.Extends,
_static = data.Static, _static = data.Static,
...@@ -2285,27 +2285,27 @@ ...@@ -2285,27 +2285,27 @@
_store = data.Store, _store = data.Store,
_self = data.Self, _self = data.Self,
_overrides = data.Override, _overrides = data.Override,
key; key;
if (_base != null) if (_base != null)
delete data.Base; delete data.Base;
if (_extends != null) if (_extends != null)
delete data.Extends; delete data.Extends;
if (_static != null) if (_static != null)
delete data.Static; delete data.Static;
if (_self != null) if (_self != null)
delete data.Self; delete data.Self;
if (_construct != null) if (_construct != null)
delete data.Construct; delete data.Construct;
if (_store != null) { if (_store != null) {
if (_extends == null) { if (_extends == null) {
_extends = _store; _extends = _store;
} else if (is_Array(_extends)) { } else if (is_Array(_extends)) {
...@@ -2313,47 +2313,47 @@ ...@@ -2313,47 +2313,47 @@
} else { } else {
_extends = [_store, _extends]; _extends = [_store, _extends];
} }
delete data.Store; delete data.Store;
} }
if (_overrides != null) if (_overrides != null)
delete data.Override; delete data.Override;
if (_base == null && _extends == null && _self == null) { if (_base == null && _extends == null && _self == null) {
if (data.toJSON === void 0) if (data.toJSON === void 0)
data.toJSON = json_proto_toJSON; data.toJSON = json_proto_toJSON;
_class = _construct == null _class = _construct == null
? function() {} ? function() {}
: _construct : _construct
; ;
data.constructor = _class.prototype.constructor; data.constructor = _class.prototype.constructor;
if (_static != null) { if (_static != null) {
obj_extendDescriptors(_class, _static); obj_extendDescriptors(_class, _static);
} }
_class.prototype = data; _class.prototype = data;
if (namespace != null) if (namespace != null)
class_register(namespace, _class); class_register(namespace, _class);
return _class; return _class;
} }
_class = function() { _class = function() {
//// consider to remove //// consider to remove
////if (this instanceof _class === false) ////if (this instanceof _class === false)
//// return new (_class.bind.apply(_class, [null].concat(_Array_slice.call(arguments)))); //// return new (_class.bind.apply(_class, [null].concat(_Array_slice.call(arguments))));
if (_extends != null) { if (_extends != null) {
var isarray = _extends instanceof Array, var isarray = _extends instanceof Array,
imax = isarray ? _extends.length : 1, imax = isarray ? _extends.length : 1,
i = 0, i = 0,
x = null; x = null;
...@@ -2367,68 +2367,68 @@ ...@@ -2367,68 +2367,68 @@
} }
} }
} }
if (_base != null) { if (_base != null) {
fn_apply(_base, this, arguments); fn_apply(_base, this, arguments);
} }
if (_self != null && is_NullOrGlobal(this) === false) { if (_self != null && is_NullOrGlobal(this) === false) {
for (var key in _self) { for (var key in _self) {
this[key] = fn_proxy(_self[key], this); this[key] = fn_proxy(_self[key], this);
} }
} }
if (_construct != null) { if (_construct != null) {
var r = fn_apply(_construct, this, arguments); var r = fn_apply(_construct, this, arguments);
if (r != null) { if (r != null) {
return r; return r;
} }
} }
this['super'] = null; this['super'] = null;
return this; return this;
}; };
if (namespace != null) if (namespace != null)
class_register(namespace, _class); class_register(namespace, _class);
if (_static != null) { if (_static != null) {
obj_extendDescriptors(_class, _static); obj_extendDescriptors(_class, _static);
} }
if (_base != null) if (_base != null)
class_inheritStatics(_class, _base); class_inheritStatics(_class, _base);
if (_extends != null) if (_extends != null)
class_inheritStatics(_class, _extends); class_inheritStatics(_class, _extends);
class_extendProtoObjects(data, _base, _extends); class_extendProtoObjects(data, _base, _extends);
class_inherit(_class, _base, _extends, data, _overrides, { class_inherit(_class, _base, _extends, data, _overrides, {
toJSON: json_proto_toJSON toJSON: json_proto_toJSON
}); });
data = null; data = null;
_static = null; _static = null;
return _class; return _class;
}; };
// end:source /src/Class.js // end:source /src/Class.js
// source /src/business/Await.js // source /src/business/Await.js
var Await; var Await;
(function(){ (function(){
Await = Class({ Await = Class({
Extends: Deferred.prototype, Extends: Deferred.prototype,
_wait: 0, _wait: 0,
_timeout: null, _timeout: null,
_result: null, _result: null,
_resolved: [], _resolved: [],
Construct: function(/* promises <optional> */){ Construct: function(/* promises <optional> */){
var imax = arguments.length, var imax = arguments.length,
i = -1, i = -1,
...@@ -2436,29 +2436,29 @@ ...@@ -2436,29 +2436,29 @@
; ;
while ( ++i < imax ){ while ( ++i < imax ){
dfr = arguments[i]; dfr = arguments[i];
if (dfr != null && typeof dfr.done === 'function') if (dfr != null && typeof dfr.done === 'function')
await_deferredDelegate(this, null, dfr); await_deferredDelegate(this, null, dfr);
} }
}, },
delegate: function(name, errorable) { delegate: function(name, errorable) {
return await_createDelegate(this, name, errorable); return await_createDelegate(this, name, errorable);
}, },
deferred: function(name) { deferred: function(name) {
return await_deferredDelegate( return await_deferredDelegate(
this, this,
name, name,
new Deferred); new Deferred);
}, },
Static: { Static: {
TIMEOUT: 2000 TIMEOUT: 2000
} }
}); });
function await_deferredDelegate(await, name, dfr){ function await_deferredDelegate(await, name, dfr){
var delegate = await_createDelegate(await, name, true), var delegate = await_createDelegate(await, name, true),
args args
...@@ -2467,116 +2467,116 @@ ...@@ -2467,116 +2467,116 @@
.done(function(){ .done(function(){
args = _Array_slice.call(arguments); args = _Array_slice.call(arguments);
args.unshift(null); args.unshift(null);
delegate.apply(null, args); delegate.apply(null, args);
}) })
.fail(function(error){ .fail(function(error){
delegate(error); delegate(error);
}) })
; ;
} }
function await_createDelegate(await, name, errorable){ function await_createDelegate(await, name, errorable){
if (errorable == null) if (errorable == null)
errorable = true; errorable = true;
if (await._timeout) if (await._timeout)
clearTimeout(await._timeout); clearTimeout(await._timeout);
await.defer(); await.defer();
await._wait++; await._wait++;
if (name){ if (name){
if (!await._result) if (!await._result)
await._result = {}; await._result = {};
if (name in await._result) if (name in await._result)
console.warn('<await>', name, 'already awaiting'); console.warn('<await>', name, 'already awaiting');
await._result[name] = null; await._result[name] = null;
} }
var delegate = fn_createDelegate(await_listener, await, name, errorable) var delegate = fn_createDelegate(await_listener, await, name, errorable)
; ;
await._timeout = setTimeout(delegate, Await.TIMEOUT); await._timeout = setTimeout(delegate, Await.TIMEOUT);
return delegate; return delegate;
} }
function await_listener(await, name, errorable /* .. args */ ) { function await_listener(await, name, errorable /* .. args */ ) {
if (arguments.length === 0) { if (arguments.length === 0) {
// timeout // timeout
await._wait = 0; await._wait = 0;
await.reject('408: Timeout'); await.reject('408: Timeout');
return; return;
} }
if (await._wait === 0) if (await._wait === 0)
return; return;
var result = await._result; var result = await._result;
if (name) { if (name) {
var args = _Array_slice.call(arguments, 3); var args = _Array_slice.call(arguments, 3);
result[name] = { result[name] = {
error: errorable ? args.shift() : null, error: errorable ? args.shift() : null,
arguments: args arguments: args
}; };
} else if (errorable && arguments[3] != null) { } else if (errorable && arguments[3] != null) {
if (result == null) if (result == null)
result = await._result = {}; result = await._result = {};
result.__error = arguments[3]; result.__error = arguments[3];
} }
if (--await._wait === 0) { if (--await._wait === 0) {
clearTimeout(await._timeout); clearTimeout(await._timeout);
var error = result && result.__error var error = result && result.__error
; ;
var val, var val,
key; key;
if (error == null) { if (error == null) {
for(key in result){ for(key in result){
val = result[key]; val = result[key];
error = val && val.error; error = val && val.error;
if (error) if (error)
break; break;
} }
} }
if (error) { if (error) {
await.reject(error, result); await.reject(error, result);
return; return;
} }
await.resolve(result); await.resolve(result);
} }
} }
}()); }());
// end:source /src/business/Await.js // end:source /src/business/Await.js
// source /src/store/Store.js // source /src/store/Store.js
var StoreProto = { var StoreProto = {
// Abstract // Abstract
fetch: null, fetch: null,
save: null, save: null,
del: null, del: null,
onSuccess: null, onSuccess: null,
onError: null, onError: null,
Static: { Static: {
fetch: function(data){ fetch: function(data){
return new this().fetch(data); return new this().fetch(data);
...@@ -2590,24 +2590,24 @@ ...@@ -2590,24 +2590,24 @@
storageEvents_remove, storageEvents_remove,
storageEvents_overridenDefer storageEvents_overridenDefer
; ;
(function(){ (function(){
var event_START = 'start', var event_START = 'start',
event_SUCCESS = 'fulfilled', event_SUCCESS = 'fulfilled',
event_FAIL = 'rejected'; event_FAIL = 'rejected';
var events_ = new EventEmitter, var events_ = new EventEmitter,
hasBeforeListeners_, hasBeforeListeners_,
hasAfterListeners_ hasAfterListeners_
; ;
storageEvents_onBefore = function(callback){ storageEvents_onBefore = function(callback){
events_.on(event_START, callback); events_.on(event_START, callback);
hasBeforeListeners_ = true; hasBeforeListeners_ = true;
}; };
storageEvents_onAfter = function(onSuccess, onFailure){ storageEvents_onAfter = function(onSuccess, onFailure){
events_ events_
.on(event_SUCCESS, onSuccess) .on(event_SUCCESS, onSuccess)
...@@ -2615,7 +2615,7 @@ ...@@ -2615,7 +2615,7 @@
; ;
hasAfterListeners_ = true; hasAfterListeners_ = true;
}; };
storageEvents_remove = function(callback){ storageEvents_remove = function(callback){
events_ events_
.off(event_SUCCESS, callback) .off(event_SUCCESS, callback)
...@@ -2623,26 +2623,26 @@ ...@@ -2623,26 +2623,26 @@
.off(event_START, callback) .off(event_START, callback)
; ;
}; };
storageEvents_overridenDefer = function(type){ storageEvents_overridenDefer = function(type){
Deferred.prototype.defer.call(this); Deferred.prototype.defer.call(this);
if (hasBeforeListeners_) if (hasBeforeListeners_)
emit([event_START, this, type]); emit([event_START, this, type]);
if (hasAfterListeners_) if (hasAfterListeners_)
this.always(listenerDelegate(this, type)); this.always(listenerDelegate(this, type));
return this; return this;
}; };
// PRIVATE // PRIVATE
function listenerDelegate(sender, type) { function listenerDelegate(sender, type) {
return function(){ return function(){
var isSuccess = sender._rejected == null, var isSuccess = sender._rejected == null,
arguments_ = isSuccess arguments_ = isSuccess
? sender._resolved ? sender._resolved
: sender._rejected : sender._rejected
, ,
...@@ -2653,68 +2653,68 @@ ...@@ -2653,68 +2653,68 @@
emit([event, sender, type].concat(arguments_)); emit([event, sender, type].concat(arguments_));
}; };
} }
function emit(arguments_/* [ event, sender, .. ]*/){ function emit(arguments_/* [ event, sender, .. ]*/){
events_.trigger.apply(events_, arguments_); events_.trigger.apply(events_, arguments_);
} }
}()); }());
// end:source /src/store/events.js // end:source /src/store/events.js
// source /src/store/Remote.js // source /src/store/Remote.js
Class.Remote = (function(){ Class.Remote = (function(){
var str_CONTENT_TYPE = 'content-type', var str_CONTENT_TYPE = 'content-type',
str_JSON = 'json' str_JSON = 'json'
; ;
var XHRRemote = function(route){ var XHRRemote = function(route){
this._route = new Route(route); this._route = new Route(route);
}; };
obj_inherit(XHRRemote, StoreProto, Serializable, Deferred, { obj_inherit(XHRRemote, StoreProto, Serializable, Deferred, {
defer: storageEvents_overridenDefer, defer: storageEvents_overridenDefer,
serialize: function(){ serialize: function(){
return is_Array(this) return is_Array(this)
? json_proto_arrayToJSON.call(this) ? json_proto_arrayToJSON.call(this)
: json_proto_toJSON.call(this) : json_proto_toJSON.call(this)
; ;
}, },
deserialize: function(json){ deserialize: function(json){
return Serializable.deserialize(this, json); return Serializable.deserialize(this, json);
}, },
fetch: function(data){ fetch: function(data){
this.defer('fetch'); this.defer('fetch');
XHR.get(this._route.create(data || this), this); XHR.get(this._route.create(data || this), this);
return this; return this;
}, },
save: function(callback){ save: function(callback){
this.defer('save'); this.defer('save');
var json = this.serialize(), var json = this.serialize(),
path = this._route.create(this), path = this._route.create(this),
method = this._route.hasAliases(this) method = this._route.hasAliases(this)
? 'put' ? 'put'
: 'post' : 'post'
; ;
XHR[method](path, json, resolveDelegate(this, callback, 'save')); XHR[method](path, json, resolveDelegate(this, callback, 'save'));
return this; return this;
}, },
patch: function(json){ patch: function(json){
this.defer('patch'); this.defer('patch');
obj_patch(this, json); obj_patch(this, json);
XHR.patch( XHR.patch(
this._route.create(this), this._route.create(this),
json, json,
...@@ -2722,44 +2722,44 @@ ...@@ -2722,44 +2722,44 @@
); );
return this; return this;
}, },
del: function(callback){ del: function(callback){
this.defer('del'); this.defer('del');
var json = this.serialize(), var json = this.serialize(),
path = this._route.create(this) path = this._route.create(this)
; ;
XHR.del(path, json, resolveDelegate(this, callback)); XHR.del(path, json, resolveDelegate(this, callback));
return this; return this;
}, },
onSuccess: function(response){ onSuccess: function(response){
parseFetched(this, response); parseFetched(this, response);
}, },
onError: function(errored, response, xhr){ onError: function(errored, response, xhr){
reject(this, response, xhr); reject(this, response, xhr);
} }
}); });
function parseFetched(self, response){ function parseFetched(self, response){
var json; var json;
try { try {
json = JSON.parse(response); json = JSON.parse(response);
} catch(error) { } catch(error) {
reject(self, error); reject(self, error);
return; return;
} }
self.deserialize(json); self.deserialize(json);
self.resolve(self); self.resolve(self);
} }
function reject(self, response, xhr){ function reject(self, response, xhr){
var obj; var obj;
if (typeof response === 'string' && is_JsonResponse(xhr)) { if (typeof response === 'string' && is_JsonResponse(xhr)) {
...@@ -2769,122 +2769,122 @@ ...@@ -2769,122 +2769,122 @@
obj = error; obj = error;
} }
} }
self.reject(obj || response); self.reject(obj || response);
} }
function is_JsonResponse(xhr){ function is_JsonResponse(xhr){
var header = xhr.getResponseHeader(str_CONTENT_TYPE); var header = xhr.getResponseHeader(str_CONTENT_TYPE);
return header != null return header != null
&& header.toLowerCase().indexOf(str_JSON) !== -1; && header.toLowerCase().indexOf(str_JSON) !== -1;
} }
function resolveDelegate(self, callback, action){ function resolveDelegate(self, callback, action){
return function(error, response, xhr){ return function(error, response, xhr){
if (is_JsonResponse(xhr)) { if (is_JsonResponse(xhr)) {
try { try {
response = JSON.parse(response); response = JSON.parse(response);
} catch(error){ } catch(error){
console.error('<XHR> invalid json response', response); console.error('<XHR> invalid json response', response);
return reject(self, error, xhr); return reject(self, error, xhr);
} }
} }
// @obsolete -> use deferred // @obsolete -> use deferred
if (callback) if (callback)
callback(error, response); callback(error, response);
if (error) if (error)
return reject(self, response, xhr); return reject(self, response, xhr);
if ('save' === action && is_Object(response)) { if ('save' === action && is_Object(response)) {
if (is_Array(self)) { if (is_Array(self)) {
var imax = self.length, var imax = self.length,
jmax = response.length, jmax = response.length,
i = -1 i = -1
; ;
while ( ++i < imax && i < jmax){ while ( ++i < imax && i < jmax){
Serializable.deserialize(self[i], response[i]); Serializable.deserialize(self[i], response[i]);
} }
} else { } else {
self.deserialize(response); self.deserialize(response);
} }
return self.resolve(self); return self.resolve(self);
} }
self.resolve(response); self.resolve(response);
}; };
} }
function Remote(route){ function Remote(route){
return new XHRRemote(route); return new XHRRemote(route);
}; };
Remote.onBefore = storageEvents_onBefore; Remote.onBefore = storageEvents_onBefore;
Remote.onAfter = storageEvents_onAfter; Remote.onAfter = storageEvents_onAfter;
arr_each(['get', 'post', 'put', 'delete'], function(method){ arr_each(['get', 'post', 'put', 'delete'], function(method){
Remote[method] = function(url, obj){ Remote[method] = function(url, obj){
var json = obj; var json = obj;
if (obj.serialize != null) if (obj.serialize != null)
json = obj.serialize(); json = obj.serialize();
if (json == null && obj.toJSON) if (json == null && obj.toJSON)
json = obj.toJSON(); json = obj.toJSON();
var dfr = new Deferred(); var dfr = new Deferred();
XHR[method](url, json, resolveDelegate(dfr)); XHR[method](url, json, resolveDelegate(dfr));
return dfr; return dfr;
}; };
}); });
return Remote; return Remote;
}()); }());
// end:source /src/store/Remote.js // end:source /src/store/Remote.js
// source /src/store/LocalStore.js // source /src/store/LocalStore.js
Class.LocalStore = (function(){ Class.LocalStore = (function(){
var LocalStore = function(route){ var LocalStore = function(route){
this._route = new Route(route); this._route = new Route(route);
}; };
obj_inherit(LocalStore, StoreProto, Serializable, Deferred, { obj_inherit(LocalStore, StoreProto, Serializable, Deferred, {
serialize: function(){ serialize: function(){
var json = is_Array(this) var json = is_Array(this)
? json_proto_arrayToJSON.call(this) ? json_proto_arrayToJSON.call(this)
: json_proto_toJSON.call(this) : json_proto_toJSON.call(this)
; ;
return JSON.stringify(json); return JSON.stringify(json);
}, },
deserialize: function(json){ deserialize: function(json){
return Serializable.deserialize(this, json); return Serializable.deserialize(this, json);
}, },
fetch: function(data){ fetch: function(data){
var path = this._route.create(data || this), var path = this._route.create(data || this),
object = localStorage.getItem(path); object = localStorage.getItem(path);
if (object == null) { if (object == null) {
return this.resolve(this); return this.resolve(this);
} }
if (is_String(object)){ if (is_String(object)){
try { try {
object = JSON.parse(object); object = JSON.parse(object);
...@@ -2892,81 +2892,81 @@ ...@@ -2892,81 +2892,81 @@
return this.reject(e); return this.reject(e);
} }
} }
this.deserialize(object); this.deserialize(object);
return this.resolve(this); return this.resolve(this);
}, },
save: function(callback){ save: function(callback){
var path = this._route.create(this), var path = this._route.create(this),
store = this.serialize(); store = this.serialize();
localStorage.setItem(path, store); localStorage.setItem(path, store);
callback && callback(); callback && callback();
return this.resolve(this); return this.resolve(this);
}, },
del: function(mix){ del: function(mix){
if (mix == null && arguments.length !== 0) { if (mix == null && arguments.length !== 0) {
return this.reject('<localStore:del> - selector is specified, but is undefined'); return this.reject('<localStore:del> - selector is specified, but is undefined');
} }
// Single // Single
if (arr_isArray(this) === false) { if (arr_isArray(this) === false) {
store_del(this._route, mix || this); store_del(this._route, mix || this);
return this.resolve(); return this.resolve();
} }
// Collection // Collection
if (mix == null) { if (mix == null) {
for (var i = 0, imax = this.length; i < imax; i++){ for (var i = 0, imax = this.length; i < imax; i++){
this[i] = null; this[i] = null;
} }
this.length = 0; this.length = 0;
store_del(this._route, this); store_del(this._route, this);
return this.resolve(); return this.resolve();
} }
var array = this.remove(mix); var array = this.remove(mix);
if (array.length === 0) { if (array.length === 0) {
// was nothing removed // was nothing removed
return this.resolve(); return this.resolve();
} }
return this.save(); return this.save();
}, },
onError: function(error){ onError: function(error){
this.reject({ this.reject({
error: error error: error
}); });
} }
}); });
function store_del(route, data){ function store_del(route, data){
var path = route.create(data); var path = route.create(data);
localStorage.removeItem(path); localStorage.removeItem(path);
} }
var Constructor = function(route){ var Constructor = function(route){
return new LocalStore(route); return new LocalStore(route);
}; };
Constructor.prototype = LocalStore.prototype; Constructor.prototype = LocalStore.prototype;
return Constructor; return Constructor;
}()); }());
// end:source /src/store/LocalStore.js // end:source /src/store/LocalStore.js
// source /src/Class.Static.js // source /src/Class.Static.js
/** /**
...@@ -2980,88 +2980,88 @@ ...@@ -2980,88 +2980,88 @@
i = 1, i = 1,
length = arguments.length, length = arguments.length,
key; key;
for (; i < length; i++) { for (; i < length; i++) {
key = arr[i]; key = arr[i];
cntx[key] = cntx[key].bind(cntx); cntx[key] = cntx[key].bind(cntx);
} }
return cntx; return cntx;
}; };
Class.cfg = function(mix, value){ Class.cfg = function(mix, value){
if (is_String(mix)) { if (is_String(mix)) {
if (arguments.length === 1) if (arguments.length === 1)
return _cfg[mix]; return _cfg[mix];
_cfg[mix] = value; _cfg[mix] = value;
return; return;
} }
if (is_Object(mix)) { if (is_Object(mix)) {
for(var key in mix){ for(var key in mix){
Class.cfg(key, mix[key]); Class.cfg(key, mix[key]);
} }
} }
}; };
Class.Model = {}; Class.Model = {};
Class.Serializable = Serializable; Class.Serializable = Serializable;
Class.Deferred = Deferred; Class.Deferred = Deferred;
Class.EventEmitter = EventEmitter; Class.EventEmitter = EventEmitter;
Class.Await = Await; Class.Await = Await;
Class.validate = obj_validate; Class.validate = obj_validate;
Class.stringify = class_stringify; Class.stringify = class_stringify;
Class.parse = class_parse; Class.parse = class_parse;
Class.patch = class_patch; Class.patch = class_patch;
Class.properties = class_properties; Class.properties = class_properties;
// end:source /src/Class.Static.js // end:source /src/Class.Static.js
// source /src/collection/Collection.js // source /src/collection/Collection.js
Class.Collection = (function(){ Class.Collection = (function(){
// source ArrayProto.js // source ArrayProto.js
var ArrayProto = (function(){ var ArrayProto = (function(){
function check(x, mix) { function check(x, mix) {
if (mix == null) if (mix == null)
return false; return false;
if (typeof mix === 'function') if (typeof mix === 'function')
return mix(x); return mix(x);
if (typeof mix === 'object'){ if (typeof mix === 'object'){
if (x.constructor === mix.constructor && x.constructor !== Object) { if (x.constructor === mix.constructor && x.constructor !== Object) {
return x === mix; return x === mix;
} }
var value, matcher; var value, matcher;
for (var key in mix) { for (var key in mix) {
value = x[key]; value = x[key];
matcher = mix[key]; matcher = mix[key];
if (typeof matcher === 'string') { if (typeof matcher === 'string') {
var c = matcher[0], var c = matcher[0],
index = 1; index = 1;
if ('<' === c || '>' === c){ if ('<' === c || '>' === c){
if ('=' === matcher[1]){ if ('=' === matcher[1]){
c +='='; c +='=';
index++; index++;
} }
matcher = matcher.substring(index); matcher = matcher.substring(index);
switch (c) { switch (c) {
case '<': case '<':
if (value >= matcher) if (value >= matcher)
...@@ -3082,73 +3082,73 @@ ...@@ -3082,73 +3082,73 @@
} }
} }
} }
// eqeq to match by type diffs. // eqeq to match by type diffs.
if (value != matcher) if (value != matcher)
return false; return false;
} }
return true; return true;
} }
console.warn('No valid matcher', mix); console.warn('No valid matcher', mix);
return false; return false;
} }
var ArrayProto = { var ArrayProto = {
length: 0, length: 0,
push: function(/*mix*/) { push: function(/*mix*/) {
var imax = arguments.length, var imax = arguments.length,
i = -1; i = -1;
while ( ++i < imax ) { while ( ++i < imax ) {
this[this.length++] = create(this._ctor, arguments[i]); this[this.length++] = create(this._ctor, arguments[i]);
} }
return this; return this;
}, },
pop: function() { pop: function() {
var instance = this[--this.length]; var instance = this[--this.length];
this[this.length] = null; this[this.length] = null;
return instance; return instance;
}, },
shift: function(){ shift: function(){
if (this.length === 0) if (this.length === 0)
return null; return null;
var first = this[0], var first = this[0],
imax = this.length - 1, imax = this.length - 1,
i = 0; i = 0;
for (; i < imax; i++){ for (; i < imax; i++){
this[i] = this[i + 1]; this[i] = this[i + 1];
} }
this[imax] = null; this[imax] = null;
this.length--; this.length--;
return first; return first;
}, },
unshift: function(mix){ unshift: function(mix){
this.length++; this.length++;
var imax = this.length; var imax = this.length;
while (--imax) { while (--imax) {
this[imax] = this[imax - 1]; this[imax] = this[imax - 1];
} }
this[0] = create(this._ctor, mix); this[0] = create(this._ctor, mix);
return this; return this;
}, },
splice: function(index, count /* args */){ splice: function(index, count /* args */){
var length = this.length; var length = this.length;
var i, imax, y; var i, imax, y;
// clear range after length until index // clear range after length until index
if (index >= length) { if (index >= length) {
count = 0; count = 0;
...@@ -3156,65 +3156,65 @@ ...@@ -3156,65 +3156,65 @@
this[i] = void 0; this[i] = void 0;
} }
} }
var rm_count = count, var rm_count = count,
rm_start = index, rm_start = index,
rm_end = index + rm_count, rm_end = index + rm_count,
add_count = arguments.length - 2, add_count = arguments.length - 2,
new_length = length + add_count - rm_count; new_length = length + add_count - rm_count;
// move block // move block
var block_start = rm_end, var block_start = rm_end,
block_end = length, block_end = length,
block_shift = new_length - length; block_shift = new_length - length;
if (0 < block_shift) { if (0 < block_shift) {
// move forward // move forward
i = block_end; i = block_end;
while (--i >= block_start) { while (--i >= block_start) {
this[i + block_shift] = this[i]; this[i + block_shift] = this[i];
} }
} }
if (0 > block_shift) { if (0 > block_shift) {
// move backwards // move backwards
i = block_start; i = block_start;
while (i < block_end) { while (i < block_end) {
this[i + block_shift] = this[i]; this[i + block_shift] = this[i];
i++; i++;
} }
} }
// insert // insert
i = rm_start; i = rm_start;
y = 2; y = 2;
for (; y < arguments.length; y) { for (; y < arguments.length; y) {
this[i++] = create(this._ctor, arguments[y++]); this[i++] = create(this._ctor, arguments[y++]);
} }
this.length = new_length; this.length = new_length;
return this; return this;
}, },
slice: function(){ slice: function(){
return fn_apply(_Array_slice, this, arguments); return fn_apply(_Array_slice, this, arguments);
}, },
sort: function(fn){ sort: function(fn){
_Array_sort.call(this, fn); _Array_sort.call(this, fn);
return this; return this;
}, },
reverse: function(){ reverse: function(){
var array = _Array_slice.call(this), var array = _Array_slice.call(this),
imax = this.length, imax = this.length,
...@@ -3225,62 +3225,62 @@ ...@@ -3225,62 +3225,62 @@
} }
return this; return this;
}, },
toString: function(){ toString: function(){
return _Array_slice.call(this, 0).toString() return _Array_slice.call(this, 0).toString()
}, },
each: forEach, each: forEach,
forEach: forEach, forEach: forEach,
where: function(mix){ where: function(mix){
var collection = new this.constructor(); var collection = new this.constructor();
for (var i = 0, x, imax = this.length; i < imax; i++){ for (var i = 0, x, imax = this.length; i < imax; i++){
x = this[i]; x = this[i];
if (check(x, mix)) { if (check(x, mix)) {
collection[collection.length++] = x; collection[collection.length++] = x;
} }
} }
return collection; return collection;
}, },
remove: function(mix){ remove: function(mix){
var index = -1, var index = -1,
array = []; array = [];
for (var i = 0, imax = this.length; i < imax; i++){ for (var i = 0, imax = this.length; i < imax; i++){
if (check(this[i], mix)) { if (check(this[i], mix)) {
array.push(this[i]); array.push(this[i]);
continue; continue;
} }
this[++index] = this[i]; this[++index] = this[i];
} }
for (i = ++index; i < imax; i++) { for (i = ++index; i < imax; i++) {
this[i] = null; this[i] = null;
} }
this.length = index; this.length = index;
return array; return array;
}, },
first: function(mix){ first: function(mix){
if (mix == null) if (mix == null)
return this[0]; return this[0];
var i = this.indexOf(mix); var i = this.indexOf(mix);
return i !== -1 return i !== -1
? this[i] ? this[i]
: null; : null;
}, },
last: function(mix){ last: function(mix){
if (mix == null) if (mix == null)
return this[this.length - 1]; return this[this.length - 1];
var i = this.lastIndexOf(mix); var i = this.lastIndexOf(mix);
return i !== -1 return i !== -1
? this[i] ? this[i]
...@@ -3289,20 +3289,20 @@ ...@@ -3289,20 +3289,20 @@
indexOf: function(mix, index){ indexOf: function(mix, index){
if (mix == null) if (mix == null)
return -1; return -1;
if (index != null) { if (index != null) {
if (index < 0) if (index < 0)
index = 0; index = 0;
if (index >= this.length) if (index >= this.length)
return -1; return -1;
} }
else{ else{
index = 0; index = 0;
} }
var imax = this.length; var imax = this.length;
for(; index < imax; index++) { for(; index < imax; index++) {
if (check(this[index], mix)) if (check(this[index], mix))
...@@ -3313,29 +3313,29 @@ ...@@ -3313,29 +3313,29 @@
lastIndexOf: function(mix, index){ lastIndexOf: function(mix, index){
if (mix == null) if (mix == null)
return -1; return -1;
if (index != null) { if (index != null) {
if (index >= this.length) if (index >= this.length)
index = this.length - 1; index = this.length - 1;
if (index < 0) if (index < 0)
return -1; return -1;
} }
else { else {
index = this.length - 1; index = this.length - 1;
} }
for (; index > -1; index--) { for (; index > -1; index--) {
if (check(this[index], mix)) if (check(this[index], mix))
return index; return index;
} }
return -1; return -1;
}, },
map: function(fn){ map: function(fn){
var arr = [], var arr = [],
imax = this.length, imax = this.length,
i = -1; i = -1;
...@@ -3344,7 +3344,7 @@ ...@@ -3344,7 +3344,7 @@
} }
return arr; return arr;
}, },
filter: function(fn, ctx){ filter: function(fn, ctx){
var coll = new this.constructor(), var coll = new this.constructor(),
imax = this.length, imax = this.length,
...@@ -3357,7 +3357,7 @@ ...@@ -3357,7 +3357,7 @@
return coll; return coll;
} }
}; };
// ES6 iterator // ES6 iterator
if (typeof Symbol !== 'undefined' && Symbol.iterator) { if (typeof Symbol !== 'undefined' && Symbol.iterator) {
ArrayProto[Symbol.iterator] = function(){ ArrayProto[Symbol.iterator] = function(){
...@@ -3376,7 +3376,7 @@ ...@@ -3376,7 +3376,7 @@
} }
}; };
} }
function forEach(fn, ctx){ function forEach(fn, ctx){
var imax = this.length, var imax = this.length,
i = -1 i = -1
...@@ -3386,139 +3386,139 @@ ...@@ -3386,139 +3386,139 @@
} }
return this; return this;
} }
return ArrayProto; return ArrayProto;
}()); }());
// end:source ArrayProto.js // end:source ArrayProto.js
function create(Constructor, mix) { function create(Constructor, mix) {
if (mix instanceof Constructor) if (mix instanceof Constructor)
return mix; return mix;
return new Constructor(mix); return new Constructor(mix);
} }
var CollectionProto = { var CollectionProto = {
toArray: function(){ toArray: function(){
var array = new Array(this.length); var array = new Array(this.length);
for (var i = 0, imax = this.length; i < imax; i++){ for (var i = 0, imax = this.length; i < imax; i++){
array[i] = this[i]; array[i] = this[i];
} }
return array; return array;
}, },
toJSON: json_proto_arrayToJSON toJSON: json_proto_arrayToJSON
}; };
function Collection(/* (ClassName, Child, Proto) (Child, Proto) */) { function Collection(/* (ClassName, Child, Proto) (Child, Proto) */) {
var length = arguments.length, var length = arguments.length,
Proto = arguments[length - 1], Proto = arguments[length - 1],
Child = arguments[length - 2], Child = arguments[length - 2],
className className
; ;
if (length > 2) if (length > 2)
className = arguments[0]; className = arguments[0];
Proto._ctor = Child; Proto._ctor = Child;
obj_inherit(Proto, CollectionProto, ArrayProto); obj_inherit(Proto, CollectionProto, ArrayProto);
return className == null return className == null
? Class(Proto) ? Class(Proto)
: Class(className, Proto) : Class(className, Proto)
; ;
} }
return Collection; return Collection;
}()); }());
// end:source /src/collection/Collection.js // end:source /src/collection/Collection.js
// source /src/fn/fn.js // source /src/fn/fn.js
(function(){ (function(){
// source memoize.js // source memoize.js
var fn_memoize, var fn_memoize,
fn_memoizeAsync; fn_memoizeAsync;
(function(){ (function(){
fn_memoize = function(fn) { fn_memoize = function(fn) {
var _cache = {}, var _cache = {},
_args = []; _args = [];
return function() { return function() {
var id = fn_argsId(arguments, _args); var id = fn_argsId(arguments, _args);
return _cache[id] == null return _cache[id] == null
? (_cache[id] = fn_apply(fn, this, arguments)) ? (_cache[id] = fn_apply(fn, this, arguments))
: _cache[id]; : _cache[id];
}; };
}; };
fn_memoizeAsync = function(fn) { fn_memoizeAsync = function(fn) {
var _cache = {}, var _cache = {},
_cacheCbs = {}, _cacheCbs = {},
_args = []; _args = [];
return function(){ return function(){
var args = _Array_slice.call(arguments), var args = _Array_slice.call(arguments),
callback = args.pop(); callback = args.pop();
var id = fn_argsId(args, _args); var id = fn_argsId(args, _args);
if (_cache[id]){ if (_cache[id]){
fn_apply(callback, this, _cache[id]) fn_apply(callback, this, _cache[id])
return; return;
} }
if (_cacheCbs[id]) { if (_cacheCbs[id]) {
_cacheCbs[id].push(callback); _cacheCbs[id].push(callback);
return; return;
} }
_cacheCbs[id] = [callback]; _cacheCbs[id] = [callback];
args = _Array_slice.call(args); args = _Array_slice.call(args);
args.push(fn_resolveDelegate(_cache, _cacheCbs, id)); args.push(fn_resolveDelegate(_cache, _cacheCbs, id));
fn_apply(fn, this, args); fn_apply(fn, this, args);
}; };
}; };
// === private // === private
function fn_resolveDelegate(cache, cbs, id) { function fn_resolveDelegate(cache, cbs, id) {
return function(){ return function(){
cache[id] = arguments; cache[id] = arguments;
for (var i = 0, x, imax = cbs[id].length; i < imax; i++){ for (var i = 0, x, imax = cbs[id].length; i < imax; i++){
x = cbs[id][i]; x = cbs[id][i];
fn_apply(x, this, arguments); fn_apply(x, this, arguments);
} }
cbs[i] = null; cbs[i] = null;
cache = null; cache = null;
cbs = null; cbs = null;
}; };
} }
}()); }());
// end:source memoize.js // end:source memoize.js
Class.Fn = { Class.Fn = {
memoize: fn_memoize, memoize: fn_memoize,
memoizeAsync: fn_memoizeAsync memoizeAsync: fn_memoizeAsync
}; };
}()); }());
// end:source /src/fn/fn.js // end:source /src/fn/fn.js
exports.Class = Class; exports.Class = Class;
})); }));
\ No newline at end of file
...@@ -4,26 +4,26 @@ ...@@ -4,26 +4,26 @@
'use strict'; 'use strict';
var _global, _exports; var _global, _exports;
if (typeof exports !== 'undefined' && (root === exports || root == null)){ if (typeof exports !== 'undefined' && (root === exports || root == null)){
// raw nodejs module // raw nodejs module
_global = _exports = global; _global = _exports = global;
} }
if (_global == null) { if (_global == null) {
_global = typeof window === 'undefined' ? global : window; _global = typeof window === 'undefined' ? global : window;
} }
if (_exports == null) { if (_exports == null) {
_exports = root || _global; _exports = root || _global;
} }
if (typeof include !== 'undefined' && typeof include.js === 'function') { if (typeof include !== 'undefined' && typeof include.js === 'function') {
// allow only one `include` per application // allow only one `include` per application
_exports.include = include; _exports.include = include;
_exports.includeLib = include.Lib || _global.includeLib; _exports.includeLib = include.Lib || _global.includeLib;
return; return;
} }
factory(_global, _exports, _global.document); factory(_global, _exports, _global.document);
}(this, function (global, exports, document) { }(this, function (global, exports, document) {
...@@ -31,8 +31,8 @@ ...@@ -31,8 +31,8 @@
// end:source ../src/head.js // end:source ../src/head.js
// source ../src/1.scope-vars.js // source ../src/1.scope-vars.js
/** /**
* .cfg * .cfg
* : path := root path. @default current working path, im browser window.location; * : path := root path. @default current working path, im browser window.location;
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
* Example "/script/main.js" within this window.location "{domain}/apps/1.html" * Example "/script/main.js" within this window.location "{domain}/apps/1.html"
* will become "{domain}/apps/script/main.js" instead of "{domain}/script/main.js" * will become "{domain}/apps/script/main.js" instead of "{domain}/script/main.js"
*/ */
var bin = { var bin = {
js: {}, js: {},
css: {}, css: {},
...@@ -64,42 +64,42 @@ ...@@ -64,42 +64,42 @@
load: {} load: {}
}, },
__array_slice = Array.prototype.slice, __array_slice = Array.prototype.slice,
XMLHttpRequest = global.XMLHttpRequest; XMLHttpRequest = global.XMLHttpRequest;
// end:source ../src/1.scope-vars.js // end:source ../src/1.scope-vars.js
// source ../src/2.Helper.js // source ../src/2.Helper.js
var Helper = { /** TODO: improve url handling*/ var Helper = { /** TODO: improve url handling*/
reportError: function(e) { reportError: function(e) {
console.error('IncludeJS Error:', e, e.message, e.url); console.error('IncludeJS Error:', e, e.message, e.url);
typeof handler.onerror === 'function' && handler.onerror(e); typeof handler.onerror === 'function' && handler.onerror(e);
} }
}, },
XHR = function(resource, callback) { XHR = function(resource, callback) {
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() { xhr.onreadystatechange = function() {
xhr.readyState === 4 && callback && callback(resource, xhr.responseText); xhr.readyState === 4 && callback && callback(resource, xhr.responseText);
}; };
xhr.open('GET', typeof resource === 'object' ? resource.url : resource, true); xhr.open('GET', typeof resource === 'object' ? resource.url : resource, true);
xhr.send(); xhr.send();
}; };
// end:source ../src/2.Helper.js // end:source ../src/2.Helper.js
// source ../src/utils/fn.js // source ../src/utils/fn.js
function fn_proxy(fn, ctx) { function fn_proxy(fn, ctx) {
return function(){ return function(){
fn.apply(ctx, arguments); fn.apply(ctx, arguments);
}; };
} }
function fn_doNothing(fn) { function fn_doNothing(fn) {
typeof fn === 'function' && fn(); typeof fn === 'function' && fn();
} }
...@@ -109,9 +109,9 @@ ...@@ -109,9 +109,9 @@
obj_getProperty, obj_getProperty,
obj_setProperty obj_setProperty
; ;
(function(){ (function(){
obj_inherit = function(target /* source, ..*/ ) { obj_inherit = function(target /* source, ..*/ ) {
if (typeof target === 'function') { if (typeof target === 'function') {
target = target.prototype; target = target.prototype;
...@@ -120,31 +120,31 @@ ...@@ -120,31 +120,31 @@
imax = arguments.length, imax = arguments.length,
source, key; source, key;
for (; i < imax; i++) { for (; i < imax; i++) {
source = typeof arguments[i] === 'function' source = typeof arguments[i] === 'function'
? arguments[i].prototype ? arguments[i].prototype
: arguments[i]; : arguments[i];
for (key in source) { for (key in source) {
target[key] = source[key]; target[key] = source[key];
} }
} }
return target; return target;
}; };
obj_getProperty = function(obj, property) { obj_getProperty = function(obj, property) {
var chain = property.split('.'), var chain = property.split('.'),
length = chain.length, length = chain.length,
i = 0; i = 0;
for (; i < length; i++) { for (; i < length; i++) {
if (obj == null) if (obj == null)
return null; return null;
obj = obj[chain[i]]; obj = obj[chain[i]];
} }
return obj; return obj;
}; };
obj_setProperty = function(obj, property, value) { obj_setProperty = function(obj, property, value) {
var chain = property.split('.'), var chain = property.split('.'),
imax = chain.length - 1, imax = chain.length - 1,
...@@ -152,24 +152,24 @@ ...@@ -152,24 +152,24 @@
key; key;
while ( ++i < imax ) { while ( ++i < imax ) {
key = chain[i]; key = chain[i];
if (obj[key] == null) if (obj[key] == null)
obj[key] = {}; obj[key] = {};
obj = obj[key]; obj = obj[key];
} }
obj[chain[i]] = value; obj[chain[i]] = value;
}; };
}()); }());
// end:source ../src/utils/object.js // end:source ../src/utils/object.js
// source ../src/utils/array.js // source ../src/utils/array.js
function arr_invoke(arr, args, ctx) { function arr_invoke(arr, args, ctx) {
if (arr == null || arr instanceof Array === false) { if (arr == null || arr instanceof Array === false) {
return; return;
} }
for (var i = 0, length = arr.length; i < length; i++) { for (var i = 0, length = arr.length; i < length; i++) {
if (typeof arr[i] !== 'function') { if (typeof arr[i] !== 'function') {
continue; continue;
...@@ -180,9 +180,9 @@ ...@@ -180,9 +180,9 @@
arr[i].apply(ctx, args); arr[i].apply(ctx, args);
} }
} }
} }
function arr_ensure(obj, xpath) { function arr_ensure(obj, xpath) {
if (!xpath) { if (!xpath) {
return obj; return obj;
...@@ -191,12 +191,12 @@ ...@@ -191,12 +191,12 @@
imax = arr.length - 1, imax = arr.length - 1,
i = 0, i = 0,
key; key;
for (; i < imax; i++) { for (; i < imax; i++) {
key = arr[i]; key = arr[i];
obj = obj[key] || (obj[key] = {}); obj = obj[key] || (obj[key] = {});
} }
key = arr[imax]; key = arr[imax];
return obj[key] || (obj[key] = []); return obj[key] || (obj[key] = []);
} }
...@@ -212,63 +212,63 @@ ...@@ -212,63 +212,63 @@
path_combine, path_combine,
path_isRelative path_isRelative
; ;
(function(){ (function(){
path_getDir = function(path) { path_getDir = function(path) {
return path.substring(0, path.lastIndexOf('/') + 1); return path.substring(0, path.lastIndexOf('/') + 1);
}; };
path_getFile = function(path) { path_getFile = function(path) {
path = path path = path
.replace('file://', '') .replace('file://', '')
.replace(/\\/g, '/') .replace(/\\/g, '/')
.replace(/\?[^\n]+$/, ''); .replace(/\?[^\n]+$/, '');
if (/^\/\w+:\/[^\/]/i.test(path)){ if (/^\/\w+:\/[^\/]/i.test(path)){
// win32 drive // win32 drive
return path.substring(1); return path.substring(1);
} }
return path; return path;
}; };
path_getExtension = function(path) { path_getExtension = function(path) {
var query = path.indexOf('?'); var query = path.indexOf('?');
if (query === -1) { if (query === -1) {
return path.substring(path.lastIndexOf('.') + 1); return path.substring(path.lastIndexOf('.') + 1);
} }
return path.substring(path.lastIndexOf('.', query) + 1, query); return path.substring(path.lastIndexOf('.', query) + 1, query);
}; };
path_resolveCurrent = function() { path_resolveCurrent = function() {
if (document == null) { if (document == null) {
return typeof module === 'undefined' return typeof module === 'undefined'
? '' ? ''
: path_win32Normalize(module.parent.filename); : path_win32Normalize(module.parent.filename);
} }
var scripts = document.getElementsByTagName('script'), var scripts = document.getElementsByTagName('script'),
last = scripts[scripts.length - 1], last = scripts[scripts.length - 1],
url = last && last.getAttribute('src') || ''; url = last && last.getAttribute('src') || '';
if (url[0] === '/') { if (url[0] === '/') {
return url; return url;
} }
var location = window var location = window
.location .location
.pathname .pathname
.replace(/\/[^\/]+\.\w+$/, ''); .replace(/\/[^\/]+\.\w+$/, '');
if (location[location.length - 1] !== '/') { if (location[location.length - 1] !== '/') {
location += '/'; location += '/';
} }
return location + url; return location + url;
}; };
path_normalize = function(path) { path_normalize = function(path) {
return path return path
.replace(/\\/g, '/') .replace(/\\/g, '/')
...@@ -276,31 +276,31 @@ ...@@ -276,31 +276,31 @@
.replace(/([^:\/])\/{2,}/g, '$1/') .replace(/([^:\/])\/{2,}/g, '$1/')
; ;
}; };
path_win32Normalize = function(path){ path_win32Normalize = function(path){
path = path_normalize(path); path = path_normalize(path);
if (path.substring(0, 5) === 'file:') if (path.substring(0, 5) === 'file:')
return path; return path;
return 'file:///' + path; return 'file:///' + path;
}; };
path_resolveUrl = function(url, parent) { path_resolveUrl = function(url, parent) {
if (reg_hasProtocol.test(url)) if (reg_hasProtocol.test(url))
return path_collapse(url); return path_collapse(url);
if (url.substring(0, 2) === './') if (url.substring(0, 2) === './')
url = url.substring(2); url = url.substring(2);
if (url[0] === '/' && parent != null && parent.base != null) { if (url[0] === '/' && parent != null && parent.base != null) {
url = path_combine(parent.base, url); url = path_combine(parent.base, url);
if (reg_hasProtocol.test(url)) if (reg_hasProtocol.test(url))
return path_collapse(url); return path_collapse(url);
} }
if (url[0] === '/' && cfg.path) { if (url[0] === '/' && cfg.path) {
url = cfg.path + url.substring(1); url = cfg.path + url.substring(1);
if (reg_hasProtocol.test(url)) if (reg_hasProtocol.test(url))
return path_collapse(url); return path_collapse(url);
} }
if (url[0] === '/') { if (url[0] === '/') {
...@@ -310,13 +310,13 @@ ...@@ -310,13 +310,13 @@
} else if (parent != null && parent.location != null) { } else if (parent != null && parent.location != null) {
url = parent.location + url; url = parent.location + url;
} }
return path_collapse(url); return path_collapse(url);
}; };
path_isRelative = function(path) { path_isRelative = function(path) {
var c = path.charCodeAt(0); var c = path.charCodeAt(0);
switch (c) { switch (c) {
case 47: case 47:
// / // /
...@@ -327,10 +327,10 @@ ...@@ -327,10 +327,10 @@
// h // h
return reg_hasProtocol.test(path) === false; return reg_hasProtocol.test(path) === false;
} }
return true; return true;
}; };
path_combine = function() { path_combine = function() {
var out = '', var out = '',
imax = arguments.length, imax = arguments.length,
...@@ -339,96 +339,96 @@ ...@@ -339,96 +339,96 @@
; ;
while ( ++i < imax ){ while ( ++i < imax ){
x = arguments[i]; x = arguments[i];
if (!x) if (!x)
continue; continue;
x = path_normalize(x); x = path_normalize(x);
if (out === '') { if (out === '') {
out = x; out = x;
continue; continue;
} }
if (out[out.length - 1] !== '/') if (out[out.length - 1] !== '/')
out += '/' out += '/'
if (x[0] === '/') if (x[0] === '/')
x = x.substring(1); x = x.substring(1);
out += x; out += x;
} }
return out; return out;
}; };
function path_collapse(url) { function path_collapse(url) {
while (url.indexOf('../') !== -1) { while (url.indexOf('../') !== -1) {
url = url.replace(reg_subFolder, ''); url = url.replace(reg_subFolder, '');
} }
return url.replace(/\/\.\//g, '/'); return url.replace(/\/\.\//g, '/');
} }
}()); }());
// end:source ../src/utils/path.js // end:source ../src/utils/path.js
// source ../src/utils/tree.js // source ../src/utils/tree.js
var tree_resolveUsage; var tree_resolveUsage;
(function(){ (function(){
tree_resolveUsage = function(resource, usage, next){ tree_resolveUsage = function(resource, usage, next){
var use = [], var use = [],
imax = usage.length, imax = usage.length,
i = -1, i = -1,
obj, path, name, index, parent obj, path, name, index, parent
; ;
while( ++i < imax ) { while( ++i < imax ) {
name = path = usage[i]; name = path = usage[i];
index = path.indexOf('.'); index = path.indexOf('.');
if ( index !== -1) { if ( index !== -1) {
name = path.substring(0, index); name = path.substring(0, index);
path = path.substring(index + 1); path = path.substring(index + 1);
} }
parent = use_resolveParent(name, resource.parent, resource); parent = use_resolveParent(name, resource.parent, resource);
if (parent == null) if (parent == null)
return null; return null;
if (parent.state !== 4){ if (parent.state !== 4){
resource.state = 3; resource.state = 3;
parent.on(4, next, parent, 'push'); parent.on(4, next, parent, 'push');
return null; return null;
} }
obj = parent.exports; obj = parent.exports;
if (name !== path) if (name !== path)
obj = obj_getProperty(obj, path); obj = obj_getProperty(obj, path);
// if DEBUG // if DEBUG
(typeof obj === 'object' && obj == null) (typeof obj === 'object' && obj == null)
&& console.warn('<include:use> Used resource has no exports', name, resource.url); && console.warn('<include:use> Used resource has no exports', name, resource.url);
// endif // endif
use[i] = obj; use[i] = obj;
} }
return use; return use;
}; };
function use_resolveParent(name, resource, initiator){ function use_resolveParent(name, resource, initiator){
if (resource == null) { if (resource == null) {
// if DEBUG // if DEBUG
console.warn('<include> Usage Not Found:', name); console.warn('<include> Usage Not Found:', name);
console.warn('- Ensure to have it included before with the correct alias') console.warn('- Ensure to have it included before with the correct alias')
console.warn('- Initiator Stacktrace:'); console.warn('- Initiator Stacktrace:');
var arr = [], res = initiator; var arr = [], res = initiator;
while(res != null){ while(res != null){
arr.push(res.url); arr.push(res.url);
...@@ -436,61 +436,61 @@ ...@@ -436,61 +436,61 @@
} }
console.warn(arr.join('\n')); console.warn(arr.join('\n'));
// endif // endif
return null; return null;
} }
var includes = resource.includes, var includes = resource.includes,
i = -1, i = -1,
imax = includes.length, imax = includes.length,
include, exports, alias include, exports, alias
; ;
while( ++i < imax ) { while( ++i < imax ) {
include = includes[i]; include = includes[i];
alias = include.route.alias || Routes.parseAlias(include.route); alias = include.route.alias || Routes.parseAlias(include.route);
if (alias === name) if (alias === name)
return include.resource; return include.resource;
} }
return use_resolveParent(name, resource.parent, initiator); return use_resolveParent(name, resource.parent, initiator);
} }
}()); }());
// end:source ../src/utils/tree.js // end:source ../src/utils/tree.js
// source ../src/2.Routing.js // source ../src/2.Routing.js
var RoutesLib = function() { var RoutesLib = function() {
var routes = {}, var routes = {},
regexpAlias = /([^\\\/]+)\.\w+$/; regexpAlias = /([^\\\/]+)\.\w+$/;
return { return {
/** /**
* @param route {String} = Example: '.reference/libjs/{0}/{1}.js' * @param route {String} = Example: '.reference/libjs/{0}/{1}.js'
*/ */
register: function(namespace, route, currentInclude) { register: function(namespace, route, currentInclude) {
if (typeof route === 'string' && path_isRelative(route)) { if (typeof route === 'string' && path_isRelative(route)) {
var res = currentInclude || include, var res = currentInclude || include,
location = res.location || path_getDir(res.url || path_resolveCurrent()); location = res.location || path_getDir(res.url || path_resolveCurrent());
if (path_isRelative(location)) { if (path_isRelative(location)) {
location = '/' + location; location = '/' + location;
} }
route = location + route; route = location + route;
} }
routes[namespace] = route instanceof Array ? route : route.split(/[\{\}]/g); routes[namespace] = route instanceof Array ? route : route.split(/[\{\}]/g);
}, },
/** /**
* @param {String} template = Example: 'scroller/scroller.min?ui=black' * @param {String} template = Example: 'scroller/scroller.min?ui=black'
*/ */
...@@ -505,28 +505,28 @@ ...@@ -505,28 +505,28 @@
x, x,
length, length,
arr; arr;
if (aliasIndex !== -1){ if (aliasIndex !== -1){
alias = template.substring(aliasIndex + 2); alias = template.substring(aliasIndex + 2);
template = template.substring(0, aliasIndex); template = template.substring(0, aliasIndex);
} }
if (questionMark !== -1) { if (questionMark !== -1) {
arr = template.substring(questionMark + 1).split('&'); arr = template.substring(questionMark + 1).split('&');
params = {}; params = {};
for (i = 0, length = arr.length; i < length; i++) { for (i = 0, length = arr.length; i < length; i++) {
x = arr[i].split('='); x = arr[i].split('=');
params[x[0]] = x[1]; params[x[0]] = x[1];
} }
template = template.substring(0, questionMark); template = template.substring(0, questionMark);
} }
template = template.split('/'); template = template.split('/');
route = routes[namespace]; route = routes[namespace];
if (route == null){ if (route == null){
return { return {
path: template.join('/'), path: template.join('/'),
...@@ -534,25 +534,25 @@ ...@@ -534,25 +534,25 @@
alias: alias alias: alias
}; };
} }
path = route[0]; path = route[0];
for (i = 1; i < route.length; i++) { for (i = 1; i < route.length; i++) {
if (i % 2 === 0) { if (i % 2 === 0) {
path += route[i]; path += route[i];
} else { } else {
/** if template provides less "breadcrumbs" than needed - /** if template provides less "breadcrumbs" than needed -
* take always the last one for failed peaces */ * take always the last one for failed peaces */
var index = route[i] << 0; var index = route[i] << 0;
if (index > template.length - 1) { if (index > template.length - 1) {
index = template.length - 1; index = template.length - 1;
} }
path += template[index]; path += template[index];
if (i === route.length - 2){ if (i === route.length - 2){
for(index++; index < template.length; index++){ for(index++; index < template.length; index++){
path += '/' + template[index]; path += '/' + template[index];
...@@ -560,14 +560,14 @@ ...@@ -560,14 +560,14 @@
} }
} }
} }
return { return {
path: path, path: path,
params: params, params: params,
alias: alias alias: alias
}; };
}, },
/** /**
* @arg includeData : * @arg includeData :
* 1. string - URL to resource * 1. string - URL to resource
...@@ -584,11 +584,11 @@ ...@@ -584,11 +584,11 @@
*/ */
each: function(type, includeData, fn, namespace, xpath) { each: function(type, includeData, fn, namespace, xpath) {
var key; var key;
if (includeData == null) { if (includeData == null) {
return; return;
} }
if (type === 'lazy' && xpath == null) { if (type === 'lazy' && xpath == null) {
for (key in includeData) { for (key in includeData) {
this.each(type, includeData[key], fn, null, key); this.each(type, includeData[key], fn, null, key);
...@@ -609,49 +609,49 @@ ...@@ -609,49 +609,49 @@
} }
return; return;
} }
if (typeof includeData === 'string') { if (typeof includeData === 'string') {
var x = this.resolve(namespace, includeData); var x = this.resolve(namespace, includeData);
if (namespace){ if (namespace){
namespace += '.' + includeData; namespace += '.' + includeData;
} }
fn(namespace, x, xpath); fn(namespace, x, xpath);
return; return;
} }
console.error('Include Package is invalid', arguments); console.error('Include Package is invalid', arguments);
}, },
getRoutes: function(){ getRoutes: function(){
return routes; return routes;
}, },
parseAlias: function(route){ parseAlias: function(route){
var path = route.path, var path = route.path,
result = regexpAlias.exec(path); result = regexpAlias.exec(path);
return result && result[1]; return result && result[1];
} }
}; };
}; };
var Routes = RoutesLib(); var Routes = RoutesLib();
/*{test} /*{test}
console.log(JSON.stringify(Routes.resolve(null,'scroller.js::Scroller'))); console.log(JSON.stringify(Routes.resolve(null,'scroller.js::Scroller')));
Routes.register('lib', '.reference/libjs/{0}/lib/{1}.js'); Routes.register('lib', '.reference/libjs/{0}/lib/{1}.js');
console.log(JSON.stringify(Routes.resolve('lib','scroller::Scroller'))); console.log(JSON.stringify(Routes.resolve('lib','scroller::Scroller')));
console.log(JSON.stringify(Routes.resolve('lib','scroller/scroller.mobile?ui=black'))); console.log(JSON.stringify(Routes.resolve('lib','scroller/scroller.mobile?ui=black')));
Routes.register('framework', '.reference/libjs/framework/{0}.js'); Routes.register('framework', '.reference/libjs/framework/{0}.js');
console.log(JSON.stringify(Routes.resolve('framework','dom/jquery'))); console.log(JSON.stringify(Routes.resolve('framework','dom/jquery')));
*/ */
// end:source ../src/2.Routing.js // end:source ../src/2.Routing.js
// source ../src/3.Events.js // source ../src/3.Events.js
...@@ -663,20 +663,20 @@ ...@@ -663,20 +663,20 @@
}; };
} }
var readycollection = []; var readycollection = [];
function onReady() { function onReady() {
Events.ready = fn_doNothing; Events.ready = fn_doNothing;
if (readycollection == null) { if (readycollection == null) {
return; return;
} }
arr_invoke(readycollection); arr_invoke(readycollection);
readycollection = null; readycollection = null;
} }
/** TODO: clean this */ /** TODO: clean this */
if ('onreadystatechange' in document) { if ('onreadystatechange' in document) {
document.onreadystatechange = function() { document.onreadystatechange = function() {
if (/complete|interactive/g.test(document.readyState) === false) { if (/complete|interactive/g.test(document.readyState) === false) {
...@@ -689,294 +689,294 @@ ...@@ -689,294 +689,294 @@
}else { }else {
window.onload = onReady; window.onload = onReady;
} }
return { return {
ready: function(callback) { ready: function(callback) {
readycollection.unshift(callback); readycollection.unshift(callback);
} }
}; };
})(document); })(document);
// end:source ../src/3.Events.js // end:source ../src/3.Events.js
// source ../src/6.ScriptStack.js // source ../src/6.ScriptStack.js
/** @TODO Refactor loadBy* {combine logic} */ /** @TODO Refactor loadBy* {combine logic} */
var ScriptStack = (function() { var ScriptStack = (function() {
var head, var head,
currentResource, currentResource,
stack = [], stack = [],
_cb_complete = [], _cb_complete = [],
_paused; _paused;
function loadScript(url, callback) { function loadScript(url, callback) {
//console.log('load script', url); //console.log('load script', url);
var tag = document.createElement('script'); var tag = document.createElement('script');
tag.type = 'text/javascript'; tag.type = 'text/javascript';
tag.src = url; tag.src = url;
if ('onreadystatechange' in tag) { if ('onreadystatechange' in tag) {
tag.onreadystatechange = function() { tag.onreadystatechange = function() {
(this.readyState === 'complete' || this.readyState === 'loaded') && callback(); (this.readyState === 'complete' || this.readyState === 'loaded') && callback();
}; };
} else { } else {
tag.onload = tag.onerror = callback; tag.onload = tag.onerror = callback;
} }
;(head || (head = document.getElementsByTagName('head')[0])).appendChild(tag); ;(head || (head = document.getElementsByTagName('head')[0])).appendChild(tag);
} }
function loadByEmbedding() { function loadByEmbedding() {
if (_paused) { if (_paused) {
return; return;
} }
if (stack.length === 0){ if (stack.length === 0){
trigger_complete(); trigger_complete();
return; return;
} }
if (currentResource != null) { if (currentResource != null) {
return; return;
} }
var resource = (currentResource = stack[0]); var resource = (currentResource = stack[0]);
if (resource.state === 1) { if (resource.state === 1) {
return; return;
} }
resource.state = 1; resource.state = 1;
global.include = resource; global.include = resource;
global.iparams = resource.route.params; global.iparams = resource.route.params;
function resourceLoaded(e) { function resourceLoaded(e) {
if (e && e.type === 'error') { if (e && e.type === 'error') {
console.log('Script Loaded Error', resource.url); console.log('Script Loaded Error', resource.url);
} }
var i = 0, var i = 0,
length = stack.length; length = stack.length;
for (; i < length; i++) { for (; i < length; i++) {
if (stack[i] === resource) { if (stack[i] === resource) {
stack.splice(i, 1); stack.splice(i, 1);
break; break;
} }
} }
if (i === length) { if (i === length) {
console.error('Loaded Resource not found in stack', resource); console.error('Loaded Resource not found in stack', resource);
return; return;
} }
if (resource.state !== 2.5) if (resource.state !== 2.5)
resource.readystatechanged(3); resource.readystatechanged(3);
currentResource = null; currentResource = null;
loadByEmbedding(); loadByEmbedding();
} }
if (resource.source) { if (resource.source) {
__eval(resource.source, resource); __eval(resource.source, resource);
resourceLoaded(); resourceLoaded();
return; return;
} }
loadScript(resource.url, resourceLoaded); loadScript(resource.url, resourceLoaded);
} }
function processByEval() { function processByEval() {
if (_paused) { if (_paused) {
return; return;
} }
if (stack.length === 0){ if (stack.length === 0){
trigger_complete(); trigger_complete();
return; return;
} }
if (currentResource != null) { if (currentResource != null) {
return; return;
} }
var resource = stack[0]; var resource = stack[0];
if (resource.state < 2) { if (resource.state < 2) {
return; return;
} }
currentResource = resource; currentResource = resource;
resource.state = 1; resource.state = 1;
global.include = resource; global.include = resource;
//console.log('evaling', resource.url, stack.length); //console.log('evaling', resource.url, stack.length);
__eval(resource.source, resource); __eval(resource.source, resource);
for (var i = 0, x, length = stack.length; i < length; i++) { for (var i = 0, x, length = stack.length; i < length; i++) {
x = stack[i]; x = stack[i];
if (x === resource) { if (x === resource) {
stack.splice(i, 1); stack.splice(i, 1);
break; break;
} }
} }
if (resource.state !== 2.5) if (resource.state !== 2.5)
resource.readystatechanged(3); resource.readystatechanged(3);
currentResource = null; currentResource = null;
processByEval(); processByEval();
} }
function trigger_complete() { function trigger_complete() {
var i = -1, var i = -1,
imax = _cb_complete.length; imax = _cb_complete.length;
while (++i < imax) { while (++i < imax) {
_cb_complete[i](); _cb_complete[i]();
} }
_cb_complete.length = 0; _cb_complete.length = 0;
} }
return { return {
load: function(resource, parent, forceEmbed) { load: function(resource, parent, forceEmbed) {
this.add(resource, parent); this.add(resource, parent);
if (!cfg.eval || forceEmbed) { if (!cfg.eval || forceEmbed) {
loadByEmbedding(); loadByEmbedding();
return; return;
} }
// was already loaded, with custom loader for example // was already loaded, with custom loader for example
if (resource.source) { if (resource.source) {
resource.state = 2; resource.state = 2;
processByEval(); processByEval();
return; return;
} }
XHR(resource, function(resource, response) { XHR(resource, function(resource, response) {
if (!response) { if (!response) {
console.error('Not Loaded:', resource.url); console.error('Not Loaded:', resource.url);
console.error('- Initiator:', resource.parent && resource.parent.url || '<root resource>'); console.error('- Initiator:', resource.parent && resource.parent.url || '<root resource>');
} }
resource.source = response; resource.source = response;
resource.state = 2; resource.state = 2;
processByEval(); processByEval();
}); });
}, },
add: function(resource, parent){ add: function(resource, parent){
if (resource.priority === 1) if (resource.priority === 1)
return stack.unshift(resource); return stack.unshift(resource);
if (parent == null) if (parent == null)
return stack.push(resource); return stack.push(resource);
var imax = stack.length, var imax = stack.length,
i = -1 i = -1
; ;
// move close to parent // move close to parent
while( ++i < imax){ while( ++i < imax){
if (stack[i] === parent) if (stack[i] === parent)
return stack.splice(i, 0, resource); return stack.splice(i, 0, resource);
} }
// was still not added // was still not added
stack.push(resource); stack.push(resource);
}, },
/* Move resource in stack close to parent */ /* Move resource in stack close to parent */
moveToParent: function(resource, parent) { moveToParent: function(resource, parent) {
var length = stack.length, var length = stack.length,
parentIndex = -1, parentIndex = -1,
resourceIndex = -1, resourceIndex = -1,
i; i;
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
if (stack[i] === resource) { if (stack[i] === resource) {
resourceIndex = i; resourceIndex = i;
break; break;
} }
} }
if (resourceIndex === -1) { if (resourceIndex === -1) {
return; return;
} }
for (i= 0; i < length; i++) { for (i= 0; i < length; i++) {
if (stack[i] === parent) { if (stack[i] === parent) {
parentIndex = i; parentIndex = i;
break; break;
} }
} }
if (parentIndex === -1) { if (parentIndex === -1) {
return; return;
} }
if (resourceIndex < parentIndex) { if (resourceIndex < parentIndex) {
return; return;
} }
stack.splice(resourceIndex, 1); stack.splice(resourceIndex, 1);
stack.splice(parentIndex, 0, resource); stack.splice(parentIndex, 0, resource);
}, },
pause: function(){ pause: function(){
_paused = true; _paused = true;
}, },
resume: function(){ resume: function(){
_paused = false; _paused = false;
if (currentResource != null) if (currentResource != null)
return; return;
this.touch(); this.touch();
}, },
touch: function(){ touch: function(){
var fn = cfg.eval var fn = cfg.eval
? processByEval ? processByEval
: loadByEmbedding : loadByEmbedding
; ;
fn(); fn();
}, },
complete: function(callback){ complete: function(callback){
if (_paused !== true && stack.length === 0) { if (_paused !== true && stack.length === 0) {
callback(); callback();
return; return;
} }
_cb_complete.push(callback); _cb_complete.push(callback);
} }
}; };
})(); })();
// end:source ../src/6.ScriptStack.js // end:source ../src/6.ScriptStack.js
// source ../src/4.IncludeDeferred.js // source ../src/4.IncludeDeferred.js
/** /**
* STATES: * STATES:
* 0: Resource Created * 0: Resource Created
...@@ -986,30 +986,30 @@ ...@@ -986,30 +986,30 @@
* 3: Evaluated - Childs Loading * 3: Evaluated - Childs Loading
* 4: Childs Loaded - Completed * 4: Childs Loaded - Completed
*/ */
var IncludeDeferred = function() { var IncludeDeferred = function() {
this.callbacks = []; this.callbacks = [];
this.state = -1; this.state = -1;
}; };
IncludeDeferred.prototype = { /** state observer */ IncludeDeferred.prototype = { /** state observer */
on: function(state, callback, sender, mutator) { on: function(state, callback, sender, mutator) {
if (this === sender && this.state === -1) { if (this === sender && this.state === -1) {
callback(this); callback(this);
return this; return this;
} }
// this === sender in case when script loads additional // this === sender in case when script loads additional
// resources and there are already parents listeners // resources and there are already parents listeners
if (mutator == null) { if (mutator == null) {
mutator = (this.state < 3 || this === sender) mutator = (this.state < 3 || this === sender)
? 'unshift' ? 'unshift'
: 'push' : 'push'
; ;
} }
state <= this.state ? callback(this) : this.callbacks[mutator]({ state <= this.state ? callback(this) : this.callbacks[mutator]({
state: state, state: state,
callback: callback callback: callback
...@@ -1017,16 +1017,16 @@ ...@@ -1017,16 +1017,16 @@
return this; return this;
}, },
readystatechanged: function(state) { readystatechanged: function(state) {
var i, length, x, currentInclude; var i, length, x, currentInclude;
if (state > this.state) { if (state > this.state) {
this.state = state; this.state = state;
} }
if (this.state === 3) { if (this.state === 3) {
var includes = this.includes; var includes = this.includes;
if (includes != null && includes.length) { if (includes != null && includes.length) {
for (i = 0; i < includes.length; i++) { for (i = 0; i < includes.length; i++) {
if (includes[i].resource.state !== 4) { if (includes[i].resource.state !== 4) {
...@@ -1034,33 +1034,33 @@ ...@@ -1034,33 +1034,33 @@
} }
} }
} }
this.state = 4; this.state = 4;
} }
i = 0; i = 0;
length = this.callbacks.length; length = this.callbacks.length;
if (length === 0){ if (length === 0){
return; return;
} }
//do not set asset resource to global //do not set asset resource to global
if (this.type === 'js' && this.state === 4) { if (this.type === 'js' && this.state === 4) {
currentInclude = global.include; currentInclude = global.include;
global.include = this; global.include = this;
} }
for (; i < length; i++) { for (; i < length; i++) {
x = this.callbacks[i]; x = this.callbacks[i];
if (x == null || x.state > this.state) { if (x == null || x.state > this.state) {
continue; continue;
} }
this.callbacks.splice(i,1); this.callbacks.splice(i,1);
length--; length--;
i--; i--;
/* if (!DEBUG) /* if (!DEBUG)
try { try {
*/ */
...@@ -1070,19 +1070,19 @@ ...@@ -1070,19 +1070,19 @@
console.error(error.toString(), 'file:', this.url); console.error(error.toString(), 'file:', this.url);
} }
*/ */
if (this.state < 4){ if (this.state < 4){
break; break;
} }
} }
if (currentInclude != null){ if (currentInclude != null){
global.include = currentInclude; global.include = currentInclude;
} }
}, },
/** assets loaded and DomContentLoaded */ /** assets loaded and DomContentLoaded */
ready: function(callback) { ready: function(callback) {
var that = this; var that = this;
return this.on(4, function() { return this.on(4, function() {
...@@ -1091,7 +1091,7 @@ ...@@ -1091,7 +1091,7 @@
}); });
}, this); }, this);
}, },
/** assets loaded */ /** assets loaded */
done: function(callback) { done: function(callback) {
var that = this; var that = this;
...@@ -1105,33 +1105,33 @@ ...@@ -1105,33 +1105,33 @@
? 0 ? 0
: includes.length : includes.length
; ;
if (length > 0 && this.response == null){ if (length > 0 && this.response == null){
this.response = {}; this.response = {};
var resource, var resource,
route; route;
for(var i = 0, x; i < length; i++){ for(var i = 0, x; i < length; i++){
x = includes[i]; x = includes[i];
resource = x.resource; resource = x.resource;
route = x.route; route = x.route;
if (typeof resource.exports === 'undefined') if (typeof resource.exports === 'undefined')
continue; continue;
var type = resource.type; var type = resource.type;
switch (type) { switch (type) {
case 'js': case 'js':
case 'load': case 'load':
case 'ajax': case 'ajax':
var alias = route.alias || Routes.parseAlias(route), var alias = route.alias || Routes.parseAlias(route),
obj = type === 'js' obj = type === 'js'
? (this.response) ? (this.response)
: (this.response[type] || (this.response[type] = {})) : (this.response[type] || (this.response[type] = {}))
; ;
if (alias != null) { if (alias != null) {
obj_setProperty(obj, alias, resource.exports); obj_setProperty(obj, alias, resource.exports);
break; break;
...@@ -1140,8 +1140,8 @@ ...@@ -1140,8 +1140,8 @@
break; break;
} }
} }
} }
var response = this.response || emptyResponse; var response = this.response || emptyResponse;
var that = this; var that = this;
if (this._use == null && this._usage != null){ if (this._use == null && this._usage != null){
...@@ -1157,41 +1157,41 @@ ...@@ -1157,41 +1157,41 @@
callback.apply(null, [response].concat(this._use)); callback.apply(null, [response].concat(this._use));
return; return;
} }
callback(response); callback(response);
} }
}; };
// end:source ../src/4.IncludeDeferred.js // end:source ../src/4.IncludeDeferred.js
// source ../src/5.Include.js // source ../src/5.Include.js
var Include, var Include,
IncludeLib = {}; IncludeLib = {};
(function(IncludeDeferred) { (function(IncludeDeferred) {
Include = function() { Include = function() {
IncludeDeferred.call(this); IncludeDeferred.call(this);
}; };
stub_release(Include.prototype); stub_release(Include.prototype);
obj_inherit(Include, IncludeDeferred, { obj_inherit(Include, IncludeDeferred, {
// Array: exports // Array: exports
_use: null, _use: null,
// Array: names // Array: names
_usage: null, _usage: null,
isBrowser: true, isBrowser: true,
isNode: false, isNode: false,
setCurrent: function(data) { setCurrent: function(data) {
var url = data.url, var url = data.url,
resource = this.getResourceById(url, 'js'); resource = this.getResourceById(url, 'js');
if (resource == null) { if (resource == null) {
if (url[0] === '/' && this.base) if (url[0] === '/' && this.base)
url = this.base + url.substring(1); url = this.base + url.substring(1);
var resource = new Resource( var resource = new Resource(
'js' 'js'
, { path: url } , { path: url }
...@@ -1203,19 +1203,19 @@ ...@@ -1203,19 +1203,19 @@
if (resource.state < 3) { if (resource.state < 3) {
console.error("<include> Resource should be loaded", data); console.error("<include> Resource should be loaded", data);
} }
/**@TODO - probably state shoulb be changed to 2 at this place */ /**@TODO - probably state shoulb be changed to 2 at this place */
resource.state = 3; resource.state = 3;
global.include = resource; global.include = resource;
}, },
cfg: function(arg) { cfg: function(arg) {
switch (typeof arg) { switch (typeof arg) {
case 'object': case 'object':
var key, value; var key, value;
for (key in arg) { for (key in arg) {
value = arg[key]; value = arg[key];
switch(key){ switch(key){
case 'loader': case 'loader':
for(var x in value){ for(var x in value){
...@@ -1231,7 +1231,7 @@ ...@@ -1231,7 +1231,7 @@
cfg[key] = value; cfg[key] = value;
break; break;
} }
} }
break; break;
case 'string': case 'string':
...@@ -1251,12 +1251,12 @@ ...@@ -1251,12 +1251,12 @@
if (mix == null) { if (mix == null) {
return Routes.getRoutes(); return Routes.getRoutes();
} }
if (arguments.length === 2) { if (arguments.length === 2) {
Routes.register(mix, arguments[1], this); Routes.register(mix, arguments[1], this);
return this; return this;
} }
for (var key in mix) { for (var key in mix) {
Routes.register(key, mix[key], this); Routes.register(key, mix[key], this);
} }
...@@ -1273,36 +1273,36 @@ ...@@ -1273,36 +1273,36 @@
}, },
/** @TODO - `id` property seems to be unsed and always equal to `url` */ /** @TODO - `id` property seems to be unsed and always equal to `url` */
register: function(_bin) { register: function(_bin) {
var base = this.base, var base = this.base,
key, key,
info, info,
infos, infos,
imax, imax,
i; i;
function transform(info){ function transform(info){
if (base == null) if (base == null)
return info; return info;
if (info.url[0] === '/') if (info.url[0] === '/')
info.url = base + info.url.substring(1); info.url = base + info.url.substring(1);
if (info.parent[0] === '/') if (info.parent[0] === '/')
info.parent = base + info.parent.substring(1); info.parent = base + info.parent.substring(1);
info.id = info.url; info.id = info.url;
return info; return info;
} }
for (key in _bin) { for (key in _bin) {
infos = _bin[key]; infos = _bin[key];
imax = infos.length; imax = infos.length;
i = -1; i = -1;
while ( ++i < imax ) { while ( ++i < imax ) {
info = transform(infos[i]); info = transform(infos[i]);
var id = info.id, var id = info.id,
url = info.url, url = info.url,
namespace = info.namespace, namespace = info.namespace,
...@@ -1310,17 +1310,17 @@ ...@@ -1310,17 +1310,17 @@
resource = new Resource(), resource = new Resource(),
state = info.state state = info.state
; ;
if (! (id || url)) if (! (id || url))
continue; continue;
if (url) { if (url) {
if (url[0] === '/') { if (url[0] === '/') {
url = url.substring(1); url = url.substring(1);
} }
resource.location = path_getDir(url); resource.location = path_getDir(url);
} }
resource.state = state == null resource.state = state == null
? (key === 'js' ? 3 : 4) ? (key === 'js' ? 3 : 4)
: state : state
...@@ -1330,7 +1330,7 @@ ...@@ -1330,7 +1330,7 @@
resource.url = url || id; resource.url = url || id;
resource.parent = parent; resource.parent = parent;
resource.base = parent && parent.base || base; resource.base = parent && parent.base || base;
switch (key) { switch (key) {
case 'load': case 'load':
case 'lazy': case 'lazy':
...@@ -1341,13 +1341,13 @@ ...@@ -1341,13 +1341,13 @@
} }
resource.exports = container.innerHTML; resource.exports = container.innerHTML;
if (CustomLoader.exists(resource)){ if (CustomLoader.exists(resource)){
resource.state = 3; resource.state = 3;
CustomLoader.load(resource, CustomLoader_onComplete); CustomLoader.load(resource, CustomLoader_onComplete);
} }
break; break;
} }
// //
(bin[key] || (bin[key] = {}))[id] = resource; (bin[key] || (bin[key] = {}))[id] = resource;
} }
...@@ -1366,42 +1366,42 @@ ...@@ -1366,42 +1366,42 @@
if (url == null) { if (url == null) {
resource = new Include(); resource = new Include();
resource.state = 4; resource.state = 4;
return resource; return resource;
} }
resource = new Resource(); resource = new Resource();
resource.state = 4; resource.state = 4;
resource.location = path_getDir(path_normalize(url)); resource.location = path_getDir(path_normalize(url));
resource.parent = parent; resource.parent = parent;
return resource; return resource;
}, },
getResource: function(url, type){ getResource: function(url, type){
if (this.base && url[0] === '/') if (this.base && url[0] === '/')
url = this.base + url.substring(1); url = this.base + url.substring(1);
return incl_getResource(url, type) return incl_getResource(url, type)
}, },
getResourceById: function(url, type){ getResourceById: function(url, type){
var _bin = bin[type], var _bin = bin[type],
_res = _bin[url]; _res = _bin[url];
if (_res != null) if (_res != null)
return _res; return _res;
if (this.base && url[0] === '/') { if (this.base && url[0] === '/') {
_res = _bin[path_combine(this.base, url)]; _res = _bin[path_combine(this.base, url)];
if (_res != null) if (_res != null)
return _res; return _res;
} }
if (this.base && this.location) { if (this.base && this.location) {
_res = _bin[path_combine(this.base, this.location, url)]; _res = _bin[path_combine(this.base, this.location, url)];
if (_res != null) if (_res != null)
return _res; return _res;
} }
if (this.location) { if (this.location) {
_res = _bin[path_combine(this.location, url)]; _res = _bin[path_combine(this.location, url)];
if (_res != null) if (_res != null)
return _res; return _res;
} }
return null; return null;
...@@ -1409,18 +1409,18 @@ ...@@ -1409,18 +1409,18 @@
getResources: function(){ getResources: function(){
return bin; return bin;
}, },
plugin: function(pckg, callback) { plugin: function(pckg, callback) {
var urls = [], var urls = [],
length = 0, length = 0,
j = 0, j = 0,
i = 0, i = 0,
onload = function(url, response) { onload = function(url, response) {
j++; j++;
embedPlugin(response); embedPlugin(response);
if (j === length - 1 && callback) { if (j === length - 1 && callback) {
callback(); callback();
callback = null; callback = null;
...@@ -1429,98 +1429,98 @@ ...@@ -1429,98 +1429,98 @@
Routes.each('', pckg, function(namespace, route) { Routes.each('', pckg, function(namespace, route) {
urls.push(route.path[0] === '/' ? route.path.substring(1) : route.path); urls.push(route.path[0] === '/' ? route.path.substring(1) : route.path);
}); });
length = urls.length; length = urls.length;
for (; i < length; i++) { for (; i < length; i++) {
XHR(urls[i], onload); XHR(urls[i], onload);
} }
return this; return this;
}, },
client: function(){ client: function(){
if (cfg.server === true) if (cfg.server === true)
stub_freeze(this); stub_freeze(this);
return this; return this;
}, },
server: function(){ server: function(){
if (cfg.server !== true) if (cfg.server !== true)
stub_freeze(this); stub_freeze(this);
return this; return this;
}, },
use: function(){ use: function(){
if (this.parent == null) { if (this.parent == null) {
console.error('<include.use> Parent resource is undefined'); console.error('<include.use> Parent resource is undefined');
return this; return this;
} }
this._usage = arguments; this._usage = arguments;
return this; return this;
}, },
pauseStack: fn_proxy(ScriptStack.pause, ScriptStack), pauseStack: fn_proxy(ScriptStack.pause, ScriptStack),
resumeStack: fn_proxy(ScriptStack.resume, ScriptStack), resumeStack: fn_proxy(ScriptStack.resume, ScriptStack),
allDone: function(callback){ allDone: function(callback){
ScriptStack.complete(function(){ ScriptStack.complete(function(){
var pending = include.getPending('js'), var pending = include.getPending('js'),
await = pending.length; await = pending.length;
if (await === 0) { if (await === 0) {
callback(); callback();
return; return;
} }
var i = -1, var i = -1,
imax = await; imax = await;
while( ++i < imax ){ while( ++i < imax ){
pending[i].on(4, check); pending[i].on(4, check);
} }
function check() { function check() {
if (--await < 1) if (--await < 1)
callback(); callback();
} }
}); });
}, },
getPending: function(type){ getPending: function(type){
var resources = [], var resources = [],
res, key, id; res, key, id;
for(key in bin){ for(key in bin){
if (type != null && type !== key) if (type != null && type !== key)
continue; continue;
for (id in bin[key]){ for (id in bin[key]){
res = bin[key][id]; res = bin[key][id];
if (res.state < 4) if (res.state < 4)
resources.push(res); resources.push(res);
} }
} }
return resources; return resources;
}, },
Lib: IncludeLib Lib: IncludeLib
}); });
// >> FUNCTIONS // >> FUNCTIONS
function incl_getResource(url, type) { function incl_getResource(url, type) {
var id = url; var id = url;
if (path_isRelative(url) === true) if (path_isRelative(url) === true)
id = '/' + id; id = '/' + id;
if (type != null){ if (type != null){
return bin[type][id]; return bin[type][id];
} }
for (var key in bin) { for (var key in bin) {
if (bin[key].hasOwnProperty(id)) { if (bin[key].hasOwnProperty(id)) {
return bin[key][id]; return bin[key][id];
...@@ -1528,12 +1528,12 @@ ...@@ -1528,12 +1528,12 @@
} }
return null; return null;
} }
function embedPlugin(source) { function embedPlugin(source) {
eval(source); eval(source);
} }
function enableModules() { function enableModules() {
if (typeof Object.defineProperty === 'undefined'){ if (typeof Object.defineProperty === 'undefined'){
console.warn('Browser do not support Object.defineProperty'); console.warn('Browser do not support Object.defineProperty');
...@@ -1544,7 +1544,7 @@ ...@@ -1544,7 +1544,7 @@
return global.include; return global.include;
} }
}); });
Object.defineProperty(global, 'exports', { Object.defineProperty(global, 'exports', {
get: function() { get: function() {
var current = global.include; var current = global.include;
...@@ -1555,26 +1555,26 @@ ...@@ -1555,26 +1555,26 @@
} }
}); });
} }
function includePackage(resource, type, mix){ function includePackage(resource, type, mix){
var pckg = mix.length === 1 ? mix[0] : __array_slice.call(mix); var pckg = mix.length === 1 ? mix[0] : __array_slice.call(mix);
if (resource instanceof Resource) { if (resource instanceof Resource) {
return resource.include(type, pckg); return resource.include(type, pckg);
} }
return new Resource('js').include(type, pckg); return new Resource('js').include(type, pckg);
} }
function createIncluder(type) { function createIncluder(type) {
return function(){ return function(){
return includePackage(this, type, arguments); return includePackage(this, type, arguments);
}; };
} }
function doNothing() { function doNothing() {
return this; return this;
} }
function stub_freeze(include) { function stub_freeze(include) {
include.js = include.js =
include.css = include.css =
...@@ -1585,25 +1585,25 @@ ...@@ -1585,25 +1585,25 @@
include.inject = include.inject =
doNothing; doNothing;
} }
function stub_release(proto) { function stub_release(proto) {
var fns = ['js', 'css', 'load', 'ajax', 'embed', 'lazy'], var fns = ['js', 'css', 'load', 'ajax', 'embed', 'lazy'],
i = fns.length; i = fns.length;
while (--i !== -1){ while (--i !== -1){
proto[fns[i]] = createIncluder(fns[i]); proto[fns[i]] = createIncluder(fns[i]);
} }
proto['inject'] = proto.js; proto['inject'] = proto.js;
} }
}(IncludeDeferred)); }(IncludeDeferred));
// end:source ../src/5.Include.js // end:source ../src/5.Include.js
// source ../src/7.CustomLoader.js // source ../src/7.CustomLoader.js
var CustomLoader = (function() { var CustomLoader = (function() {
// source loader/json.js // source loader/json.js
var JSONParser = { var JSONParser = {
process: function(source, res){ process: function(source, res){
try { try {
...@@ -1614,32 +1614,32 @@ ...@@ -1614,32 +1614,32 @@
} }
} }
}; };
// end:source loader/json.js // end:source loader/json.js
cfg.loader = { cfg.loader = {
json : JSONParser json : JSONParser
}; };
function loader_isInstance(x) { function loader_isInstance(x) {
if (typeof x === 'string') if (typeof x === 'string')
return false; return false;
return typeof x.ready === 'function' || typeof x.process === 'function'; return typeof x.ready === 'function' || typeof x.process === 'function';
} }
function createLoader(url) { function createLoader(url) {
var extension = path_getExtension(url), var extension = path_getExtension(url),
loader = cfg.loader[extension]; loader = cfg.loader[extension];
if (loader_isInstance(loader)) { if (loader_isInstance(loader)) {
return loader; return loader;
} }
var path = loader, var path = loader,
namespace; namespace;
if (typeof path === 'object') { if (typeof path === 'object') {
// is route {namespace: path} // is route {namespace: path}
for (var key in path) { for (var key in path) {
...@@ -1648,7 +1648,7 @@ ...@@ -1648,7 +1648,7 @@
break; break;
} }
} }
return (cfg.loader[extension] = new Resource( return (cfg.loader[extension] = new Resource(
'js', 'js',
Routes.resolve(namespace, path), Routes.resolve(namespace, path),
...@@ -1659,54 +1659,54 @@ ...@@ -1659,54 +1659,54 @@
1 1
)); ));
} }
function loader_completeDelegate(callback, resource) { function loader_completeDelegate(callback, resource) {
return function(response){ return function(response){
callback(resource, response); callback(resource, response);
}; };
} }
function loader_process(source, resource, loader, callback) { function loader_process(source, resource, loader, callback) {
if (loader.process == null) { if (loader.process == null) {
callback(resource, source); callback(resource, source);
return; return;
} }
var delegate = loader_completeDelegate(callback, resource), var delegate = loader_completeDelegate(callback, resource),
syncResponse = loader.process(source, resource, delegate); syncResponse = loader.process(source, resource, delegate);
// match also null // match also null
if (typeof syncResponse !== 'undefined') { if (typeof syncResponse !== 'undefined') {
callback(resource, syncResponse); callback(resource, syncResponse);
} }
} }
function tryLoad(resource, loader, callback) { function tryLoad(resource, loader, callback) {
if (typeof resource.exports === 'string') { if (typeof resource.exports === 'string') {
loader_process(resource.exports, resource, loader, callback); loader_process(resource.exports, resource, loader, callback);
return; return;
} }
function onLoad(resource, response){ function onLoad(resource, response){
loader_process(response, resource, loader, callback); loader_process(response, resource, loader, callback);
} }
if (loader.load) if (loader.load)
return loader.load(resource, onLoad); return loader.load(resource, onLoad);
XHR(resource, onLoad); XHR(resource, onLoad);
} }
return { return {
load: function(resource, callback) { load: function(resource, callback) {
var loader = createLoader(resource.url); var loader = createLoader(resource.url);
if (loader.process) { if (loader.process) {
tryLoad(resource, loader, callback); tryLoad(resource, loader, callback);
return; return;
} }
loader.on(4, function() { loader.on(4, function() {
tryLoad(resource, loader.exports, callback); tryLoad(resource, loader.exports, callback);
}, null, 'push'); }, null, 'push');
...@@ -1715,12 +1715,12 @@ ...@@ -1715,12 +1715,12 @@
if (!resource.url) { if (!resource.url) {
return false; return false;
} }
var ext = path_getExtension(resource.url); var ext = path_getExtension(resource.url);
return cfg.loader.hasOwnProperty(ext); return cfg.loader.hasOwnProperty(ext);
}, },
/** /**
* IHandler: * IHandler:
* { process: function(content) { return _handler(content); }; } * { process: function(content) { return _handler(content); }; }
...@@ -1731,20 +1731,20 @@ ...@@ -1731,20 +1731,20 @@
register: function(extension, handler){ register: function(extension, handler){
if (typeof handler === 'string'){ if (typeof handler === 'string'){
var resource = include; var resource = include;
if (resource.location == null) { if (resource.location == null) {
resource = { resource = {
location: path_getDir(path_resolveCurrent()) location: path_getDir(path_resolveCurrent())
}; };
} }
handler = path_resolveUrl(handler, resource); handler = path_resolveUrl(handler, resource);
} }
cfg.loader[extension] = handler; cfg.loader[extension] = handler;
} }
}; };
}()); }());
// end:source ../src/7.CustomLoader.js // end:source ../src/7.CustomLoader.js
// source ../src/8.LazyModule.js // source ../src/8.LazyModule.js
var LazyModule = { var LazyModule = {
...@@ -1757,10 +1757,10 @@ ...@@ -1757,10 +1757,10 @@
obj = obj[prop] || (obj[prop] = {}); obj = obj[prop] || (obj[prop] = {});
} }
arr = null; arr = null;
Object.defineProperty(obj, module, { Object.defineProperty(obj, module, {
get: function() { get: function() {
delete obj[module]; delete obj[module];
try { try {
var r = __eval(code, global.include); var r = __eval(code, global.include);
...@@ -1782,18 +1782,18 @@ ...@@ -1782,18 +1782,18 @@
// end:source ../src/8.LazyModule.js // end:source ../src/8.LazyModule.js
// source ../src/9.Resource.js // source ../src/9.Resource.js
var Resource; var Resource;
(function(Include, Routes, ScriptStack, CustomLoader) { (function(Include, Routes, ScriptStack, CustomLoader) {
Resource = function(type, route, namespace, xpath, parent, id, priority) { Resource = function(type, route, namespace, xpath, parent, id, priority) {
Include.call(this); Include.call(this);
this.childLoaded = fn_proxy(this.childLoaded, this); this.childLoaded = fn_proxy(this.childLoaded, this);
var url = route && route.path; var url = route && route.path;
if (url != null) if (url != null)
this.url = url = path_resolveUrl(url, parent); this.url = url = path_resolveUrl(url, parent);
this.type = type; this.type = type;
this.xpath = xpath; this.xpath = xpath;
this.route = route; this.route = route;
...@@ -1801,44 +1801,44 @@ ...@@ -1801,44 +1801,44 @@
this.priority = priority; this.priority = priority;
this.namespace = namespace; this.namespace = namespace;
this.base = parent && parent.base; this.base = parent && parent.base;
if (id == null && url) if (id == null && url)
id = (path_isRelative(url) ? '/' : '') + url; id = (path_isRelative(url) ? '/' : '') + url;
var resource = bin[type] && bin[type][id]; var resource = bin[type] && bin[type][id];
if (resource) { if (resource) {
if (resource.state < 4 && type === 'js') if (resource.state < 4 && type === 'js')
ScriptStack.moveToParent(resource, parent); ScriptStack.moveToParent(resource, parent);
return resource; return resource;
} }
if (url == null) { if (url == null) {
this.state = 3; this.state = 3;
this.location = path_getDir(path_resolveCurrent()); this.location = path_getDir(path_resolveCurrent());
return this; return this;
} }
this.state = 0; this.state = 0;
this.location = path_getDir(url); this.location = path_getDir(url);
(bin[type] || (bin[type] = {}))[id] = this; (bin[type] || (bin[type] = {}))[id] = this;
if (cfg.version) if (cfg.version)
this.url += (this.url.indexOf('?') === -1 ? '?' : '&') + 'v=' + cfg.version; this.url += (this.url.indexOf('?') === -1 ? '?' : '&') + 'v=' + cfg.version;
return process(this); return process(this);
}; };
Resource.prototype = obj_inherit(Resource, Include, { Resource.prototype = obj_inherit(Resource, Include, {
state: null, state: null,
location: null, location: null,
includes: null, includes: null,
response: null, response: null,
url: null, url: null,
base: null, base: null,
type: null, type: null,
...@@ -1847,12 +1847,12 @@ ...@@ -1847,12 +1847,12 @@
parent: null, parent: null,
priority: null, priority: null,
namespace: null, namespace: null,
setBase: function(baseUrl){ setBase: function(baseUrl){
this.base = baseUrl; this.base = baseUrl;
return this; return this;
}, },
childLoaded: function(child) { childLoaded: function(child) {
var resource = this, var resource = this,
includes = resource.includes; includes = resource.includes;
...@@ -1871,23 +1871,23 @@ ...@@ -1871,23 +1871,23 @@
}, },
create: function(type, route, namespace, xpath, id) { create: function(type, route, namespace, xpath, id) {
var resource; var resource;
this.state = this.state >= 3 this.state = this.state >= 3
? 3 ? 3
: 2; : 2;
this.response = null; this.response = null;
if (this.includes == null) if (this.includes == null)
this.includes = []; this.includes = [];
resource = new Resource(type, route, namespace, xpath, this, id); resource = new Resource(type, route, namespace, xpath, this, id);
this.includes.push({ this.includes.push({
resource: resource, resource: resource,
route: route route: route
}); });
return resource; return resource;
}, },
include: function(type, pckg) { include: function(type, pckg) {
...@@ -1895,7 +1895,7 @@ ...@@ -1895,7 +1895,7 @@
children = [], children = [],
child; child;
Routes.each(type, pckg, function(namespace, route, xpath) { Routes.each(type, pckg, function(namespace, route, xpath) {
if (that.route != null && that.route.path === route.path) { if (that.route != null && that.route.path === route.path) {
// loading itself // loading itself
return; return;
...@@ -1903,46 +1903,46 @@ ...@@ -1903,46 +1903,46 @@
child = that.create(type, route, namespace, xpath); child = that.create(type, route, namespace, xpath);
children.push(child); children.push(child);
}); });
var i = -1, var i = -1,
imax = children.length; imax = children.length;
while ( ++i < imax ){ while ( ++i < imax ){
children[i].on(4, this.childLoaded); children[i].on(4, this.childLoaded);
} }
return this; return this;
}, },
pause: function(){ pause: function(){
this.state = 2.5; this.state = 2.5;
var that = this; var that = this;
return function(exports){ return function(exports){
if (arguments.length === 1) if (arguments.length === 1)
that.exports = exports; that.exports = exports;
that.readystatechanged(3); that.readystatechanged(3);
}; };
}, },
getNestedOfType: function(type){ getNestedOfType: function(type){
return resource_getChildren(this.includes, type); return resource_getChildren(this.includes, type);
} }
}); });
// private // private
function process(resource) { function process(resource) {
var type = resource.type, var type = resource.type,
parent = resource.parent, parent = resource.parent,
url = resource.url; url = resource.url;
if (document == null && type === 'css') { if (document == null && type === 'css') {
resource.state = 4; resource.state = 4;
return resource; return resource;
} }
if (CustomLoader.exists(resource) === false) { if (CustomLoader.exists(resource) === false) {
switch (type) { switch (type) {
case 'js': case 'js':
...@@ -1956,7 +1956,7 @@ ...@@ -1956,7 +1956,7 @@
break; break;
case 'css': case 'css':
resource.state = 4; resource.state = 4;
var tag = document.createElement('link'); var tag = document.createElement('link');
tag.href = url; tag.href = url;
tag.rel = "stylesheet"; tag.rel = "stylesheet";
...@@ -1965,24 +1965,24 @@ ...@@ -1965,24 +1965,24 @@
break; break;
} }
} else { } else {
if ('js' === type || 'embed' === type) { if ('js' === type || 'embed' === type) {
ScriptStack.add(resource, resource.parent); ScriptStack.add(resource, resource.parent);
} }
CustomLoader.load(resource, onXHRCompleted); CustomLoader.load(resource, onXHRCompleted);
} }
return resource; return resource;
} }
function onXHRCompleted(resource, response) { function onXHRCompleted(resource, response) {
if (!response) { if (!response) {
console.warn('Resource cannt be loaded', resource.url); console.warn('Resource cannt be loaded', resource.url);
//- resource.readystatechanged(4); //- resource.readystatechanged(4);
//- return; //- return;
} }
switch (resource.type) { switch (resource.type) {
case 'js': case 'js':
case 'embed': case 'embed':
...@@ -2004,46 +2004,46 @@ ...@@ -2004,46 +2004,46 @@
document.getElementsByTagName('head')[0].appendChild(tag); document.getElementsByTagName('head')[0].appendChild(tag);
break; break;
} }
resource.readystatechanged(4); resource.readystatechanged(4);
} }
function resource_getChildren(includes, type, out) { function resource_getChildren(includes, type, out) {
if (includes == null) if (includes == null)
return null; return null;
if (out == null) if (out == null)
out = []; out = [];
var imax = includes.length, var imax = includes.length,
i = -1, i = -1,
x; x;
while ( ++i < imax ){ while ( ++i < imax ){
x = includes[i].resource; x = includes[i].resource;
if (type === x.type) if (type === x.type)
out.push(x); out.push(x);
if (x.includes != null) if (x.includes != null)
resource_getChildren(x.includes, type, out); resource_getChildren(x.includes, type, out);
} }
return out; return out;
} }
}(Include, Routes, ScriptStack, CustomLoader)); }(Include, Routes, ScriptStack, CustomLoader));
// end:source ../src/9.Resource.js // end:source ../src/9.Resource.js
// source ../src/10.export.js // source ../src/10.export.js
IncludeLib.Routes = RoutesLib; IncludeLib.Routes = RoutesLib;
IncludeLib.Resource = Resource; IncludeLib.Resource = Resource;
IncludeLib.ScriptStack = ScriptStack; IncludeLib.ScriptStack = ScriptStack;
IncludeLib.registerLoader = CustomLoader.register; IncludeLib.registerLoader = CustomLoader.register;
exports.include = new Include(); exports.include = new Include();
exports.includeLib = IncludeLib; exports.includeLib = IncludeLib;
// end:source ../src/10.export.js // end:source ../src/10.export.js
})); }));
...@@ -2051,14 +2051,14 @@ ...@@ -2051,14 +2051,14 @@
function __eval(source, include) { function __eval(source, include) {
"use strict"; "use strict";
var iparams = include && include.route.params; var iparams = include && include.route.params;
/* if !DEBUG /* if !DEBUG
try { try {
*/ */
return eval.call(window, source); return eval.call(window, source);
/* if !DEBUG /* if !DEBUG
} catch (error) { } catch (error) {
error.url = include && include.url; error.url = include && include.url;
...@@ -2066,6 +2066,6 @@ function __eval(source, include) { ...@@ -2066,6 +2066,6 @@ function __eval(source, include) {
console.error(error); console.error(error);
} }
*/ */
} }
// end:source ../src/global-vars.js // end:source ../src/global-vars.js
\ No newline at end of file
(function(root, factory){ (function(root, factory){
"use strict"; "use strict";
if (root == null) { if (root == null) {
root = typeof window !== 'undefined' && typeof document !== 'undefined' root = typeof window !== 'undefined' && typeof document !== 'undefined'
? window ? window
: global; : global;
} }
root.ruta = factory(root); root.ruta = factory(root);
}(this, function(global){ }(this, function(global){
"use strict"; "use strict";
// source ../src/vars.js // source ../src/vars.js
var mask = global.mask || Mask; var mask = global.mask || Mask;
// settings // settings
/** define if routes like '/path' are strict by default, /** define if routes like '/path' are strict by default,
* or set explicit '!/path' - strict, '^/path' - not strict * or set explicit '!/path' - strict, '^/path' - not strict
* *
...@@ -30,13 +30,13 @@ ...@@ -30,13 +30,13 @@
// source ../src/utils/log.js // source ../src/utils/log.js
var log_error; var log_error;
(function(){ (function(){
log_error = function(){ log_error = function(){
var args = _Array_slice.call(arguments); var args = _Array_slice.call(arguments);
console.error.apply(console, ['Ruta'].concat(args)); console.error.apply(console, ['Ruta'].concat(args));
}; };
}()); }());
// end:source ../src/utils/log.js // end:source ../src/utils/log.js
// source ../src/utils/path.js // source ../src/utils/path.js
...@@ -45,152 +45,152 @@ ...@@ -45,152 +45,152 @@
path_join, path_join,
path_fromCLI path_fromCLI
; ;
(function(){ (function(){
path_normalize = function(str) { path_normalize = function(str) {
var length = str.length, var length = str.length,
i = 0, i = 0,
j = length - 1; j = length - 1;
for(; i < length; i++) { for(; i < length; i++) {
if (str[i] === '/') if (str[i] === '/')
continue; continue;
break; break;
} }
for (; j > i; j--) { for (; j > i; j--) {
if (str[j] === '/') if (str[j] === '/')
continue; continue;
break; break;
} }
return str.substring(i, j + 1); return str.substring(i, j + 1);
}; };
path_split = function(path) { path_split = function(path) {
path = path_normalize(path); path = path_normalize(path);
return path === '' return path === ''
? [] ? []
: path.split('/'); : path.split('/');
}; };
path_join = function(pathParts) { path_join = function(pathParts) {
return '/' + pathParts.join('/'); return '/' + pathParts.join('/');
}; };
path_fromCLI = function(commands){ path_fromCLI = function(commands){
if (typeof commands === 'string') if (typeof commands === 'string')
commands = cli_split(commands); commands = cli_split(commands);
var parts = cli_parseArguments(commands); var parts = cli_parseArguments(commands);
return parts_serialize(parts); return parts_serialize(parts);
}; };
// == private // == private
function cli_split(string){ function cli_split(string){
var args = string.trim().split(/\s+/); var args = string.trim().split(/\s+/);
var imax = args.length, var imax = args.length,
i = -1, i = -1,
c, arg; c, arg;
while ( ++i < imax ){ while ( ++i < imax ){
arg = args[i]; arg = args[i];
if (arg.length === 0) if (arg.length === 0)
continue; continue;
c = arg[0]; c = arg[0];
if (c !== '"' && c !== "'") if (c !== '"' && c !== "'")
continue; continue;
var start = i; var start = i;
for( ; i < imax; i++ ){ for( ; i < imax; i++ ){
arg = args[i]; arg = args[i];
if (arg[arg.length - 1] === c) { if (arg[arg.length - 1] === c) {
var str = args var str = args
.splice(start, i - start + 1) .splice(start, i - start + 1)
.join(' ') .join(' ')
.slice(1, -1) .slice(1, -1)
; ;
args.splice(start, 0, str); args.splice(start, 0, str);
imax = args.length; imax = args.length;
break; break;
} }
} }
} }
return args; return args;
} }
function cli_parseArguments(argv){ function cli_parseArguments(argv){
var imax = argv.length, var imax = argv.length,
i = 0, i = 0,
params = {}, params = {},
args = [], args = [],
key, val, x; key, val, x;
for (; i < imax; i++){ for (; i < imax; i++){
x = argv[i]; x = argv[i];
if (x[0] === '-') { if (x[0] === '-') {
key = x.replace(/^[\-]+/, ''); key = x.replace(/^[\-]+/, '');
if (i < imax - 1 && argv[i + 1][0] !== '-') { if (i < imax - 1 && argv[i + 1][0] !== '-') {
val = argv[i + 1]; val = argv[i + 1];
i++; i++;
} else { } else {
val = true; val = true;
} }
params[key] = val; params[key] = val;
continue; continue;
} }
args.push(x); args.push(x);
} }
return { return {
path: args, path: args,
query: params query: params
}; };
} }
}()); }());
// end:source ../src/utils/path.js // end:source ../src/utils/path.js
// source ../src/utils/query.js // source ../src/utils/query.js
var query_deserialize, var query_deserialize,
query_serialize query_serialize
; ;
(function(){ (function(){
query_deserialize = function(query, delimiter) { query_deserialize = function(query, delimiter) {
if (delimiter == null) if (delimiter == null)
delimiter = '&'; delimiter = '&';
var obj = {}, var obj = {},
parts = query.split(delimiter), parts = query.split(delimiter),
i = 0, i = 0,
imax = parts.length, imax = parts.length,
x, val; x, val;
for (; i < imax; i++) { for (; i < imax; i++) {
x = parts[i].split('='); x = parts[i].split('=');
val = x[1] == null val = x[1] == null
...@@ -202,45 +202,45 @@ ...@@ -202,45 +202,45 @@
return obj; return obj;
}; };
query_serialize = function(params, delimiter) { query_serialize = function(params, delimiter) {
if (delimiter == null) if (delimiter == null)
delimiter = '&'; delimiter = '&';
var query = '', var query = '',
key, val; key, val;
for(key in params) { for(key in params) {
val = params[key]; val = params[key];
if (val == null) if (val == null)
continue; continue;
// serialize as flag // serialize as flag
if (typeof val === 'boolean') if (typeof val === 'boolean')
val = null; val = null;
query = query + (query ? delimiter : '') + key; query = query + (query ? delimiter : '') + key;
if (val != null) if (val != null)
query += '=' + encode(val); query += '=' + encode(val);
} }
return query; return query;
}; };
// = private // = private
function obj_setProperty(obj, property, value) { function obj_setProperty(obj, property, value) {
var chain = property.split('.'), var chain = property.split('.'),
imax = chain.length, imax = chain.length,
i = -1, i = -1,
key; key;
while ( ++i < imax - 1) { while ( ++i < imax - 1) {
key = chain[i]; key = chain[i];
if (obj[key] == null) if (obj[key] == null)
obj[key] = {}; obj[key] = {};
obj = obj[key]; obj = obj[key];
} }
obj[chain[i]] = value; obj[chain[i]] = value;
} }
function decode(str) { function decode(str) {
...@@ -260,92 +260,92 @@ ...@@ -260,92 +260,92 @@
} }
} }
}()); }());
// end:source ../src/utils/query.js // end:source ../src/utils/query.js
// source ../src/utils/rgx.js // source ../src/utils/rgx.js
var rgx_fromString, var rgx_fromString,
// Url part should be completely matched, so add ^...$ and create RegExp // Url part should be completely matched, so add ^...$ and create RegExp
rgx_aliasMatcher, rgx_aliasMatcher,
// :debugger(d|debug) => { alias: 'debugger', matcher: RegExp } // :debugger(d|debug) => { alias: 'debugger', matcher: RegExp }
rgx_parsePartWithRegExpAlias rgx_parsePartWithRegExpAlias
; ;
(function(){ (function(){
rgx_fromString = function(str, flags) { rgx_fromString = function(str, flags) {
return new RegExp(str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), flags); return new RegExp(str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), flags);
}; };
rgx_aliasMatcher = function(str){ rgx_aliasMatcher = function(str){
if (str[0] === '^') if (str[0] === '^')
return new RegExp(str); return new RegExp(str);
var groups = str.split('|'); var groups = str.split('|');
for (var i = 0, imax = groups.length; i < imax; i++){ for (var i = 0, imax = groups.length; i < imax; i++){
groups[i] = '^' + groups[i] + '$'; groups[i] = '^' + groups[i] + '$';
} }
return new RegExp(groups.join('|')); return new RegExp(groups.join('|'));
}; };
rgx_parsePartWithRegExpAlias = function(str){ rgx_parsePartWithRegExpAlias = function(str){
var pStart = str.indexOf('('), var pStart = str.indexOf('('),
pEnd = str.lastIndexOf(')') pEnd = str.lastIndexOf(')')
; ;
if (pStart === -1 || pEnd === -1) { if (pStart === -1 || pEnd === -1) {
log_error('Expected alias part with regexp', str); log_error('Expected alias part with regexp', str);
return null; return null;
} }
var rgx = str.substring(pStart + 1, pEnd); var rgx = str.substring(pStart + 1, pEnd);
return { return {
alias: str.substring(1, pStart), alias: str.substring(1, pStart),
matcher: rgx_aliasMatcher(rgx) matcher: rgx_aliasMatcher(rgx)
}; };
}; };
}()); }());
// end:source ../src/utils/rgx.js // end:source ../src/utils/rgx.js
// source ../src/utils/parts.js // source ../src/utils/parts.js
/** /**
* '/foo/bar?a=b' => * '/foo/bar?a=b' =>
* { path: ['foo', 'bar'], query: { a: 'b' } } * { path: ['foo', 'bar'], query: { a: 'b' } }
*/ */
var parts_serialize, var parts_serialize,
parts_deserialize parts_deserialize
; ;
(function(){ (function(){
parts_serialize = function(parts){ parts_serialize = function(parts){
var path = path_join(parts.path); var path = path_join(parts.path);
if (parts.query == null) if (parts.query == null)
return path; return path;
return path return path
+ '?' + '?'
+ query_serialize(parts.query, '&') + query_serialize(parts.query, '&')
; ;
}; };
parts_deserialize = function(url){ parts_deserialize = function(url){
var query = url.indexOf('?'), var query = url.indexOf('?'),
path = query === -1 path = query === -1
? url ? url
: url.substring(0, query); : url.substring(0, query);
return { return {
path: path_split(path), path: path_split(path),
query: query === -1 query: query === -1
...@@ -353,29 +353,29 @@ ...@@ -353,29 +353,29 @@
: query_deserialize(url.substring(query + 1), '&') : query_deserialize(url.substring(query + 1), '&')
}; };
}; };
}()); }());
// end:source ../src/utils/parts.js // end:source ../src/utils/parts.js
// source ../src/route/Collection.js // source ../src/route/Collection.js
var Routes = (function(){ var Routes = (function(){
// source Route.js // source Route.js
// source parse.js // source parse.js
var route_parseDefinition, // out route, definition var route_parseDefinition, // out route, definition
// path should be already matched by the route // path should be already matched by the route
route_parsePath // route, path route_parsePath // route, path
; ;
(function(){ (function(){
route_parseDefinition = function(route, definition) { route_parseDefinition = function(route, definition) {
var c = definition.charCodeAt(0); var c = definition.charCodeAt(0);
switch(c){ switch(c){
case 33: case 33:
...@@ -398,13 +398,13 @@ ...@@ -398,13 +398,13 @@
log_error('parser - expect group closing'); log_error('parser - expect group closing');
end ++; end ++;
} }
route.match = new RegExp(definition.substring(start, end)); route.match = new RegExp(definition.substring(start, end));
return; return;
} }
var parts = definition.split('/'), var parts = definition.split('/'),
search, search,
searchIndex, searchIndex,
...@@ -414,8 +414,8 @@ ...@@ -414,8 +414,8 @@
c0, c0,
index, index,
c1; c1;
var last = parts[imax - 1]; var last = parts[imax - 1];
searchIndex = last.indexOf('?'); searchIndex = last.indexOf('?');
if (searchIndex > (imax === 1 ? -1 : 0)) { if (searchIndex > (imax === 1 ? -1 : 0)) {
...@@ -423,67 +423,67 @@ ...@@ -423,67 +423,67 @@
search = last.substring(searchIndex + 1); search = last.substring(searchIndex + 1);
parts[imax - 1] = last.substring(0, searchIndex); parts[imax - 1] = last.substring(0, searchIndex);
} }
var matcher = '', var matcher = '',
alias = null, alias = null,
strictCount = 0; strictCount = 0;
var gettingMatcher = true, var gettingMatcher = true,
isOptional, isOptional,
isAlias, isAlias,
rgx; rgx;
var array = route.path = []; var array = route.path = [];
for (; i < imax; i++) { for (; i < imax; i++) {
x = parts[i]; x = parts[i];
if (x === '') if (x === '')
continue; continue;
c0 = x.charCodeAt(0); c0 = x.charCodeAt(0);
c1 = x.charCodeAt(1); c1 = x.charCodeAt(1);
isOptional = c0 === 63; /* ? */ isOptional = c0 === 63; /* ? */
isAlias = (isOptional ? c1 : c0) === 58; /* : */ isAlias = (isOptional ? c1 : c0) === 58; /* : */
index = 0; index = 0;
if (isOptional) if (isOptional)
index++; index++;
if (isAlias) if (isAlias)
index++; index++;
if (index !== 0) if (index !== 0)
x = x.substring(index); x = x.substring(index);
// if DEBUG // if DEBUG
if (!isOptional && !gettingMatcher) if (!isOptional && !gettingMatcher)
log_error('Strict part found after optional', definition); log_error('Strict part found after optional', definition);
// endif // endif
if (isOptional) if (isOptional)
gettingMatcher = false; gettingMatcher = false;
var bracketIndex = x.indexOf('('); var bracketIndex = x.indexOf('(');
if (isAlias && bracketIndex !== -1) { if (isAlias && bracketIndex !== -1) {
var end = x.length - 1; var end = x.length - 1;
if (x[end] !== ')') if (x[end] !== ')')
end+= 1; end+= 1;
rgx = new RegExp(rgx_aliasMatcher(x.substring(bracketIndex + 1, end))); rgx = new RegExp(rgx_aliasMatcher(x.substring(bracketIndex + 1, end)));
x = x.substring(0, bracketIndex); x = x.substring(0, bracketIndex);
} }
if (!isOptional && !isAlias) { if (!isOptional && !isAlias) {
array.push(x); array.push(x);
continue; continue;
} }
if (isAlias) { if (isAlias) {
array.push({ array.push({
alias: x, alias: x,
...@@ -491,100 +491,100 @@ ...@@ -491,100 +491,100 @@
optional: isOptional optional: isOptional
}); });
} }
} }
if (search) { if (search) {
var query = route.query = {}; var query = route.query = {};
parts = search.split('&'); parts = search.split('&');
i = -1; i = -1;
imax = parts.length; imax = parts.length;
var key, value, str, eqIndex; var key, value, str, eqIndex;
while(++i < imax){ while(++i < imax){
str = parts[i]; str = parts[i];
eqIndex = str.indexOf('='); eqIndex = str.indexOf('=');
if (eqIndex === -1) { if (eqIndex === -1) {
query[str] = ''; // <empty string> query[str] = ''; // <empty string>
continue; continue;
} }
key = str.substring(0, eqIndex); key = str.substring(0, eqIndex);
value = str.substring(eqIndex + 1); value = str.substring(eqIndex + 1);
if (value.charCodeAt(0) === 40) { if (value.charCodeAt(0) === 40) {
// ( // (
value = new RegExp(rgx_aliasMatcher(value)); value = new RegExp(rgx_aliasMatcher(value));
} }
query[key] = value; query[key] = value;
} }
if (route.path.length === 0) { if (route.path.length === 0) {
route.strict = false; route.strict = false;
} }
} }
}; };
route_parsePath = function(route, path) { route_parsePath = function(route, path) {
var queryIndex = path.indexOf('?'), var queryIndex = path.indexOf('?'),
query = queryIndex === -1 query = queryIndex === -1
? null ? null
: path.substring(queryIndex + 1), : path.substring(queryIndex + 1),
current = { current = {
path: path, path: path,
params: query == null params: query == null
? {} ? {}
: query_deserialize(query, '&') : query_deserialize(query, '&')
}; };
if (route.query) { if (route.query) {
// ensura aliased queries, like ?:debugger(d|debug) // ensura aliased queries, like ?:debugger(d|debug)
for (var key in route.query){ for (var key in route.query){
if (key[0] === '?') if (key[0] === '?')
key = key.substring(1); key = key.substring(1);
if (key[0] === ':') { if (key[0] === ':') {
var alias = rgx_parsePartWithRegExpAlias(key), var alias = rgx_parsePartWithRegExpAlias(key),
name = alias.alias; name = alias.alias;
current.params[name] = getAliasedValue(current.params, alias.matcher); current.params[name] = getAliasedValue(current.params, alias.matcher);
} }
} }
} }
if (queryIndex !== -1) { if (queryIndex !== -1) {
path = path.substring(0, queryIndex); path = path.substring(0, queryIndex);
} }
if (route.path != null) { if (route.path != null) {
var pathArr = path_split(path), var pathArr = path_split(path),
routePath = route.path, routePath = route.path,
routeLength = routePath.length, routeLength = routePath.length,
imax = pathArr.length, imax = pathArr.length,
i = 0, i = 0,
part, part,
x; x;
for (; i < imax; i++) { for (; i < imax; i++) {
part = pathArr[i]; part = pathArr[i];
x = i < routeLength ? routePath[i] : null; x = i < routeLength ? routePath[i] : null;
if (x) { if (x) {
if (typeof x === 'string') if (typeof x === 'string')
continue; continue;
if (x.alias) { if (x.alias) {
current.params[x.alias] = part; current.params[x.alias] = part;
continue; continue;
...@@ -592,16 +592,16 @@ ...@@ -592,16 +592,16 @@
} }
} }
} }
return current; return current;
}; };
// = private // = private
function getAliasedValue(obj, matcher) { function getAliasedValue(obj, matcher) {
for (var key in obj){ for (var key in obj){
if (matcher.test(key)) if (matcher.test(key))
return obj[key]; return obj[key];
} }
} }
...@@ -611,321 +611,311 @@ ...@@ -611,321 +611,311 @@
var route_match, var route_match,
route_isMatch route_isMatch
; ;
(function(){ (function(){
route_match = function(url, routes, currentMethod){ route_match = function(url, routes, currentMethod){
var parts = parts_deserialize(url); var parts = parts_deserialize(url);
for (var i = 0, route, imax = routes.length; i < imax; i++){ for (var i = 0, route, imax = routes.length; i < imax; i++){
route = routes[i]; route = routes[i];
if (route_isMatch(parts, route, currentMethod)) { if (route_isMatch(parts, route, currentMethod)) {
route.current = route_parsePath(route, url); route.current = route_parsePath(route, url);
return route; return route;
} }
} }
return null; return null;
}; };
route_isMatch = function(parts, route, currentMethod) { route_isMatch = function(parts, route, currentMethod) {
if (currentMethod != null && if (currentMethod != null &&
route.method != null && route.method != null &&
route.method !== currentMethod) { route.method !== currentMethod) {
return false; return false;
} }
if (route.match) { if (route.match) {
return route.match.test( return route.match.test(
typeof parts === 'string' typeof parts === 'string'
? parts ? parts
: parts_serialize(parts) : parts_serialize(parts)
); );
} }
if (typeof parts === 'string') if (typeof parts === 'string')
parts = parts_deserialize(parts); parts = parts_deserialize(parts);
// route defines some query, match these with the current path{parts} // route defines some query, match these with the current path{parts}
if (route.query) { if (route.query) {
var query = parts.query, var query = parts.query,
key, value; key, value;
if (query == null) if (query == null)
return false; return false;
for(key in route.query){ for(key in route.query){
value = route.query[key]; value = route.query[key];
var c = key[0]; var c = key[0];
if (c === ':') { if (c === ':') {
// '?:isGlob(g|glob) will match if any is present // '?:isGlob(g|glob) will match if any is present
var alias = rgx_parsePartWithRegExpAlias(key); var alias = rgx_parsePartWithRegExpAlias(key);
if (alias == null || hasKey(query, alias.matcher) === false) if (alias == null || hasKey(query, alias.matcher) === false)
return false; return false;
continue; continue;
} }
if (c === '?') if (c === '?')
continue; continue;
if (typeof value === 'string') { if (typeof value === 'string') {
if (query[key] == null) if (query[key] == null)
return false; return false;
if (value && query[key] !== value) if (value && query[key] !== value)
return false; return false;
continue; continue;
} }
if (value.test && !value.test(query[key])) if (value.test && !value.test(query[key]))
return false; return false;
} }
} }
var routePath = route.path, var routePath = route.path,
routeLength = routePath.length; routeLength = routePath.length;
if (routeLength === 0) { if (routeLength === 0) {
if (route.strict) if (route.strict)
return parts.path.length === 0; return parts.path.length === 0;
return true; return true;
} }
for (var i = 0, x, imax = parts.path.length; i < imax; i++){ for (var i = 0, x, imax = parts.path.length; i < imax; i++){
x = routePath[i]; x = routePath[i];
if (i >= routeLength) if (i >= routeLength)
return route.strict !== true; return route.strict !== true;
if (typeof x === 'string') { if (typeof x === 'string') {
if (parts.path[i] === x) if (parts.path[i] === x)
continue; continue;
return false; return false;
} }
if (x.matcher && x.matcher.test(parts.path[i]) === false) { if (x.matcher && x.matcher.test(parts.path[i]) === false) {
return false; return false;
} }
if (x.optional) if (x.optional)
return true; return true;
if (x.alias) if (x.alias)
continue; continue;
return false; return false;
} }
if (i < routeLength) if (i < routeLength)
return routePath[i].optional === true; return routePath[i].optional === true;
return true; return true;
}; };
function hasKey(obj, rgx){ function hasKey(obj, rgx){
for(var key in obj){ for(var key in obj){
if (rgx.test(key)) if (rgx.test(key))
return true; return true;
} }
return false; return false;
} }
}()); }());
// end:source match.js // end:source match.js
var regexp_var = '([^\\\\]+)'; var regexp_var = '([^\\\\]+)';
function Route(definition, value) { function Route(definition, value) {
this.method = definition.charCodeAt(0) === 36 this.method = definition.charCodeAt(0) === 36
? definition.substring(1, definition.indexOf(' ')).toUpperCase() ? definition.substring(1, definition.indexOf(' ')).toUpperCase()
: null : null
; ;
if (this.method != null) { if (this.method != null) {
definition = definition.substring( this.method.length + 2 ); definition = definition.substring( this.method.length + 2 );
} }
this.strict = _cfg_isStrict; this.strict = _cfg_isStrict;
this.value = value; this.value = value;
this.definition = definition; this.definition = definition;
route_parseDefinition(this, definition); route_parseDefinition(this, definition);
} }
Route.prototype = { Route.prototype = {
path: null, path: null,
query: null, query: null,
value: null, value: null,
current: null current: null
}; };
// end:source Route.js // end:source Route.js
function RouteCollection() { function RouteCollection() {
this.routes = []; this.routes = [];
} }
RouteCollection.prototype = { RouteCollection.prototype = {
add: function(regpath, value){ add: function(regpath, value){
this.routes.push(new Route(regpath, value)); this.routes.push(new Route(regpath, value));
return this; return this;
}, },
get: function(path, currentMethod){ get: function(path, currentMethod){
return route_match(path, this.routes, currentMethod); return route_match(path, this.routes, currentMethod);
}, },
clear: function(){ clear: function(){
this.routes.length = 0; this.routes.length = 0;
return this; return this;
} }
}; };
RouteCollection.parse = function(definition, path){ RouteCollection.parse = function(definition, path){
var route = {}; var route = {};
route_parseDefinition(route, definition); route_parseDefinition(route, definition);
return route_parsePath(route, path); return route_parsePath(route, path);
}; };
return RouteCollection; return RouteCollection;
}()); }());
// end:source ../src/route/Collection.js // end:source ../src/route/Collection.js
// source ../src/emit/Location.js // source ../src/emit/Location.js
var Location = (function(){ var Location = (function(){
if (typeof window === 'undefined') { if (typeof window === 'undefined') {
return function(){}; return function(){};
} }
// source Hash.js // source Hash.js
function HashEmitter(listener) { function HashEmitter(listener) {
if (typeof window === 'undefined' || 'onhashchange' in window === false) if (typeof window === 'undefined' || 'onhashchange' in window === false)
return null; return null;
this.listener = listener; this.listener = listener;
var that = this; var that = this;
window.onhashchange = function() { window.onhashchange = function() {
that.changed(location.hash); that.changed(location.hash);
}; };
return this; return this;
} }
(function() { (function() {
function hash_normalize(hash) { function hash_normalize(hash) {
return hash.replace(/^[!#/]+/, '/'); return hash.replace(/^[!#/]+/, '/');
} }
HashEmitter.prototype = { HashEmitter.prototype = {
navigate: function(hash) { navigate: function(hash) {
if (hash == null) { if (hash == null) {
this.changed(location.hash); this.changed(location.hash);
return; return;
} }
location.hash = hash; location.hash = hash;
}, },
changed: function(hash) { changed: function(hash) {
this this
.listener .listener
.changed(hash_normalize(hash)); .changed(hash_normalize(hash));
}, },
current: function() { current: function() {
return hash_normalize(location.hash); return hash_normalize(location.hash);
} }
}; };
}()); }());
// end:source Hash.js // end:source Hash.js
// source History.js // source History.js
function HistoryEmitter(listener){
function HistoryEmitter(listener){
if (typeof window === 'undefined') if (typeof window === 'undefined')
return null; return null;
if (!(window.history && window.history.pushState)) if (!(window.history && window.history.pushState))
return null; return null;
var that = this; var that = this;
that.listener = listener; that.listener = listener;
that.initial = location.pathname; that.initial = location.pathname;
window.onpopstate = function(){ window.onpopstate = function(){
if (that.initial === location.pathname) { if (that.initial === location.pathname) {
that.initial = null; that.initial = null;
return; return;
} }
that.changed(); that.changed();
}; };
return that; return that;
} }
(function(){ HistoryEmitter.prototype = {
navigate: function(url){
HistoryEmitter.prototype = { if (url == null) {
navigate: function(url){
if (url == null) {
this.changed();
return;
}
history.pushState({}, null, url);
this.changed(); this.changed();
}, return;
changed: function(){
this.listener.changed(location.pathname + location.search);
},
current: function(){
return location.pathname + location.search;
} }
};
history.pushState({}, null, url);
}()); this.initial = null;
this.changed();
},
changed: function(){
this.listener.changed(location.pathname + location.search);
},
current: function(){
return location.pathname + location.search;
}
};
// end:source History.js // end:source History.js
function Location(collection, type) { function Location(collection, type) {
this.collection = collection || new Routes(); this.collection = collection || new Routes();
if (type) { if (type) {
var Constructor = type === 'hash' var Constructor = type === 'hash'
? HashEmitter ? HashEmitter
...@@ -933,25 +923,25 @@ ...@@ -933,25 +923,25 @@
; ;
this.emitter = new Constructor(this); this.emitter = new Constructor(this);
} }
if (this.emitter == null) if (this.emitter == null)
this.emitter = new HistoryEmitter(this); this.emitter = new HistoryEmitter(this);
if (this.emitter == null) if (this.emitter == null)
this.emitter = new HashEmitter(this); this.emitter = new HashEmitter(this);
if (this.emitter == null) if (this.emitter == null)
log_error('Router can not be initialized - (nor HistoryAPI / nor hashchange'); log_error('Router can not be initialized - (nor HistoryAPI / nor hashchange');
} }
Location.prototype = { Location.prototype = {
changed: function(path){ changed: function(path){
var item = this.collection.get(path); var item = this.collection.get(path);
if (item) if (item)
this.action(item); this.action(item);
}, },
action: function(route){ action: function(route){
if (typeof route.value === 'function') { if (typeof route.value === 'function') {
...@@ -971,43 +961,43 @@ ...@@ -971,43 +961,43 @@
return this.emitter.current(); return this.emitter.current();
} }
}; };
return Location; return Location;
}()); }());
// end:source ../src/emit/Location.js // end:source ../src/emit/Location.js
// source ../src/ruta.js // source ../src/ruta.js
var routes = new Routes(), var routes = new Routes(),
router; router;
function router_ensure() { function router_ensure() {
if (router == null) if (router == null)
router = new Location(routes); router = new Location(routes);
return router; return router;
} }
var Ruta = { var Ruta = {
Collection: Routes, Collection: Routes,
setRouterType: function(type){ setRouterType: function(type){
if (router == null) if (router == null)
router = new Location(routes, type); router = new Location(routes, type);
return this; return this;
}, },
setStrictBehaviour: function(isStrict){ setStrictBehaviour: function(isStrict){
_cfg_isStrict = isStrict; _cfg_isStrict = isStrict;
return this; return this;
}, },
add: function(regpath, mix){ add: function(regpath, mix){
router_ensure(); router_ensure();
routes.add(regpath, mix); routes.add(regpath, mix);
return this; return this;
}, },
get: function(path){ get: function(path){
return routes.get(path); return routes.get(path);
}, },
...@@ -1021,48 +1011,48 @@ ...@@ -1021,48 +1011,48 @@
currentPath: function(){ currentPath: function(){
return router_ensure().currentPath(); return router_ensure().currentPath();
}, },
notifyCurrent: function(){ notifyCurrent: function(){
router_ensure().navigate(); router_ensure().navigate();
return this; return this;
}, },
parse: Routes.parse, parse: Routes.parse,
$utils: { $utils: {
/* /*
* Format URI path from CLI command: * Format URI path from CLI command:
* some action -foo bar === /some/action?foo=bar * some action -foo bar === /some/action?foo=bar
*/ */
pathFromCLI: path_fromCLI, pathFromCLI: path_fromCLI,
query: { query: {
serialize: query_serialize, serialize: query_serialize,
deserialize: query_deserialize deserialize: query_deserialize
} }
} }
}; };
// end:source ../src/ruta.js // end:source ../src/ruta.js
// source ../src/mask/attr/anchor-dynamic.js // source ../src/mask/attr/anchor-dynamic.js
(function() { (function() {
mask.registerAttrHandler('x-dynamic', function(node, value, model, ctx, tag){ mask.registerAttrHandler('x-dynamic', function(node, value, model, ctx, tag){
tag.onclick = navigate; tag.onclick = navigate;
}, 'client'); }, 'client');
function navigate(event) { function navigate(event) {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
Ruta.navigate(this.href); Ruta.navigate(this.href);
} }
}()); }());
// end:source ../src/mask/attr/anchor-dynamic.js // end:source ../src/mask/attr/anchor-dynamic.js
return Ruta; return Ruta;
})); }));
\ No newline at end of file
...@@ -12,104 +12,81 @@ button { ...@@ -12,104 +12,81 @@ button {
font-size: 100%; font-size: 100%;
vertical-align: baseline; vertical-align: baseline;
font-family: inherit; font-family: inherit;
font-weight: inherit;
color: inherit; color: inherit;
-webkit-appearance: none; -webkit-appearance: none;
-ms-appearance: none; -ms-appearance: none;
-o-appearance: none;
appearance: none; appearance: none;
-webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased;
-ms-font-smoothing: antialiased;
font-smoothing: antialiased;
} }
body { body {
font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif; font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
line-height: 1.4em; line-height: 1.4em;
background: #eaeaea url('bg.png'); background: #f5f5f5;
color: #4d4d4d; color: #4d4d4d;
width: 550px; min-width: 230px;
max-width: 550px;
margin: 0 auto; margin: 0 auto;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased; -moz-font-smoothing: antialiased;
-ms-font-smoothing: antialiased; -ms-font-smoothing: antialiased;
-o-font-smoothing: antialiased;
font-smoothing: antialiased; font-smoothing: antialiased;
font-weight: 300;
} }
button, button,
input[type="checkbox"] { input[type="checkbox"] {
outline: none; outline: none;
}
.hidden {
display: none;
} }
#todoapp { #todoapp {
background: #fff; background: #fff;
background: rgba(255, 255, 255, 0.9);
margin: 130px 0 40px 0; margin: 130px 0 40px 0;
border: 1px solid #ccc;
position: relative; position: relative;
border-top-left-radius: 2px; box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2),
border-top-right-radius: 2px; 0 25px 50px 0 rgba(0, 0, 0, 0.1);
box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2),
0 25px 50px 0 rgba(0, 0, 0, 0.15);
}
#todoapp:before {
content: '';
border-left: 1px solid #f5d6d6;
border-right: 1px solid #f5d6d6;
width: 2px;
position: absolute;
top: 0;
left: 40px;
height: 100%;
} }
#todoapp input::-webkit-input-placeholder { #todoapp input::-webkit-input-placeholder {
font-style: italic; font-style: italic;
font-weight: 300;
color: #e6e6e6;
} }
#todoapp input::-moz-placeholder { #todoapp input::-moz-placeholder {
font-style: italic; font-style: italic;
color: #a9a9a9; font-weight: 300;
color: #e6e6e6;
}
#todoapp input::input-placeholder {
font-style: italic;
font-weight: 300;
color: #e6e6e6;
} }
#todoapp h1 { #todoapp h1 {
position: absolute; position: absolute;
top: -120px; top: -155px;
width: 100%; width: 100%;
font-size: 70px; font-size: 100px;
font-weight: bold; font-weight: 100;
text-align: center; text-align: center;
color: #b3b3b3; color: rgba(175, 47, 47, 0.15);
color: rgba(255, 255, 255, 0.3);
text-shadow: -1px -1px rgba(0, 0, 0, 0.2);
-webkit-text-rendering: optimizeLegibility; -webkit-text-rendering: optimizeLegibility;
-moz-text-rendering: optimizeLegibility; -moz-text-rendering: optimizeLegibility;
-ms-text-rendering: optimizeLegibility; -ms-text-rendering: optimizeLegibility;
-o-text-rendering: optimizeLegibility;
text-rendering: optimizeLegibility; text-rendering: optimizeLegibility;
} }
#header {
padding-top: 15px;
border-radius: inherit;
}
#header:before {
content: '';
position: absolute;
top: 0;
right: 0;
left: 0;
height: 15px;
z-index: 2;
border-bottom: 1px solid #6c615c;
background: #8d7d77;
background: -webkit-gradient(linear, left top, left bottom, from(rgba(132, 110, 100, 0.8)),to(rgba(101, 84, 76, 0.8)));
background: -webkit-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
background: linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#9d8b83', EndColorStr='#847670');
border-top-left-radius: 1px;
border-top-right-radius: 1px;
}
#new-todo, #new-todo,
.edit { .edit {
position: relative; position: relative;
...@@ -117,6 +94,7 @@ input[type="checkbox"] { ...@@ -117,6 +94,7 @@ input[type="checkbox"] {
width: 100%; width: 100%;
font-size: 24px; font-size: 24px;
font-family: inherit; font-family: inherit;
font-weight: inherit;
line-height: 1.4em; line-height: 1.4em;
border: 0; border: 0;
outline: none; outline: none;
...@@ -124,29 +102,25 @@ input[type="checkbox"] { ...@@ -124,29 +102,25 @@ input[type="checkbox"] {
padding: 6px; padding: 6px;
border: 1px solid #999; border: 1px solid #999;
box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2); box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
-moz-box-sizing: border-box;
-ms-box-sizing: border-box; -ms-box-sizing: border-box;
-o-box-sizing: border-box;
box-sizing: border-box; box-sizing: border-box;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased; -moz-font-smoothing: antialiased;
-ms-font-smoothing: antialiased; -ms-font-smoothing: antialiased;
-o-font-smoothing: antialiased;
font-smoothing: antialiased; font-smoothing: antialiased;
} }
#new-todo { #new-todo {
padding: 16px 16px 16px 60px; padding: 16px 16px 16px 60px;
border: none; border: none;
background: rgba(0, 0, 0, 0.02); background: rgba(0, 0, 0, 0.003);
z-index: 2; box-shadow: inset 0 -2px 1px rgba(0,0,0,0.03);
box-shadow: none;
} }
#main { #main {
position: relative; position: relative;
z-index: 2; z-index: 2;
border-top: 1px dotted #adadad; border-top: 1px solid #e6e6e6;
} }
label[for='toggle-all'] { label[for='toggle-all'] {
...@@ -155,19 +129,19 @@ label[for='toggle-all'] { ...@@ -155,19 +129,19 @@ label[for='toggle-all'] {
#toggle-all { #toggle-all {
position: absolute; position: absolute;
top: -42px; top: -55px;
left: -4px; left: -12px;
width: 40px; width: 60px;
height: 34px;
text-align: center; text-align: center;
/* Mobile Safari */ border: none; /* Mobile Safari */
border: none;
} }
#toggle-all:before { #toggle-all:before {
content: '»'; content: '';
font-size: 28px; font-size: 22px;
color: #d9d9d9; color: #e6e6e6;
padding: 0 25px 7px; padding: 10px 27px 10px 27px;
} }
#toggle-all:checked:before { #toggle-all:checked:before {
...@@ -183,7 +157,7 @@ label[for='toggle-all'] { ...@@ -183,7 +157,7 @@ label[for='toggle-all'] {
#todo-list li { #todo-list li {
position: relative; position: relative;
font-size: 24px; font-size: 24px;
border-bottom: 1px dotted #ccc; border-bottom: 1px solid #ededed;
} }
#todo-list li:last-child { #todo-list li:last-child {
...@@ -215,28 +189,18 @@ label[for='toggle-all'] { ...@@ -215,28 +189,18 @@ label[for='toggle-all'] {
top: 0; top: 0;
bottom: 0; bottom: 0;
margin: auto 0; margin: auto 0;
/* Mobile Safari */ border: none; /* Mobile Safari */
border: none;
-webkit-appearance: none; -webkit-appearance: none;
-ms-appearance: none; -ms-appearance: none;
-o-appearance: none;
appearance: none; appearance: none;
} }
#todo-list li .toggle:after { #todo-list li .toggle:after {
content: '✔'; content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="-10 -18 100 135"><circle cx="50" cy="50" r="50" fill="none" stroke="#ededed" stroke-width="3"/></svg>');
/* 40 + a couple of pixels visual adjustment */
line-height: 43px;
font-size: 20px;
color: #d9d9d9;
text-shadow: 0 -1px 0 #bfbfbf;
} }
#todo-list li .toggle:checked:after { #todo-list li .toggle:checked:after {
color: #85ada7; content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="-10 -18 100 135"><circle cx="50" cy="50" r="50" fill="none" stroke="#bddad5" stroke-width="3"/><path fill="#5dc2af" d="M72 25L42 71 27 56l-4 4 20 20 34-52z"/></svg>');
text-shadow: 0 1px 0 #669991;
bottom: 1px;
position: relative;
} }
#todo-list li label { #todo-list li label {
...@@ -246,12 +210,11 @@ label[for='toggle-all'] { ...@@ -246,12 +210,11 @@ label[for='toggle-all'] {
margin-left: 45px; margin-left: 45px;
display: block; display: block;
line-height: 1.2; line-height: 1.2;
-webkit-transition: color 0.4s;
transition: color 0.4s; transition: color 0.4s;
} }
#todo-list li.completed label { #todo-list li.completed label {
color: #a9a9a9; color: #d9d9d9;
text-decoration: line-through; text-decoration: line-through;
} }
...@@ -264,21 +227,18 @@ label[for='toggle-all'] { ...@@ -264,21 +227,18 @@ label[for='toggle-all'] {
width: 40px; width: 40px;
height: 40px; height: 40px;
margin: auto 0; margin: auto 0;
font-size: 22px; font-size: 30px;
color: #a88a8a; color: #cc9a9a;
-webkit-transition: all 0.2s; margin-bottom: 11px;
transition: all 0.2s; transition: color 0.2s ease-out;
} }
#todo-list li .destroy:hover { #todo-list li .destroy:hover {
text-shadow: 0 0 1px #000, color: #af5b5e;
0 0 10px rgba(199, 107, 107, 0.8);
-webkit-transform: scale(1.3);
transform: scale(1.3);
} }
#todo-list li .destroy:after { #todo-list li .destroy:after {
content: ''; content: '×';
} }
#todo-list li:hover .destroy { #todo-list li:hover .destroy {
...@@ -295,29 +255,25 @@ label[for='toggle-all'] { ...@@ -295,29 +255,25 @@ label[for='toggle-all'] {
#footer { #footer {
color: #777; color: #777;
padding: 0 15px; padding: 10px 15px;
position: absolute;
right: 0;
bottom: -31px;
left: 0;
height: 20px; height: 20px;
z-index: 1;
text-align: center; text-align: center;
border-top: 1px solid #e6e6e6;
} }
#footer:before { #footer:before {
content: ''; content: '';
position: absolute; position: absolute;
right: 0; right: 0;
bottom: 31px; bottom: 0;
left: 0; left: 0;
height: 50px; height: 50px;
z-index: -1; overflow: hidden;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3), box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2),
0 6px 0 -3px rgba(255, 255, 255, 0.8), 0 8px 0 -3px #f6f6f6,
0 7px 1px -3px rgba(0, 0, 0, 0.3), 0 9px 1px -3px rgba(0, 0, 0, 0.2),
0 43px 0 -6px rgba(255, 255, 255, 0.8), 0 16px 0 -6px #f6f6f6,
0 44px 2px -6px rgba(0, 0, 0, 0.2); 0 17px 2px -6px rgba(0, 0, 0, 0.2);
} }
#todo-count { #todo-count {
...@@ -325,6 +281,10 @@ label[for='toggle-all'] { ...@@ -325,6 +281,10 @@ label[for='toggle-all'] {
text-align: left; text-align: left;
} }
#todo-count strong {
font-weight: 300;
}
#filters { #filters {
margin: 0; margin: 0;
padding: 0; padding: 0;
...@@ -339,49 +299,72 @@ label[for='toggle-all'] { ...@@ -339,49 +299,72 @@ label[for='toggle-all'] {
} }
#filters li a { #filters li a {
color: #83756f; color: inherit;
margin: 2px; margin: 3px;
padding: 3px 7px;
text-decoration: none; text-decoration: none;
border: 1px solid transparent;
border-radius: 3px;
}
#filters li a.selected,
#filters li a:hover {
border-color: rgba(175, 47, 47, 0.1);
} }
#filters li a.selected { #filters li a.selected {
font-weight: bold; border-color: rgba(175, 47, 47, 0.2);
} }
#clear-completed { #clear-completed,
html #clear-completed:active {
float: right; float: right;
position: relative; position: relative;
line-height: 20px; line-height: 20px;
text-decoration: none; text-decoration: none;
background: rgba(0, 0, 0, 0.1); cursor: pointer;
font-size: 11px; visibility: hidden;
padding: 0 10px; position: relative;
border-radius: 3px; }
box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.2);
#clear-completed::after {
visibility: visible;
content: 'Clear completed';
position: absolute;
right: 0;
white-space: nowrap;
} }
#clear-completed:hover { #clear-completed:hover::after {
background: rgba(0, 0, 0, 0.15); text-decoration: underline;
box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.3);
} }
#info { #info {
margin: 65px auto 0; margin: 65px auto 0;
color: #a6a6a6; color: #bfbfbf;
font-size: 12px; font-size: 10px;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7); text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
text-align: center; text-align: center;
} }
#info p {
line-height: 1;
}
#info a { #info a {
color: inherit; color: inherit;
text-decoration: none;
font-weight: 400;
}
#info a:hover {
text-decoration: underline;
} }
/* /*
Hack to remove background from Mobile Safari. Hack to remove background from Mobile Safari.
Can't use it globally since it destroys checkboxes in Firefox and Opera Can't use it globally since it destroys checkboxes in Firefox
*/ */
@media screen and (-webkit-min-device-pixel-ratio:0) { @media screen and (-webkit-min-device-pixel-ratio:0) {
#toggle-all, #toggle-all,
#todo-list li .toggle { #todo-list li .toggle {
...@@ -393,10 +376,6 @@ label[for='toggle-all'] { ...@@ -393,10 +376,6 @@ label[for='toggle-all'] {
} }
#toggle-all { #toggle-all {
top: -56px;
left: -15px;
width: 65px;
height: 41px;
-webkit-transform: rotate(90deg); -webkit-transform: rotate(90deg);
transform: rotate(90deg); transform: rotate(90deg);
-webkit-appearance: none; -webkit-appearance: none;
...@@ -404,151 +383,12 @@ label[for='toggle-all'] { ...@@ -404,151 +383,12 @@ label[for='toggle-all'] {
} }
} }
.hidden { @media (max-width: 430px) {
display: none; #footer {
} height: 50px;
hr {
margin: 20px 0;
border: 0;
border-top: 1px dashed #C5C5C5;
border-bottom: 1px dashed #F7F7F7;
}
.learn a {
font-weight: normal;
text-decoration: none;
color: #b83f45;
}
.learn a:hover {
text-decoration: underline;
color: #787e7e;
}
.learn h3,
.learn h4,
.learn h5 {
margin: 10px 0;
font-weight: 500;
line-height: 1.2;
color: #000;
}
.learn h3 {
font-size: 24px;
}
.learn h4 {
font-size: 18px;
}
.learn h5 {
margin-bottom: 0;
font-size: 14px;
}
.learn ul {
padding: 0;
margin: 0 0 30px 25px;
}
.learn li {
line-height: 20px;
}
.learn p {
font-size: 15px;
font-weight: 300;
line-height: 1.3;
margin-top: 0;
margin-bottom: 0;
}
.quote {
border: none;
margin: 20px 0 60px 0;
}
.quote p {
font-style: italic;
}
.quote p:before {
content: '“';
font-size: 50px;
opacity: .15;
position: absolute;
top: -20px;
left: 3px;
}
.quote p:after {
content: '”';
font-size: 50px;
opacity: .15;
position: absolute;
bottom: -42px;
right: 3px;
}
.quote footer {
position: absolute;
bottom: -40px;
right: 0;
}
.quote footer img {
border-radius: 3px;
}
.quote footer a {
margin-left: 5px;
vertical-align: middle;
}
.speech-bubble {
position: relative;
padding: 10px;
background: rgba(0, 0, 0, .04);
border-radius: 5px;
}
.speech-bubble:after {
content: '';
position: absolute;
top: 100%;
right: 30px;
border: 13px solid transparent;
border-top-color: rgba(0, 0, 0, .04);
}
.learn-bar > .learn {
position: absolute;
width: 272px;
top: 8px;
left: -300px;
padding: 10px;
border-radius: 5px;
background-color: rgba(255, 255, 255, .6);
-webkit-transition-property: left;
transition-property: left;
-webkit-transition-duration: 500ms;
transition-duration: 500ms;
}
@media (min-width: 899px) {
.learn-bar {
width: auto;
margin: 0 0 0 300px;
}
.learn-bar > .learn {
left: 8px;
} }
.learn-bar #todoapp { #filters {
width: 550px; bottom: 10px;
margin: 130px auto 40px auto;
} }
} }
hr {
margin: 20px 0;
border: 0;
border-top: 1px dashed #c5c5c5;
border-bottom: 1px dashed #f7f7f7;
}
.learn a {
font-weight: normal;
text-decoration: none;
color: #b83f45;
}
.learn a:hover {
text-decoration: underline;
color: #787e7e;
}
.learn h3,
.learn h4,
.learn h5 {
margin: 10px 0;
font-weight: 500;
line-height: 1.2;
color: #000;
}
.learn h3 {
font-size: 24px;
}
.learn h4 {
font-size: 18px;
}
.learn h5 {
margin-bottom: 0;
font-size: 14px;
}
.learn ul {
padding: 0;
margin: 0 0 30px 25px;
}
.learn li {
line-height: 20px;
}
.learn p {
font-size: 15px;
font-weight: 300;
line-height: 1.3;
margin-top: 0;
margin-bottom: 0;
}
#issue-count {
display: none;
}
.quote {
border: none;
margin: 20px 0 60px 0;
}
.quote p {
font-style: italic;
}
.quote p:before {
content: '“';
font-size: 50px;
opacity: .15;
position: absolute;
top: -20px;
left: 3px;
}
.quote p:after {
content: '”';
font-size: 50px;
opacity: .15;
position: absolute;
bottom: -42px;
right: 3px;
}
.quote footer {
position: absolute;
bottom: -40px;
right: 0;
}
.quote footer img {
border-radius: 3px;
}
.quote footer a {
margin-left: 5px;
vertical-align: middle;
}
.speech-bubble {
position: relative;
padding: 10px;
background: rgba(0, 0, 0, .04);
border-radius: 5px;
}
.speech-bubble:after {
content: '';
position: absolute;
top: 100%;
right: 30px;
border: 13px solid transparent;
border-top-color: rgba(0, 0, 0, .04);
}
.learn-bar > .learn {
position: absolute;
width: 272px;
top: 8px;
left: -300px;
padding: 10px;
border-radius: 5px;
background-color: rgba(255, 255, 255, .6);
transition-property: left;
transition-duration: 500ms;
}
@media (min-width: 899px) {
.learn-bar {
width: auto;
padding-left: 300px;
}
.learn-bar > .learn {
left: 8px;
}
}
/* global _ */
(function () { (function () {
'use strict'; 'use strict';
/* jshint ignore:start */
// Underscore's Template Module // Underscore's Template Module
// Courtesy of underscorejs.org // Courtesy of underscorejs.org
var _ = (function (_) { var _ = (function (_) {
...@@ -114,6 +116,7 @@ ...@@ -114,6 +116,7 @@
if (location.hostname === 'todomvc.com') { if (location.hostname === 'todomvc.com') {
window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script')); window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'));
} }
/* jshint ignore:end */
function redirect() { function redirect() {
if (location.hostname === 'tastejs.github.io') { if (location.hostname === 'tastejs.github.io') {
...@@ -175,13 +178,17 @@ ...@@ -175,13 +178,17 @@
if (learnJSON.backend) { if (learnJSON.backend) {
this.frameworkJSON = learnJSON.backend; this.frameworkJSON = learnJSON.backend;
this.frameworkJSON.issueLabel = framework;
this.append({ this.append({
backend: true backend: true
}); });
} else if (learnJSON[framework]) { } else if (learnJSON[framework]) {
this.frameworkJSON = learnJSON[framework]; this.frameworkJSON = learnJSON[framework];
this.frameworkJSON.issueLabel = framework;
this.append(); this.append();
} }
this.fetchIssueCount();
} }
Learn.prototype.append = function (opts) { Learn.prototype.append = function (opts) {
...@@ -212,6 +219,26 @@ ...@@ -212,6 +219,26 @@
document.body.insertAdjacentHTML('afterBegin', aside.outerHTML); document.body.insertAdjacentHTML('afterBegin', aside.outerHTML);
}; };
Learn.prototype.fetchIssueCount = function () {
var issueLink = document.getElementById('issue-count-link');
if (issueLink) {
var url = issueLink.href.replace('https://github.com', 'https://api.github.com/repos');
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onload = function (e) {
var parsedResponse = JSON.parse(e.target.responseText);
if (parsedResponse instanceof Array) {
var count = parsedResponse.length
if (count !== 0) {
issueLink.innerHTML = 'This app has ' + count + ' open issues';
document.getElementById('issue-count').style.display = 'inline';
}
}
};
xhr.send();
}
};
redirect(); redirect();
getFile('learn.json', Learn); getFile('learn.json', Learn);
})(); })();
{
"private": true,
"dependencies": {
"atma-class": "^1.0.68",
"includejs": "^0.9.10",
"jquery": "^2.1.3",
"maskjs": "^0.10.1",
"ruta": "^0.1.12",
"todomvc-common": "^1.0.1",
"todomvc-app-css": "^1.0.0",
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment