src/utility.js

Method $

Parameters:

  • arg must be a String.
    (Comma delimited string of CSS selectors)

Returns a Mixed
(Element or Array of Elements)

$ : function ( arg ) { var result; if ( !arg ) { return; } arg = string.trim( arg ); if ( arg.indexOf( "," ) === -1 ) { result = utility.dom( arg ); } else { result = []; array.each( string.explode( arg ), function ( query ) { var obj = utility.dom( query ); if ( obj instanceof Array ) { result = result.concat( obj ); } else if ( obj ) { result.push( obj ); } }); } return result; },

Method alias

Aliases origin onto obj

Parameters:

  • obj must be an Object.
    (Object receiving aliasing)

  • origin must be an Object.
    (Object providing structure to obj)

Returns an Object
(Object receiving aliasing)

alias : function ( obj, origin ) { var o = obj, s = origin; utility.iterate( s, function ( v, k ) { var getter, setter; if ( !( v instanceof RegExp ) && typeof v === "function" ) { o[k] = v.bind( o[k] ); } else if ( !(v instanceof RegExp ) && !(v instanceof Array ) && v instanceof Object ) { if ( o[k] === undefined ) { o[k] = {}; } utility.alias( o[k], s[k] ); } else { getter = function () { return s[k]; }; setter = function ( arg ) { s[k] = arg; }; utility.property( o, k, {enumerable: true, get: getter, set: setter, value: s[k]} ); } }); return obj; },

Method clearTimers

Clears deferred & repeating functions

Parameters:

  • id must be a String.
    (ID of timer( s ))

Returns an Undefined
(undefined)

clearTimers : function ( id ) { if ( id === undefined || string.isEmpty( id ) ) { throw new Error( label.error.invalidArguments ); }

deferred

if ( utility.timer[id] !== undefined ) { clearTimeout( utility.timer[id] ); delete utility.timer[id]; }

repeating

if ( utility.repeating[id] !== undefined ) { clearTimeout( utility.repeating[id] ); delete utility.repeating[id]; } },

Method clone

Clones an Object

Parameters:

  • obj must be an Object.
    (Object to clone)

  • shallow must be a Boolean.
    ([Optional] Create a shallow clone, which doesn't maintain prototypes, default is false)

Returns an Object
(Clone of obj)

clone : function ( obj, shallow ) { var clone; if ( shallow === true ) { return json.decode( json.encode( obj ) ); } else if ( !obj || regex.primitive.test( typeof obj ) || ( obj instanceof RegExp ) ) { return obj; } else if ( obj instanceof Array ) { return obj.slice(); } else if ( !server && !client.ie && obj instanceof Document ) { return xml.decode( xml.encode( obj ) ); } else if ( typeof obj.__proto__ !== "undefined" ) { return utility.extend( obj.__proto__, obj ); } else if ( obj instanceof Object ) {

If JSON encoding fails due to recursion, the original Object is returned because it's assumed this is for decoration

clone = json.encode( obj, true ); if ( clone !== undefined ) { clone = json.decode( clone );

Decorating Functions that would be lost with JSON encoding/decoding

utility.iterate( obj, function ( v, k ) { if ( typeof v === "function" ) { clone[k] = v; } }); } else { clone = obj; } return clone; } else { return obj; } },

Method coerce

Coerces a String to a Type

Parameters:

  • value must be a String.
    (String to coerce)

Returns a Mixed
(Primitive version of the String)

coerce : function ( value ) { var tmp; if ( value === null || value === undefined ) { return undefined; } else if ( value === "true" ) { return true; } else if ( value === "false" ) { return false; } else if ( value === "null" ) { return null; } else if ( value === "undefined" ) { return undefined; } else if ( value === "" ) { return value; } else if ( !isNaN( tmp = Number( value ) ) ) { return tmp; } else if ( regex.json_wrap.test( value ) ) { return json.decode( value, true ) || value; } else { return value; } },

Method compile

Recompiles a RegExp by reference This is ideal when you need to recompile a regex for use within a conditional statement

Parameters:

  • regex must be an Object.
    (RegExp)

  • pattern must be a String.
    (Regular expression pattern)

  • modifiers must be a String.
    (Modifiers to apply to the pattern)

Returns a Boolean
(true)

compile : function ( reg, pattern, modifiers ) { reg.compile( pattern, modifiers ); return true; },

Method css

Creates a CSS stylesheet in the View

Parameters:

  • content must be a String.
    (CSS to put in a style tag)

  • media must be a String.
    ([Optional] Medias the stylesheet applies to)

Returns an Object
(Element created or undefined)

css : function ( content, media ) { var ss, css; ss = element.create( "style", {type: "text/css", media: media || "print, screen"}, utility.$( "head" )[0] ); if ( ss.styleSheet ) { ss.styleSheet.cssText = content; } else { css = document.createTextNode( content ); ss.appendChild( css ); } return ss; },

Method debounce

Debounces a function

Parameters:

  • fn must be a Function.
    (Function to execute)

  • ms must be a Number.
    (Time to wait to execute in milliseconds, default is 1000)

  • scope can be of any type.
    (this context during execution, default is global)

Returns an Undefined
(undefined)

debounce : function ( fn, ms, scope ) { ms = ms || 1000; scope = scope || global; return function debounced () { setTimeout( function () { fn.apply( scope, arguments ); }, ms); }; },

Method define

Allows deep setting of properties without knowing if the structure is valid

Parameters:

  • args must be a String.
    (Dot delimited string of the structure)

  • value can be of any type.
    (Value to set)

  • obj must be an Object.
    (Object receiving value)

Returns an Object
(Object receiving value)

define : function ( args, value, obj ) { args = args.split( "." ); var p = obj, nth = args.length; if ( obj === undefined ) { obj = this; } if ( value === undefined ) { value = null; } array.each( args, function ( i, idx ) { var num = idx + 1 < nth && !isNaN( number.parse( args[idx + 1], 10 ) ), val = value; if ( !isNaN( number.parse( i, 10 ) ) ) { i = number.parse( i, 10 ); }

Creating or casting

if ( p[i] === undefined ) { p[i] = num ? [] : {}; } else if ( p[i] instanceof Object && num ) { p[i] = array.cast( p[i] ); } else if ( p[i] instanceof Object ) {

Do nothing

} else if ( p[i] instanceof Array && !num ) { p[i] = array.toObject( p[i] ); } else { p[i] = {}; }

Setting reference or value

idx + 1 === nth ? p[i] = val : p = p[i]; }); return obj; },

Method defer

Defers the execution of Function by at least the supplied milliseconds Timing may vary under "heavy load" relative to the CPU & client JavaScript engine

Parameters:

  • fn must be a Function.
    (Function to defer execution of)

  • ms must be a Number.
    (Milliseconds to defer execution)

  • id must be a Number.
    ([Optional] ID of the deferred function)

  • repeat must be a Boolean.
    ([Optional] Describes the execution, default is false)

Returns a String
(ID of the timer)

defer : function ( fn, ms, id, repeat ) { var op; ms = ms || 0; repeat = ( repeat === true ); if ( id !== undefined ) { utility.clearTimers( id ); } else { id = utility.uuid( true ); } op = function () { utility.clearTimers( id ); fn(); }; utility[repeat ? "repeating" : "timer"][id] = setTimeout( op, ms ); return id; },

Method dom

Queries DOM with fastest method

Parameters:

  • arg must be a String.
    (DOM query)

Returns a Mixed
(undefined, Element, or Array of Elements)

dom : function ( arg ) { var result; if ( !regex.selector_complex.test( arg ) ) { if ( regex.hash.test( arg ) ) { result = document.getElementById( arg.replace( regex.hash, "" ) ) || undefined; } else if ( regex.klass.test( arg ) ) { result = array.cast( document.getElementsByClassName( arg.replace( regex.klass, "" ) ) ); } else if ( regex.word.test( arg ) ) { result = array.cast( document.getElementsByTagName( arg ) ); } else { result = array.cast( document.querySelectorAll( arg ) ); } } else { result = array.cast( document.querySelectorAll( arg ) ); } return result; },

Method domId

Encodes a UUID to a DOM friendly ID

Parameters:

  • UUID must be a String.

Returns a String
(DOM friendly ID)

domId : function ( arg ) { return "a" + arg.replace( /-/g, "" ).slice( 1 ); },

Method error

Error handling, with history in .log

Parameters:

  • e can be of any type.
    (Error object or message to display)

  • args must be an Array.
    (Array of arguments from the callstack)

  • scope can be of any type.
    (Entity that was "this")

  • warning must be a Boolean.
    ([Optional] Will display as console warning if true)

Returns an Undefined
(undefined)

error : function ( e, args, scope, warning ) { warning = ( warning === true ); var o = { "arguments" : args !== undefined ? array.cast( args ) : [], message : e.message || e, number : e.number !== undefined ? ( e.number & 0xFFFF ) : undefined, scope : scope, stack : e.stack || undefined, timestamp : new Date().toUTCString(), type : e.type || "TypeError" }; utility.log( ( o.stack || o.message || o ), !warning ? "error" : "warn" ); utility.error.log.push( o ); observer.fire( abaaso, "error", o ); return undefined; },

Method extend

Creates a "class" extending Object, with optional decoration

Parameters:

  • obj must be an Object.
    (Object to extend)

  • arg must be an Object.
    ([Optional] Object for decoration)

Returns an Object
(Decorated obj)

extend : function () { if ( typeof Object.create === "function" ) { return function ( obj, arg ) { var o; if ( obj === undefined ) { throw new Error( label.error.invalidArguments ); } o = Object.create( obj ); if ( arg instanceof Object ) { utility.merge( o, arg ); } return o; }; } else { return function ( obj, arg ) { function Extended () {} var o; if ( obj === undefined ) { throw new Error( label.error.invalidArguments ); } Extended.prototype = obj; o = new Extended(); if ( arg instanceof Object ) { utility.merge( o, arg ); } return o; }; } }(),

Method fib

Fibonacci calculator

Parameters:

  • i must be a Number.
    (Number to calculate)

  • r must be a Boolean.
    (Recursive if true)

Returns a Number
(Calculated number)

fib : function ( i, r ) { if ( r === true ) { return i > 1 ? utility.fib( i - 1, r ) + utility.fib( i - 2, r ) : i; } else { return array.last( array.fib( i ) ); } },

Method genId

Generates an ID value

Parameters:

  • obj can be of any type.
    ([Optional] Object to receive id)

  • dom must be a Boolean.
    ([Optional] Verify the ID is unique in the DOM, default is false)

Returns a Mixed
(Object or id)

genId : function ( obj, dom ) { dom = ( dom === true ); var id; if ( obj !== undefined && ( ( obj.id !== undefined && obj.id !== "" ) || ( obj instanceof Array ) || ( obj instanceof String || typeof obj === "string" ) ) ) { return obj; } if ( dom ) { do { id = utility.domId( utility.uuid( true) ); } while ( utility.$( "#" + id ) !== undefined ); } else { id = utility.domId( utility.uuid( true) ); } if ( typeof obj === "object" ) { obj.id = id; return obj; } else { return id; } },

Method hash

Getter / setter for the hashbang

Parameters:

  • arg must be a String.
    (Route to set)

Returns a String
(Current route)

hash : function ( arg ) { if ( arg !== undefined ) { document.location.hash = arg; } return document.location.hash; },

Method hex

Converts RGB to HEX

Parameters:

  • color must be a String.
    (RGB as rgb(255, 255, 255) or 255, 255, 255)

Returns a String
(Color as HEX)

hex : function ( color ) { var digits, red, green, blue, result, i, nth; if ( color.charAt( 0 ) === "#" ) { result = color; } else { digits = string.explode( color.replace( /.*\(|\)/g, "" ) ); red = number.parse( digits[0] || 0 ); green = number.parse( digits[1] || 0 ); blue = number.parse( digits[2] || 0 ); result = ( blue | ( green << 8 ) | ( red << 16 ) ).toString( 16 ); if ( result.length < 6 ) { nth = number.diff( result.length, 6 ); i = -1; while ( ++i < nth ) { result = "0" + result; } } result = "#" + result; } return result; },

Method iterate

Iterates an Object and executes a function against the properties Iteration can be stopped by returning false from fn

Parameters:

  • obj must be an Object.
    (Object to iterate)

  • fn must be a Function.
    (Function to execute against properties)

Returns an Object
(Object)

iterate : function () { if ( typeof Object.keys === "function" ) { return function ( obj, fn ) { if ( typeof fn !== "function" ) { throw new Error( label.error.invalidArguments ); } array.each( Object.keys( obj ), function ( i ) { return fn.call( obj, obj[i], i ); }); return obj; }; } else { return function ( obj, fn ) { var i, result; if ( typeof fn !== "function" ) { throw new Error( label.error.invalidArguments ); } for ( i in obj ) { if ( has.call( obj, i ) ) { result = fn.call( obj, obj[i], i ); if ( result === false ) { break; } } else { break; } } return obj; }; } }(),

Method loading

Renders a loading icon in a target element, with a class of "loading"

Parameters:

  • obj can be of any type.
    (Element)

Returns a Mixed
(Element)

loading : function ( obj ) { var l = abaaso.loading; if ( l.url === null || obj === undefined ) { throw new Error( label.error.invalidArguments ); }

Setting loading image

if ( l.image === undefined ) { l.image = new Image(); l.image.src = l.url; }

Clearing target element

element.clear( obj );

Creating loading image in target element

element.create( "img", {alt: label.common.loading, src: l.image.src}, element.create( "div", {"class": "loading"}, obj ) ); return obj; },

Method log

Writes argument to the console

Parameters:

  • arg must be a String.
    (String to write to the console)

  • target must be a String.
    ([Optional] Target console, default is "log")

Returns an Undefined
(undefined)

log : function ( arg, target ) { var ts, msg; if ( typeof console !== "undefined" ) { ts = typeof arg !== "object"; msg = ts ? "[" + new Date().toLocaleTimeString() + "] " + arg : arg; console[target || "log"]( msg ); } },

Method merge

Merges obj with arg

Parameters:

  • obj must be an Object.
    (Object to decorate)

  • arg must be an Object.
    (Decoration)

Returns an Object
(Decorated Object)

merge : function ( obj, arg ) { utility.iterate( arg, function ( v, k ) { if ( ( obj[k] instanceof Array ) && ( v instanceof Array ) ) { array.merge( obj[k], v ); } else if ( ( obj[k] instanceof Object ) && ( v instanceof Object ) ) { utility.iterate( v, function ( x, y ) { obj[k][y] = utility.clone( x ); }); } else { obj[k] = utility.clone( v ); } }); return obj; },

Method module

Registers a module on abaaso

Parameters:

  • arg must be a String.
    (Module name)

  • obj must be an Object.
    (Module structure)

Returns an Object
(Module registered)

module : function ( arg, obj ) { if ( $[arg] !== undefined || !obj instanceof Object ) { throw new Error( label.error.invalidArguments ); } $[arg] = obj; return $[arg]; },

Private method object

Returns Object, or reference to Element

Parameters:

  • obj can be of any type.
    (Entity or $ query)

Returns a Mixed
(Entity)

object : function ( obj ) { return typeof obj === "object" ? obj : ( obj.charAt && obj.charAt( 0 ) === "#" ? utility.$( obj ) : obj ); },

Method parse

Parses a URI into an Object

Parameters:

  • uri must be a String.
    (URI to parse)

Returns an Object
(Parsed URI)

parse : function ( uri ) { var obj = {}, parsed = {}; if ( uri === undefined ) { uri = !server ? location.href : ""; } uri = decodeURIComponent( uri ); if ( !server ) { obj = document.createElement( "a" ); obj.href = uri; } else { obj = url.parse( uri ); } if ( server ) { utility.iterate( obj, function ( v, k ) { if ( v === null ) { obj[k] = undefined; } }); } parsed = { auth : server ? null : regex.auth.exec( uri ), protocol : obj.protocol || "http:", hostname : obj.hostname || "localhost", port : obj.port ? number.parse( obj.port, 10 ) : "", pathname : obj.pathname, search : obj.search || "", hash : obj.hash || "", host : obj.host || "localhost" };

'cause IE is ... IE; required for data.batch()

if ( client.ie ) { if ( parsed.protocol === ":" ) { parsed.protocol = location.protocol; } if ( string.isEmpty( parsed.hostname ) ) { parsed.hostname = location.hostname; } if ( string.isEmpty( parsed.host ) ) { parsed.host = location.host; } if ( parsed.pathname.charAt( 0 ) !== "/" ) { parsed.pathname = "/" + parsed.pathname; } } parsed.auth = obj.auth || ( parsed.auth === null ? "" : parsed.auth[1] ); parsed.href = obj.href || ( parsed.protocol + "//" + ( string.isEmpty( parsed.auth ) ? "" : parsed.auth + "@" ) + parsed.host + parsed.pathname + parsed.search + parsed.hash ); parsed.path = obj.path || parsed.pathname + parsed.search; parsed.query = utility.queryString( null, parsed.search ); return parsed; },

Method property

Sets a property on an Object, if defineProperty cannot be used the value will be set classically

Parameters:

  • obj must be an Object.
    (Object to decorate)

  • prop must be a String.
    (Name of property to set)

  • descriptor must be an Object.
    (Descriptor of the property)

Returns an Object
(Object receiving the property)

property : function () { if ( ( server || ( !client.ie || client.version > 8 ) ) && typeof Object.defineProperty === "function" ) { return function ( obj, prop, descriptor ) { if ( !( descriptor instanceof Object ) ) { throw new Error( label.error.invalidArguments ); } if ( descriptor.value !== undefined && descriptor.get !== undefined ) { delete descriptor.value; } Object.defineProperty( obj, prop, descriptor ); }; } else { return function ( obj, prop, descriptor ) { if ( !( descriptor instanceof Object ) ) { throw new Error( label.error.invalidArguments ); } obj[prop] = descriptor.value; return obj; }; } },

Method proto

Sets methods on a prototype object Allows hooks to be overwritten

Parameters:

  • obj must be an Object.
    (Object receiving prototype extension)

  • type must be a String.
    (Identifier of obj, determines what Arrays to apply)

Returns an Object
(obj or undefined)

proto : function ( obj, type ) { var target = obj.prototype || obj; utility.iterate( prototypes[type], function ( v, k ) { if ( !target[k] ) { utility.property( target, k, {value: v, configurable: true, writable: true} ); } }); return obj; },

Method queryString

Parses a query string & coerces values

Parameters:

  • arg must be a String.
    ([Optional] Key to find in the querystring)

  • qstring must be a String.
    ([Optional] Query string to parse)

Returns a Mixed
(Value or Object of key:value pairs)

queryString : function ( arg, qstring ) { var obj = {}, result = qstring !== undefined ? ( qstring.indexOf( "?" ) > -1 ? qstring.replace( /.*\?/, "" ) : null) : ( server || string.isEmpty( location.search ) ? null : location.search.replace( "?", "" ) ), item; if ( result !== null && !string.isEmpty( result ) ) { result = result.split( "&" ); array.each( result, function (prop ) { item = prop.split( "=" ); if ( string.isEmpty( item[0] ) ) { return; } if ( item[1] === undefined || string.isEmpty( item[1] ) ) { item[1] = ""; } else if ( string.isNumber( item[1] )) { item[1] = Number(item[1] ); } else if ( string.isBoolean( item[1] )) { item[1] = (item[1] === "true" ); } if ( obj[item[0]] === undefined ) { obj[item[0]] = item[1]; } else if ( !(obj[item[0]] instanceof Array) ) { obj[item[0]] = [obj[item[0]]]; obj[item[0]].push( item[1] ); } else { obj[item[0]].push( item[1] ); } }); } if ( arg !== null && arg !== undefined ) { obj = obj[arg]; } return obj; },

Method reflect

Returns an Array of parameters of a Function

Parameters:

  • arg must be a Function.
    (Function to reflect)

Returns an Array
(Array of parameters)

reflect : function ( arg ) { if ( arg === undefined ) { arg = this || utility.$; } arg = arg.toString().match( regex.reflect )[1]; return string.explode( arg ); },

Method repeat

Creates a recursive function Return false from the function to halt recursion

Parameters:

  • fn must be a Function.
    (Function to execute repeatedly)

  • ms must be a Number.
    (Milliseconds to stagger the execution)

  • id must be a String.
    ([Optional] Timeout ID)

  • now must be a Boolean.
    (Executes fn and then setup repetition, default is true)

Returns a String
(Timeout ID)

repeat : function ( fn, ms, id, now ) { ms = ms || 10; id = id || utility.uuid( true ); now = ( now !== false );

Could be valid to return false from initial execution

if ( now && fn() === false ) { return; }

Creating repeating execution

utility.defer( function () { var recursive = function ( fn, ms, id ) { var recursive = this; if ( fn() !== false ) { utility.repeating[id] = setTimeout( function () { recursive.call( recursive, fn, ms, id ); }, ms ); } else { delete utility.repeating[id]; } }; recursive.call( recursive, fn, ms, id ); }, ms, id, true ); return id; },

Method stop

Stops an Event from bubbling

Parameters:

  • e must be an Object.
    (Event)

Returns an Object
(Event)

stop : function ( e ) { if ( e.cancelBubble !== undefined ) { e.cancelBubble = true; } if ( typeof e.preventDefault === "function" ) { e.preventDefault(); } if ( typeof e.stopPropagation === "function" ) { e.stopPropagation(); }

Assumed to always be valid, even if it's not decorated on e ( I'm looking at you IE8 )

e.returnValue = false; return e; },

Method target

Returns the Event target

Parameters:

  • e must be an Object.
    (Event)

Returns an Object
(Event target)

target : function ( e ) { return e.target || e.srcElement; },

Method tpl

Transforms JSON to HTML and appends to Body or target Element

Parameters:

  • data must be an Object.
    (JSON Object describing HTML)

  • target can be of any type.
    ([Optional] Target Element or Element.id to receive the HTML)

Returns an Object
(New Element created from the template)

tpl : function ( arg, target ) { var frag; if ( typeof arg !== "object" || (!(regex.object_undefined.test( typeof target ) ) && ( target = target.charAt( 0 ) === "#" ? utility.$( target ) : utility.$( target )[0] ) === undefined ) ) { throw new Error( label.error.invalidArguments ); } if ( target === undefined ) { target = utility.$( "body" )[0]; } frag = document.createDocumentFragment(); if ( arg instanceof Array ) { array.each( arg, function ( i ) { element.html( element.create( array.cast( i, true )[0], frag ), array.cast(i)[0] ); }); } else { utility.iterate( arg, function ( v, k ) { if ( typeof v === "string" ) { element.html( element.create( k, undefined, frag ), v ); } else if ( ( v instanceof Array ) || ( v instanceof Object ) ) { utility.tpl( v, element.create( k, undefined, frag ) ); } }); } target.appendChild( frag ); return array.last( target.childNodes ); },

Method uuid

Generates a version 4 UUID

Parameters:

  • safe must be a Boolean.
    ([Optional] Strips - from UUID)

Returns a String
(UUID)

uuid : function ( safe ) { var s = function () { return ( ( ( 1 + Math.random() ) * 0x10000 ) | 0 ).toString( 16 ).substring( 1 ); }, r = [8, 9, "a", "b"], o; o = ( s() + s() + "-" + s() + "-4" + s().substr( 0, 3 ) + "-" + r[Math.floor( Math.random() * 4 )] + s().substr( 0, 3 ) + "-" + s() + s() + s() ); if ( safe === true ) { o = o.replace( /-/g, "" ); } return o; },

Method walk

Walks a structure and returns arg

Parameters:

  • obj can be of any type.
    (Object or Array)

  • arg must be a String.
    (String describing the property to return)

Returns a Mixed
(arg)

walk : function ( obj, arg ) { array.each( arg.replace( /\]$/, "" ).replace( /\]/g, "." ).replace( /\.\./g, "." ).split( /\.|\[/ ), function ( i ) { obj = obj[i]; }); return obj; },

Method when

Accepts Deferreds or Promises as arguments or an Array

Returns an Object
(Deferred)

when : function () { var i = 0, defer = deferred(), args = array.cast( arguments ), nth;

Did we receive an Array? if so it overrides any other arguments

if ( args[0] instanceof Array ) { args = args[0]; }

How many instances to observe?

nth = args.length;

None, end on next tick

if ( nth === 0 ) { defer.resolve( null ); }

Setup and wait

else { array.each( args, function ( p ) { p.then( function () { if ( ++i === nth && !defer.isResolved()) { if ( args.length > 1 ) { defer.resolve( args.map( function ( obj ) { return obj.value || obj.promise.value; })); } else { defer.resolve( args[0].value || args[0].promise.value ); } } }, function () { if ( !defer.isResolved() ) { if ( args.length > 1 ) { defer.reject( args.map( function ( obj ) { return obj.value || obj.promise.value; })); } else { defer.reject( args[0].value || args[0].promise.value ); } } }); }); } return defer; } };