Created
December 26, 2015 00:58
-
-
Save TechNinjaWeb/e846e9a5059f5d638162 to your computer and use it in GitHub Desktop.
Custom App - Module Installer - Test Using Require
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
define(function (require) { | |
// Function Executes with window[your-module.namespace] | |
// && selector of div to hold alerts eg: <div id='alert'></div> | |
// || <div class="alert"></div> | |
return (function(m, selector) { | |
// Define The Module To Be Instantiated | |
var that; | |
var AlertSystem = that = new m.constructor({ | |
name: 'AlertSystem', | |
state: { | |
current: "Alerts Module Initialized", | |
last: m.getModuleProperty('state').prototype.memory | |
}, | |
init: this.init | |
}); | |
// Define App Boundaries | |
that.primaryNode = m.getModuleProperty('node'); | |
// Return Any Element By Id | |
that.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 | |
*/ | |
that.Alerts = (function() { | |
"use strict"; | |
// Apend Alerts Container to Body | |
var alerts = document.createElement('div'); | |
alerts.id = "alert", | |
alerts.className = "alert-system", | |
alerts.style.display = "none"; | |
var span = document.createElement('span'); | |
span.innerHTML = "Loading Notification System"; | |
// Create Text Span and append to alerts div | |
alerts.appendChild(span), | |
// Append alerts to body | |
document.body.appendChild(alerts); | |
// Initialize Private Variables | |
var elem, | |
hideHandler, | |
self = {}; | |
// Run Custom Options | |
self.init = function(options) { // Set Element By options.selector | |
elem = !options ? alerts : 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.innerHTML = text + " " + args || text; | |
// Find Element To Fade | |
var el = document.querySelector(selector); | |
// 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')); }, 100) | |
}).then(function(res) { setTimeout(function() { el.style.display = 'block'; fadeOut(); }, 100); }) | |
}()); | |
// 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; | |
}(elem)); | |
}; | |
return self; | |
}()); | |
// Define the Selector To Search For | |
// And Initialize the Alert | |
that.init = function() { | |
// Initialize The Alerts Module | |
!!selector ? that.Alerts.init({"selector": selector}) : that.Alerts.init(); | |
// Set Alert System As Active Messaging Service | |
m.getModuleProperty('messaging').active = that.Alerts | |
m.getModuleProperty('messaging').active.Class = 'alert-info'; | |
} | |
// Install the module to App Modules list | |
m.prototype.installModule(that); | |
}( require('modules/main-module') )) | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// For any third party dependencies, like jQuery, place them in the lib folder. | |
// Configure loading modules from the lib directory, | |
// except for 'app' ones, which are in a sibling | |
// directory. | |
requirejs.config({ | |
baseUrl: '', | |
paths: { | |
app: 'modules' | |
} | |
}); | |
// Load the primary constructor, | |
// Define the app and Instantiate | |
// Each Module with main as the object | |
requirejs(['modules/main-module'], function(main){ | |
requirejs(['modules/alerts-module']) | |
requirejs(['modules/local-storage-module']) | |
requirejs(['modules/user-module']) | |
requirejs(['modules/http-module']) | |
requirejs(['modules/events-module']), | |
requirejs(['js/examples']) | |
}); | |
console.log("Loaded App.js"); | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
define(function (require) { | |
return (function(m){ | |
var that; | |
// Define The Module To Be Instantiated | |
var EventManager = that = new m.constructor({ name: 'EventManager', | |
state: {current: "Event Manager Initialized", | |
last: m.getModuleProperty('state').prototype.memory | |
} }); | |
// Event Node Creation Function | |
that.createEvent = function(name, eventObject) { return new CustomEvent(name, eventObject); } | |
// Default Node Creation | |
that.createNode = function(id, eventName, listener, options) { | |
if (!id || !listener || !eventName) return "Arguments Not Valid Got " + arguments.length + " arguments. Need 3 arguments"; | |
var node = document.createElement('div'); | |
node.id = id; | |
// Add Options to node | |
if (options) for (var property in options) { node[property] = options[property]; } | |
// Add Event Listenr | |
node.addEventListener(eventName, listener); | |
return node; | |
} | |
that.setEvent = function(id, eventData, listener, options) { | |
// Return if defaults not mset | |
if (!id || !listener || !eventData) return "Arguments Not Valid Got " + arguments.length + " arguments. Need 3 arguments"; | |
// Create Event and Event Node | |
var event = this.createEvent(eventData.name || id, eventData.data); | |
console.warn("Here's the event", event, eventData); | |
var node = this.createNode(id, listener, options || {}); | |
console.warn("Your node sir", node); | |
// Register Node to Event Module | |
this.registerEvent(event, node, listener); | |
return {event: event, node: node}; | |
} | |
// Send Node Through System | |
that.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 | |
that.responderNode = (function(EM, m) { | |
EM.responder = document.createElement('div'); | |
EM.responder.id = EM.name; | |
EM.responder.className = "default-node"; | |
EM.responder.module = {}; | |
EM.responder.data = {default: 'value is this'}; | |
EM.responder.addEventListener(EM.name, function(e){ | |
console.log("I Will Respond Shortly ...", e.detail); | |
return this; | |
}); | |
EM.responder.listener = [].push(EM.responder); | |
return EM.responder; | |
}(EventManager, m)); | |
// Add Event Listener to document | |
that.registerEvent = function(event, node, cb) { | |
var elem = !node ? window.document : 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 | |
if (cb) elem.listener = [].push(cb); | |
// Test Event Fire | |
var event = new CustomEvent('EventManager', {detail: {message: 'Got It'}});; | |
// Return The Dom Nodes To This Function | |
// return that.responderNode.push(elem) && that.responderNode; | |
return that.responderNode.appendChild(node) && that.responderNode; | |
} | |
// Convert an element node into a JSON object | |
that.getNode = function(id) { | |
var type = id[0] === "." | |
? 'class' | |
: id[0] === "#" | |
? 'id' : 'undefined'; | |
// Responder Nodes Definition | |
var def = that.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 def if idx returns nothing | |
if (idx.length <= 0) return def; | |
// Return IDX since it contains node ref | |
else if (idx) return idx[0]; | |
// Handle Uncaught Error | |
else return "Don't Know What To Return"; | |
} | |
// Install the module to App Modules list | |
m.prototype.installModule(that); | |
// Set Event Manager As Default | |
var events = m.getModuleProperty('events'); | |
events.prototype.setEventSystem(that); | |
// Hide Enumeration | |
Object.defineProperty(events, 'prototype', {enumerable: false}); | |
// Disable Enumeration For Functions | |
that.prototype.disableFunctionEnumeration(that); | |
}( require('modules/main-module') )) | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
define(function (require) { | |
// Define the app and Instantiate | |
// Each Module | |
var app = window.TechNinjaModule = require('../modules/main-module'); | |
// require('../modules/alerts-module')(app); | |
// require('../modules/events-module')(app); | |
// require('../modules/http-module')(app); | |
// require('../modules/local-storage-module')(app); | |
// require('../modules/user-module')(app); | |
console.log("Examples", app); | |
/* | |
This allows an object to be created | |
using the "new" constructor and it takes on | |
properties of the main module using the | |
this.namespace property | |
eg: var bob = new TechNinjaModule.constructor({name: 'test', properties: [undefined]}); | |
*/ | |
/* | |
Events Module will allow you to create | |
A messaging service between modules and | |
Page elements | |
*/ | |
/* | |
// create ref to Event Manager | |
var EventManager = app.getModuleProperty('modules').EventManager; | |
// Must Use Detail Property To Send Data | |
// Name Is Optional | |
var eventObject = {name: 'CustomEventMagic', detail: {message: "This is the sweetest thing ever!"}}; | |
// Create A Listner Function | |
var listener = function(event){ | |
console.log("This Node Has Heard Your Request"); | |
// Advanced: Tap into Alert System Module | |
app.getModuleProperty('modules').AlertSystem.sendMessageToClient("Your Welcome", ""); | |
// Turn Off Messaging Service | |
app.turnOffMessaging(); | |
} | |
// Store Event Ref | |
var eventNode = EventManager.setEvent('myEventNode', eventObject, listener, {className: "my-class-name", data: eventObject, fakeProperty: "I am cool!"}); | |
console.log("Here's the Event & Node", eventNode); | |
// Send Something to this node | |
setTimeout(function(){ | |
// Turn Messaging System On | |
app.turnOnMessaging(); | |
// Enjoy Messaging Service | |
EventManager.sendEvent(eventNode.node, eventNode.event); | |
}, 4000) | |
*/ | |
/* Example Of Alert */ | |
/* | |
// Ref to Module | |
var alerts = app.getModuleProperty('modules').Alerts; | |
// Create Your Custom Alert | |
var sendAlert = function(message) { alerts.log(message, "", 'alert-success') }; | |
*/ | |
/* | |
Example Below: | |
This module allows you to set and retrieve data | |
From the browsers local storage | |
*/ | |
/* | |
setTimeout(function(){ | |
// Set Storage System Refs | |
var storageSystem = app.getModuleProperty('modules').StorageSystem.storage; | |
// Local Cache Ref | |
var localStore = app.getModuleProperty('modules').StorageSystem.storage.cache; | |
// Store Data | |
storageSystem.save('some-data', 'Hello World'); | |
// Retrieve Your Item By ID/Property Name | |
var getData = storageSystem.get('some-data'); | |
console.log("Your Item Saved As", '"'+getData+'"'); | |
console.log("Don't Believe Me, Check The Storage Adapters", app.getModuleProperty('modules').StorageSystem.storage); | |
}, 1); | |
*/ | |
/* | |
Example below shows how to save | |
and retrieve a user from the local cache | |
*/ | |
/* | |
// Create Module Ref | |
var UserModule = app.getModuleProperty('modules').UserModule; | |
// Save A User | |
var saveUser = UserModule.saveUser({name: 'ben johnson', age: 25}); | |
// Get All Users In DB | |
var getAll = UserModule.getUser(); | |
console.log("Here Are All Users", getAll); | |
// Retrieve The User You've Created | |
var getBen = UserModule.getUser('name', 'ben'); | |
console.log("This is Ben", getBen[0]); | |
*/ | |
/* Example 2: | |
Set Config Object | |
Request Headers is optional | |
*/ | |
/* | |
// Create Ref to HTTP Module | |
var http = require('modules/main-module').getModuleProperty('modules').HTTP; | |
// Basic GET Example | |
// Create Callback Object | |
var callback = { | |
success: function(e){ | |
console.log("response", [e]); | |
return e; | |
}, | |
error: function(e){ | |
console.log('got error', e); | |
return e; | |
} | |
}; | |
// Create Your Request | |
var request1 = http.request('/index.html', callback).then(function(res){ console.log("got response"); return res; }); | |
// Second Chain Method | |
request1.then(function(res){ console.log("Second Chain", [res]); }); | |
// Example 2: | |
// Timeout Only for Example. Not required | |
setTimeout(function(){ | |
var config = {url: '/index.html', method: 'GET', requestHeaders: []}; | |
// Make Your Request on the Config | |
var request2 = http.request(config); | |
// Chain Your request object | |
// Make sure to return res to continue chain | |
request2.then(function(res){console.log("First Chain"); return res;}); | |
// Continue chaining ... | |
request2.then(function(res){console.log("Second Chain", [res]); return res}).then(function(res){console.log("Last Chain", [res])}); | |
}, 1000); | |
*/ | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
define(function (require) { | |
return (function(m){ | |
// Define The Module To Be Instantiated | |
var that; | |
var HTTP = that = new m.constructor({ | |
name: 'HTTP', | |
state: {current: "HTTP Module Initialized", last: m.getModuleProperty('state').prototype.memory }, | |
init: function(){ m.getModuleProperty('state').prototype.memory; } | |
}); | |
// Create HTTP Object | |
var xhr = window['XMLHttpRequest'] ? new window['XMLHttpRequest']() : new ActiveXObject("Microsoft.xhr"); | |
// Request Function | |
that.request = function(url, callback){ | |
// If only 1 argument, set config to this | |
// Otherwise set default | |
var config = !callback ? url : {url: url, method: 'GET'}; | |
// Set Request Headers if config provided | |
config.requestHeaders ? config.requestHeaders.forEach(function(header){ | |
xhr.setRequestHeader(header[0], header[1]); | |
}) : null; | |
// Open Connection to URL | |
xhr.open(config.method, config.url, config.async || true); | |
// Return new Promise to chain function | |
return new Promise(function(resolve, reject){ | |
// Resolve Response from Ready State Change | |
xhr.onreadystatechange = callback ? function() { | |
try { | |
if (xhr.status == 200 && xhr.readyState == 4) { | |
// Resolve The Response And Create | |
// Chain Method | |
return resolve(callback.success(xhr.response)); | |
// console.log(xhr.response); | |
} else if (xhr.status != 200 && xhr.readyState == 4) { | |
// Reject Any Response That | |
// Is Not 200 OK | |
return reject(callback.error(xhr.response)); | |
// console.log(xhr.response); | |
} | |
} catch(e) { console.error(e.message, e); } | |
}: function basicReadyState() { | |
// If no callback provided in config | |
// Use basicReadyState functionality | |
try { | |
if (xhr.status == 200 && xhr.readyState == 4) { | |
// Resolve The Response And Create | |
// Chain Method | |
return resolve(xhr.response); | |
// console.log(xhr.response); | |
} else if (xhr.status != 200 && xhr.readyState == 4) { | |
// Reject Any Response That | |
// Is Not 200 OK | |
return reject(xhr.response); | |
// console.log(xhr.response); | |
} | |
} catch(e) { console.error(e.message, e); } | |
}; | |
// Stringify User Provided Parameters | |
// Use if config has a POST method | |
var params = JSON.stringify(config.params || {}); | |
// Send Request | |
xhr.send(params); | |
}); | |
} | |
// Install the module to App Modules list | |
m.prototype.installModule(that); | |
}( require('modules/main-module') )) | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"> | |
<head> | |
<meta charset="utf-8"> | |
<title>Tech Ninja | Web & IT</title> | |
<meta name="description" content="Tech Ninja | Web & IT Advanced Web Applications"> | |
<meta name="author" content="4UmNinja"> | |
<link rel="stylesheet" href="css/bootstrap.css"> | |
<!-- Custom Module --> | |
<script type="application/javascript" async="true" data-main="app" src="js/require.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></body></html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
define(function (require) { | |
return (function(m) { | |
// Define The Module To Be Instantiated | |
var that; | |
var StorageSystem = that = 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', 'cache']; | |
// Define A Storage Objects | |
that.storage = {}; | |
// Set Storage System | |
for(var system in storages) { | |
// Empty Reference Object | |
that.storage[storages[system]] = window[storages[system]] || {}; | |
// Set Storage Name In Object | |
that.storage[storages[system]]['namespace'] = StorageSystem["namespace"]; | |
that.storage[storages[system]]['DB'] = storages[system]; | |
} | |
// Define A Save Function | |
that.storage.save = function(property, value){ | |
// If No Second Arg Present, | |
// Assume It's an Object | |
var cache = that.storage.cache; | |
var message; | |
// console.warn(["Data is cached", dataIsCached(property || "", value)], "\n", | |
// ["Values are equal", valuesAreEqual(cache[property] || "", value)], "\n", | |
// []); | |
// console.warn("Attempting to save user", property, value); | |
if (!dataIsCached(property || "", value) && !valuesAreEqual(that.storage.localStorage[property] || "", value)) | |
saveToAllStorageSystems(property, value) | |
, message = "Saved Data Successfully"; | |
if (dataIsCached(property || "", value) && !valuesAreEqual(that.storage.localStorage[property] || "", value)) | |
mergeAndReturnData(property, value) | |
, message = "Updated Data Successfully"; | |
else message = "Data Already Cached"; | |
// Update Cache Length | |
cache.length = Object.keys(that.storage.cache).length; | |
// Send Success Or Fail To Client | |
return m.sendMessageToClient(message, ""); | |
} | |
function mergeAndReturnData(property, value) { | |
console.warn("Implement Merging Unequal Data Keys", property, value); | |
var data = that.storage.get(property), | |
type = typeof data !== 'string' || typeof data !== 'number' | |
? Array.isArray(data) | |
? 'array' | |
: typeof data === 'object' && !Array.isArray(data) | |
? 'object' | |
: 'basic' | |
: null; | |
console.log("Type of Data", type, data); | |
if (type === 'basic') return saveToAllStorageSystems( property, value ); | |
if (type === 'array') return saveToAllStorageSystems(property, data); | |
// -------- TEMPORARY USER FORCED MERGE ------- | |
// -------------------------------------------- | |
// if (property === "Users") return saveToAllStorageSystems( property, value ); | |
// if (!that.cache[property]) saveToAllStorageSystems( property, value ); | |
} | |
// Determine Type and Save To Storage | |
function saveToAllStorageSystems(property, value) { | |
var s = storages.slice(); | |
s.splice(s.indexOf('cache'), 1); | |
for(var system in s) { | |
// Save The Property And It's Value | |
if (typeof value === 'object') that.storage[s[system]][property] = returnStringData(value); | |
else that.storage[s[system]][property] = value; | |
} | |
that.storage.cache[property] = value; | |
} | |
function returnParsedData(data) { | |
console.warn("Return This As Parsed", data); | |
var response; | |
try { | |
response = JSON.parse(data); | |
} catch(e) { | |
response = data; | |
} finally { | |
console.info("Data Has Been Parsed", response); | |
return response; | |
} | |
} | |
function returnStringData(data) { | |
// console.warn("Return This As String", data); | |
var response; | |
try { | |
response = JSON.stringify(data); | |
} catch(e) { | |
response = data; | |
} finally { | |
// console.info("Data Has Been Stringified", response); | |
return response; | |
} | |
} | |
// Check If Data Already Exists | |
// In Local Cache | |
function dataIsCached(property, value) { | |
// console.log("Prop In Cache", that.storage.cache.hasOwnProperty(property), property, value); | |
// console.log("Stings Are Equal?", returnStringData( that.storage.cache[property] ) == returnStringData(value), [returnStringData( that.storage.cache[property] ), returnStringData(value)]); | |
// Check If Data Is Cached | |
// Return true if so, else false | |
if (!that.storage.cache.hasOwnProperty(property) && !valuesAreEqual(that.storage.cache[property] || "", value)) return false; | |
else return returnStringData( that.storage.cache[property] ) == returnStringData(value); | |
} | |
// Return Bool If Data Equal | |
function valuesAreEqual(val1, val2){ | |
// console.info("Arguments", val1, val2); | |
// Determine Both Value Types | |
var isArray = [Array.isArray(val1), Array.isArray(val2)].every(function(el){ return el === true; }); | |
var isObject = [Object.keys(val1)[0] != "0", Object.keys(val2)[0] != "0"].every(function(el){ return el === true; }); | |
// console.warn("Is Array?", isArray, "Is Object?", isObject, ["data", [val1, val2]], ["Keys", Object.keys(val1), Object.keys(val2)]); | |
// Check If Array Lengths Are the same or return false | |
if (typeof val1 == 'string' && typeof val2 == 'string' || typeof val1 == 'number' && typeof val2 == 'number') return val1 == val2; | |
if (isArray && val1.length == val2.length) return Array.prototype.slice.call(val1).every(function(element, index, keys){ | |
// console.log("This Array Is Same", val1[index] == val2[index]); | |
return JSON.stringify(val1[index]) == JSON.stringify(val2[index]); | |
}); | |
// Check if Object[key].values are equal or return false | |
var aKeys = Object.keys(val1); | |
var bKeys = Object.keys(val2); | |
if (isObject && Object.keys(val1).length == Object.keys(val2).length) Array.prototype.slice.call(aKeys).every(function(property, index, keys){ | |
console.log("This Object Is Same", JSON.stringify(val1[property]) == JSON.stringify(val2[property])); | |
return JSON.stringify(val1[property]) == JSON.stringify(val2[property]); | |
}); | |
else return false; | |
} | |
// Get Item From Store | |
that.storage.get = function(id) { | |
for (var system in storages) { | |
// Get id from DB | |
// 2nd Argument is Bool that Forces Get Item To | |
// Return from the Local Storage | |
if (arguments[1]) return new Promise(function(res, rej){ | |
var data = that.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 String Data As Object | |
return res(JSON.parse( that.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(that.storage.cache[id]); } catch(e) | |
{ // Data Cannot Be Parsed | |
data = that.storage.cache[id]; | |
} finally { // Save Data To Local Store | |
// console.log("Data", data); | |
return data; | |
} | |
} | |
} | |
} | |
// Delete Feature | |
that.storage.delete = function(id) { | |
var s = storages.slice(); | |
s.splice(s.indexOf('cache'), 1); | |
for(var system in s) { | |
// Delete Stored Ref | |
delete that.storage[s[system]][id]; | |
} | |
// Delete From Cache | |
delete that.storage.cache[id]; | |
} | |
// Remove Single Reference | |
that.storage.deleteOne = function(id, index) { | |
/* Implementation Needs More Work To | |
determine how to remove object nodes | |
*/ | |
var data = that.storage.get(id), | |
type = typeof data !== 'string' || typeof data !== 'number' | |
? Array.isArray(data) | |
? 'array' | |
: typeof data === 'object' && !Array.isArray(data) | |
? 'object' | |
: 'basic' | |
: null; | |
console.log("Data", data); | |
if (type === 'array') return data.splice(index, 1), saveToAllStorageSystems(id, data); | |
if (type === 'object') return saveToAllStorageSystems(id ,deleteKey(data, index)); | |
if (type === 'basic') return that.storage.delete(id); | |
function deleteKey(object, key) { | |
console.warn("Delete This Key", key, "From Object", object); | |
// Iterate over each key in the object | |
// If You reach the key, delete it | |
// And return the object | |
var parsedKey = key.split('.'), | |
ref; | |
for (var i=0;i<parsedKey.length;i++){ | |
console.log("Working on Iteration - "+ i, "Ref", ref); | |
if (i < (parsedKey.length)) ref = object[parsedKey[i]]; | |
else console.log("Deleting This Ref", ref[parsedKey[i]])// delete ref[parsedKey[i]]; | |
return ref; | |
} | |
} | |
return data; | |
} | |
that.storage.manuallyUpdateLocalCache = function(property, value){ | |
// Add Item To Local Store | |
var cache = that.storage.cache; | |
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); | |
} | |
} | |
// Set Emtpy Function | |
that.storage.clear = function() | |
{ window['localStorage'].clear(); window['sessionStorage'].clear(); return "Local Storage Emptied"; }; | |
// Get All Data Saved In Local Storage | |
(function populateLocalCache(s) { | |
for(system in s) { | |
// Define Store Refs | |
var store = that.storage[s[system]]; | |
var cache = that.storage.cache; | |
// Loop over Prop Names and Save | |
// To Local Cache | |
for (var prop in store) { | |
// Add Item To Local Store | |
var data = that.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"; | |
// Set Length Of Storage | |
cache.length = Object.keys(cache).length; | |
// Hide Length From Enumeration | |
Object.defineProperty(cache, 'length', {enumerable: false}) | |
// console.log("Data Has Been Populated"); | |
return cache; | |
} | |
}(storages)); | |
// Disable Function Enumeration | |
that.prototype.disableFunctionEnumeration(that.storage); | |
} | |
}); | |
// console.log("Storage Object", StorageSystem); | |
// Listen For Changes From Other Clients | |
window.addEventListener('storage', function(e) { // Update Local Cache When DB Changes | |
that.storage.manuallyUpdateLocalCache(e.key, e.newValue); | |
}); | |
// Install the module to App Modules list | |
m.prototype.installModule(that); | |
// Set App Storage to Cached Data | |
m.setStore(that.storage.cache); | |
// Enable Main Module's Default Storage | |
m.setStorageDevice( that.storage ); | |
}( require('modules/main-module') )) | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
define(function (require) { | |
return (function(m){ | |
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.prototype.installModule = s.install; | |
this.prototype.uninstallModule = s.uninstall; | |
this.prototype.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 = s.messaging.setActive; | |
this.sendMessageToClient = s.sendMessageToClient; | |
this.setStore = s.setStore; | |
this.setStorageDevice = s.setStorageDevice; | |
this.localStorageDevice = {}; | |
this.localStorageDevice.save = this.getModuleProperty('storageDevice').save; | |
// Set State To Initialized | |
s.state.set({current: "App Initialized", last: s.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); | |
this.prototype.disableFunctionEnumeration(this.prototype); | |
// Define Properties for this module | |
Object.defineProperties(this, { | |
prototype: { | |
enumerable: false | |
}, | |
namespace: { | |
value: this.namespace, | |
writable: false | |
}, | |
localStorageDevice: { | |
enumerable: 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"; | |
// Class is an optional value to | |
// determine what css style | |
// is to be used eg: alert-danger or alert-success | |
if (!args) args = ""; | |
else if (Object.keys(args)[0] != 0) args = JSON.stringify(args); | |
if (!m.messaging.active.hasOwnProperty('log')) m.messaging.default.log(message, args); | |
else m.messaging.active.log(message, args, Class || m.messaging.active.Class); | |
} | |
// Set Storage Object | |
m.store = {}; | |
// Set Default Storage | |
m.storageDevice = {}; | |
m.setStore = function(storage){ m.store.data = storage; } | |
// Define Default Save Behavior | |
m.setStorageDevice = function(device){ m.storageDevice = device; } | |
// Save Functionality | |
m.storageDevice.saveDataToStore = function(data){ | |
console.log("Data To Save", data, m.storageDevice, this); | |
// Store Data Into Local Store | |
for ( var Class in data ) { m.store[Class] = data[Class]; } | |
} | |
m.events = {}; | |
m.events.prototype = {}; | |
m.events.prototype.setEventSystem = function(system) { | |
// If Object Is Available Set Event System | |
if (Object.keys(m.events).length <= 1 && m.events.hasOwnProperty('prototype')) | |
// For Each Property Add it to events Object | |
for (var property in system) { m.events[property] = system[property]; m.prototype.disableFunctionEnumeration(m.events)} | |
else return "Event System Already Set"; | |
} | |
// 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 | |
} | |
m.prototype = {}; | |
m.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; | |
} | |
// 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 self; }(m)); | |
}({})); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function(m){ | |
// Define The Module To Be Instantiated | |
var that; | |
var TestModule = that = 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 | |
that.components.properties = [1,2,4]; | |
// Install the module to App Modules list | |
m.prototype.installModule(that); | |
}(requirejs('modules/main-module'))); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
define(function (require) { | |
return (function(m){ | |
// Define The Module To Be Instantiated | |
var that; | |
var UserModule = that = new m.constructor({ | |
name: 'UserModule', | |
state: {current: "Test Module Initialized", last: m.getModuleProperty('state').prototype.memory }, | |
init: function(){ m.getModuleProperty('state').prototype.memory; } | |
}); | |
// Get Default Storage Device | |
var store = m.getModuleProperty('storageDevice'); | |
// Save User As Object | |
that.saveUser = function(user) { | |
// Get User Object From Storage | |
var users = m.getModuleProperty('store').data['Users'] || []; | |
// Add User If Not Already In List | |
var userInList = users.some(function(u){ return u.name == user.name }); | |
// Push and Save if User Not In List | |
// And Storage Device has Save Method | |
if (!userInList) users.push(user); | |
// Save The Users Object | |
if (store.hasOwnProperty('save') && !userInList) store.save("Users", users); | |
else if (store.hasOwnProperty('save') && userInList) m.sendMessageToClient('User Already In List', ''); | |
// Handle If No Storage Method Present | |
else console.warn("No Storage Device Set", "Find Other Save Method Or None At All"); | |
} | |
that.getUser = function(reference, value) { | |
// Provide a reference/ID and a Value | |
// To Retrieve a name.. Run function with | |
// No values to retrieve all users | |
var cache = m.getModuleProperty('store').data.Users; | |
return !!reference ? cache.filter(function(user){ if (user[reference]) return user[reference].search(value) >= 0; }) : cache; | |
} | |
// Install the module to App Modules list | |
m.prototype.installModule(that); | |
// Disable Enumeration for this Module | |
that.prototype.disableFunctionEnumeration(that); | |
}( require('modules/main-module') )) | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment