View difference between Paste ID: eDD4kFaY and TfgQZYTX
SHOW: | | - or go back to the newest paste.
1
// =========================
2
// Utilities
3
// =========================
4
var utils = utils || {};
5
6
// ========================================
7
// Flag which defines the behaviour of the routes
8
// and templates.
9
// If set to 'true', the page will clean everytime
10
// the route changes.
11
//
12
// ========================================
13
utils.resetTemplateOnRouteChange = false;
14
15
// ========================================
16
// Que for all AJAX request for the current view,
17
// cleaned after every reload.
18
//
19
// ========================================
20
utils.queuedAjax = [];
21
22
// ========================================
23
// Load template file into the DOM webpage
24
// Params:
25
// 	url  - url to the template file (starting from the index.html directory)
26
//  args - parameters to be put into the template, on the template mark
27
//         them with double curly braces like: {{argumentName}}
28
//  override - OPTIONAL override the previous template ( default: false )
29
//  callback - OPTIONAL callback function run after template is loaded
30
//
31
// ========================================
32
utils.loadTemplate = (function(f,u,n,c){
33
	var $templateDom = $('#dynamic-template'),
34
		  $ajaxCall;
35
36
	if( typeof n === 'function' && typeof c === 'undefined' ) c = n;
37
38
	$ajaxCall = $.get(f).success(function(response){
39
		var mustachedTemplate = Mustache.render(response,u);
40
41
		if( n === true ){
42
			$templateDom.html(mustachedTemplate);
43
		} else {
44
			$templateDom.append(mustachedTemplate);
45
		}
46
47
		if( typeof c === 'function' ){
48
			c(mustachedTemplate);
49
		}
50
51
	}).fail(function(response){
52
		console.warn('Template error',response);
53
		
54
	});
55
56
	utils.queuedAjax.push($ajaxCall);
57
58
	return true;
59
});
60
61
// ========================================
62
// Load a json file from the back-end ( via GET )
63
// Params:
64
// 	url  - url/path to the external, back-end server
65
//  callback - OPTIONAL callback function for the request
66
//
67
// ========================================
68
utils.getData = utils.loadJSON = (function(f,u){
69
	var $ajaxCall,
70
			json;
71
72
	$ajaxCall = $.get(f).success(function(response){
73
		if( typeof response === 'String'){
74
			try {
75
				json = JSON.parse(response);
76
			} catch(exception){
77
				console.warn('JSON error',exception);
78
			}
79
		} else {
80
			json = response;
81
		}
82
83
		if( typeof u === 'function' ){
84
			u( json || null );
85
		}
86
	}).fail(function(response){
87
		// console.warn('JSON error',response);
88
89
	});
90
91
	utils.queuedAjax.push($ajaxCall);
92
});
93
94
// ========================================
95
// Send data to the back-end ( via POST )
96
// Params:
97
// 	url  - url/path to the external, back-end server
98
//  data - parameters sent to the back-end
99
//  callback - OPTIONAL function called after the back-end responds
100
//
101
// ========================================
102
utils.sendData = utils.sendJSON = (function(f,u,n){
103
	var $ajaxCall;
104
105
	$ajaxCall = $.post(f,u).success(function(response){
106
		if( typeof response === 'String'){
107
			try {
108
				json = JSON.parse(response);
109
			} catch(exception){
110
				console.warn('JSON error',exception);
111
			}
112
		} else {
113
			json = response;
114
		}
115
116
		if( typeof n === 'function' ){
117
			n( json || null );
118
		}
119
	}).fail(function(response){
120
		console.warn('POST error',response);
121
122
	});
123
});
124
125
// ========================================
126
// Call a callback when a proper URL is given
127
// Params:
128
// 	url  - url/path expected
129
//  callback - function called after URL is matched with the expected
130
//
131
// ========================================
132
utils.onRoute = (function(f,u){
133
	var urlParams = [];
134
135
	if( f === null ){
136
		f = 'index';
137
	}
138
139
	if( f[0] === '#' ){
140
		f = f.substr(1);
141
	}
142
143
	urlParams = (f.match(/\{\w+\}/g) || []).map(function(paramQuote){
144
		return paramQuote.substr(1,paramQuote.length-2);
145
	});
146
147
	f = f.replace(/\{\w+\}/g,'{p}');
148
149
	if( typeof u === 'function' ){
150
		utils.routesMapping[f] = {
151
			callback: u,
152
			params: urlParams
153
		};
154
	}
155
156
	return utils;
157
});
158
159
// ========================================
160
// Routing Setup Function
161
// ========================================
162
utils.routesMapping = {};
163
164
$(function(){
165
	$(window).on('hashchange load',function(ev){
166
		var route = window.location.href.substr(window.location.origin.length).substr(2),
167
				routeCallbackParams = {},
168
				routeCallback;
169
170
		utils.clearAjaxRequests();
171
		if( utils.resetTemplateOnRouteChange === true ){
172
			utils.clearTemplates();
173
		}
174
175
		for( var path in utils.routesMapping ){
176
			var pathOption = utils.routesMapping[path],
177
					regexMapping,
178
					regexMatch,
179
					regexSplit,
180
					splitStep;
181
182
			if( pathOption.params.length < Object.keys(routeCallbackParams).length && Object.keys(routeCallbackParams).length !== 0 ){
183
				continue;
184
			}
185
186
			var a;
187
188
			regexMapping = path.replace(/\//g,'\\/').replace(/{p}/g,'\\w+');
189
190
			if( (regexMatch = route.match(new RegExp(regexMapping,'g')) || []) && regexMatch.length === 1 ){
191
				routeCallbackParams = {};
192
193
				regexSplit = (path.split(/\{\w+\}/) || []).filter(function(value){
194
					return value;
195
				});
196
197
				splitStep = route;
198
				for( var i = 0, j = regexSplit.length; i < j; i++ ){
199
					var splitIndex = splitStep.indexOf(regexSplit[i]),
200
							splitHead = splitStep.slice(0, splitIndex),
201
							splitTail = splitStep.slice(splitIndex + regexSplit[i].length);
202
					
203
					splitStep = splitTail;
204
205
					if( splitHead && splitHead.indexOf('/') === -1 ){
206
						routeCallbackParams[pathOption.params[i-1]] = splitHead;
207
					}
208
					if( splitTail && i === j-1 && splitTail.indexOf('/') === -1 ){
209
						routeCallbackParams[pathOption.params[i]] = splitTail;
210
					}
211
				}
212
213
				routeCallback = pathOption.callback;
214
				a = pathOption;
215
			}
216
		}
217
218
		if( !routeCallback ){
219
			routeCallback = utils.routesMapping['index'];
220
			a = 'index';
221
		}
222
223
		console.log(a);
224
225
		if( typeof routeCallback === 'function' ){
226
			routeCallback(routeCallbackParams);
227
		}
228
	});
229
});
230
231
// ========================================
232
// Remove previous templates
233
// ========================================
234
utils.clearTemplates = (function(){
235
	var $templateDom = $('#dynamic-template');
236
237
	$templateDom.html('');
238
});
239
240
// ========================================
241
// Cancel previous AJAX requests
242
// ========================================
243
utils.clearAjaxRequests = (function(){
244
	$.each(utils.queuedAjax, function(i,request){
245
		request.abort();
246
	});
247
	utils.queuedAjax = [];
248
});
249-
// TODO: (URL masking function) window.history.pushState(null, null, route.substr(1) );
249+
250
251
// DOCCOOKIES
252
253
var docCookies = {
254
  getItem: function (sKey) {
255
    if (!sKey) { return null; }
256
    return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;
257
  },
258
  setItem: function (sKey, sValue, vEnd, sPath, sDomain, bSecure) {
259
    if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) { return false; }
260
    var sExpires = "";
261
    if (vEnd) {
262
      switch (vEnd.constructor) {
263
        case Number:
264
          sExpires = vEnd === Infinity ? "; expires=Fri, 31 Dec 9999 23:59:59 GMT" : "; max-age=" + vEnd;
265
          break;
266
        case String:
267
          sExpires = "; expires=" + vEnd;
268
          break;
269
        case Date:
270
          sExpires = "; expires=" + vEnd.toUTCString();
271
          break;
272
      }
273
    }
274
    document.cookie = encodeURIComponent(sKey) + "=" + encodeURIComponent(sValue) + sExpires + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "") + (bSecure ? "; secure" : "");
275
    return true;
276
  },
277
  removeItem: function (sKey, sPath, sDomain) {
278
    if (!this.hasItem(sKey)) { return false; }
279
    document.cookie = encodeURIComponent(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT" + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "");
280
    return true;
281
  },
282
  hasItem: function (sKey) {
283
    if (!sKey) { return false; }
284
    return (new RegExp("(?:^|;\\s*)" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie);
285
  },
286
  keys: function () {
287
    var aKeys = document.cookie.replace(/((?:^|\s*;)[^\=]+)(?=;|$)|^\s*|\s*(?:\=[^;]*)?(?:\1|$)/g, "").split(/\s*(?:\=[^;]*)?;\s*/);
288
    for (var nLen = aKeys.length, nIdx = 0; nIdx < nLen; nIdx++) { aKeys[nIdx] = decodeURIComponent(aKeys[nIdx]); }
289
    return aKeys;
290
  }
291
};