tiger
Version:
A full port of Spine.js MVC framework to Titanium Mobile, with enhancements
613 lines (537 loc) • 17.1 kB
JavaScript
// Generated by CoffeeScript 1.6.3
(function() {
var Ajax, Controller, Element, Env, Log, Module, Spine, Tiger, capitalize, event, eventList, eventWraps, extend, level, logLevels, makeArray, _fn, _fn1, _fn2, _i, _j, _k, _len, _len1, _len2, _ref, _ref1,
__slice = [].slice,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
Spine = this.Spine || require('./spine');
extend = function() {
var key, source, sources, target, val, _i, _len;
target = arguments[0], sources = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
for (_i = 0, _len = sources.length; _i < _len; _i++) {
source = sources[_i];
for (key in source) {
val = source[key];
target[key] = val;
}
}
return target;
};
makeArray = function(args) {
return Array.prototype.slice.call(args, 0);
};
Module = (function(_super) {
__extends(Module, _super);
function Module() {
_ref = Module.__super__.constructor.apply(this, arguments);
return _ref;
}
Module.include({
extend: function() {
var sources;
sources = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return extend.apply(null, [this].concat(__slice.call(sources)));
}
});
return Module;
})(Spine.Class);
Env = {};
logLevels = ['info', 'warn', 'error', 'debug', 'trace'];
Log = extend({}, Spine.Log, {
logLevel: false,
stackTraceLimit: 10,
log: function() {
var args, key, level, obj, prefix, val, _i, _len, _ref1;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
if (!Tiger.Log.trace) {
return;
}
level = (_ref1 = args[0], __indexOf.call(logLevels, _ref1) >= 0) && args.shift();
level = this.logLevel || level || 'info';
prefix = this.logPrefix && this.logPrefix + ' ' || '';
for (_i = 0, _len = args.length; _i < _len; _i++) {
obj = args[_i];
if (typeof obj === 'string') {
Ti.API.log(level, prefix + obj);
} else {
for (key in obj) {
val = obj[key];
Ti.API.log(level, prefix + ("" + key + ": " + val));
}
}
}
return this;
},
stackTrace: function(err) {
var frame, _i, _len, _ref1, _results;
if (err == null) {
err = new Error;
}
Error.stackTraceLimit = this.stackTraceLimit;
Error.prepareStackTrace = function(err, stack) {
return stack;
};
Error.captureStackTrace(err, arguments.callee);
_ref1 = err.stack;
_results = [];
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
frame = _ref1[_i];
_results.push(Log.debug("(trace) " + (frame.getFileName()) + ":" + (frame.getLineNumber()) + " - " + (frame.getFunctionName())));
}
return _results;
}
});
_fn = function(level) {
return Log[level] = function() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
args.unshift(level);
return Log.log.apply(this, args);
};
};
for (_i = 0, _len = logLevels.length; _i < _len; _i++) {
level = logLevels[_i];
_fn(level);
}
Ajax = (function(_super) {
__extends(Ajax, _super);
Ajax.include(Log);
Ajax.prototype.logPrefix = '(Ajax)';
Ajax.prototype.defaults = {
method: 'GET',
url: null,
data: false,
contentType: 'application/json',
enableKeepAlive: false,
timeout: 10000,
async: true,
autoEncodeUrl: true,
success: function() {},
error: function() {},
beforeSend: null,
complete: function() {},
onreadystatechanged: null
};
Ajax.encode = function(string) {
return Ti.Network.encodeURIComponent(string);
};
Ajax.params = function(data) {
var key, params, val;
if (data == null) {
return '';
}
params = (function() {
var _results;
_results = [];
for (key in data) {
val = data[key];
_results.push("" + (this.encode(key)) + "=" + (this.encode(val)));
}
return _results;
}).call(this);
return params.join('&');
};
Ajax.get = function(o) {
o.method = 'GET';
return new this(o);
};
Ajax.post = function(o) {
o.method = 'POST';
return new this(o);
};
Ajax.download = function(options) {
var file;
file = conf.file;
options.onload = function(xhr) {
var f;
if (xhr.responseData == null) {
return;
}
if (xhr.responseData.type === 1) {
f = Ti.Filesystem.getFile(xhr.responseData.nativePath);
if (file.exists()) {
file.deleteFile();
}
f.move(file.nativePath);
} else {
file.write(xhr.responseData);
}
return options.success(file, xhr.statusText, xhr);
};
return new this(options);
};
function Ajax(options) {
var header, name, xhr, _debug, _ref1,
_this = this;
if (options == null) {
options = {};
}
options = Tiger.extend({}, this.defaults, options);
options.method = options.method.toUpperCase();
this.debug("" + options.method + " " + options.url + " ...");
xhr = Ti.Network.createHTTPClient({
autoEncodeUrl: options.autoEncodeUrl,
async: options.async,
timeout: options.timeout
});
xhr.onerror = function() {
var error;
if (!xhr.statusText) {
if (xhr.readyState === xhr.OPENED) {
error = 'No response from server';
} else {
error = 'Unknown error';
}
}
options.error(xhr, xhr.statusText, error);
return options.complete(xhr, xhr.statusText);
};
xhr.onload = function() {
var e, response;
try {
response = xhr.responseXML;
} catch (_error) {
e = _error;
}
if (!response) {
response = xhr.responseText;
}
options.success(response, xhr.statusText, xhr);
return options.complete(xhr, xhr.statusText);
};
_debug = this.proxy(this.debug);
xhr.onreadystatechanged = options.onreadystatechanged || function() {
switch (this.readyState) {
case this.OPENED:
return _debug('readyState: opened...');
case this.HEADERS_RECEIVED:
return _debug('readyState: headers received...');
case this.LOADING:
return _debug('readyState: loading...');
case this.DONE:
return _debug('readyState: done.');
}
};
xhr.onsendstream = options.onsendstream || function(e) {
return _this.debug('Upload progress: ' + e.progress);
};
if (options.method === 'GET' && options.data) {
if (options.url.indexOf('?') !== -1) {
options.url += '&';
} else {
options.url += '?';
}
options.url += this.constructor.params(options.data);
}
if (Ti.Network.networkType === Ti.Network.NETWORK_NONE) {
this.debug("No network available. Cannot open connection to " + options.url);
return xhr;
}
xhr.open(options.method, options.url);
if (options.file) {
xhr.file = options.file;
}
if (options.headers) {
_ref1 = options.headers;
for (name in _ref1) {
header = _ref1[name];
xhr.setRequestHeader(name, header);
}
}
if (options.beforeSend) {
options.beforeSend(xhr, options);
}
if (options.data && options.method === 'POST' || options.method === 'PUT') {
this.debug("Sending " + options.data + " ...");
xhr.setRequestHeader('Content-Type', options.contentType);
xhr.send(options.data);
} else {
xhr.send();
}
xhr;
}
return Ajax;
})(Module);
Controller = (function(_super) {
__extends(Controller, _super);
Controller.include(Spine.Events);
Controller.include(Log);
Controller.prototype.eventSplitter = /^(\w+)\s*(.*)$/;
function Controller(options) {
var key, val, _ref1;
this.options = options != null ? options : {};
this.release = __bind(this.release, this);
_ref1 = this.options;
for (key in _ref1) {
val = _ref1[key];
this[key] = val;
}
this._map = {};
this._events = {};
this.elements || (this.elements = this.constructor.elements);
if (this.elements) {
this.refreshElements();
}
this.events || (this.events = this.constructor.events);
if (this.events) {
this.delegateEvents();
}
this.map || (this.map = this.constructor.map);
if (this.map) {
this.bindSynced();
}
}
Controller.prototype.refreshElements = function() {
var el, _j, _len1, _ref1;
if (!this.view) {
return;
}
_ref1 = this.elements;
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
el = _ref1[_j];
this[el] = this.view[el];
}
return this;
};
Controller.prototype.mapSelector = function(selector) {
var el, s, sel, selectors, _j, _len1;
if (el = this._map[selector]) {
return el;
}
if (__indexOf.call(selector, '.') >= 0) {
selectors = selector.split('.');
sel = selectors.shift();
el = this[sel] || (this[sel] = this.view[sel]);
for (_j = 0, _len1 = selectors.length; _j < _len1; _j++) {
s = selectors[_j];
el = el[s];
}
} else {
el = this[selector] || (this[selector] = this.view[selector]);
}
return this._map[selector] = el;
};
Controller.prototype.delegateEvents = function() {
var el, eventName, key, match, methodName, selector, _ref1;
_ref1 = this.events;
for (key in _ref1) {
methodName = _ref1[key];
this._events[key] = this.proxy(this[methodName]);
match = key.match(this.eventSplitter);
eventName = match[1];
selector = match[2];
this.debug("Binding " + selector + " " + eventName + "...");
if (selector === '') {
this.view.tiBind(eventName, this._events[key]);
} else {
el = this.mapSelector(selector);
el.tiBind(eventName, this._events[key]);
}
}
return this;
};
Controller.prototype.release = function(key) {
var el, eventName, match, selector;
if (!key) {
this.trigger('release');
this.view.remove();
return this.unbind();
} else {
match = key.match(this.eventSplitter);
eventName = match[1];
selector = match[2];
el = selector ? this.mapSelector(selector) : this.view;
return el.tiUnbind(eventName, this._events[key]);
}
};
Controller.prototype.bindSynced = function() {
var field, selector, _fn1, _ref1;
_ref1 = this.map;
_fn1 = function(field, self) {
var el;
el = self.mapSelector(selector);
if (el) {
return el.change(function(e) {
return self.store[field] = e.value;
});
}
};
for (field in _ref1) {
selector = _ref1[field];
this.debug("Binding " + field + " to " + selector + "...");
_fn1(field, this);
}
return this;
};
Controller.prototype.loadSynced = function() {
var el, field, prop, props, selector, selectors, value, _ref1;
_ref1 = this.map;
for (field in _ref1) {
selector = _ref1[field];
if (__indexOf.call(selector, '.') >= 0) {
selectors = selector.split('.');
prop = "" + (selectors.pop());
selector = selectors.join();
} else {
prop = 'value';
}
el = this._map[selector] || this.mapSelector(selector);
value = this.store[field];
if (prop === 'value') {
value || (value = '');
}
props = {};
props[prop] = value;
el.set(props);
}
return this;
};
Controller.prototype.delay = function(timeout, func) {
if (timeout == null) {
timeout = 0;
}
return setTimeout(this.proxy(func), timeout);
};
return Controller;
})(Module);
eventList = ['return', 'click', 'dblclick', 'longpress', 'swipe', 'touchstart', 'touchmove', 'touchcancel', 'touchend', 'singletap', 'twofingertap', 'pinch', 'change', 'open', 'close', 'postlayout'];
eventWraps = {};
_fn1 = function(event) {
return eventWraps[event] = function(fn) {
if (!fn) {
this.element.fireEvent(event);
} else {
this.tiBind(event, fn);
}
return this;
};
};
for (_j = 0, _len1 = eventList.length; _j < _len1; _j++) {
event = eventList[_j];
_fn1(event);
}
_ref1 = ['blur', 'focus'];
_fn2 = function(event) {
return eventWraps[event] = function(fn) {
if (!fn) {
this.element[event]();
} else {
this.tiBind(event, fn);
}
return this;
};
};
for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) {
event = _ref1[_k];
_fn2(event);
}
capitalize = function(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
};
Element = (function(_super) {
__extends(Element, _super);
Element.include(eventWraps);
function Element(props) {
if (props == null) {
props = {};
}
props = Tiger.extend({}, this.defaults || {}, props);
this.element = Ti.UI['create' + this.elementName](props);
}
Element.prototype.add = function(el) {
this.element.add(el.element || el);
return this;
};
Element.prototype.set = function(props) {
var cKey, key, val;
for (key in props) {
val = props[key];
cKey = capitalize(key);
if ('set' + cKey in this) {
this['set' + cKey](val);
} else {
this.element[key] = val;
}
}
return this;
};
Element.prototype.get = function(prop) {
var cProp;
cProp = capitalize(prop);
return this[prop] || this['get' + cProp] && this['get' + cProp]() || this.element[prop];
};
Element.prototype.hide = function() {
this.element.hide();
this.element.visible = false;
return this;
};
Element.prototype.show = function() {
this.element.show();
this.element.visible = true;
return this;
};
Element.prototype.tiBind = function(event, fn) {
this.element.addEventListener(event, fn);
return this;
};
Element.prototype.tiUnbind = function(event, fn) {
this.element.removeEventListener(event, fn);
return this;
};
Element.prototype.tiOne = function(event, fn) {
return this.tiBind(event, function() {
this.removeEventListener(event, arguments.callee);
return fn.apply(this, arguments);
});
};
Element.prototype.tiTrigger = function() {
this.element.fireEvent.apply(this.element, arguments);
return this;
};
Element.prototype.remove = function(el) {
this.element.remove(el.element || el);
return this;
};
Element.prototype.step = function() {
if (this.animations.length) {
delete this.animation;
this.animation = this.animations.shift();
this.element.animate(this.animation);
}
return this;
};
Element.prototype.animate = function(options, callback) {
var animation, callbackAndStep,
_this = this;
callbackAndStep = function() {
if (callback) {
callback();
}
return _this.step();
};
animation = Ti.UI.createAnimation(options);
animation.addEventListener('complete', callbackAndStep);
this.animations = [animation];
return this.step();
};
return Element;
})(Module);
Tiger = this.Tiger = {};
if (typeof module !== "undefined" && module !== null) {
module.exports = Tiger;
}
Tiger.version = '0.2.1';
Tiger.extend = extend;
Tiger.makeArray = makeArray;
Tiger.isArray = Spine.isArray;
Tiger.Class = Module;
Tiger.Ajax = Ajax;
Tiger.Controller = Controller;
Tiger.Element = Element;
Tiger.Env = Env;
Tiger.Events = Spine.Events;
Tiger.Log = Log;
Tiger.Model = Spine.Model;
}).call(this);