snappymail/vendors/ssm/ssm.js
2013-12-30 01:13:35 +04:00

348 lines
9.1 KiB
JavaScript

/*global window document clearTimeout setTimeout */
;(function (window, document, undefined) {
"use strict";
var ssm = {},
states = [],
browserWidth = 0,
currentStates = [],
resizeTimeout = 10,
resizeTimer = null,
configOptions = [];
var browserResizeDebounce = function () {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(browserResizeWrapper, resizeTimeout);
};
//Added wrapper for the resize method
var browserResizeWrapper = function() {
browserWidth = getWidth();
browserResize(browserWidth);
};
var browserResize = function (localBrowserWidth) {
var totalStates = states.length,
totalConfigOptions = configOptions.length,
leaveMethods = [],
resizeMethods = [],
enterMethods = [],
validState = true,
tempObj = ssm;
for (var i = 0; i < totalStates; i++) {
validState = true;
tempObj.state = states[i];
tempObj.browserWidth = localBrowserWidth;
for (var j = 0; j < totalConfigOptions; j++) {
tempObj.callback = configOptions[j].test;
if(tempObj.callback() === false){
validState = false;
break;
}
}
if(validState){
if(objectInArray(currentStates, states[i])){
resizeMethods.push(states[i].onResize);
}
else{
currentStates.push(states[i]);
enterMethods.push(states[i].onEnter);
}
}
else{
if(objectInArray(currentStates, states[i])){
leaveMethods.push(states[i].onLeave);
currentStates = removeObjectInArray(currentStates,states[i]);
}
}
}
fireAllMethodsInArray(leaveMethods);
fireAllMethodsInArray(enterMethods);
fireAllMethodsInArray(resizeMethods);
};
ssm.browserResize = browserResize;
ssm.getBrowserWidth = function(){
return browserWidth;
};
//Add a new state
ssm.addState = function (options) {
//Setting sensible defaults for a state
//Max width is set to 99999 for comparative purposes, is bigger than any display on market
var defaultOptions = {
id: makeID(),
minWidth: 0,
maxWidth: 99999,
onEnter: function () {},
onLeave: function () {},
onResize: function () {}
};
//Merge options with defaults
options = mergeOptions(defaultOptions, options);
//Add state to the master states array
states.push(options);
//Sort
states = sortByKey(states, "minWidth");
return this;
};
//Allow updating of an already added state
ssm.updateState = function (stateId, options) {
for (var i = states.length - 1; i >= 0; i--) {
if (states[i].id === stateId) {
states[i] = mergeOptions(states[i], options);
}
}
return this;
};
//Find and remove the state from the array
ssm.removeState = function (stateId) {
for (var i = states.length - 1; i >= 0; i--) {
if (states[i].id === stateId) {
states.splice(i, 1);
}
}
return this;
};
//Remove multiple states from an array
ssm.removeStates = function (statesArray) {
for (var i = statesArray.length - 1; i >= 0; i--) {
ssm.removeState(statesArray[i]);
}
return this;
};
//Find and remove the state from the array
ssm.removeAllStates = function () {
states = currentStates = [];
return this;
};
//Add multiple states from an array
ssm.addStates = function (statesArray) {
for (var i = statesArray.length - 1; i >= 0; i--) {
ssm.addState(statesArray[i]);
}
return this;
};
ssm.getStates = function(idArr){
var idCount = null, returnArr = [];
if(typeof(idArr) === "undefined"){
return states;
}
else{
idCount = idArr.length;
for (var i = 0; i < idCount; i++) {
returnArr.push(getStateByID(idArr[i]));
}
return returnArr;
}
};
ssm.addConfigOption = function(options){
var defaultOptions = {
name: "",
test: null
};
//Merge options with defaults
options = mergeOptions(defaultOptions, options);
if(options.name !== "" && options.test !== null){
configOptions.push(options);
}
};
ssm.getConfigOption = function(name){
if(typeof name === "string"){
for (var i = configOptions.length - 1; i >= 0; i--) {
if(configOptions[i].name === name){
return configOptions[i];
}
}
}
else{
return configOptions;
}
};
ssm.removeConfigOption = function(name){
for (var i = configOptions.length - 1; i >= 0; i--) {
if (configOptions[i].name === name) {
configOptions.splice(i, 1);
}
}
};
ssm.getCurrentStates = function(){
return currentStates;
};
//Change the timeout before firing the resize function
ssm.setResizeTimeout = function (milliSeconds) {
resizeTimeout = milliSeconds;
};
//Change the timeout before firing the resize function
ssm.getResizeTimeout = function () {
return resizeTimeout;
};
ssm.ready = function () {
//Update browser width
browserWidth = getWidth();
//Attach event for resizing
if (window.attachEvent) {
window.attachEvent("onresize", browserResizeDebounce);
} else if (window.addEventListener) {
window.addEventListener("resize", browserResizeDebounce, true);
}
browserResize(browserWidth);
return this;
};
var makeID = function () {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < 10; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
};
var getWidth = function () {
var x = 0;
if (typeof(document.body.clientWidth) === "number") {
// newest gen browsers
x = document.body.clientWidth;
}
else if( typeof( window.innerWidth ) === "number" ) {
//Non-IE
x = window.innerWidth;
}
else if( document.documentElement && document.documentElement.clientWidth ) {
//IE 6+ in 'standards compliant mode'
x = document.documentElement.clientWidth;
}
return x;
};
var mergeOptions = function (obj1, obj2) {
var obj3 = {};
for (var attrname in obj1) {
obj3[attrname] = obj1[attrname];
}
for (var attrname2 in obj2) {
obj3[attrname2] = obj2[attrname2];
}
return obj3;
};
var sortByKey = function (array, key) {
return array.sort(function (a, b) {
var x = a[key];
var y = b[key];
return ((x < y) ? -1 : ((x > y) ? 1 : 0));
});
};
//Method to get a state based on the ID
var getStateByID = function(id){
for (var i = states.length - 1; i >= 0; i--) {
if(states[i].id === id){
return states[i];
}
}
};
var objectInArray = function(arr, obj){
for (var i = 0; i < arr.length; i++) {
if(arr[i] === obj){
return true;
}
}
};
var removeObjectInArray = function(arr,obj){
var length = arr.length;
for (var i = 0; i < length; i++) {
if (arr[i] === obj) {
arr.splice(i, 1);
}
}
return arr;
};
var fireAllMethodsInArray = function(arr){
var arrLength = arr.length;
for (var i = 0; i < arrLength; i++) {
arr[i]();
}
};
//define the built in methods (required for compatabilty)
ssm.addConfigOption({name:"minWidth", test: function(){
if(typeof this.state.minWidth === "number" && this.state.minWidth <= this.browserWidth){
return true;
}
else{
return false;
}
}});
ssm.addConfigOption({name:"maxWidth", test: function(){
if(typeof this.state.maxWidth === "number" && this.state.maxWidth >= this.browserWidth){
return true;
}
else{
return false;
}
}});
//Expose Simple State Manager
window.ssm = ssm;
if (typeof window.define === "function" && window.define.amd) {
window.define("ssm", [], function () {
return window.ssm;
});
}
})(window, document);