plat4m.bootstrap(function() { var JS = tri4m.lib.loader.Javascript, JSLoader = tri4m.lib.loader.Queue, Bootstrap = new JSLoader({ success : tri4m.compstrap }); Bootstrap.push(new JS({ src : JQUERY_SRC, success : Bootstrap.next })); setTimeout ( function() { typeof jQuery === 'undefined' ? Bootstrap.start() : tri4m.compstrap(); }, JQUERY_INIT_TIME ); }); tri4m.extend ( { lib : { exception : { Throwable : function(name) { var name = name; var constructor = function(message) { //Error.apply(this, arguments); if(this == window) return new arguments.callee(message, level); this.message = message || ''; this.name = name + '.Exception'; }; constructor.name = name || 'tri4m.lib.exception.Throwable'; constructor.prototype.toString = Error.prototype.toString; return constructor; } }, loader : { /** * @param string src * @param object lfo the expected object * @param function onload * @param function callback */ Javascript : function(options) { this.name = 'tri4m.lib.loader.Javascript'; this.Exception = new tri4m.lib.exception.Throwable(this.name); var tried = false; var avail = false; var __settings = tri4m.extend( { src : null, lfo : null, success : null }, options); this.load = function() { if(true === tried) return this; tried = true; if(null === __settings.src) throw new this.Exception('src is null.'); /* NullReferenceError.... if(typeof __settings.lfo !== 'undefined' && __settings.lfo !== null) { tri4m.log('lfo is avail: ' + tri4m.objectToString(__settings.lfo)); avail = true; __settings.callback(this); return this; } */ tri4m.log('Load script ' + __settings.src); try { var head = document.getElementsByTagName('head')[0], script = document.createElement('script'); script.setAttribute('src', __settings.src); script.setAttribute('type', 'text/javascript'); script.setAttribute('charset', 'utf-8'); script.onload = script.onreadstatechange = function() { if(!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete') { script.onload = script.onreadystatechange = null; if(tri4m.isFunction(__settings.success)) __settings.success(__settings); } }; head.insertBefore(script, head.firstChild); } catch(e) { throw new this.Exception('Unable to append javasript ' + __settings.src) } return this; } }, /** * @param string src * @param object lfo the expected object * @param function onload * @param function callback */ Stylesheet : function(options) { this.name = 'tri4m.lib.loader.Stylesheet'; this.Exception = new tri4m.lib.exception.Throwable(this.name); var tried = false; var avail = false; var __settings = tri4m.extend( { src : null, lfo : null, success : null }, options); this.load = function() { if(true === tried) return this; tried = true; if(null === __settings.src) throw new this.Exception('src is null.'); /* NullReferenceError.... if(typeof __settings.lfo !== 'undefined' && __settings.lfo !== null) { tri4m.log('lfo is avail: ' + tri4m.objectToString(__settings.lfo)); avail = true; __settings.callback(this); return this; } */ tri4m.log('Load script ' + __settings.src); try { var head = document.getElementsByTagName('head')[0], script = document.createElement('link'); script.setAttribute('src', __settings.src); script.setAttribute('type', 'text/css'); script.setAttribute('media', 'all'); script.onload = script.onreadstatechange = function() { if(!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete') { script.onload = script.onreadystatechange = null; if(tri4m.isFunction(__settings.success)) __settings.success(__settings); } }; head.insertBefore(script, head.firstChild); } catch(e) { throw new this.Exception('Unable to append stylesheet ' + __settings.src) } return this; } }, /** * Queue-Loader based on Automation-Player * * * var Loader = new tri4m.lib.loader.Queue('Javascript'); * * var myComplete = function() { Loader.next(); alert('whohoo'); } * * Loader.push(new tri4m.lib.loader.Javascript({src : 'swfobject.js', success : Loader.next})) * Loader.push(new tri4m.lib.loader.Javascript({src : 'whoohooo.js', success : myComplete })); * Loader.push(new tri4m.lib.loader.Javascript({src : 'another.js', success : Loader.next })); * Loader.start(); * * * jQuery is ready before we init our plugins: * plat4m.bootstrap(function() * { * var JS = tri4m.lib.loader.Javascript, JSLoader = tri4m.lib.loader.Queue, * Compstrap = new JSLoader, * Bootstrap = new JSLoader({ success: Compstrap.start }); * * Bootstrap.push(new JS({ src : 'http://localfrost/wp-content/plugins/tri4m/jquery.js', success : Bootstrap.next })); * Compstrap.push(new JS({ src : 'http://localfrost/wp-content/plugins/tri4m/tri4mQtLoader/js/tri4m.QtLoader.js' })); * * setTimeout * ( * function() * { * typeof jQuery === 'undefined' * ? Bootstrap.start() * : Compstrap.start(); * } , 200 * ); * }); * * @note calling Loader.next() in File-callback is required * @see ri4m.lib.automation.Player */ Queue : function(options) { var __methods = new tri4m.lib.method.Hook, __player = new tri4m.lib.automation.Player(options); /** * @param tri4m.lib.loader.File File */ this.push = function(File) { __methods.push(File.load); return this; } /** * start */ this.start = function() { __player.setup(__methods).play(); return this; } /** * next */ this.next = function() { __player.next(); return this; } } }, property : { /** * value for value-queue * * overwrite is allowed or not * * @param value mixed * @param protect bool true: can not overwrite existing value */ Value : function(value, protect) { this.name = 'tri4m.lib.property.Value'; this.Exception = new tri4m.lib.exception.Throwable(this.name); var __value = value || null; var __protect = (protect === true) ? true : false; /** * get value * @return mixed */ this.get = function() { return __value; }; /** * set value * * this has no effect, if __protect is true * @return tri4m.lib.property.Value */ this.set = function(value) { if(__protect === true) throw new this.Exception(value + ' is protected', 3); __value = value; return this; }; /** * get variable as object * * @return object */ this.toObject = function() { return { value : __value, protect : __protect }; }; }, /** * value registry * * store vars with values * * // new value-queue * var foo = new tri4m.lib.property.Registry(); * * // var "baz" * foo.register('baz', 'baz: bar'); log.t100(foo.get('baz')); // baz: bar * foo.set('baz', 'baz: bar -> foo'); log.t100(foo.get('baz')); // baz: foo * * // protected var "foo" * foo.register('foo', 'foo: lol', true); log.t100(foo.get('foo')); // foo: lol * foo.set('foo', 'foo: lol -> rofl'); log.t100(foo.get('foo')); // foo: lol */ Registry : function() { this.name = 'tri4m.lib.property.Registry'; this.Exception = new tri4m.lib.exception.Throwable(this.name); var __data = {}; /** * register value-instance * * @param name string instance-name * @param value mixed * @param protect bool true: can not overwrite existing value * @see tri4m.lib.property.Value() * @return tri4m.lib.property.Registry */ this.register = function(name, value, protect) { if(this.isset(name) === true) throw new this.Exception('Unable to register existing property ' + name, 3); __data[name] = new tri4m.lib.property.Value(value, protect); return this; }; /** * unregister value-instance * * @param name string instance-name * @return tri4m.lib.property.Registry */ this.unregister = function(name) { if(this.isset(name) === false) return this; delete _data[name] return this; }; /** * isset instance * * @param name string instance-name * @return bool */ this.isset = function(name) { return (!__data[name]) ? false : true; }; /** * get value of instance * * @param name string instance-name * @see tri4m.lib.property.Value.get() * @return tri4m.lib.property.Value || null */ this.get = function(name) { return ((this.isset(name) === true) ? __data[name].get() : null); }; /** * set value of instance * * you must register your variable at first! * you can not use this registry as garbage dump! * * @param name string instance-name * @param value mixed * @see tri4m.lib.property.Value.set() * @return tri4m.lib.property.Registry */ this.set = function(name, value) { if(false === this.isset(name)) throw new this.Exception('Unable to update value for ' + name + ': not found', 3); try{ __data[name].set(value); } catch(e){ throw new this.Exception('Unable update value for ' + name, 3); } return this; }; /** * get queue as object * * @return tri4m.lib.property.Registry as propertyName:propertyValue object */ this.toObject = function() { var q = {}; for(i in __data) q[i] = __data[i].toObject(); return q; }; /** * get queue as value object * * @return tri4m.lib.property.Registry.__data as propertyValue object */ this.toValueObject = function() { var q = {}; for(i in __data) q[i] = __data[i].toObject().value; return q; }; /** * get queue as property object * * @return tri4m.lib.property.Registry.__data as propertyName object */ this.toPropertyObject = function() { var q = {}; var k = 0; for(i in __data) { q[k] = i; k++; } return q; }; } }, method : { /** * method FIFO * * @param runonce bool true: terminate queue on exec * * // some stuff * var test11 = function(){log.t100('test1.1')}; * var test12 = function(){log.t100('test1.2')}; * * // default queue * var bar = new tri4m.lib.method.Hook; * bar.push(test11).push(test12) * .execute() // test1.1 test1.2 * .execute(); // test1.1 test1.2 * * // run-once queue * var baz = new tri4m.lib.method.Hook(true); * baz.push(test11).push(test12) * .execute() // test1.1 test1.2 * .execute(); // nothing */ Hook : function(runonce) { this.name = 'tri4m.lib.method.Hook'; this.Exception = new tri4m.lib.exception.Throwable(this.name); var __hook = []; var __runonce = (runonce !== true) ? false : true; /** * add function to queue * * @param fn function * @return tri4m.lib.method.Hook */ this.push = function(fn) { __hook.push(fn); return this; }; /** * execute queue * * @return tri4m.lib.method.Hook */ this.execute = function() { if(__hook.length === 0) return this; if(__runonce === false) for(i in __hook) __hook[i](); else while(__hook.length > 0) (__hook.shift())(); return this; }; /** * terminate queue * * @return tri4m.lib.method.Hook */ this.reset = function() { __hook = []; return this; }; /** * get queue as array * * @return tri4m.lib.method.Hook.__hook... imho as copy */ this.toArray = function() { var a = __hook; return a; }; }, /** * method hook registry * * // some stuff * var test11 = function(){log.t100('test1.1')}; * var test12 = function(){log.t100('test1.2')}; * var test21 = function(){log.t100('test2.1')}; * var test22 = function(){log.t100('test2.2')}; * * // create registry queue * var foo = new tri4m.lib.method.Registry(); * * // default queue * foo.register('test1').push('test1', test11).push('test1', test12) * .execute('test1') // test1.1 test1.2 * .execute('test1'); // test1.1 test1.2 * * // run-once queue * foo.register('test2', true).push('test2', test11).push('test2', test12) * .execute('test2') // test2.1 test2.2 * .execute('test2'); // nothing * * * // shorthand: * // default queue * foo.get('test3').push(test21).push(test22) * .execute() // test2.1 test2.2 * .execute(); // test2.1 test2.2 * * // run-once queue * foo.get('test4', true).push(test21).push(test22) * .execute() // test2.1 test2.2 * .execute(); // nothing */ Registry : function() { this.name = 'tri4m.lib.method.Registry'; this.Exception = new tri4m.lib.exception.Throwable(this.name); var __hook = new tri4m.lib.property.Registry(); /** * register queue instance * * @param name string instance-name * @param runonce bool * @see tri4m.lib.method.Hook() * @see tri4m.lib.property.Registry.register() * @return tri4m.lib.method.Registry */ this.register = function(name, runonce) { __hook.register(name, new tri4m.lib.method.Hook(runonce), true); return this; }; /** * isset instance * * @param name string instance-name * @see tri4m.lib.property.Registry.isset() * @return bool tri4m.lib.property.Registry.isset() */ this.isset = function(name) { return __hook.isset(name); }; /** * get/create queue instance * * @param name string instance-name * @param runonce bool * @see tri4m.lib.method.Hook * @return tri4m.lib.method.Hook */ this.get = function(name, runonce) { //log.t100(__hook.get(name).className()); if(this.isset(name) === false) this.register(name, runonce); return __hook.get(name); }; /** * execute queue of instance * * @param name string instance-name * @see tri4m.lib.method.Hook.execute() * @return tri4m.lib.method.Registry */ this.execute = function(name) { if(this.isset(name) === true) this.get(name).execute(); return this; }; /** * terminate queue * * @see tri4m.lib.method.Hook.reset() * @return tri4m.lib.method.Registry */ this.reset = function(name) { if(this.isset(name) === true) this.get(name).reset(); return this; }; /** * add function to queue of instance * * @param name string instance-name * @param fn function * @see tri4m.lib.method.Hook.push() * @return tri4m.lib.method.Registry */ this.push = function(name, fn) { if(this.isset(name) === true) this.get(name).push(fn); return this; }; /** * get queue as object * * @return tri4m.lib.property.Registry.__hook as copy */ this.toObject = function() { return __hook.toObject(); }; /** * get queue as object * * @return tri4m.lib.property.Registry.__hook as copy */ this.getHook = function() { var q = __hook; return q; }; } }, automation : { /** * animation playlist player * * split methods from tri4m.lib.method.Hook * to partials * * @example tri4m.lib.loader.Queue * * * step 1: * create your methods: * * ... * Env : * { * Playlists : null, * Animation : * { * test10 : function(){ * log.t100('test10'); * tri4m('ul.list li').css({height: 5}); * tri4m.Env.Playlists.next('intro'); * }, * test11 : function(){ * log.t100('test11'); * tri4m('ul.list li').animate({height: 140}, 2200, function() * { * log.t100('test11 anim callback'); * tri4m.Env.Playlists.next('intro'); * }); * }, * test12 : function(){ * log.t100('test12'); * tri4m('ul.list li').css({width: 10}); * tri4m.Env.Playlists.next('intro'); * }, * test13 : function(){ * log.t100('test13'); * tri4m('ul.list li').animate({width: 140}, 2200); * tri4m.Env.Playlists.next('intro'); * } * } * }, * ... * * * step 2: * init the animation registry and register * the methods into sections, e.g. "intro" or "button-hover" * * ... * test : function() * { * tri4m.Env.Playlists = * new tri4m.lib.automation.Registry(); * * tri4m.Env.Playlists.register('intro') * .push(tri4m.Env.Animation.test10) * .push(tri4m.Env.Animation.test11) * .push(tri4m.Env.Animation.test12) * .push(tri4m.Env.Animation.test13) * ; * tri4m.Env.Playlists.play('intro'); * }, * ... * * * @todo lock, pause, start, stop not really implemented */ Player : function(options) { this.name = 'tri4m.lib.automation.Player'; this.Exception = new tri4m.lib.exception.Throwable(this.name); var __settings = tri4m.extend( { onPlayStart : tri4m.noop, onPlayNext : tri4m.noop, onPlayPause : tri4m.noop, onPlayStop : tri4m.noop, success : tri4m.noop }, options); /** * method registry queue */ var __registry = null; /** * __isPlaying bool status quo */ var __isPlaying = false; /** * translated registry as func-callback-object */ var __playlist = []; /** * working-copy of __playlist */ var __playqueue = []; /** * counter */ var __playedTimes = 0; /** * install method queue * * @param registry tri4m.lib.method.Hook * @return tri4m.lib.automation.Player */ this.setup = function(registry) { if(__registry !== null) return this; __registry = registry; var methods = __registry.toArray(); for(var i = 0; i < methods.length; i++) { var fn = methods[i]; if(typeof fn !== 'function') continue; var cb = function(){}; if((next = methods[i+1])) { if(typeof next !== 'function') continue; cb = next; } var item = { method: fn, callback : { method : cb } }; __playlist.push(item); } return this; }; /** * init playing * * @return tri4m.lib.automation.Player */ this.play = function() { if(true === this.isPlaying()) return false; if(__playqueue.length === 0) { __playedTimes++; __settings.onPlayStart(); } __isPlaying = true; __playqueue = __playlist; this.next(); return this; }; /** * play next method * * test11 : function(){ * log.t100('test11'); * tri4m('ul.list li').animate({height: 140}, 2200, function() * { * log.t100('test11 anim callback'); * tri4m.Env.Playlists.next('intro'); * }); * }, * * @return tri4m.lib.automation.Player */ this.next = function() { if(null === __playqueue) return this; var next = null; if(__playqueue.length > 0) next = __playqueue.shift(); if(!next) { this.stop(); __settings.success(); return this; } __settings.onPlayNext(); next.method(); return this; }; /** * pause * * @return tri4m.lib.automation.Player */ this.pause = function() { __isPlaying = false; __settings.onPlayPause(); return this; }; /** * stop/abort playing and delete working copy * * @return tri4m.lib.automation.Player */ this.stop = function() { __playqueue = []; __isPlaying = false; __settings.onPlayStop(); return this; }; /** * is playing status * * @return bool status quo */ this.isPlaying = function() { return __isPlaying; }; }, /** * playlist class * * holds a methodhook (playlist) and the player * */ Playlist : function() { this.name = 'tri4m.lib.automation.Playlist'; this.Exception = new tri4m.lib.exception.Throwable(this.name); /** * method queue/playlist */ var __playlist = new tri4m.lib.method.Hook(); /** * player */ var __player = new tri4m.lib.automation.Player(); /** * push method to __playlist * * @param function * @return tri4m.lib.automation.Playlist */ this.push = function(fn) { __playlist.push(fn); return this; }; /** * initialize player and start playing * * @return tri4m.lib.automation.Playlist */ this.play = function() { __player.setup(__playlist).play(); return this; }; /** * play next frame * * this is the callback-caller * * test11 : function(){ * log.t100('test11'); * tri4m('ul.list li').animate({height: 140}, 2200, function() * { * log.t100('test11 anim callback'); * tri4m.Env.Playlists.next('intro'); * }); * }, * * * @return tri4m.lib.automation.Playlist */ this.next = function() { __player.next(); return this; }; }, /** * playlist/player registry * * store animation-queues by event-name * */ Registry : function() { this.name = 'tri4m.lib.automation.Registry'; this.Exception = new tri4m.lib.exception.Throwable(this.name); var __queue = new tri4m.lib.property.Registry(); /** * craete a new playlist-instance * * @param string instance name * @return tri4m.lib.automation.Playlist */ this.register = function(name) { __queue.register(name, new tri4m.lib.automation.Playlist(), true); return __queue.get(name); }; /** * get playlist-instance * * @param string instance name * @return tri4m.lib.automation.Playlist */ this.get = function(name) { return __queue.get(name); }; /** * play a playlist-instance * * @param string instance name * @return tri4m.lib.automation.Registry */ this.play = function(name) { __queue.get(name).play(); return this; }; /** * play next callback * * @param string instance name * @return tri4m.lib.automation.Registry */ this.next = function(name) { __queue.get(name).next(); return this; }; } } } } ); tri4m.extend ( { append : { /** * head: * * (function(tri4m, undefined) * { * tri4m(function() * { * tri4m.append([ * 'plugin.js', * 'another.js' * ], * { * success : function() * { * tri4m.log('-- init my plugin'); * } * }); * }); * })(tri4m); */ Javascript : function(src, options, hold) { var __settings = tri4m.extend ( { success : tri4m.noop }, options ); if(typeof stack === 'undefined') stack = new tri4m.lib.loader.Queue({ success : __settings.success }); if(typeof src !== 'string') { var i = 0, l = src.length; for(var name in src) { i++; tri4m.append.Javascript(src[name], {}, i !== l) } return tri4m.com; } if(typeof cache === 'undefined') cache = []; for(var i in cache) if(src === cache[i]) return tri4m.com; cache.push(src); tri4m.log('append script ' + src); var cur = stack; stack.push(new tri4m.lib.loader.Javascript( { //src : src + '?' + Math.random(0, 100000000), src : src, success : cur.next })); if(!hold || hold !== true) stack.start(); return tri4m; }, Stylesheet : function(src, options, hold) { var __settings = tri4m.extend ( { success : tri4m.noop }, options ); if(typeof stack === 'undefined') stack = new tri4m.lib.loader.Queue({ success : __settings.success }); if(typeof src !== 'string') { var i = 0, l = src.length; for(var name in src) { i++; tri4m.append.Stylesheet(src[name], {}, i !== l) } return tri4m.com; } if(typeof cache === 'undefined') cache = []; for(var i in cache) if(src === cache[i]) return tri4m.com; cache.push(src); tri4m.log('append script ' + src); var cur = stack; stack.push(new tri4m.lib.loader.Stylesheet( { //src : src + '?' + Math.random(0, 100000000), src : src, success : cur.next })); if(!hold || hold !== true) stack.start(); return tri4m; } }