277 lines
6.5 KiB
Plaintext
277 lines
6.5 KiB
Plaintext
define([
|
|
'jquery'
|
|
], function ($) {
|
|
var Utils = {};
|
|
|
|
Utils.Extend = function (ChildClass, SuperClass) {
|
|
var __hasProp = {}.hasOwnProperty;
|
|
|
|
function BaseConstructor () {
|
|
this.constructor = ChildClass;
|
|
}
|
|
|
|
for (var key in SuperClass) {
|
|
if (__hasProp.call(SuperClass, key)) {
|
|
ChildClass[key] = SuperClass[key];
|
|
}
|
|
}
|
|
|
|
BaseConstructor.prototype = SuperClass.prototype;
|
|
ChildClass.prototype = new BaseConstructor();
|
|
ChildClass.__super__ = SuperClass.prototype;
|
|
|
|
return ChildClass;
|
|
};
|
|
|
|
function getMethods (theClass) {
|
|
var proto = theClass.prototype;
|
|
|
|
var methods = [];
|
|
|
|
for (var methodName in proto) {
|
|
var m = proto[methodName];
|
|
|
|
if (typeof m !== 'function') {
|
|
continue;
|
|
}
|
|
|
|
if (methodName === 'constructor') {
|
|
continue;
|
|
}
|
|
|
|
methods.push(methodName);
|
|
}
|
|
|
|
return methods;
|
|
}
|
|
|
|
Utils.Decorate = function (SuperClass, DecoratorClass) {
|
|
var decoratedMethods = getMethods(DecoratorClass);
|
|
var superMethods = getMethods(SuperClass);
|
|
|
|
function DecoratedClass () {
|
|
var unshift = Array.prototype.unshift;
|
|
|
|
var argCount = DecoratorClass.prototype.constructor.length;
|
|
|
|
var calledConstructor = SuperClass.prototype.constructor;
|
|
|
|
if (argCount > 0) {
|
|
unshift.call(arguments, SuperClass.prototype.constructor);
|
|
|
|
calledConstructor = DecoratorClass.prototype.constructor;
|
|
}
|
|
|
|
calledConstructor.apply(this, arguments);
|
|
}
|
|
|
|
DecoratorClass.displayName = SuperClass.displayName;
|
|
|
|
function ctr () {
|
|
this.constructor = DecoratedClass;
|
|
}
|
|
|
|
DecoratedClass.prototype = new ctr();
|
|
|
|
for (var m = 0; m < superMethods.length; m++) {
|
|
var superMethod = superMethods[m];
|
|
|
|
DecoratedClass.prototype[superMethod] =
|
|
SuperClass.prototype[superMethod];
|
|
}
|
|
|
|
var calledMethod = function (methodName) {
|
|
// Stub out the original method if it's not decorating an actual method
|
|
var originalMethod = function () {};
|
|
|
|
if (methodName in DecoratedClass.prototype) {
|
|
originalMethod = DecoratedClass.prototype[methodName];
|
|
}
|
|
|
|
var decoratedMethod = DecoratorClass.prototype[methodName];
|
|
|
|
return function () {
|
|
var unshift = Array.prototype.unshift;
|
|
|
|
unshift.call(arguments, originalMethod);
|
|
|
|
return decoratedMethod.apply(this, arguments);
|
|
};
|
|
};
|
|
|
|
for (var d = 0; d < decoratedMethods.length; d++) {
|
|
var decoratedMethod = decoratedMethods[d];
|
|
|
|
DecoratedClass.prototype[decoratedMethod] = calledMethod(decoratedMethod);
|
|
}
|
|
|
|
return DecoratedClass;
|
|
};
|
|
|
|
var Observable = function () {
|
|
this.listeners = {};
|
|
};
|
|
|
|
Observable.prototype.on = function (event, callback) {
|
|
this.listeners = this.listeners || {};
|
|
|
|
if (event in this.listeners) {
|
|
this.listeners[event].push(callback);
|
|
} else {
|
|
this.listeners[event] = [callback];
|
|
}
|
|
};
|
|
|
|
Observable.prototype.trigger = function (event) {
|
|
var slice = Array.prototype.slice;
|
|
var params = slice.call(arguments, 1);
|
|
|
|
this.listeners = this.listeners || {};
|
|
|
|
// Params should always come in as an array
|
|
if (params == null) {
|
|
params = [];
|
|
}
|
|
|
|
// If there are no arguments to the event, use a temporary object
|
|
if (params.length === 0) {
|
|
params.push({});
|
|
}
|
|
|
|
// Set the `_type` of the first object to the event
|
|
params[0]._type = event;
|
|
|
|
if (event in this.listeners) {
|
|
this.invoke(this.listeners[event], slice.call(arguments, 1));
|
|
}
|
|
|
|
if ('*' in this.listeners) {
|
|
this.invoke(this.listeners['*'], arguments);
|
|
}
|
|
};
|
|
|
|
Observable.prototype.invoke = function (listeners, params) {
|
|
for (var i = 0, len = listeners.length; i < len; i++) {
|
|
listeners[i].apply(this, params);
|
|
}
|
|
};
|
|
|
|
Utils.Observable = Observable;
|
|
|
|
Utils.generateChars = function (length) {
|
|
var chars = '';
|
|
|
|
for (var i = 0; i < length; i++) {
|
|
var randomChar = Math.floor(Math.random() * 36);
|
|
chars += randomChar.toString(36);
|
|
}
|
|
|
|
return chars;
|
|
};
|
|
|
|
Utils.bind = function (func, context) {
|
|
return function () {
|
|
func.apply(context, arguments);
|
|
};
|
|
};
|
|
|
|
Utils._convertData = function (data) {
|
|
for (var originalKey in data) {
|
|
var keys = originalKey.split('-');
|
|
|
|
var dataLevel = data;
|
|
|
|
if (keys.length === 1) {
|
|
continue;
|
|
}
|
|
|
|
for (var k = 0; k < keys.length; k++) {
|
|
var key = keys[k];
|
|
|
|
// Lowercase the first letter
|
|
// By default, dash-separated becomes camelCase
|
|
key = key.substring(0, 1).toLowerCase() + key.substring(1);
|
|
|
|
if (!(key in dataLevel)) {
|
|
dataLevel[key] = {};
|
|
}
|
|
|
|
if (k == keys.length - 1) {
|
|
dataLevel[key] = data[originalKey];
|
|
}
|
|
|
|
dataLevel = dataLevel[key];
|
|
}
|
|
|
|
delete data[originalKey];
|
|
}
|
|
|
|
return data;
|
|
};
|
|
|
|
Utils.hasScroll = function (index, el) {
|
|
// Adapted from the function created by @ShadowScripter
|
|
// and adapted by @BillBarry on the Stack Exchange Code Review website.
|
|
// The original code can be found at
|
|
// http://codereview.stackexchange.com/q/13338
|
|
// and was designed to be used with the Sizzle selector engine.
|
|
|
|
var $el = $(el);
|
|
var overflowX = el.style.overflowX;
|
|
var overflowY = el.style.overflowY;
|
|
|
|
//Check both x and y declarations
|
|
if (overflowX === overflowY &&
|
|
(overflowY === 'hidden' || overflowY === 'visible')) {
|
|
return false;
|
|
}
|
|
|
|
if (overflowX === 'scroll' || overflowY === 'scroll') {
|
|
return true;
|
|
}
|
|
|
|
return ($el.innerHeight() < el.scrollHeight ||
|
|
$el.innerWidth() < el.scrollWidth);
|
|
};
|
|
|
|
Utils.escapeMarkup = function (markup) {
|
|
var replaceMap = {
|
|
'\\': '\',
|
|
'&': '&',
|
|
'<': '<',
|
|
'>': '>',
|
|
'"': '"',
|
|
'\'': ''',
|
|
'/': '/'
|
|
};
|
|
|
|
// Do not try to escape the markup if it's not a string
|
|
if (typeof markup !== 'string') {
|
|
return markup;
|
|
}
|
|
|
|
return String(markup).replace(/[&<>"'\/\\]/g, function (match) {
|
|
return replaceMap[match];
|
|
});
|
|
};
|
|
|
|
// Append an array of jQuery nodes to a given element.
|
|
Utils.appendMany = function ($element, $nodes) {
|
|
// jQuery 1.7.x does not support $.fn.append() with an array
|
|
// Fall back to a jQuery object collection using $.fn.add()
|
|
if ($.fn.jquery.substr(0, 3) === '1.7') {
|
|
var $jqNodes = $();
|
|
|
|
$.map($nodes, function (node) {
|
|
$jqNodes = $jqNodes.add(node);
|
|
});
|
|
|
|
$nodes = $jqNodes;
|
|
}
|
|
|
|
$element.append($nodes);
|
|
};
|
|
|
|
return Utils;
|
|
});
|