Socket
Socket
Sign inDemoInstall

3m5-coco

Package Overview
Dependencies
5
Maintainers
1
Versions
64
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.2.0 to 0.3.0

.browserslistrc

4

CHANGELOG.md
# Coco changelog
## 0.3.0
- Use Babel 7 with preset env
## 0.2.0

@@ -4,0 +8,0 @@

9

gulpfile.js

@@ -91,4 +91,9 @@ var gulp = require('gulp'),

.pipe(babel({
presets: ['es2015', 'stage-2', 'stage-3'],
plugins: ['es6-promise']
presets: [
['@babel/env', {
useBuiltIns: 'entry',
corejs: 'core-js@2',
modules: 'cjs',
}]
]
}))

@@ -95,0 +100,0 @@ .pipe(gulp.dest('lib/'));

"use strict";
require("core-js/modules/es6.array.copy-within");
require("core-js/modules/es6.array.fill");
require("core-js/modules/es6.array.find");
require("core-js/modules/es6.array.find-index");
require("core-js/modules/es7.array.flat-map");
require("core-js/modules/es6.array.from");
require("core-js/modules/es7.array.includes");
require("core-js/modules/es6.array.iterator");
require("core-js/modules/es6.array.of");
require("core-js/modules/es6.array.sort");
require("core-js/modules/es6.array.species");
require("core-js/modules/es6.date.to-primitive");
require("core-js/modules/es6.function.has-instance");
require("core-js/modules/es6.function.name");
require("core-js/modules/es6.map");
require("core-js/modules/es6.math.acosh");
require("core-js/modules/es6.math.asinh");
require("core-js/modules/es6.math.atanh");
require("core-js/modules/es6.math.cbrt");
require("core-js/modules/es6.math.clz32");
require("core-js/modules/es6.math.cosh");
require("core-js/modules/es6.math.expm1");
require("core-js/modules/es6.math.fround");
require("core-js/modules/es6.math.hypot");
require("core-js/modules/es6.math.imul");
require("core-js/modules/es6.math.log1p");
require("core-js/modules/es6.math.log10");
require("core-js/modules/es6.math.log2");
require("core-js/modules/es6.math.sign");
require("core-js/modules/es6.math.sinh");
require("core-js/modules/es6.math.tanh");
require("core-js/modules/es6.math.trunc");
require("core-js/modules/es6.number.constructor");
require("core-js/modules/es6.number.epsilon");
require("core-js/modules/es6.number.is-finite");
require("core-js/modules/es6.number.is-integer");
require("core-js/modules/es6.number.is-nan");
require("core-js/modules/es6.number.is-safe-integer");
require("core-js/modules/es6.number.max-safe-integer");
require("core-js/modules/es6.number.min-safe-integer");
require("core-js/modules/es6.number.parse-float");
require("core-js/modules/es6.number.parse-int");
require("core-js/modules/es6.object.assign");
require("core-js/modules/es7.object.define-getter");
require("core-js/modules/es7.object.define-setter");
require("core-js/modules/es7.object.entries");
require("core-js/modules/es6.object.freeze");
require("core-js/modules/es6.object.get-own-property-descriptor");
require("core-js/modules/es7.object.get-own-property-descriptors");
require("core-js/modules/es6.object.get-own-property-names");
require("core-js/modules/es6.object.get-prototype-of");
require("core-js/modules/es7.object.lookup-getter");
require("core-js/modules/es7.object.lookup-setter");
require("core-js/modules/es6.object.prevent-extensions");
require("core-js/modules/es6.object.to-string");
require("core-js/modules/es6.object.is");
require("core-js/modules/es6.object.is-frozen");
require("core-js/modules/es6.object.is-sealed");
require("core-js/modules/es6.object.is-extensible");
require("core-js/modules/es6.object.keys");
require("core-js/modules/es6.object.seal");
require("core-js/modules/es6.object.set-prototype-of");
require("core-js/modules/es7.object.values");
require("core-js/modules/es6.promise");
require("core-js/modules/es7.promise.finally");
require("core-js/modules/es6.reflect.apply");
require("core-js/modules/es6.reflect.construct");
require("core-js/modules/es6.reflect.define-property");
require("core-js/modules/es6.reflect.delete-property");
require("core-js/modules/es6.reflect.get");
require("core-js/modules/es6.reflect.get-own-property-descriptor");
require("core-js/modules/es6.reflect.get-prototype-of");
require("core-js/modules/es6.reflect.has");
require("core-js/modules/es6.reflect.is-extensible");
require("core-js/modules/es6.reflect.own-keys");
require("core-js/modules/es6.reflect.prevent-extensions");
require("core-js/modules/es6.reflect.set");
require("core-js/modules/es6.reflect.set-prototype-of");
require("core-js/modules/es6.regexp.constructor");
require("core-js/modules/es6.regexp.flags");
require("core-js/modules/es6.regexp.match");
require("core-js/modules/es6.regexp.replace");
require("core-js/modules/es6.regexp.split");
require("core-js/modules/es6.regexp.search");
require("core-js/modules/es6.regexp.to-string");
require("core-js/modules/es6.set");
require("core-js/modules/es6.symbol");
require("core-js/modules/es7.symbol.async-iterator");
require("core-js/modules/es6.string.anchor");
require("core-js/modules/es6.string.big");
require("core-js/modules/es6.string.blink");
require("core-js/modules/es6.string.bold");
require("core-js/modules/es6.string.code-point-at");
require("core-js/modules/es6.string.ends-with");
require("core-js/modules/es6.string.fixed");
require("core-js/modules/es6.string.fontcolor");
require("core-js/modules/es6.string.fontsize");
require("core-js/modules/es6.string.from-code-point");
require("core-js/modules/es6.string.includes");
require("core-js/modules/es6.string.italics");
require("core-js/modules/es6.string.iterator");
require("core-js/modules/es6.string.link");
require("core-js/modules/es7.string.pad-start");
require("core-js/modules/es7.string.pad-end");
require("core-js/modules/es6.string.raw");
require("core-js/modules/es6.string.repeat");
require("core-js/modules/es6.string.small");
require("core-js/modules/es6.string.starts-with");
require("core-js/modules/es6.string.strike");
require("core-js/modules/es6.string.sub");
require("core-js/modules/es6.string.sup");
require("core-js/modules/es7.string.trim-left");
require("core-js/modules/es7.string.trim-right");
require("core-js/modules/es6.typed.array-buffer");
require("core-js/modules/es6.typed.int8-array");
require("core-js/modules/es6.typed.uint8-array");
require("core-js/modules/es6.typed.uint8-clamped-array");
require("core-js/modules/es6.typed.int16-array");
require("core-js/modules/es6.typed.uint16-array");
require("core-js/modules/es6.typed.int32-array");
require("core-js/modules/es6.typed.uint32-array");
require("core-js/modules/es6.typed.float32-array");
require("core-js/modules/es6.typed.float64-array");
require("core-js/modules/es6.weak-map");
require("core-js/modules/es6.weak-set");
require("core-js/modules/web.timers");
require("core-js/modules/web.immediate");
require("core-js/modules/web.dom.iterable");
require("regenerator-runtime/runtime");
// Rewrite modern console methods for olders browsers (like IE 9/10)
if (!window.console) {
window.console = {};
window.console = {};
}
if (!window.console.debug) {
window.console.debug = window.console.log || function () {};
window.console.debug = window.console.log || function () {};
}
if (!window.console.error) {
window.console.error = window.console.log || function () {};
window.console.error = window.console.log || function () {};
}
if (!window.console.warn) {
window.console.warn = window.console.log || function () {};
}
window.console.warn = window.console.log || function () {};
} //IE support
//IE support
var Event = Event || window.Event;
Event.prototype.stopPropagation = Event.prototype.stopPropagation || function () {
this.cancelBubble = true;
this.cancelBubble = true;
};
Event.prototype.preventDefault = Event.prototype.preventDefault || function () {
this.returnValue = false;
};
this.returnValue = false;
}; //add $compute function to all functions
//add $compute function to all functions
/** $compute function to register change listeners to properties in Coco.Model */
if (!Function.prototype.$compute) {
Function.prototype.$compute = function () {
var fn = this;
var args = Array.prototype.slice.call(arguments);
Function.prototype.$compute = function () {
var fn = this;
var args = Array.prototype.slice.call(arguments);
/**
* We capsule the function and the $compute properties, because our this context is the function and not the
* model. When the model gets instantiated we call this returned function with the model context, set the observers
* and return the original function (with assigned model context) back to the initial model property.
*/
/**
* We capsule the function and the $compute properties, because our this context is the function and not the
* model. When the model gets instantiated we call this returned function with the model context, set the observers
* and return the original function (with assigned model context) back to the initial model property.
*/
var retFn = function retFn(targetAttribute, observers) {
for (var i = 0; i < args.length; i++) {
observers.push({
attribute: args[i],
target: targetAttribute,
old: fn.call(this)
});
}
var retFn = function retFn(targetAttribute, observers) {
for (var i = 0; i < args.length; i++) {
observers.push({
attribute: args[i],
target: targetAttribute,
old: fn.call(this)
});
}
return fn.$bind(this);
};
return fn.$bind(this);
}; // Assign a flag to the function, that we can distinct between normal functions as attributes and computed properties.
// Assign a flag to the function, that we can distinct between normal functions as attributes and computed properties.
retFn.isComputed = true;
return retFn;
};
}
retFn.isComputed = true;
return retFn;
};
} // Dependencies
// Dependencies
var Coco = Coco || {};

@@ -65,15 +325,13 @@

$ = require("jquery");
window.$ = $;
window.jQuery = $;
window.jQuery = $; //require non public Coco classes
//use babel-polyfill for IE support
require("babel-polyfill");
require("./service/Coco.ServiceContainer.js");
//require non public Coco classes
require("./service/Coco.ServiceContainer.js");
require("./helpers/HandlebarsHelpers.js");
require("./router/Coco.RouterService.js");
var Translator = require("./lib/Coco.Translator.js");
/**

@@ -104,96 +362,86 @@ * Class: .Coco

*/
Coco.SDK = dejavu.Class.declare({
$name: "Coco.Init",
////////////////////////////////////////////////////////////
//////// CONFIGURATION
config: {
baseUrl: "/", //server context path
router: {
loaderDelay: 300 // When views are swapped by Router, this time adjusts when the loading class
},
restService: { //restService configuration
path: "rest/", //restService path
cacheGet: 0 //cache time in SECONDS for GET Requests of same url, value lower than 0 causes unlimited cache
}
},
//////// CLASS DEFINITIONS
Event: require("./event/Coco.Event.js"),
ModelEvent: require("./event/Coco.ModelEvent.js"),
RestServiceEvent: require("./event/Coco.RestServiceEvent.js"),
RouterEvent: require("./event/Coco.RouterEvent.js"),
TranslatorEvent: require("./event/Coco.TranslatorEvent.js"),
ViewEvent: require("./event/Coco.ViewEvent.js"),
Coco.SDK = dejavu.Class.declare({
$name: "Coco.Init",
////////////////////////////////////////////////////////////
//////// CONFIGURATION
config: {
baseUrl: "/",
//server context path
router: {
loaderDelay: 300 // When views are swapped by Router, this time adjusts when the loading class
EventDispatcher: require("./event/Coco.EventDispatcher.js"),
},
restService: {
//restService configuration
path: "rest/",
//restService path
cacheGet: 0 //cache time in SECONDS for GET Requests of same url, value lower than 0 causes unlimited cache
//PACKAGE MODEL
Model: require("./model/Coco.Model.js"),
Collection: require("./model/Coco.Collection.js"),
}
},
//////// CLASS DEFINITIONS
Event: require("./event/Coco.Event.js"),
ModelEvent: require("./event/Coco.ModelEvent.js"),
RestServiceEvent: require("./event/Coco.RestServiceEvent.js"),
RouterEvent: require("./event/Coco.RouterEvent.js"),
TranslatorEvent: require("./event/Coco.TranslatorEvent.js"),
ViewEvent: require("./event/Coco.ViewEvent.js"),
EventDispatcher: require("./event/Coco.EventDispatcher.js"),
//PACKAGE MODEL
Model: require("./model/Coco.Model.js"),
Collection: require("./model/Coco.Collection.js"),
//PACKAGE SERVICE
Service: require("./service/Coco.Service.js"),
ServiceProvider: require("./service/Coco.ServiceProvider.js"),
//PACKAGE ROUTER
Router: require("./router/Coco.Router.js"),
//REST
BaseRestService: require("./service/Coco.BaseRestService.js"),
//PACKAGE LIB
Math: require("./lib/Coco.Math.js"),
Utils: require("./lib/Coco.Utils.js"),
Storage: require("./lib/Coco.Storage.js"),
StringUtils: require("./lib/Coco.StringUtils.js"),
URLHelper: require("./lib/Coco.URLHelper.js"),
//PACKAGE VIEW
View: require("./view/Coco.View.js"),
ChildView: require("./view/Coco.ChildView.js"),
//i18n Translator
Translator: new Translator(),
//////// CLASS DEFINITIONS END
////////////////////////////////////////////////////////////
$statics: {
version: "0.3.0",
initialized: false
},
initialize: function initialize() {
console.logWithDate = true;
//PACKAGE SERVICE
Service: require("./service/Coco.Service.js"),
ServiceProvider: require("./service/Coco.ServiceProvider.js"),
try {
Handlebars;
} catch (error) {
console.error(error);
throw new Error("Missing Handlebars! include npm-module 'handlebars' into your project!");
}
//PACKAGE ROUTER
Router: require("./router/Coco.Router.js"),
try {
$;
} catch (error) {
console.error(error);
throw new Error("Missing jQuery! Install jQuery to use Coco.SDK ", error);
}
//REST
BaseRestService: require("./service/Coco.BaseRestService.js"),
//PACKAGE LIB
Math: require("./lib/Coco.Math.js"),
Utils: require("./lib/Coco.Utils.js"),
Storage: require("./lib/Coco.Storage.js"),
StringUtils: require("./lib/Coco.StringUtils.js"),
URLHelper: require("./lib/Coco.URLHelper.js"),
//PACKAGE VIEW
View: require("./view/Coco.View.js"),
ChildView: require("./view/Coco.ChildView.js"),
//i18n Translator
Translator: new Translator(),
//////// CLASS DEFINITIONS END
////////////////////////////////////////////////////////////
$statics: {
version: "0.2.0",
initialized: false
},
initialize: function initialize() {
console.logWithDate = true;
try {
Handlebars;
} catch (error) {
console.error(error);
throw new Error("Missing Handlebars! include npm-module 'handlebars' into your project!");
}
try {
$;
} catch (error) {
console.error(error);
throw new Error("Missing jQuery! Install jQuery to use Coco.SDK ", error);
}
console.debug("-------------------------------------------");
console.debug("Coco.js v" + this.$static.version + " initialized. Coco.config on startup: ", $.extend({}, this.config));
console.debug("Bugreport@ GitHub: https://github.com/3m5/coco/issues");
console.debug("Handlebars v" + Handlebars.VERSION);
console.debug("registered Handlebars helpers: ", Handlebars.helpers);
console.debug("jQuery v" + $().jquery);
console.debug("-------------------------------------------");
$("body").trigger(this.Event.INITIALIZED);
this.initialized = true;
}
console.debug("-------------------------------------------");
console.debug("Coco.js v" + this.$static.version + " initialized. Coco.config on startup: ", $.extend({}, this.config));
console.debug("Bugreport@ GitHub: https://github.com/3m5/coco/issues");
console.debug("Handlebars v" + Handlebars.VERSION);
console.debug("registered Handlebars helpers: ", Handlebars.helpers);
console.debug("jQuery v" + $().jquery);
console.debug("-------------------------------------------");
$("body").trigger(this.Event.INITIALIZED);
this.initialized = true;
}
});
module.exports = new Coco.SDK();

@@ -1,2 +0,2 @@

'use strict';
"use strict";

@@ -29,3 +29,2 @@ /**

data: null,
//available types are:

@@ -38,2 +37,3 @@ $constants: {

INITIALIZED: 'coco:initialized',
/**

@@ -44,2 +44,3 @@ * Event: ADD

ADD: 'coco:add',
/**

@@ -50,2 +51,3 @@ * Event: AUTHORIZATION_FAILED

AUTHORIZATION_FAILED: 'coco:authorization_failed',
/**

@@ -56,2 +58,3 @@ * Event: CHANGE

CHANGE: 'coco:change',
/**

@@ -62,2 +65,3 @@ * Event: CHANGE_KEY

CHANGE_KEY: 'coco:change:',
/**

@@ -68,2 +72,3 @@ * Event: DESTROY

DESTROY: 'coco:destroy',
/**

@@ -74,2 +79,3 @@ * Event: INTERNAL_SERVER_ERROR

INTERNAL_SERVER_ERROR: 'coco:internal_server_error',
/**

@@ -80,2 +86,3 @@ * Event: INVALID

INVALID: 'coco:invalid',
/**

@@ -86,2 +93,3 @@ * Event: REMOVE

REMOVE: 'coco:remove',
/**

@@ -92,2 +100,3 @@ * Event: RENDER

RENDER: 'coco:render',
/**

@@ -98,2 +107,3 @@ * Event: RESET

RESET: 'coco:reset',
/**

@@ -104,2 +114,3 @@ * Event: REST_SERVER_ERROR

REST_SERVER_ERROR: 'coco:rest-server-error',
/**

@@ -110,2 +121,3 @@ * Event: SORTED

SORTED: 'coco:sorted',
/**

@@ -112,0 +124,0 @@ * Event: VALID

"use strict";
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }

@@ -16,270 +16,276 @@ /**

module.exports = dejavu.Class.declare({
$name: "Coco.EventDispatcher",
$name: "Coco.EventDispatcher",
/**
* Private map of listeners.
*/
__listeners: {},
/**
* Private map of listeners.
*/
__listeners: {},
$abstracts: {
/**
* Function: {abstract} getId()
*
* returns unique identifier for inheritance, it's needed to get unique event context
*
* If you inherit from Coco.Event you always have to implement this function.
*
* @returns: {String} uid
*/
getId: function getId() {}
},
$abstracts: {
/**
* Function: {abstract} getId()
/**
* Ctor.
*/
initialize: function initialize() {},
/**
* Function: addEventListener
*
* returns unique identifier for inheritance, it's needed to get unique event context
* Description:
* Adds an event listener to this class. Save the returned event listener handle for removing this listener again.
*
* If you inherit from Coco.Event you always have to implement this function.
* Parameter:
* @param {string} eventType - The event type to listen to
*
* @returns: {String} uid
* @param {Function} listener - The event listener function
*
* @param {boolean} $once - Flag if the listener should only listen for first event
*
* Return:
* @returns {Symbol} listener handle for removing event listeners again
*/
getId: function getId() {}
},
addEventListener: function addEventListener(eventType, listener, $once) {
if (eventType == null) {
throw new Error("Missing eventType parameter in " + this.$name + ".addEventListener", _typeof(eventType), eventType);
}
/**
* Ctor.
*/
initialize: function initialize() {},
if (typeof eventType !== 'string') {
throw new Error("Invalid eventType parameter in " + this.$name + ".addEventListener ", _typeof(eventType), eventType);
}
/**
* Function: addEventListener
*
* Description:
* Adds an event listener to this class. Save the returned event listener handle for removing this listener again.
*
* Parameter:
* @param {string} eventType - The event type to listen to
*
* @param {Function} listener - The event listener function
*
* @param {boolean} $once - Flag if the listener should only listen for first event
*
* Return:
* @returns {Symbol} listener handle for removing event listeners again
*/
addEventListener: function addEventListener(eventType, listener, $once) {
if (eventType == null) {
throw new Error("Missing eventType parameter in " + this.$name + ".addEventListener", typeof eventType === "undefined" ? "undefined" : _typeof(eventType), eventType);
}
if (typeof eventType !== 'string') {
throw new Error("Invalid eventType parameter in " + this.$name + ".addEventListener ", typeof eventType === "undefined" ? "undefined" : _typeof(eventType), eventType);
}
if (listener == null) {
throw new Error("Missing listener parameter in " + this.$name + ".addEventListener");
}
if (typeof listener !== 'function') {
throw new Error("Invalid listener parameter in " + this.$name + ".addEventListener");
}
if (listener == null) {
throw new Error("Missing listener parameter in " + this.$name + ".addEventListener");
}
// create unique handle by ES6 Symbol
var handle = Symbol();
if (typeof listener !== 'function') {
throw new Error("Invalid listener parameter in " + this.$name + ".addEventListener");
} // create unique handle by ES6 Symbol
// create array of listeners if not exists yet
if (!$.isArray(this.__listeners[eventType])) {
this.__listeners[eventType] = [];
}
// create listener object
var listenerObject = {
handle: handle,
listener: listener
};
var handle = Symbol(); // create array of listeners if not exists yet
if ($once) {
listenerObject.once = true;
}
this.__listeners[eventType].push(listenerObject);
if (!$.isArray(this.__listeners[eventType])) {
this.__listeners[eventType] = [];
} // create listener object
return handle;
},
/**
* Function: addOnceEventListener
*
* Adds an event listener to this class that will only be called on first event. Save the returned event listener handle for removing this listener again.
*
* Parameter:
* @param {string} eventType - The event type to listen to
*
* @param {Function} listener - The event listener function
*
* Return:
* @returns {number} listener handle for removing event listeners again
*/
addOnceEventListener: function addOnceEventListener(eventType, listener) {
return this.addEventListener(eventType, listener, true);
},
var listenerObject = {
handle: handle,
listener: listener
};
/**
* Function: removeAllEventListener
*
* Removes all event listener from this class.
*/
removeAllEventListener: function removeAllEventListener() {
delete this.__listeners;
this.__listeners = {};
},
if ($once) {
listenerObject.once = true;
}
this.__listeners[eventType].push(listenerObject);
/**
* Function: removeEventListener
*
* Removes an event listener from this class. If there is no such event listener the method does nothing.
*
* Parameter:
* @param {Symbol|String} handle - The event type to remove all event listeners for or the event handle to remove a specific event listener.
*/
removeEventListener: function removeEventListener(eventTypeOrHandle) {
if (eventTypeOrHandle == null) {
throw new Error("Missing parameter in " + this.$name + ".removeEventListener");
}
if (typeof eventTypeOrHandle === 'string') {
this.__removeEventListenerByEventType(eventTypeOrHandle);
} else if ((typeof eventTypeOrHandle === "undefined" ? "undefined" : _typeof(eventTypeOrHandle)) === "symbol") {
this.__removeEventListenerByHandle(eventTypeOrHandle);
} else if ((typeof eventTypeOrHandle === "undefined" ? "undefined" : _typeof(eventTypeOrHandle)) === "object" && ("" + eventTypeOrHandle).indexOf("Symbol()") > -1) {
//for older browsers
this.__removeEventListenerByHandle(eventTypeOrHandle);
} else {
console.error(this.$name + ".removeEventListener - Parameter: ", eventTypeOrHandle);
throw new Error("Invalid parameter in " + this.$name + ".removeEventListener");
}
},
return handle;
},
/**
* Function: hasEventListener
*
* Checks if there is an event listener for the given event type.
*
* Parameter:
* @param {string} eventType - The event type to check for event listeners.
*
* Return:
* @returns {boolean} true if the event dispatcher has event listeners for the given event type
*/
hasEventListener: function hasEventListener(eventType) {
if (eventType == null) {
throw new Error("Missing eventType parameter in " + this.$name + ".hasEventListener", typeof eventType === "undefined" ? "undefined" : _typeof(eventType), eventType);
}
if (typeof eventType !== 'string') {
throw new Error("Invalid eventType parameter in " + this.$name + ".hasEventListener", typeof eventType === "undefined" ? "undefined" : _typeof(eventType), eventType);
}
/**
* Function: addOnceEventListener
*
* Adds an event listener to this class that will only be called on first event. Save the returned event listener handle for removing this listener again.
*
* Parameter:
* @param {string} eventType - The event type to listen to
*
* @param {Function} listener - The event listener function
*
* Return:
* @returns {number} listener handle for removing event listeners again
*/
addOnceEventListener: function addOnceEventListener(eventType, listener) {
return this.addEventListener(eventType, listener, true);
},
return $.isArray(this.__listeners[eventType]) && this.__listeners[eventType].length > 0;
},
/**
* Function: removeAllEventListener
*
* Removes all event listener from this class.
*/
removeAllEventListener: function removeAllEventListener() {
delete this.__listeners;
this.__listeners = {};
},
/**
* Function: __removeEventListenerByEventType
*
* Removes all event listener with for the given event type from this class.
*
* Parameter:
* @param {string} eventType - The event type to remove all event listeners for.
*/
__removeEventListenerByEventType: function __removeEventListenerByEventType(eventType) {
// check if we have event listeners
if (this.__listeners[eventType] == null || this.__listeners[eventType].length == 0) {
return;
}
/**
* Function: removeEventListener
*
* Removes an event listener from this class. If there is no such event listener the method does nothing.
*
* Parameter:
* @param {Symbol|String} handle - The event type to remove all event listeners for or the event handle to remove a specific event listener.
*/
removeEventListener: function removeEventListener(eventTypeOrHandle) {
if (eventTypeOrHandle == null) {
throw new Error("Missing parameter in " + this.$name + ".removeEventListener");
}
delete this.__listeners[eventType];
},
if (typeof eventTypeOrHandle === 'string') {
this.__removeEventListenerByEventType(eventTypeOrHandle);
} else if (_typeof(eventTypeOrHandle) === "symbol") {
this.__removeEventListenerByHandle(eventTypeOrHandle);
} else if (_typeof(eventTypeOrHandle) === "object" && ("" + eventTypeOrHandle).indexOf("Symbol()") > -1) {
//for older browsers
this.__removeEventListenerByHandle(eventTypeOrHandle);
} else {
console.error(this.$name + ".removeEventListener - Parameter: ", eventTypeOrHandle);
throw new Error("Invalid parameter in " + this.$name + ".removeEventListener");
}
},
/**
* Function: __removeEventListenerByHandle
*
* Removes an event listener with the given handle from this class.
*
* Parameter:
* @param {number} handle - The event listener handle to remove.
*/
__removeEventListenerByHandle: function __removeEventListenerByHandle(handle) {
// iterate over all event types
for (var eventType in this.__listeners) {
var listeners = this.__listeners[eventType];
/**
* Function: hasEventListener
*
* Checks if there is an event listener for the given event type.
*
* Parameter:
* @param {string} eventType - The event type to check for event listeners.
*
* Return:
* @returns {boolean} true if the event dispatcher has event listeners for the given event type
*/
hasEventListener: function hasEventListener(eventType) {
if (eventType == null) {
throw new Error("Missing eventType parameter in " + this.$name + ".hasEventListener", _typeof(eventType), eventType);
}
// iterate over all listeners for this event type
var i = -1;
var foundHandle = false;
while (++i < listeners.length) {
var listener = listeners[i];
if (listener.handle === handle) {
// found matching handle
listeners.splice(i, 1);
foundHandle = true;
break;
}
}
if (typeof eventType !== 'string') {
throw new Error("Invalid eventType parameter in " + this.$name + ".hasEventListener", _typeof(eventType), eventType);
}
// cleanup
if (foundHandle) {
if (listeners.length == 0) {
// remove listeners array
delete this.__listeners[eventType];
}
break;
}
}
},
return $.isArray(this.__listeners[eventType]) && this.__listeners[eventType].length > 0;
},
/**
* Function: _dispatchEvent
*
* Dispatches an event to all event listeners. If there are no event listeners nothing happens.
*
* Parameter:
* @param {Coco.Event} event - The event type to dispatch. You can supply a string as shortcut when you don't want to pass any parameters to the event listener.
*/
_dispatchEvent: function _dispatchEvent(event) {
if (event == null) {
throw new Error("Missing event parameter in " + this.$name + "._dispatchEvent");
}
/**
* Function: __removeEventListenerByEventType
*
* Removes all event listener with for the given event type from this class.
*
* Parameter:
* @param {string} eventType - The event type to remove all event listeners for.
*/
__removeEventListenerByEventType: function __removeEventListenerByEventType(eventType) {
// check if we have event listeners
if (this.__listeners[eventType] == null || this.__listeners[eventType].length == 0) {
return;
}
// get event type
var eventType = null;
var hasEventParam = false;
//console.warn("check eventType: ", event);
if (typeof event === 'string') {
eventType = event;
} else if (event instanceof require("./Coco.Event.js")) {
eventType = event.type;
hasEventParam = true;
} else {
throw new Error("Unknown event parameter in " + this.$name + "._dispatchEvent. Must be typeof string!");
}
delete this.__listeners[eventType];
},
// check if we have event listeners
if (!this.hasEventListener(eventType)) {
//no listern, do not dispatch event/ do not call listener
return;
}
var listeners = this.__listeners[eventType];
/**
* Function: __removeEventListenerByHandle
*
* Removes an event listener with the given handle from this class.
*
* Parameter:
* @param {number} handle - The event listener handle to remove.
*/
__removeEventListenerByHandle: function __removeEventListenerByHandle(handle) {
// iterate over all event types
for (var eventType in this.__listeners) {
var listeners = this.__listeners[eventType]; // iterate over all listeners for this event type
// iterate over all event listeners
var i = -1;
while (++i < listeners.length) {
if (listeners[i] == null || listeners[i].listener == null) {
console.warn("invalid eventlistener registered: ", listeners[i]);
continue;
}
var i = -1;
var foundHandle = false;
if (hasEventParam) {
// dispatch event
listeners[i].listener(event);
} else {
// call listener without event as shortcut for "dispatchEvent('MYEVENT')"
listeners[i].listener();
}
while (++i < listeners.length) {
var listener = listeners[i];
if (listeners[i] && listeners[i].once) {
// remove once listener
listeners.splice(i, 1);
i--;
}
}
if (listener.handle === handle) {
// found matching handle
listeners.splice(i, 1);
foundHandle = true;
break;
}
} // cleanup
// check if we just removed the last once listener
if (listeners.length == 0) {
// ... and remove event type array from listeners map
delete this.__listeners[eventType];
}
}
if (foundHandle) {
if (listeners.length == 0) {
// remove listeners array
delete this.__listeners[eventType];
}
break;
}
}
},
/**
* Function: _dispatchEvent
*
* Dispatches an event to all event listeners. If there are no event listeners nothing happens.
*
* Parameter:
* @param {Coco.Event} event - The event type to dispatch. You can supply a string as shortcut when you don't want to pass any parameters to the event listener.
*/
_dispatchEvent: function _dispatchEvent(event) {
if (event == null) {
throw new Error("Missing event parameter in " + this.$name + "._dispatchEvent");
} // get event type
var eventType = null;
var hasEventParam = false; //console.warn("check eventType: ", event);
if (typeof event === 'string') {
eventType = event;
} else if (event instanceof require("./Coco.Event.js")) {
eventType = event.type;
hasEventParam = true;
} else {
throw new Error("Unknown event parameter in " + this.$name + "._dispatchEvent. Must be typeof string!");
} // check if we have event listeners
if (!this.hasEventListener(eventType)) {
//no listern, do not dispatch event/ do not call listener
return;
}
var listeners = this.__listeners[eventType]; // iterate over all event listeners
var i = -1;
while (++i < listeners.length) {
if (listeners[i] == null || listeners[i].listener == null) {
console.warn("invalid eventlistener registered: ", listeners[i]);
continue;
}
if (hasEventParam) {
// dispatch event
listeners[i].listener(event);
} else {
// call listener without event as shortcut for "dispatchEvent('MYEVENT')"
listeners[i].listener();
}
if (listeners[i] && listeners[i].once) {
// remove once listener
listeners.splice(i, 1);
i--;
}
} // check if we just removed the last once listener
if (listeners.length == 0) {
// ... and remove event type array from listeners map
delete this.__listeners[eventType];
}
}
});

@@ -13,44 +13,47 @@ "use strict";

*/
module.exports = dejavu.Class.declare({
$name: "Coco.ModelEvent",
$extends: Coco.Event,
$name: "Coco.ModelEvent",
$extends: Coco.Event,
/**
* Variable: model
*
* Description:
* <Coco.Model> or <Coco.Collection> that dispatched this event.
*/
model: null,
/**
* Variable: key
*
* Description:
* Key that has changed in case of an change event.
*/
key: null,
/**
* Variable: model
*
* Description:
* <Coco.Model> or <Coco.Collection> that dispatched this event.
*/
model: null,
/**
* Function: Constructor
*
* Parameter:
* @param {string} type - the type of this event
*
* @param {Coco.Model|Coco.Collection} model - The <Coco.Model> or <Coco.Collection> that dispatched the event
*
* @param {string} $key - {optional} The key in the <Coco.Collection> that has changed in case of an change event
*/
initialize: function initialize(type, model, $key) {
this.$super(type);
if (model == null) {
throw new Error("Missing model parameter in " + this.$name + ".initialize");
}
if (!(model instanceof require("../model/Coco.Model.js") || model instanceof require("../model/Coco.Collection.js"))) {
throw new Error("Invalid model parameter in " + this.$name + ".initialize. Must be Coco.Model or Coco.Collection!");
}
/**
* Variable: key
*
* Description:
* Key that has changed in case of an change event.
*/
key: null,
this.model = model;
this.key = $key;
/**
* Function: Constructor
*
* Parameter:
* @param {string} type - the type of this event
*
* @param {Coco.Model|Coco.Collection} model - The <Coco.Model> or <Coco.Collection> that dispatched the event
*
* @param {string} $key - {optional} The key in the <Coco.Collection> that has changed in case of an change event
*/
initialize: function initialize(type, model, $key) {
this.$super(type);
if (model == null) {
throw new Error("Missing model parameter in " + this.$name + ".initialize");
}
if (!(model instanceof require("../model/Coco.Model.js") || model instanceof require("../model/Coco.Collection.js"))) {
throw new Error("Invalid model parameter in " + this.$name + ".initialize. Must be Coco.Model or Coco.Collection!");
}
this.model = model;
this.key = $key;
}
});

@@ -13,39 +13,41 @@ "use strict";

*/
module.exports = dejavu.Class.declare({
$name: "Coco.RestServiceEvent",
$extends: Coco.Event,
$name: "Coco.RestServiceEvent",
$extends: Coco.Event,
/**
* Variable: error
*
* Description:
* {object} the (response) error
*/
error: null,
/**
* Variable: error
*
* Description:
* {object} the (response) error
*/
error: null,
/**
* Variable: status
*
* Description:
* {int} the (response) error state (default: -1)
*/
status: -1,
/**
* Variable: status
*
* Description:
* {int} the (response) error state (default: -1)
*/
status: -1,
/**
* Function: Constructor
*
* Parameter:
* @param {string} type - The type of this dispatched the event
* @param {int} status - http status of RESTService Response
* @param {object} error - the error object
*/
initialize: function initialize(type, status, $error) {
this.$super(type);
if (status == null) {
throw new Error("Missing status parameter in " + this.$name + ".initialize");
}
this.status = status;
this.error = $error;
/**
* Function: Constructor
*
* Parameter:
* @param {string} type - The type of this dispatched the event
* @param {int} status - http status of RESTService Response
* @param {object} error - the error object
*/
initialize: function initialize(type, status, $error) {
this.$super(type);
if (status == null) {
throw new Error("Missing status parameter in " + this.$name + ".initialize");
}
this.status = status;
this.error = $error;
}
});

@@ -13,63 +13,69 @@ "use strict";

*/
module.exports = dejavu.Class.declare({
$name: "Coco.RouterEvent",
$extends: Coco.Event,
$name: "Coco.RouterEvent",
$extends: Coco.Event,
/**
* Variable: newRoute {object}
*
* Description:
* the new route changed to
*/
newRoute: null,
/**
* Variable: oldRoute {object}
*
* the old route changed from
*/
oldRoute: null,
$constants: {
/**
* Variable: newRoute {object}
*
* Description:
* the new route changed to
* Event: CHANGE_ROUTE
* Called in <Coco.RouterService> when the url changed.
*/
newRoute: null,
CHANGE_ROUTE: 'coco:route:change',
/**
* Variable: oldRoute {object}
*
* the old route changed from
* Event: FIRE_ROUTE
*/
oldRoute: null,
FIRE_ROUTE: 'coco:route:fire',
$constants: {
/**
* Event: CHANGE_ROUTE
* Called in <Coco.RouterService> when the url changed.
*/
CHANGE_ROUTE: 'coco:route:change',
/**
* Event: FIRE_ROUTE
*/
FIRE_ROUTE: 'coco:route:fire',
/**
* Event: HIDE_VIEW
* Called in <Coco.RouterService> when the url changed.
*/
HIDE_VIEW: 'coco:view:hide',
/**
* Event: SHOW_VIEW
* Called in <Coco.RouterService> when the url changed.
*/
SHOW_VIEW: 'coco:view:show'
},
/**
* Event: HIDE_VIEW
* Called in <Coco.RouterService> when the url changed.
*/
HIDE_VIEW: 'coco:view:hide',
/**
* Function: Constructor
*
* Parameter:
* @param {string} type - The type that dispatched the event
* @param {object} newRoute - The new route changed to
* @param {object} oldRoute - The old route changed from
* Event: SHOW_VIEW
* Called in <Coco.RouterService> when the url changed.
*/
initialize: function initialize(type, newRoute, oldRoute) {
this.$super(type);
if (newRoute == null) {
throw new Error("Missing newRoute parameter in " + this.$name + ".initialize");
}
this.newRoute = newRoute;
if (oldRoute == null) {
throw new Error("Missing oldRoute parameter in " + this.$name + ".initialize");
}
this.oldRoute = oldRoute;
SHOW_VIEW: 'coco:view:show'
},
/**
* Function: Constructor
*
* Parameter:
* @param {string} type - The type that dispatched the event
* @param {object} newRoute - The new route changed to
* @param {object} oldRoute - The old route changed from
*/
initialize: function initialize(type, newRoute, oldRoute) {
this.$super(type);
if (newRoute == null) {
throw new Error("Missing newRoute parameter in " + this.$name + ".initialize");
}
this.newRoute = newRoute;
if (oldRoute == null) {
throw new Error("Missing oldRoute parameter in " + this.$name + ".initialize");
}
this.oldRoute = oldRoute;
}
});

@@ -13,37 +13,38 @@ "use strict";

*/
module.exports = dejavu.Class.declare({
$name: "Coco.TranslatorEvent",
$extends: Coco.Event,
$name: "Coco.TranslatorEvent",
$extends: Coco.Event,
/**
* Variable: locale {string}
*
* Description:
* the current locale
*/
locale: null,
$constants: {
/**
* Variable: locale {string}
*
* Description:
* the current locale
* Event: CHANGE_LOCALE
* Called in <Coco.Translator> when the locale was changed.
*/
locale: null,
CHANGE_LOCALE: 'coco:locale:change'
},
$constants: {
/**
* Event: CHANGE_LOCALE
* Called in <Coco.Translator> when the locale was changed.
*/
CHANGE_LOCALE: 'coco:locale:change'
},
/**
* Function: Constructor
*
* Parameter:
* @param {string} type - The type that dispatched the event
* @param {string} locale - The current locale
*/
initialize: function initialize(type, locale) {
this.$super(type);
/**
* Function: Constructor
*
* Parameter:
* @param {string} type - The type that dispatched the event
* @param {string} locale - The current locale
*/
initialize: function initialize(type, locale) {
this.$super(type);
if (locale == null) {
throw new Error("Missing locale parameter in " + this.$name + ".initialize");
}
this.locale = locale;
if (locale == null) {
throw new Error("Missing locale parameter in " + this.$name + ".initialize");
}
this.locale = locale;
}
});

@@ -13,31 +13,34 @@ "use strict";

*/
module.exports = dejavu.Class.declare({
$name: "Coco.ViewEvent",
$extends: Coco.Event,
$name: "Coco.ViewEvent",
$extends: Coco.Event,
/**
* Variable: view
*
* Description:
* <Coco.View> that dispatched this event.
*/
view: null,
/**
* Variable: view
*
* Description:
* <Coco.View> that dispatched this event.
*/
view: null,
/**
* Function: Constructor
*
* Parameter:
* @param {<Coco.View>} view - The <Coco.View> that dispatched the event
*/
initialize: function initialize(type, view) {
this.$super(type);
if (view == null) {
throw new Error("Missing view parameter in " + this.$name + ".initialize");
}
if (!(view instanceof require("../view/Coco.View.js"))) {
throw new Error("Invalid view parameter in " + this.$name + ".initialize. Must be Coco.View!");
}
this.view = view;
/**
* Function: Constructor
*
* Parameter:
* @param {<Coco.View>} view - The <Coco.View> that dispatched the event
*/
initialize: function initialize(type, view) {
this.$super(type);
if (view == null) {
throw new Error("Missing view parameter in " + this.$name + ".initialize");
}
if (!(view instanceof require("../view/Coco.View.js"))) {
throw new Error("Invalid view parameter in " + this.$name + ".initialize. Must be Coco.View!");
}
this.view = view;
}
});

@@ -1,2 +0,2 @@

'use strict';
"use strict";

@@ -7,130 +7,127 @@ /**

*/
var Handlebars = require('handlebars/runtime');
var Handlebars = require('handlebars/runtime'),
JSON = require("JSON");
Handlebars.registerHelper('getText', function (key, $replace) {
var Coco = require("../Coco.Init.js"); //console.log(".$replace: ", $replace);
//if $replace is not set in template, its not null here, its an handlebars object...
Handlebars.registerHelper('getText', function (key, $replace) {
var Coco = require("../Coco.Init.js");
//console.log(".$replace: ", $replace);
//if $replace is not set in template, its not null here, its an handlebars object...
if (typeof $replace == "number") {
//keep numbers working
$replace = [$replace];
} else {
if (typeof $replace != "string") {
$replace = null;
} else {
if ($replace.indexOf(":") > -1) {
try {
//parse strings to object/ array
$replace = JSON.parse($replace);
} catch (error) {
//keep strings & numbers
$replace = [$replace];
}
} else {
$replace = [$replace];
}
}
}
return Coco.Translator.get(key, $replace);
if (typeof $replace == "number") {
//keep numbers working
$replace = [$replace];
} else {
if (typeof $replace != "string") {
$replace = null;
} else {
if ($replace.indexOf(":") > -1) {
try {
//parse strings to object/ array
$replace = JSON.parse($replace);
} catch (error) {
//keep strings & numbers
$replace = [$replace];
}
} else {
$replace = [$replace];
}
}
}
return Coco.Translator.get(key, $replace);
});
Handlebars.registerHelper('ifNot', function (v1, options) {
if (!v1) {
return options.fn(this);
}
if (!v1) {
return options.fn(this);
}
return options.inverse(this);
return options.inverse(this);
});
Handlebars.registerHelper('nl2br', function (value) {
if (!value) {
return "";
}
Handlebars.registerHelper('nl2br', function (value) {
if (!value) {
return "";
}
return value.replace(/\n/g, "<br/>");
return value.replace(/\n/g, "<br/>");
});
Handlebars.registerHelper('ifCond', function (v1, operator, v2, options) {
switch (operator) {
case '==':
return v1 == v2 ? options.fn(this) : options.inverse(this);
Handlebars.registerHelper('ifCond', function (v1, operator, v2, options) {
switch (operator) {
case '==':
return v1 == v2 ? options.fn(this) : options.inverse(this);
case '!=':
return v1 != v2 ? options.fn(this) : options.inverse(this);
case '===':
return v1 === v2 ? options.fn(this) : options.inverse(this);
case '<':
return v1 < v2 ? options.fn(this) : options.inverse(this);
case '<=':
return v1 <= v2 ? options.fn(this) : options.inverse(this);
case '>':
return v1 > v2 ? options.fn(this) : options.inverse(this);
case '>=':
return v1 >= v2 ? options.fn(this) : options.inverse(this);
case '&&':
return v1 && v2 ? options.fn(this) : options.inverse(this);
case '||':
return v1 || v2 ? options.fn(this) : options.inverse(this);
default:
return options.inverse(this);
}
case '!=':
return v1 != v2 ? options.fn(this) : options.inverse(this);
case '===':
return v1 === v2 ? options.fn(this) : options.inverse(this);
case '<':
return v1 < v2 ? options.fn(this) : options.inverse(this);
case '<=':
return v1 <= v2 ? options.fn(this) : options.inverse(this);
case '>':
return v1 > v2 ? options.fn(this) : options.inverse(this);
case '>=':
return v1 >= v2 ? options.fn(this) : options.inverse(this);
case '&&':
return v1 && v2 ? options.fn(this) : options.inverse(this);
case '||':
return v1 || v2 ? options.fn(this) : options.inverse(this);
default:
return options.inverse(this);
}
});
Handlebars.registerHelper('add', function (v1, v2) {
return Number(v1) + Number(v2);
return Number(v1) + Number(v2);
});
Handlebars.registerHelper('sub', function (v1, v2) {
return Number(v1) - Number(v2);
return Number(v1) - Number(v2);
});
Handlebars.registerHelper('concat', function (v1, v2) {
return v1 + v2;
return v1 + v2;
});
Handlebars.registerHelper('for', function (from, to, step, block) {
var accum = '';
Handlebars.registerHelper('for', function (from, to, step, block) {
var accum = '';
for (var i = from; i < to; i += step) {
accum += block.fn(i);
}
return accum;
for (var i = from; i < to; i += step) {
accum += block.fn(i);
}
return accum;
});
Handlebars.registerHelper('is', function (v1, v2, options) {
console.error("Handlebars.Helper 'is' is deprecated! use 'ifCond' instead!");
console.error("Handlebars.Helper 'is' is deprecated! use 'ifCond' instead!");
});
Handlebars.registerHelper('isNot', function (v1, v2, options) {
console.error("Handlebars.Helper 'isNot' is deprecated! use 'ifCond' instead!");
console.error("Handlebars.Helper 'isNot' is deprecated! use 'ifCond' instead!");
});
Handlebars.registerHelper('isGreater', function (v1, v2, options) {
console.error("Handlebars.Helper 'isGreater' is deprecated! use 'ifCond' instead!");
console.error("Handlebars.Helper 'isGreater' is deprecated! use 'ifCond' instead!");
});
Handlebars.registerHelper('isGreaterThan', function (v1, v2, options) {
console.error("Handlebars.Helper 'isGreaterThan' is deprecated! use 'ifCond' instead!");
console.error("Handlebars.Helper 'isGreaterThan' is deprecated! use 'ifCond' instead!");
});
Handlebars.registerHelper('isLess', function () {
console.error("Handlebars.Helper 'isLess' is deprecated! use 'ifCond' instead!");
console.error("Handlebars.Helper 'isLess' is deprecated! use 'ifCond' instead!");
});
Handlebars.registerHelper('isLessThan', function () {
console.error("Handlebars.Helper 'isLessThan' is deprecated! use 'ifCond' instead!");
console.error("Handlebars.Helper 'isLessThan' is deprecated! use 'ifCond' instead!");
});
Handlebars.registerHelper('testIf', function () {
var args = Array.prototype.slice.call(arguments);
var args = Array.prototype.slice.call(arguments); // We just have one argument (besides options), so this one is just a regular
// We just have one argument (besides options), so this one is just a regular
if (args.length === 2) {
return args[0] == true ? args[1].fn(this) : args[1].inverse(this);
}
if (args.length === 2) {
return args[0] == true ? args[1].fn(this) : args[1].inverse(this);
}
if (v1 <= v2) {
return options.fn(this);
}
if (v1 <= v2) {
return options.fn(this);
}
return options.inverse(this);
return options.inverse(this);
});

@@ -1,2 +0,2 @@

'use strict';
"use strict";

@@ -7,57 +7,56 @@ /**

*/
function measure(msg, $scope) {
if ($scope) {
if (measure.scopes.hasOwnProperty($scope)) {
var ms = new Date().getTime();
if ($scope) {
if (measure.scopes.hasOwnProperty($scope)) {
var ms = new Date().getTime();
if (measure.scopes[$scope].time !== null) {
console.log(ms - measure.scopes[$scope].time, $scope + ' - ' + msg);
} else {
measure.scopes[$scope].startTime = ms;
console.log(0, $scope + ' - ' + msg);
}
measure.scopes[$scope].time = ms;
return;
}
measure.scopes[$scope] = { time: new Date().getTime(), startTime: new Date().getTime(), endTime: null };
console.log('start scope', $scope);
if (measure.scopes[$scope].time !== null) {
console.log(ms - measure.scopes[$scope].time, $scope + ' - ' + msg);
} else {
measure.scopes[$scope].startTime = ms;
console.log(0, $scope + ' - ' + msg);
}
return;
measure.scopes[$scope].time = ms;
return;
}
console.log(new Date().getTime(), msg);
measure.scopes[$scope] = {
time: new Date().getTime(),
startTime: new Date().getTime(),
endTime: null
};
console.log('start scope', $scope);
console.log(0, $scope + ' - ' + msg);
return;
}
console.log(new Date().getTime(), msg);
}
measure.scopes = {};
measure.resetScope = function (scope) {
if (measure.scopes.hasOwnProperty(scope)) {
measure.scopes[scope].time = null;
measure.scopes[scope].startTime = null;
measure.scopes[scope].endTime = null;
}
if (measure.scopes.hasOwnProperty(scope)) {
measure.scopes[scope].time = null;
measure.scopes[scope].startTime = null;
measure.scopes[scope].endTime = null;
}
};
measure.endScope = function (scope, $reset) {
if (measure.scopes.hasOwnProperty(scope)) {
measure.scopes[scope].endTime = new Date().getTime();
if (measure.scopes.hasOwnProperty(scope)) {
measure.scopes[scope].endTime = new Date().getTime();
console.log('Total time of Scope ' + scope, measure.scopes[scope].endTime - measure.scopes[scope].startTime);
console.log('Total time of Scope ' + scope, measure.scopes[scope].endTime - measure.scopes[scope].startTime);
if ($reset !== false) {
measure.resetScope(scope);
}
if ($reset !== false) {
measure.resetScope(scope);
}
}
};
measure.getTotalTimeOfScope = function (scope) {
if (measure.scopes.hasOwnProperty(scope)) {
console.log('Total time of Scope ' + scope, measure.scopes[scope].endTime - measure.scopes[scope].startTime);
}
if (measure.scopes.hasOwnProperty(scope)) {
console.log('Total time of Scope ' + scope, measure.scopes[scope].endTime - measure.scopes[scope].startTime);
}
};

@@ -13,232 +13,252 @@ "use strict";

*/
'use strict';
Coco.File = dejavu.Class.declare({
//className
$name: "Coco.File",
//className
$name: "Coco.File",
initialize: function initialize() {
console.error("Do not instantiate static class: " + this.$name);
},
$finals: {
$statics: {
/**
* Function: saveAs(blob, name)
*
* Description:
* A {static} saveAs() FileSaver implementation.
*
* By Eli Grey, http://eligrey.com
* License: X11/MIT
* See LICENSE.md
*
* needs global variable 'window'
* jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true, plusplus: true
*
* @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js
*
* Parameter:
* Blob blob - Blob of data to save
* String name - filename of download target file
**/
saveAs: navigator.msSaveBlob && navigator.msSaveBlob.bind(navigator) || function (view) {
"use strict"; //prevent errors in IE8, this fixes nothing!
initialize: function initialize() {
console.error("Do not instantiate static class: " + this.$name);
},
if (typeof view.document.createElementNS !== 'function') {
return false;
}
$finals: {
$statics: {
var doc = view.document // only get URL when necessary in case BlobBuilder.js hasn't overridden it yet
,
get_URL = function get_URL() {
return view.URL || view.webkitURL || view;
},
URL = view.URL || view.webkitURL || view,
save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a"),
can_use_save_link = "download" in save_link,
click = function click(node) {
var event = doc.createEvent("MouseEvents");
event.initMouseEvent("click", true, false, view, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
node.dispatchEvent(event);
},
webkit_req_fs = view.webkitRequestFileSystem,
req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem,
throw_outside = function throw_outside(ex) {
(view.setImmediate || view.setTimeout)(function () {
throw ex;
}, 0);
},
force_saveable_type = "application/octet-stream",
fs_min_size = 0,
deletion_queue = [],
process_deletion_queue = function process_deletion_queue() {
var i = deletion_queue.length;
/**
* Function: saveAs(blob, name)
*
* Description:
* A {static} saveAs() FileSaver implementation.
*
* By Eli Grey, http://eligrey.com
* License: X11/MIT
* See LICENSE.md
*
* needs global variable 'window'
* jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true, plusplus: true
*
* @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js
*
* Parameter:
* Blob blob - Blob of data to save
* String name - filename of download target file
**/
saveAs: navigator.msSaveBlob && navigator.msSaveBlob.bind(navigator) || function (view) {
"use strict";
while (i--) {
var file = deletion_queue[i];
//prevent errors in IE8, this fixes nothing!
if (typeof file === "string") {
// file is an object URL
URL.revokeObjectURL(file);
} else {
// file is a File
file.remove();
}
}
if (typeof view.document.createElementNS !== 'function') {
return false;
}
deletion_queue.length = 0; // clear queue
},
dispatch = function dispatch(filesaver, event_types, event) {
event_types = [].concat(event_types);
var i = event_types.length;
var doc = view.document
// only get URL when necessary in case BlobBuilder.js hasn't overridden it yet
,
get_URL = function get_URL() {
return view.URL || view.webkitURL || view;
},
URL = view.URL || view.webkitURL || view,
save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a"),
can_use_save_link = "download" in save_link,
click = function click(node) {
var event = doc.createEvent("MouseEvents");
event.initMouseEvent("click", true, false, view, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
node.dispatchEvent(event);
},
webkit_req_fs = view.webkitRequestFileSystem,
req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem,
throw_outside = function throw_outside(ex) {
(view.setImmediate || view.setTimeout)(function () {
throw ex;
}, 0);
},
force_saveable_type = "application/octet-stream",
fs_min_size = 0,
deletion_queue = [],
process_deletion_queue = function process_deletion_queue() {
var i = deletion_queue.length;
while (i--) {
var file = deletion_queue[i];
if (typeof file === "string") {
// file is an object URL
URL.revokeObjectURL(file);
} else {
// file is a File
file.remove();
}
}
deletion_queue.length = 0; // clear queue
},
dispatch = function dispatch(filesaver, event_types, event) {
event_types = [].concat(event_types);
var i = event_types.length;
while (i--) {
var listener = filesaver["on" + event_types[i]];
if (typeof listener === "function") {
try {
listener.call(filesaver, event || filesaver);
} catch (ex) {
throw_outside(ex);
}
}
}
},
FileSaver = function FileSaver(blob, name) {
// First try a.download, then web filesystem, then object URLs
var filesaver = this,
type = blob.type,
blob_changed = false,
object_url,
target_view,
get_object_url = function get_object_url() {
var object_url = get_URL().createObjectURL(blob);
deletion_queue.push(object_url);
return object_url;
},
dispatch_all = function dispatch_all() {
dispatch(filesaver, "writestart progress write writeend".split(" "));
}
// on any filesys errors revert to saving with object URLs
,
fs_error = function fs_error() {
// don't create more object URLs than needed
if (blob_changed || !object_url) {
object_url = get_object_url(blob);
}
if (target_view) {
target_view.location.href = object_url;
}
filesaver.readyState = filesaver.DONE;
dispatch_all();
},
abortable = function abortable(func) {
return function () {
if (filesaver.readyState !== filesaver.DONE) {
return func.apply(this, arguments);
}
};
},
create_if_not_found = { create: true, exclusive: false },
slice;
filesaver.readyState = filesaver.INIT;
if (!name) {
name = "download";
}
if (can_use_save_link) {
object_url = get_object_url(blob);
save_link.href = object_url;
save_link.download = name;
click(save_link);
filesaver.readyState = filesaver.DONE;
dispatch_all();
return;
}
// Object and web filesystem URLs have a problem saving in Google Chrome when
// viewed in a tab, so I force save with application/octet-stream
// http://code.google.com/p/chromium/issues/detail?id=91158
if (view.chrome && type && type !== force_saveable_type) {
slice = blob.slice || blob.webkitSlice;
blob = slice.call(blob, 0, blob.size, force_saveable_type);
blob_changed = true;
}
// Since I can't be sure that the guessed media type will trigger a download
// in WebKit, I append .download to the filename.
// https://bugs.webkit.org/show_bug.cgi?id=65440
if (webkit_req_fs && name !== "download") {
name += ".download";
}
if (type === force_saveable_type || webkit_req_fs) {
target_view = view;
} else {
target_view = view.open();
}
if (!req_fs) {
while (i--) {
var listener = filesaver["on" + event_types[i]];
if (typeof listener === "function") {
try {
listener.call(filesaver, event || filesaver);
} catch (ex) {
throw_outside(ex);
}
}
}
},
FileSaver = function FileSaver(blob, name) {
// First try a.download, then web filesystem, then object URLs
var filesaver = this,
type = blob.type,
blob_changed = false,
object_url,
target_view,
get_object_url = function get_object_url() {
var object_url = get_URL().createObjectURL(blob);
deletion_queue.push(object_url);
return object_url;
},
dispatch_all = function dispatch_all() {
dispatch(filesaver, "writestart progress write writeend".split(" "));
} // on any filesys errors revert to saving with object URLs
,
fs_error = function fs_error() {
// don't create more object URLs than needed
if (blob_changed || !object_url) {
object_url = get_object_url(blob);
}
if (target_view) {
target_view.location.href = object_url;
}
filesaver.readyState = filesaver.DONE;
dispatch_all();
},
abortable = function abortable(func) {
return function () {
if (filesaver.readyState !== filesaver.DONE) {
return func.apply(this, arguments);
}
};
},
create_if_not_found = {
create: true,
exclusive: false
},
slice;
filesaver.readyState = filesaver.INIT;
if (!name) {
name = "download";
}
if (can_use_save_link) {
object_url = get_object_url(blob);
save_link.href = object_url;
save_link.download = name;
click(save_link);
filesaver.readyState = filesaver.DONE;
dispatch_all();
return;
} // Object and web filesystem URLs have a problem saving in Google Chrome when
// viewed in a tab, so I force save with application/octet-stream
// http://code.google.com/p/chromium/issues/detail?id=91158
if (view.chrome && type && type !== force_saveable_type) {
slice = blob.slice || blob.webkitSlice;
blob = slice.call(blob, 0, blob.size, force_saveable_type);
blob_changed = true;
} // Since I can't be sure that the guessed media type will trigger a download
// in WebKit, I append .download to the filename.
// https://bugs.webkit.org/show_bug.cgi?id=65440
if (webkit_req_fs && name !== "download") {
name += ".download";
}
if (type === force_saveable_type || webkit_req_fs) {
target_view = view;
} else {
target_view = view.open();
}
if (!req_fs) {
fs_error();
return;
}
fs_min_size += blob.size;
req_fs(view.TEMPORARY, fs_min_size, abortable(function (fs) {
fs.root.getDirectory("saved", create_if_not_found, abortable(function (dir) {
var save = function save() {
dir.getFile(name, create_if_not_found, abortable(function (file) {
file.createWriter(abortable(function (writer) {
writer.onwriteend = function (event) {
target_view.location.href = file.toURL();
deletion_queue.push(file);
filesaver.readyState = filesaver.DONE;
dispatch(filesaver, "writeend", event);
};
writer.onerror = function () {
var error = writer.error;
if (error.code !== error.ABORT_ERR) {
fs_error();
return;
}
fs_min_size += blob.size;
req_fs(view.TEMPORARY, fs_min_size, abortable(function (fs) {
fs.root.getDirectory("saved", create_if_not_found, abortable(function (dir) {
var save = function save() {
dir.getFile(name, create_if_not_found, abortable(function (file) {
file.createWriter(abortable(function (writer) {
writer.onwriteend = function (event) {
target_view.location.href = file.toURL();
deletion_queue.push(file);
filesaver.readyState = filesaver.DONE;
dispatch(filesaver, "writeend", event);
};
writer.onerror = function () {
var error = writer.error;
if (error.code !== error.ABORT_ERR) {
fs_error();
}
};
"writestart progress write abort".split(" ").forEach(function (event) {
writer["on" + event] = filesaver["on" + event];
});
writer.write(blob);
filesaver.abort = function () {
writer.abort();
filesaver.readyState = filesaver.DONE;
};
filesaver.readyState = filesaver.WRITING;
}), fs_error);
}), fs_error);
};
dir.getFile(name, { create: false }, abortable(function (file) {
// delete file if it already exists
file.remove();
save();
}), abortable(function (ex) {
if (ex.code === ex.NOT_FOUND_ERR) {
save();
} else {
fs_error();
}
}));
}), fs_error);
}), fs_error);
},
FS_proto = FileSaver.prototype,
saveAs = function saveAs(blob, name) {
return new FileSaver(blob, name);
};
FS_proto.abort = function () {
var filesaver = this;
filesaver.readyState = filesaver.DONE;
dispatch(filesaver, "abort");
};
FS_proto.readyState = FS_proto.INIT = 0;
FS_proto.WRITING = 1;
FS_proto.DONE = 2;
}
};
FS_proto.error = FS_proto.onwritestart = FS_proto.onprogress = FS_proto.onwrite = FS_proto.onabort = FS_proto.onerror = FS_proto.onwriteend = null;
"writestart progress write abort".split(" ").forEach(function (event) {
writer["on" + event] = filesaver["on" + event];
});
writer.write(blob);
view.addEventListener("unload", process_deletion_queue, false);
return saveAs;
}(window)
}
filesaver.abort = function () {
writer.abort();
filesaver.readyState = filesaver.DONE;
};
filesaver.readyState = filesaver.WRITING;
}), fs_error);
}), fs_error);
};
dir.getFile(name, {
create: false
}, abortable(function (file) {
// delete file if it already exists
file.remove();
save();
}), abortable(function (ex) {
if (ex.code === ex.NOT_FOUND_ERR) {
save();
} else {
fs_error();
}
}));
}), fs_error);
}), fs_error);
},
FS_proto = FileSaver.prototype,
saveAs = function saveAs(blob, name) {
return new FileSaver(blob, name);
};
FS_proto.abort = function () {
var filesaver = this;
filesaver.readyState = filesaver.DONE;
dispatch(filesaver, "abort");
};
FS_proto.readyState = FS_proto.INIT = 0;
FS_proto.WRITING = 1;
FS_proto.DONE = 2;
FS_proto.error = FS_proto.onwritestart = FS_proto.onprogress = FS_proto.onwrite = FS_proto.onabort = FS_proto.onerror = FS_proto.onwriteend = null;
view.addEventListener("unload", process_deletion_queue, false);
return saveAs;
}(window)
}
}
});

@@ -1,2 +0,2 @@

'use strict';
"use strict";

@@ -11,56 +11,54 @@ /**

module.exports = dejavu.Class.declare({
$name: "Math",
$name: "Math",
$finals: {
$statics: {
/**
* Function: {final static} isNumber(x)
*
* Description:
* checks if a given variable is a number
*
* returns:
*
* boolean
*/
isNumber: function isNumber(x) {
return !isNaN(parseFloat(x));
},
$finals: {
$statics: {
/**
* Function: {final static} isNumber(x)
*
* Description:
* checks if a given variable is a number
*
* returns:
*
* boolean
*/
isNumber: function isNumber(x) {
return !isNaN(parseFloat(x));
},
/**
* Function: {final static} round(value, precision)
*
* Description:
* rounds a float to a given precision.
*
* Parameter:
* @param {Number} value - The value to round.
* @param {Number} $precision - {optional} The number of decimals. If omitted, the function will round to an Integer
*
* Return:
* @returns {number}
*/
round: function round(value, $precision) {
$precision = $precision != null ? $precision : 0;
return Math.round((value + 0.0000001) * Math.pow(10, $precision)) / Math.pow(10, $precision);
},
/**
* Function: {final static} round(value, precision)
*
* Description:
* rounds a float to a given precision.
*
* Parameter:
* @param {Number} value - The value to round.
* @param {Number} $precision - {optional} The number of decimals. If omitted, the function will round to an Integer
*
* Return:
* @returns {number}
*/
round: function round(value, $precision) {
$precision = $precision != null ? $precision : 0;
/**
* Function: {final static} random(noOfDigits)
*
* Description:
*/
random: function random(noOfDigits) {
var charset = '123456789';
var ret = '';
return Math.round((value + 0.0000001) * Math.pow(10, $precision)) / Math.pow(10, $precision);
},
for (var i = 0; i < noOfDigits; i++) {
ret += charset.substr(Math.floor(Math.random() * 9), 1);
}
/**
* Function: {final static} random(noOfDigits)
*
* Description:
*/
random: function random(noOfDigits) {
var charset = '123456789';
var ret = '';
for (var i = 0; i < noOfDigits; i++) {
ret += charset.substr(Math.floor(Math.random() * 9), 1);
}
return parseInt(ret);
}
}
return parseInt(ret);
}
}
}
});
"use strict";
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
var JSON = require("JSON");
/**

@@ -13,165 +12,166 @@ * Class: Coco.Storage

module.exports = dejavu.Class.declare({
$name: 'Storage',
$name: 'Storage',
$statics: {
/**
* holds a boolean, that checks if the localStorage is available.
*/
isAvailable: function isAvailable() {
if (window) {
try {
return window.localStorage != null;
} catch (error) {
console.error(error);
}
}
$statics: {
/**
* holds a boolean, that checks if the localStorage is available.
*/
isAvailable: function isAvailable() {
if (window) {
try {
return window.localStorage != null;
} catch (error) {
console.error(error);
}
}
console.warn("No window.localStorage available!");
return false;
},
console.warn("No window.localStorage available!");
return false;
},
/**
* Function: has(key)
*
* Description:
* Checks if the key is in the localStorage.
*
* Parameter:
* @param {string} key
*
* Return:
* @returns {boolean}
*/
has: function has(key) {
if (this.isAvailable()) {
return window.localStorage.hasOwnProperty(key);
}
return false;
},
/**
* Function: has(key)
*
* Description:
* Checks if the key is in the localStorage.
*
* Parameter:
* @param {string} key
*
* Return:
* @returns {boolean}
*/
has: function has(key) {
if (this.isAvailable()) {
return window.localStorage.hasOwnProperty(key);
}
/**
* Function: get(key)
*
* Description:
* Returns the value of the key.
* If value is an object, the method will try to parse it and then return the parsed object.
*
* Parameter:
* @param {string} key
*
* Return:
* @returns {*}
*/
get: function get(key) {
if (this.isAvailable()) {
var value = window.localStorage.getItem(key);
return false;
},
try {
value = JSON.parse(value);
} catch (e) {}
/**
* Function: get(key)
*
* Description:
* Returns the value of the key.
* If value is an object, the method will try to parse it and then return the parsed object.
*
* Parameter:
* @param {string} key
*
* Return:
* @returns {*}
*/
get: function get(key) {
if (this.isAvailable()) {
var value = window.localStorage.getItem(key);
return value;
}
try {
value = JSON.parse(value);
} catch (e) {}
return null;
},
return value;
}
/**
* Function: set(key, value)
*
* Description:
* Saves a key and it's value to the localStorage.
* If the value is an object, the function will stringify it.
*
* Parameter:
* @param {string} key
* @param {*} value
*/
set: function set(key, value) {
if (this.isAvailable()) {
if ((typeof value === "undefined" ? "undefined" : _typeof(value)) === 'object') {
value = JSON.stringify(value);
}
return null;
},
window.localStorage.setItem(key, value);
}
},
/**
* Function: set(key, value)
*
* Description:
* Saves a key and it's value to the localStorage.
* If the value is an object, the function will stringify it.
*
* Parameter:
* @param {string} key
* @param {*} value
*/
set: function set(key, value) {
if (this.isAvailable()) {
if (_typeof(value) === 'object') {
value = JSON.stringify(value);
}
/**
* Function: copy(sourceKey, targetKey, $deleteSource)
*
* Description:
* Copies a value to another destination.
*
* @param {string} sourceKey - Where lives the value that should be copied
* @param {string} targetKey - The destination
* @param {boolean} $deleteSource - {optional} If set to true the sourceKey will be deleted.
*/
copy: function copy(sourceKey, targetKey, $deleteSource) {
if (this.isAvailable()) {
if (window.localStorage.hasOwnProperty(sourceKey)) {
window.localStorage.setItem(targetKey, window.localStorage.getItem(sourceKey));
}
window.localStorage.setItem(key, value);
}
},
if ($deleteSource) {
window.localStorage.removeItem(sourceKey);
}
}
},
/**
* Function: copy(sourceKey, targetKey, $deleteSource)
*
* Description:
* Copies a value to another destination.
*
* @param {string} sourceKey - Where lives the value that should be copied
* @param {string} targetKey - The destination
* @param {boolean} $deleteSource - {optional} If set to true the sourceKey will be deleted.
*/
copy: function copy(sourceKey, targetKey, $deleteSource) {
if (this.isAvailable()) {
if (window.localStorage.hasOwnProperty(sourceKey)) {
window.localStorage.setItem(targetKey, window.localStorage.getItem(sourceKey));
}
/**
* Function: remove(key)
*
* Description:
* Removes a key and it's value from the localStorage.
*
* Parameter:
* @param {string} key
*/
remove: function remove(key) {
if (this.isAvailable()) {
window.localStorage.removeItem(key);
}
},
if ($deleteSource) {
window.localStorage.removeItem(sourceKey);
}
}
},
/**
* Function: clear()
*
* Description:
* Clears the locationStorage.
*/
clear: function clear() {
if (this.isAvailable()) {
window.localStorage.clear();
}
},
/**
* Function: remove(key)
*
* Description:
* Removes a key and it's value from the localStorage.
*
* Parameter:
* @param {string} key
*/
remove: function remove(key) {
if (this.isAvailable()) {
window.localStorage.removeItem(key);
}
},
/**
* Function: getUsedSpace()
*
* Description:
* Returns the number of kilobyte of memory the localStorage has taken.
*
* Return:
* @returns {null|Number}
*/
getUsedSpace: function getUsedSpace($key) {
if (this.isAvailable()) {
var values = '';
/**
* Function: clear()
*
* Description:
* Clears the locationStorage.
*/
clear: function clear() {
if (this.isAvailable()) {
window.localStorage.clear();
}
},
if ($key) {
values = window.localStorage.hasOwnProperty($key) ? window.localStorage.getItem($key) : '';
} else {
for (var key in window.localStorage) {
if (window.localStorage.hasOwnProperty(key)) {
values += window.localStorage[key];
}
}
}
/**
* Function: getUsedSpace()
*
* Description:
* Returns the number of kilobyte of memory the localStorage has taken.
*
* Return:
* @returns {null|Number}
*/
getUsedSpace: function getUsedSpace($key) {
if (this.isAvailable()) {
var values = '';
return values ? 3 + values.length * 16 / (8 * 1024) : 0;
}
if ($key) {
values = window.localStorage.hasOwnProperty($key) ? window.localStorage.getItem($key) : '';
} else {
for (var key in window.localStorage) {
if (window.localStorage.hasOwnProperty(key)) {
values += window.localStorage[key];
}
}
}
return null;
}
}
return values ? 3 + values.length * 16 / (8 * 1024) : 0;
}
return null;
}
}
});

@@ -13,26 +13,24 @@ /**

module.exports = dejavu.Class.declare({
$name: "Coco.StringUtils",
initialize: function initialize() {
console.error("Do not instantiate static class: " + this.$name);
},
$finals: {
$statics: {
/**
* Function: {final static} isEmpty
*
* Description:
*
* checks if given string is null or empty
*
* returns:
*
* boolean
*/
isEmpty: function isEmpty(string) {
return string == null || string === "" || string.length === 0;
}
}
$name: "Coco.StringUtils",
initialize: function initialize() {
console.error("Do not instantiate static class: " + this.$name);
},
$finals: {
$statics: {
/**
* Function: {final static} isEmpty
*
* Description:
*
* checks if given string is null or empty
*
* returns:
*
* boolean
*/
isEmpty: function isEmpty(string) {
return string == null || string === "" || string.length === 0;
}
}
}
});
"use strict";
var JSON = require("JSON"),
_ = require("underscore"),
TranslatorEvent = require("../event/Coco.TranslatorEvent.js");
var TranslatorEvent = require("../event/Coco.TranslatorEvent.js");
/**

@@ -18,2 +15,4 @@ * Package: lib

*/
module.exports = dejavu.Class.declare({

@@ -73,2 +72,3 @@ $name: "Coco.Translator",

}
_this.setLocale($locale);

@@ -81,2 +81,3 @@

_this.createDomain(_this.__domain);
_this.fill(data, true);

@@ -139,5 +140,5 @@

}
if (key.split('.').length > 1) {
var array = this.__messages[this.__locale + ':' + this.__domain];
$.each(key.split('.'), function (i, e) {

@@ -148,8 +149,9 @@ if (array == null) {

}
array = array[e];
});
string = array;
} else {
var data = this.__messages[this.__locale + ':' + this.__domain];
if (data == null) {

@@ -159,2 +161,3 @@ console.error("Could not find label with key: " + key);

}
string = data[key];

@@ -164,4 +167,4 @@ }

if (string == null || typeof string != "string") {
console.warn("Could not find label with key: " + key, string);
//return objects or arrays from i18n file
console.warn("Could not find label with key: " + key, string); //return objects or arrays from i18n file
return string == null ? "" : string;

@@ -201,2 +204,3 @@ }

var msgs = {};
for (var key in this.__messages) {

@@ -209,2 +213,3 @@ if (this.__messages.hasOwnProperty(key)) {

}
return msgs;

@@ -343,4 +348,6 @@ }

}
var oldLocale = this.__locale;
this.__locale = newLocale;
if (oldLocale != this.__locale) {

@@ -347,0 +354,0 @@ this._dispatchEvent(new TranslatorEvent(TranslatorEvent.CHANGE_LOCALE, this.__locale));

@@ -12,30 +12,26 @@ /**

module.exports = dejavu.Class.declare({
$name: "Coco.URLHelper",
initialize: function initialize() {
console.error("Do not instantiate static class: " + this.$name);
},
$finals: {
$statics: {
/**
* Function: getUrlVars (static)
*
* Description:
* {final static} parses current url for GET parameter
*
* Return:
* @returns {Map} of given URL GET-Parameters
*/
getUrlVars: function getUrlVars() {
var vars = new Map();
window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function (m, key, value) {
vars.set(key, value);
});
return vars;
}
}
$name: "Coco.URLHelper",
initialize: function initialize() {
console.error("Do not instantiate static class: " + this.$name);
},
$finals: {
$statics: {
/**
* Function: getUrlVars (static)
*
* Description:
* {final static} parses current url for GET parameter
*
* Return:
* @returns {Map} of given URL GET-Parameters
*/
getUrlVars: function getUrlVars() {
var vars = new Map();
window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function (m, key, value) {
vars.set(key, value);
});
return vars;
}
}
}
});
"use strict";
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }

@@ -14,249 +14,252 @@ var Coco = Coco || {};

*/
Coco.Utils = module.exports = dejavu.Class.declare({
$name: "Utils",
$name: "Utils",
/**
* Constants:
* These constants are used to cast or type test variables.
*
* @public
*/
//$constants: {
/**
* Constant: BOOLEAN
*
* for boolean casting
*
*/
BOOLEAN: 0,
/**
* Constant: INTEGER
*
* for integer casting
*/
INTEGER: 1,
/**
* Constants:
* These constants are used to cast or type test variables.
*
* @public
*/
//$constants: {
/**
* Constant: FLOAT
*
* for float casting
*/
FLOAT: 2,
/**
* Constant: BOOLEAN
*
* for boolean casting
*
*/
BOOLEAN: 0,
/**
* Constant: STRING
*
* for string casting
*/
STRING: 3,
/**
* Constant: INTEGER
*
* for integer casting
*/
INTEGER: 1,
/**
* Constant: OBJECT
*
* for object casting
*/
OBJECT: 4,
/**
* Constant: FLOAT
*
* for float casting
*/
FLOAT: 2,
/**
* Constant: ARRAY
*
* for array casting
*/
ARRAY: 5,
/**
* Constant: STRING
*
* for string casting
*/
STRING: 3,
/**
* Constant: NULL
*
* for null casting
*/
NULL: 6,
/**
* Constant: OBJECT
*
* for object casting
*/
OBJECT: 4,
/**
* Constant: ARRAY
*
* for array casting
*/
ARRAY: 5,
/**
* Constant: NULL
*
* for null casting
*/
NULL: 6,
/**
* Constant: UNDEFINED
*
* for undefined casting
*/
UNDEFINED: 99,
//},
$statics: {
__id: 0
},
//$finals: {
// $statics: {
/**
* Function: sizeOfObject
*
* Paramter:
* @param {object} obj
*
* Return:
* @return {number} - number of object properties
*/
sizeOfObject: function sizeOfObject(obj) {
var size = 0,
key;
for (key in obj) {
if (obj.hasOwnProperty(key)) size++;
}
return size;
},
/**
* Function: uniqueId
*
* Description:
* {final static} Generates a unique id with an optional prefix. Be careful: It's only unique if all generated ids use the
* same function and it's only unique while lifetime of application.
*
* Parameter:
* @param {string} $prefix - {optional} optional prefix for unique id. Is not allowed to contain a number.
*
* Return:
* @returns {string|number} - created unique id
*/
uniqueId: function uniqueId($prefix) {
if (/[0-9]$/.test($prefix)) {
throw new Error("$prefix is not allowed to end with a number in Coco.Utils.uniqueId().");
}
var id = ++Coco.Utils.$static.__id + '';
var x = $prefix ? "" + $prefix + id : id;
return x;
},
/**
* Function: randomId
*
* Description:
* {final static} Generates a random id with an optional prefix.
*
* Parameter:
* @param {string} $prefix - {optional} optional prefix for random id.
*
* Return:
* @returns {string|number} - created random id
*/
randomId: function randomId($prefix) {
var rand = window.btoa(Math.floor(Math.random() * 5000000) + '' + new Date().getTime() + '' + ++Coco.Utils.$static.__id);
return $prefix ? "" + $prefix + rand.substr(0, 32) : rand.substr(0, 32);
},
/**
* Function: isMobile : {Android, BlackBerry, iOS, Opera, Windows, any}
*
* {final static} object for mobile detection
*/
isMobile: {
/**
* Constant: UNDEFINED
* Function: isMobile.Android
*
* for undefined casting
* returns matched navigator String if Android device detected, otherwise null
*/
UNDEFINED: 99,
//},
$statics: {
__id: 0
Android: function Android() {
return navigator && navigator.userAgent && navigator.userAgent.match(/Android/i);
},
//$finals: {
// $statics: {
/**
* Function: sizeOfObject
* Function: isMobile.BlackBerry
*
* Paramter:
* @param {object} obj
*
* Return:
* @return {number} - number of object properties
* returns matched navigator String if BlackBerry device detected, otherwise null
*/
sizeOfObject: function sizeOfObject(obj) {
var size = 0,
key;
BlackBerry: function BlackBerry() {
return navigator && navigator.userAgent && navigator.userAgent.match(/BlackBerry/i);
},
for (key in obj) {
if (obj.hasOwnProperty(key)) size++;
}
return size;
},
/**
* Function: uniqueId
* Function: isMobile.BlackBerry
*
* Description:
* {final static} Generates a unique id with an optional prefix. Be careful: It's only unique if all generated ids use the
* same function and it's only unique while lifetime of application.
*
* Parameter:
* @param {string} $prefix - {optional} optional prefix for unique id. Is not allowed to contain a number.
*
* Return:
* @returns {string|number} - created unique id
* returns matched navigator String if BlackBerry device detected, otherwise null
*/
uniqueId: function uniqueId($prefix) {
if (/[0-9]$/.test($prefix)) {
throw new Error("$prefix is not allowed to end with a number in Coco.Utils.uniqueId().");
}
var id = ++Coco.Utils.$static.__id + '';
var x = $prefix ? "" + $prefix + id : id;
return x;
iOS: function iOS() {
return navigator && navigator.userAgent && navigator.userAgent.match(/iPhone|iPad|iPod/i);
},
/**
* Function: randomId
* Function: isMobile.Opera
*
* Description:
* {final static} Generates a random id with an optional prefix.
*
* Parameter:
* @param {string} $prefix - {optional} optional prefix for random id.
*
* Return:
* @returns {string|number} - created random id
* returns matched navigator String if Opera Mini device detected, otherwise null
*/
randomId: function randomId($prefix) {
var rand = window.btoa(Math.floor(Math.random() * 5000000) + '' + new Date().getTime() + '' + ++Coco.Utils.$static.__id);
return $prefix ? "" + $prefix + rand.substr(0, 32) : rand.substr(0, 32);
Opera: function Opera() {
return navigator && navigator.userAgent && navigator.userAgent.match(/Opera Mini/i);
},
/**
* Function: isMobile : {Android, BlackBerry, iOS, Opera, Windows, any}
* Function: isMobile.Windows
*
* {final static} object for mobile detection
* returns matched navigator String if IEMobile device detected, otherwise null
*/
isMobile: {
/**
* Function: isMobile.Android
*
* returns matched navigator String if Android device detected, otherwise null
*/
Android: function Android() {
return navigator && navigator.userAgent && navigator.userAgent.match(/Android/i);
},
/**
* Function: isMobile.BlackBerry
*
* returns matched navigator String if BlackBerry device detected, otherwise null
*/
BlackBerry: function BlackBerry() {
return navigator && navigator.userAgent && navigator.userAgent.match(/BlackBerry/i);
},
/**
* Function: isMobile.BlackBerry
*
* returns matched navigator String if BlackBerry device detected, otherwise null
*/
iOS: function iOS() {
return navigator && navigator.userAgent && navigator.userAgent.match(/iPhone|iPad|iPod/i);
},
/**
* Function: isMobile.Opera
*
* returns matched navigator String if Opera Mini device detected, otherwise null
*/
Opera: function Opera() {
return navigator && navigator.userAgent && navigator.userAgent.match(/Opera Mini/i);
},
/**
* Function: isMobile.Windows
*
* returns matched navigator String if IEMobile device detected, otherwise null
*/
Windows: function Windows() {
return navigator && navigator.userAgent && navigator.userAgent.match(/IEMobile/i);
},
/**
* Function: isMobile.any
*
* returns matched navigator String if any mobile device detected, otherwise null
*/
any: function any() {
return Coco.Utils.$static.isMobile.Android() || Coco.Utils.$static.isMobile.BlackBerry() || Coco.Utils.$static.isMobile.iOS() || Coco.Utils.$static.isMobile.Opera() || Coco.Utils.$static.isMobile.Windows();
}
Windows: function Windows() {
return navigator && navigator.userAgent && navigator.userAgent.match(/IEMobile/i);
},
/**
* Function: cast
* Function: isMobile.any
*
* Description:
* {final static} Cast value to a specific type.
*
* Parameter:
* @param {*} value - The value to cast
*
* @param {Number} type - The type to cast the value to. Should refer to <Coco.Utils.Constants>
*
* @param {string|Number} $key - optional $key is needed if type is Coco.Util.OBJECT
* returns matched navigator String if any mobile device detected, otherwise null
*/
cast: function cast(value, type, $key) {
switch (type) {
case Coco.Utils.INTEGER:
return parseInt(value, 10);
any: function any() {
return Coco.Utils.$static.isMobile.Android() || Coco.Utils.$static.isMobile.BlackBerry() || Coco.Utils.$static.isMobile.iOS() || Coco.Utils.$static.isMobile.Opera() || Coco.Utils.$static.isMobile.Windows();
}
},
case Coco.Utils.BOOLEAN:
return parseInt(value, 10) === 1 || value === "true" || value === "1";
/**
* Function: cast
*
* Description:
* {final static} Cast value to a specific type.
*
* Parameter:
* @param {*} value - The value to cast
*
* @param {Number} type - The type to cast the value to. Should refer to <Coco.Utils.Constants>
*
* @param {string|Number} $key - optional $key is needed if type is Coco.Util.OBJECT
*/
cast: function cast(value, type, $key) {
switch (type) {
case Coco.Utils.INTEGER:
return parseInt(value, 10);
case Coco.Utils.FLOAT:
return parseFloat(value);
case Coco.Utils.BOOLEAN:
return parseInt(value, 10) === 1 || value === "true" || value === "1";
case Coco.Utils.STRING:
return value.toString();
case Coco.Utils.FLOAT:
return parseFloat(value);
case Coco.Utils.ARRAY:
return value instanceof Array ? value : [value];
case Coco.Utils.STRING:
return value.toString();
case Coco.Utils.OBJECT:
if ((typeof value === "undefined" ? "undefined" : _typeof(value)) === 'object') {
return value;
}
case Coco.Utils.ARRAY:
return value instanceof Array ? value : [value];
if (typeof $key !== 'undefined') {
var o = {};
o[$key] = value;
case Coco.Utils.OBJECT:
if (_typeof(value) === 'object') {
return value;
}
return o;
}
if (typeof $key !== 'undefined') {
var o = {};
o[$key] = value;
return o;
}
throw new Error('Cannot cast value ' + value + ' to object because no $key is given in Coco.Utils.cast().');
break;
throw new Error('Cannot cast value ' + value + ' to object because no $key is given in Coco.Utils.cast().');
break;
case Coco.Utils.NULL:
return null;
case Coco.Utils.NULL:
return null;
default:
return value;
}
default:
return value;
}
//}
//}
} //}
//}
});
module.exports = new Coco.Utils();

@@ -5,2 +5,3 @@ "use strict";

_ = require("underscore");
Coco.Event = require("../event/Coco.Event.js"), Coco.EventDispatcher = require("../event/Coco.EventDispatcher.js"), Coco.ModelEvent = require("../event/Coco.ModelEvent.js"), Coco.Utils = require("../lib/Coco.Utils.js"), Coco.Model = require("./Coco.Model.js"), Coco.Math = require("../lib/Coco.Math.js");

@@ -17,719 +18,716 @@ /**

*/
module.exports = dejavu.Class.declare({
$name: 'Collection',
$name: 'Collection',
$extends: Coco.EventDispatcher,
$extends: Coco.EventDispatcher,
/**
* The internal collection id.
*/
__id: null,
/**
* The internal collection id.
*/
__id: null,
/**
* A private class identifier, copied from `this.$name`
*/
__$name: "Collection",
/**
* A private class identifier, copied from `this.$name`
*/
__$name: "Collection",
/**
* Variable: _models
* {protected} Array of Coco.Model objects.
*/
_models: [],
/**
* Variable: _models
* {protected} Array of Coco.Model objects.
*/
_models: [],
/**
* Variable: __handles
* {private} Map of EventListener-handles for models from _models-Array
*/
__handles: null,
/**
* Variable: __handles
* {private} Map of EventListener-handles for models from _models-Array
*/
__handles: null,
/**
* Variable: _modelClass
* The class of the models. Calling <Coco.Collection.createOne> and <Coco.Collection.add> will always add models
* with the class referred here.
* {protected}
*/
_modelClass: null,
/**
* Variable: _modelClass
* The class of the models. Calling <Coco.Collection.createOne> and <Coco.Collection.add> will always add models
* with the class referred here.
* {protected}
*/
_modelClass: null,
/**
* Function: Constructor
*
* Parameter:
* @param {Array} $models - The models to add initial.
*/
initialize: function initialize($models) {
if (this._modelClass == null || !this._modelClass.prototype || this._modelClass.prototype.__$name !== 'Model' && this._modelClass.$parent && this._modelClass.$parent.prototype.__$name !== 'Model') {
throw new Error("Cannot create Collection '" + this.$name + "' with '_modelClass' being null or not extending from Coco.Model.");
}
/**
* Function: Constructor
*
* Parameter:
* @param {Array} $models - The models to add initial.
*/
initialize: function initialize($models) {
if (this._modelClass == null || !this._modelClass.prototype || this._modelClass.prototype.__$name !== 'Model' && this._modelClass.$parent && this._modelClass.$parent.prototype.__$name !== 'Model') {
throw new Error("Cannot create Collection '" + this.$name + "' with '_modelClass' being null or not extending from Coco.Model.");
}
this.__$name = this.$name;
this.__id = Coco.Utils.uniqueId("c");
this.__handles = new Map();
this.__$name = this.$name;
this.__id = Coco.Utils.uniqueId("c");
this._onInitialize($models);
this.__handles = new Map();
if ($models != null) {
this.add($models);
}
},
this._onInitialize($models);
/**
* Function: _onInitialize
* Function is called after class is initialized, but BEFORE models are added.
*
* Parameter:
* @param {Array} $models - The models to add initial. You can change those by altering the this parameter.
*/
_onInitialize: function _onInitialize($models) {},
if ($models != null) {
this.add($models);
}
},
/**
* Function: add
* Adds an array of models to the collection. This can be either an instance of Coco.Model or attributes or an Array
* containing one of both.
*
* Parameter:
* @param {Coco.Model|Object|Array} attributes - Array of models to add.
*
* Event:
* Triggers <Coco.Event.ADD> event with each model that has been added.
*/
add: function add(attributes) {
var _this = this;
/**
* Function: _onInitialize
* Function is called after class is initialized, but BEFORE models are added.
*
* Parameter:
* @param {Array} $models - The models to add initial. You can change those by altering the this parameter.
*/
_onInitialize: function _onInitialize($models) {},
if (attributes == null) {
return;
}
/**
* Function: add
* Adds an array of models to the collection. This can be either an instance of Coco.Model or attributes or an Array
* containing one of both.
*
* Parameter:
* @param {Coco.Model|Object|Array} attributes - Array of models to add.
*
* Event:
* Triggers <Coco.Event.ADD> event with each model that has been added.
*/
add: function add(attributes) {
var _this = this;
if (!(attributes instanceof Array)) {
attributes = [attributes];
}
if (attributes == null) {
return;
}
var model = null;
if (!(attributes instanceof Array)) {
attributes = [attributes];
}
for (var i = 0; i < attributes.length; i++) {
if (attributes[i] == null) {
continue;
} // If attribute is a model store it, otherwise create a new model and set it's attributes.
var model = null;
for (var i = 0; i < attributes.length; i++) {
if (attributes[i] == null) {
continue;
}
model = !(attributes[i] instanceof this._modelClass) ? new this._modelClass(attributes[i]) : attributes[i];
var handle = model.addEventListener(Coco.Event.DESTROY, function (event) {
_this.__onModelDestroy(event);
}, true);
// If attribute is a model store it, otherwise create a new model and set it's attributes.
model = !(attributes[i] instanceof this._modelClass) ? new this._modelClass(attributes[i]) : attributes[i];
this._models.push(model);
var handle = model.addEventListener(Coco.Event.DESTROY, function (event) {
_this.__onModelDestroy(event);
}, true);
this._models.push(model);
this._addModelHandle(handle, model);
this._addModelHandle(handle, model);
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.ADD, model));
}
},
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.ADD, model));
}
},
/**
* Function: _addModelHandle
*
* stores all handles for one model, to delete eventlistener, after rmoving model from collection
*
* Parameter:
* @param {Coco.Model} model - model to add handle for
*
* @param {Symbol} handle - handle to add
*
* @protected
*/
_addModelHandle: function _addModelHandle(handle, model) {
var mh = this.__handles.get(model.getId());
if (mh == null) {
mh = [];
}
mh.push(handle);
this.__handles.set(model.getId(), mh);
},
/**
* Function: _addModelHandle
*
* stores all handles for one model, to delete eventlistener, after rmoving model from collection
*
* Parameter:
* @param {Coco.Model} model - model to add handle for
*
* @param {Symbol} handle - handle to add
*
* @protected
*/
_addModelHandle: function _addModelHandle(handle, model) {
var mh = this.__handles.get(model.getId());
if (mh == null) {
mh = [];
}
/**
* Function: _removeModelHandles
*
* removes all handles for given model
*
* Parameter:
* @param {Coco.Model} model - model to remove EventListener from
* @protected
*/
_removeModelHandles: function _removeModelHandles(model) {
var mh = this.__handles.get(model.getId());
if (mh != null && mh.length > 0) {
for (var i = 0; i < mh.length; i++) {
model.removeEventListener(mh[i]);
}
}
this.__handles.delete(model.getId());
},
mh.push(handle);
this.__handles.set(model.getId(), mh);
},
/**
* Function: insertAt
* Add a model a the specified index to the collection
*
* Parameter:
* @param {integer} index - The index position.
*
* @param {Coco.Model} model - The <Coco.Model> instance to add.
*
* Event:
* Triggers <Coco.Event.ADD> event
*/
insertAt: function insertAt(index, model) {
if (model instanceof this._modelClass) {
if (index >= 0 && index <= this._models.length) {
this._models.splice(index, 0, model);
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.ADD, model));
} else {
throw new Error("index out of bound error");
}
}
},
/**
* Function: _removeModelHandles
*
* removes all handles for given model
*
* Parameter:
* @param {Coco.Model} model - model to remove EventListener from
* @protected
*/
_removeModelHandles: function _removeModelHandles(model) {
var mh = this.__handles.get(model.getId());
/**
* Function: createOne
* Creates a new model based on given attributes.
*
* Parameter:
* @param {Object} $attributes - {optional} The attributes the new model should have.
*
* Return:
* @return {Coco.Model} - The created model.
*
* Event:
* Triggers <Coco.Event.ADD> event.
*/
createOne: function createOne($attributes) {
var _this2 = this;
if (mh != null && mh.length > 0) {
for (var i = 0; i < mh.length; i++) {
model.removeEventListener(mh[i]);
}
}
if ($attributes instanceof this._modelClass) {
return null;
}
this.__handles.delete(model.getId());
},
var model = new this._modelClass($attributes);
/**
* Function: insertAt
* Add a model a the specified index to the collection
*
* Parameter:
* @param {integer} index - The index position.
*
* @param {Coco.Model} model - The <Coco.Model> instance to add.
*
* Event:
* Triggers <Coco.Event.ADD> event
*/
insertAt: function insertAt(index, model) {
if (model instanceof this._modelClass) {
if (index >= 0 && index <= this._models.length) {
this._models.splice(index, 0, model);
var handle = model.addEventListener(Coco.Event.DESTROY, function (event) {
_this2.__onModelDestroy(event);
}, true);
this._models.push(model);
this._addModelHandle(handle, model);
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.ADD, model));
} else {
throw new Error("index out of bound error");
}
}
},
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.ADD, model));
/**
* Function: createOne
* Creates a new model based on given attributes.
*
* Parameter:
* @param {Object} $attributes - {optional} The attributes the new model should have.
*
* Return:
* @return {Coco.Model} - The created model.
*
* Event:
* Triggers <Coco.Event.ADD> event.
*/
createOne: function createOne($attributes) {
var _this2 = this;
return model;
},
if ($attributes instanceof this._modelClass) {
return null;
}
/**
* Function: has
* checks for existing model in collection.
*
* Parameter:
* @param {Coco.Model} model - An <Coco.Model> instance
*
* Return:
* @returns {boolean} - True if model is in Collection
*/
has: function has(model) {
for (var i = 0; i < this._models.length; i++) {
if (model.isEqual(this._models[i])) {
return true;
}
}
var model = new this._modelClass($attributes);
var handle = model.addEventListener(Coco.Event.DESTROY, function (event) {
_this2.__onModelDestroy(event);
}, true);
return false;
},
this._models.push(model);
/**
* Function: reset
* Removes all models from the collection.
*
* Event:
* Triggers <Coco.Event.REMOVE> event for each model that gets removed.
*
* Triggers <Coco.Event.RESET> event.
*
* Return:
* @return {Coco.Collection} - The <Coco.Collection> instance.
*/
reset: function reset() {
for (var i = 0; i < this._models.length; i++) {
//remove all model handles
this._removeModelHandles(this._models[i]);
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.REMOVE, this._models[i]));
}
this._models = [];
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.RESET, this));
this._addModelHandle(handle, model);
return this;
},
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.ADD, model));
/**
* Function: remove
* Removes one model.
*
* Parameter:
* @param {Coco.Model} model - The instance of <Coco.Model> to remove.
*
* @param {boolean} $silent - If set to true the model won't trigger the <Coco.Event.REMOVE> event.
*
* Event:
* Triggers <Coco.Event.REMOVE> event if $silent is not set to true.
*/
remove: function remove(model, $silent) {
if (model == null) {
console.warn(this.$name + ": can't delete null object!");
return;
}
for (var i = 0; i < this._models.length; i++) {
if (model.isEqual(this._models[i])) {
this.removeAt(i, $silent);
break;
}
}
},
return model;
},
/**
* Function: removeAt
* Removes model at specific index position.
*
* Parameter:
* @param {integer} index - The index position.
*
* @param {boolean} $silent - {optional} If set to true the model won't trigger the `remove` event.
*
* Event:
* Triggers <Coco.Event.REMOVE> event if $silent is not set to true.
*/
removeAt: function removeAt(index, $silent) {
if (this._models.length > index) {
var m = this._models.splice(index, 1);
/**
* Function: has
* checks for existing model in collection.
*
* Parameter:
* @param {Coco.Model} model - An <Coco.Model> instance
*
* Return:
* @returns {boolean} - True if model is in Collection
*/
has: function has(model) {
for (var i = 0; i < this._models.length; i++) {
if (model.isEqual(this._models[i])) {
return true;
}
}
this._removeModelHandles(m[0]);
return false;
},
if ($silent !== true) {
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.REMOVE, m[0]));
}
}
},
/**
* Function: reset
* Removes all models from the collection.
*
* Event:
* Triggers <Coco.Event.REMOVE> event for each model that gets removed.
*
* Triggers <Coco.Event.RESET> event.
*
* Return:
* @return {Coco.Collection} - The <Coco.Collection> instance.
*/
reset: function reset() {
for (var i = 0; i < this._models.length; i++) {
//remove all model handles
this._removeModelHandles(this._models[i]);
/**
* Function: getAt
* Gets model at specific index.
*
* Parameter:
* @param {integer} index - The index position.
*
* Return:
* @return {Coco.Model} - The remove <Coco.Model> instance.
*/
getAt: function getAt(index) {
if (index >= this._models.length || index < 0) {
return null;
}
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.REMOVE, this._models[i]));
}
return this._models[index];
},
this._models = [];
/**
* Function: indexOf
* Gets the index of a model.
*
* Parameter:
* @param {Coco.Model} model - An <Coco.Model> instance
*
* Return:
* @return {Number} - The index of the <Coco.Model> instance.
*/
indexOf: function indexOf(model) {
for (var i = 0; i < this._models.length; i++) {
if (model.isEqual(this._models[i])) {
return i;
}
}
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.RESET, this));
return -1;
},
return this;
},
/**
* Function: getAll
* Gets all models as <Coco.Model> instances.
*
* Return:
* @return {Array} - Array of <Coco.Model> instances.
*/
getAll: function getAll() {
return this._models;
},
/**
* Function: remove
* Removes one model.
*
* Parameter:
* @param {Coco.Model} model - The instance of <Coco.Model> to remove.
*
* @param {boolean} $silent - If set to true the model won't trigger the <Coco.Event.REMOVE> event.
*
* Event:
* Triggers <Coco.Event.REMOVE> event if $silent is not set to true.
*/
remove: function remove(model, $silent) {
if (model == null) {
console.warn(this.$name + ": can't delete null object!");
return;
}
/**
* Function: getAllAttributes
* Gets all models. This returns an array of all attributes of all models, not the Coco.Model instances.
* every model has its own entry
*
* Return:
* @returns {Array} - Array of attributes of <Coco.Model> instances.
*/
getAllAttributes: function getAllAttributes() {
var models = [];
for (var i = 0; i < this._models.length; i++) {
if (model.isEqual(this._models[i])) {
this.removeAt(i, $silent);
break;
}
}
},
$.each(this._models, function (i, e) {
// Add all attributes of current model
models.push(e.getAttributes());
});
/**
* Function: removeAt
* Removes model at specific index position.
*
* Parameter:
* @param {integer} index - The index position.
*
* @param {boolean} $silent - {optional} If set to true the model won't trigger the `remove` event.
*
* Event:
* Triggers <Coco.Event.REMOVE> event if $silent is not set to true.
*/
removeAt: function removeAt(index, $silent) {
if (this._models.length > index) {
var m = this._models.splice(index, 1);
return models;
},
this._removeModelHandles(m[0]);
/**
* Function: each
* Iterates over all objects in the collection and executes a given callback function for every model.
*
* If the callback returns false, the each function breaks.
*
* Parameter:
* @param {Function} callback - The method to execute for each model. Parameters are Coco.Model instance and index.
*/
each: function each(callback) {
if (this._models == null) {
return false;
}
for (var i = 0; i < this._models.length; i++) {
if (callback(this._models[i], i) === false) {
break;
}
}
},
if ($silent !== true) {
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.REMOVE, m[0]));
}
}
},
/**
* Function: push
* Adds a model at the end of the collection.
*
* Parameter:
* @param {Coco.Model} model - The <Coco.Model> instance to add.
*
* Event:
* Triggers <Coco.Event.ADD> event
*/
push: function push(model) {
var _this3 = this;
/**
* Function: getAt
* Gets model at specific index.
*
* Parameter:
* @param {integer} index - The index position.
*
* Return:
* @return {Coco.Model} - The remove <Coco.Model> instance.
*/
getAt: function getAt(index) {
if (index >= this._models.length || index < 0) {
return null;
}
if (model instanceof this._modelClass) {
var handle = model.addEventListener(Coco.Event.DESTROY, function (event) {
_this3.__onModelDestroy(event);
}, true);
this._models.push(model);
this._addModelHandle(handle, model);
return this._models[index];
},
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.ADD, model));
}
},
/**
* Function: indexOf
* Gets the index of a model.
*
* Parameter:
* @param {Coco.Model} model - An <Coco.Model> instance
*
* Return:
* @return {Number} - The index of the <Coco.Model> instance.
*/
indexOf: function indexOf(model) {
for (var i = 0; i < this._models.length; i++) {
if (model.isEqual(this._models[i])) {
return i;
}
}
/**
* Function: pop
* Removes and returns the last model from the collection.
*
* Return
* @return {Coco.Model} - The removed <Coco.Model> instance.
*
* Event:
* Triggers <Coco.Event.REMOVE> event
*/
pop: function pop() {
var model = this._models.pop();
return -1;
},
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.REMOVE, model));
/**
* Function: getAll
* Gets all models as <Coco.Model> instances.
*
* Return:
* @return {Array} - Array of <Coco.Model> instances.
*/
getAll: function getAll() {
return this._models;
},
return model;
},
/**
* Function: getAllAttributes
* Gets all models. This returns an array of all attributes of all models, not the Coco.Model instances.
* every model has its own entry
*
* Return:
* @returns {Array} - Array of attributes of <Coco.Model> instances.
*/
getAllAttributes: function getAllAttributes() {
var models = [];
$.each(this._models, function (i, e) {
// Add all attributes of current model
models.push(e.getAttributes());
});
return models;
},
/**
* Function: unshift
* Adds a model at the beginning of the collection.
*
* Parameter:
* @param {Coco.Model} model - The <Coco.Model> instance to add.
*
* Event:
* Triggers <Coco.Event.ADD> event
*/
unshift: function unshift(model) {
if (model instanceof this._modelClass) {
//TODO ????
//this._removeModelHandles(model);
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.ADD, model));
return this._models.unshift(model);
}
},
/**
* Function: each
* Iterates over all objects in the collection and executes a given callback function for every model.
*
* If the callback returns false, the each function breaks.
*
* Parameter:
* @param {Function} callback - The method to execute for each model. Parameters are Coco.Model instance and index.
*/
each: function each(callback) {
if (this._models == null) {
return false;
}
/**
* Function: shift
* Removes and returns the first model from the collection.
*
* Return:
* @return {Coco.Model} - The removed <Coco.Model> instance.
*
* Event:
* Triggers <Coco.Event.REMOVE> event
*/
shift: function shift() {
var model = this._models.shift();
for (var i = 0; i < this._models.length; i++) {
if (callback(this._models[i], i) === false) {
break;
}
}
},
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.REMOVE, model));
/**
* Function: push
* Adds a model at the end of the collection.
*
* Parameter:
* @param {Coco.Model} model - The <Coco.Model> instance to add.
*
* Event:
* Triggers <Coco.Event.ADD> event
*/
push: function push(model) {
var _this3 = this;
return model;
},
if (model instanceof this._modelClass) {
var handle = model.addEventListener(Coco.Event.DESTROY, function (event) {
_this3.__onModelDestroy(event);
}, true);
/**
* Function: findBy
* Finds models by given query object. The object contains attributes and their values and findBy will match this
* against the collections models.
*
* Parameter:
* @param {object} query - The object of attributes and values to look for in the collection.
*
* Return:
* @return {Array} - Array of matched <Coco.Model> instances.
*/
findBy: function findBy(query) {
var models = [];
var valid = false;
this._models.push(model);
$.each(this._models, function (i, e) {
valid = true;
this._addModelHandle(handle, model);
$.each(query, function (key, value) {
if (!e.has(key) || e.get(key) != value) {
valid = false;
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.ADD, model));
}
},
return false;
}
});
/**
* Function: pop
* Removes and returns the last model from the collection.
*
* Return
* @return {Coco.Model} - The removed <Coco.Model> instance.
*
* Event:
* Triggers <Coco.Event.REMOVE> event
*/
pop: function pop() {
var model = this._models.pop();
if (valid) {
models.push(e);
}
});
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.REMOVE, model));
return models;
},
return model;
},
/**
* Function: findOneBy
* Acts like findBy but returns the first matched model.
*
* Parameter:
* @param {object} query - The object of attributes and values to look for in the collection.
*
* Return:
* @return {Coco.Model|null} - First matched <Coco.Model> instance of null.
*/
findOneBy: function findOneBy(query) {
var model = null;
var valid = false;
/**
* Function: unshift
* Adds a model at the beginning of the collection.
*
* Parameter:
* @param {Coco.Model} model - The <Coco.Model> instance to add.
*
* Event:
* Triggers <Coco.Event.ADD> event
*/
unshift: function unshift(model) {
if (model instanceof this._modelClass) {
//TODO ????
//this._removeModelHandles(model);
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.ADD, model));
$.each(this._models, function (i, e) {
valid = true;
return this._models.unshift(model);
}
},
$.each(query, function (key, value) {
if (!e.has(key) || e.get(key) != value) {
valid = false;
/**
* Function: shift
* Removes and returns the first model from the collection.
*
* Return:
* @return {Coco.Model} - The removed <Coco.Model> instance.
*
* Event:
* Triggers <Coco.Event.REMOVE> event
*/
shift: function shift() {
var model = this._models.shift();
return false;
}
});
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.REMOVE, model));
if (valid) {
model = e;
return model;
},
return false;
}
});
/**
* Function: findBy
* Finds models by given query object. The object contains attributes and their values and findBy will match this
* against the collections models.
*
* Parameter:
* @param {object} query - The object of attributes and values to look for in the collection.
*
* Return:
* @return {Array} - Array of matched <Coco.Model> instances.
*/
findBy: function findBy(query) {
var models = [];
var valid = false;
$.each(this._models, function (i, e) {
valid = true;
$.each(query, function (key, value) {
if (!e.has(key) || e.get(key) != value) {
valid = false;
return false;
}
});
return model;
},
if (valid) {
models.push(e);
}
});
return models;
},
/**
* Function: removeBy
* removes all matched models from current collection
*
* Parameter:
* @param {object} query - The object of attributes and values to look for in the collection.
*
* Return:
* @return {Array} - all removed models
*/
removeBy: function removeBy(query, $silent) {
var _this4 = this;
/**
* Function: findOneBy
* Acts like findBy but returns the first matched model.
*
* Parameter:
* @param {object} query - The object of attributes and values to look for in the collection.
*
* Return:
* @return {Coco.Model|null} - First matched <Coco.Model> instance of null.
*/
findOneBy: function findOneBy(query) {
var model = null;
var valid = false;
$.each(this._models, function (i, e) {
valid = true;
$.each(query, function (key, value) {
if (!e.has(key) || e.get(key) != value) {
valid = false;
return false;
}
});
var models = [];
var modelIndex = [];
var valid;
$.each(this._models, function (i, e) {
valid = true;
if (valid) {
model = e;
return false;
}
});
return model;
},
$.each(query, function (key, value) {
if (!e.has(key) || e.get(key) != value) {
valid = false;
/**
* Function: removeBy
* removes all matched models from current collection
*
* Parameter:
* @param {object} query - The object of attributes and values to look for in the collection.
*
* Return:
* @return {Array} - all removed models
*/
removeBy: function removeBy(query, $silent) {
var _this4 = this;
return false;
}
});
var models = [];
var modelIndex = [];
var valid;
$.each(this._models, function (i, e) {
valid = true;
$.each(query, function (key, value) {
if (!e.has(key) || e.get(key) != value) {
valid = false;
return false;
}
});
if (valid) {
models.push(e);
modelIndex.push(i);
}
});
if (valid) {
models.push(e);
modelIndex.push(i);
}
});
_.each(modelIndex, function (index) {
_this4.removeAt(index, $silent);
});
_.each(modelIndex, function (index) {
_this4.removeAt(index, $silent);
});
return models;
},
return models;
},
/**
* Function: sortByProperty
* sorts all models in collection by property
*
* Parameter:
* @param {String }propertyName - name of property to sort on
*
* @param {boolean} $descending - (optional) sort direction: descending (default) == true
*/
sortByProperty: function sortByProperty(propertyName, $descending) {
if ($descending == null) {
$descending = true;
}
/**
* Function: sortByProperty
* sorts all models in collection by property
*
* Parameter:
* @param {String }propertyName - name of property to sort on
*
* @param {boolean} $descending - (optional) sort direction: descending (default) == true
*/
sortByProperty: function sortByProperty(propertyName, $descending) {
if ($descending == null) {
$descending = true;
}
var val;
var val;
this._models.sort(function (a, b) {
if (a === b) {
return 0;
}
this._models.sort(function (a, b) {
if (a === b) {
return 0;
}
if (a == null) {
//b is not null
return $descending ? 1 : -1;
}
if (a == null) {
//b is not null
return $descending ? 1 : -1;
}
if (b == null) {
//a is not null
return $descending ? -1 : 1;
}
if (b == null) {
//a is not null
return $descending ? -1 : 1;
}
if (a.get(propertyName) === b.get(propertyName)) {
return 0;
}
if (a.get(propertyName) === b.get(propertyName)) {
return 0;
}
if (a.get(propertyName) == null) {
return $descending ? 1 : -1;
}
if (a.get(propertyName) == null) {
return $descending ? 1 : -1;
}
if (b.get(propertyName) == null) {
return $descending ? -1 : 1;
}
if (b.get(propertyName) == null) {
return $descending ? -1 : 1;
}
if (Coco.Math.isNumber(a.get(propertyName))) {
val = parseFloat(a.get(propertyName)) < parseFloat(b.get(propertyName)) ? 1 : parseFloat(a.get(propertyName)) === parseFloat(b.get(propertyName)) ? 0 : -1;
return $descending ? val : -1 * val;
}
if (Coco.Math.isNumber(a.get(propertyName))) {
val = parseFloat(a.get(propertyName)) < parseFloat(b.get(propertyName)) ? 1 : parseFloat(a.get(propertyName)) === parseFloat(b.get(propertyName)) ? 0 : -1;
return $descending ? val : -1 * val;
} //sort alphabetically - UPPER letters are sorted BEFOR lower letters!!! --> convert all letters to lower case
//sort alphabetically - UPPER letters are sorted BEFOR lower letters!!! --> convert all letters to lower case
if (typeof a.get(propertyName) == "string") {
val = a.get(propertyName).toLowerCase() < b.get(propertyName).toLowerCase() ? 1 : a.get(propertyName).toLowerCase() === b.get(propertyName).toLowerCase() ? 0 : -1;
return $descending ? val : -1 * val;
}
//other
val = a.get(propertyName) < b.get(propertyName) ? 1 : a.get(propertyName) === b.get(propertyName) ? 0 : -1;
if (typeof a.get(propertyName) == "string") {
val = a.get(propertyName).toLowerCase() < b.get(propertyName).toLowerCase() ? 1 : a.get(propertyName).toLowerCase() === b.get(propertyName).toLowerCase() ? 0 : -1;
return $descending ? val : -1 * val;
} //other
return $descending ? val : -1 * val;
});
},
/**
* Function: size
* Returns the size of the collection.
*
* Return:
* @return {integer} - The size of the collection.
*/
size: function size() {
return this._models.length;
},
val = a.get(propertyName) < b.get(propertyName) ? 1 : a.get(propertyName) === b.get(propertyName) ? 0 : -1;
return $descending ? val : -1 * val;
});
},
/**
* Function: where
*
* Description:
* Looks through each value in the list, filters models by given object properties
*
* @return {array} - returning an array of all the values that contain all of the key-value pairs listed in properties.
*/
where: function where(propertyObject) {
return _.where(this.getAllAttributes(), propertyObject);
},
/**
* Function: size
* Returns the size of the collection.
*
* Return:
* @return {integer} - The size of the collection.
*/
size: function size() {
return this._models.length;
},
/**
* Function: where
*
* Description:
* Looks through each value in the list, filters models by given object properties
*
* @return {array} - returning an array of all the values that contain all of the key-value pairs listed in properties.
*/
where: function where(propertyObject) {
return _.where(this.getAllAttributes(), propertyObject);
},
/**
* Function: __onModelDestroy
*
* EventListener for Coco.Event.DESTROY - Event
*
* Removes a model from the collection when it's destroyed.
*
* Parameter:
* @param {Coco.ModelEvent} model - model to remove
* @private
*/
__onModelDestroy: function __onModelDestroy(event) {
this.remove(event.model, true);
},
/**
* Function: __onModelDestroy
*
* EventListener for Coco.Event.DESTROY - Event
*
* Removes a model from the collection when it's destroyed.
*
* Parameter:
* @param {Coco.ModelEvent} model - model to remove
* @private
*/
__onModelDestroy: function __onModelDestroy(event) {
this.remove(event.model, true);
},
/**
* Function: getId
* Returns the internal id. Useful for comparison between different objects. If two object have the same id,
* they are identical.
*
* Return:
* @return {string} - The internal collection id.
*/
getId: function getId() {
return this.__id;
},
/**
* Function: getId
* Returns the internal id. Useful for comparison between different objects. If two object have the same id,
* they are identical.
*
* Return:
* @return {string} - The internal collection id.
*/
getId: function getId() {
return this.__id;
},
/**
* Function: isEqual
* Checks if two collections are the same
*
* Parameter:
* @param {Coco.Collection} collection - The <Coco.Collection> instance to compare
*
* Return:
* @return {boolean} - True if both collections are the same instance, otherwise false.
*/
isEqual: function isEqual(collection) {
return this.__id === collection.getId();
},
/**
* Function: isEqual
* Checks if two collections are the same
*
* Parameter:
* @param {Coco.Collection} collection - The <Coco.Collection> instance to compare
*
* Return:
* @return {boolean} - True if both collections are the same instance, otherwise false.
*/
isEqual: function isEqual(collection) {
return this.__id === collection.getId();
},
/**
* Function: destroy
* Destroy the collection. Destroying the collection will remove and destroy
* all attached models.
*/
destroy: function destroy() {
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.DESTROY, this));
/**
* Function: destroy
* Destroy the collection. Destroying the collection will remove and destroy
* all attached models.
*/
destroy: function destroy() {
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.DESTROY, this));
this.each(function (model) {
// Destroy all models
model.destroy();
});
this.removeAllEventListener();
}
this.each(function (model) {
// Destroy all models
model.destroy();
});
this.removeAllEventListener();
}
});
"use strict";
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }

@@ -11,3 +11,2 @@ var Coco = Coco || {};

Coco.ModelEvent = require("../event/Coco.ModelEvent.js");
/**

@@ -36,624 +35,621 @@ * Class: Coco.Model

*/
module.exports = Coco.Model = dejavu.Class.declare({
$name: 'Model',
$name: 'Model',
$extends: Coco.ServiceProvider,
$extends: Coco.ServiceProvider,
/**
* The internal model id.
*/
__id: 0,
/**
* The internal model id.
*/
__id: 0,
/**
* A private class identifier, copied from `this.$name`
*/
__$name: "Model",
/**
* A private class identifier, copied from `this.$name`
*/
__$name: "Model",
/**
* The current attributes of the model.
*
* @type {Object}
*/
__attributes: {},
/**
* The current attributes of the model.
*
* @type {Object}
*/
__attributes: {},
/**
* The status of the attributes on instantiation. Used to check if the model has changed since it was created.
*
* @type {Object}
*/
__initialAttributes: null,
/**
* The status of the attributes on instantiation. Used to check if the model has changed since it was created.
*
* @type {Object}
*/
__initialAttributes: null,
/**
* Hold probable validation error. You can retrieve this with `this.getValidationError()`. It's set internally by
* the `this.isValid()` method.
*
* @type {Object}
*/
__validationError: null,
/**
* Hold probable validation error. You can retrieve this with `this.getValidationError()`. It's set internally by
* the `this.isValid()` method.
*
* @type {Object}
*/
__validationError: null,
/**
* Array of observers registered by the $compute flag on computed functions.
*/
__observers: [],
/**
* Array of observers registered by the $compute flag on computed functions.
*/
__observers: [],
/**
* Variable: _defaults
*
* Description:
* The default attributes that are assigned to each new instance of the model.
* Default values can be overwritten on instantiation.
*
* @type {Object}
*/
_defaults: {},
/**
* Variable: _defaults
*
* Description:
* The default attributes that are assigned to each new instance of the model.
* Default values can be overwritten on instantiation.
*
* @type {Object}
*/
_defaults: {},
/**
* Variable: _etherKeys
*
* Description:
* The ether keys, that can be demanded by all Coco.View instances.
*
* @type {Array}
*/
_etherKeys: [],
/**
* Variable: _etherKeys
*
* Description:
* The ether keys, that can be demanded by all Coco.View instances.
*
* @type {Array}
*/
_etherKeys: [],
/**
* Function: Constructor
*
* Parameter:
* @param {Object} $attributes - {optional} The attributes that are set to the models attributes on creation.
*/
initialize: function initialize($attributes) {
this.__$name = this.$name;
this.__id = Coco.Utils.uniqueId("m");
/**
* Function: Constructor
*
* Parameter:
* @param {Object} $attributes - {optional} The attributes that are set to the models attributes on creation.
*/
initialize: function initialize($attributes) {
this.__$name = this.$name;
this.__id = Coco.Utils.uniqueId("m");
if ($attributes != null) {
for (var i in this._defaults) {
// Check if the value of the attributes key is a function and if so, delete it (because we don't want to overwrite the computed properties)
if (this._defaults.hasOwnProperty(i) && typeof this._defaults[i] === 'function' && $attributes.hasOwnProperty(i)) {
delete $attributes[i];
}
}
}
if ($attributes != null) {
for (var i in this._defaults) {
this.__attributes = $.extend({}, this._defaults, $attributes != null ? $attributes : {});
this.__attributes = this.__setObservers(this.__attributes);
this.__initialAttributes = $.extend({}, this.__attributes);
// Check if the value of the attributes key is a function and if so, delete it (because we don't want to overwrite the computed properties)
if (this._defaults.hasOwnProperty(i) && typeof this._defaults[i] === 'function' && $attributes.hasOwnProperty(i)) {
delete $attributes[i];
}
}
}
this._setCollections();
this.__attributes = $.extend({}, this._defaults, $attributes != null ? $attributes : {});
this.__attributes = this.__setObservers(this.__attributes);
this.__initialAttributes = $.extend({}, this.__attributes);
this._setCollections();
this._onInitialize();
},
this._onInitialize();
},
/**
* Function: _onInitialize
*
* Description:
* Is called at the end of the initialize method and acts like the hook in <Coco.View>
*
* @protected
*/
_onInitialize: function _onInitialize() {},
/**
* Function: _onInitialize
*
* Description:
* Is called at the end of the initialize method and acts like the hook in <Coco.View>
*
* @protected
*/
_onInitialize: function _onInitialize() {},
/**
* Function: _setCollections
*
* Description:
* Overwrite this function in your model if you have collections inside the model. You need to set the default
*
* parameters with `new <Coco.Collection> ()` to ensure that a new collection is created.
*
* @protected
*/
_setCollections: function _setCollections() {},
/**
* Function: _setCollections
*
* Description:
* Overwrite this function in your model if you have collections inside the model. You need to set the default
*
* parameters with `new <Coco.Collection> ()` to ensure that a new collection is created.
*
* @protected
*/
_setCollections: function _setCollections() {},
/**
* Sets the observers and assigns the correct context to the computed properties functions.
*
* @param attributes
* @returns {*}
* @private
*/
__setObservers: function __setObservers(attributes) {
for (var i in attributes) {
if (attributes.hasOwnProperty(i) && typeof attributes[i] === 'function' && attributes[i].isComputed === true) {
attributes[i] = attributes[i].call(this, i, this.__observers);
}
/**
* Sets the observers and assigns the correct context to the computed properties functions.
*
* @param attributes
* @returns {*}
* @private
*/
__setObservers: function __setObservers(attributes) {
for (var i in attributes) {
if (attributes.hasOwnProperty(i) && typeof attributes[i] === 'function' && attributes[i].isComputed === true) {
attributes[i] = attributes[i].call(this, i, this.__observers);
}
}
return attributes;
},
/**
* We trigger the target attribute keys, when an observed attribute changed.
*
* @param attribute
* @private
*/
__triggerObservers: function __triggerObservers(attribute) {
for (var i in this.__observers) {
if (this.__observers.hasOwnProperty(i) && this.__observers[i].attribute === attribute) {
var newValue = this.get(this.__observers[i].target);
if (newValue !== this.__observers[i].old) {
//this.trigger(Coco.Event.CHANGE_KEY + this.__observers[i].target, newValue, this.__observers[i].old);
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.CHANGE_KEY + this.__observers[i].target, this, this.__observers[i].target));
this.__observers[i].old = newValue;
}
}
}
},
return attributes;
},
/**
* Function: add
* Adds a new key value pair(s) to the attributes. If key already exists, <Coco.Model.set> will be called instead.
*
* Parameter:
* @param {string} attribute - The new attribute to add
*
* @param {*} value - The attributes value.
*
* Return:
* @returns {Coco.Model} - The <Coco.Model> instance.
*
* Event:
* Triggers <Coco.Event.ADD> event if attribute did not exist before.
*/
add: function add(attribute, value) {
var object = {};
typeof attribute === 'string' ? object[attribute] = value : object = attribute;
/**
* We trigger the target attribute keys, when an observed attribute changed.
*
* @param attribute
* @private
*/
__triggerObservers: function __triggerObservers(attribute) {
for (var i in this.__observers) {
if (this.__observers.hasOwnProperty(i) && this.__observers[i].attribute === attribute) {
var newValue = this.get(this.__observers[i].target);
for (var key in object) {
if (object.hasOwnProperty(key)) {
// Check for existing key in attributes
if (!this.__attributes.hasOwnProperty(key)) {
// Key does not exist, so add it
this.__attributes[key] = object[key]; //this.trigger(Coco.Event.ADD, key, object[key], this);
if (newValue !== this.__observers[i].old) {
//this.trigger(Coco.Event.CHANGE_KEY + this.__observers[i].target, newValue, this.__observers[i].old);
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.CHANGE_KEY + this.__observers[i].target, this, this.__observers[i].target));
this.__observers[i].old = newValue;
}
}
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.ADD, this));
} else {
// Key exists, set new value
this.set(key, object[key]);
}
},
}
}
/**
* Function: add
* Adds a new key value pair(s) to the attributes. If key already exists, <Coco.Model.set> will be called instead.
*
* Parameter:
* @param {string} attribute - The new attribute to add
*
* @param {*} value - The attributes value.
*
* Return:
* @returns {Coco.Model} - The <Coco.Model> instance.
*
* Event:
* Triggers <Coco.Event.ADD> event if attribute did not exist before.
*/
add: function add(attribute, value) {
var object = {};
return this;
},
typeof attribute === 'string' ? object[attribute] = value : object = attribute;
/**
* Function: set
* Sets one or more attributes.
*
* Parameter:
* @param {string|object} attribute - If a string is given, Coco will use this value as key, if object is given, Coco will overwrite all matched attributes of the object.
*
* @param {*} $value - {optional} The attributes value, if attribute is a string.
*
* Return:
* @returns {Coco.Model} - The <Coco.Model> instance.
*
* Event:
* Triggers <Coco.Event.CHANGE> event.
*
* Triggers <Coco.Event.CHANGE_KEY> value on each changes attribute.
*/
set: function set(attribute, $value) {
var object = {};
var oldObject = $.extend(true, {}, this.__attributes);
var changed = false;
typeof attribute === 'string' ? object[attribute] = $value : object = attribute;
for (var key in object) {
if (object.hasOwnProperty(key)) {
// Check for existing key in attributes
if (!this.__attributes.hasOwnProperty(key)) {
// Key does not exist, so add it
this.__attributes[key] = object[key];
for (var key in object) {
if (object.hasOwnProperty(key)) {
this.__attributes[key] = object[key]; // TODO: deep check for objects.
//this.trigger(Coco.Event.ADD, key, object[key], this);
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.ADD, this));
} else {
// Key exists, set new value
this.set(key, object[key]);
}
}
}
if (object[key] !== oldObject[key]) {
changed = true; // Throw special key changed event
//this.trigger(Coco.Event.CHANGE_KEY + key, object[key], this, oldObject[key]);
return this;
},
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.CHANGE_KEY + key, this, key)); // Trigger all dependent computed attributes when an observed attribute changed.
/**
* Function: set
* Sets one or more attributes.
*
* Parameter:
* @param {string|object} attribute - If a string is given, Coco will use this value as key, if object is given, Coco will overwrite all matched attributes of the object.
*
* @param {*} $value - {optional} The attributes value, if attribute is a string.
*
* Return:
* @returns {Coco.Model} - The <Coco.Model> instance.
*
* Event:
* Triggers <Coco.Event.CHANGE> event.
*
* Triggers <Coco.Event.CHANGE_KEY> value on each changes attribute.
*/
set: function set(attribute, $value) {
var object = {};
var oldObject = $.extend(true, {}, this.__attributes);
var changed = false;
typeof attribute === 'string' ? object[attribute] = $value : object = attribute;
this.__triggerObservers(key);
}
}
}
for (var key in object) {
if (object.hasOwnProperty(key)) {
this.__attributes[key] = object[key];
if (changed) {
// Throw default changed event
//this.trigger(Coco.Event.CHANGE, object, this, oldObject);
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.CHANGE, this));
}
// TODO: deep check for objects.
if (object[key] !== oldObject[key]) {
changed = true;
return this;
},
// Throw special key changed event
//this.trigger(Coco.Event.CHANGE_KEY + key, object[key], this, oldObject[key]);
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.CHANGE_KEY + key, this, key));
/**
* Function: get
* Gets a value by key. If no key is passed the whole object is returned. This can be also achieved by calling `this.getAll`.
*
* Parameter:
* @param {string} $attribute - {optional} The key to return the value of
*
* @param {integer} $castTo - {optional} Parse the value to given type. Should refer to a constant from `Coco.Util`
*
* @param {boolean} $fix - {optional} If set to `true` the casted value will be saved to the attributes.
*
* Return:
* @returns {*} - The value of the key.
*
* Event:
* Triggers <Coco.Event.CHANGE> and <Coco.Event.Event_CHANGE_KEY> events, if $fix is set to true.
*/
get: function get($attribute, $castTo, $fix) {
if ($attribute == null) {
// Return all attributes of this model
var ret = {};
// Trigger all dependent computed attributes when an observed attribute changed.
this.__triggerObservers(key);
}
}
for (var i in this.__attributes) {
if (this.__attributes.hasOwnProperty(i)) {
ret[i] = typeof this.__attributes[i] === 'function' && this.__attributes[i].isComputed ? this.__attributes[i]() : this.__attributes[i];
}
}
if (changed) {
// Throw default changed event
//this.trigger(Coco.Event.CHANGE, object, this, oldObject);
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.CHANGE, this));
return ret;
}
if ($castTo == null) {
// Return value of given key
if (this.__attributes.hasOwnProperty($attribute)) {
// If value is a function, call it
if (typeof this.__attributes[$attribute] === 'function' && this.__attributes[$attribute].isComputed) {
return this.__attributes[$attribute].call(this);
}
return this;
},
return this.__attributes[$attribute];
} else {
throw new Error("Tried to get '" + $attribute + "' in model '" + this.$name + "'. The key does not exist. Maybe you have a typo.");
}
}
/**
* Function: get
* Gets a value by key. If no key is passed the whole object is returned. This can be also achieved by calling `this.getAll`.
*
* Parameter:
* @param {string} $attribute - {optional} The key to return the value of
*
* @param {integer} $castTo - {optional} Parse the value to given type. Should refer to a constant from `Coco.Util`
*
* @param {boolean} $fix - {optional} If set to `true` the casted value will be saved to the attributes.
*
* Return:
* @returns {*} - The value of the key.
*
* Event:
* Triggers <Coco.Event.CHANGE> and <Coco.Event.Event_CHANGE_KEY> events, if $fix is set to true.
*/
get: function get($attribute, $castTo, $fix) {
if ($attribute == null) {
// Return all attributes of this model
var ret = {};
if ($fix == null) {
console.log("Coco.Utils.cast ... ???");
return this.__attributes.hasOwnProperty($attribute) ? Coco.Utils.cast(this.__attributes[$attribute], $castTo, $attribute) : null;
}
for (var i in this.__attributes) {
if (this.__attributes.hasOwnProperty(i)) {
ret[i] = typeof this.__attributes[i] === 'function' && this.__attributes[i].isComputed ? this.__attributes[i]() : this.__attributes[i];
}
}
if (this.__attributes.hasOwnProperty($attribute)) {
// Save casted value into this attributes
this.cast($attribute, $castTo);
return this.__attributes[$attribute];
}
return ret;
}
throw new Error("Tried to get '" + $attribute + "' in model '" + this.$name + "'. The key does not exist. Maybe you have a typo.");
},
if ($castTo == null) {
// Return value of given key
if (this.__attributes.hasOwnProperty($attribute)) {
// If value is a function, call it
if (typeof this.__attributes[$attribute] === 'function' && this.__attributes[$attribute].isComputed) {
return this.__attributes[$attribute].call(this);
}
/**
* Function: boundGet
* A bound variant of <Coco.Model.get>
*
* Parameter:
* @param {string} $key - {optional} The key to return the value of
* @param {integer} $castTo - {optional} Parse the value to given type. Should refer to a constant from `Coco.Util`
* @param {boolean} $fix - {optional} If set to `true` the casted value will be saved to the attributes.
*
* Return:
* @returns {*} - The value of the key
*/
boundGet: function ($key, $castTo, $fix) {
return this.get($key, $castTo, $fix);
}.$bound(),
return this.__attributes[$attribute];
} else {
throw new Error("Tried to get '" + $attribute + "' in model '" + this.$name + "'. The key does not exist. Maybe you have a typo.");
}
}
/**
* Function: getAttributes
* Returns the attributes object.
*
* Return:
* @returns {Object} - All attributes of the model instance.
*/
getAttributes: function getAttributes() {
var attributes = {};
var keys = this.getKeys();
if ($fix == null) {
console.log("Coco.Utils.cast ... ???");
return this.__attributes.hasOwnProperty($attribute) ? Coco.Utils.cast(this.__attributes[$attribute], $castTo, $attribute) : null;
}
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
var value = this.get(key);
if (this.__attributes.hasOwnProperty($attribute)) {
// Save casted value into this attributes
this.cast($attribute, $castTo);
if (value instanceof Coco.Model) {
//resolve all Coco.Models
value = value.getAttributes();
}
return this.__attributes[$attribute];
}
if (value instanceof Coco.Collection) {
//resolve all Coco.Collections
value = value.getAllAttributes();
}
throw new Error("Tried to get '" + $attribute + "' in model '" + this.$name + "'. The key does not exist. Maybe you have a typo.");
},
if (value instanceof Array) {
//search for Coco.Models within an array
var val = [];
/**
* Function: boundGet
* A bound variant of <Coco.Model.get>
*
* Parameter:
* @param {string} $key - {optional} The key to return the value of
* @param {integer} $castTo - {optional} Parse the value to given type. Should refer to a constant from `Coco.Util`
* @param {boolean} $fix - {optional} If set to `true` the casted value will be saved to the attributes.
*
* Return:
* @returns {*} - The value of the key
*/
boundGet: function ($key, $castTo, $fix) {
return this.get($key, $castTo, $fix);
}.$bound(),
for (var j = 0; j < value.length; j++) {
var innerValue = value[j];
/**
* Function: getAttributes
* Returns the attributes object.
*
* Return:
* @returns {Object} - All attributes of the model instance.
*/
getAttributes: function getAttributes() {
var attributes = {};
var keys = this.getKeys();
if (innerValue instanceof Coco.Model) {
innerValue = innerValue.getAttributes();
}
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
var value = this.get(key);
if (innerValue instanceof Coco.Collection) {
innerValue = innerValue.getAllAttributes();
}
if (value instanceof Coco.Model) {
//resolve all Coco.Models
value = value.getAttributes();
}
val.push(innerValue);
}
if (value instanceof Coco.Collection) {
//resolve all Coco.Collections
value = value.getAllAttributes();
}
value = val;
}
if (value instanceof Array) {
//search for Coco.Models within an array
var val = [];
attributes[key] = value;
}
for (var j = 0; j < value.length; j++) {
var innerValue = value[j];
return attributes;
},
if (innerValue instanceof Coco.Model) {
innerValue = innerValue.getAttributes();
}
/**
* Function: getKeys
* Returns all attribute keys as an array.
*
* Return:
* @return {Array} - All attribute keys of the model instance as an Array.
*/
getKeys: function getKeys() {
// Check for ECMA5
if (typeof Object.keys === "function") {
return Object.keys(this.__attributes);
}
if (innerValue instanceof Coco.Collection) {
innerValue = innerValue.getAllAttributes();
}
var keys = [];
val.push(innerValue);
}
for (var k in this.__attributes) {
if (this.__attributes.hasOwnProperty(k)) {
keys.push(k);
}
}
value = val;
}
return keys;
},
attributes[key] = value;
}
/**
* Function: has
* Returns `true` if the value is defined, otherwise `false`.
*
* Parameter:
* @param {string} key - The attribute to check for it's existence.
*
* @param {boolean} $strict - {optional} If set to true, also attributes with the value null will return false
*
* Return:
* @return {boolean} - True if the key exists, otherwise false.
*/
has: function has(key, $strict) {
if ($strict) {
// Check also for defined value
return this.__attributes.hasOwnProperty(key) && this.__attributes[key] != null && this.__attributes[key].length !== 0;
} // Check only for key
return attributes;
},
/**
* Function: getKeys
* Returns all attribute keys as an array.
*
* Return:
* @return {Array} - All attribute keys of the model instance as an Array.
*/
getKeys: function getKeys() {
// Check for ECMA5
if (typeof Object.keys === "function") {
return Object.keys(this.__attributes);
}
return this.__attributes.hasOwnProperty(key);
},
var keys = [];
/**
* Function: is
* Checks if `key` is type of the parameter `type`.
*
* Parameter:
* @param {string} attribute - The models attribute to check
* @param {integer} type - The type to check for. Should refer to a constant from `Coco.Util`
*
* Return:
* @return {boolean} True if the typed is matched, otherwise false.
*/
is: function is(attribute, type) {
console.log("Coco.Utils. type");
for (var k in this.__attributes) {
if (this.__attributes.hasOwnProperty(k)) {
keys.push(k);
}
}
if (!this.__attributes.hasOwnProperty(attribute)) {
return type === Coco.Utils.UNDEFINED;
}
return keys;
},
var value = this.__attributes[attribute];
/**
* Function: has
* Returns `true` if the value is defined, otherwise `false`.
*
* Parameter:
* @param {string} key - The attribute to check for it's existence.
*
* @param {boolean} $strict - {optional} If set to true, also attributes with the value null will return false
*
* Return:
* @return {boolean} - True if the key exists, otherwise false.
*/
has: function has(key, $strict) {
if ($strict) {
// Check also for defined value
return this.__attributes.hasOwnProperty(key) && this.__attributes[key] != null && this.__attributes[key].length !== 0;
}
switch (type) {
case Coco.Utils.INTEGER:
return typeof value === 'number' && value % 1 == 0;
// Check only for key
return this.__attributes.hasOwnProperty(key);
},
case Coco.Utils.FLOAT:
// Returns false, if we have an integer value or sth like this: 1.0
return typeof value === 'number' && value % 1 != 0;
/**
* Function: is
* Checks if `key` is type of the parameter `type`.
*
* Parameter:
* @param {string} attribute - The models attribute to check
* @param {integer} type - The type to check for. Should refer to a constant from `Coco.Util`
*
* Return:
* @return {boolean} True if the typed is matched, otherwise false.
*/
is: function is(attribute, type) {
console.log("Coco.Utils. type");
if (!this.__attributes.hasOwnProperty(attribute)) {
return type === Coco.Utils.UNDEFINED;
}
case Coco.Utils.STRING:
return typeof value === 'string';
var value = this.__attributes[attribute];
case Coco.Utils.ARRAY:
return value instanceof Array;
switch (type) {
case Coco.Utils.INTEGER:
return typeof value === 'number' && value % 1 == 0;
case Coco.Utils.OBJECT:
return _typeof(value) === 'object' && !(value instanceof Array);
case Coco.Utils.FLOAT:
// Returns false, if we have an integer value or sth like this: 1.0
return typeof value === 'number' && value % 1 != 0;
case Coco.Utils.NULL:
return value === null;
case Coco.Utils.STRING:
return typeof value === 'string';
default:
return false;
}
},
case Coco.Utils.ARRAY:
return value instanceof Array;
/**
* Function: remove($key)
* Removes a key from the model.
*
* Parameter:
* @param {string} key - The key to remove.
*/
remove: function remove(key) {
if (this.has(key)) {
delete this.__attributes[key];
}
},
case Coco.Utils.OBJECT:
return (typeof value === "undefined" ? "undefined" : _typeof(value)) === 'object' && !(value instanceof Array);
/**
* Function reset
* Resets the attributes of a model to its defaults.
*
* Parameter:
* @param {boolean} $toDefaults - {optional} if set to true the model will be reset with the `this._defaults` object.
*
* Event:
* Triggers <Coco.Event.RESET> event.
*/
reset: function reset($toDefaults) {
var collections = {};
case Coco.Utils.NULL:
return value === null;
for (var i in this.__attributes) {
if (this.__attributes.hasOwnProperty(i) && this.__attributes[i] instanceof Coco.Event) {
collections[i] = this.__attributes[i].reset();
}
}
default:
return false;
}
},
if ($toDefaults) {
this.__attributes = $.extend({}, this._defaults, collections);
this.__initialAttributes = $.extend({}, this.__attributes);
} else {
this.__attributes = $.extend({}, this.__initialAttributes, collections);
} //this.trigger(Coco.Event.RESET);
/**
* Function: remove($key)
* Removes a key from the model.
*
* Parameter:
* @param {string} key - The key to remove.
*/
remove: function remove(key) {
if (this.has(key)) {
delete this.__attributes[key];
}
},
/**
* Function reset
* Resets the attributes of a model to its defaults.
*
* Parameter:
* @param {boolean} $toDefaults - {optional} if set to true the model will be reset with the `this._defaults` object.
*
* Event:
* Triggers <Coco.Event.RESET> event.
*/
reset: function reset($toDefaults) {
var collections = {};
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.RESET, this));
},
for (var i in this.__attributes) {
if (this.__attributes.hasOwnProperty(i) && this.__attributes[i] instanceof Coco.Event) {
collections[i] = this.__attributes[i].reset();
}
}
/**
* Function: cast
* Casts a attributes value to given `type` and stores it to the attributes.
*
* Parameter:
* @param {string} attribute - The attribute key
* @param {integer} type - The type to cast to. Should refer to a constant from `Coco.Utils`
*
* Return:
* @return {*} - The casted value of the attribute.
*
* Event:
* See <Coco.Model.set> for information what events are triggered.
*/
cast: function cast(attribute, type) {
this.set(attribute, Coco.Utils.cast(this.get(attribute), type, attribute));
return this.get(attribute);
},
if ($toDefaults) {
this.__attributes = $.extend({}, this._defaults, collections);
this.__initialAttributes = $.extend({}, this.__attributes);
} else {
this.__attributes = $.extend({}, this.__initialAttributes, collections);
}
/**
* Function: isValid
* Checks if model is valid by calling user specified `this._validate` function.
*
* Return:
* @return {boolean}
*
* Event:
* @event Triggers `invalid` if model validation failed, otherwise `valid`
*/
isValid: function isValid() {
this.__validationError = null;
//this.trigger(Coco.Event.RESET);
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.RESET, this));
},
var result = this._validate(this.getAttributes());
/**
* Function: cast
* Casts a attributes value to given `type` and stores it to the attributes.
*
* Parameter:
* @param {string} attribute - The attribute key
* @param {integer} type - The type to cast to. Should refer to a constant from `Coco.Utils`
*
* Return:
* @return {*} - The casted value of the attribute.
*
* Event:
* See <Coco.Model.set> for information what events are triggered.
*/
cast: function cast(attribute, type) {
this.set(attribute, Coco.Utils.cast(this.get(attribute), type, attribute));
if (result !== true) {
this.__validationError = result; //this.trigger(Coco.Event.INVALID, result, this);
return this.get(attribute);
},
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.INVALID, this));
/**
* Function: isValid
* Checks if model is valid by calling user specified `this._validate` function.
*
* Return:
* @return {boolean}
*
* Event:
* @event Triggers `invalid` if model validation failed, otherwise `valid`
*/
isValid: function isValid() {
this.__validationError = null;
var result = this._validate(this.getAttributes());
return false;
} else {
//this.trigger(Coco.Event.VALID, this);
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.VALID, this));
}
if (result !== true) {
this.__validationError = result;
return true;
},
//this.trigger(Coco.Event.INVALID, result, this);
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.INVALID, this));
/**
* Function: _validate
* Is called by `this.isValid` from within the model. Return anything but `true` to indicate that the validation failed.
*
* Parameter:
* @param {object} attrs - The attributes of the model
*
* Return:
* @return {*}
*
* @protected
*/
_validate: function _validate(attrs) {
return true;
},
return false;
} else {
//this.trigger(Coco.Event.VALID, this);
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.VALID, this));
}
/**
* Function: getValidationError
* Returns the validation errors.
*
* Return:
* @return {null|Object}
*/
getValidationError: function getValidationError() {
return this.__validationError;
},
return true;
},
/**
* Function: getEtherKeys
* Returns the ether keys.
*
* Return:
* @return {Array}
*/
getEtherKeys: function getEtherKeys() {
return this._etherKeys;
},
/**
* Function: _validate
* Is called by `this.isValid` from within the model. Return anything but `true` to indicate that the validation failed.
*
* Parameter:
* @param {object} attrs - The attributes of the model
*
* Return:
* @return {*}
*
* @protected
*/
_validate: function _validate(attrs) {
return true;
},
/**
* Function: getId
* Returns the internal id. Useful for comparison between different objects. If two object have the same id,
* they are identical.
*
* Return:
* @return {string}
*/
getId: function getId() {
return this.__id;
},
/**
* Function: getValidationError
* Returns the validation errors.
*
* Return:
* @return {null|Object}
*/
getValidationError: function getValidationError() {
return this.__validationError;
},
/**
* Function: isEqual
* Checks if two models are the same
*
* Parameter:
* @param {Coco.Model} model - The <Coco.Model> instance
*
* Return:
* @return {boolean} - True if both are equal.
*/
isEqual: function isEqual(model) {
return this.__id === model.getId();
},
/**
* Function: getEtherKeys
* Returns the ether keys.
*
* Return:
* @return {Array}
*/
getEtherKeys: function getEtherKeys() {
return this._etherKeys;
},
/**
* Function: destroy
* Destroy the model
*/
destroy: function destroy() {
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.DESTROY, this)); //remove all eventListener
/**
* Function: getId
* Returns the internal id. Useful for comparison between different objects. If two object have the same id,
* they are identical.
*
* Return:
* @return {string}
*/
getId: function getId() {
return this.__id;
},
/**
* Function: isEqual
* Checks if two models are the same
*
* Parameter:
* @param {Coco.Model} model - The <Coco.Model> instance
*
* Return:
* @return {boolean} - True if both are equal.
*/
isEqual: function isEqual(model) {
return this.__id === model.getId();
},
/**
* Function: destroy
* Destroy the model
*/
destroy: function destroy() {
this._dispatchEvent(new Coco.ModelEvent(Coco.Event.DESTROY, this));
//remove all eventListener
this.removeAllEventListener();
}
this.removeAllEventListener();
}
});

@@ -18,120 +18,117 @@ "use strict";

*/
module.exports = dejavu.Class.declare({
$name: 'Router',
$name: 'Router',
$extends: Coco.ServiceProvider,
$inject: ['router'],
__id: Coco.Utils.uniqueId("r"),
$extends: Coco.ServiceProvider,
/**
* A jQuery element where the view gets appended to.
*/
__$container: null,
$inject: ['router'],
/**
* Function: Constructor
*
* Description:
* Initialize the routing functionality of Coco.
*
* @param selector {string} - A CSS selector to append the current views.
* @param routing {Object} - A object containing routing information.
* @param $initialPath {Object} - A optional $initialPath to start the application with. Defaults to '/'
*/
initialize: function initialize(selector, routing, $initialPath) {
var _this = this;
__id: Coco.Utils.uniqueId("r"),
//you HAVE to use constructor, because of the given variables
this.$super();
/**
* A jQuery element where the view gets appended to.
*/
__$container: null,
this._getService("router").addEventListener(Coco.RouterEvent.SHOW_VIEW, function () {
_this.__onShowView();
});
/**
* Function: Constructor
*
* Description:
* Initialize the routing functionality of Coco.
*
* @param selector {string} - A CSS selector to append the current views.
* @param routing {Object} - A object containing routing information.
* @param $initialPath {Object} - A optional $initialPath to start the application with. Defaults to '/'
*/
initialize: function initialize(selector, routing, $initialPath) {
var _this = this;
this._getService("router").addEventListener(Coco.RouterEvent.HIDE_VIEW, function () {
_this.__onHideView();
});
//you HAVE to use constructor, because of the given variables
this.$super();
this.__$container = $(selector);
this.$services.router.setContainer(this.__$container); // Copy the routing object to prevent any modification during application lifetime.
this._getService("router").addEventListener(Coco.RouterEvent.SHOW_VIEW, function () {
_this.__onShowView();
});
this._getService("router").addEventListener(Coco.RouterEvent.HIDE_VIEW, function () {
_this.__onHideView();
});
this.__createRouting($.extend({}, routing), $initialPath);
},
this.__$container = $(selector);
/**
* Adds the routing object to the routerService and starts the routing.
*
* @param routing
* @param $initialPath
* @private
*/
__createRouting: function __createRouting(routing, $initialPath) {
for (var i in routing) {
if (routing.hasOwnProperty(i)) {
this.$services.router.addRoute(i, routing[i]);
}
}
this.$services.router.setContainer(this.__$container);
this.$services.router.start($initialPath);
},
// Copy the routing object to prevent any modification during application lifetime.
this.__createRouting($.extend({}, routing), $initialPath);
},
/**
* This function checks if the cached routing anchor is still in the DOM or has been removed or replaced during
* the lifetime of the application.
*
* @returns {boolean}
* @private
*/
__isRoutingAnchorStillInDom: function __isRoutingAnchorStillInDom() {
return this.__$container.closest('body').length > 0;
},
/**
* Adds the routing object to the routerService and starts the routing.
*
* @param routing
* @param $initialPath
* @private
*/
__createRouting: function __createRouting(routing, $initialPath) {
for (var i in routing) {
if (routing.hasOwnProperty(i)) {
this.$services.router.addRoute(i, routing[i]);
}
}
/**
* Reselect the routing anchor, if it has been replaced.
*
* @private
*/
__reselectAnchor: function __reselectAnchor() {
this.__$container = $(this.__$container.selector);
},
this.$services.router.start($initialPath);
},
/**
* Show the new view.
*
* @param $dom {Array} - {optional} The dom of the view
* @private
*/
__onShowView: function __onShowView($dom) {
if (!this.__isRoutingAnchorStillInDom()) {
this.__reselectAnchor();
}
/**
* This function checks if the cached routing anchor is still in the DOM or has been removed or replaced during
* the lifetime of the application.
*
* @returns {boolean}
* @private
*/
__isRoutingAnchorStillInDom: function __isRoutingAnchorStillInDom() {
return this.__$container.closest('body').length > 0;
},
this.__$container.append($dom);
/**
* Reselect the routing anchor, if it has been replaced.
*
* @private
*/
__reselectAnchor: function __reselectAnchor() {
this.__$container = $(this.__$container.selector);
},
window.scrollTo(0, 0);
},
/**
* Show the new view.
*
* @param $dom {Array} - {optional} The dom of the view
* @private
*/
__onShowView: function __onShowView($dom) {
if (!this.__isRoutingAnchorStillInDom()) {
this.__reselectAnchor();
}
/**
* Hide the old view.
*
* @private
*/
__onHideView: function __onHideView() {
if (!this.__isRoutingAnchorStillInDom()) {
this.__reselectAnchor();
}
},
this.__$container.append($dom);
window.scrollTo(0, 0);
},
/**
* Hide the old view.
*
* @private
*/
__onHideView: function __onHideView() {
if (!this.__isRoutingAnchorStillInDom()) {
this.__reselectAnchor();
}
},
/**
* Function: getId
* returns unique id of this ServiceProvider
*
* @returns {String}
*/
getId: function getId() {
return this.__id;
}
/**
* Function: getId
* returns unique id of this ServiceProvider
*
* @returns {String}
*/
getId: function getId() {
return this.__id;
}
});

@@ -21,557 +21,571 @@ "use strict";

*/
'use strict';
Coco.RouterService = dejavu.Class.declare({
$name: 'RouterService',
$name: 'RouterService',
$extends: Coco.Service,
$serviceId: 'router',
$extends: Coco.Service,
/**
* Holds the routing object, that defines routes and their corresponding views that should be shown.
*/
__routes: {},
$serviceId: 'router',
/**
* Holds the current route plus it's current mapped arguments.
*/
__currentRoute: null,
/**
* Holds the routing object, that defines routes and their corresponding views that should be shown.
*/
__routes: {},
/**
* If the hashchange event has been triggered, a next route will be determined that is stored here and copied to
* __currentRoute after the views have been switched.
*/
__nextRoute: null,
/**
* Holds the current route plus it's current mapped arguments.
*/
__currentRoute: null,
/**
* The path history to refer to for back and forth manipulation.
*/
__pathHistory: [],
/**
* If the hashchange event has been triggered, a next route will be determined that is stored here and copied to
* __currentRoute after the views have been switched.
*/
__nextRoute: null,
/**
* The current path history index.
*/
__pathHistoryIndex: -1,
/**
* The path history to refer to for back and forth manipulation.
*/
__pathHistory: [],
/**
* Function: _onServicesInjected
*
* Description:
* override callback, after service initialization was completed
*
* Event:
* triggers <Coco.RouterEvent>(Coco.RouterEvent.HIDE_VIEW, ...) when current views is hidden
* triggers <Coco.RouterEvent>(Coco.RouterEvent.CHANGE_ROUTE, ...) when route is changing
*/
_onServicesInjected: function _onServicesInjected() {
var _this = this;
$(window).on('hashchange', function (event) {
_this.__onRouteChanged(event);
});
/**
* The current path history index.
*/
__pathHistoryIndex: -1,
/**
* Function: _onServicesInjected
* The syntax in the helper is e.g. "id:id, linkOne:someKeyInTheModel"
* We split the string to a array of these key1:key2 pairs.
*
* Description:
* override callback, after service initialization was completed
*
* Event:
* triggers <Coco.RouterEvent>(Coco.RouterEvent.HIDE_VIEW, ...) when current views is hidden
* triggers <Coco.RouterEvent>(Coco.RouterEvent.CHANGE_ROUTE, ...) when route is changing
* In the for loop we then split the key1:key2 and add key1 as key to the parsedParams object and the value of
* key2 as the key1 value.
*/
_onServicesInjected: function _onServicesInjected() {
var _this = this;
$(window).on('hashchange', function (event) {
_this.__onRouteChanged(event);
});
Handlebars.registerHelper('route', function (v1, v2) {
var params = [];
/**
* The syntax in the helper is e.g. "id:id, linkOne:someKeyInTheModel"
* We split the string to a array of these key1:key2 pairs.
*
* In the for loop we then split the key1:key2 and add key1 as key to the parsedParams object and the value of
* key2 as the key1 value.
*/
Handlebars.registerHelper('route', function (v1, v2) {
var params = [];
if (typeof v2 == 'string') {
params = v2.replace(/\s+/g, '').split(',');
}
if (typeof v2 == 'string') {
params = v2.replace(/\s+/g, '').split(',');
}
var parsedParams = {};
var key;
var parsedParams = {};
var key;
for (var i = 0; i < params.length; i++) {
if (params[i].indexOf(':') === -1) {
if (_this.hasOwnProperty(params[i])) {
parsedParams[params[i]] = _this[params[i]];
} else {
throw new Error('Error while generating route "' + v1 + '". Model has no key "' + params[i] + '".');
}
} else {
key = params[i].substring(params[i].indexOf(':') + 1);
for (var i = 0; i < params.length; i++) {
if (params[i].indexOf(':') === -1) {
if (_this.hasOwnProperty(params[i])) {
parsedParams[params[i]] = _this[params[i]];
} else {
throw new Error('Error while generating route "' + v1 + '". Model has no key "' + params[i] + '".');
}
} else {
key = params[i].substring(params[i].indexOf(':') + 1);
if (_this.hasOwnProperty(key)) {
parsedParams[params[i].substr(0, params[i].indexOf(':'))] = _this[key];
} else {
parsedParams[params[i].substr(0, params[i].indexOf(':'))] = key;
}
}
}
if (_this.hasOwnProperty(key)) {
parsedParams[params[i].substr(0, params[i].indexOf(':'))] = _this[key];
} else {
parsedParams[params[i].substr(0, params[i].indexOf(':'))] = key;
}
}
}
return _this.generateUrl(v1, parsedParams);
});
return _this.generateUrl(v1, parsedParams);
});
Handlebars.registerHelper('routeParam', function (key, value) {
return key + ":" + value;
});
},
setContainer: function setContainer($container) {
this.$container = $container;
},
Handlebars.registerHelper('routeParam', function (key, value) {
return key + ":" + value;
});
},
/**
* Function: start($path)
* Start the Routing.
*
* Parameter:
* @param {string} $path - {optional} If a path is given, the routing starts with this path.
*/
start: function start($path) {
if ($path == null) {
$path = '/';
} //only accept valid deeplinks!
setContainer: function setContainer($container) {
this.$container = $container;
},
/**
* Function: start($path)
* Start the Routing.
*
* Parameter:
* @param {string} $path - {optional} If a path is given, the routing starts with this path.
*/
start: function start($path) {
if ($path == null) {
$path = '/';
}
//only accept valid deeplinks!
if (window.location.hash.length > 0 && this.__matchRoute(window.location.hash)) {
$(window).trigger('hashchange');
} else {
window.location.hash = $path;
}
},
if (window.location.hash.length > 0 && this.__matchRoute(window.location.hash)) {
$(window).trigger('hashchange');
} else {
window.location.hash = $path;
}
},
/**
* Function: addRoute(name, params)
* Add a route.
*
* @param name {string} - The name of the route.
* @param params {object} - The params of the route (view object or constructor and path)
*/
addRoute: function addRoute(name, params) {
if (this.__routes.hasOwnProperty(name)) {
throw new Error('Route "' + name + '" is already defined.');
}
/**
* Function: addRoute(name, params)
* Add a route.
*
* @param name {string} - The name of the route.
* @param params {object} - The params of the route (view object or constructor and path)
*/
addRoute: function addRoute(name, params) {
if (this.__routes.hasOwnProperty(name)) {
throw new Error('Route "' + name + '" is already defined.');
}
this.__routes[name] = params;
},
this.__routes[name] = params;
},
/**
* Function: generateUrl(route, $params)
* Generate a url by a route name and optional arguments to fill the placeholders.
*
* Parameter:
* @param {string} route - The route name
* @param {object} $params - {optional} A object of parameters for the given route
*/
generateUrl: function generateUrl(route, $params) {
if (!this.__routes.hasOwnProperty(route)) {
throw new Error('Route "' + route + '" does not exist.');
}
/**
* Function: generateUrl(route, $params)
* Generate a url by a route name and optional arguments to fill the placeholders.
*
* Parameter:
* @param {string} route - The route name
* @param {object} $params - {optional} A object of parameters for the given route
*/
generateUrl: function generateUrl(route, $params) {
if (!this.__routes.hasOwnProperty(route)) {
throw new Error('Route "' + route + '" does not exist.');
}
if ($params) {
var parts = this.__routes[route].path.slice(1).replace(/[()]/g, '').split('/');
if ($params) {
var parts = this.__routes[route].path.slice(1).replace(/[()]/g, '').split('/');
for (var i = 0; i < parts.length; i++) {
if (parts[i].indexOf(':') === 0) {
if ($params.hasOwnProperty(parts[i].substr(1))) {
parts[i] = $params[parts[i].substr(1)];
} else {
parts.splice(i, 1);
i--;
}
}
}
parts.unshift('');
return '#' + parts.join('/');
for (var i = 0; i < parts.length; i++) {
if (parts[i].indexOf(':') === 0) {
if ($params.hasOwnProperty(parts[i].substr(1))) {
parts[i] = $params[parts[i].substr(1)];
} else {
parts.splice(i, 1);
i--;
}
}
}
return this.__routes[route].path.replace(/\(.*\)/g, '');
},
parts.unshift('');
return '#' + parts.join('/');
}
/**
* Function: getCurrentRoute()
* Returns the current route object.
*
* Return:
* @return {object} - The current route object.
*/
getCurrentRoute: function getCurrentRoute() {
return this.__currentRoute;
},
return this.__routes[route].path.replace(/\(.*\)/g, '');
},
/**
* Function: setPath(path)
* Set the new path programmatically.
*
* Parameter:
* @param path {string} - The path the application should be set to.
*/
setPath: function setPath(path) {
window.location.hash = path;
},
/**
* Function: getCurrentRoute()
* Returns the current route object.
*
* Return:
* @return {object} - The current route object.
*/
getCurrentRoute: function getCurrentRoute() {
return this.__currentRoute;
},
/**
* Function: callPath(path)
* Set the new path programmatically.
*
* Parameter:
* @param route {string} - The route the application should be set to.
* @param $params {object} - An object containing the parameters.
*/
callRoute: function callRoute(route, $params) {
window.location.hash = this.generateUrl(route, $params);
},
/**
* Function: setPath(path)
* Set the new path programmatically.
*
* Parameter:
* @param path {string} - The path the application should be set to.
*/
setPath: function setPath(path) {
window.location.hash = path;
},
/**
* Function: hasRoute(route)
* Returns true if the route exists.
*
* @param route {string} - The route name
* @returns {boolean}
*/
hasRoute: function hasRoute(route) {
return this.__routes.hasOwnProperty(route);
},
/**
* Function: callPath(path)
* Set the new path programmatically.
*
* Parameter:
* @param route {string} - The route the application should be set to.
* @param $params {object} - An object containing the parameters.
*/
callRoute: function callRoute(route, $params) {
window.location.hash = this.generateUrl(route, $params);
},
/**
* Function history
* returns array with historical path objects, without current path
*
* @params {Integer} steps - steps needed for history, -1 for whole history
* @returns {Array}
*/
history: function history(steps, duplicates) {
var history = [];
if (steps == -1) {
steps = this.__pathHistory.length - 1;
}
steps = Math.min(this.__pathHistory.length - 1, steps);
var routes = [];
var counter = 1;
for (var i = this.__pathHistory.length - 1; i >= this.__pathHistory.length - 1 - steps; i--) {
var pHistory = this.__pathHistory[i];
if (!duplicates) {
if (routes.indexOf(pHistory) > -1) {
//no duplicates allowed
continue;
}
}
routes.push(pHistory);
//send steps back to reach this route
var route = $.extend(true, { back: counter }, this.__getRoute(pHistory));
counter++;
history.unshift(route);
};
/**
* Function: hasRoute(route)
* Returns true if the route exists.
*
* @param route {string} - The route name
* @returns {boolean}
*/
hasRoute: function hasRoute(route) {
return this.__routes.hasOwnProperty(route);
},
return history;
},
/**
* Function history
* returns array with historical path objects, without current path
*
* @params {Integer} steps - steps needed for history, -1 for whole history
* @returns {Array}
*/
history: function history(steps, duplicates) {
var history = [];
clearHistory: function clearHistory() {
this.__pathHistory = [];
this.__pathHistoryIndex = -1;
},
if (steps == -1) {
steps = this.__pathHistory.length - 1;
}
/**
* Function: goback()
* Go back given steps in history, delete
*/
goback: function goback(steps) {
if (steps > 0 && steps < this.__pathHistory.length) {
//drop current route
var newPath = this.__pathHistory.pop();
//drop previous routes
while (steps > 0) {
newPath = this.__pathHistory.pop();
steps--;
}
this.__pathHistoryIndex = this.__pathHistory.length - 1;
this.setPath(newPath);
}
},
steps = Math.min(this.__pathHistory.length - 1, steps);
var routes = [];
var counter = 1;
/**
* Function: back()
* Go back one step in history.
*/
back: function back() {
if (this.__pathHistoryIndex > 0 && this.__pathHistoryIndex <= this.__pathHistory.length) {
this.setPath(this.__pathHistory[--this.__pathHistoryIndex]);
}
},
for (var i = this.__pathHistory.length - 1; i >= this.__pathHistory.length - 1 - steps; i--) {
var pHistory = this.__pathHistory[i];
/**
* Function: forward()
* Go one step forward in history.
*/
forward: function forward() {
if (this.__pathHistoryIndex - 1 < this.__pathHistory.length) {
this.setPath(this.__pathHistory[++this.__pathHistoryIndex]);
if (!duplicates) {
if (routes.indexOf(pHistory) > -1) {
//no duplicates allowed
continue;
}
},
}
/**
* Function: go(steps)
* Go a specified number of steps back or forth in history.
*
* Parameter:
* @param {Number} steps - A signed integer indicating how many steps to go. Values below zero go back, values above go forth in History.
*/
go: function go(steps) {
if (steps === 0) {
return;
}
routes.push(pHistory); //send steps back to reach this route
var i = this.__pathHistoryIndex += steps;
var route = $.extend(true, {
back: counter
}, this.__getRoute(pHistory));
counter++;
history.unshift(route);
}
if (i > 0 && i < this.__pathHistory.length) {
window.location.hash = this.__pathHistory[i];
}
},
;
return history;
},
clearHistory: function clearHistory() {
this.__pathHistory = [];
this.__pathHistoryIndex = -1;
},
/**
* Adds the current hash value of the location to the pathHistory array.
*
* @param {string} path - The path to add to the history.
* @private
*/
__pushPathToHistory: function __pushPathToHistory(path) {
this.__pathHistory.splice(++this.__pathHistoryIndex, this.__pathHistory.length - this.__pathHistoryIndex, path);
},
/**
* Function: goback()
* Go back given steps in history, delete
*/
goback: function goback(steps) {
if (steps > 0 && steps < this.__pathHistory.length) {
//drop current route
var newPath = this.__pathHistory.pop(); //drop previous routes
/**
* Callback for hashchange event. Tries to match a route.
* If a route has been found this.__fireRoute will be called.
*
* @private
*/
__onRouteChanged: function __onRouteChanged() {
if (this.__matchRoute(window.location.hash)) {
this.__fireRoute();
}
},
/**
* Tries to match a route by taken the given path and returns route object.
*
* @param {string} path - The path from the current url
* @param {boolean} duplicates - Allow duplicates?
* @return {boolean}
*
* @private
*/
__getRoute: function __getRoute(path, duplicates) {
path = path.slice(2);
var pathParts = path.split('/'),
matched;
while (steps > 0) {
newPath = this.__pathHistory.pop();
steps--;
}
var addedRoutes = [];
for (var i in this.__routes) {
if (this.__routes.hasOwnProperty(i)) {
var routeRegex = this.__convertToRegex(this.__routes[i].path.slice(1));
matched = true;
this.__pathHistoryIndex = this.__pathHistory.length - 1;
this.setPath(newPath);
}
},
if (path.match(routeRegex) === null) {
matched = false;
}
/**
* Function: back()
* Go back one step in history.
*/
back: function back() {
if (this.__pathHistoryIndex > 0 && this.__pathHistoryIndex <= this.__pathHistory.length) {
this.setPath(this.__pathHistory[--this.__pathHistoryIndex]);
}
},
if (matched) {
if (!duplicates) {
if (addedRoutes.indexOf[i] > -1) {
//no duplicates allowed
continue;
}
}
addedRoutes.push(i);
/**
* Function: forward()
* Go one step forward in history.
*/
forward: function forward() {
if (this.__pathHistoryIndex - 1 < this.__pathHistory.length) {
this.setPath(this.__pathHistory[++this.__pathHistoryIndex]);
}
},
var routeParts = this.__routes[i].path.slice(1).replace(/[()]/g, '').split('/');
/**
* Function: go(steps)
* Go a specified number of steps back or forth in history.
*
* Parameter:
* @param {Number} steps - A signed integer indicating how many steps to go. Values below zero go back, values above go forth in History.
*/
go: function go(steps) {
if (steps === 0) {
return;
}
this.__mapArguments(pathParts, routeParts, this.__routes[i]);
//copy route object, add route label
var r = $.extend(true, { key: i }, this.__routes[i]);
//replace path variables
for (var parts = 0; parts < routeParts.length; parts++) {
r.path = r.path.replace(routeParts[parts], pathParts[parts]);
}
var i = this.__pathHistoryIndex += steps;
//delete view from route
delete r.view;
return r;
}
}
}
if (i > 0 && i < this.__pathHistory.length) {
window.location.hash = this.__pathHistory[i];
}
},
return null;
},
/**
* Adds the current hash value of the location to the pathHistory array.
*
* @param {string} path - The path to add to the history.
* @private
*/
__pushPathToHistory: function __pushPathToHistory(path) {
this.__pathHistory.splice(++this.__pathHistoryIndex, this.__pathHistory.length - this.__pathHistoryIndex, path);
},
/**
* Tries to match a route by taken the given path and returns boolean flag.
*
* @param {string} path - The path from the current url
* @return {boolean}
* @private
*/
__matchRoute: function __matchRoute(path) {
path = path.slice(2);
var pathParts = path.split('/'),
matched;
/**
* Callback for hashchange event. Tries to match a route.
* If a route has been found this.__fireRoute will be called.
*
* @private
*/
__onRouteChanged: function __onRouteChanged() {
if (this.__matchRoute(window.location.hash)) {
this.__fireRoute();
}
},
for (var i in this.__routes) {
if (this.__routes.hasOwnProperty(i)) {
var routeRegex = this.__convertToRegex(this.__routes[i].path.slice(1));
matched = true;
/**
* Tries to match a route by taken the given path and returns route object.
*
* @param {string} path - The path from the current url
* @param {boolean} duplicates - Allow duplicates?
* @return {boolean}
*
* @private
*/
__getRoute: function __getRoute(path, duplicates) {
path = path.slice(2);
var pathParts = path.split('/'),
matched;
var addedRoutes = [];
if (path.match(routeRegex) === null) {
matched = false;
}
for (var i in this.__routes) {
if (this.__routes.hasOwnProperty(i)) {
var routeRegex = this.__convertToRegex(this.__routes[i].path.slice(1));
if (matched) {
var routeParts = this.__routes[i].path.slice(1).replace(/[()]/g, '').split('/');
this.__nextRoute = this.__mapArguments(pathParts, routeParts, this.__routes[i]);
this.__nextRoute.key = i;
matched = true;
return true;
}
}
if (path.match(routeRegex) === null) {
matched = false;
}
return false;
},
if (matched) {
if (!duplicates) {
if (addedRoutes.indexOf[i] > -1) {
//no duplicates allowed
continue;
}
}
__convertToRegex: function __convertToRegex(route) {
var optionalParam = /\((.*?)\)/g;
var namedParam = /(\(\?)?:\w+/g;
addedRoutes.push(i);
route = route.replace(optionalParam, '(?:$1)?').replace(namedParam, function (match, optional) {
return optional ? match : '([^/?]+)';
});
var routeParts = this.__routes[i].path.slice(1).replace(/[()]/g, '').split('/');
return new RegExp('^' + route + '(?:\\?([\\s\\S]*))?$');
},
this.__mapArguments(pathParts, routeParts, this.__routes[i]); //copy route object, add route label
/**
* Maps the arguments from the hash path to the currently matched route.
*
* @param {Array} pathParts
* @param {Array} routeParts
* @param {object} nextRoute
* @return {object}
* @private
*/
__mapArguments: function __mapArguments(pathParts, routeParts, nextRoute) {
var mode = 0;
if (nextRoute.paramsAsObject != null && nextRoute.paramsAsObject) {
mode = 1;
}
var r = $.extend(true, {
key: i
}, this.__routes[i]); //replace path variables
nextRoute.args = [];
for (var parts = 0; parts < routeParts.length; parts++) {
r.path = r.path.replace(routeParts[parts], pathParts[parts]);
} //delete view from route
if (mode === 1) {
nextRoute.args.push({});
delete r.view;
return r;
}
}
}
for (var i = 0; i < routeParts.length; i++) {
if (routeParts[i].indexOf(':') === 0) {
if (!isNaN(pathParts[i])) {
pathParts[i] = Number(pathParts[i]);
}
return null;
},
if (mode === 0) {
nextRoute.args.push(pathParts[i]);
} else {
nextRoute.args[0][routeParts[i].substring(1)] = pathParts[i];
}
}
}
/**
* Tries to match a route by taken the given path and returns boolean flag.
*
* @param {string} path - The path from the current url
* @return {boolean}
* @private
*/
__matchRoute: function __matchRoute(path) {
path = path.slice(2);
var pathParts = path.split('/'),
matched;
return nextRoute;
},
for (var i in this.__routes) {
if (this.__routes.hasOwnProperty(i)) {
var routeRegex = this.__convertToRegex(this.__routes[i].path.slice(1));
/**
* Fires a route and executes the attached callback methods of the view that will be showed and the view that will
* be hidden.
*
* @private
*/
__fireRoute: function __fireRoute() {
//do not fire route, if it is the same as previous
if (this.__nextRoute && this.__currentRoute && this.__nextRoute.key == this.__currentRoute.key && JSON.stringify(this.__nextRoute.args) == JSON.stringify(this.__currentRoute.args)) {
return false;
}
matched = true;
if (this.__currentRoute != null) {
// The onPause method of a view can return a value that is pushed to the params to the next active view.
this.__callRouteView(this.__currentRoute);
this.__callRouteMethod(this.__currentRoute, 'onPause');
if (path.match(routeRegex) === null) {
matched = false;
}
this.__callRouteView(this.__nextRoute);
if (matched) {
var routeParts = this.__routes[i].path.slice(1).replace(/[()]/g, '').split('/');
if (this.__nextRoute == null || this.__nextRoute.view == null) {
console.error("invalid route called! ", this.__nextRoute);
return;
this.__nextRoute = this.__mapArguments(pathParts, routeParts, this.__routes[i]);
this.__nextRoute.key = i;
return true;
}
}
}
if (this.__currentRoute != null) {
//this.trigger(Coco.Event.HIDE_VIEW);
//this.trigger(Coco.Event.HIDE_VIEW + this.__currentRoute.view.$name);
//dispatch event for router
this._dispatchEvent(new Coco.RouterEvent(Coco.RouterEvent.HIDE_VIEW, $.extend({}, this.__nextRoute), $.extend({}, this.__currentRoute)));
return false;
},
__convertToRegex: function __convertToRegex(route) {
var optionalParam = /\((.*?)\)/g;
var namedParam = /(\(\?)?:\w+/g;
route = route.replace(optionalParam, '(?:$1)?').replace(namedParam, function (match, optional) {
return optional ? match : '([^/?]+)';
});
return new RegExp('^' + route + '(?:\\?([\\s\\S]*))?$');
},
//dispatch event for view
this._dispatchEvent(new Coco.RouterEvent(Coco.RouterEvent.HIDE_VIEW + this.__currentRoute.view.$name, $.extend({}, this.__nextRoute), $.extend({}, this.__currentRoute)));
/**
* Maps the arguments from the hash path to the currently matched route.
*
* @param {Array} pathParts
* @param {Array} routeParts
* @param {object} nextRoute
* @return {object}
* @private
*/
__mapArguments: function __mapArguments(pathParts, routeParts, nextRoute) {
var mode = 0;
this.__currentRoute.view.deactivate();
}
if (nextRoute.paramsAsObject != null && nextRoute.paramsAsObject) {
mode = 1;
}
this.__nextRoute.view.activate();
nextRoute.args = [];
//call this AFTER deactivating current view, because current view can be also NEXT view - and so, all events are killed
this.__callRouteMethod(this.__nextRoute, 'onActive');
if (mode === 1) {
nextRoute.args.push({});
}
if (this.__currentRoute && this.__currentRoute.view.$name == this.__nextRoute.view.$name) {
// If we navigate to the same view, don't add new route to history array
// Just replace the last one with new value
this.__pathHistory[this.__pathHistory.length - 1] = window.location.hash;
for (var i = 0; i < routeParts.length; i++) {
if (routeParts[i].indexOf(':') === 0) {
if (!isNaN(pathParts[i])) {
pathParts[i] = Number(pathParts[i]);
}
if (mode === 0) {
nextRoute.args.push(pathParts[i]);
} else {
// Otherwise add new route path to history array
this.__pushPathToHistory(window.location.hash);
nextRoute.args[0][routeParts[i].substring(1)] = pathParts[i];
}
}
}
this._dispatchEvent(new Coco.RouterEvent(Coco.RouterEvent.CHANGE_ROUTE, $.extend({}, this.__nextRoute), $.extend({}, this.__currentRoute)));
return nextRoute;
},
this.__currentRoute = $.extend({}, this.__nextRoute);
/**
* Fires a route and executes the attached callback methods of the view that will be showed and the view that will
* be hidden.
*
* @private
*/
__fireRoute: function __fireRoute() {
//do not fire route, if it is the same as previous
if (this.__nextRoute && this.__currentRoute && this.__nextRoute.key == this.__currentRoute.key && JSON.stringify(this.__nextRoute.args) == JSON.stringify(this.__currentRoute.args)) {
return false;
}
this.__callRouteMethod(this.__nextRoute, 'onRenderedActive');
if (this.__currentRoute != null) {
// The onPause method of a view can return a value that is pushed to the params to the next active view.
this.__callRouteView(this.__currentRoute);
this.__nextRoute = null;
},
this.__callRouteMethod(this.__currentRoute, 'onPause');
}
/**
* Calls the onActive or onPause callback of the view.
*
* @param {object} route - The route object where the view lies in
*/
__callRouteView: function __callRouteView(route) {
if (typeof route.view === 'function') {
console.debug("callRouteView: ", route);
if (route.model && route.model instanceof Coco.Model) {
route.view = new route.view(route.model);
} else {
route.view = new route.view();
}
}
},
this.__callRouteView(this.__nextRoute);
__callRouteMethod: function __callRouteMethod(route, method) {
if (method === 'onPause') {
//deactivated views do not need any eventhandler!
route.view.undelegateEvents();
return route.view[method]();
} else if (method === 'onActive') {
//route.view.delegateEvents();
return route.view[method].apply(route.view, this.__nextRoute.args);
} else if (typeof route.view[method] === 'function') {
route.view[method].apply(route.view, this.__nextRoute.args);
}
if (this.__nextRoute == null || this.__nextRoute.view == null) {
console.error("invalid route called! ", this.__nextRoute);
return;
}
if (this.__currentRoute != null) {
//this.trigger(Coco.Event.HIDE_VIEW);
//this.trigger(Coco.Event.HIDE_VIEW + this.__currentRoute.view.$name);
//dispatch event for router
this._dispatchEvent(new Coco.RouterEvent(Coco.RouterEvent.HIDE_VIEW, $.extend({}, this.__nextRoute), $.extend({}, this.__currentRoute))); //dispatch event for view
this._dispatchEvent(new Coco.RouterEvent(Coco.RouterEvent.HIDE_VIEW + this.__currentRoute.view.$name, $.extend({}, this.__nextRoute), $.extend({}, this.__currentRoute)));
this.__currentRoute.view.deactivate();
}
this.__nextRoute.view.activate(); //call this AFTER deactivating current view, because current view can be also NEXT view - and so, all events are killed
this.__callRouteMethod(this.__nextRoute, 'onActive');
if (this.__currentRoute && this.__currentRoute.view.$name == this.__nextRoute.view.$name) {
// If we navigate to the same view, don't add new route to history array
// Just replace the last one with new value
this.__pathHistory[this.__pathHistory.length - 1] = window.location.hash;
} else {
// Otherwise add new route path to history array
this.__pushPathToHistory(window.location.hash);
}
this._dispatchEvent(new Coco.RouterEvent(Coco.RouterEvent.CHANGE_ROUTE, $.extend({}, this.__nextRoute), $.extend({}, this.__currentRoute)));
this.__currentRoute = $.extend({}, this.__nextRoute);
this.__callRouteMethod(this.__nextRoute, 'onRenderedActive');
this.__nextRoute = null;
},
/**
* Calls the onActive or onPause callback of the view.
*
* @param {object} route - The route object where the view lies in
*/
__callRouteView: function __callRouteView(route) {
if (typeof route.view === 'function') {
console.debug("callRouteView: ", route);
if (route.model && route.model instanceof Coco.Model) {
route.view = new route.view(route.model);
} else {
route.view = new route.view();
}
}
},
__callRouteMethod: function __callRouteMethod(route, method) {
if (method === 'onPause') {
//deactivated views do not need any eventhandler!
route.view.undelegateEvents();
return route.view[method]();
} else if (method === 'onActive') {
//route.view.delegateEvents();
return route.view[method].apply(route.view, this.__nextRoute.args);
} else if (typeof route.view[method] === 'function') {
route.view[method].apply(route.view, this.__nextRoute.args);
}
}
}); //.$service();
//instantiate Service automatically
module.exports = new Coco.RouterService();
"use strict";
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
var RestServiceEvent = require("../event/Coco.RestServiceEvent.js");
var Event = require("../event/Coco.Event.js");
var JSON = require("JSON");
/**

@@ -19,417 +19,468 @@ * Class: Coco.BaseRestService

*/
module.exports = dejavu.AbstractClass.declare({
/**
* Class name.
*/
$name: "Coco.BaseRestService",
/**
* Class name.
*/
$name: "Coco.BaseRestService",
/**
* Super class: Coco.Service
*/
$extends: require("./Coco.Service.js"),
/**
* Super class: Coco.Service
*/
$extends: require("./Coco.Service.js"),
/**
* cache for GET requests
*/
_getCache: null,
/**
* cache for GET requests
*/
_getCache: null,
/**
* cache for POST requests
*/
_postCache: null,
/**
* cache for POST requests
*/
_postCache: null,
/**
* The REST service path.
*/
_restServicePath: null,
/**
* The REST service path.
*/
_restServicePath: null,
$constants: {
XHR_FIELDS: {
withCredentials: true
},
CROSSDOMAIN: true
},
$constants: {
XHR_FIELDS: {
withCredentials: true
},
CROSSDOMAIN: true
},
/**
* Ctor.
*/
initialize: function initialize() {
//call constructor for service registration
this.$super();
/**
* Ctor.
*/
initialize: function initialize() {
//call constructor for service registration
this.$super();
this._onInitialize();
},
this._onInitialize();
},
/**
* Function: _onInitialize
*
* is called after class was initialized
* @protected
*/
_onInitialize: function _onInitialize() {},
/**
* Function: _onInitialize
*
* is called after class was initialized
* @protected
*/
_onInitialize: function _onInitialize() {},
_validateParameterIsBoolean: function _validateParameterIsBoolean(param, onError) {
if (param != null && typeof param != "boolean") {
onError({
status: 99,
responseText: "Parameter is not type of Boolean"
});
return false;
}
_validateParameterIsBoolean: function _validateParameterIsBoolean(param, onError) {
if (param != null && typeof param != "boolean") {
onError({ status: 99, responseText: "Parameter is not type of Boolean" });
return false;
}
return true;
},
return true;
},
_validateParameterIsInteger: function _validateParameterIsInteger(param, onError) {
if (param != null && parseInt(param) !== param) {
onError({
status: 99,
responseText: "Parameter is not type of Integer"
});
return false;
}
_validateParameterIsInteger: function _validateParameterIsInteger(param, onError) {
if (param != null && parseInt(param) !== param) {
onError({ status: 99, responseText: "Parameter is not type of Integer" });
return false;
}
return true;
},
return true;
},
_validateParameterIsFloat: function _validateParameterIsFloat(param, onError) {
if (param != null && typeof param !== "number") {
onError({
status: 99,
responseText: "Parameter is not type of Number"
});
return false;
}
_validateParameterIsFloat: function _validateParameterIsFloat(param, onError) {
if (param != null && typeof param !== "number") {
onError({ status: 99, responseText: "Parameter is not type of Number" });
return false;
}
return true;
},
_validateParameterIsArray: function _validateParameterIsArray(param, onError) {
if (param != null && !Array.isArray(param)) {
onError({ status: 99, responseText: "Parameter is not type of Array" });
return false;
}
return true;
},
return true;
},
_validateParameterIsArray: function _validateParameterIsArray(param, onError) {
if (param != null && !Array.isArray(param)) {
onError({
status: 99,
responseText: "Parameter is not type of Array"
});
return false;
}
_validateParameterClass: function _validateParameterClass(param, paramType, onError) {
if (param != null && !(param instanceof paramType)) {
onError({ status: 99, responseText: "Parameter is not type of " + (typeof paramType === "undefined" ? "undefined" : _typeof(paramType)) });
return false;
}
return true;
},
return true;
},
_validateParameterClass: function _validateParameterClass(param, paramType, onError) {
if (param != null && !(param instanceof paramType)) {
onError({
status: 99,
responseText: "Parameter is not type of " + _typeof(paramType)
});
return false;
}
/**
* Function: _buildEndpointURL
*
* Builds the full endpoint URL absolute to the host. The URL looks like:
* [CONTEXT-PATH]/[REST-PATH]/[ENDPOINT]
*
* Parameter:
*
* @param {string} endpoint the REST endpoint
*/
_buildEndpointURL: function _buildEndpointURL(endpoint, pathParameter) {
var Coco = require("../Coco.Init.js");
if (this._restServicePath == null) {
throw new Error(this.$serviceId + "._restServicePath not set!");
}
if (Coco.config.baseUrl == null) {
throw new Error("Coco.config.baseUrl not set! ", Coco.config);
}
if (!Coco.config.restService || Coco.config.restService.path == null) {
throw new Error("Coco.config.restService.path not set! ", Coco.config);
}
if (endpoint == null) {
endpoint = "";
}
var finalUrl = Coco.config.baseUrl + Coco.config.restService.path + this._restServicePath + endpoint;
if (pathParameter && pathParameter.length > 0) {
finalUrl = this._replacePathParameters(finalUrl, pathParameter);
}
return finalUrl;
},
return true;
},
_replacePathParameters: function _replacePathParameters(path, pathParameter) {
do {
var paramStart = path.indexOf("{");
if (paramStart < 0) {
break;
}
var paramEnd = paramStart;
var depth = 1;
do {
paramEnd++;
var c = path.substring(paramEnd, paramEnd + 1);
if (c === "{") {
depth++;
} else if (c === "}") {
depth--;
}
} while (depth > 0 && paramEnd + 1 < path.length);
paramEnd++;
if (paramEnd > path.length) {
break;
}
var pathDefinition = path.substring(paramStart, paramEnd);
var paramName = pathDefinition.substring(1, pathDefinition.length - 1);
if (paramName.indexOf(":") > 0) {
paramName = paramName.substring(0, paramName.indexOf(":"));
}
var value = null;
for (var i = 0; i < pathParameter.length; i++) {
if (pathParameter[i].name === paramName) {
value = pathParameter[i].replacement;
break;
}
}
if (value == null) {
console.error("missing path parameter: " + paramName + " not set... ", pathParameter);
}
//replace position
path = path.substring(0, paramStart) + value + path.substring(paramEnd);
} while (true);
/**
* Function: _buildEndpointURL
*
* Builds the full endpoint URL absolute to the host. The URL looks like:
* [CONTEXT-PATH]/[REST-PATH]/[ENDPOINT]
*
* Parameter:
*
* @param {string} endpoint the REST endpoint
*/
_buildEndpointURL: function _buildEndpointURL(endpoint, pathParameter) {
var Coco = require("../Coco.Init.js");
return path;
},
if (this._restServicePath == null) {
throw new Error(this.$serviceId + "._restServicePath not set!");
}
/**
* Function: __call {private}
*
* Calls the given endpoint via jQuery ajax function using the given method, data and callbacks.
*
* Parameter:
* @param {string} endpoint the REST endpoint
*
* @param {string} method the request method ('GET', 'POST', 'PUT' or 'DELETE')
*
* @param {object} data the request data
*
* @param {object} xhrFields
*
* @param {function} callbackSuccess the success handler
*
* @param {function} callbackError the error handler
*/
__call: function __call(endpoint, pathParameter, method, data, xhrFields, callbackSuccess, callbackError, $contentType) {
var _this = this;
if (Coco.config.baseUrl == null) {
throw new Error("Coco.config.baseUrl not set! ", Coco.config);
}
var url = this._buildEndpointURL(endpoint, pathParameter);
var Coco = require("../Coco.Init.js");
if (!Coco.config.restService || Coco.config.restService.path == null) {
throw new Error("Coco.config.restService.path not set! ", Coco.config);
}
var cacheKey = url;
if ($contentType) {
cacheKey = cacheKey + $contentType;
}
if (endpoint == null) {
endpoint = "";
}
if (method == "GET") {
if (this._getCache == null) {
this._getCache = new Map();
}
var finalUrl = Coco.config.baseUrl + Coco.config.restService.path + this._restServicePath + endpoint;
var cacheData = this._getCache.get(cacheKey);
if (cacheData != null) {
//cached entry found
if (cacheData.cocoTimeout == null || cacheData.cocoTimeout > new Date().getTime()) {
//parse stringed cached response
var cacheDataResponse = JSON.parse(cacheData.response);
if (callbackSuccess) {
callbackSuccess(cacheDataResponse);
}
return Promise.resolve(cacheDataResponse);
}
//cache timed out, delete it
this._getCache.delete(cacheKey);
}
}
if (pathParameter && pathParameter.length > 0) {
finalUrl = this._replacePathParameters(finalUrl, pathParameter);
}
//delete empty keys from data object
Object.keys(data).forEach(function (k) {
if (typeof data[k] != 'boolean' && typeof data[k] != 'number' && !data[k]) {
delete data[k];
}
});
return finalUrl;
},
_replacePathParameters: function _replacePathParameters(path, pathParameter) {
do {
var paramStart = path.indexOf("{");
//console.debug("Calling REST service (method: '" + method + "', URL: " + url + ") with data: ", data);
return $.ajax({
url: url,
type: method,
xhrFields: xhrFields,
contentType: $contentType || false,
crossDomain: this.$self.CROSSDOMAIN, //enable crossdomain calls - implement serverside!
data: data,
dataType: 'json', //dont use jsonp for RESTservices, only GET requests allowed with jsonp
processData: window.FormData && data instanceof FormData ? false : true,
success: function success(response) {
if (method == "GET") {
if (Coco.config.restService.cacheGet < 0) {
//unlimited caching
_this._getCache.set(cacheKey, { response: JSON.stringify(response) });
} else {
if (Coco.config.restService.cacheGet > 0) {
var timeout = new Date(new Date().getTime() + 1000 * Coco.config.restService.cacheGet);
if (paramStart < 0) {
break;
}
// todo when array - don't make object from array
_this._getCache.set(cacheKey, { cocoTimeout: timeout, response: JSON.stringify(response) });
} else {
//cache disabled
}
}
}
var paramEnd = paramStart;
var depth = 1;
callbackSuccess(response);
},
error: function error(_error) {
if (_error != null && _error.status == 401) {
//Authorization failed - throw Event
//this.trigger(Coco.Event.AUTHORIZATION_FAILED);
_this._dispatchEvent(new RestServiceEvent(Event.AUTHORIZATION_FAILED, _error.status, _error));
} else if (_error != null && _error.status == 500) {
//Authorization failed - throw Event
//this.trigger(Coco.Event.INTERNAL_SERVER_ERROR, error);
_this._dispatchEvent(new RestServiceEvent(Event.INTERNAL_SERVER_ERROR, _error.status, _error));
} else {
_this._dispatchEvent(new RestServiceEvent(Event.REST_SERVER_ERROR, _error.status, _error));
}
do {
paramEnd++;
var c = path.substring(paramEnd, paramEnd + 1);
if (callbackError != null) {
callbackError(_error);
}
}
});
},
if (c === "{") {
depth++;
} else if (c === "}") {
depth--;
}
} while (depth > 0 && paramEnd + 1 < path.length);
/**
* Function: _get
*
* Delegates to _call using 'GET' method.
*
* Parameter:
* @param {string} endpoint the REST endpoint
*
* @param {array} pathParameter Array
*
* @param {object} data the request data
*
* @param {object} xhrFields
*
* @param {function} callbackSuccess the success handler
*
* @param {function} callbackError the error handler
*/
_get: function _get(endpoint, pathParameter, data, xhrFields, callbackSuccess, callbackError) {
if (!Array.isArray(pathParameter)) {
throw new Error("2nd parameter has to be pathParameter array, but was: " + (typeof pathParameter === "undefined" ? "undefined" : _typeof(pathParameter)));
}
return this.__call(endpoint, pathParameter, 'GET', data, xhrFields, callbackSuccess, callbackError, false);
},
paramEnd++;
/**
* Function: _post
*
* Delegates to _call using 'POST' method.
*
* Parameter:
* @param {string} endpoint the REST endpoint
*
* @param {object} data the request data
*
* @param {object} xhrFields
*
* @param {function} callbackSuccess the success handler
*
* @param {function} callbackError the error handler
*
* @param {string} contentType
*/
_post: function _post(endpoint, pathParameter, data, xhrFields, callbackSuccess, callbackError, contentType) {
if (!Array.isArray(pathParameter)) {
throw new Error("2nd parameter has to be pathParameter array, but was: " + (typeof pathParameter === "undefined" ? "undefined" : _typeof(pathParameter)));
}
return this.__call(endpoint, pathParameter, 'POST', data, xhrFields, callbackSuccess, callbackError, contentType);
},
if (paramEnd > path.length) {
break;
}
/**
* Function: _postJson
*
* Delegates to _call using 'POST' method, contentType 'application/json' and
* stringifys the data object.
* Use this method if you consume a (complexly JSON) mapped object on server-side.
*
* Parameter:
* @param {string} endpoint the REST endpoint
*
* @param {object} data the request data
*
* @param {object} xhrFields
*
* @param {function} callbackSuccess the success handler
*
* @param {function} callbackError the error handler
*/
_postJson: function _postJson(endpoint, pathParameter, data, xhrFields, callbackSuccess, callbackError) {
if (!Array.isArray(pathParameter)) {
throw new Error("2nd parameter has to be pathParameter array, but was: " + (typeof pathParameter === "undefined" ? "undefined" : _typeof(pathParameter)));
}
return this.__call(endpoint, pathParameter, 'POST', JSON.stringify(data), xhrFields, callbackSuccess, callbackError, 'application/json');
},
var pathDefinition = path.substring(paramStart, paramEnd);
var paramName = pathDefinition.substring(1, pathDefinition.length - 1);
/**
* Function: _put
*
* Delegates to _call using 'PUT' method.
*
* Parameter:
* @param {string} endpoint the REST endpoint
*
* @param {object} data the request data
*
* @param {object} xhrFields
*
* @param {function} callbackSuccess the success handler
*
* @param {function} callbackError the error handler
*
* @param {string} contentType
*/
_put: function _put(endpoint, pathParameter, data, xhrFields, callbackSuccess, callbackError, contentType) {
if (!Array.isArray(pathParameter)) {
throw new Error("2nd parameter has to be pathParameter array, but was: " + (typeof pathParameter === "undefined" ? "undefined" : _typeof(pathParameter)));
}
return this.__call(endpoint, pathParameter, 'PUT', data, xhrFields, callbackSuccess, callbackError, contentType);
},
if (paramName.indexOf(":") > 0) {
paramName = paramName.substring(0, paramName.indexOf(":"));
}
/**
* Function: _putJson
*
* Delegates to _call using 'PUT' method.
*
* Parameter:
* @param {string} endpoint the REST endpoint
*
* @param {object} data the request data
*
* @param {object} xhrFields
*
* @param {function} callbackSuccess the success handler
*
* @param {function} callbackError the error handler
*/
_putJson: function _putJson(endpoint, pathParameter, data, xhrFields, callbackSuccess, callbackError) {
if (!Array.isArray(pathParameter)) {
throw new Error("2nd parameter has to be pathParameter array, but was: " + (typeof pathParameter === "undefined" ? "undefined" : _typeof(pathParameter)));
}
return this.__call(endpoint, pathParameter, 'PUT', JSON.stringify(data), xhrFields, callbackSuccess, callbackError, 'application/json');
},
var value = null;
/**
* Function: _delete
*
* Delegates to _call using 'DELETE' method.
*
* Parameter:
* @param {string} endpoint the REST endpoint
*
* @param {object} data the request data
*
* @param {object} xhrFields
*
* @param {function} callbackSuccess the success handler
*
* @param {function} callbackError the error handler
*/
_delete: function _delete(endpoint, pathParameter, data, xhrFields, callbackSuccess, callbackError, contentType) {
if (!Array.isArray(pathParameter)) {
throw new Error("2nd parameter has to be pathParameter array, but was: " + (typeof pathParameter === "undefined" ? "undefined" : _typeof(pathParameter)));
}
return this.__call(endpoint, pathParameter, 'DELETE', data, xhrFields, callbackSuccess, callbackError, contentType);
}
for (var i = 0; i < pathParameter.length; i++) {
if (pathParameter[i].name === paramName) {
value = pathParameter[i].replacement;
break;
}
}
if (value == null) {
console.error("missing path parameter: " + paramName + " not set... ", pathParameter);
} //replace position
path = path.substring(0, paramStart) + value + path.substring(paramEnd);
} while (true);
return path;
},
/**
* Function: __call {private}
*
* Calls the given endpoint via jQuery ajax function using the given method, data and callbacks.
*
* Parameter:
* @param {string} endpoint the REST endpoint
*
* @param {string} method the request method ('GET', 'POST', 'PUT' or 'DELETE')
*
* @param {object} data the request data
*
* @param {object} xhrFields
*
* @param {function} callbackSuccess the success handler
*
* @param {function} callbackError the error handler
*/
__call: function __call(endpoint, pathParameter, method, data, xhrFields, callbackSuccess, callbackError, $contentType) {
var _this = this;
var url = this._buildEndpointURL(endpoint, pathParameter);
var Coco = require("../Coco.Init.js");
var cacheKey = url;
if ($contentType) {
cacheKey = cacheKey + $contentType;
}
if (method == "GET") {
if (this._getCache == null) {
this._getCache = new Map();
}
var cacheData = this._getCache.get(cacheKey);
if (cacheData != null) {
//cached entry found
if (cacheData.cocoTimeout == null || cacheData.cocoTimeout > new Date().getTime()) {
//parse stringed cached response
var cacheDataResponse = JSON.parse(cacheData.response);
if (callbackSuccess) {
callbackSuccess(cacheDataResponse);
}
return Promise.resolve(cacheDataResponse);
} //cache timed out, delete it
this._getCache.delete(cacheKey);
}
} //delete empty keys from data object
Object.keys(data).forEach(function (k) {
if (typeof data[k] != 'boolean' && typeof data[k] != 'number' && !data[k]) {
delete data[k];
}
}); //console.debug("Calling REST service (method: '" + method + "', URL: " + url + ") with data: ", data);
return $.ajax({
url: url,
type: method,
xhrFields: xhrFields,
contentType: $contentType || false,
crossDomain: this.$self.CROSSDOMAIN,
//enable crossdomain calls - implement serverside!
data: data,
dataType: 'json',
//dont use jsonp for RESTservices, only GET requests allowed with jsonp
processData: window.FormData && data instanceof FormData ? false : true,
success: function success(response) {
if (method == "GET") {
if (Coco.config.restService.cacheGet < 0) {
//unlimited caching
_this._getCache.set(cacheKey, {
response: JSON.stringify(response)
});
} else {
if (Coco.config.restService.cacheGet > 0) {
var timeout = new Date(new Date().getTime() + 1000 * Coco.config.restService.cacheGet); // todo when array - don't make object from array
_this._getCache.set(cacheKey, {
cocoTimeout: timeout,
response: JSON.stringify(response)
});
} else {//cache disabled
}
}
}
callbackSuccess(response);
},
error: function error(_error) {
if (_error != null && _error.status == 401) {
//Authorization failed - throw Event
//this.trigger(Coco.Event.AUTHORIZATION_FAILED);
_this._dispatchEvent(new RestServiceEvent(Event.AUTHORIZATION_FAILED, _error.status, _error));
} else if (_error != null && _error.status == 500) {
//Authorization failed - throw Event
//this.trigger(Coco.Event.INTERNAL_SERVER_ERROR, error);
_this._dispatchEvent(new RestServiceEvent(Event.INTERNAL_SERVER_ERROR, _error.status, _error));
} else {
_this._dispatchEvent(new RestServiceEvent(Event.REST_SERVER_ERROR, _error.status, _error));
}
if (callbackError != null) {
callbackError(_error);
}
}
});
},
/**
* Function: _get
*
* Delegates to _call using 'GET' method.
*
* Parameter:
* @param {string} endpoint the REST endpoint
*
* @param {array} pathParameter Array
*
* @param {object} data the request data
*
* @param {object} xhrFields
*
* @param {function} callbackSuccess the success handler
*
* @param {function} callbackError the error handler
*/
_get: function _get(endpoint, pathParameter, data, xhrFields, callbackSuccess, callbackError) {
if (!Array.isArray(pathParameter)) {
throw new Error("2nd parameter has to be pathParameter array, but was: " + _typeof(pathParameter));
}
return this.__call(endpoint, pathParameter, 'GET', data, xhrFields, callbackSuccess, callbackError, false);
},
/**
* Function: _post
*
* Delegates to _call using 'POST' method.
*
* Parameter:
* @param {string} endpoint the REST endpoint
*
* @param {object} data the request data
*
* @param {object} xhrFields
*
* @param {function} callbackSuccess the success handler
*
* @param {function} callbackError the error handler
*
* @param {string} contentType
*/
_post: function _post(endpoint, pathParameter, data, xhrFields, callbackSuccess, callbackError, contentType) {
if (!Array.isArray(pathParameter)) {
throw new Error("2nd parameter has to be pathParameter array, but was: " + _typeof(pathParameter));
}
return this.__call(endpoint, pathParameter, 'POST', data, xhrFields, callbackSuccess, callbackError, contentType);
},
/**
* Function: _postJson
*
* Delegates to _call using 'POST' method, contentType 'application/json' and
* stringifys the data object.
* Use this method if you consume a (complexly JSON) mapped object on server-side.
*
* Parameter:
* @param {string} endpoint the REST endpoint
*
* @param {object} data the request data
*
* @param {object} xhrFields
*
* @param {function} callbackSuccess the success handler
*
* @param {function} callbackError the error handler
*/
_postJson: function _postJson(endpoint, pathParameter, data, xhrFields, callbackSuccess, callbackError) {
if (!Array.isArray(pathParameter)) {
throw new Error("2nd parameter has to be pathParameter array, but was: " + _typeof(pathParameter));
}
return this.__call(endpoint, pathParameter, 'POST', JSON.stringify(data), xhrFields, callbackSuccess, callbackError, 'application/json');
},
/**
* Function: _put
*
* Delegates to _call using 'PUT' method.
*
* Parameter:
* @param {string} endpoint the REST endpoint
*
* @param {object} data the request data
*
* @param {object} xhrFields
*
* @param {function} callbackSuccess the success handler
*
* @param {function} callbackError the error handler
*
* @param {string} contentType
*/
_put: function _put(endpoint, pathParameter, data, xhrFields, callbackSuccess, callbackError, contentType) {
if (!Array.isArray(pathParameter)) {
throw new Error("2nd parameter has to be pathParameter array, but was: " + _typeof(pathParameter));
}
return this.__call(endpoint, pathParameter, 'PUT', data, xhrFields, callbackSuccess, callbackError, contentType);
},
/**
* Function: _putJson
*
* Delegates to _call using 'PUT' method.
*
* Parameter:
* @param {string} endpoint the REST endpoint
*
* @param {object} data the request data
*
* @param {object} xhrFields
*
* @param {function} callbackSuccess the success handler
*
* @param {function} callbackError the error handler
*/
_putJson: function _putJson(endpoint, pathParameter, data, xhrFields, callbackSuccess, callbackError) {
if (!Array.isArray(pathParameter)) {
throw new Error("2nd parameter has to be pathParameter array, but was: " + _typeof(pathParameter));
}
return this.__call(endpoint, pathParameter, 'PUT', JSON.stringify(data), xhrFields, callbackSuccess, callbackError, 'application/json');
},
/**
* Function: _delete
*
* Delegates to _call using 'DELETE' method.
*
* Parameter:
* @param {string} endpoint the REST endpoint
*
* @param {object} data the request data
*
* @param {object} xhrFields
*
* @param {function} callbackSuccess the success handler
*
* @param {function} callbackError the error handler
*/
_delete: function _delete(endpoint, pathParameter, data, xhrFields, callbackSuccess, callbackError, contentType) {
if (!Array.isArray(pathParameter)) {
throw new Error("2nd parameter has to be pathParameter array, but was: " + _typeof(pathParameter));
}
return this.__call(endpoint, pathParameter, 'DELETE', data, xhrFields, callbackSuccess, callbackError, contentType);
}
});

@@ -8,3 +8,2 @@ "use strict";

Coco.StringUtils = Coco.StringUtils || require("../lib/Coco.StringUtils.js");
/**

@@ -21,5 +20,5 @@ * Class: Coco.Service

*/
module.exports = dejavu.AbstractClass.declare({
$name: 'Service',
$extends: Coco.ServiceProvider,

@@ -49,6 +48,6 @@

throw new Error(this.$name + " has no service id!");
}
//inject this service into ServiceContainer
} //inject this service into ServiceContainer
Coco.ServiceContainer.addService(this);
this.$super();

@@ -55,0 +54,0 @@ },

@@ -13,40 +13,41 @@ "use strict";

*/
module.exports = Coco.ServiceContainer = dejavu.Class.declare({
$name: 'Coco.ServiceContainer',
$extends: Coco.EventDispatcher,
$name: 'Coco.ServiceContainer',
$extends: Coco.EventDispatcher,
$statics: {
__services: {},
$statics: {
__services: {},
/**
* Function addService
*
* {static} function to add service class
*
* @param serviceInstance
*/
addService: function addService(serviceInstance) {
console.debug("register service for Coco: ", serviceInstance.$serviceId);
if (!this.$static.__services.hasOwnProperty(serviceInstance.$serviceId)) {
this.$static.__services[serviceInstance.$serviceId] = serviceInstance;
} else {
throw new Error("Service '" + serviceInstance.$serviceId + "' already defined with class '" + serviceInstance.$name + "'.");
}
}
},
/**
* Function: getService
* Function addService
*
* Return the service
* {static} function to add service class
*
* @param serviceId
* @param serviceInstance
*/
getService: function getService(serviceId) {
if (this.$static.__services.hasOwnProperty(serviceId)) {
return this.$static.__services[serviceId];
}
addService: function addService(serviceInstance) {
console.debug("register service for Coco: ", serviceInstance.$serviceId);
throw new Error("Service '" + serviceId + "' does not exist. Maybe you forgot to initialize your service at the end of the declaration of your class, or you did not require the serviceClass.js");
if (!this.$static.__services.hasOwnProperty(serviceInstance.$serviceId)) {
this.$static.__services[serviceInstance.$serviceId] = serviceInstance;
} else {
throw new Error("Service '" + serviceInstance.$serviceId + "' already defined with class '" + serviceInstance.$name + "'.");
}
}
},
/**
* Function: getService
*
* Return the service
*
* @param serviceId
*/
getService: function getService(serviceId) {
if (this.$static.__services.hasOwnProperty(serviceId)) {
return this.$static.__services[serviceId];
}
throw new Error("Service '" + serviceId + "' does not exist. Maybe you forgot to initialize your service at the end of the declaration of your class, or you did not require the serviceClass.js");
}
});

@@ -6,3 +6,2 @@ "use strict";

Coco.ServiceContainer = require("./Coco.ServiceContainer.js");
/**

@@ -18,81 +17,83 @@ * Class: Coco.ServiceProvider

*/
module.exports = dejavu.AbstractClass.declare({
$name: 'ServiceProvider',
$name: 'ServiceProvider',
$extends: Coco.EventDispatcher,
$extends: Coco.EventDispatcher,
/**
* Variable: $inject
* Array to inject other services, simply provide an array of service ids.
*/
$inject: [],
/**
* Variable: $inject
* Array to inject other services, simply provide an array of service ids.
*/
$inject: [],
/**
* Variable: $services
* The services will be filled on instantiation of the class.
* Key is the serviceId and value is the service instance.
*/
$services: {},
initialize: function initialize() {
this._injectServices();
},
/**
* Variable: $services
* The services will be filled on instantiation of the class.
* Key is the serviceId and value is the service instance.
*/
$services: {},
/**
* Function: _injectServices
*
* {protected} function is called in constructor to inject services defined in $services-Array, deletes itself after calling 1st time
*/
_injectServices: function _injectServices() {
if (this.__injectServices != null) {
this.__injectServices();
} else {
console.warn("Services already injected, do not call this._injectServices twice!");
return;
} // Protect the ServiceContainer
initialize: function initialize() {
this._injectServices();
},
/**
* Function: _injectServices
*
* {protected} function is called in constructor to inject services defined in $services-Array, deletes itself after calling 1st time
*/
_injectServices: function _injectServices() {
if (this.__injectServices != null) {
this.__injectServices();
} else {
console.warn("Services already injected, do not call this._injectServices twice!");
return;
}
// Protect the ServiceContainer
delete this.__injectServices;
this._onServicesInjected();
},
delete this.__injectServices;
/**
* Function: _onServicesInjected
*
* {protected} function is called after services were injected, use it as hook to prevent overriding constructor
*/
_onServicesInjected: function _onServicesInjected() {},
this._onServicesInjected();
},
/**
* Function: _onServicesInjected
*
* {protected} function is called after services were injected, use it as hook to prevent overriding constructor
*/
_onServicesInjected: function _onServicesInjected() {},
/**
* __injectServices
*
* {private} function injects service instances
*/
__injectServices: function __injectServices() {
var serviceContainer = new Coco.ServiceContainer();
/**
* __injectServices
*
* {private} function injects service instances
*/
__injectServices: function __injectServices() {
var serviceContainer = new Coco.ServiceContainer();
for (var i = 0; i < this.$inject.length; i++) {
console.debug(this.$name + ".inject service: " + this.$inject[i]);
this.$services[this.$inject[i]] = serviceContainer.getService(this.$inject[i]);
}
},
for (var i = 0; i < this.$inject.length; i++) {
console.debug(this.$name + ".inject service: " + this.$inject[i]);
this.$services[this.$inject[i]] = serviceContainer.getService(this.$inject[i]);
}
},
/**
* Function: _getService(serviceId)
*
* {protected} returns special service by given service id
*
* Parameter:
* @param serviceId - String service id to get
*
* Return:
* @returns {Coco.Service} service
*/
_getService: function _getService(serviceId) {
var service = this.$services[serviceId];
if (service == null) {
console.error(this.$name + " service " + serviceId + " not injected!");
}
return service;
/**
* Function: _getService(serviceId)
*
* {protected} returns special service by given service id
*
* Parameter:
* @param serviceId - String service id to get
*
* Return:
* @returns {Coco.Service} service
*/
_getService: function _getService(serviceId) {
var service = this.$services[serviceId];
if (service == null) {
console.error(this.$name + " service " + serviceId + " not injected!");
}
return service;
}
});
"use strict";
var Coco = Coco || {};
Coco.Utils = Coco.Utils || require("../lib/Coco.Utils.js");

@@ -9,3 +8,2 @@ Coco.Model = Coco.Model || require("../model/Coco.Model.js");

Coco.View = Coco.View || require("./Coco.View.js");
/**

@@ -23,68 +21,63 @@ * Class: Coco.ChildView

*/
module.exports = Coco.ChildView = dejavu.Class.declare({
$name: 'Coco.ChildView',
$name: 'Coco.ChildView',
$extends: Coco.View,
$extends: Coco.View,
/**
* Ctor.
*
* @param {Coco.Model|Coco.Collection} $model Can be a new or existing model.
* @param {Object} $syncModelWithForms Override default options of view (optional).
* @param {string} $template Will override `this._template`
*/
initialize: function initialize($model, $syncModelWithForms, $template) {
this._injectServices(); //kill service injection
/**
* Ctor.
*
* @param {Coco.Model|Coco.Collection} $model Can be a new or existing model.
* @param {Object} $syncModelWithForms Override default options of view (optional).
* @param {string} $template Will override `this._template`
*/
initialize: function initialize($model, $syncModelWithForms, $template) {
this._injectServices();
//kill service injection
this._injectServices = null;
this._injectServices = null; // Assign new id to the view object
// Assign new id to the view object
this.__id = Coco.Utils.uniqueId("v");
this.__id = Coco.Utils.uniqueId("v");
var modelSet = false; // Set the model if given
var modelSet = false;
if ($model instanceof Coco.Model) {
modelSet = true;
this.setModel($model);
} // Set the collection if given
// Set the model if given
if ($model instanceof Coco.Model) {
modelSet = true;
this.setModel($model);
}
// Set the collection if given
if (!modelSet && $model instanceof Coco.Collection) {
modelSet = true;
this.setCollection($model);
}
if (!modelSet && $model instanceof Coco.Collection) {
modelSet = true;
this.setCollection($model);
}
if ($model && !modelSet) {
console.error("Invalid model object! Coco.Model or Coco.Collection expected, given: ", $model);
}
if ($model && !modelSet) {
console.error("Invalid model object! Coco.Model or Coco.Collection expected, given: ", $model);
} // Extend the options
// Extend the options
this._options.syncModelWithForm = null != $syncModelWithForms ? $syncModelWithForms : false;
// Set the template
this._template = typeof $template !== 'undefined' && null != $template ? $template : this._template;
this._options.syncModelWithForm = null != $syncModelWithForms ? $syncModelWithForms : false; // Set the template
// Call this._onInitialize before this.$el is set, to prevent any multiple rendering on initialization.
this._onInitialize();
this._template = typeof $template !== 'undefined' && null != $template ? $template : this._template; // Call this._onInitialize before this.$el is set, to prevent any multiple rendering on initialization.
// Create the html wrapper element.
this.$el = $(this._anchor);
this.$el.attr('data-coco', this.__id);
this._onInitialize(); // Create the html wrapper element.
this._configure();
},
/**
* Function: autoRender()
* Calls render. This function is used when ChildViews are added to another View. If the user does not want to
* automatically render his ChildViews, override this function and leave it empty.
*
* Return:
* @return Coco.View - The current <Coco.View> instance.
*/
autoRender: function autoRender() {
return this.render();
}
this.$el = $(this._anchor);
this.$el.attr('data-coco', this.__id);
this._configure();
},
/**
* Function: autoRender()
* Calls render. This function is used when ChildViews are added to another View. If the user does not want to
* automatically render his ChildViews, override this function and leave it empty.
*
* Return:
* @return Coco.View - The current <Coco.View> instance.
*/
autoRender: function autoRender() {
return this.render();
}
});
"use strict";
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
/** @namespace **/
var Coco = Coco || {};
Coco.Event = require("../event/Coco.Event.js");

@@ -14,4 +13,4 @@ Coco.RouterEvent = require("../event/Coco.RouterEvent.js");

Coco.Model = require("../model/Coco.Model.js");
Coco.Collection = require("../model/Coco.Collection.js");
//! do not require ChildView here!, because there is no Coco.View class during require process !
Coco.Collection = require("../model/Coco.Collection.js"); //! do not require ChildView here!, because there is no Coco.View class during require process !
/**

@@ -27,7 +26,6 @@ * Class: Coco.View

*/
module.exports = Coco.View = dejavu.Class.declare({
$name: 'Coco.View',
$extends: Coco.ServiceProvider,
$statics: {

@@ -55,4 +53,3 @@ /**

*/
_add: function _add(model) {
//var etherObjects = {};
_add: function _add(model) {//var etherObjects = {};
//var etherModel = model.getEtherKeys();

@@ -94,3 +91,3 @@ //

return value.slice();
} else if ((typeof value === "undefined" ? "undefined" : _typeof(value)) === 'object') {
} else if (_typeof(value) === 'object') {
//return object clone to protect original model

@@ -237,16 +234,13 @@ return $.extend({}, value);

this.$super();
this.$super(); // Assign new id to the view object
// Assign new id to the view object
this.__id = Coco.Utils.uniqueId("v");
var modelSet = false; // Set the model if given
var modelSet = false;
// Set the model if given
if ($model instanceof Coco.Model) {
modelSet = true;
this.setModel($model);
}
} // Set the collection if given
// Set the collection if given
if ($model instanceof Coco.Collection) {

@@ -259,8 +253,7 @@ modelSet = true;

console.error("Invalid model object! Coco.Model or Coco.Collection expected, given: ", $model);
}
} // Extend the options
// Extend the options
this._options.syncModelWithForm = null != $syncModelWithForms ? $syncModelWithForms : false;
// Call this._onInitialize before this.$el is set, to prevent any multiple rendering on initialization.
this._options.syncModelWithForm = null != $syncModelWithForms ? $syncModelWithForms : false; // Call this._onInitialize before this.$el is set, to prevent any multiple rendering on initialization.
this._onInitialize();

@@ -272,14 +265,16 @@

});
}
} // Create the html wrapper element.
// Create the html wrapper element.
this.$el = $(this._anchor);
if (this.$el == null || this.$el.length == 0) {
console.error(this.$name + "-anchor [" + this._anchor + "] not found in DOM: ", this.$el);
}
this.$el.attr('data-coco', this.__id);
this._configure();
this._configure(); //we only use precompiled templates
//we only use precompiled templates
if (this._template != null) {

@@ -362,2 +357,3 @@ //no autorender anymore!

}
this._collection = collection;

@@ -414,3 +410,2 @@

_onFirstRender: function _onFirstRender() {},
onPreActive: function onPreActive() {

@@ -457,7 +452,8 @@ this.$el.attr('data-coco', this.__id);

throw new Error("Could not render Coco.View [" + this.$name + "], no template found! ", this._template);
}
} // If 'locale' parameter exists in Coco.config - send locale information to template
// This parameter will be used by 'handlebars-intl' extension (formatjs)
// If 'locale' parameter exists in Coco.config - send locale information to template
// This parameter will be used by 'handlebars-intl' extension (formatjs)
var localeObject = {};
var coco = require('../Coco.Init');

@@ -473,5 +469,5 @@

};
}
} //we use require now, so hbs templates are precompiled, just add the model here
//we use require now, so hbs templates are precompiled, just add the model here
var html = this._template(this._getHBSModel(), localeObject);

@@ -483,3 +479,2 @@

if (this.__isActive) {
// Empty/append ONLY IF the $el inside main container is not THE SAME

@@ -494,7 +489,8 @@ if (this._getRouter() && this._getRouter().$container.children().first()[0] != this.$el[0]) {

if (this._firstRendered === false) {
this._firstRendered = true;
//use delayed callback, to let the DOM get rendered
this._firstRendered = true; //use delayed callback, to let the DOM get rendered
setTimeout(function () {
_this2._onFirstRender();
//also call delegate events delayed
_this2._onFirstRender(); //also call delegate events delayed
_this2.delegateEvents();

@@ -558,5 +554,4 @@

_getHBSModel: function _getHBSModel() {
var props = {};
var props = {}; //use only simple comparison, to catch null and undefined
//use only simple comparison, to catch null and undefined
if (this._collection != null || this._model != null) {

@@ -572,2 +567,3 @@ /**

}
props = this._collection == null ? this._model.getAttributes() : {

@@ -593,3 +589,2 @@ collection: {

this.render();
return this.$el.get();

@@ -622,2 +617,3 @@ },

this._model.destroy();
this._model = null;

@@ -628,8 +624,8 @@ }

this._collection.destroy();
this._collection = null;
}
this.removeAllEventListener();
this.removeAllEventListener(); //stop listening jQuery events
//stop listening jQuery events
this.undelegateEvents();

@@ -696,2 +692,3 @@ this.removeAllChildViews();

var $container = this.$el.find(selector);
if (!$addToAllMatching) {

@@ -712,3 +709,2 @@ $container = $container.first();

}
/**

@@ -720,2 +716,3 @@ * Call child views _onFirstRender. Because this method is called after the first rendering, but has no effect

return view;

@@ -741,16 +738,15 @@ },

this.__childViews[selector] = [];
}
} // Create virtual DOM element
// Create virtual DOM element
var $virtualElement = $(document.createDocumentFragment());
// Append all childviews to it
var $virtualElement = $(document.createDocumentFragment()); // Append all childviews to it
collection.each(function (model) {
var view_instance = new view_definition(model);
_this5.__childViews[selector].push(view_instance);
$virtualElement.append(view_instance.getDOM());
});
}); // Append virtual element to actual HTML
// Append virtual element to actual HTML
this.$el.find(selector).first().append($virtualElement);

@@ -771,3 +767,2 @@ },

var ret = this.__childViews[selector];
return ret instanceof Array ? ret : [];

@@ -835,2 +830,3 @@ },

}
return 0;

@@ -882,2 +878,3 @@ },

this.__childViews[views][i].remove();
this.__childViews[views].splice(i, 1);

@@ -957,5 +954,5 @@

_this6._model = null;
}, true);
}, true); //this works only with 1 model
//this works only with 1 model
if (this._options.syncModelWithForm) {

@@ -990,5 +987,4 @@ this.$el.on('change', 'select, textarea, input', function (e) {

view.delegateEvents(null);
});
}); //do not delegate events twice
//do not delegate events twice
return;

@@ -1010,5 +1006,5 @@ }

throw new Error("The callback function '" + callback + "' does not exist in '" + this.$name + "'.");
}
} //TODO remove dejavu binding
//TODO remove dejavu binding
this.$el.on(event, selector, this[callback].$bind(this));

@@ -1040,5 +1036,4 @@ }

var event = key.substr(0, key.indexOf(' '));
var selector = key.substr(key.indexOf(' ') + 1);
var selector = key.substr(key.indexOf(' ') + 1); //remove evenhandler
//remove evenhandler
this.$el.off(event, selector);

@@ -1068,3 +1063,2 @@ }

$duration = null != $duration ? $duration : 100;
this.$(selector).animate(properties, $duration, $callback);

@@ -1101,11 +1095,8 @@ },

},
isActive: function isActive() {
return this.__isActive;
},
activate: function activate() {
this.__isActive = true;
},
deactivate: function deactivate() {

@@ -1112,0 +1103,0 @@ this.__isActive = false;

{
"name": "3m5-coco",
"version": "0.2.0",
"version": "0.3.0",
"description": "a simple MVC Framework",

@@ -32,15 +32,13 @@ "main": "lib/Coco.Init.js",

{
"name": "Erik Neumann",
"email": "erik.neumann@3m5.de"
"name": "Erik Swars",
"email": "erik.swars@3m5.de"
},
{
"name": "Sergey Rizovs",
"email": "sergey.rizovs@3m5.de"
"name": "Lukas Gerlach",
"email": "lukas.gerlach@3m5.de"
}
],
"devDependencies": {
"babel-plugin-es6-promise": "^1.0.0",
"babel-preset-es2015": "^6.9.0",
"babel-preset-stage-2": "^6.11.0",
"babel-preset-stage-3": "^6.11.0",
"@babel/core": "^7.4.3",
"@babel/preset-env": "^7.4.3",
"browserify": "^13.0.0",

@@ -50,3 +48,3 @@ "domain": "0.0.1",

"gulp": "^3.9.1",
"gulp-babel": "^6.1.2",
"gulp-babel": "^8.0.0",
"gulp-clean": "^0.3.2",

@@ -64,6 +62,7 @@ "gulp-concat": "^2.5.2",

},
"peerDependencies": {
"@babel/polyfill": "^7.4.3",
"jquery": "^2.2.4"
},
"dependencies": {
"JSON": "^1.0.0",
"babel-polyfill": "^6.9.1",
"jquery": "^2.2.4",
"underscore": "^1.8.3"

@@ -70,0 +69,0 @@ },

@@ -0,0 +0,0 @@ <p align="center">

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc