UNPKG

microbejs

Version:

microbe.js - A modular JS library for DOM manipulation, and more

1,514 lines (1,305 loc) 39.9 kB
/*! * Microbe JavaScript Library v0.5.2 * http://m.icro.be * * Copyright 2014-2016 Sociomantic Labs and other contributors * Released under the MIT license * http://m.icro.be/license * * Date: Tue May 03 2016 */ !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.µ=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ /** * ## Microbe * * Builds the Microbe object * * @author Mouse Braun <mouse@knoblau.ch> * @author Nicolas Brugneaux <nicolas.brugneaux@gmail.com> * * @package Microbe */ /*jshint globalstrict: true*/ 'use strict'; var _type = '[object MicrobeRoot]'; var _version = require( './version' ) + '-tool'; var Microbe = { core : {} }; require( './modules/tools' )( Microbe ); require( './modules/pageStyles' )( Microbe ); require( './modules/http' )( Microbe ); Object.defineProperty( Microbe, 'version', { get : function() { return _version; } } ); Object.defineProperty( Microbe, 'type', { get : function() { return _type; } } ); module.exports = Microbe; },{"./modules/http":9,"./modules/pageStyles":10,"./modules/tools":11,"./version":13}],2:[function(require,module,exports){ (function (process){ // Use the fastest possible means to execute a task in a future turn // of the event loop. // linked list of tasks (single, with head node) var head = {task: void 0, next: null}; var tail = head; var flushing = false; var requestFlush = void 0; var isNodeJS = false; function flush() { /* jshint loopfunc: true */ while (head.next) { head = head.next; var task = head.task; head.task = void 0; var domain = head.domain; if (domain) { head.domain = void 0; domain.enter(); } try { task(); } catch (e) { if (isNodeJS) { // In node, uncaught exceptions are considered fatal errors. // Re-throw them synchronously to interrupt flushing! // Ensure continuation if the uncaught exception is suppressed // listening "uncaughtException" events (as domains does). // Continue in next event to avoid tick recursion. if (domain) { domain.exit(); } setTimeout(flush, 0); if (domain) { domain.enter(); } throw e; } else { // In browsers, uncaught exceptions are not fatal. // Re-throw them asynchronously to avoid slow-downs. setTimeout(function() { throw e; }, 0); } } if (domain) { domain.exit(); } } flushing = false; } if (typeof process !== "undefined" && process.nextTick) { // Node.js before 0.9. Note that some fake-Node environments, like the // Mocha test runner, introduce a `process` global without a `nextTick`. isNodeJS = true; requestFlush = function () { process.nextTick(flush); }; } else if (typeof setImmediate === "function") { // In IE10, Node.js 0.9+, or https://github.com/NobleJS/setImmediate if (typeof window !== "undefined") { requestFlush = setImmediate.bind(window, flush); } else { requestFlush = function () { setImmediate(flush); }; } } else if (typeof MessageChannel !== "undefined") { // modern browsers // http://www.nonblocking.io/2011/06/windownexttick.html var channel = new MessageChannel(); channel.port1.onmessage = flush; requestFlush = function () { channel.port2.postMessage(0); }; } else { // old browsers requestFlush = function () { setTimeout(flush, 0); }; } function asap(task) { tail = tail.next = { task: task, domain: isNodeJS && process.domain, next: null }; if (!flushing) { flushing = true; requestFlush(); } }; module.exports = asap; }).call(this,require('_process')) },{"_process":3}],3:[function(require,module,exports){ // shim for using process in browser var process = module.exports = {}; process.nextTick = (function () { var canSetImmediate = typeof window !== 'undefined' && window.setImmediate; var canPost = typeof window !== 'undefined' && window.postMessage && window.addEventListener ; if (canSetImmediate) { return function (f) { return window.setImmediate(f) }; } if (canPost) { var queue = []; window.addEventListener('message', function (ev) { var source = ev.source; if ((source === window || source === null) && ev.data === 'process-tick') { ev.stopPropagation(); if (queue.length > 0) { var fn = queue.shift(); fn(); } } }, true); return function nextTick(fn) { queue.push(fn); window.postMessage('process-tick', '*'); }; } return function nextTick(fn) { setTimeout(fn, 0); }; })(); process.title = 'browser'; process.browser = true; process.env = {}; process.argv = []; function noop() {} process.on = noop; process.addListener = noop; process.once = noop; process.off = noop; process.removeListener = noop; process.removeAllListeners = noop; process.emit = noop; process.binding = function (name) { throw new Error('process.binding is not supported'); } // TODO(shtylman) process.cwd = function () { return '/' }; process.chdir = function (dir) { throw new Error('process.chdir is not supported'); }; },{}],4:[function(require,module,exports){ 'use strict'; module.exports = require('./lib/core.js') require('./lib/done.js') require('./lib/es6-extensions.js') require('./lib/node-extensions.js') },{"./lib/core.js":5,"./lib/done.js":6,"./lib/es6-extensions.js":7,"./lib/node-extensions.js":8}],5:[function(require,module,exports){ 'use strict'; var asap = require('asap') module.exports = Promise; function Promise(fn) { if (typeof this !== 'object') throw new TypeError('Promises must be constructed via new') if (typeof fn !== 'function') throw new TypeError('not a function') var state = null var value = null var deferreds = [] var self = this this.then = function(onFulfilled, onRejected) { return new self.constructor(function(resolve, reject) { handle(new Handler(onFulfilled, onRejected, resolve, reject)) }) } function handle(deferred) { if (state === null) { deferreds.push(deferred) return } asap(function() { var cb = state ? deferred.onFulfilled : deferred.onRejected if (cb === null) { (state ? deferred.resolve : deferred.reject)(value) return } var ret try { ret = cb(value) } catch (e) { deferred.reject(e) return } deferred.resolve(ret) }) } function resolve(newValue) { try { //Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure if (newValue === self) throw new TypeError('A promise cannot be resolved with itself.') if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) { var then = newValue.then if (typeof then === 'function') { doResolve(then.bind(newValue), resolve, reject) return } } state = true value = newValue finale() } catch (e) { reject(e) } } function reject(newValue) { state = false value = newValue finale() } function finale() { for (var i = 0, len = deferreds.length; i < len; i++) handle(deferreds[i]) deferreds = null } doResolve(fn, resolve, reject) } function Handler(onFulfilled, onRejected, resolve, reject){ this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null this.onRejected = typeof onRejected === 'function' ? onRejected : null this.resolve = resolve this.reject = reject } /** * Take a potentially misbehaving resolver function and make sure * onFulfilled and onRejected are only called once. * * Makes no guarantees about asynchrony. */ function doResolve(fn, onFulfilled, onRejected) { var done = false; try { fn(function (value) { if (done) return done = true onFulfilled(value) }, function (reason) { if (done) return done = true onRejected(reason) }) } catch (ex) { if (done) return done = true onRejected(ex) } } },{"asap":2}],6:[function(require,module,exports){ 'use strict'; var Promise = require('./core.js') var asap = require('asap') module.exports = Promise Promise.prototype.done = function (onFulfilled, onRejected) { var self = arguments.length ? this.then.apply(this, arguments) : this self.then(null, function (err) { asap(function () { throw err }) }) } },{"./core.js":5,"asap":2}],7:[function(require,module,exports){ 'use strict'; //This file contains the ES6 extensions to the core Promises/A+ API var Promise = require('./core.js') var asap = require('asap') module.exports = Promise /* Static Functions */ function ValuePromise(value) { this.then = function (onFulfilled) { if (typeof onFulfilled !== 'function') return this return new Promise(function (resolve, reject) { asap(function () { try { resolve(onFulfilled(value)) } catch (ex) { reject(ex); } }) }) } } ValuePromise.prototype = Promise.prototype var TRUE = new ValuePromise(true) var FALSE = new ValuePromise(false) var NULL = new ValuePromise(null) var UNDEFINED = new ValuePromise(undefined) var ZERO = new ValuePromise(0) var EMPTYSTRING = new ValuePromise('') Promise.resolve = function (value) { if (value instanceof Promise) return value if (value === null) return NULL if (value === undefined) return UNDEFINED if (value === true) return TRUE if (value === false) return FALSE if (value === 0) return ZERO if (value === '') return EMPTYSTRING if (typeof value === 'object' || typeof value === 'function') { try { var then = value.then if (typeof then === 'function') { return new Promise(then.bind(value)) } } catch (ex) { return new Promise(function (resolve, reject) { reject(ex) }) } } return new ValuePromise(value) } Promise.all = function (arr) { var args = Array.prototype.slice.call(arr) return new Promise(function (resolve, reject) { if (args.length === 0) return resolve([]) var remaining = args.length function res(i, val) { try { if (val && (typeof val === 'object' || typeof val === 'function')) { var then = val.then if (typeof then === 'function') { then.call(val, function (val) { res(i, val) }, reject) return } } args[i] = val if (--remaining === 0) { resolve(args); } } catch (ex) { reject(ex) } } for (var i = 0; i < args.length; i++) { res(i, args[i]) } }) } Promise.reject = function (value) { return new Promise(function (resolve, reject) { reject(value); }); } Promise.race = function (values) { return new Promise(function (resolve, reject) { values.forEach(function(value){ Promise.resolve(value).then(resolve, reject); }) }); } /* Prototype Methods */ Promise.prototype['catch'] = function (onRejected) { return this.then(null, onRejected); } },{"./core.js":5,"asap":2}],8:[function(require,module,exports){ 'use strict'; //This file contains then/promise specific extensions that are only useful for node.js interop var Promise = require('./core.js') var asap = require('asap') module.exports = Promise /* Static Functions */ Promise.denodeify = function (fn, argumentCount) { argumentCount = argumentCount || Infinity return function () { var self = this var args = Array.prototype.slice.call(arguments) return new Promise(function (resolve, reject) { while (args.length && args.length > argumentCount) { args.pop() } args.push(function (err, res) { if (err) reject(err) else resolve(res) }) var res = fn.apply(self, args) if (res && (typeof res === 'object' || typeof res === 'function') && typeof res.then === 'function') { resolve(res) } }) } } Promise.nodeify = function (fn) { return function () { var args = Array.prototype.slice.call(arguments) var callback = typeof args[args.length - 1] === 'function' ? args.pop() : null var ctx = this try { return fn.apply(this, arguments).nodeify(callback, ctx) } catch (ex) { if (callback === null || typeof callback == 'undefined') { return new Promise(function (resolve, reject) { reject(ex) }) } else { asap(function () { callback.call(ctx, ex) }) } } } } Promise.prototype.nodeify = function (callback, ctx) { if (typeof callback != 'function') return this this.then(function (value) { asap(function () { callback.call(ctx, null, value) }) }, function (err) { asap(function () { callback.call(ctx, err) }) }) } },{"./core.js":5,"asap":2}],9:[function(require,module,exports){ /** * http.js * * @author Mouse Braun <mouse@knoblau.ch> * @author Nicolas Brugneaux <nicolas.brugneaux@gmail.com> * * @package Microbe */ module.exports = function( Microbe ) { 'use strict'; var Promise = require( 'promise' ); /** * ## http * * Method takes as many as necessary parameters, with url being the only required. * The return then has the methods `.then( _cb )` and `.error( _cb )` * * @param {Object} _parameters http parameters. possible properties * method, url, data, user, password, headers, async * * @example µ.http( {url: './test.html', method: 'POST', data: { number: 67867} } ).then( function(){} ).catch( function(){} ); */ Microbe.http = function( _parameters ) { var req, method, url, data, user, password, headers, async; if ( !_parameters ) { return new Error( 'No parameters given' ); } else { if ( typeof _parameters === 'string' ) { _parameters = { url: _parameters }; } req = new XMLHttpRequest(); method = _parameters.method || 'GET'; url = _parameters.url; data = JSON.stringify( _parameters.data ) || null; user = _parameters.user || ''; password = _parameters.password || ''; headers = _parameters.headers || null; async = typeof _parameters.async === "boolean" ? _parameters.async : true; req.onreadystatechange = function() { if ( req.readyState === 4 ) { return req; } }; } req.open( method, url, async, user, password ); // weird Safari voodoo fix if ( method === 'POST' ) { req.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' ); } if ( headers ) { for ( var header in headers ) { req.setRequestHeader( header, headers[header] ); } } if ( async ) { return new Promise( function( resolve, reject ) { req.onerror = function() { reject( new Error( 'Network error!' ) ); }; req.send( data ); req.onload = function() { if ( req.status === 200 ) { resolve( req.response ); } else { reject( new Error( req.status ) ); } }; }); } else { var _response = function( _val ) { var _responses = { /** * ## .then * * Called after `http`, `http.get`, or `http.post`, this is * called passing the result as the first parameter to the callback * * @param {Function} _cb function to call after http request * * @return _Object_ contains the `.catch` method */ then: function( _cb ) { if ( _val.status === 200 ) { _cb( _val.responseText ); } return _responses; }, /** * ## .catch * * Called after `http`, `http.get`, or `http.post`, this is * called passing the error as the first parameter to the callback * * @param {Function} _cb function to call after http request * * @return _Object_ contains the `.then` method */ catch: function( _cb ) { if ( _val.status !== 200 ) { _cb( { status : _val.status, statusText : _val.statusText } ); } return _responses; } }; return _responses; }; req.send( data ); req.onloadend = function() { req.onreadystatechange(); return _response( req ); }; return req.onloadend(); } }; /** * ## http.get * * Syntactic shortcut for simple GET requests * * @param {String} _url file url * * @example µ.http.get( './test.html' ).then( function(){} ).catch( function(){} ); * * @return _Object_ contains `.then` and `.catch` */ Microbe.http.get = function( _url ) { return this( { url : _url, method : 'GET' } ); }; /** * ## http.post * * Syntactic shortcut for simple POST requests * * @param {String} _url file url * @param {Mixed} _data data to post to location {Object or String} * * @example µ.http.post( './test.html', { number: 67867} ).then( function(){} ).catch( function(){} ); * * @return _Object_ contains `.then` and `.catch` */ Microbe.http.post = function( _url, _data ) { return this( { url : _url, data : _data, method : 'POST' } ); }; }; },{"promise":4}],10:[function(require,module,exports){ /** * pageStyles.js * * @author Mouse Braun <mouse@knoblau.ch> * @author Nicolas Brugneaux <nicolas.brugneaux@gmail.com> * * @package Microbe */ module.exports = function( Microbe ) { 'use strict'; /** * ## insertStyle * * builds a style tag for the given selector/ media query. Reference to the style * tag and object is saved in µ.__customCSSRules[ selector ][ media ]. * next rule with the same selector combines the old and new rules and overwrites * the contents * * @param {String} selector selector to apply it to * @param {Mixed} cssObj css object. _{String or Object}_ * @param {String} media media query * * @example µ.insertStyle( '.example', { display: 'block', color: '#000' } ); * @example µ.insertStyle( '.example', { display: 'block', color: '#000' }, 'min-width: 61.25em' ); * * @return _Object_ reference to the appropriate style object */ Microbe.insertStyle = function( selector, cssObj, media ) { var _s = selector.replace( / /g, '-' ); var _clss = media ? _s + media.replace( /[\s:\/\[\]\(\)]+/g, '-' ) : _s; media = media || 'none'; var createStyleTag = function() { var el = document.createElement( 'style' ); el.className = 'microbe--inserted--style__' + _clss; if ( media && media !== 'none' ) { el.setAttribute( 'media', media ); } document.head.appendChild( el ); return el; }; var _el, prop; var styleObj = Microbe.__customCSSRules[ _s ]; if ( styleObj && styleObj[ media ] ) { _el = styleObj[ media ].el; var obj = styleObj[ media ].obj; for ( prop in cssObj ) { obj[ prop ] = cssObj[ prop ]; } cssObj = obj; } else { _el = createStyleTag(); } var css = selector + '{'; for ( prop in cssObj ) { css += prop + ' : ' + cssObj[ prop ] + ';'; } css += '}'; _el.innerHTML = css; Microbe.__customCSSRules[ _s ] = Microbe.__customCSSRules[ _s ] || {}; Microbe.__customCSSRules[ _s ][ media ] = { el: _el, obj: cssObj }; return _el; }; // keep track of tags created with insertStyle Microbe.__customCSSRules = {}; /** * ## removeStyle * * removes a microbe added style tag for the given selector/ media query. If the * properties array is passed, rules are removed individually. If properties is * set to true, all tags for this selector are removed. The media query can * also be passed as the second variable * * @param {String} selector selector to apply it to * @param {Mixed} properties css properties to remove 'all' to remove all * selector tags string as media query {String or Array} * @param {String} media media query * * @example µ.removeStyle( '.example', 'all' ); * @example µ.removeStyle( '.example', 'display' ); * @example µ.removeStyle( '.example', [ 'display', 'color' ], 'min-width:70em' ); * * @return _Boolean_ removed or not */ Microbe.removeStyle = function( selector, properties, media ) { if ( !media && typeof properties === 'string' && properties !== 'all' ) { media = properties; properties = null; } media = media || 'none'; var _removeStyle = function( _el, _media ) { _el.parentNode.removeChild( _el ); delete Microbe.__customCSSRules[ selector ][ _media ]; }; var style = Microbe.__customCSSRules[ selector ]; if ( style ) { if ( properties === 'all' ) { for ( var _mq in style ) { _removeStyle( style[ _mq ].el, _mq ); } } else { style = style[ media ]; if ( style ) { if ( Microbe.isArray( properties ) && !Microbe.isEmpty( properties ) ) { for ( var i = 0, lenI = properties.length; i < lenI; i++ ) { if ( style.obj[ properties[ i ] ] ) { delete style.obj[ properties[ i ] ]; } } if ( Microbe.isEmpty( style.obj ) ) { _removeStyle( style.el, media ); } else { Microbe.insertStyle( selector, style.obj, media ); } } else { _removeStyle( style.el, media ); } } else { return false; } } } else { return false; } return true; }; /** * ## removeStyles * * removes all microbe added style tags for the given selector * * @param {String} selector selector to apply it to * * @example µ.removeStyle( '.example' ); * * @return _Boolean_ removed or not */ Microbe.removeStyles = function( selector ) { return Microbe.removeStyle( selector, 'all' ); }; }; },{}],11:[function(require,module,exports){ /** * root.js * * @author Mouse Braun <mouse@knoblau.ch> * @author Nicolas Brugneaux <nicolas.brugneaux@gmail.com> * * @package Microbe */ module.exports = function( Microbe ) { 'use strict'; window.Promise = window.Promise || require( 'promise' ); var Types = require( './types' ); /** * ## capitalize * * capitalizes every word in a string or an array of strings and returns the * type that it was given * * @param {Mixed} text string(s) to capitalize _{String or Array}_ * * @example µ.capitalize( 'moon doge' ); // "Moon Doge" * * @return _Mixed_ capitalized string(s) values _{String or Array}_ */ Microbe.capitalize = function( text ) { var array = Microbe.isArray( text ); text = !array ? [ text ] : text; var str, res = []; for ( var i = 0, lenI = text.length; i < lenI; i++ ) { str = text[ i ].split( ' ' ); for ( var j = 0, lenJ = str.length; j < lenJ; j++ ) { str[ j ] = str[ j ][ 0 ].toUpperCase() + str[ j ].slice( 1 ); } res.push( str.join( ' ' ) ); } return ( array ) ? res : res[ 0 ]; }; /** * ## capitalise * * british people.... * * @example µ.capitalise( 'moon doge' ); // "Moon Doge" */ Microbe.capitalise = Microbe.capitalize; /** * ## debounce * * Returns a function, that, as long as it continues to be invoked, will not * be triggered. The function will be called after it stops being called for * [[wait]] milliseconds. If `immediate` is passed, trigger the function on * the leading edge, instead of the trailing. * * @param {Function} _func function to meter * @param {Number} wait milliseconds to wait * @param {Boolean} immediate run function at the start of the timeout * * @example µ.debounce( function(){ return Date.now(); }, 250 ); * @example µ.debounce( function(){ return Date.now(); }, 250, true ); * * @return _Function_ */ Microbe.debounce = function( _func, wait, immediate ) { var timeout; return function() { var self = this, args = arguments; var later = function() { timeout = null; if ( !immediate ) { _func.apply( self, args ); } }; var callNow = immediate && !timeout; clearTimeout( timeout ); timeout = setTimeout( later, wait ); if ( callNow ) { _func.apply( self, args ); } }; }; /** * ## extend * * Extends an object or microbe * * @example µ.extend( { a: 1, b: 2 }, { c: 3, d: 4 } ); * * @return _Object_ reference to this (microbe) or the first * object passed (root) */ Microbe.extend = function() { var µIsObject = Microbe.isObject; var µIsArray = Microbe.isArray; var res = arguments[ 0 ] || {}; var i = 1; var length = arguments.length; var deep = false; if ( typeof res === 'boolean' ) { deep = res; res = arguments[ i ] || {}; i++; } if ( typeof res !== 'object' && !Microbe.isFunction( res ) ) { res = {}; } if ( i === length ) { res = this; i--; } var _object, _p, src, copy, isArray, clone; for ( ; i < length; i++ ) { _object = arguments[ i ]; if ( _object !== null && _object !== undefined ) { for ( _p in _object ) { src = res[ _p ]; copy = _object[ _p ]; if ( res === copy ) { continue; } if ( deep && copy && ( µIsObject( copy ) || ( isArray = µIsArray( copy ) ) ) ) { if ( isArray ) { isArray = false; clone = src && µIsArray( src ) ? src : []; } else { clone = src && µIsObject( src ) ? src : {}; } res[ _p ] = Microbe.extend( deep, clone, copy ); } else if ( copy !== undefined ) { res[ _p ] = copy; } } } } return res; }; /** * mounts extend to the core * * @example µ( '.example' ).extend( { c: 3, d: 4 } ); */ Microbe.core.extend = Microbe.extend; /** * ## identity * * returns itself. useful in functional programmnig when a function must be executed * * @param {any} value any value * * @example µ.identity( 'moon' ); // 'moon' * * @return _any_ */ Microbe.identity = function( value ) { return value; }; /** * ## isArray * * native isArray for completeness * * @example µ.isArray( [ 1, 2, 3 ] ); // true * * @type _Function_ */ Microbe.isArray = Array.isArray; /** * ## isEmpty * * Checks if the passed object is empty * * @param {Object} obj object to check * * @example µ.isEmpty( {} ); // true * * @return _Boolean_ empty or not */ Microbe.isEmpty = function( obj ) { var name; for ( name in obj ) { return false; } return true; }; /** * ## isFunction * * Checks if the passed parameter is a function * * @param {Object} obj object to check * * @example µ.isFunction( function(){} ); // true * * @return _Boolean_ function or not */ Microbe.isFunction = function( obj ) { return Microbe.type( obj ) === "function"; }; /** * ## isObject * * Checks if the passed parameter is an object * * @param {Object} obj object to check * * @example µ.isObject( {} ); // true * * @return _Boolean_ isObject or not */ Microbe.isObject = function( obj ) { if ( Microbe.type( obj ) !== "object" || obj.nodeType || Microbe.isWindow( obj ) ) { return false; } return true; }; /** * ## isUndefined * * Checks if the passed parameter is undefined * * @param {String} obj property * @param {Object} parent object to check * * @example µ.isUndefined( {} ); // false * * @return _Boolean_ obj in parent */ Microbe.isUndefined = function( obj, parent ) { if ( parent && typeof parent !== 'object' ) { return true; } return parent ? !( obj in parent ) : obj === void 0; }; /** * ## isWindow * * Checks if the passed parameter equals window * * @param {Object} obj object to check * * @example µ.isWindow( window ); // true * * @return _Boolean_ isWindow or not */ Microbe.isWindow = function( obj ) { return obj !== null && obj === obj.window; }; /** * ## merge * * Combines microbes, arrays, and/or array-like objects. * * @param {Mixed} first first object _{Array-like Object or Array}_ * @param {Mixed} second second object _{Array-like Object or Array}_ * * @example µ.merge( [ 1, 2 ], [ 2, 3, 4 ] ); // [ 1, 2, 2, 3, 4 ] * @example µ.merge( [ 1, 2 ], [ 2, 3, 4 ], true );// [ 1, 2, 3, 4 ] * * @return _Mixed_ combined array or array-like object (based off first) */ Microbe.merge = function( first, second, unique ) { if ( typeof second === 'boolean' ) { unique = second; second = null; } if ( !second ) { second = first; first = this; } var i = first.length; if ( typeof i === 'number' ) { for ( var j = 0, len = second.length; j < len; j++ ) { if ( !unique || first.indexOf( second[ j ] ) === -1 ) { first[ i++ ] = second[ j ]; } } first.length = i; } return first; }; Microbe.core.merge = Microbe.merge; /** * ## noop * * Nothing happens * * https://en.wikipedia.org/wiki/Xyzzy_(computing) * * @example µ.noop() * * @return _void_ */ Microbe.noop = function() {}; /** * ## once * * returns a function that can only be run once * * @param {Function} _func function to run once * * @example µ.once( function( a ){ return 1 + 1; } ); * * @return _Function_ */ Microbe.once = function( _func, self ) { var result; return function() { if( _func ) { result = _func.apply( self || this, arguments ); _func = null; } return result; }; }; /** * ## poll * * checks a passed function for true every [[interval]] milliseconds. when * true, it will run _success, if [[timeout[[]] is reached without a success, * _error is excecuted * * @param {Function} _func function to check for true * @param {Function} _success function to run on success * @param {Function} _error function to run on error * @param {Number} timeout time (in ms) to stop polling * @param {Number} interval time (in ms) in between polling * * @example µ.poll( function( a ){ return a === 2; }, * function( a ){ console.log( 'a === 2' ); }, * function( a ){ console.log( 'a !== 2' ); } ); * @example µ.poll( function( a ){ return a === 2; }, * function( a ){ console.log( 'a === 2' ); }, * function( a ){ console.log( 'a !== 2' ); }, * 200, 10000 ); * * @return _Function_ */ Microbe.poll = function( _func, _success, _error, timeout, interval ) { var endTime = Number( new Date() ) + ( timeout || 2000 ); interval = interval || 100; ( function p() { if ( _func() ) { try { _success(); } catch( e ) { throw 'No argument given for success function'; } } else if ( Number( new Date() ) < endTime ) { setTimeout( p, interval ); } else { try { _error( new Error( 'timed out for ' + _func + ': ' + arguments ) ); } catch( e ) { throw 'No argument given for error function.'; } } } )(); }; /** * ## toArray * * Methods returns all the elements in an array. * * @example µ.toArray( µ( 'div' ) ); * * @return _Array_ */ Microbe.toArray = function( _arr ) { return Array.prototype.slice.call( _arr || this ); }; /** * attaches toArray to core * * @example µ( 'div' ).toArray(); */ Microbe.core.toArray = Microbe.toArray; /** * ## type * * returns the type of the parameter passed to it * * @param {all} obj parameter to test * * @example µ.type( 'moon' ); // 'string' * @example µ.type( [ 'moon' ] ); // 'array' * * @return _String_ typeof obj */ Microbe.type = function( obj ) { if ( obj === null ) { return obj + ''; } var type = Types[ Object.prototype.toString.call( obj ) ]; type = !type ? Types[ obj.toString() ] : type; type = type || typeof obj; if ( type === 'object' && obj instanceof Promise ) { type = 'promise'; } return type; }; /** * ## xyzzy * * nothing happens * * https://en.wikipedia.org/wiki/Xyzzy_(computing) * * @example µ.xyzzy(); * * @return _void_ */ Microbe.xyzzy = Microbe.noop; }; },{"./types":12,"promise":4}],12:[function(require,module,exports){ /** * types.js * * @author Mouse Braun <mouse@knoblau.ch> * @author Nicolas Brugneaux <nicolas.brugneaux@gmail.com> * * @package Microbe */ /*jshint globalstrict: true*/ 'use strict'; module.exports = { '[object Number]' : 'number', '[object String]' : 'string', '[object Function]' : 'function', '[object Array]' : 'array', '[object Date]' : 'date', '[object RegExp]' : 'regExp', '[object Error]' : 'error', '[object Promise]' : 'promise', '[object Microbe]' : 'microbe' }; },{}],13:[function(require,module,exports){ module.exports = '0.5.2'; },{}]},{},[1])(1) });