commit
4e1e04e526
@ -0,0 +1,4 @@ |
|||||||
|
node_modules/ |
||||||
|
assets/dist/ |
||||||
|
package-lock.json |
||||||
|
nbproject/ |
||||||
@ -0,0 +1,22 @@ |
|||||||
|
The MIT License |
||||||
|
|
||||||
|
Copyright (c) 2021 Robert Strutts |
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining |
||||||
|
a copy of this software and associated documentation files (the |
||||||
|
"Software"), to deal in the Software without restriction, including |
||||||
|
without limitation the rights to use, copy, modify, merge, publish, |
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to |
||||||
|
permit persons to whom the Software is furnished to do so, subject to |
||||||
|
the following conditions: |
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be |
||||||
|
included in all copies or substantial portions of the Software. |
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||||
@ -0,0 +1,15 @@ |
|||||||
|
# tts_js |
||||||
|
|
||||||
|
TTS Framework - JavaScript assets. |
||||||
|
|
||||||
|
Install node, npm, then GulpJS. |
||||||
|
Google how to install node & npm for your OS. |
||||||
|
|
||||||
|
GulpJS here: |
||||||
|
$ sudo npm install --global gulp-cli |
||||||
|
|
||||||
|
Goto this Repo where the package.json file exists, then run: |
||||||
|
$ npm install |
||||||
|
|
||||||
|
Now, Compile all JavaScript assets into the assets/dist folders: |
||||||
|
$ gulp |
||||||
@ -0,0 +1,3 @@ |
|||||||
|
For instance, jQuery is about 250kb (90kb if minified). |
||||||
|
Not that bad, huh? |
||||||
|
But, if you have 50,000 monthly visitors, jQuery will consume 4Gb! |
||||||
@ -0,0 +1,181 @@ |
|||||||
|
/* |
||||||
|
* @author Robert Strutts |
||||||
|
* @copyright 2019 |
||||||
|
* @license MIT |
||||||
|
* AJAX |
||||||
|
*/ |
||||||
|
|
||||||
|
tts.grab_form = function (form_id) { |
||||||
|
try { |
||||||
|
let myForm = document.getElementById(form_id); |
||||||
|
let arr = {}; |
||||||
|
for (var i = 0; i < myForm.elements.length; i++) { |
||||||
|
let id = myForm.elements[i].id; |
||||||
|
let value = myForm.elements[i].value; |
||||||
|
let node = myForm.elements[i].nodeName; |
||||||
|
if ((node == "INPUT" || node == "TEXTAREA" || node == "SELECT") && (typeof id !== "undefined" && id !== "")) { |
||||||
|
arr[id] = value; |
||||||
|
} |
||||||
|
} |
||||||
|
return arr; |
||||||
|
} catch (e) { |
||||||
|
tts.logger(e); |
||||||
|
return false; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
function json_parse(json) { |
||||||
|
try { |
||||||
|
var obj = JSON.parse(json); |
||||||
|
var unfetched = obj.unfetched; |
||||||
|
if (typeof unfetched !== "undefined") { |
||||||
|
console.warn(`You have some unFetched JSON Vars: ${unfetched}`); |
||||||
|
} |
||||||
|
var err = obj.error; |
||||||
|
if (typeof err === "undefined") { |
||||||
|
return obj; |
||||||
|
} else if (err !== null) { |
||||||
|
throw err; |
||||||
|
} |
||||||
|
} catch (e) { |
||||||
|
return e; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
tts.send_json = function (php_script, args) { |
||||||
|
let myPromise = new Promise(function (myResolve, myReject) { |
||||||
|
if (args === false) { |
||||||
|
let nodata = "No Data from Form!"; |
||||||
|
throw nodata; |
||||||
|
} |
||||||
|
var xmlhttp = new XMLHttpRequest(); // new HttpRequest instance
|
||||||
|
xmlhttp.open("POST", php_script); |
||||||
|
xmlhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); |
||||||
|
|
||||||
|
xmlhttp.onreadystatechange = function () { |
||||||
|
if (this.readyState == 4) { |
||||||
|
if (this.status == 200) { |
||||||
|
myResolve(json_parse(this.response)); |
||||||
|
} else { |
||||||
|
myReject(json_parse(this.response)); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
xmlhttp.send(JSON.stringify(args)); |
||||||
|
}); |
||||||
|
return myPromise; |
||||||
|
}; |
||||||
|
|
||||||
|
tts.Post = function (url, data) { |
||||||
|
return new Promise((resolve, reject) => { |
||||||
|
var request = new XMLHttpRequest(); |
||||||
|
request.open("POST", url, true); |
||||||
|
request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); |
||||||
|
request.onload = function (d) { |
||||||
|
resolve(d.currentTarget.responseText); |
||||||
|
}; |
||||||
|
try { |
||||||
|
request.send(data); |
||||||
|
} catch (err) { |
||||||
|
reject(err); |
||||||
|
} |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
function doProgress(eventName, evt) { |
||||||
|
if (eventName !== false && evt.lengthComputable) { |
||||||
|
var percentComplete = (evt.loaded / evt.total) * 100; |
||||||
|
var pc = Math.round(percentComplete); |
||||||
|
var event = new CustomEvent(eventName, {detail: {progress: pc}}); |
||||||
|
var el = document.getElementsByTagName('body')[0]; |
||||||
|
el.dispatchEvent(event); |
||||||
|
} |
||||||
|
} |
||||||
|
function setHTML(elementID, html) { |
||||||
|
try { |
||||||
|
return document.getElementById(elementID).innerHTML = html; |
||||||
|
} catch (e) { |
||||||
|
tts.logger("ID of " + elementID + " not found...!", "warn"); |
||||||
|
} |
||||||
|
} |
||||||
|
tts.lastAjax = false; /* So you can use the xmlHttp Request later on... if not cached... */ |
||||||
|
let ajaxCallback = function (url, resolve, reject, options) { |
||||||
|
var doCache = tts.getValue(options.useCache, false), eventName = tts.getValue(options.eventName, false); |
||||||
|
var elementID = tts.getValue(options.elementID, false), ts = tts.getValue(options.ts, ""); |
||||||
|
if (doCache) { |
||||||
|
var myCache = new tts.store(); |
||||||
|
if (myCache) { |
||||||
|
let stored_data = myCache.get(url + ts); /* timestamp cache buster */ |
||||||
|
let done = tts.getValue(stored_data, false); |
||||||
|
if (!tts.isEmpty(done)) { |
||||||
|
tts.logger('Used cache, on ' + url + ' !'); |
||||||
|
tts.lastAjax = false; |
||||||
|
doProgress(eventName, {lengthComputable: true, loaded: 100, total: 100}); |
||||||
|
if (elementID) { |
||||||
|
setHTML(elementID, stored_data); |
||||||
|
} |
||||||
|
return resolve(stored_data); |
||||||
|
} else { |
||||||
|
tts.logger('Adding to cache, for ' + url + ' !'); |
||||||
|
} |
||||||
|
} else { |
||||||
|
tts.logger('No Cache Engine enabled, for ' + url + ' !'); |
||||||
|
} |
||||||
|
} else { |
||||||
|
tts.logger('No Caching, for ' + url); |
||||||
|
} |
||||||
|
var xmlHttp = new XMLHttpRequest(); |
||||||
|
tts.lastAjax = xmlHttp; |
||||||
|
xmlHttp.upload.addEventListener("progress", function (evt) { |
||||||
|
doProgress(eventName, evt); |
||||||
|
}); |
||||||
|
xmlHttp.addEventListener("progress", function (evt) { |
||||||
|
doProgress(eventName, evt); |
||||||
|
}); |
||||||
|
xmlHttp.onreadystatechange = function () { |
||||||
|
var result; |
||||||
|
if (xmlHttp.readyState == 4) { |
||||||
|
if (xmlHttp.status == 200) { |
||||||
|
switch (options.dataType) { |
||||||
|
case 'xml': |
||||||
|
result = xmlHttp.responseXML; |
||||||
|
break; |
||||||
|
case 'json': |
||||||
|
result = JSON.parse(xmlHttp.responseText); |
||||||
|
break; |
||||||
|
default: |
||||||
|
result = xmlHttp.responseText; |
||||||
|
break; |
||||||
|
} |
||||||
|
if (myCache && doCache) { |
||||||
|
myCache.set(url + ts, result); |
||||||
|
} |
||||||
|
if (elementID) { |
||||||
|
setHTML(elementID, result); |
||||||
|
} |
||||||
|
resolve(result); |
||||||
|
} else if (reject) { |
||||||
|
reject('Ajax error: ' + xmlHttp.status + ' url: ' + url); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
xmlHttp.open(options.method || 'GET', url, true); |
||||||
|
if (options.headers) { |
||||||
|
for (var key in options.headers) { |
||||||
|
xmlHttp.setRequestHeader(key, options.headers[key]); |
||||||
|
} |
||||||
|
} |
||||||
|
xmlHttp.send(options.data || ''); |
||||||
|
}; |
||||||
|
tts.ajax = function (url, options) { |
||||||
|
if (typeof options === "undefined") { |
||||||
|
options = {}; |
||||||
|
} |
||||||
|
return new Promise(function (resolve, reject) { |
||||||
|
ajaxCallback(url, resolve, reject, options); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
/* |
||||||
|
* End of AJAX
|
||||||
|
*/ |
||||||
@ -0,0 +1,76 @@ |
|||||||
|
/* |
||||||
|
* Cookies |
||||||
|
*/ |
||||||
|
|
||||||
|
var pluses = /\+/g; |
||||||
|
function encode(s) { |
||||||
|
return config.raw ? s : encodeURIComponent(s); |
||||||
|
} |
||||||
|
function decode(s) { |
||||||
|
return config.raw ? s : decodeURIComponent(s); |
||||||
|
} |
||||||
|
function stringifyCookieValue(value) { |
||||||
|
return encode(config.json ? JSON.stringify(value) : String(value)); |
||||||
|
} |
||||||
|
function parseCookieValue(s) { |
||||||
|
if (s.indexOf('"') === 0) { /* This is a quoted cookie as according to RFC2068, unescape... */ |
||||||
|
s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\'); |
||||||
|
} |
||||||
|
try { |
||||||
|
/* Replace server-side written pluses with spaces. */ |
||||||
|
/* If we can't decode the cookie, ignore it, it's unusable. */ |
||||||
|
/* If we can't parse the cookie, ignore it, it's unusable. */ |
||||||
|
s = decodeURIComponent(s.replace(pluses, ' ')); |
||||||
|
return config.json ? JSON.parse(s) : s; |
||||||
|
} catch (e) { |
||||||
|
} |
||||||
|
} |
||||||
|
function read(s, converter) { |
||||||
|
var value = config.raw ? s : parseCookieValue(s); |
||||||
|
return tts.isFunction(converter) ? converter(value) : value; |
||||||
|
} |
||||||
|
var config = tts.cookie = function (key, value, options) { |
||||||
|
if (arguments.length > 1 && !tts.isFunction(value)) { /* Write */ |
||||||
|
options = tts.extend(config.defaults, options); |
||||||
|
if (typeof options.expires === 'number') { |
||||||
|
var days = options.expires, t = options.expires = new Date(); |
||||||
|
t.setMilliseconds(t.getMilliseconds() + days * 864e+5); |
||||||
|
} |
||||||
|
return (document.cookie = [ |
||||||
|
encode(key), '=', stringifyCookieValue(value), |
||||||
|
options.expires ? '; expires=' + options.expires.toUTCString() : '', /* use expires attribute, max-age is not supported by IE */ |
||||||
|
options.path ? '; path=' + options.path : '', |
||||||
|
options.domain ? '; domain=' + options.domain : '', |
||||||
|
options.secure ? '; secure' : '' |
||||||
|
].join('')); |
||||||
|
} |
||||||
|
var result = key ? undefined : {}, /* Read */ |
||||||
|
/* To prevent the for loop in the first place assign an empty array |
||||||
|
* in case there are no cookies at all. Also prevents odd result when |
||||||
|
* calling $.cookie().
|
||||||
|
*/ |
||||||
|
cookies = document.cookie ? document.cookie.split('; ') : [], l = cookies.length; |
||||||
|
for (let i = 0; i < l; i++) { |
||||||
|
var parts = cookies[i].split('='), name = decode(parts.shift()), cookie = parts.join('='); |
||||||
|
/* If second argument (value) is a function it's a converter... */ |
||||||
|
if (key === name) { |
||||||
|
result = read(cookie, value); |
||||||
|
break; |
||||||
|
} |
||||||
|
/* Prevent storing a cookie that we couldn't decode. */ |
||||||
|
if (!key && (cookie = read(cookie)) !== undefined) { |
||||||
|
result[name] = cookie; |
||||||
|
} |
||||||
|
} |
||||||
|
return result; |
||||||
|
}; |
||||||
|
config.defaults = {}; |
||||||
|
tts.removeCookie = function (key, options) { |
||||||
|
/* Must not alter options, thus extending a fresh object... */ |
||||||
|
tts.cookie(key, '', $.extend({}, options, {expires: -1})); |
||||||
|
return !$.cookie(key); |
||||||
|
}; |
||||||
|
|
||||||
|
/* |
||||||
|
* End of Cookies |
||||||
|
*/ |
||||||
@ -0,0 +1,361 @@ |
|||||||
|
/* |
||||||
|
* Grapnel Router |
||||||
|
* @author Greg Sabia Tucker <greg@narrowlabs.com> |
||||||
|
* @copyright 2019 Greg Sabia Tucker |
||||||
|
* @link https://github.com/baseprime/grapnel
|
||||||
|
* Released under MIT License. See http://opensource.org/licenses/MIT
|
||||||
|
*/ |
||||||
|
class MyRouter { |
||||||
|
constructor(opts) { |
||||||
|
var self = this; /* Scope reference */ |
||||||
|
this.events = {}; /* Event Listeners */ |
||||||
|
this.state = null; /* Router state object */ |
||||||
|
this.options = opts || {}; /* Options */ |
||||||
|
this.options.env = this.options.env || (!!(Object.keys(root).length === 0 && process && process.browser !== true) ? 'server' : 'client'); |
||||||
|
this.options.mode = this.options.mode || (!!(this.options.env !== 'server' && this.options.pushState && root.history && root.history.pushState) ? 'pushState' : 'hashchange'); |
||||||
|
if ('function' === typeof root.addEventListener) { |
||||||
|
root.addEventListener('hashchange', function () { |
||||||
|
self.trigger('hashchange'); |
||||||
|
}); |
||||||
|
root.addEventListener('popstate', function (e) { |
||||||
|
/* Make sure popstate doesn't run on init -- this is a common issue with Safari and old versions of Chrome */ |
||||||
|
if (self.state && self.state.previousState === null) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
self.trigger('navigate'); |
||||||
|
}); |
||||||
|
} |
||||||
|
return this; |
||||||
|
} |
||||||
|
} |
||||||
|
/** |
||||||
|
* Create a RegExp Route from a string |
||||||
|
* This is the heart of the router and I've made it as small as possible! |
||||||
|
* @param {String} path - Path of route |
||||||
|
* @param {Array} keys - Array of keys to fill |
||||||
|
* @param {Bool} sensitive - Case sensitive comparison |
||||||
|
* @param {Bool} strict - Strict mode |
||||||
|
*/ |
||||||
|
MyRouter.regexRoute = function (path, keys, sensitive, strict) { |
||||||
|
if (path instanceof RegExp) { |
||||||
|
return path; |
||||||
|
} |
||||||
|
if (path instanceof Array) { |
||||||
|
path = '(' + path.join('|') + ')'; |
||||||
|
} |
||||||
|
/* Build route RegExp */ |
||||||
|
path = path.concat(strict ? '' : '/?') |
||||||
|
.replace(/\/\(/g, '(?:/') |
||||||
|
.replace(/\+/g, '__plus__') |
||||||
|
.replace(/(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?/g, function (_, slash, format, key, capture, optional) { |
||||||
|
keys.push({name: key, optional: !!optional}); |
||||||
|
slash = slash || ''; |
||||||
|
return '' + (optional ? '' : slash) + '(?:' + (optional ? slash : '') + (format || '') + (capture || (format && '([^/.]+?)' || '([^/]+?)')) + ')' + (optional || ''); |
||||||
|
}) |
||||||
|
.replace(/([\/.])/g, '\\$1') |
||||||
|
.replace(/__plus__/g, '(.+)') |
||||||
|
.replace(/\*/g, '(.*)'); |
||||||
|
return new RegExp('^' + path + '$', sensitive ? '' : 'i'); |
||||||
|
}; |
||||||
|
/** |
||||||
|
* ForEach workaround utility |
||||||
|
* @param {Array} a - to iterate |
||||||
|
* @param {Function} callback |
||||||
|
*/ |
||||||
|
MyRouter._forEach = function (a, callback) { |
||||||
|
if (typeof Array.prototype.forEach === 'function') { |
||||||
|
return Array.prototype.forEach.call(a, callback); |
||||||
|
} |
||||||
|
/* Replicate forEach() */ |
||||||
|
return function (c, next) { |
||||||
|
for (var i = 0, n = this.length; i < n; ++i) { |
||||||
|
c.call(next, this[i], i, this); |
||||||
|
} |
||||||
|
}.call(a, callback); |
||||||
|
}; |
||||||
|
/** |
||||||
|
* Add an route and handler |
||||||
|
* @param {String|RegExp} route name |
||||||
|
* @return {self} Router |
||||||
|
*/ |
||||||
|
MyRouter.prototype.get = MyRouter.prototype.add = function (route) { |
||||||
|
var self = this, middleware = Array.prototype.slice.call(arguments, 1, -1), |
||||||
|
handler = Array.prototype.slice.call(arguments, -1)[0], request = new Request(route); |
||||||
|
var invoke = function RouteHandler() { |
||||||
|
/* Build request parameters */ |
||||||
|
var req = request.parse(self.path()); |
||||||
|
/* Check if matches are found */ |
||||||
|
if (req.match) { |
||||||
|
/* Match found */ |
||||||
|
var extra = {route: route, params: req.params, req: req, regex: req.match}; |
||||||
|
/* Create call stack -- add middleware first, then handler */ |
||||||
|
var stack = new CallStack(self, extra).enqueue(middleware.concat(handler)); |
||||||
|
/* Trigger main event */ |
||||||
|
self.trigger('match', stack, req); |
||||||
|
/* Continue */ |
||||||
|
if (!stack.runCallback) { |
||||||
|
return self; |
||||||
|
} |
||||||
|
/* Previous state becomes current state */ |
||||||
|
stack.previousState = self.state; |
||||||
|
/* Save new state */ |
||||||
|
self.state = stack; |
||||||
|
/* Prevent this handler from being called if parent handler in stack has instructed not to propagate any more events */ |
||||||
|
if (stack.parent() && stack.parent().propagateEvent === false) { |
||||||
|
stack.propagateEvent = false; |
||||||
|
return self; |
||||||
|
} |
||||||
|
/* Call handler */ |
||||||
|
stack.callback(); |
||||||
|
} |
||||||
|
/* Returns self */ |
||||||
|
return self; |
||||||
|
}; |
||||||
|
/* Event name */ |
||||||
|
var eventName = (self.options.mode !== 'pushState' && self.options.env !== 'server') ? 'hashchange' : 'navigate'; |
||||||
|
/* Invoke when route is defined, and once again when app navigates */ |
||||||
|
return invoke().on(eventName, invoke); |
||||||
|
}; |
||||||
|
/** |
||||||
|
* Fire an event listener |
||||||
|
* @param {String} event name |
||||||
|
* @param {Mixed} [attributes] Parameters that will be applied to event handler |
||||||
|
* @return {self} Router |
||||||
|
*/ |
||||||
|
MyRouter.prototype.trigger = function (event) { |
||||||
|
var self = this, params = Array.prototype.slice.call(arguments, 1); |
||||||
|
/* Call matching events */ |
||||||
|
if (this.events[event]) { |
||||||
|
MyRouter._forEach(this.events[event], function (fn) { |
||||||
|
fn.apply(self, params); |
||||||
|
}); |
||||||
|
} |
||||||
|
return this; |
||||||
|
}; |
||||||
|
/** |
||||||
|
* Add an event listener |
||||||
|
* @param {String} event name (multiple events can be called when separated by a space " ") |
||||||
|
* @param {Function} handler - callback |
||||||
|
* @return {self} Router |
||||||
|
*/ |
||||||
|
MyRouter.prototype.on = MyRouter.prototype.bind = function (event, handler) { |
||||||
|
var self = this, events = event.split(' '); |
||||||
|
MyRouter._forEach(events, function (event) { |
||||||
|
if (self.events[event]) { |
||||||
|
self.events[event].push(handler); |
||||||
|
} else { |
||||||
|
self.events[event] = [handler]; |
||||||
|
} |
||||||
|
}); |
||||||
|
return this; |
||||||
|
}; |
||||||
|
/** |
||||||
|
* Allow event to be called only once |
||||||
|
* @param {String} event name(s) |
||||||
|
* @param {Function} handler - callback |
||||||
|
* @return {self} Router |
||||||
|
*/ |
||||||
|
MyRouter.prototype.once = function (event, handler) { |
||||||
|
var ran = false; |
||||||
|
return this.on(event, function () { |
||||||
|
if (ran) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
ran = true; |
||||||
|
handler.apply(this, arguments); |
||||||
|
handler = null; |
||||||
|
return true; |
||||||
|
}); |
||||||
|
}; |
||||||
|
/** |
||||||
|
* @param {String} context - Route context (without trailing slash) |
||||||
|
* param {[Function]} Middleware (optional) |
||||||
|
* @return {Function} Adds route to context |
||||||
|
*/ |
||||||
|
MyRouter.prototype.context = function (context) { |
||||||
|
var self = this, middleware = Array.prototype.slice.call(arguments, 1); |
||||||
|
return function () { |
||||||
|
var value = arguments[0], |
||||||
|
submiddleware = (arguments.length > 2) ? Array.prototype.slice.call(arguments, 1, -1) : [], |
||||||
|
handler = Array.prototype.slice.call(arguments, -1)[0], |
||||||
|
prefix = (context.slice(-1) !== '/' && value !== '/' && value !== '') ? context + '/' : context, |
||||||
|
path = (value.substr(0, 1) !== '/') ? value : value.substr(1), |
||||||
|
pattern = prefix + path; |
||||||
|
return self.add.apply(self, [pattern].concat(middleware).concat(submiddleware).concat([handler])); |
||||||
|
}; |
||||||
|
}; |
||||||
|
/** |
||||||
|
* Navigate through history API |
||||||
|
* @param {String} path - Pathname |
||||||
|
* @return {self} Router |
||||||
|
*/ |
||||||
|
MyRouter.prototype.navigate = function (path) { |
||||||
|
return this.path(path).trigger('navigate'); |
||||||
|
}; |
||||||
|
MyRouter.prototype.path = function (pathname) { |
||||||
|
var self = this, frag; |
||||||
|
if ('string' === typeof pathname) { |
||||||
|
/* Set path */ |
||||||
|
if (self.options.mode === 'pushState') { |
||||||
|
frag = (self.options.root) ? (self.options.root + pathname) : pathname; |
||||||
|
root.history.pushState({}, null, frag); |
||||||
|
} else if (root.location) { |
||||||
|
root.location.hash = (self.options.hashBang ? '!' : '') + pathname; |
||||||
|
} else { |
||||||
|
root._pathname = pathname || ''; |
||||||
|
} |
||||||
|
return this; |
||||||
|
} else if ('undefined' === typeof pathname) { |
||||||
|
/* Get path */ |
||||||
|
if (self.options.mode === 'pushState') { |
||||||
|
frag = root.location.pathname.replace(self.options.root, ''); |
||||||
|
} else if (self.options.mode !== 'pushState' && root.location) { |
||||||
|
frag = (root.location.hash) ? root.location.hash.split((self.options.hashBang ? '#!' : '#'))[1] : ''; |
||||||
|
} else { |
||||||
|
frag = root._pathname || ''; |
||||||
|
} |
||||||
|
return frag; |
||||||
|
} else if (pathname === false) { |
||||||
|
/* Clear path */ |
||||||
|
if (self.options.mode === 'pushState') { |
||||||
|
root.history.pushState({}, null, self.options.root || '/'); |
||||||
|
} else if (root.location) { |
||||||
|
root.location.hash = (self.options.hashBang) ? '!' : ''; |
||||||
|
} |
||||||
|
return self; |
||||||
|
} |
||||||
|
}; |
||||||
|
/** |
||||||
|
* Create routes based on an object |
||||||
|
* @param {Object} [Options, Routes] |
||||||
|
* @param {Object Routes} |
||||||
|
* @return {self} Router |
||||||
|
*/ |
||||||
|
MyRouter.listen = function () { |
||||||
|
var opts, routes; |
||||||
|
if (arguments[0] && arguments[1]) { |
||||||
|
opts = arguments[0]; |
||||||
|
routes = arguments[1]; |
||||||
|
} else { |
||||||
|
routes = arguments[0]; |
||||||
|
} |
||||||
|
/* Return a new MyRouter instance */ |
||||||
|
return (function () { |
||||||
|
/* TODO: Accept multi-level routes */ |
||||||
|
for (var key in routes) { |
||||||
|
this.add.call(this, key, routes[key]); |
||||||
|
} |
||||||
|
return this; |
||||||
|
}).call(new MyRouter(opts || {})); |
||||||
|
}; |
||||||
|
/** |
||||||
|
* Create a call stack that can be enqueued by handlers and middleware |
||||||
|
* @param {Object} router - Router |
||||||
|
* @param {Object} extendObj - Extend |
||||||
|
* @return {self} CallStack |
||||||
|
*/ |
||||||
|
class CallStack { |
||||||
|
constructor(router, extendObj) { |
||||||
|
this.stack = CallStack.global.slice(0); |
||||||
|
this.router = router; |
||||||
|
this.runCallback = true; |
||||||
|
this.callbackRan = false; |
||||||
|
this.propagateEvent = true; |
||||||
|
this.value = router.path(); |
||||||
|
for (var key in extendObj) { |
||||||
|
this[key] = extendObj[key]; |
||||||
|
} |
||||||
|
return this; |
||||||
|
} |
||||||
|
} |
||||||
|
/** |
||||||
|
* Build request parameters and allow them to be checked against a string (usually the current path) |
||||||
|
* @param {String} route - Route |
||||||
|
* @return {self} Request
|
||||||
|
*/ |
||||||
|
function Request(route) { |
||||||
|
this.route = route; |
||||||
|
this.keys = []; |
||||||
|
this.regex = MyRouter.regexRoute(route, this.keys); |
||||||
|
} |
||||||
|
; |
||||||
|
/* This allows global middleware */ |
||||||
|
CallStack.global = []; |
||||||
|
/** |
||||||
|
* Prevent a callback from being called |
||||||
|
* @return {self} CallStack
|
||||||
|
*/ |
||||||
|
CallStack.prototype.preventDefault = function () { |
||||||
|
this.runCallback = false; |
||||||
|
}; |
||||||
|
/** |
||||||
|
* Prevent any future callbacks from being called |
||||||
|
* @return {self} CallStack
|
||||||
|
*/ |
||||||
|
CallStack.prototype.stopPropagation = function () { |
||||||
|
this.propagateEvent = false; |
||||||
|
}; |
||||||
|
/** |
||||||
|
* Get parent state |
||||||
|
* @return {Object} Previous state
|
||||||
|
*/ |
||||||
|
CallStack.prototype.parent = function () { |
||||||
|
var hasParentEvents = !!(this.previousState && this.previousState.value && this.previousState.value == this.value); |
||||||
|
return (hasParentEvents) ? this.previousState : false; |
||||||
|
}; |
||||||
|
/** |
||||||
|
* Run a callback (calls to next) |
||||||
|
* @return {self} CallStack
|
||||||
|
*/ |
||||||
|
CallStack.prototype.callback = function () { |
||||||
|
this.callbackRan = true; |
||||||
|
this.timeStamp = Date.now(); |
||||||
|
this.next(); |
||||||
|
}; |
||||||
|
/** |
||||||
|
* Add handler or middleware to the stack |
||||||
|
* @param {Function|Array} handler - Handler or a array of handlers |
||||||
|
* @param {Int} atIndex - Index to start inserting |
||||||
|
* @return {self} CallStack
|
||||||
|
*/ |
||||||
|
CallStack.prototype.enqueue = function (handler, atIndex) { |
||||||
|
var handlers = (!Array.isArray(handler)) ? [handler] : ((atIndex < handler.length) ? handler.reverse() : handler); |
||||||
|
while (handlers.length) { |
||||||
|
this.stack.splice(atIndex || this.stack.length + 1, 0, handlers.shift()); |
||||||
|
} |
||||||
|
return this; |
||||||
|
}; |
||||||
|
/** |
||||||
|
* Call to next item in stack -- this adds the `req`, `event`, and `next()` arguments to all middleware |
||||||
|
* @return {self} CallStack
|
||||||
|
*/ |
||||||
|
CallStack.prototype.next = function () { |
||||||
|
var self = this; |
||||||
|
return this.stack.shift().call(this.router, this.req, this, function next() { |
||||||
|
self.next.call(self); |
||||||
|
}); |
||||||
|
}; |
||||||
|
/** |
||||||
|
* Match a path string -- returns a request object if there is a match -- returns false otherwise |
||||||
|
* @param {String} path
|
||||||
|
* @return {Object} req |
||||||
|
*/ |
||||||
|
Request.prototype.parse = function (path) { |
||||||
|
var match = path.match(this.regex), self = this; |
||||||
|
var req = {params: {}, keys: this.keys, matches: (match || []).slice(1), match: match}; |
||||||
|
/* Build parameters */ |
||||||
|
MyRouter._forEach(req.matches, function (value, i) { |
||||||
|
var key = (self.keys[i] && self.keys[i].name) ? self.keys[i].name : i; |
||||||
|
/* Parameter key will be its key or the iteration index. This is useful if a wildcard (*) is matched */ |
||||||
|
req.params[key] = (value) ? decodeURIComponent(value) : undefined; |
||||||
|
}); |
||||||
|
return req; |
||||||
|
}; |
||||||
|
|
||||||
|
MyRouter.CallStack = CallStack; |
||||||
|
MyRouter.Request = Request; |
||||||
|
tts.Router = new MyRouter(); |
||||||
|
|
||||||
|
/* |
||||||
|
* End of MyRouter Router
|
||||||
|
*/ |
||||||
@ -0,0 +1,115 @@ |
|||||||
|
/* |
||||||
|
* Load Assets |
||||||
|
* @author Robert Strutts |
||||||
|
* @copyright 2019 |
||||||
|
* @license MIT |
||||||
|
*/ |
||||||
|
|
||||||
|
var assets_loaded_once = []; |
||||||
|
|
||||||
|
tts.AddAssetCachedFile = function (full_file) { |
||||||
|
assets_loaded_once.push(full_file); |
||||||
|
}; |
||||||
|
/** |
||||||
|
* Get an StyleSheet/Script |
||||||
|
* @param {Object} source - CSS/JavaScript File with Options |
||||||
|
* @param {Object} options - element to use, etc... |
||||||
|
* @returns {Promise} |
||||||
|
*/ |
||||||
|
tts.getAsset = (source, options) => { |
||||||
|
if (typeof options === "undefined") { |
||||||
|
options = {}; |
||||||
|
} |
||||||
|
return new Promise((resolve, reject) => { |
||||||
|
var defaults_caching = tts.getValue(DO_CACHE_ON_ASSETS, true); |
||||||
|
var file = source.name, kind = file.split('.').pop(), doCache = tts.getValue(source.useCache, defaults_caching); |
||||||
|
var full_file = tts.getValue(source.path, "") + file; |
||||||
|
var ts = tts.getValue(source.ts, ""); |
||||||
|
var has_loaded = (assets_loaded_once.indexOf(full_file) === -1) ? false : true; |
||||||
|
if (has_loaded) { |
||||||
|
resolve("Already Loaded..." + full_file); |
||||||
|
} else { |
||||||
|
assets_loaded_once.push(full_file); |
||||||
|
switch (kind) { |
||||||
|
case 'css': |
||||||
|
var dataType = tts.getValue(source.dataType, "text/css"), style = document.createElement('style'); |
||||||
|
var elm = tts.getValue(options.element, document.getElementsByTagName('style')[0] || document.getElementsByTagName('head')[0]); |
||||||
|
var loaded = tts.ajax(full_file, {dataType: "text/css", useCache: doCache, ts: ts}); |
||||||
|
loaded.then(function (code) { |
||||||
|
style.type = dataType; |
||||||
|
style.innerText = code; |
||||||
|
elm.parentNode.insertBefore(style, elm.nextSibling); |
||||||
|
setTimeout(function () { |
||||||
|
resolve(); |
||||||
|
}, 12); |
||||||
|
}); |
||||||
|
loaded.catch(function (e) { |
||||||
|
reject(e); |
||||||
|
}); |
||||||
|
break; |
||||||
|
default: |
||||||
|
var dataType = tts.getValue(source.dataType, "text/javascript"); |
||||||
|
var script = document.createElement('script'); |
||||||
|
var elm = tts.getValue(options.element, document.getElementsByTagName('script')[0] || document.getElementsByTagName('head')[0]); |
||||||
|
var loaded = tts.ajax(full_file, {dataType: "text/javascript", useCache: doCache, ts: ts}); |
||||||
|
loaded.then(function (code) { |
||||||
|
script.type = dataType; |
||||||
|
script.text = code; |
||||||
|
elm.parentNode.insertBefore(script, elm); |
||||||
|
setTimeout(function () { |
||||||
|
resolve(); |
||||||
|
}, 12); |
||||||
|
}); |
||||||
|
loaded.catch(function (e) { |
||||||
|
reject(e); |
||||||
|
}); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
}; |
||||||
|
/** Useage: to combine options on each Asset for use with getMultiAssets. |
||||||
|
* Updates the sources Array/Objects with new data from Options.....as it is passed by Reference!!! |
||||||
|
* @param {Array of Objects} sources - CSS/JavaScript File with Options |
||||||
|
* @param {Array of Objects} options - path, useCache, dataType... |
||||||
|
*/ |
||||||
|
tts.mergeOptions = function (sources, options) { |
||||||
|
let keys = Object.keys(options); |
||||||
|
for (let key of keys) { |
||||||
|
for (var x = 0; x < sources.length; x++) { |
||||||
|
if (typeof sources[x][key] === 'undefined') { |
||||||
|
sources[x][key] = options[key]; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
/** |
||||||
|
*
|
||||||
|
* @param {Array of Objects} sources - CSS/JavaScript File with Options |
||||||
|
* @param {Object} options - element to apply to, etc... |
||||||
|
* @returns {Promise} - All done will all Files. |
||||||
|
*/ |
||||||
|
tts.getMultiAssets = (sources, options) => { |
||||||
|
if (typeof options === "undefined") { |
||||||
|
options = {}; |
||||||
|
} |
||||||
|
var prArr = []; |
||||||
|
sources.forEach(function (source) { |
||||||
|
(function (source) { |
||||||
|
prArr.push(new Promise(function (resolve, reject) { |
||||||
|
tts.getAsset(source, options).then(function () { |
||||||
|
resolve(); |
||||||
|
}).catch(function (e) { |
||||||
|
reject(e); |
||||||
|
}); |
||||||
|
})); |
||||||
|
})(source); |
||||||
|
}); |
||||||
|
return Promise.all(prArr, function () { |
||||||
|
return true; |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
/* |
||||||
|
* End of Assets |
||||||
|
*/ |
||||||
@ -0,0 +1,69 @@ |
|||||||
|
/* |
||||||
|
* Local Storage |
||||||
|
*/ |
||||||
|
function store(temp) { |
||||||
|
if (typeof temp === "undefined") { |
||||||
|
this.temp = false; |
||||||
|
} else { |
||||||
|
this.temp = temp; |
||||||
|
} |
||||||
|
if (typeof (Storage) !== "undefined") { |
||||||
|
return true; |
||||||
|
} else { |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
store.prototype.set = function (name, data) { |
||||||
|
try { |
||||||
|
if (typeof (Storage) !== "undefined") { |
||||||
|
var d = JSON.stringify(data); |
||||||
|
if (this.temp === false) { |
||||||
|
localStorage.setItem(name, d); |
||||||
|
} else { |
||||||
|
sessionStorage.setItem(name, d); |
||||||
|
} |
||||||
|
return true; |
||||||
|
} else { |
||||||
|
return false; |
||||||
|
} |
||||||
|
} catch (er) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
}; |
||||||
|
store.prototype.get = function (name) { |
||||||
|
if (typeof (Storage) !== "undefined") { |
||||||
|
if (this.temp === false) { |
||||||
|
return JSON.parse(localStorage.getItem(name)); |
||||||
|
} else { |
||||||
|
return JSON.parse(sessionStorage.getItem(name)); |
||||||
|
} |
||||||
|
} else { |
||||||
|
return false; |
||||||
|
} |
||||||
|
}; |
||||||
|
store.prototype.remove = function (name) { |
||||||
|
if (typeof (Storage) !== "undefined") { |
||||||
|
if (this.temp === false) { |
||||||
|
localStorage.removeItem(name); |
||||||
|
} else { |
||||||
|
sessionStorage.removeItem(name); |
||||||
|
} |
||||||
|
return true; |
||||||
|
} else { |
||||||
|
return false; |
||||||
|
} |
||||||
|
}; |
||||||
|
store.prototype.clear = function () { |
||||||
|
if (typeof (Storage) !== "undefined") { |
||||||
|
if (this.temp === false) { |
||||||
|
localStorage.clear(); |
||||||
|
} else { |
||||||
|
sessionStorage.clear(); |
||||||
|
} |
||||||
|
return true; |
||||||
|
} else { |
||||||
|
return false; |
||||||
|
} |
||||||
|
}; |
||||||
|
tts.store = store; |
||||||
|
/* End of Local Storage */ |
||||||
@ -0,0 +1,143 @@ |
|||||||
|
/* |
||||||
|
* Begin Logger
|
||||||
|
* @author Robert Strutts |
||||||
|
* @copyright 2019 |
||||||
|
* @license MIT |
||||||
|
*/ |
||||||
|
|
||||||
|
tts.time = function () { |
||||||
|
var now = new Date(), hours = now.getHours() % 12 || 12, minutes = now.getMinutes(), seconds = now.getSeconds(), XM = (now.getHours() < 12) ? "AM" : "PM", formmated = hours + ":" + minutes + ":" + seconds + " " + XM; |
||||||
|
return formmated; |
||||||
|
}; |
||||||
|
tts.debugMode = true; |
||||||
|
tts.doTrace = false; |
||||||
|
var startTimer = [], endTimer = [], time = [], beginCodeTimer = 0, loggerData = [{message: navigator.userAgent, kind: "userAgent", option: ""}]; |
||||||
|
tts.allowedElapsedTime = 4000; |
||||||
|
tts.completedCodeTimer = 0; |
||||||
|
tts.startCodeTimer = function () { |
||||||
|
beginCodeTimer = Date.now(); |
||||||
|
}; |
||||||
|
tts.endCodeTimer = function () { |
||||||
|
tts.completedCodeTimer = Date.now() - beginCodeTimer; |
||||||
|
loggerData.push({message: "Toal Code Time Elapsed", kind: "MainTimer", option: tts.completedCodeTimer}); |
||||||
|
if (tts.completedCodeTimer > tts.allowedElapsedTime) { |
||||||
|
tts.sendReport(); |
||||||
|
} |
||||||
|
}; |
||||||
|
tts.getLoggerData = loggerData; |
||||||
|
tts.logger = function (message, level, option) { |
||||||
|
if (typeof level === "undefined") { |
||||||
|
level = "info"; |
||||||
|
} |
||||||
|
if (typeof option === "undefined") { |
||||||
|
option = ""; |
||||||
|
} |
||||||
|
if (tts.debugMode === false || !window.console) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
if (typeof message === "object") { |
||||||
|
message = `[ ${tts.time()} ] ` + JSON.stringify(message); |
||||||
|
} else { |
||||||
|
message = `[ ${tts.time()} ] ${message}`; |
||||||
|
} |
||||||
|
if (level === "microStart" || level === "start") { |
||||||
|
console.group(message, option); |
||||||
|
} else if (level === "microStop" || level === "stop") { |
||||||
|
console.groupEnd(message, option); |
||||||
|
} else { |
||||||
|
loggerData.push({message: message, kind: level, option: option}); |
||||||
|
} |
||||||
|
if (tts.doTrace && (level === "warn" || level === "error")) { |
||||||
|
console.trace(); |
||||||
|
} |
||||||
|
if (level === "info" && console.info) { |
||||||
|
console.info(message); |
||||||
|
} else if (level === "microStart" && performance.now) { |
||||||
|
startTimer[option] = performance.now(); |
||||||
|
} else if (level === "microStop" && performance.now) { |
||||||
|
endTimer[option] = performance.now(); |
||||||
|
var data = endTimer[option] - startTimer[option]; |
||||||
|
console.info(data); |
||||||
|
loggerData.push({message: message, kind: level, option: data}); |
||||||
|
} else if (level === "warn" && console.warn) { |
||||||
|
console.warn(message); |
||||||
|
} else if (level === "error" && console.error) { |
||||||
|
console.error(message); |
||||||
|
} else if (level === "table" && console.table) { |
||||||
|
console.table(message, option); /* option = Table Column */ |
||||||
|
} else if (level === "group" && console.group) { |
||||||
|
console.group(message, option); /* option = Group Label */ |
||||||
|
} else if (level === "end" && console.groupEnd) { |
||||||
|
console.groupEnd(message, option); /* option = Group Label */ |
||||||
|
} else if (level === "trace" && console.trace) { |
||||||
|
console.trace(); |
||||||
|
} else if (level === "start" && console.time) { |
||||||
|
console.time(option); |
||||||
|
time[option] = Date.now(); |
||||||
|
} else if (level === "stop" && console.timeEnd) { |
||||||
|
console.timeEnd(option); |
||||||
|
var data = Date.now() - time[option]; |
||||||
|
loggerData.push({message: message, kind: level, option: data}); |
||||||
|
} else if (console.log) { |
||||||
|
console.log(message); /* for Chorme Console is enabled */ |
||||||
|
} |
||||||
|
}; |
||||||
|
tts.ReportsURL = ""; |
||||||
|
tts.sendReport = function (markComplete) { |
||||||
|
return new Promise((resolve, reject) => { |
||||||
|
if (tts.ReportsURL === "") { |
||||||
|
reject(); |
||||||
|
} else { |
||||||
|
var strValues = "&logs=" + encodeURI(JSON.stringify(loggerData)); |
||||||
|
if (sent_errors_yet === false) { |
||||||
|
if (typeof markComplete === 'undefined') { |
||||||
|
markComplete = false; |
||||||
|
} |
||||||
|
if (markComplete === true) { |
||||||
|
sent_errors_yet = true; |
||||||
|
} |
||||||
|
tts.Post(tts.ReportsURL, strValues).then(values => { |
||||||
|
resolve(values); |
||||||
|
}).catch(errors => { |
||||||
|
reject(errors); |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
}; |
||||||
|
var sent_errors_yet = false; |
||||||
|
function errorReports(errorMsg, url, lineNumber, column, errorObj) { |
||||||
|
if (tts.ReportsURL === "") { |
||||||
|
return false; |
||||||
|
} |
||||||
|
if (errorMsg.indexOf('Script error.') > -1 || typeof errorMsg === "null") { |
||||||
|
return; /* At the moment, we filter out the exceptions for iOS Safari and older Androids by checking if the error message is equal to “Script error.”. */ |
||||||
|
} |
||||||
|
|
||||||
|
var strValues = "errMessage=" + encodeURI(errorMsg); |
||||||
|
strValues += "&errLine=" + encodeURI(lineNumber); |
||||||
|
if (typeof column !== "undeinfed" && typeof column !== "null") { |
||||||
|
strValues += "&errColumn=" + encodeURI(column); |
||||||
|
} |
||||||
|
if (typeof errorObj !== "undeinfed" && typeof errorObj !== "null") { |
||||||
|
strValues += "&errObject=" + encodeURI(errorObj); |
||||||
|
} |
||||||
|
strValues += "&queryString=" + encodeURI(location.search); |
||||||
|
strValues += "&Url=" + encodeURI(url); |
||||||
|
strValues += "&Path=" + encodeURI(location.pathname); |
||||||
|
strValues += "&Hash=" + encodeURI(location.hash); |
||||||
|
strValues += "&HTTPRef=" + encodeURI(document.referrer); |
||||||
|
strValues += "&logs=" + encodeURI(JSON.stringify(loggerData)); |
||||||
|
if (sent_errors_yet === false) { |
||||||
|
tts.Post(tts.ReportsURL, strValues); |
||||||
|
} |
||||||
|
sent_errors_yet = true; |
||||||
|
} |
||||||
|
try { |
||||||
|
window.onerror = errorReports; |
||||||
|
} catch (er) { |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
* End of Logger
|
||||||
|
*/ |
||||||
@ -0,0 +1,41 @@ |
|||||||
|
/* |
||||||
|
* Printer Support |
||||||
|
* @author Robert Strutts |
||||||
|
* @copyright 2019 |
||||||
|
* @license MIT |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Printer Framed Window */ |
||||||
|
var array_of_frames = []; /* Needed to track open iFrames */ |
||||||
|
var printFrameID = 0; |
||||||
|
function donePrintFrame() { |
||||||
|
var frm = document.getElementById(printFrameID).contentWindow; |
||||||
|
frm.focus(); |
||||||
|
frm.print(); /* set focus on contentWindow is needed on some ie versions */ |
||||||
|
} |
||||||
|
/* id is the id of the iframe */ |
||||||
|
tts.printFrame = function (id, src) { |
||||||
|
try { |
||||||
|
for (var i = 0; i < array_of_frames.length; i++) { |
||||||
|
document.body.removeChild(array_of_frames[i]); /* Delete old page when done, for new data */ |
||||||
|
array_of_frames.pop(); |
||||||
|
} |
||||||
|
var newIframe = document.createElement('iframe'); |
||||||
|
newIframe.width = '0'; |
||||||
|
newIframe.height = '0'; |
||||||
|
newIframe.name = id; |
||||||
|
newIframe.id = id; |
||||||
|
newIframe.src = src; |
||||||
|
printFrameID = id; |
||||||
|
document.body.appendChild(newIframe); |
||||||
|
array_of_frames.push(newIframe); /* Add frame to list to be removed next time */ |
||||||
|
newIframe.onload = donePrintFrame; |
||||||
|
} catch (err) { |
||||||
|
tts.logger(err.message); |
||||||
|
} |
||||||
|
return false; |
||||||
|
}; |
||||||
|
|
||||||
|
/* |
||||||
|
* End of Printer Support |
||||||
|
*/ |
||||||
@ -0,0 +1,2 @@ |
|||||||
|
var prefData = window.performance.timing; |
||||||
|
!(function (root, window, document, pref_data, undefined) { // (immediately-invoked function expression), for Private Scope. ! means an expression
|
||||||
@ -0,0 +1,381 @@ |
|||||||
|
/* |
||||||
|
* Miq |
||||||
|
@copyright 2019 Edwin Martin |
||||||
|
@link https://github.com/edwinm/miq/blob/master/miq.js
|
||||||
|
@license MIT |
||||||
|
* |
||||||
|
* Miq, the micro jQuery library |
||||||
|
*/ |
||||||
|
var tts = function (arg, doc) { |
||||||
|
doc = doc && doc.first || doc || document; |
||||||
|
if (typeof arg == 'function') { /* $(function() {...}) */ |
||||||
|
if (doc.readyState == 'loading') { |
||||||
|
doc.addEventListener('DOMContentLoaded', arg); |
||||||
|
} else { |
||||||
|
arg(); |
||||||
|
} |
||||||
|
} else { |
||||||
|
var ret = Object.create(tts.fn), match; /* $([domObject]) or $(ttsObject) */ |
||||||
|
if (typeof arg == 'object') { |
||||||
|
if ('length' in arg) { |
||||||
|
ret.length = arg.length; |
||||||
|
for (var o = 0; o < arg.length; o++) { |
||||||
|
ret[o] = arg[o]; |
||||||
|
} |
||||||
|
} else { /* $(domObject) */ |
||||||
|
ret[0] = arg; |
||||||
|
ret.length = 1; |
||||||
|
} |
||||||
|
} else if (!arg) { /* $() */ |
||||||
|
ret[0] = doc.createDocumentFragment(); |
||||||
|
ret.length = 1; |
||||||
|
} else if ((match = arg.match(/<(.+)>/))) { /* $('<div>') */ |
||||||
|
ret[0] = doc.createElement(match[1]); |
||||||
|
ret.length = 1; |
||||||
|
} else { /* $('div.widget') */ |
||||||
|
var els = doc.querySelectorAll(arg); |
||||||
|
ret.length = els.length; |
||||||
|
for (var w = 0; w < els.length; w++) { |
||||||
|
ret[w] = els[w]; |
||||||
|
} |
||||||
|
} |
||||||
|
return ret; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
tts.version = "1.0"; |
||||||
|
tts.performanceData = pref_data; |
||||||
|
tts.pageLoadTime = function () { |
||||||
|
return pref_data.loadEventEnd - pref_data.navigationStart; |
||||||
|
}; |
||||||
|
tts.connectTime = function () { |
||||||
|
return pref_data.responseEnd - pref_data.requestStart; |
||||||
|
}; |
||||||
|
tts.renderTime = function () { |
||||||
|
return pref_data.domComplete - pref_data.domLoading; |
||||||
|
}; |
||||||
|
tts.isNotSet = function (check) { |
||||||
|
return (check === null || typeof check === "undefined" || check.length === 0) ? true : false; |
||||||
|
}; |
||||||
|
tts.getValue = function (input, defaults) { |
||||||
|
return (tts.isNotSet(input) === true) ? defaults : input; |
||||||
|
}; |
||||||
|
tts.matches = ['matches', 'webkitMatchesSelector', 'mozMatchesSelector', 'msMatchesSelector'].filter(function (sel) { |
||||||
|
return sel in document.documentElement; |
||||||
|
})[0]; |
||||||
|
tts.fn = Object.create(Array.prototype, { |
||||||
|
each: {value: function (callback) { |
||||||
|
if ( ! tts.isFunction(callback) ) { |
||||||
|
/*throw new Error("Callback should be a function");*/ |
||||||
|
} |
||||||
|
var $this = {}; |
||||||
|
for (var index = 0; index < this.length; index++) { |
||||||
|
$this = this[index]; |
||||||
|
$this.callback = callback; |
||||||
|
$this.callback(index); |
||||||
|
} |
||||||
|
return this; |
||||||
|
}}, |
||||||
|
first: {get: function () { |
||||||
|
return this[0]; |
||||||
|
}}, |
||||||
|
eq: {value: function (i) { |
||||||
|
return tts(this[i || 0]); |
||||||
|
}}, |
||||||
|
on: {value: function (evt, fn) { |
||||||
|
if (!tts.isFunction(fn)) |
||||||
|
tts.logger('Callback should be a function', 'warn'); |
||||||
|
var hasit = this[0].addEventListener; |
||||||
|
for (var i = 0; i < this.length; i++) { |
||||||
|
if (hasit) { |
||||||
|
this[i].addEventListener(evt, fn); |
||||||
|
} else { |
||||||
|
this[i].attachEvent("on" + evt, fn); |
||||||
|
} |
||||||
|
} |
||||||
|
return this; |
||||||
|
}}, |
||||||
|
off: {value: function (evt, fn) { |
||||||
|
if (!tts.isFunction(fn)) |
||||||
|
tts.logger('Callback should be a function', 'warn'); |
||||||
|
var hasit = this[0].removeEventListener; |
||||||
|
for (var i = 0; i < this.length; i++) { |
||||||
|
if (hasit) { |
||||||
|
this[i].removeEventListener(evt, fn); |
||||||
|
} else { |
||||||
|
this[i].detachEvent("on" + evt, fn); |
||||||
|
} |
||||||
|
} |
||||||
|
return this; |
||||||
|
}}, |
||||||
|
trigger: {value: function (eventName) { |
||||||
|
for (var i = 0; i < this.length; i++) { |
||||||
|
var event = document.createEvent('Event'); |
||||||
|
event.initEvent(eventName, true, true); |
||||||
|
this[i].dispatchEvent(event); |
||||||
|
} |
||||||
|
return this; |
||||||
|
}}, |
||||||
|
toggleClass: {value: function (cls) { |
||||||
|
for (var i = 0; i < this.length; i++) { |
||||||
|
if (this[i].classList) { |
||||||
|
this[i].classList.toggle(cls); |
||||||
|
} else { |
||||||
|
var classes = this[i].className.split(' '); |
||||||
|
var existingIndex = classes.indexOf(cls); |
||||||
|
if (existingIndex >= 0) { |
||||||
|
classes.splice(existingIndex, 1); |
||||||
|
} else { |
||||||
|
classes.push(cls); |
||||||
|
} |
||||||
|
this[i].className = classes.join(' '); |
||||||
|
} |
||||||
|
} |
||||||
|
return this; |
||||||
|
}}, |
||||||
|
addClass: {value: function (cls) { |
||||||
|
for (var i = 0; i < this.length; i++) { |
||||||
|
if (!tts.fn.hasClass.call({first: this[i]}, cls)) { |
||||||
|
this[i].className += ' ' + cls; |
||||||
|
} |
||||||
|
} |
||||||
|
return this; |
||||||
|
}}, |
||||||
|
removeClass: {value: function (cls) { |
||||||
|
for (var i = 0; i < this.length; i++) { |
||||||
|
this[i].className = this[i].className.replace(cls, ''); |
||||||
|
} |
||||||
|
return this; |
||||||
|
}}, |
||||||
|
hasClass: {value: function (cls) { |
||||||
|
return this.first.className != '' && new RegExp('\\b' + cls + '\\b').test(this.first.className); |
||||||
|
}}, |
||||||
|
prop: {value: function (property, value) { |
||||||
|
if (typeof value == 'undefined') { |
||||||
|
return this.first[property]; |
||||||
|
} else { |
||||||
|
for (var i = 0; i < this.length; i++) { |
||||||
|
this[i][property] = value; |
||||||
|
} |
||||||
|
return this; |
||||||
|
} |
||||||
|
}}, |
||||||
|
attr: {value: function (property, value) { |
||||||
|
if (typeof value == 'undefined') { |
||||||
|
return this.first.getAttribute(property); |
||||||
|
} else { |
||||||
|
for (var i = 0; i < this.length; i++) { |
||||||
|
this[i].setAttribute(property, value); |
||||||
|
} |
||||||
|
return this; |
||||||
|
} |
||||||
|
}}, |
||||||
|
removeAttr: {value: function (property) { |
||||||
|
for (var i = 0; i < this.length; i++) { |
||||||
|
this[i].removeAttribute(property); |
||||||
|
} |
||||||
|
return this; |
||||||
|
}}, |
||||||
|
val: {value: function (value) { |
||||||
|
var el = this.first, prop = 'value'; |
||||||
|
switch (el.tagName) { |
||||||
|
case 'SELECT': |
||||||
|
prop = 'selectedIndex'; |
||||||
|
break; |
||||||
|
case 'OPTION': |
||||||
|
prop = 'selected'; |
||||||
|
break; |
||||||
|
case 'INPUT': |
||||||
|
if (el.type == 'checkbox' || el.type == 'radio') { |
||||||
|
prop = 'checked'; |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
return this.prop(prop, value); |
||||||
|
}}, |
||||||
|
append: {value: function (value) { |
||||||
|
var t = this, v = tts(value), len = v.length; |
||||||
|
for (var i = 0; i < len; i++) { |
||||||
|
t.first.appendChild(v[i].first || v[i]); |
||||||
|
} |
||||||
|
return this; |
||||||
|
}}, |
||||||
|
before: {value: function (value) { |
||||||
|
this.first.parentElement.insertBefore(tts().append(value).first, this.first); |
||||||
|
return this; |
||||||
|
}}, |
||||||
|
parent: {value: function () { |
||||||
|
return tts(this.first.parentNode); |
||||||
|
}}, |
||||||
|
clone: {value: function () { |
||||||
|
return tts(this.first.cloneNode(true)); |
||||||
|
}}, |
||||||
|
remove: {value: function () { |
||||||
|
for (var i = 0; i < this.length; i++) { |
||||||
|
this[i].parentNode.removeChild(this[i]); |
||||||
|
} |
||||||
|
return this; |
||||||
|
}}, |
||||||
|
find: {value: function (value) { |
||||||
|
return tts(value, this.first); |
||||||
|
}}, |
||||||
|
closest: {value: function (selector) { |
||||||
|
var el = this.first; |
||||||
|
do { |
||||||
|
if (el[tts.matches](selector)) { |
||||||
|
return tts(el); |
||||||
|
} |
||||||
|
} while (el = el.parentElement); |
||||||
|
return null; |
||||||
|
}}, |
||||||
|
is: {value: function (selector) { |
||||||
|
return tts(this.filter(function (el) { |
||||||
|
return el[tts.matches](selector); |
||||||
|
})); |
||||||
|
}}, |
||||||
|
css: {value: function (property, value) { |
||||||
|
if (typeof value == 'undefined') { |
||||||
|
return this.first.style[property]; |
||||||
|
} else { |
||||||
|
for (var i = 0; i < this.length; i++) { |
||||||
|
this[i].style[property] = value; |
||||||
|
} |
||||||
|
return this; |
||||||
|
} |
||||||
|
}}, |
||||||
|
html: {value: function (value) { |
||||||
|
return this.prop('innerHTML', value); |
||||||
|
}}, |
||||||
|
text: {value: function (value) { |
||||||
|
return this.prop('textContent', value); |
||||||
|
}}, |
||||||
|
empty: {value: function () { |
||||||
|
return this.prop('innerHTML', ''); |
||||||
|
}}, |
||||||
|
hide: {value: function () { |
||||||
|
for (var i = 0; i < this.length; i++) { |
||||||
|
this[i].style.display = 'none'; |
||||||
|
} |
||||||
|
return this; |
||||||
|
}}, |
||||||
|
show: {value: function (type) { |
||||||
|
var display_type = (type) ? type : ''; |
||||||
|
for (var i = 0; i < this.length; i++) { |
||||||
|
this[i].style.display = display_type; |
||||||
|
} |
||||||
|
return this; |
||||||
|
}}, |
||||||
|
invisible: {value: function () { |
||||||
|
for (var i = 0; i < this.length; i++) { |
||||||
|
this[i].style.visibility = 'hidden'; |
||||||
|
} |
||||||
|
return this; |
||||||
|
}}, |
||||||
|
visible: {value: function (type) { |
||||||
|
for (var i = 0; i < this.length; i++) { |
||||||
|
this[i].style.visibility = "visible"; |
||||||
|
} |
||||||
|
return this; |
||||||
|
}}, |
||||||
|
fadeStop: {value: function () { |
||||||
|
for (var i = 0; i < this.length; i++) { |
||||||
|
this[i].style.opacity = 1; |
||||||
|
this[i].style.filter = "alpha(opacity=1)"; |
||||||
|
this[i].style.display = "inline-block"; |
||||||
|
this[i].style.visibility = "visible"; |
||||||
|
} |
||||||
|
}}, |
||||||
|
fadeIn: {value: function (ms, display) { |
||||||
|
var tms = (typeof ms == 'undefined') ? 600 : ms, display_as = (typeof display == 'undefined') ? "inline-block" : display; |
||||||
|
for (var i = 0; i < this.length; i++) { |
||||||
|
var elem = this[i].style, opacity = {}, timer = {}; |
||||||
|
elem.opacity = 0; |
||||||
|
elem.filter = "alpha(opacity=0)"; |
||||||
|
elem.display = display_as; |
||||||
|
elem.visibility = "visible"; |
||||||
|
opacity.i = 0; |
||||||
|
timer.i = setInterval(function () { |
||||||
|
opacity.i += 50 / tms; |
||||||
|
if (opacity.i >= 1) { |
||||||
|
clearInterval(timer.i); |
||||||
|
opacity.i = 1; |
||||||
|
} |
||||||
|
elem.opacity = opacity.i; |
||||||
|
elem.filter = "alpha(opacity=" + opacity.i * 100 + ")"; |
||||||
|
}, 50); |
||||||
|
} |
||||||
|
}}, |
||||||
|
fadeOut: {value: function (ms) { |
||||||
|
var tms = (typeof ms == 'undefined') ? 600 : ms; |
||||||
|
for (var i = 0; i < this.length; i++) { |
||||||
|
var opacity = {}, timer = {}, elem = this[i].style; |
||||||
|
opacity.i = 1; |
||||||
|
timer.i = setInterval(function () { |
||||||
|
opacity.i -= 50 / tms; |
||||||
|
if (opacity.i <= 0) { |
||||||
|
clearInterval(timer.i); |
||||||
|
opacity.i = 0; |
||||||
|
elem.display = "none"; |
||||||
|
elem.visibility = "hidden"; |
||||||
|
} |
||||||
|
elem.opacity = opacity.i; |
||||||
|
elem.filter = "alpha(opacity=" + opacity.i * 100 + ")"; |
||||||
|
}, 50); |
||||||
|
} |
||||||
|
}} |
||||||
|
}); |
||||||
|
|
||||||
|
tts.now = function () { |
||||||
|
return Date.now(); |
||||||
|
}; |
||||||
|
tts.parse = function (string) { |
||||||
|
return JSON.parse(string); |
||||||
|
}; |
||||||
|
tts.map = function (array, callback, arg) { |
||||||
|
return array.map(callback, arg); |
||||||
|
}; |
||||||
|
tts.random = function (min, max) { |
||||||
|
return Math.floor((Math.random() * max) + min); |
||||||
|
}; |
||||||
|
tts.trim = function (string) { |
||||||
|
return string.trim(); |
||||||
|
}; |
||||||
|
tts.inArray = function (item, array) { |
||||||
|
return (array.indexOf(item) !== -1) ? true : false; |
||||||
|
}; |
||||||
|
tts.isFunction = function (item) { |
||||||
|
if (typeof item === 'function') { |
||||||
|
return true; |
||||||
|
} |
||||||
|
var type = Object.prototype.toString.call(item); |
||||||
|
return type === '[object Function]' || type === '[object GeneratorFunction]'; |
||||||
|
}; |
||||||
|
var arrayOfCalls = []; |
||||||
|
tts.once = function (callback, id, parms) { |
||||||
|
var fn = window[callback], found = (!tts.inArray(id, arrayOfCalls) && tts.isFunction(fn)) ? fn(parms) : false; |
||||||
|
if (found !== false) { |
||||||
|
arrayOfCalls.push(id); |
||||||
|
} |
||||||
|
return found; |
||||||
|
}; |
||||||
|
tts.isEmptyObject = function (obj) { |
||||||
|
return Object.keys(obj).length === 0; |
||||||
|
}; |
||||||
|
tts.isEmpty = function (str) { |
||||||
|
return (!str || 0 === str.length); |
||||||
|
}; |
||||||
|
tts.isNumeric = function (n) { |
||||||
|
return !isNaN(parseFloat(n)) && isFinite(n); |
||||||
|
}; |
||||||
|
tts.extend = function (object1, object2) { |
||||||
|
return Object.assign({}, object1, object2); |
||||||
|
}; |
||||||
|
tts.when = function (arrayOfPromises) { |
||||||
|
return new Promise(function (resolve, reject) { |
||||||
|
Promise.all(arrayOfPromises).then(values => { |
||||||
|
resolve(values); |
||||||
|
}).catch(errors => { |
||||||
|
reject(errors); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
@ -0,0 +1,7 @@ |
|||||||
|
if (typeof module === 'object' && module.exports) { |
||||||
|
module.exports = tts; |
||||||
|
} else { |
||||||
|
window.tts = tts; |
||||||
|
} |
||||||
|
|
||||||
|
}).call({}, ('object' === typeof window) ? window : this, window, document, prefData); /* These get passed into the Local Scope, in the top of this Script function */ |
||||||
@ -0,0 +1,11 @@ |
|||||||
|
combine = function (source, dest) { |
||||||
|
|
||||||
|
for (var i = 0; i < source.length; i++) { |
||||||
|
dest.push(source[i]); |
||||||
|
} |
||||||
|
|
||||||
|
return dest; |
||||||
|
|
||||||
|
}; |
||||||
|
|
||||||
|
module.exports = combine; |
||||||
@ -0,0 +1,39 @@ |
|||||||
|
var extend = function () { |
||||||
|
|
||||||
|
// Variables
|
||||||
|
var extended = {}; |
||||||
|
var deep = false; |
||||||
|
var i = 0; |
||||||
|
var length = arguments.length; |
||||||
|
|
||||||
|
// Check if a deep merge
|
||||||
|
if (Object.prototype.toString.call(arguments[0]) === '[object Boolean]') { |
||||||
|
deep = arguments[0]; |
||||||
|
i++; |
||||||
|
} |
||||||
|
|
||||||
|
// Merge the object into the extended object
|
||||||
|
var merge = function (obj) { |
||||||
|
for (var prop in obj) { |
||||||
|
if (Object.prototype.hasOwnProperty.call(obj, prop)) { |
||||||
|
// If deep merge and property is an object, merge properties
|
||||||
|
if (deep && Object.prototype.toString.call(obj[prop]) === '[object Object]') { |
||||||
|
extended[prop] = extend(true, extended[prop], obj[prop]); |
||||||
|
} else { |
||||||
|
extended[prop] = obj[prop]; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
// Loop through each object and conduct a merge
|
||||||
|
for (; i < length; i++) { |
||||||
|
var obj = arguments[i]; |
||||||
|
merge(obj); |
||||||
|
} |
||||||
|
|
||||||
|
return extended; |
||||||
|
|
||||||
|
}; |
||||||
|
|
||||||
|
module.exports = extend; |
||||||
@ -0,0 +1,11 @@ |
|||||||
|
when = function (arrayOfPromises) { |
||||||
|
return new Promise(function (resolve, reject) { |
||||||
|
Promise.all(arrayOfPromises).then(values => { |
||||||
|
resolve(values); |
||||||
|
}).catch(errors => { |
||||||
|
reject(errors); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
module.exports = when; |
||||||
@ -0,0 +1,58 @@ |
|||||||
|
/* My Plug-Ins */ |
||||||
|
const extend = require('./gulp_deps/gulp-extend'); |
||||||
|
const when = require('./gulp_deps/gulp-when'); |
||||||
|
const combine = require('./gulp_deps/gulp-combine'); |
||||||
|
/* Terser Ugilfy Settings */ |
||||||
|
const ecma_latest = 8; |
||||||
|
const warn_level = { warnings: true }; |
||||||
|
const compress = { compress: { dead_code: true, drop_debugger: false, arrows: false, properties: false } }; |
||||||
|
const mangle = { mangle: false }; // { properties: { keep_quoted: true } }
|
||||||
|
const output = { output: {comments: false} }; // Destroy Commment Blocks!
|
||||||
|
const options = { module: false, keep_classnames: true, keep_fnames: true, toplevel: false, safari10: false }; |
||||||
|
const common = extend( warn_level, compress, mangle, options, output ); |
||||||
|
const uglify_latest_e = { ecma: ecma_latest, ie8: false }; |
||||||
|
const uglify_latest = extend( uglify_latest_e, common ); |
||||||
|
/* Gulp Add-Ons */ |
||||||
|
const { src, dest, series, parallel, watch } = require('gulp'); |
||||||
|
const uglify = require('gulp-terser'); |
||||||
|
const concat = require('gulp-concat'); |
||||||
|
const rename = require('gulp-rename'); |
||||||
|
const sourcemaps = require("gulp-sourcemaps"); |
||||||
|
/* Core TTS JS */ |
||||||
|
const tts_js_files = [
|
||||||
|
'core/begin.js',
|
||||||
|
'core/core.js',
|
||||||
|
'core/addons/*.js', |
||||||
|
'core/end.js'
|
||||||
|
]; |
||||||
|
/* Destination Folders for JS */ |
||||||
|
const js_dest = 'assets/dist/'; |
||||||
|
/* Use Map instead of .js.map */ |
||||||
|
const map = { mapFile: function(mapFilePath) { return mapFilePath.replace('.js.map', '.map'); } }; |
||||||
|
|
||||||
|
function tts_js() { |
||||||
|
return when([ |
||||||
|
new Promise(function(resolve, reject) {
|
||||||
|
src( tts_js_files ) |
||||||
|
.pipe(sourcemaps.init({ loadMaps: true })) |
||||||
|
.pipe(concat( 'tts.js' )) |
||||||
|
.pipe(dest( js_dest )) |
||||||
|
.pipe(rename( { extname: '.min.js' } )) |
||||||
|
.pipe(uglify( uglify_latest ) ) |
||||||
|
.pipe(sourcemaps.write(".", map )) |
||||||
|
.pipe(dest( js_dest )) |
||||||
|
.on('end', resolve); |
||||||
|
}) |
||||||
|
]);
|
||||||
|
} |
||||||
|
|
||||||
|
function watch_js() { |
||||||
|
watch(tts_js_files, tts_js); |
||||||
|
} |
||||||
|
|
||||||
|
exports.js = parallel(tts_js); |
||||||
|
exports.all = parallel(tts_js); |
||||||
|
exports.watcher = series( parallel(tts_js), watch_js ); |
||||||
|
//exports.css = css;
|
||||||
|
//exports.html = html;
|
||||||
|
exports.default = parallel(tts_js); |
||||||
@ -0,0 +1,301 @@ |
|||||||
|
/* Robs Router Loader */ |
||||||
|
tts.RouteObject = {}; /* This is the main Object to use for AJAX Pages */ |
||||||
|
var include_once_files = []; /* Was this Asset loaded yet, and did the PHP Footer file find this Asset */ |
||||||
|
|
||||||
|
tts.AddRouterCachedFile = function(filename) { |
||||||
|
include_once_files.push(filename); |
||||||
|
};
|
||||||
|
|
||||||
|
function doesAssetExists(filename) { |
||||||
|
// console.log(filename);
|
||||||
|
return new Promise((resolve, reject) => { |
||||||
|
if (hasLoaded(filename) === false) { |
||||||
|
var exists = false; |
||||||
|
for (var i = 0; i < assets_files.length; i++) { |
||||||
|
if (filename == assets_files[i].filename) { |
||||||
|
tts.logger('Loading: ' + filename) |
||||||
|
include_once_files.push(filename); |
||||||
|
exists = true; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
if (exists === false) { |
||||||
|
reject("skipped: " + filename); |
||||||
|
} else { |
||||||
|
resolve(assets_files[i].ts); |
||||||
|
} |
||||||
|
} else { |
||||||
|
resolve("loaded"); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
function getClassName(obj) { |
||||||
|
if (typeof obj.constructor.name === "undefined") { |
||||||
|
return obj.constructor.toString().match(/^function\s(.+)\(/)[1]; |
||||||
|
} else { |
||||||
|
return obj.constructor.name; |
||||||
|
} |
||||||
|
} |
||||||
|
function hasLoaded(file) { |
||||||
|
return tts.inArray(file, include_once_files); |
||||||
|
} /* Just checks if file has been loaded once yet */ |
||||||
|
function apply_css(css_file, version) { |
||||||
|
return new Promise((resolve, reject) => { |
||||||
|
tts.getAsset({name: css_file, path: AJAX_Folder, version: version}).then(function () { |
||||||
|
resolve(); |
||||||
|
}).catch(function () { |
||||||
|
reject(); |
||||||
|
}); |
||||||
|
}); |
||||||
|
} |
||||||
|
function hasPromise(obj, fn, text) { // tts.logger("promise"+fn, "trace");
|
||||||
|
if (typeof text === "undefined") { |
||||||
|
text = ""; |
||||||
|
} |
||||||
|
return new Promise((resolve, reject) => { |
||||||
|
var usePromise = tts.getValue(obj.Promise, true); |
||||||
|
if (typeof fn === "undefined" && typeof fn !== "function") { |
||||||
|
reject(text + " Function does not exist"); |
||||||
|
} else { |
||||||
|
if (usePromise === true) { |
||||||
|
tts.logger("Promise exec of " + text); |
||||||
|
fn().then(function (out) { |
||||||
|
resolve(out); |
||||||
|
}).catch(function (e) { |
||||||
|
reject(e); |
||||||
|
}); |
||||||
|
} else { |
||||||
|
tts.logger("Exec of " + text); |
||||||
|
fn(); |
||||||
|
resolve(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
/* Run Main method on Class File */ |
||||||
|
function do_run_main(obj) { |
||||||
|
var className = getClassName(obj); |
||||||
|
return new Promise((resolve, reject) => { |
||||||
|
hasPromise(obj, obj['Main'], className).then(function () { |
||||||
|
resolve(); |
||||||
|
}).catch(function (e) { |
||||||
|
reject(e); |
||||||
|
}); |
||||||
|
}); |
||||||
|
} |
||||||
|
; |
||||||
|
/* This will Run JS code for Tabs! */ |
||||||
|
function do_run(obj) { |
||||||
|
var className = getClassName(obj); |
||||||
|
return new Promise((resolve, reject) => { |
||||||
|
hasPromise(obj, obj[obj.tab], className + " " + obj.tab).then(function () { |
||||||
|
resolve(); |
||||||
|
}).catch(function (e) { |
||||||
|
reject(e); |
||||||
|
}); |
||||||
|
}); |
||||||
|
} |
||||||
|
; |
||||||
|
function is_unknown(obj) { |
||||||
|
if (is_404(obj.tab)) { |
||||||
|
var className = getClassName(obj); |
||||||
|
tts.logger(className + " " + obj.tab + " tab FN not found!"); |
||||||
|
do_404_page(); |
||||||
|
return true; |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
function loadJS(scriptFile, version, obj, fn) { |
||||||
|
var stuff = { name: scriptFile, path: AJAX_Folder, ts: version }; |
||||||
|
// console.log(stuff);
|
||||||
|
return new Promise((resolve, reject) => { |
||||||
|
tts.getAsset(stuff) |
||||||
|
.then(function () { |
||||||
|
switch (fn) { |
||||||
|
case 'ErrorMain': |
||||||
|
hasPromise(obj, obj.Main, "404").then(function () { |
||||||
|
resolve(); |
||||||
|
}).catch(function () { |
||||||
|
reject(); |
||||||
|
}); |
||||||
|
break; |
||||||
|
case 'do_run_main': |
||||||
|
do_run_main(obj).then(function () { |
||||||
|
resolve("js_complete"); |
||||||
|
}).catch(function (e) { |
||||||
|
reject(e); |
||||||
|
}); |
||||||
|
break; |
||||||
|
case 'do_run': |
||||||
|
do_run(obj).then(function () { |
||||||
|
resolve("js_complete"); |
||||||
|
}).catch(function (e) { |
||||||
|
reject(e); |
||||||
|
}); |
||||||
|
break; |
||||||
|
default: |
||||||
|
window[fn](obj).then(function () { |
||||||
|
resolve("js_complete"); |
||||||
|
}).catch(function (e) { |
||||||
|
reject(e); |
||||||
|
}); |
||||||
|
break; |
||||||
|
} |
||||||
|
}).catch(function (exception) { |
||||||
|
switch (fn) { |
||||||
|
case 'ErrorMain': |
||||||
|
tts.logger("404 Page - does not exist", "error"); |
||||||
|
break; |
||||||
|
case 'do_run_main': |
||||||
|
do_run_main(obj).catch(function () { |
||||||
|
reject(e); |
||||||
|
}); |
||||||
|
break; |
||||||
|
case 'do_run': |
||||||
|
do_run(obj).catch(function () { |
||||||
|
reject(e); |
||||||
|
}); |
||||||
|
break; |
||||||
|
default: |
||||||
|
window[fn](obj).catch(function () { }); |
||||||
|
break; |
||||||
|
} |
||||||
|
if (fn !== 'ErrorMain') { |
||||||
|
tts.logger("Something went wrong: " + exception, "warn"); |
||||||
|
} |
||||||
|
reject('Something went wrong'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
} |
||||||
|
tts.JS_EXT = ".js"; |
||||||
|
tts.CSS_EXT = ".css"; |
||||||
|
/* Does Class StartUp, CSS, and JS - After Main JS has completed loading... */ |
||||||
|
function do_other_FN(obj) { |
||||||
|
return new Promise((resolve, reject) => { |
||||||
|
var className = getClassName(obj); |
||||||
|
var tab = tts.getValue(obj.tab, false); |
||||||
|
hasPromise(obj, obj['StartUp'], "Start Up").catch(function () { }); |
||||||
|
if (tab === false) { |
||||||
|
resolve(); |
||||||
|
} else { |
||||||
|
var Script_File = className + "_" + tab + tts.JS_EXT; |
||||||
|
var CSS_File = className + "_" + tab + tts.CSS_EXT; |
||||||
|
var MainCSS_File = className + "_Main" + tts.CSS_EXT; |
||||||
|
doesAssetExists(Script_File).then(function (versionNumber) { |
||||||
|
if (versionNumber === 'loaded') { |
||||||
|
do_run(obj).then(function (ok) { |
||||||
|
resolve(ok); |
||||||
|
}).catch(function (e) { |
||||||
|
reject(e); |
||||||
|
}); |
||||||
|
} else { |
||||||
|
loadJS(Script_File, versionNumber, obj, 'do_run').then(function (ok) { |
||||||
|
resolve(ok); |
||||||
|
}).catch(function (e) { |
||||||
|
reject(e); |
||||||
|
}); |
||||||
|
} |
||||||
|
}).catch(function (err) { |
||||||
|
do_run(obj).then(function (ok) { |
||||||
|
resolve(ok); |
||||||
|
}).catch(function (e) { |
||||||
|
is_unknown(obj); |
||||||
|
reject(e); |
||||||
|
}); |
||||||
|
}); |
||||||
|
doesAssetExists(MainCSS_File).then(function (versionNumber) { |
||||||
|
if (versionNumber !== 'loaded') { |
||||||
|
apply_css(MainCSS_File, versionNumber); |
||||||
|
} |
||||||
|
}).catch(function (e) { }); |
||||||
|
doesAssetExists(CSS_File).then(function (versionNumber) { |
||||||
|
if (versionNumber !== 'loaded') { |
||||||
|
apply_css(CSS_File, versionNumber); |
||||||
|
} |
||||||
|
}).catch(function (e) { }); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
function mainRouting(obj) { |
||||||
|
return new Promise((resolve, reject) => { |
||||||
|
tts.RouteObject = obj; |
||||||
|
var className = getClassName(obj); |
||||||
|
var MainScript_File = className + "_Main" + tts.JS_EXT; |
||||||
|
doesAssetExists(MainScript_File).then(function (versionNumber) { |
||||||
|
if (versionNumber === 'loaded') { |
||||||
|
do_run_main(obj).then(function () { |
||||||
|
do_other_FN(obj).then(function (ok) { |
||||||
|
resolve(ok); |
||||||
|
}).catch(function (e) { |
||||||
|
reject(e); |
||||||
|
}); |
||||||
|
}).catch(function (e) { |
||||||
|
reject(e); |
||||||
|
}); |
||||||
|
} else { |
||||||
|
loadJS(MainScript_File, versionNumber, obj, 'do_run_main').then(function () { |
||||||
|
do_other_FN(obj).then(function (ok) { |
||||||
|
resolve(ok); |
||||||
|
}).catch(function (e) { |
||||||
|
reject(e); |
||||||
|
}); |
||||||
|
}).catch(function (e) { |
||||||
|
reject(e); |
||||||
|
}); |
||||||
|
} |
||||||
|
}).catch(function (err) { |
||||||
|
do_run_main(obj).then(function () { |
||||||
|
do_other_FN(obj).then(function (ok) { |
||||||
|
resolve(ok); |
||||||
|
}).catch(function (e) { |
||||||
|
reject(e); |
||||||
|
}); |
||||||
|
}).catch(function (e) { |
||||||
|
reject(e); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
tts.Route = function (obj) { /* This is the core loader for Tabs and Main Route */ |
||||||
|
tts.startCodeTimer(); |
||||||
|
return new Promise((resolve, reject) => { |
||||||
|
mainRouting(obj).then(function (r) { |
||||||
|
tts.endCodeTimer(); |
||||||
|
$_.logger(r + " - Resolved Took " + tts.completedCodeTimer); |
||||||
|
resolve(r); |
||||||
|
}).catch(function (e) { |
||||||
|
tts.endCodeTimer(); |
||||||
|
$_.logger(e + " - Rejected Took " + tts.completedCodeTimer); |
||||||
|
reject(e); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
/* Load 404 JS for doing 404 Page */ |
||||||
|
function do_404_page() { |
||||||
|
var ErrorScript_File = "PageNotFound_Main" + tts.JS_EXT; |
||||||
|
var err_page = new PageNotFound(false); |
||||||
|
doesAssetExists(ErrorScript_File).then(function (versionNumber) { |
||||||
|
if (versionNumber === 'loaded') { |
||||||
|
err_page.Main(); |
||||||
|
} else { |
||||||
|
loadJS(ErrorScript_File, versionNumber, err_page, "ErrorMain").catch(function (e) { }); |
||||||
|
} |
||||||
|
}).catch(function (err) { |
||||||
|
tts.logger("404 Page - does not exist", "error"); |
||||||
|
}); |
||||||
|
} |
||||||
|
/* Is 404 on, if so does Tab Method/File exists, if not was an exception made */ |
||||||
|
tts.do_404_page_on_bad_Route = true; |
||||||
|
tts.empty_Route_pages = []; |
||||||
|
function is_404(tab_name) { |
||||||
|
if (tts.do_404_page_on_bad_Route === false) |
||||||
|
return false; /* Is 404 off?? */ |
||||||
|
for (var i = 0; i < tts.empty_Route_pages.length; i++) { |
||||||
|
if (tts.empty_Route_pages[i] == tab_name) { |
||||||
|
return false; /* Found allowed empty tab page */ |
||||||
|
} |
||||||
|
} |
||||||
|
return true; /* Unable to find tab page hash in allowed list */ |
||||||
|
} |
||||||
|
/* End of Robs Router Loader */ |
||||||
@ -0,0 +1,18 @@ |
|||||||
|
{ |
||||||
|
"name": "tts_js", |
||||||
|
"version": "1.0.0", |
||||||
|
"description": "TTS Framework JavaScript Assets.", |
||||||
|
"main": "gulpfile.js", |
||||||
|
"scripts": { |
||||||
|
"test": "echo \"Error: no test specified\" && exit 1" |
||||||
|
}, |
||||||
|
"author": "Robert Strutts", |
||||||
|
"license": "MIT", |
||||||
|
"devDependencies": { |
||||||
|
"gulp": "^4.0.2", |
||||||
|
"gulp-concat": "^2.6.1", |
||||||
|
"gulp-rename": "^2.0.0", |
||||||
|
"gulp-sourcemaps": "^3.0.0", |
||||||
|
"gulp-terser": "^2.1.0" |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue