Skip to content

Instantly share code, notes, and snippets.

@TechNinjaWeb
Last active December 21, 2015 12:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TechNinjaWeb/597dfcde9609b6a15fef to your computer and use it in GitHub Desktop.
Save TechNinjaWeb/597dfcde9609b6a15fef to your computer and use it in GitHub Desktop.
Custom App - Module Installer & Configuration
(function(m, eId) {
// Define The Module To Be Instantiated
var AlertSystem = new m.constructor({
name: 'AlertSystem',
state: {
current: "Dom Module Initialized",
last: m.getModuleProperty('state').prototype.memory
},
init: this.init
});
// Define App Boundaries
AlertSystem.primaryNode = m.getModuleProperty('node');
// Return Any Element By Id
AlertSystem.getNode = function(id) {
var type = id[0] === "." ? 'class' : id[0] === "#" ? 'id' : 'undefined';
// Return Node
return document.querySelectorAll(id)[0];
}
/**
* This tiny script just helps us demonstrate
* what the various example callbacks are doing
*/
AlertSystem.Alerts = (function() {
"use strict";
// Initialize Private Variables
var elem,
fakeEl,
hideHandler,
self = {};
// Run Custom Options
self.init = function(options) { // Set Element By options.selector
elem = document.querySelectorAll(options.selector)[0];
};
// Function to Show Alerts To Client
self.log = function(text, args, alertType) {
clearTimeout(hideHandler);
// Add Alert Type To Element
if (!!alertType) elem.classList.add(alertType);
// Set HTML Text
elem.firstChild.nextSibling.innerHTML = text + " " + args || text;
// Find Element To Fade
var el = document.querySelector("." + eId);
// Fade Node Function with auto init();
self.fadeNode = (function(el) {
// Fade In with Init()
(function fadeIn() {
return new Promise(function(resolve, reject) {
setTimeout(function() { el.classList.remove('fade-out'); resolve(el.classList.add('fade-in')); }, 500)
}).then(function(res) { setTimeout(function() { el.style.display = 'block'; fadeOut(); }, 500); })
}());
// Fade Out
function fadeOut() {
return new Promise(function(resolve, reject) {
setTimeout(function() { el.classList.remove('fade-in'); resolve(el.classList.add('fade-out')); }, 2500)
}).then(function(res) { setTimeout(function() { el.style.display = 'none'; !!alertType ? el.classList.remove( alertType ) : null }, 2500); })
}
// Return the log function;
return self.log;
}(el));
};
return self;
}());
// Define the Selector To Search For
// And Initialize the Alert
AlertSystem.init = function() {
// Initialize The Alerts Module
AlertSystem.Alerts.init({ "selector": "." + eId });
// Set Alert System As Active Messaging Service
m.getModuleProperty('messaging').active = AlertSystem.Alerts
m.getModuleProperty('messaging').active.Class = 'alert-info';
// Turn Messaging System On
m.turnOnMessaging();
}
// Install the module to App Modules list
m.installModule(AlertSystem);
}(window.TechNinjaModule, 'alert'));
/* Example Of Alert */
// Ref to Module
var alerts = TechNinjaModule.getModuleProperty('modules').AlertSystem.Alerts;
// Create Your Custom Alert
var sendAlert = function(message) { alerts.log(message, "", 'alert-success') };
(function(m){
// Define The Module To Be Instantiated
var EventManager = new m.constructor({ name: 'EventManager',
state: {current: "Event Manager Initialized",
last: m.getModuleProperty('state').prototype.memory
} });
// Event Node Creation Function
EventManager.createEvent = function(name, eventObject) { return new CustomEvent(name, eventObject); }
// Send Node Through System
EventManager.sendEvent = function(node, event) {
if (document.createEvent) {
// console.log("Dispatching Event", event);
return node.dispatchEvent(event);
} else {
// console.log("Firing Event", event);
return node.fireEvent("on" + event.eventType, event);
}
}
// Create Internal Dom Node
// To Respond To Events
EventManager.responderNode = (function(d, m) {
d.responder = document.createElement('div');
d.responder.id = d.name;
d.responder.className = "default-node";
d.responder.module = {};
d.responder.data = {default: 'value is this'};
d.responder.addEventListener(d.name, function(e){
console.log("I Will Respond Shortly ...", e.detail);
return this;
});
d.responder.listener = [].push(d.responder);
return d.responder;
}(EventManager, m));
// Add Event Listener to document
EventManager.registerEvent = function(event, node, cb) {
var elem;
if (!node) elem = window.document;
else elem = node;
// Attach Event Listener
if (!cb) elem.addEventListener(event.type, node);
else elem.addEventListener(event.type, cb);
// Set The Listener's Copy On The Element
elem.listener = [].push(cb);
// Test Event Fire
var event = new CustomEvent('EventManager', {detail: {message: 'Got It'}});;
// Return The Dom Nodes To This Function
// return EventManager.responderNode.push(elem) && EventManager.responderNode;
return EventManager.responderNode.appendChild(node) && EventManager.responderNode;
}
// Convert an element node into a JSON object
EventManager.getNode = function(id) {
var type = id[0] === "."
? 'class'
: id[0] === "#"
? 'id' : 'undefined';
// Responder Nodes Definition
var def = EventManager.responderNode;
// Definitions Children
var elems = def.children;
// Return the Node That is Equal To id
// console.log("Truth?", "#" + el.id, id, "#" + el.id == id)
var idx = Array.prototype.slice.call(elems).filter(function(el, i, a){
return ("#" + el.id) == id;
});
// Determine if IDX Is valid,
// Return Valid Ref to Node
if (idx.length <= 0) return def;
else if (idx) return idx[0];
else return "Don't Know What To Return";
}
// Install the module to App Modules list
m.installModule(EventManager);
}(window.TechNinjaModule));
(function(m) {
// Define The Module To Be Instantiated
var FaceBook = new m.constructor({
name: 'FaceBook',
state: {
current: "Test Module Initialized",
last: m.getModuleProperty('state').prototype.memory
},
init: function() {
window.fbAsyncInit = function() {
FB.init({
appId: '796575453734742',
xfbml: true,
version: 'v2.5'
});
};
(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {
return;
}
js = d.createElement(s);
js.async = true;
js.id = id;
console.log("JS File Addy", document.location.protocol + "//connect.facebook.net/en_US/sdk.js");
js.src = "https:" + "//connect.facebook.net/en_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
var fbDiv = document.createElement('div');
fbDiv.id = "fb-root";
fbDiv.className = "fb-root";
document.body.appendChild(fbDiv);
}(document, 'script', 'facebook-jssdk'));
}
});
// Define A Component either in the constructor,
// or as an object key
FaceBook.components.properties = [1, 2, 4];
// Install the module to App Modules list
// m.installModule(FaceBook);
}(window.TechNinjaModule));
<!doctype html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8">
<title>Tech Ninja | Web &amp; IT</title>
<meta name="description" content="Tech Ninja | Web &amp; IT Advanced Web Applications">
<meta name="author" content="4UmNinja">
<link rel="stylesheet" href="css/bootstrap.css">
<!-- Custom Module Manager -->
<script type="application/javascript" src="modules/main-module.js"></script>
<style>
/* Alert System Classes And Key Frames */
@-webkit-keyframes fade-in {
to {
opacity: 1;
}
}
@keyframes fade-in {
to {
opacity: 1;
}
}
@-webkit-keyframes fade-out {
0% { opacity: 1; }
85% { opacity: 1; }
100% { opacity: 0; }
}
@keyframes fade-out {
0% { opacity: 1; }
85% {opacity: 1; }
100% { opacity: 0;}
}
.fade-in {
-webkit-animation: fade-in .5s ease-in 1 forwards;
animation: fade-in .5s ease-in 1 forwards;
opacity: 0;
}
.fade-out {-webkit-animation-delay: 1.5s;}
.fade-out {
-webkit-animation: fade-out 1s ease-out;
-webkit-animation-fill-mode: forwards;
-webkit-animation-iteration-count: 1;
opacity: 1;
}
.is-paused {
animation-play-state: paused;
}
/* Alert System Main Class */
.bb-alert, .alert-system {
position: fixed;
bottom: 5%;
right: 0;
margin-bottom: 0;
font-size: 1.2em;
padding: 1em 1.3em;
z-index: 2000;
}
</style>
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body tn-app>
<div class="container">
<div class="alert-system alert" style="display:none;">
<span>Invalid Notification</span>
</div>
<!-- Custom Modules -->
<script type="application/javascript" src="modules/test-module.js"></script>
<script type="application/javascript" src="modules/facebook-module.js"></script>
<script type="application/javascript" src="modules/alerts-module.js"></script>
<script type="application/javascript" src="modules/events-module.js"></script>
<script type="application/javascript" src="modules/local-storage-module.js"></script>
</body>
</html>
(function(m) {
// Define The Module To Be Instantiated
var StorageSystem = new m.constructor({
name: 'StorageSystem',
state: {
current: "Local Storage Module Initialized",
last: m.getModuleProperty('state').prototype.memory
},
init: function() {
// Available Storage System
var storages = ['localStorage', 'sessionStorage'];
// Define A Storage Objects
StorageSystem.storage = {};
StorageSystem.storage.cache = {};
StorageSystem.storage.cache.data = {};
// Set Storage System
for(system in storages) {
// Empty Reference Object
StorageSystem.storage[storages[system]] = window[storages[system]];
// Set Storage Name In Object
StorageSystem.storage[storages[system]]['namespace'] = StorageSystem["namespace"];
StorageSystem.storage[storages[system]]['DB'] = storages[system];
}
// Define A Save Function
StorageSystem.storage.setItem = function(property, value){
// If No Second Arg Present,
// Assume It's an Object
if (!dataIsCached(property, value)) {
// console.log("In Local Store?", dataIsCached(property, value));
// saveTo(storages);
// For Each Storage System ...
for(system in storages) {
// Save The Property And It's Value
// To the Storage System
// console.log("Storing")
StorageSystem.storage[storages[system]].setItem(property, JSON.stringify(value));
StorageSystem.storage.cache.data[property] = value;
}
return { message: "Data From Local Storage", data: value };
} else {
// Data Is The Same As Local Data
return { message: "Data From Cache", data: StorageSystem.storage.cache.data[property] };
}
}
// Get Item From Store
StorageSystem.storage.getItem = function(id) {
for (system in storages) {
// Get id from DB
// console.log("!dataIsCached", dataIsCached(id));
// 2nd Argument Forces Get Item To
// Return from the Local Storage
if (arguments[1]) return new Promise(function(res, rej){
var data = StorageSystem.storage[storages[system]].getItem(id)
if (typeof data == 'string') data = JSON.parse(data);
return res( data );
})
// If Data Is Not Cached
// Get From Local Storage
if (!dataIsCached) return new Promise(function(res, rej){
return res(JSON.parse( StorageSystem.storage[storages[system]].getItem(id) ));
});
// If Data Is Cached Return It From Local Data
else {
var data;
try {// Try To Parse Data
data = JSON.parse(StorageSystem.storage.cache.data[id]); } catch(e)
{ // Data Cannot Be Parsed
data = StorageSystem.storage.cache.data[id];
} finally { // Save Data To Local Store
console.log("Data", data);
return data;
}
}
}
}
StorageSystem.storage.manuallyUpdateLocalCache = function(property, value){
// Add Item To Local Store
var cache = StorageSystem.storage.cache.data;
var data;
try {// Try To Parse Data
data = JSON.parse(value); } catch(e)
{ // Data Cannot Be Parsed
data = data;
} finally { // Save Data To Local Store
cache[property] = data;
console.log("Cache Data - " + property, data);
}
}
// Check If Data Already Exists
// In Local Cache
function dataIsCached(property, value) {
// Check If Data Is Cached
// Return true if so, else false
// console.log("Value Defined?" + value, value == 'undefined' || value == null, "Property In Cache?", StorageSystem.storage.cache.data.hasOwnProperty(property))
if (value == 'undefined' || value == null) return StorageSystem.storage.cache.data.hasOwnProperty(property);
if (!StorageSystem.storage.cache.data.hasOwnProperty(property)) return false;
else return JSON.stringify( StorageSystem.storage.cache.data[property] ) == JSON.stringify(value);
}
// Get All Data Saved In Local Storage
(function populateLocalCache(s) {
for(system in s) {
// Define Store Refs
var store = StorageSystem.storage[s[system]];
var cache = StorageSystem.storage.cache.data;
// Loop over Prop Names and Save
// To Local Cache
for (prop in store) {
// Add Item To Local Store
var data = StorageSystem.storage[s[system]].getItem(prop);
try {// Try To Parse Data
data = JSON.parse(data); } catch(e)
{ // Data Cannot Be Parsed
data = data;
} finally { // Save Data To Local Store
cache[prop] = data;
}
}
// Set Local DB name to 'Cache'
cache.DB = "Cache";
// console.log("Data Has Been Populated");
return cache;
}
}(storages));
// Set Emtpy Function
StorageSystem.storage.clear = function() { window['localStorage'].clear(); window['sessionStorage'].clear(); return "Local Storage Emptied"; };
// Disable Function Enumeration
StorageSystem.prototype.disableFunctionEnumeration(StorageSystem.storage);
}
});
console.log("Storage Object", StorageSystem);
// Listen For Changes From Other Clients
window.addEventListener('storage', function(e) {
// Update Local Cache When DB Changes
StorageSystem.storage.manuallyUpdateLocalCache(e.key, e.newValue);
});
// Install the module to App Modules list
m.installModule(StorageSystem);
}(window.TechNinjaModule));
/*
Examples Below:
This module allows you to set and retrieve data
From the browsers local storage area
*/
// Set Storage System Refs
var storageSystem = TechNinjaModule.getModuleProperty('modules').StorageSystem.storage;
// Local Cache
var localStore = TechNinjaModule.getModuleProperty('modules').StorageSystem.storage.cache.data;
// Store Data
storageSystem.setItem('some-data', 'Hello World');
// Retrieve Your Item By ID/Property Name
var getData = storageSystem.getItem('some-data');
console.log("Your Item Is", '"'+getData+'"');
(function(m){
/*
Constructor allows an object to be created
using the "new" constructor and it takes on
properties of the main module using the
namespace TechNinjaModule
eg: var bob = new TechNinjaModule.constructor({name: 'test', properties: [undefined]});
*/
m.constructor = (function constructor(s){
// This constructor's return acts as an index
// For all new modules instantiated by this function
return function() {
var args = Array.prototype.slice.call(arguments);
// Check for arguments definition
if (typeof args[0] != 'undefined'
|| typeof args[0] != null) for (var key in args[0]) { this[key] = args[0][key]; }
// Standard NameSpace For All Applications
this.namespace = "TechNinjaModule";
// Prototype Obeject (blank)
this.prototype = {};
// Return the Proterty to the client
this.getModuleProperty = function(property) { return s[property]; }
// Function List Factory
this.installModule = s.install;
this.uninstallModule = s.uninstall;
this.reboot = s.reinstall;
this.setState = s.state.set;
this.plugins = s.installedModules;
this.components = this.components || {};
this.toggleMessages = s.toggleMessages;
this.turnOnMessaging = function(){ return s.messagesEnabled = true; };
this.turnOffMessaging = function(){ return s.messagesEnabled = false; };
this.setMessagingTo = m.messaging.setActive;
this.sendMessageToClient = m.sendMessageToClient;
// Set State To Initialized
s.state.set({current: "App Initialized", last: m.state.prototype.memory});
// Disable all function enurations
this.prototype.disableFunctionEnumeration = function(o) {
for (var p in o) {
if (!isFunction(o[p])) "Skipping";
else Object.defineProperty(o, p, {
enumerable: false
});
}
// Return True if Object is a Function
function isFunction(functionToCheck) {
var getType = {};
return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
}
// Return self
return this;
}
// Init Disable Function Enumeration
this.prototype.disableFunctionEnumeration(this);
// Define Properties for this module
Object.defineProperties(this, {
prototype: {
enumerable: false
},
namespace: {
value: this.namespace,
writable: false
}
});
};
})(m);
// Define Private Function to This Module
// All m['some property'] are hidden from
// the client and window scope
m.id = "Installation Manager";
// Get The Node The App Is Defined On
m.node = document.querySelectorAll('[tn-app]')[0] || document.body;
// Define State of the Application
m.state = {
current: "Starting App ...",
last: ""
};
// State Manager
m.state.set = function(s){
// Get Keys from arguments object
var keys = Object.keys(s);
// Get Keys for the Modules state object
var stateKeys = Object.keys(m.state);
// Validate state keys argument
var valid = keys.length > 0 ? keys.every(function(key){ return stateKeys.indexOf(key) >= 0 }) : false;
// If Keys are valid,
// Set the state with keys
if (valid) { // Set Properties onto state object;
for (var prop in s) { m.state[prop] = s[prop]; } }
else return {message: 'Could Not Set State. State Object Is Invalid'};
return m.state;
}
// Reference to Last State
m.state.prototype = {};
m.state.prototype.memory = m.state.current;
Object.defineProperty(m.state, 'prototype', {
enumerable: false
})
// Define an Applications Node List
m.modules = {};
m.installedModules = [];
// Define a logging system,
// Must be an object with log property
// eg: {log: { some log functionality eg: console.log() }};
m.messaging = {
default: console,
active: {},
installed: ['console']
};
m.messaging.setActive = function(object) {
console.log("Setting To", object);
Object.defineProperty(m.messaging, 'setActive', {
enumerable: false
});
m.messaging['active'] = object;
m.sendMessageToClient("Loaded Messagin Service", object);
return object;
}
// Client Console Messaging System
m.messagesEnabled = false;
// Toggle Messaging On Or Off
m.toggleMessages = function(){ m.messagesEnabled = !m.messagesEnabled }
// Send Message To Client Function
m.sendMessageToClient = function(message, args, Class) {
if (!m.messagesEnabled) return "Messages Disabled";
// System is an optional value to
// determine what messaging system
// is to be used eg: system = {log: object.logFunction()};
if (!m.messaging.active.hasOwnProperty('log')) m.messaging.default.log(message, args);
else m.messaging.active.log(message, args, m.messaging.active.Class);
}
// Run App Functionality
m.run = function(app, cb) { // Apply the Callback on the new app module
cb(app); }
// Module Installer Functionality
m.install = function(app) {
m.run(app, function(a){
try {
/* Run This App (just return true);
Check if name has been loaded and
is not unidentified
*/
if (app.hasOwnProperty('name') && app.hasOwnProperty('prototype') && !m.modules.hasOwnProperty(app.name)) { m.modules[app.name] = app; }
// Halt the compiler
else throw new Error("App Not Valid. Check app.prototype = {} or app.name is correct");
// Run Module Initilizer
// If Apps List has this app's name
if (m.modules.hasOwnProperty(a.name) && a.hasOwnProperty("init")) a.init();
// No Init().. Do Not Init Module
else if (m.modules.hasOwnProperty(a.name) && !a.hasOwnProperty("init")) "No Module To Load";
// Halt the compiler
else throw new Error("Could Not Initialize " + a.name) + " Module";
// Update InstalledApps List
m.installedModules.push(app.name);
// Send Success To Client;
m.sendMessageToClient(a.name + " Has Been Initialized Successfully", "");
// Change State
m.state.set({current: "Initialized " + a.name, last: m.state.prototype.memory});
// Catch The Error
} catch (e) {
// Send Error to Client
console.error({message: e.message, stack: e, arguments: arguments});
} finally {
// To Be Implemented
}
});
}
// Uninstall App Functionality
m.uninstall = function(name) {
// Delete App Node
delete m.modules[name];
// Send Success To Client, but not uninitialized;
m.sendMessageToClient(name + " Has Been Uninstalled Successfully", "");
// Change State
m.state.set({current: "Uninstalled " + name, last: m.state.prototype.memory});
}
// Reinstall App Functionality
m.reinstall = function(name) {
var app = m.modules[name];
// Uninstall App
m.uninstall(name);
// Install App
m.install(app);
// Send Success To Client;
m.sendMessageToClient(name + " Has Been Reinstalled Successfully", "");
// Change State
m.state.set({current: "Reinstalled " + name, last: m.state.prototype.memory});
}
// Implement Better Error Handling
m.ErrorHandler = function(fn, args) {
// Empty Function
}
// Hide Inner Properties of this module
Object.defineProperties(m, { constructor: { enumerable: false } });
// Return this object and it's constructor
return (function(m){ var self = new m.constructor(); return window[self.namespace] = self; }(m));
}({}));
(function(m){
// Define The Module To Be Instantiated
var TestModule = new m.constructor({
name: 'TestModule',
components: {array: [1,2,3,4]},
state: {current: "Test Module Initialized", last: m.getModuleProperty('state').prototype.memory },
init: function(){ m.getModuleProperty('state').prototype.memory; }
});
// Define A Component either in the constructor,
// or as an object key
TestModule.components.properties = [1,2,4];
// Install the module to App Modules list
m.installModule(TestModule);
}(window.TechNinjaModule));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment