js/siteapp.core.js
last analyzed

Size

Total Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
nc 24
nop 0
dl 0
loc 32

3 Functions

Rating   Name   Duplication   Size   Complexity  
Date.now 0 1 ?
window.performance.now 0 1 ?
window.requestAnimationFrame 0 6 ?
1
/**
2
 * [Siteapp] - multi-purpose frontend application
3
 * 
4
 * Siteapp core module
5
 *     
6
 * @package     [Siteapp]
7
 * @subpackage  [Siteapp] core
8
 * @author      Björn Bartels <[email protected]>
9
 * @link        https://gitlab.bjoernbartels.earth/groups/themes
10
 * @license     http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
11
 * @copyright   copyright (c) 2016 Björn Bartels <[email protected]>
12
 * 
13
 * @namespace   Siteapp
14
 * @module      Siteapp
15
 */
16
"use strict";
17
18
var Siteapp_VERSION = '0.0.1';
19
20
// Global [Siteapp] object
21
// This is attached to the window, or used as a module for AMD/Browserify
22
const Siteapp = class Siteapp {
23
    
24
    /**
25
     * Create a new instance of the application.
26
     * @class
27
     * @name Plugin
28
     * @param {jQuery} element - jQuery object to apply the plugin to.
0 ignored issues
show
Documentation introduced by
The parameter element does not exist. Did you maybe forget to remove this comment?
Loading history...
29
     * @param {Object} options - Overrides to the default plugin settings.
30
     */
31
    constructor (options) { 
32
    	
33
        this.options = $.extend({}, this.defaults, options);
34
35
        this._initializeApplication();
36
    }
37
    
38
    /**
39
     * Setup objects
40
     * @access private
41
     */
42
    _initializeApplication () {
43
    	this._version = Siteapp_VERSION;
44
    	
45
        this._plugins   = {};
46
        this._uuids     = [];
47
        
48
        this._initTriggers();
49
        
50
        this._initMediaQuery();
51
52
        if (!this.options.disableStorage) { 
53
        	this._setupStorageManager();
54
        }
55
        if (!this.options.disableModules) { 
56
        	this._setupMainModuleManager();
57
        }
58
        if (!this.options.disableUi) { 
59
        	this._setupMainUiManager();
60
        }
61
        
62
        this._dependencyInjections();
63
        
64
    }
65
66
    /**
67
     * Setup events
68
     * @access private
69
     */
70
    _initTriggers () {
71
    	if (this.Triggers) {
72
    		this.Triggers._ns = this.appName;
73
    		this.Triggers.init($, this);
74
    	}
75
    }
76
77
    /**
78
     * Setup events
79
     * @access private
80
     */
81
    _initMediaQuery () {
82
    	if (this.MediaQuery) {
83
    		this.MediaQuery._ns = this.appName;
84
    		this.MediaQuery._init();
85
    	}
86
    }
87
88
    /**
89
     * Setup storage manager
90
     * @access private
91
     */
92
    _setupStorageManager () {
93
    	if (this.StorageManager && !this.options.disableStorage) {
94
    	    if ( this.options.storageManager ) {
95
        	    this.Storage = new this.StorageManager(this.options.storageManager);
96
    	    } else {
97
        	    this.Storage = new this.StorageManager();
98
    	    }
99
    	    this.Storage._app = this;
100
    	    
101
        	if (this.StorageAdapter) {
102
        	    this.Storage.setNamespaceAdapter(
103
        	    	this.appName+'Storage', 
104
        	    	new this.StorageAdapter(this.appName, 'memory', {}, this.Storage)
105
        	    );
106
        	}
107
    	}
108
    }
109
110
    /**
111
     * Setup main module manager
112
     * @access private
113
     */
114
    _setupMainModuleManager () {
115
116
    	if (this.ModuleManager && !this.options.disableModules) {
117
    	    this.ModuleManager.prototype._app = this;
118
    	    if ( this.options.moduleManager ) {
119
        	    this.Modules = new this.ModuleManager(this.options.moduleManager);
120
    	    } else {
121
        	    this.Modules = new this.ModuleManager();
122
    	    }
123
    	    this.Modules._app = this;
124
125
    	    if (this.ModuleFactory) {
126
        	    this.ModuleFactory.prototype._app     = this;
127
        	    this.ModuleFactory.prototype._manager = this.Modules;
128
        	    // register the module factory
129
    	    	this.Modules.registerModule(this.ModuleFactory);
130
    	    }
131
    	    if (this.Module) {
132
        	    this.Module.prototype._app     = this;
133
        	    this.Module.prototype._manager = this.Modules;
134
    	    }
135
    	}
136
    }
137
    
138
    /**
139
     * Setup main UI manager
140
     * @access private
141
     */
142
    _setupMainUiManager () {
143
144
    	if (this.UiManager && !this.options.disableUi) {
145
    	    if ( this.options.uiManager ) {
146
        	    this.Ui = new this.UiManager(this.options.uiManager);
147
    	    } else {
148
        	    this.Ui = new this.UiManager();
149
    	    }
150
    	    this.Ui._app = this;
151
152
    	    if (this.UiManager.Screenlayer) {
153
        	    this.UiManager.Screenlayer.prototype._app     = this;
154
        	    this.UiManager.Screenlayer.prototype._manager = this.Ui;
155
    	    	this.Ui.registerModule(this.UiManager.Screenlayer);
156
    	    }
157
158
    	    if (this.UiManager.Screenpanel) {
159
        	    this.UiManager.Screenpanel.prototype._app     = this;
160
        	    this.UiManager.Screenpanel.prototype._manager = this.Ui;
161
    	    	this.Ui.registerModule(this.UiManager.Screenpanel);
162
    	    }
163
164
    	    if (this.UiManager.Action) {
165
        	    this.UiManager.Action.prototype._app     = this;
166
        	    this.UiManager.Action.prototype._manager = this.Ui;
167
    	    	this.Ui.registerModule(this.UiManager.Action);
168
    	    }
169
    	}
170
    }
171
    
172
    /**
173
     * Setup sub objects
174
     * @access private
175
     */
176
    _dependencyInjections () {
177
    	// core stuff
178
        if (typeof this.Triggers != 'undefined') {
179
        	this.Triggers._ns  = this.appName;
180
        	this.Triggers._app = this;
181
        }
182
        if (typeof this.MediaQuery != 'undefined') {
183
        	this.MediaQuery._ns  = this.appName;
184
        	this.MediaQuery._app = this;
185
        }
186
        if (typeof this.Keyboard != 'undefined') {
187
        	this.Keyboard._ns  = this.appName;
188
        	this.Keyboard._app = this;
189
        }
190
        // extension
191
        if (typeof this.Exception != 'undefined') {
192
        	this.Exception._ns  = this.appName;
193
        	this.Exception._app = this;
194
        }
195
        if (typeof this.Debugger != 'undefined') {
196
        	this.Debugger._ns  = this.appName;
197
        	this.Debugger._app = this;
198
        }
199
        if (typeof this.Logger != 'undefined') {
200
        	this.Logger._ns  = this.appName;
201
        	this.Logger._app = this;
202
        }
203
        
204
        // object/class abstracts
205
        if (typeof this.Module != 'undefined') {
206
        	this.Module._ns  = this.appName;
207
        	this.Module._app = this;
208
        }
209
        if (typeof this.ModuleFactory != 'undefined') {
210
        	this.ModuleFactory._ns  = this.appName;
211
        	this.ModuleFactory._app = this;
212
        }
213
        if (typeof this.Plugin != 'undefined') {
214
        	this.Plugin._ns  = this.appName;
215
        	this.Plugin._app = this;
216
        }
217
        
218
    }
219
220
    /**
221
     * Add (Siteapp) application object and its shortcut to global namespace.
222
     * 
223
     * The application shortcut is a sequence of '$' appended by your Siteapp 
224
     * instance name.
225
     * 
226
     * For example:
227
     * in some absent data scope, eg. a callback used by require, an app instance
228
     * is created, like:
229
     * ``` 
230
     * require(...
231
     *     class MyApp extends Siteapp({...});
232
     *     var myApp = new MyApp();
233
     *     // maybe do something different first...
234
     *     myApp.run(); // alternatively: $(document).myapp();
235
     *     ...
236
     * ```
237
     * to access your (global) application object from some other obscure ;) data 
238
     * scope, just do:
239
     * ```
240
     * MyApp.reflow();
241
     * ```
242
     * or via its shortcut:
243
     * ```
244
     * $M.reflow();
245
     * ```
246
     * 
247
     * @function
248
     * @param {object} global - leave empty to detect 'window' in Browser
249
     * @param {boolean} add$Shortcut
250
     * @returns {object}
251
     */
252
    addToGlobal (global, add$Shortcut) {
253
    	var global = global || ((window) ? window : {}),
254
    	    name   = this.utilities.functionName(this),
255
    	    appId  = String( name ).charAt(0).toLowerCase() + name.slice(1)
256
    	;
257
258
    	if (typeof global[appId] == 'undefined') {
259
        	global[appId] = this;
260
        	
261
    	}
262
    	//console.//log('appid:', appId, global[appId]);
263
    	
264
    	if (add$Shortcut !== false) {
265
    		var shortcut = "$"+String(appId).charAt(0).toUpperCase();
266
267
        	if (typeof global[shortcut] == 'undefined') {
268
            	global[shortcut] = global[appId];
269
        	}
270
    	}
271
    	return global;
272
    }
273
274
    /**
275
     * Add shortcut to an element's (Siteapp) module/plugin instance.
276
     * 
277
     * The plugin shortcut is a sequence of '$$' appended by your Siteapp 
278
     * instance name.
279
     * 
280
     * For example:
281
     * assume an app instance, like:
282
     * ``` 
283
     * var MyApp = new Siteapp(......);
284
     * ```
285
     * to retrive the plugin object attached to one element, just do:
286
     * ```
287
     * var thePlugin = $$M('#someElementWithPlugin');
288
     * ```
289
     * or
290
     * ```
291
     * var thePlugin = $$MyApp('#someElementWithPlugin');
292
     * ```
293
     * then, use the plugin as desired...
294
     * ```
295
     * if (thePlugin instanceof MyPluginClass) { 
296
     *     thePlugin.doSomething()...
297
     * }
298
     * ```
299
     * 
300
     * @function
301
     * @param {object} global - leave empty to detect 'window' in Browser
302
     * @returns {object|array}
303
     */
304
    addPluginShortcut (global) {
305
    	var global     = global || ((window) ? window : {}),
306
    	    $app       = this,
307
    	    name       = this.utilities.functionName(this),
308
    	    methodName = "$$"+String( name ).charAt(0).toUpperCase(),
309
    	    methodLong = "$$"+String( name ).charAt(0).toUpperCase() + name.slice(1),
310
    	    
311
    	    method     = (selector) => {
312
    	    	var $elem = $(selector);
313
    	    	if ($elem.length == 1) {
314
    	    	    return ($elem.data($app.appName+'Plugin'));
315
    	    	} else {
316
    	    		var plugins = [];
317
    	    		$elem.each((idx, plgn) => { 
318
    	    			var obj    = {},
0 ignored issues
show
Unused Code introduced by
The variable obj seems to be never used. Consider removing it.
Loading history...
319
    	    			    plugin = $(plgn).data($app.appName+'Plugin')
320
    	    			; 
321
    	    			plugins[plugin.uuid] = plugin; 
322
    	    		});
323
    	    		return plugins;
324
    	    	}
325
    	    }
326
    	    
327
    	;
328
329
    	if (typeof global[methodName] == 'undefined') {
330
        	global[methodName] = method;
331
    	}
332
    	if (typeof global[methodLong] == 'undefined') {
333
        	global[methodLong] = method;
334
    	}
335
    	return global;
336
    }
337
338
    /**
339
     * Adds (Siteapp) application plugin to jQuery
340
     * 
341
     * adds a function/mapping for [Siteapp].run to the given jQuery object
342
     * with the name taken from the application namespace option
343
     * 
344
     * @see Siteapp.run
345
     * @function
346
     * @param {jQuery} $ 
347
     * @returns {jQuery}
348
     */
349
    addToJquery ($) {
350
    	
351
        /**
352
         * The Siteapp jQuery plugin.
353
         * @param {String|Array} method - An action to perform on the current jQuery object.
354
         */
355
    	var $app = this;
356
        var invoke = function(method) {
357
            $app.run(this, method);
358
            return this;
359
        };
360
        
361
        // add to jQuery object
362
        $.fn[this.appName] = invoke;
363
        
364
        return $;
365
    }
366
367
    /**
368
     * (re)initialize modules attached to corresponding elements
369
     * 
370
     * @function
371
     * @see ModuleManager.reInit
372
     */
373
    reInit (plugins) {
374
    	//console.//log('app re-init:', this.utilities.functionName(this));
375
    	
376
    	// re-init (generic) modules
377
    	if (this.Modules && !this.options.Modules) {
378
    		this.Modules.reInit(plugins);
379
    	}
380
    	// re-init UI modules
381
    	if (this.Ui && !this.options.disableUi) { 
382
    		this.Ui.reInit(plugins);
383
    	}
384
    	
385
    	return this;
386
    } 
387
    
388
    /**
389
     * (re)apply modules on corrensponding elements
390
     * 
391
     * @function
392
     * @see ModuleManager.reflow
393
     */
394
    reflow (elem, plugins) {
395
    	//console.//log('app reflow:', this.utilities.functionName(this));
396
    	
397
    	// reflow (generic) modules
398
    	if (this.Modules && !this.options.disableModules) {
399
    		this.Modules.reflow(elem, plugins);
400
    	}
401
    	// reflow UI modules
402
    	if (this.Ui && !this.options.disableUi) {
403
    		this.Ui.reflow(elem, plugins);
404
    	}
405
    	
406
    	return this;
407
    } 
408
    
409
    /**
410
     * Initializes the application cycle and 'reflow' modules, if no parameter is given.
411
     * If only an element is given, invokes all elements' 'reflow'.
412
     * If a method name is given, invokes an element's plugin method if available.
413
     * If only a method name is given, tries to invoke a plugin's method attached to 'document'.
414
     * 
415
     * Throws an error if the given method is not available.
416
     * 
417
     * example:
418
     * ```
419
     * MyApp.run();  // -> init application and reflow all modules
420
     * ```
421
     * just a selector:
422
     * ```
423
     * MyApp.run('.someelements');  // -> reflows all modules attached to elements matching the selector
424
     * ```
425
     * with selector and method name:
426
     * ```
427
     * MyApp.run('.someelements', 'doSomething');  // -> invokes a module's 'doSomething' method elements matching the selector
428
     * ```
429
     * just a method name:
430
     * ```
431
     * MyApp.run('doSomething');  // -> invokes a module's 'doSomething' method attached to 'document'
432
     * ```
433
     * 
434
     * 
435
     * @function
436
     * @param {jQuery|HTMLElement} element - reference element to start with applying the method/reflow
0 ignored issues
show
Documentation Bug introduced by
The parameter element does not exist. Did you maybe mean elem instead?
Loading history...
437
     * @param {String|Array} method - An action to perform on the current jQuery object.
438
     * @returns {Siteapp}
439
     */
440
    run ( elem, method ) {
441
    	if (this.options.hasJS) {
442
    		this.hasJS();
443
    	}
444
    	if (typeof elem === 'undefined') {
445
    		elem = document;
446
    	} else {
447
    		if ( (arguments.length === 1) && (typeof elem === 'string') ) {
448
    			if ( $(elem).length === 0 ) {
449
    				// no element found by selector, so assume methodname
450
    				method = elem;
451
    				elem   = document;
452
    			}   
453
    		}
454
    	}
455
    	var $element = $(elem),
456
    	    type     = typeof method,
457
    	    $app     = this
458
    	;
459
	
460
	    if (type === 'undefined') {
461
	    	// needs to initialize the Siteapp object, or an individual plugin.
462
	    	if (this.MediaQuery && (typeof this.MediaQuery._init == 'function')) {
463
	    		this.MediaQuery._init();
464
	    	}
465
	        this.reflow($element);
466
	    } else if (type === 'string') {
467
	    	if ( 
468
	    			this.options.disablePrivateMethods && 
469
	    			(method !== '_init') && // (re)allow '_init' method ;)
470
	    			(method.charAt(0) == this.options.privateMethodsIndicator) 
471
	        ) {
472
		    	// error for calling private plugin methods
473
		    	throw new TypeError(`We're sorry, invoking private module/plugin methods is restricted.`);
474
	    	}
475
	    	
476
	    	// an individual method to invoke on a plugin/module or group of plugins/modules
477
	        var args = [];
478
	        if ((arguments.length > 2)) { 
479
	        	args = Array.prototype.slice.call(arguments, 2); 
480
	        	//collect all the arguments, if necessary
481
	        }
482
	        var plugClass = $element.data($app.appName+'Plugin'); 
483
	        // determine the class of plugin
484
	        
485
	        if (plugClass !== undefined && plugClass[method] !== undefined) { 
486
	        	// make sure both the class and method exist
487
	            if ($element.length === 1) { 
488
	            	// if there's only one, call it directly.
489
	                plugClass[method].apply( plugClass, args );
490
	            } else {
491
	            	$element.each(function (i, el) { 
492
	                	// otherwise loop through the jQuery collection and invoke the method on each
493
	                    plugClass[method].apply( $(el).data($app.appName+'Plugin'), args );
494
	                });
495
	            }
496
	        } else if ($element.length > 0) {
497
	        	// error for no class or no method, but only if elements were explicitly selected
498
	   	 	    //console.//log('plugin method:', plugClass, method, $element);
499
	            throw new ReferenceError("We're sorry, '" + method + "' is not an available method for " + (plugClass ? $app.utilities.functionName(plugClass) : 'this element') + '.');
500
	        }
501
	    } else {
502
	    	// error for invalid argument type
503
	    	throw new TypeError(`We're sorry, ${type} is not a valid parameter. You must use a string representing the method you wish to invoke.`);
504
	    }
505
	    return this;
506
    }
507
    
508
    /**
509
     * Removes -no JavaScript- indicator class from elements
510
     * @function
511
     */
512
    hasJS() { 
513
    	var $noJS = $('.'+this.options.classnameNoJS);
514
515
        if($noJS.length){
516
            $noJS.removeClass( this.options.classnameNoJS );
517
        }
518
    }
519
520
    /**
521
     * retrieve the application's (namespace) name
522
     */
523
    get appName ( ) { 
524
        return this.options.namespace;
525
    }
526
    
527
    /**
528
     * retrieve the application's instance name
529
     */
530
    get instanceName ( ) { 
531
        return this.utilities.functionName(this);
532
    }
533
    
534
    /**
535
     * Retrieve current version.
536
     */
537
    get version () { 
538
        return this._version; 
539
    }
540
    
541
    /**
542
     * Retrieve current version.
543
     */
544
    set version ( ver ) {
545
    	this._version = ver;
546
    }
547
548
    /**
549
     * Namespace alias.
550
     */
551
    get NS () { 
552
        return this.Namespace;
553
    }
554
555
    /**
556
     * Debugger alias.
557
     */
558
    get D () { 
559
        return this.Debugger;
560
    }
561
562
    /**
563
     * Logger alias.
564
     */
565
    get L () { 
566
        return this.Log;
567
    }
568
    
569
    
570
    //
571
    // Since we are more or less directly deriving from it,
572
    // these methods make [Siteapp] compatible with Foundation 
573
    // back again, mapping all plugins to the main module
574
    // manager.
575
    //
576
    
577
    
578
    /**
579
     * [BC] Siteapp.plugin alias for ModuleManager.registerModule
580
     * @function
581
     * @deprecated
582
     * @see ModuleManager.registerModule
583
     */
584
    plugin (_plugin, name) {
585
    	return this.Modules.registerModule(_plugin, name);
586
    } 
587
588
    /**
589
     * [BC] Siteapp.registerPlugin alias for ModuleManager.initializeModule
590
     * @function
591
     * @deprecated
592
     * @see ModuleManager.initializeModule
593
     */
594
    registerPlugin (plugin, name) {
595
    	return this.Modules.initializeModule(plugin, name);
596
    } 
597
598
    /**
599
     * [BC] Siteapp.unregisterPlugin alias for ModuleManager.destroyModule
600
     * @function
601
     * @deprecated
602
     * @see ModuleManager.destroyModule
603
     */
604
    unregisterPlugin (plugin) {
605
    	return this.Modules.destroyModule(plugin);
606
    } 
607
    
608
    
609
};
610
611
Siteapp.prototype.defaults  = {
612
		
613
	// applicatin namespace
614
	namespace: 'siteapp',
615
	
616
	// application language code (ISO)
617
	lang: 'en_US',
618
	
619
	
620
	
621
	// disable storage engine
622
	disableStorage: false,
623
	
624
	// disable UI manager
625
	disableUi: false,
626
	
627
	// disable module manager (well, TBH, it makes no sence to turn this one off)
628
	disableModules: false,
629
	
630
	
631
	// remove -noJS- indicator on start-up
632
	hasJS: true,
633
	
634
	// -noJS- indicator classname
635
	classnameNoJS: 'no-js',
636
	
637
	
638
	
639
	
640
	// disable calls to/invokations of private plugin/module methods 
641
	disablePrivateMethods: true,
642
	
643
	// indicator, first character of a methodname, to determine calls to/invokations of private plugin/module methods 
644
	privateMethodsIndicator: '_'
645
	
646
		
647
};
648
649
650
// is this still needed?
651
Siteapp.prototype.libs      = {};
652
653
654
655
/**
656
 * Add Siteapp Utils to Siteapp utilities/'sys' namespace
657
 */
658
import {
659
	
660
	rtl, 
661
	GenerateUUID, 
662
	transitionend, 
663
	secureProperties,
664
	functionName,
665
	parseValue,
666
	hyphenate,
667
	throttle
668
	
669
} from './util/siteapp.util.core';
670
import EventManager from './sys/siteapp.eventManager';
671
672
Siteapp.prototype.utilities = {
673
		
674
    /**
675
     * Function for applying a debounce effect to a function call.
676
     * @function
677
     * @param {Function} func - Function to be called at end of timeout.
678
     * @param {Number} delay - Time in ms to delay the call of `func`.
679
     * @returns function
680
     */
681
    throttle: throttle,
682
    
683
    /**
684
     * returns a random base-36 uid with namespacing
685
     * @function
686
     * @param {Number} length - number of random base-36 digits desired. Increase 
687
     *                          for more random strings.
688
     * @param {String} namespace - name of plugin to be incorporated in uid, optional.
689
     * @default {String} '' - if no plugin name is provided, nothing is appended 
690
     *                        to the uid.
691
     * @returns {String} - unique id
692
     */
693
    genUUID: GenerateUUID,
694
    
695
    /**
696
     * Vendor polyfill for 'transitionend'
697
     * 
698
     * @function
699
     * @param {jQuery} $elem
700
     * @returns {String}
701
     */
702
    transitionend: transitionend,
703
    
704
    /**
705
     * Polyfill to get the name of a function/class instance in IE9
706
     * 
707
     * @function
708
     * @param {function} fn
709
     * @returns {string}
710
     */
711
    functionName: functionName,
712
713
    /**
714
     * Normalize value
715
     * 
716
     * @function
717
     * @param {mixed} str
718
     * @returns {boolean|number|string}
719
     */
720
    parseValue: parseValue,
721
722
    /**
723
     * Convert PascalCase to kebab-case
724
     * @see http://stackoverflow.com/a/8955580
725
     * 
726
     * @function
727
     * @param {string} str
728
     * @returns {string}
729
     */
730
    hyphenate: hyphenate,
731
    
732
    /**
733
     * Returns a boolean for RTL support
734
     * 
735
     * @function
736
     * @returns {boolean}
737
     */
738
    rtl: rtl,
739
740
    /**
741
     * Overrides setters for some $object's properties(2secure).
742
     * So those properties can only be set, eg., when creating a new instance. 
743
     * 
744
     * This should try to prevent at least obvious direct hacking. #crossing-fingers
745
     * 
746
     * - example:
747
     *   ```
748
     *   var obj = { a: 'x' };
749
     *   secureProperties( obj, ['a'] );
750
     *   
751
     *   obj.a = 'y' // => ERROR
752
     *   ```
753
     *   
754
     * @function
755
     * @access private
756
     * @param {object} $object - target object
757
     * @param {[string]} properties2secure - list of property keys to secure
758
     * @returns {object} - the modified $object
759
     */
760
    secureProperties: secureProperties,
761
    
762
    /**
763
     * Event distpatcher/manager to create event driven components not attached to a DOM element
764
     * @var {EventManager} EventManager
765
     * @see Siteapp.EventManager
766
     */
767
    EventManager: EventManager
768
769
};
770
771
/**
772
 * alias for utility namespace
773
 */
774
Siteapp.prototype.sys  = Siteapp.prototype.utilities;
775
// map to 'own property'
776
Siteapp.utilities = Siteapp.prototype.utilities;
777
Siteapp.sys       = Siteapp.prototype.utilities;
778
779
780
781
// Polyfill for requestAnimationFrame
782
(function() {
783
    if (!Date.now || !window.Date.now)
784
        window.Date.now = Date.now = function() { return new Date().getTime(); };
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
Compatibility Best Practice introduced by
You are extending the built-in type Date. This may have unintended consequences on other objects using this built-in type. Consider subclassing instead.
Loading history...
785
786
    var vendors = ['webkit', 'moz'];
787
    for (var i = 0; i < vendors.length && !window.requestAnimationFrame; ++i) {
788
        var vp = vendors[i];
789
        window.requestAnimationFrame = window[vp+'RequestAnimationFrame'];
790
        window.cancelAnimationFrame = (window[vp+'CancelAnimationFrame']
791
                                    || window[vp+'CancelRequestAnimationFrame']);
792
    }
793
    if (/iP(ad|hone|od).*OS 6/.test(window.navigator.userAgent)
794
        || !window.requestAnimationFrame || !window.cancelAnimationFrame) {
795
        var lastTime = 0;
796
        window.requestAnimationFrame = function(callback) {
797
                var now = Date.now();
798
                var nextTime = Math.max(lastTime + 16, now);
799
                return setTimeout(function() { callback(lastTime = nextTime); },
800
                                                    nextTime - now);
801
        };
802
        window.cancelAnimationFrame = clearTimeout;
0 ignored issues
show
Bug introduced by
The variable clearTimeout seems to be never declared. If this is a global, consider adding a /** global: clearTimeout */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
803
    }
804
    /**
805
     * Polyfill for performance.now, recommended by rAF
806
     */
807
    if(!window.performance || !window.performance.now){
808
        window.performance = {
809
            start: Date.now(),
810
            now: function(){ return Date.now() - this.start; }
811
        };
812
    }
813
})();
814
815
816
817
// Polyfill for {function-name}.bind(object)
818
if (!Function.prototype.bind) {
819
    Function.prototype.bind = function(oThis) {
0 ignored issues
show
Compatibility Best Practice introduced by
You are extending the built-in type Function. This may have unintended consequences on other objects using this built-in type. Consider subclassing instead.
Loading history...
820
        if (typeof this !== 'function') {
821
            // closest thing possible to the ECMAScript 5
822
            // internal IsCallable function
823
            throw new TypeError('Function.prototype.bind - what is trying to be '+
824
                    'bound is not callable');
825
        }
826
827
        var aArgs   = Array.prototype.slice.call(arguments, 1),
828
            fToBind = this,
829
            fNOP    = function() {},
830
            fBound  = function() {
831
                return fToBind.apply(
832
                    this instanceof fNOP ? this : oThis,
833
                    aArgs.concat(Array.prototype.slice.call(arguments))
834
                );
835
            };
836
837
        if (this.prototype) {
838
            // native functions don't have a prototype
839
            fNOP.prototype = this.prototype;
840
        }
841
        fBound.prototype = new fNOP();
0 ignored issues
show
Coding Style Best Practice introduced by
By convention, constructors like fNOP should be capitalized.
Loading history...
842
843
        return fBound;
844
    };
845
}
846
847
848
849
//export {Siteapp};
850
export default Siteapp;
851
852
853