Skip to content

Instantly share code, notes, and snippets.

@Raynos
Created December 2, 2011 15:37
Show Gist options
  • Save Raynos/1423661 to your computer and use it in GitHub Desktop.
Save Raynos/1423661 to your computer and use it in GitHub Desktop.
"use strict";
var win = window,
doc = window.doc,
$ = jQuery,
undef;
/****** BASE LIBRARY ABSTRACTIONS ## JQUERY 1.7.0 ******** *******/
/****** ************************************************** *******/
var storageObject = { },
buffer = { },
Public = {},
access = App.name || 'BarFoos';
if( Object.type( win.localStorage ) === 'Storage' ) {
storageObject = win.localStorage;
}
else {
// TODO: read cookie into storageObject
}
if( storageObject[ access ] ) {
buffer = win.JSON.parse( storageObject[ access ] );
}
Public.data = function _data( elem, key, value ) {
var rVal = $.data( elem, key, value );
return value ? this : rVal;
};
Public.removeData = function _removeData( elem, key ) {
$.removeData( elem, key );
return Public;
};
Public.hasData = function _hasData( elem ) {
return $.hasData( elem );
};
Public.lsWrite = function _lsWrite( key, value ) {
buffer[ key ] = value;
return Public;
};
Public.lsRead = function _lsRead( key ) {
return buffer[ key ];
};
Public.lsRemove = function _lsRemove( key ) {
delete buffer[ key ];
return Public;
};
Public.lsStore = function _lsStore() {
storageObject[ access ] = win.JSON.stringify( buffer );
return Public;
};
Public.lsClear = function _clear() {
buffer = { };
storageObject[ access ] = null;
return Public;
};
$( win ).bind( 'beforeunload', function _beforeUnload() {
Public.lsStore();
});
module.exports = Public;
/**
* Javascript Application Core (Layer 1)
* -----------------------------------------
* The core is the only part from the application which has direct access to the base library.
* Any access to the base library (from a Module) is marshaled down through the Sandbox.
* Furthermore, the Core is responsible for Module lifecycles, communication between modules,
* error handling and extensions.
*
* -----------------------------------------
* Author: Andreas Goebel
* Date: 2011-03-17
* Changed: 2011-11-30 - loadModule is now IE compliant
*/
"use strict";
var win = window,
doc = win.document,
$ = jQuery,
undef;
var moduleData = { },
Public = { },
Private = { },
Application = { },
Sandbox = function Sandbox() { };
/****** CORE SPECIFIC METHODS (MODULE LIFECYCLE, SANDBOX) *******/
/****** ************************************************** *******/
Public.registerApplication = function _registerApplication( app ) {
if( Object.type( app ) === 'Object' ) {
Application = app;
Object.freeze( Public );
if( 'environment' in Application ) {
$.extend( Private, Application.environment );
}
}
else {
Public.error({
type: 'type',
origin: 'Core',
name: '_registerApplication',
msg: 'object was expected, received ' + win.getLastError() + ' instead'
});
}
return Public;
};
Public.registerSandbox = function _registerSandbox( sandbox ) {
if( typeof sandbox === 'function' ) {
Sandbox = sandbox;
}
else {
Public.error({
type: 'type',
origin: 'Core',
name: '_registerSandbox',
msg: 'function was expected, received ' + win.getLastError() + ' instead'
});
}
return Public;
};
Public.registerModule = function _registerModule( moduleID, creator ) {
if( Object.type( moduleID ) === 'String' ) {
if( !(moduleID in moduleData) ) {
moduleData[ moduleID ] = {
creator: creator || Public.loadModule( moduleID ),
instances: [ ]
};
}
else {
Public.error({
type: 'custom',
origin: 'Core',
name: '_registerModule',
msg: 'Module name "' + moduleID + '" already registered'
});
}
return Public;
}
else {
Public.error({
type: 'type',
origin: 'Core',
name: '_registerModule',
msg: 'string expected, received ' + win.getLastError() + ' instead'
});
}
return Public;
};
Public.loadModule = function _loadModule( moduleID ) {
if( Object.type( moduleID ) === 'String' ) {
var scr = doc.createElement( 'script' ),
head = doc.head || doc.getElementsByTagName( 'head' )[ 0 ] || doc.documentElement;
return $.Deferred( function _createDeferred( promise ) {
scr.onload = scr.onreadystatechange = function _onload() {
if( !scr.readyState || /complete|loaded/.test( scr.readyState ) ) {
scr.onload = scr.onreadystatechange = null;
scr = undef;
promise.resolve( moduleID, Modules[ moduleID ] );
}
};
scr.onerror = function _onerror( err ) {
promise.reject( moduleID, err );
};
scr.type = 'text/javascript';
scr.async = true;
scr.defer = true;
scr.src = Private.modulePath + Private.modulePrefix + moduleID.toLowerCase() + '.js';
head.insertBefore( scr, head.firstChild );
}).promise();
}
else {
Public.error({
type: 'type',
origin: 'Core',
name: '_loadModule',
msg: 'string was expected, received ' + getLastError() + ' instead'
});
}
};
Public.start = function _start( moduleID, args ) {
if( moduleID in moduleData ) {
var data = moduleData[ moduleID ],
args = args || { },
instances = data.instances,
initResult = null;
$.extend( args, {
moduleID: moduleID,
moduleIndex: instances.length,
moduleKey: ++Private.globalModuleKey
});
try {
if( instances && instances.length ) {
if( data.multipleInstances ) {
instances.push( data.creator( Sandbox( this ), Application, args ) );
instances.slice( -1 )[ 0 ].moduleKey = Private.globalModuleKey;
initResult = instances.slice( -1 )[ 0 ].init();
if( initResult === -1 ) {
Public.stop( moduleID, instances.slice( -1 )[ 0 ].moduleKey );
}
}
else {
throw new Error( 'Module "' + moduleID + '" does not allow multiple instances' );
}
}
else {
$.when( data.creator ).then(function _done( moduleName, moduleCreator ) {
data.creator = moduleCreator || data.creator;
instances.push( data.creator( Sandbox( Core ), Application, args ) );
instances[ 0 ].moduleKey = Private.globalModuleKey;
initResult = instances[ 0 ].init();
data.multipleInstances = instances[ 0 ].multipleInstances;
if( initResult === -1 ) {
Public.stop( moduleID, instances[ 0 ].moduleKey );
}
}, function _fail( moduleName, err ) {
// TODO: I did not decide what to do here. Try reloading the module ? Throw ? Warn?
});
}
} catch( ex ) {
Public.error({
type: 'Unknown',
origin: 'Core',
name: '_start',
msg: 'unable to load module "' + moduleID + '". Error was: ' + ex.message + '\n\n' + 'Stacktrace:\n' + Private.formatStacktrace( ex.stack || ex.stacktrace )
});
}
}
return Public;
};
Public.stop = function _stop( moduleID, key ) {
if( moduleID in moduleData ) {
var data = moduleData[ moduleID ],
mIndex = -1;
try {
if( data.instances && data.instances.length ) {
if( key === undef ) {
data.instances.forEach(function _forEach( inst ) {
inst.flaggedForRemoval = true; // flag the Modules "Public" object so it has a chance to skip/cancel running requests
inst.destroy();
inst = null;
});
data.instances = [ ];
}
else {
data.instances.some(function _some( inst, index ) {
if( inst.moduleKey === key ) {
mIndex = index;
inst.destroy();
inst = null;
return true;
}
});
if( mIndex > -1 ) {
data.instances.splice( mIndex, 1 );
}
}
}
} catch( ex ) {
Public.error({
type: 'Unknown',
origin: 'Core',
name: '_stop',
msg: 'unable to unload module "' + moduleID + '". Error was: ' + ex.message + '\n\n' + 'Stacktrace: ' + Private.formatStacktrace( ex.stack || ex.stacktrace )
});
}
}
return Public;
};
Public.startAll = function _startAll() {
Object.keys( moduleData ).forEach(function _forEach( moduleID ) {
Public.start( moduleID );
});
return Public;
};
Public.stopAll = function _stopAll() {
Object.keys( moduleData ).forEach(function _forEach( moduleID ) {
Public.stop( moduleID );
});
return Public;
};
Public.error = function _error( err ) {
if( Object.type( err ) === 'Object' ) {
if( typeof err.type === 'string' ) {
var output = '\nApplication error\n\n' + 'Origin: ' + (err.origin || 'General') + '\n' + 'Calling context: ' + (err.name || 'Unknown') + '\n' + 'Message: ' + (err.msg || '');
// backup output. If for some reason the base library lays an outer try/catch around a handler, we've lost our chance to bubble our error
win[ 'console' ].group('App Failure');
win[ 'console' ].info( output );
win[ 'console' ].groupEnd('App Failure');
switch( err.type.toLowerCase() ) {
case 'type':
throw new TypeError( output );
case 'reference':
throw new ReferenceError( output );
case 'syntax':
throw new SyntaxError( output );
default:
throw new Error( err.type + output );
}
}
else {
throw new TypeError( 'Core: error(). String expected - received "' + win.getLastError() + '" instead.' );
}
}
return Public;
};
/*^^^^^ ^^^^^^^^^^^^^^^^^^^BLOCK END^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^*/
Public.trim = function _trim() {
return $.trim.apply( null, arguments );
};
Public.Promise = function _Promise() {
return $.Deferred.apply( null, arguments );
};
Public.when = function _when() {
return $.when.apply( null, arguments );
};
Public.extend = function _extend() {
return $.extend.apply( null, arguments );
};
Public.plugin = function _plugin( ext ) {
if( typeof ext === 'function' ) {
ext.apply( Public, [win, doc, $, Private, Public, Sandbox, Application] );
}
return Public;
};
// createCSS returns a cross-browser compatible CSS string. For instance, .createCSS('boxShadow') returns "MozBoxShadow" in FF<4 while in WebKit browsers the result is just "boxShadow"
Public.createCSS = (function _createCSS() {
var div = doc.createElement( 'div' ),
divStyle = div.style,
ret = null,
cache = { };
return function _createCSSClosure( name ) {
// convert names like "font-width" into css camelCase form like "fontWidth"
name = name.replace( /-(\w)/g, function _replace( $1, $2 ) {
return $2.toUpperCase();
});
// check if we already got that css string in our lookup-cache table
if( name in cache ) { return cache[ name ]; }
// now check if "name" can get found by looping over propertys from our testDiv style object
for( var prop in divStyle ) {
if( prop.toLowerCase() === name.toLowerCase() ) {
cache[ name ] = prop;
return prop;
}
}
// at this point, do another check for WebKit browsers
if( name in divStyle ) {
cache[ name ] = name;
return name;
}
// still no match, try to lookup things with vendor prefixes, again any match will get cached in our closured lookup table object.
name = name.replace( /^./, name.charAt( 0 ).toUpperCase() );
'Moz Webkit ms O'.split( ' ' ).some(function _some( prefix ) {
ret = prefix + name;
if( name in divStyle ) {
ret = cache[ name ] = name;
return true;
}
if( name.toLowerCase() in divStyle ) {
ret = cache[ name ] = name.toLowerCase();
return true;
}
if( ret in divStyle ) {
cache[ name ] = ret;
return true;
}
for( var prop in divStyle ) {
if( prop.toLowerCase() === ret.toLowerCase() ) {
ret = cache[ name ] = prop;
return true;
}
}
// we tried, we tried really hard but we could not resolve anything for that css string.
ret = null;
});
return ret;
};
}());
/*^^^^^ ^^^^^^^^^^^^^^^^^^^BLOCK END^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^*/
$.extend(Private, {
globalModuleKey: 0,
jsPath: '/js',
modulePath: '/js/modules/',
modulePrefix: 'm_'
});
Private.formatStacktrace = function( strace ) {
if( Object.type( strace ) === 'String' ) {
var lines = strace.split( /\n/ );
if( lines && lines.length ) {
return lines.map(function( line ) {
var parts = line.split( /@/ );
if( parts && parts.length ) {
if( Object.type( parts[ 1 ] ) === 'String' ) {
return parts[0].substr(0, 40) + '\t->\t' + parts[ 1 ].substr( parts[ 1 ].lastIndexOf( '/' ) ).slice(1, 40);
}
}
}).join( '\n' );
}
}
return '';
};
module.exports = Public;
"use strict";
var Core = require("BF::Core");
// register Sandbox
Core.registerSandbox( "BF::Sandbox" ); // implement
// register Modules
Core.registerModule( 'modules::Window');
if( Core.createCSS( 'perspective' ) ) {
Core.registerModule( 'modules::Box3D' );
}
else {
Core.registerModule( 'modules::Box2D' );
}
// startup all registered Modules
Core.startAll();
/*
* init.js (typeofNaN2.0)
* ------------------------------
* Application init script, creates more App specific methods, variables and abstractions.
*
* This code runs in strict mode (if supported by the environment).
* ------------------------------
* Author: Andreas Goebel
* Date: 2011-11-10
* Changed: 2011-11-12 - added pathes
*/
"use strict";
var Core = require("BF::Core");
var Public = { },
Private = {
isJSON: /^(?:\{.*\}|\[.*\])$/ // JSON validation regex
};
// copy and shortcut some native methods
Public.toStr = Object.prototype.toString;
Public.hasOwn = Object.prototype.hasOwnProperty;
Public.type = Object.type;
Public.ua = navigator.userAgent;
// setup environment pathes
Public.environment = {
jsPath: '/js/',
modulePath: '/js/modules/'
};
Public.name = 'TypeofNaN 2.0 Website';
Public.version = 0.10;
var TypeofNan = Public;
if( Core ) {
Core.registerApplication( TypeofNaN = TypeofNaN );
}
else {
throw new TypeError( 'typeofNaN2.0 init: BarFoos Core not available - aborting.' );
}
module.exports = TypeofNan;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment