<commit_before>/**
* @license Apache-2.0
*
* Copyright (c) 2020 The Stdlib Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

/*
* When adding modules to the namespace, ensure that they are added in alphabetical order according to module name.
*/

// MODULES //

var setReadOnly = require( '@stdlib/utils/define-read-only-property' );

// MAIN //

/**
* Top-level namespace.
*
* @namespace ns
*/
var ns = {};

/**
* @name binary
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/binary}
*/
setReadOnly( ns, 'binary', require( '@stdlib/strided/base/binary' ) );

/**
* @name binaryAddonDispatch
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/binary-addon-dispatch}
*/
setReadOnly( ns, 'binaryAddonDispatch', require( '@stdlib/strided/base/binary-addon-dispatch' ) );

/**
* @name dmap
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/dmap}
*/
setReadOnly( ns, 'dmap', require( '@stdlib/strided/base/dmap' ) );

/**
* @name dmap2
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/dmap2}
*/
setReadOnly( ns, 'dmap2', require( '@stdlib/strided/base/dmap2' ) );

/**
* @name dmskmap
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/dmskmap}
*/
setReadOnly( ns, 'dmskmap', require( '@stdlib/strided/base/dmskmap' ) );

/**
* @name dmskmap2
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/dmskmap2}
*/
setReadOnly( ns, 'dmskmap2', require( '@stdlib/strided/base/dmskmap2' ) );

/**
* @name dtypeEnum2Str
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/dtype-enum2str}
*/
setReadOnly( ns, 'dtypeEnum2Str', require( '@stdlib/strided/base/dtype-enum2str' ) );

/**
* @name dtypeResolveEnum
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/dtype-resolve-enum}
*/
setReadOnly( ns, 'dtypeResolveEnum', require( '@stdlib/strided/base/dtype-resolve-enum' ) );

/**
* @name dtypeStr2Enum
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/dtype-str2enum}
*/
setReadOnly( ns, 'dtypeStr2Enum', require( '@stdlib/strided/base/dtype-str2enum' ) );

/**
* @name mapBy
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/map-by}
*/
setReadOnly( ns, 'mapBy', require( '@stdlib/strided/base/map-by' ) );

/**
* @name mapBy2
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/map-by2}
*/
setReadOnly( ns, 'mapBy2', require( '@stdlib/strided/base/map-by2' ) );

/**
* @name metaDataProps
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/meta-data-props}
*/
setReadOnly( ns, 'metaDataProps', require( '@stdlib/strided/base/meta-data-props' ) );

/**
* @name mskunary
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/mskunary}
*/
setReadOnly( ns, 'mskunary', require( '@stdlib/strided/base/mskunary' ) );

/**
* @name nullary
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/nullary}
*/
setReadOnly( ns, 'nullary', require( '@stdlib/strided/base/nullary' ) );

/**
* @name quaternary
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/quaternary}
*/
setReadOnly( ns, 'quaternary', require( '@stdlib/strided/base/quaternary' ) );

/**
* @name quinary
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/quinary}
*/
setReadOnly( ns, 'quinary', require( '@stdlib/strided/base/quinary' ) );

/**
* @name reinterpretComplex64
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/reinterpret-complex64}
*/
setReadOnly( ns, 'reinterpretComplex64', require( '@stdlib/strided/base/reinterpret-complex64' ) );

/**
* @name reinterpretComplex128
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/reinterpret-complex128}
*/
setReadOnly( ns, 'reinterpretComplex128', require( '@stdlib/strided/base/reinterpret-complex128' ) );

/**
* @name smap
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/smap}
*/
setReadOnly( ns, 'smap', require( '@stdlib/strided/base/smap' ) );

/**
* @name smap2
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/smap2}
*/
setReadOnly( ns, 'smap2', require( '@stdlib/strided/base/smap2' ) );

/**
* @name smskmap
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/smskmap}
*/
setReadOnly( ns, 'smskmap', require( '@stdlib/strided/base/smskmap' ) );

/**
* @name smskmap2
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/smskmap2}
*/
setReadOnly( ns, 'smskmap2', require( '@stdlib/strided/base/smskmap2' ) );

/**
* @name ternary
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/ternary}
*/
setReadOnly( ns, 'ternary', require( '@stdlib/strided/base/ternary' ) );

/**
* @name unary
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/unary}
*/
setReadOnly( ns, 'unary', require( '@stdlib/strided/base/unary' ) );

/**
* @name unaryAddonDispatch
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/unary-addon-dispatch}
*/
setReadOnly( ns, 'unaryAddonDispatch', require( '@stdlib/strided/base/unary-addon-dispatch' ) );

// EXPORTS //

module.exports = ns;
<commit_msg>Update namespace<commit_after>/**
* @license Apache-2.0
*
* Copyright (c) 2020 The Stdlib Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

/*
* When adding modules to the namespace, ensure that they are added in alphabetical order according to module name.
*/

// MODULES //

var setReadOnly = require( '@stdlib/utils/define-read-only-property' );

// MAIN //

/**
* Top-level namespace.
*
* @namespace ns
*/
var ns = {};

/**
* @name binary
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/binary}
*/
setReadOnly( ns, 'binary', require( '@stdlib/strided/base/binary' ) );

/**
* @name binaryAddonDispatch
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/binary-addon-dispatch}
*/
setReadOnly( ns, 'binaryAddonDispatch', require( '@stdlib/strided/base/binary-addon-dispatch' ) );

/**
* @name dmap
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/dmap}
*/
setReadOnly( ns, 'dmap', require( '@stdlib/strided/base/dmap' ) );

/**
* @name dmap2
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/dmap2}
*/
setReadOnly( ns, 'dmap2', require( '@stdlib/strided/base/dmap2' ) );

/**
* @name dmskmap
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/dmskmap}
*/
setReadOnly( ns, 'dmskmap', require( '@stdlib/strided/base/dmskmap' ) );

/**
* @name dmskmap2
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/dmskmap2}
*/
setReadOnly( ns, 'dmskmap2', require( '@stdlib/strided/base/dmskmap2' ) );

/**
* @name dtypeEnum2Str
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/dtype-enum2str}
*/
setReadOnly( ns, 'dtypeEnum2Str', require( '@stdlib/strided/base/dtype-enum2str' ) );

/**
* @name dtypeResolveEnum
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/dtype-resolve-enum}
*/
setReadOnly( ns, 'dtypeResolveEnum', require( '@stdlib/strided/base/dtype-resolve-enum' ) );

/**
* @name dtypeStr2Enum
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/dtype-str2enum}
*/
setReadOnly( ns, 'dtypeStr2Enum', require( '@stdlib/strided/base/dtype-str2enum' ) );

/**
* @name mapBy
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/map-by}
*/
setReadOnly( ns, 'mapBy', require( '@stdlib/strided/base/map-by' ) );

/**
* @name mapBy2
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/map-by2}
*/
setReadOnly( ns, 'mapBy2', require( '@stdlib/strided/base/map-by2' ) );

/**
* @name metaDataProps
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/meta-data-props}
*/
setReadOnly( ns, 'metaDataProps', require( '@stdlib/strided/base/meta-data-props' ) );

/**
* @name mskunary
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/mskunary}
*/
setReadOnly( ns, 'mskunary', require( '@stdlib/strided/base/mskunary' ) );

/**
* @name nullary
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/nullary}
*/
setReadOnly( ns, 'nullary', require( '@stdlib/strided/base/nullary' ) );

/**
* @name offsetView
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/offset-view}
*/
setReadOnly( ns, 'offsetView', require( '@stdlib/strided/base/offset-view' ) );

/**
* @name quaternary
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/quaternary}
*/
setReadOnly( ns, 'quaternary', require( '@stdlib/strided/base/quaternary' ) );

/**
* @name quinary
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/quinary}
*/
setReadOnly( ns, 'quinary', require( '@stdlib/strided/base/quinary' ) );

/**
* @name reinterpretComplex64
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/reinterpret-complex64}
*/
setReadOnly( ns, 'reinterpretComplex64', require( '@stdlib/strided/base/reinterpret-complex64' ) );

/**
* @name reinterpretComplex128
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/reinterpret-complex128}
*/
setReadOnly( ns, 'reinterpretComplex128', require( '@stdlib/strided/base/reinterpret-complex128' ) );

/**
* @name smap
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/smap}
*/
setReadOnly( ns, 'smap', require( '@stdlib/strided/base/smap' ) );

/**
* @name smap2
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/smap2}
*/
setReadOnly( ns, 'smap2', require( '@stdlib/strided/base/smap2' ) );

/**
* @name smskmap
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/smskmap}
*/
setReadOnly( ns, 'smskmap', require( '@stdlib/strided/base/smskmap' ) );

/**
* @name smskmap2
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/smskmap2}
*/
setReadOnly( ns, 'smskmap2', require( '@stdlib/strided/base/smskmap2' ) );

/**
* @name ternary
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/ternary}
*/
setReadOnly( ns, 'ternary', require( '@stdlib/strided/base/ternary' ) );

/**
* @name unary
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/unary}
*/
setReadOnly( ns, 'unary', require( '@stdlib/strided/base/unary' ) );

/**
* @name unaryAddonDispatch
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/strided/base/unary-addon-dispatch}
*/
setReadOnly( ns, 'unaryAddonDispatch', require( '@stdlib/strided/base/unary-addon-dispatch' ) );

// EXPORTS //

module.exports = ns;
<|endoftext|>


<commit_before>/**
 * @name App
 * @memberOf {Enpowi}
 * @constructor
 */
Namespace('Enpowi').

    Class('App', {
		Static: {
			pubs: {},
			sub: function(eventName, callback) {
				var pubs;
				if ((pubs = this.pubs[eventName]) === undefined) pubs = this.pubs[eventName] = [];
				pubs.push(callback);

				return this;
			},
			pub: function(eventName, data) {
				var pubs,
					max,
					i;

				if ((pubs = this.pubs[eventName]) === undefined) return this;

				i = 0;
				max = pubs.length;

				for (;i <max;i++) {
					pubs[i].apply(this, data);
				}

				return this;
			}
		},
        construct: function(callback) {
            this.router = crossroads;
            this.routes = [];
            this.hasher = hasher;
            this.loadingElement = null;
            this.routeCallback = callback;

            Enpowi.directives.setup(this);
            Enpowi.module.setup(this);
            Enpowi.translation.setup(this);

            this.setupRoutes();
        },

        setupRoutes: function() {
            //setup router
            var router = this.router,
                app = this,
                landRoute = function(url, route) {
	                var init = false,
		                completed = false,
		                timer = setInterval(function() {
			                if (!init) {
				                init = true;
				                app.setLoading(true);
			                }

			                if (completed) {
				                clearInterval(timer);
				                app.setLoading(false);
			                }
		                }, 500);

                    app.load(url, function(data) {
                        app.loadScript('modules?module=app&component=session.js', function() {
	                        completed = true;
                            var result = app.process(data);
                            app.routeCallback(result);
                            Enpowi.App.pub('app.land', [route]);
                        });
                    });
                };

            this.hasher = hasher;

            this.bindRouteUrls(router, landRoute);

            //setup hasher
            function parseHash(newHash, oldHash){
                router.parse(newHash);
            }

            hasher.initialized.add(parseHash); //parse initial hash
            hasher.changed.add(parseHash); //parse hash changes
            hasher.init(); //start listening for history change

        },

        bindRouteUrls: function(router, callback) {
            //none
            //moduleName
            //moduleName/component
            //moduleName/component/id
            //moduleName/component?querystring
            router.normalizeFn = crossroads.NORM_AS_OBJECT;

            router.addRoute('/', function() {
                callback('modules?module=' + Enpowi.session.theme + '&component=index', '');
            });
            router.addRoute('/{module}', function(path) {
                callback('modules?module=' + path.module, path.request_);
            });
            router.addRoute('/{module}{?query}', function(path) {
                callback('modules?module=' + path.module + '&'  + path['?query_'], path.request_);
            });
            router.addRoute('/{module}/{component}', function(path) {
                callback('modules?module=' + path.module + '&component=' + path.component, path.request_);
            });
            router.addRoute('/{module}/{component}/{id}', function(path) {
                callback('modules?module=' + path.module + '&component=' + path.component + '&id' + path.id, path.request_);
            });
            router.addRoute('/{module}/{component}{?query}', function(path) {
                callback('modules?module=' + path.module + '&component=' + path.component + '&'  + path['?query_'], path.request_);
            });

	        router.routed.add(function(route) {
		        Enpowi.App.pub('app.go', [route]);
	        });
        },

        logRoutes: function() {
            this.router.routed.add(console.log, console); //log all routes

            return this;
        },

        loadScripts: function(urls, callback) {
            this.loadAll(urls, function(results) {
                var i = 0,
                    max = results.length;

                for(;i < max; i++) {
                    (new Function(results[i]))();
                }

                if (callback) callback();
            });
        },
        loadStyles: function(urls) {
            var i = 0,
                max = urls.length,
                style,
                styles = document.createDocumentFragment();

            for(;i<max;i++) {
                style = document.createElement('link');
                style.setAttribute('href', urls[i]);
                style.setAttribute('rel', 'stylesheet');
                styles.appendChild(style);
            }

            return styles;
        },
        process: function(html) {
            var el = document.createElement('div'),
                frag = document.createDocumentFragment(),
                child,
	            scripts,
	            script,
	            i = 0,
	            max,
	            scriptBody,
	            scriptXSS = [],
	            scriptsRemote = [],
	            scriptsLocal = document.createDocumentFragment();

            el.innerHTML = html;

	        Enpowi.App.pub('pre-process', [el]);

	        //obtain scripts
	        scripts = el.querySelectorAll('script');

	        max = scripts.length;

	        for(;i<max;i++) {
		        script = scripts[i];
		        if (script.hasAttribute('src')) {
			        if (script.hasAttribute('xss')) {
				        scriptXSS.push(script);
			        } else {
				        scriptsRemote.push(script.getAttribute('src'));
			        }
		        } else {
			        scriptBody = script.innerHTML;
			        script = document.createElement('script');
			        script.innerHTML = scriptBody;
			        scriptsLocal.appendChild(script);
		        }
	        }

	        //process html
            while (el.children.length > 0) {
                child = el.firstChild;
                el.removeChild(child);
                frag.appendChild(child);

                if (child.nodeType === 1) {
                    new Vue({
                        el: child,
                        data: (function () {
                            var data = {
                                    session: Enpowi.session
                                },
                                jsonEncoded = child.getAttribute('data'),
                                jsonDecoded,
                                moduleData,
                                i;

                            if (jsonEncoded) {
                                child.removeAttribute('data');
                                jsonDecoded = decodeURIComponent(jsonEncoded);
                                moduleData = JSON.parse(jsonDecoded);

                                for (i in moduleData) if (i && moduleData.hasOwnProperty(i)) {
                                    data[i] = moduleData[i];
                                }
                            }

                            return data;
                        })(),
                        methods: {
                            go: function (sig) {
                                app.go(sig);
                            },
                            stringify: function (json) {
                                return JSON.stringify(json);
                            },
                            arrayLookup: function(array, key, value) {
                                var i = 0,
                                    max = array.length;

                                for(;i < max; i++) {
                                    if (array[i][key] === value) return array[i];
                                }

                                return null;
                            },
                            hasPerm: function (module, component) {
                                var hasPerm = false;
                                $.each(Enpowi.session.user.groups, function () {
                                    $.each(this.perms, function () {
                                        if (this.module === module || this.module === '*') {
                                            if (this.component === component || this.component === '*') {
                                                hasPerm = true;
                                            }
                                        }
                                    });
                                });

                                return hasPerm;
                            },
                            hasKey: function (key, array) {
                                return array[key] !== undefined;
                            }
                        }
                    });
                }
            }

	        //process scripts
	        if (scriptsRemote.length > 0) {
		        this.loadScripts(scriptsRemote, function() {
			        if (scriptsLocal.children.length > 0) {
				        document.querySelector('script').parentElement.appendChild(scriptsLocal);
			        }
		        });
	        } else if (scriptsLocal.children.length > 0) {
		        document.querySelector('script').parentElement.appendChild(scriptsLocal);
	        }

	        if (scriptXSS.length > 0) {
		        $('body').append(scriptXSS);
	        }

            return frag;
        },

        go: function(route) {
            if ('#/' + route === window.location.hash.toString()) {
                this.hasher.setHash(route + '/');
            } else {
                this.hasher.setHash(route);
            }

            return this;
        },

        loadScript: function(url, callback) {
            this.load(url, function(scriptHTML) {
                (new Function(scriptHTML))();
                if (callback !== undefined) callback();
            });
        },

        loadAll: function(urls, callback) {
            var app = this,
                i = 0,
                progress = 0,
                max = urls.length,
                results = [];

            for (;i < max; i++) {
                (function(i) {
                    app.load(urls[i], function(result) {
                        results[i] = result;
                        progress++;
                        if (progress === max) {
                            callback(results);
                        }
                    });
                })(i);
            }

            return this;
        },
        load: function(url, callback, usePost) {
            var request = new XMLHttpRequest();

            request.open((usePost ? 'POST' : 'GET'), url, true);

            request.onload = function() {
                if (request.status >= 200 && request.status < 400) {
                    // Success!
                    callback(request.responseText);
                } else {
                    // Error
                    callback(null, request.responseText);

                }
            };

            request.onerror = function() {};

            request.send();

            return this;
        },
        loadModule: function(url, callback) {
            var app = this;

            this.load(Enpowi.module.url(url), function(moduleHtml) {
                callback(app.process(moduleHtml));
            });

            return this;
        },
        isLoading: false,
        /**
         *
         * @param {Boolean} isLoading
         * @returns {Enpowi.App}
         */
        setLoading: function(isLoading) {
            var el;
            if ((el = this.loadingElement) === null) return this;

            if (this.isLoading === false && isLoading) {
                this.isLoading = isLoading;
	            Enpowi.App.pub('app.delay');
            }

            else if (this.isLoading && isLoading === false) {
                this.isLoading = isLoading;
	            Enpowi.App.pub('app.continue');
            }

            return this;
        }
    });<commit_msg>Add getElementById to app so to obtain elements that are being processed that are not yet in the dom.<commit_after>/**
 * @name App
 * @memberOf {Enpowi}
 * @constructor
 */
Namespace('Enpowi').

    Class('App', {
		Static: {
			pubs: {},
			sub: function(eventName, callback) {
				var pubs;
				if ((pubs = this.pubs[eventName]) === undefined) pubs = this.pubs[eventName] = [];
				pubs.push(callback);

				return this;
			},
			pub: function(eventName, data) {
				var pubs,
					max,
					i;

				if ((pubs = this.pubs[eventName]) === undefined) return this;

				i = 0;
				max = pubs.length;

				for (;i <max;i++) {
					pubs[i].apply(this, data);
				}

				return this;
			}
		},
        construct: function(callback) {
            this.router = crossroads;
            this.routes = [];
            this.hasher = hasher;
            this.loadingElement = null;
            this.routeCallback = callback;

            Enpowi.directives.setup(this);
            Enpowi.module.setup(this);
            Enpowi.translation.setup(this);

            this.setupRoutes();
        },

        setupRoutes: function() {
            //setup router
            var router = this.router,
                app = this,
                landRoute = function(url, route) {
	                var init = false,
		                completed = false,
		                timer = setInterval(function() {
			                if (!init) {
				                init = true;
				                app.setLoading(true);
			                }

			                if (completed) {
				                clearInterval(timer);
				                app.setLoading(false);
			                }
		                }, 500);

                    app.load(url, function(data) {
                        app.loadScript('modules?module=app&component=session.js', function() {
	                        completed = true;
                            var result = app.process(data);
                            app.routeCallback(result);
                            Enpowi.App.pub('app.land', [route]);
                        });
                    });
                };

            this.hasher = hasher;

            this.bindRouteUrls(router, landRoute);

            //setup hasher
            function parseHash(newHash, oldHash){
                router.parse(newHash);
            }

            hasher.initialized.add(parseHash); //parse initial hash
            hasher.changed.add(parseHash); //parse hash changes
            hasher.init(); //start listening for history change

        },

        bindRouteUrls: function(router, callback) {
            //none
            //moduleName
            //moduleName/component
            //moduleName/component/id
            //moduleName/component?querystring
            router.normalizeFn = crossroads.NORM_AS_OBJECT;

            router.addRoute('/', function() {
                callback('modules?module=' + Enpowi.session.theme + '&component=index', '');
            });
            router.addRoute('/{module}', function(path) {
                callback('modules?module=' + path.module, path.request_);
            });
            router.addRoute('/{module}{?query}', function(path) {
                callback('modules?module=' + path.module + '&'  + path['?query_'], path.request_);
            });
            router.addRoute('/{module}/{component}', function(path) {
                callback('modules?module=' + path.module + '&component=' + path.component, path.request_);
            });
            router.addRoute('/{module}/{component}/{id}', function(path) {
                callback('modules?module=' + path.module + '&component=' + path.component + '&id' + path.id, path.request_);
            });
            router.addRoute('/{module}/{component}{?query}', function(path) {
                callback('modules?module=' + path.module + '&component=' + path.component + '&'  + path['?query_'], path.request_);
            });

	        router.routed.add(function(route) {
		        Enpowi.App.pub('app.go', [route]);
	        });
        },

        logRoutes: function() {
            this.router.routed.add(console.log, console); //log all routes

            return this;
        },

        loadScripts: function(urls, callback) {
            this.loadAll(urls, function(results) {
                var i = 0,
                    max = results.length;

                for(;i < max; i++) {
                    (new Function(results[i]))();
                }

                if (callback) callback();
            });
        },
        loadStyles: function(urls) {
            var i = 0,
                max = urls.length,
                style,
                styles = document.createDocumentFragment();

            for(;i<max;i++) {
                style = document.createElement('link');
                style.setAttribute('href', urls[i]);
                style.setAttribute('rel', 'stylesheet');
                styles.appendChild(style);
            }

            return styles;
        },
		/**
		 * @type {HTMLElement}
		 */
		processContainer: null,
        process: function(html) {
            var el = this.processContainer = document.createElement('div'),
                frag = document.createDocumentFragment(),
                child,
	            scripts,
	            script,
	            i = 0,
	            max,
	            scriptBody,
	            scriptXSS = [],
	            scriptsRemote = [],
	            scriptsLocal = document.createDocumentFragment();

            el.innerHTML = html;

	        Enpowi.App.pub('pre-process', [el]);

	        //obtain scripts
	        scripts = el.querySelectorAll('script');

	        max = scripts.length;

	        for(;i<max;i++) {
		        script = scripts[i];
		        if (script.hasAttribute('src')) {
			        if (script.hasAttribute('xss')) {
				        scriptXSS.push(script);
			        } else {
				        scriptsRemote.push(script.getAttribute('src'));
			        }
		        } else {
			        scriptBody = script.innerHTML;
			        script = document.createElement('script');
			        script.innerHTML = scriptBody;
			        scriptsLocal.appendChild(script);
		        }
	        }

	        //process html
            while (el.children.length > 0) {
                child = el.firstChild;
                el.removeChild(child);
                frag.appendChild(child);

                if (child.nodeType === 1) {
                    new Vue({
                        el: child,
                        data: (function () {
                            var data = {
                                    session: Enpowi.session
                                },
                                jsonEncoded = child.getAttribute('data'),
                                jsonDecoded,
                                moduleData,
                                i;

                            if (jsonEncoded) {
                                child.removeAttribute('data');
                                jsonDecoded = decodeURIComponent(jsonEncoded);
                                moduleData = JSON.parse(jsonDecoded);

                                for (i in moduleData) if (i && moduleData.hasOwnProperty(i)) {
                                    data[i] = moduleData[i];
                                }
                            }

                            return data;
                        })(),
                        methods: {
                            go: function (sig) {
                                app.go(sig);
                            },
                            stringify: function (json) {
                                return JSON.stringify(json);
                            },
                            arrayLookup: function(array, key, value) {
                                var i = 0,
                                    max = array.length;

                                for(;i < max; i++) {
                                    if (array[i][key] === value) return array[i];
                                }

                                return null;
                            },
                            hasPerm: function (module, component) {
                                var hasPerm = false;
                                $.each(Enpowi.session.user.groups, function () {
                                    $.each(this.perms, function () {
                                        if (this.module === module || this.module === '*') {
                                            if (this.component === component || this.component === '*') {
                                                hasPerm = true;
                                            }
                                        }
                                    });
                                });

                                return hasPerm;
                            },
                            hasKey: function (key, array) {
                                return array[key] !== undefined;
                            }
                        }
                    });
                }
            }

	        //process scripts
	        if (scriptsRemote.length > 0) {
		        this.loadScripts(scriptsRemote, function() {
			        if (scriptsLocal.children.length > 0) {
				        document.querySelector('script').parentElement.appendChild(scriptsLocal);
			        }
		        });
	        } else if (scriptsLocal.children.length > 0) {
		        document.querySelector('script').parentElement.appendChild(scriptsLocal);
	        }

	        if (scriptXSS.length > 0) {
		        $('body').append(scriptXSS);
	        }

            return frag;
        },

        go: function(route) {
            if ('#/' + route === window.location.hash.toString()) {
                this.hasher.setHash(route + '/');
            } else {
                this.hasher.setHash(route);
            }

            return this;
        },

        loadScript: function(url, callback) {
            this.load(url, function(scriptHTML) {
                (new Function(scriptHTML))();
                if (callback !== undefined) callback();
            });
        },

        loadAll: function(urls, callback) {
            var app = this,
                i = 0,
                progress = 0,
                max = urls.length,
                results = [];

            for (;i < max; i++) {
                (function(i) {
                    app.load(urls[i], function(result) {
                        results[i] = result;
                        progress++;
                        if (progress === max) {
                            callback(results);
                        }
                    });
                })(i);
            }

            return this;
        },
        load: function(url, callback, usePost) {
            var request = new XMLHttpRequest();

            request.open((usePost ? 'POST' : 'GET'), url, true);

            request.onload = function() {
                if (request.status >= 200 && request.status < 400) {
                    // Success!
                    callback(request.responseText);
                } else {
                    // Error
                    callback(null, request.responseText);

                }
            };

            request.onerror = function() {};

            request.send();

            return this;
        },
		getElementById: function(id) {
			var el = document.getElementById(id);

			if (el !== null) return el;

			if (this.processContainer !== null) {
				return this.processContainer.querySelector('#' + id);
			}
		},
        loadModule: function(url, callback) {
            var app = this;

            this.load(Enpowi.module.url(url), function(moduleHtml) {
                callback(app.process(moduleHtml));
            });

            return this;
        },
        isLoading: false,
        /**
         *
         * @param {Boolean} isLoading
         * @returns {Enpowi.App}
         */
        setLoading: function(isLoading) {
            var el;
            if ((el = this.loadingElement) === null) return this;

            if (this.isLoading === false && isLoading) {
                this.isLoading = isLoading;
	            Enpowi.App.pub('app.delay');
            }

            else if (this.isLoading && isLoading === false) {
                this.isLoading = isLoading;
	            Enpowi.App.pub('app.continue');
            }

            return this;
        }
    });<|endoftext|>


<commit_before>#!/usr/bin/env node

const configUtil = require('../lib/config-util')
const foreground = require('foreground-child')
var NYC
try {
  NYC = require('../index.covered.js')
} catch (e) {
  NYC = require('../index.js')
}
const processArgs = require('../lib/process-args')

const sw = require('spawn-wrap')
const wrapper = require.resolve('./wrap.js')

// parse configuration and command-line arguments;
// we keep these values in a few different forms,
// used in the various execution contexts of nyc:
// reporting, instrumenting subprocesses, etc.
const yargs = configUtil.buildYargs()
const instrumenterArgs = processArgs.hideInstrumenteeArgs()
const config = configUtil.loadConfig(yargs.parse(instrumenterArgs))
configUtil.addCommandsAndHelp(yargs)
const argv = yargs.config(config).parse(instrumenterArgs)

if ([
  'check-coverage', 'report', 'instrument', 'merge'
].indexOf(argv._[0]) !== -1) {
  // look in lib/commands for logic.
} else if (argv._.length) {
  // if instrument is set to false,
  // enable a noop instrumenter.
  if (!argv.instrument) argv.instrumenter = './lib/instrumenters/noop'
  else argv.instrumenter = './lib/instrumenters/istanbul'

  var nyc = (new NYC(argv))
  if (argv.clean) {
    nyc.reset()
  } else {
    nyc.createTempDirectory()
  }
  if (argv.all) nyc.addAllFiles()

  var env = {
    NYC_CONFIG: JSON.stringify(argv),
    NYC_CWD: process.cwd(),
    NYC_ROOT_ID: nyc.rootId,
    NYC_INSTRUMENTER: argv.instrumenter
  }

  if (argv['babel-cache'] === false) {
    // babel's cache interferes with some configurations, so is
    // disabled by default. opt in by setting babel-cache=true.
    env.BABEL_DISABLE_CACHE = process.env.BABEL_DISABLE_CACHE = '1'
  }

  sw([wrapper], env)

  // Both running the test script invocation and the check-coverage run may
  // set process.exitCode. Keep track so that both children are run, but
  // a non-zero exit codes in either one leads to an overall non-zero exit code.
  process.exitCode = 0
  foreground(processArgs.hideInstrumenterArgs(
    // use the same argv descrption, but don't exit
    // for flags like --help.
    configUtil.buildYargs().parse(process.argv.slice(2))
  ), function (done) {
    var mainChildExitCode = process.exitCode

    if (argv.checkCoverage) {
      checkCoverage(argv)
      process.exitCode = process.exitCode || mainChildExitCode
      if (!argv.silent) report(argv)
      return done()
    } else {
      if (!argv.silent) report(argv)
      return done()
    }
  })
} else {
  // I don't have a clue what you're doing.
  yargs.showHelp()
}

function report (argv) {
  process.env.NYC_CWD = process.cwd()

  var nyc = new NYC(argv)
  nyc.report()
}

function checkCoverage (argv, cb) {
  process.env.NYC_CWD = process.cwd()

  ;(new NYC(argv)).checkCoverage({
    lines: argv.lines,
    functions: argv.functions,
    branches: argv.branches,
    statements: argv.statements
  }, argv['per-file'])
}
<commit_msg>feat: avoid hardcoded HOME for spawn-wrap working dir (#957)<commit_after>#!/usr/bin/env node

const configUtil = require('../lib/config-util')
const foreground = require('foreground-child')
var NYC
try {
  NYC = require('../index.covered.js')
} catch (e) {
  NYC = require('../index.js')
}
const processArgs = require('../lib/process-args')

const sw = require('spawn-wrap')
const wrapper = require.resolve('./wrap.js')

// parse configuration and command-line arguments;
// we keep these values in a few different forms,
// used in the various execution contexts of nyc:
// reporting, instrumenting subprocesses, etc.
const yargs = configUtil.buildYargs()
const instrumenterArgs = processArgs.hideInstrumenteeArgs()
const config = configUtil.loadConfig(yargs.parse(instrumenterArgs))
configUtil.addCommandsAndHelp(yargs)
const argv = yargs.config(config).parse(instrumenterArgs)

if ([
  'check-coverage', 'report', 'instrument', 'merge'
].indexOf(argv._[0]) !== -1) {
  // look in lib/commands for logic.
} else if (argv._.length) {
  // if instrument is set to false,
  // enable a noop instrumenter.
  if (!argv.instrument) argv.instrumenter = './lib/instrumenters/noop'
  else argv.instrumenter = './lib/instrumenters/istanbul'

  var nyc = (new NYC(argv))
  if (argv.clean) {
    nyc.reset()
  } else {
    nyc.createTempDirectory()
  }
  if (argv.all) nyc.addAllFiles()

  var env = {
    // Support running nyc as a user without HOME (e.g. linux 'nobody'),
    // https://github.com/istanbuljs/nyc/issues/951
    SPAWN_WRAP_SHIM_ROOT: process.env.SPAWN_WRAP_SHIM_ROOT || process.env.XDG_CACHE_HOME || require('os').homedir(),
    NYC_CONFIG: JSON.stringify(argv),
    NYC_CWD: process.cwd(),
    NYC_ROOT_ID: nyc.rootId,
    NYC_INSTRUMENTER: argv.instrumenter
  }

  if (argv['babel-cache'] === false) {
    // babel's cache interferes with some configurations, so is
    // disabled by default. opt in by setting babel-cache=true.
    env.BABEL_DISABLE_CACHE = process.env.BABEL_DISABLE_CACHE = '1'
  }

  sw([wrapper], env)

  // Both running the test script invocation and the check-coverage run may
  // set process.exitCode. Keep track so that both children are run, but
  // a non-zero exit codes in either one leads to an overall non-zero exit code.
  process.exitCode = 0
  foreground(processArgs.hideInstrumenterArgs(
    // use the same argv descrption, but don't exit
    // for flags like --help.
    configUtil.buildYargs().parse(process.argv.slice(2))
  ), function (done) {
    var mainChildExitCode = process.exitCode

    if (argv.checkCoverage) {
      checkCoverage(argv)
      process.exitCode = process.exitCode || mainChildExitCode
      if (!argv.silent) report(argv)
      return done()
    } else {
      if (!argv.silent) report(argv)
      return done()
    }
  })
} else {
  // I don't have a clue what you're doing.
  yargs.showHelp()
}

function report (argv) {
  process.env.NYC_CWD = process.cwd()

  var nyc = new NYC(argv)
  nyc.report()
}

function checkCoverage (argv, cb) {
  process.env.NYC_CWD = process.cwd()

  ;(new NYC(argv)).checkCoverage({
    lines: argv.lines,
    functions: argv.functions,
    branches: argv.branches,
    statements: argv.statements
  }, argv['per-file'])
}
<|endoftext|>


<commit_before>/*
*   Copyright 2012 Comcast
*
*   Licensed under the Apache License, Version 2.0 (the "License");
*   you may not use this file except in compliance with the License.
*   You may obtain a copy of the License at
*
*       http://www.apache.org/licenses/LICENSE-2.0
*
*   Unless required by applicable law or agreed to in writing, software
*   distributed under the License is distributed on an "AS IS" BASIS,
*   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*   See the License for the specific language governing permissions and
*   limitations under the License.
*/

define('dropdown',['jquery', 'base'], function($, Base) {

    //helper method to turn a collection of event.which values into an array
    var parseWhich = function(which) {
        if (typeof which === 'string') {
            which = which.split(',');
            return which.map(function(string){ return parseInt(string, 10); });
        } else if (typeof which === 'number') {
            return [which];
        }

        return which;
    };

    var Dropdown = Base('dropdown', function() {
        var self = this,
            trigger,
            handles = self.getHandle(),
            expanders = self.getExpander(),

            onTriggers = this.options.triggers.on,
            offTriggers = self.options.triggers.off;

        //Private helper methods
        var getTriggerHandle;

        getTriggerHandle = function(triggerData, index){
            if (triggerData.selector) {
                return triggerData.selector === 'document' ? $(document) : $(triggerData.selector);
            } else {
                return typeof index === 'undefined' ? handles : handles.eq(index);
            }
        };

        this.handlers = {
            off: function(event){
                if ((typeof event.data.which !== 'undefined' && event.data.which.indexOf(event.which) === -1) || ($(event.target).is(self.getExpander(event.data.index)) || $(event.target).parents(self.options.dropdownExpanderSelector).length > 0) && !$(event.target).is($(this))) {
                    return true;
                }

                event.preventDefault();

                self.collapse(event.data.index, event.data.delay);
            },

            on: function(event){
                var index = event.data.index || parseInt($(this).attr('data-dropdown-index'), 10),
                    delay = event.data.delay,
                    handle = $(this);

                if (typeof event.data.which !== 'undefined' && event.data.which.indexOf(event.which) === -1) {
                    return true;
                }

                event.preventDefault();

                self.expand(index, delay);
            }
        };

        this.timers = {
            expand: [],
            collapse: [],
            throttle: []
        };

        for (trigger in onTriggers) {
            if (typeof onTriggers[trigger].which !== 'undefined') {
                onTriggers[trigger].which = parseWhich(onTriggers[trigger].which);
            }

            getTriggerHandle(onTriggers[trigger]).on(trigger, $.extend({delay: 0}, onTriggers[trigger]), self.handlers.on);
        }

        handles.on('dropdownExpand', function(event, index){
            var trigger, handle;

            for (trigger in offTriggers) {
                if (typeof offTriggers[trigger].which !== 'undefined') {
                    offTriggers[trigger].which = parseWhich(offTriggers[trigger].which);
                }

                handle = getTriggerHandle(offTriggers[trigger], index);

                handle.data('eventCount-' + trigger, handle.data('eventCount-' + trigger) + 1 || 1);

                handle.on(trigger, $.extend({delay: 0, index: index}, offTriggers[trigger]), self.handlers.off);
            }
        });

        handles.on('dropdownCollapse', function(event, index){
            var trigger, handle, eventCount;

            for (trigger in offTriggers) {
                handle = getTriggerHandle(offTriggers[trigger], index);

                eventCount = handle.data('eventCount-' + trigger) - 1;

                if (eventCount <= 0) {
                    handle.unbind(trigger, self.handlers.off);

                    handle.data('eventCount-' + trigger, 0);
                } else {
                    handle.data('eventCount-' + trigger, eventCount);
                }
            }
        });

        handles.each(function(index){
            var handle = $(this),
                expander = expanders.eq(index);

            handle.attr('data-dropdown-index', index);
            expander.attr('data-dropdown-index', index);
        });

        expanders.on('mouseover focus', function(){
            var index = parseInt($(this).attr('data-dropdown-index'), 10);

            if (self.timers.collapse[index]){
                self.timers.collapse[index] = clearTimeout(self.timers.collapse[index]);

                $(this).on('mouseleave blur', {index: index}, function(event){
                    self.collapse(event.data.index, 0);
                    $(this).unbind(event);
                });
            }
        });

    });

    Dropdown.setDefaultOptions({
        dropdownHandleSelector: '[data-role="dropdown-handle"]',
        dropdownExpanderSelector: '[data-role="dropdown-content"]',

        activeDropdownClass: 'is-dropdown-active',

        throttleDelay: 300,
        triggers: {
            on: {
                focus: {}
            },
            off: {
                blur: {}
            }
        }

    });

    $.extend(Dropdown.prototype, {
        getHandle: function(index){
            var handles = this.root.find(this.options.dropdownHandleSelector);

            return (typeof index !== 'undefined' && index >= 0) ? handles.eq(index) : handles;
        },

        getExpander: function(index){
            var expanders = this.root.find(this.options.dropdownExpanderSelector);

            return (typeof index !== 'undefined' && index >= 0) ? expanders.eq(index) : expanders;
        },

        setState: function(index, delay, active){
            if (typeof index === 'undefined' || isNaN(index)) {
                return;
            }

            var state = active ? 'expand' : 'collapse',
                counterState = active ? 'collapse' : 'expand';

            this.timers[counterState][index] = clearTimeout(this.timers[counterState][index]);

            if (this.timers.throttle[index] || this.timers[state][index]) {
                return;
            }

            this.timers[state][index] = setTimeout(function(i, _state, _active) {
                var expander = this.getExpander(i),
                    handle = this.getHandle(i),
                    self = this;

                this.timers[_state][i] = clearTimeout(this.timers[_state][i]);

                expander.toggleClass(this.options.activeDropdownClass, _active);
                this.getHandle(i).toggleClass(this.options.activeDropdownClass, _active);

                if (_active){
                    handle.trigger('dropdownExpand', i);
                    this.setFocus(expander);
                } else {
                    handle.trigger('dropdownCollapse', i);
                }

                if (this.options.throttleDelay > 0){
                    this.timers.throttle[i] = setTimeout(function(){
                        self.timers.throttle[i] = clearTimeout(self.timers.throttle[i]);
                    }, this.options.throttleDelay);
                }

            }.bind(this, index, state, active), delay);
        },

        expand: function(index, delay) {
            if (!this.getHandle(index).hasClass(this.options.activeDropdownClass)) {
                this.setState(index, delay, true);
            }
        },

        collapse: function(index, delay) {
            if (this.getHandle(index).hasClass(this.options.activeDropdownClass)) {
                this.setState(index, delay, false);
            }
        },

        setFocus: function(element){
            element.find('a,input,textarea,button,select,iframe,[tabindex][tabindex!=-1]')
                   .first()
                   .focus();
        }
    });

    return Dropdown;
});
<commit_msg>Updated Dropdown logic so that on events and off events are apporpriately bound and unbound<commit_after>/*
*   Copyright 2012 Comcast
*
*   Licensed under the Apache License, Version 2.0 (the "License");
*   you may not use this file except in compliance with the License.
*   You may obtain a copy of the License at
*
*       http://www.apache.org/licenses/LICENSE-2.0
*
*   Unless required by applicable law or agreed to in writing, software
*   distributed under the License is distributed on an "AS IS" BASIS,
*   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*   See the License for the specific language governing permissions and
*   limitations under the License.
*/

define('dropdown',['jquery', 'base'], function($, Base) {

    var parseWhich = function(which) {
        if (typeof which === 'string') {
            which = which.split(',');
            return which.map(function(string){ return parseInt(string, 10); });
        } else if (typeof which === 'number') {
            return [which];
        }

        return which;
     };

    var Dropdown = Base('dropdown', function() {
        var self = this,
            handles = self.getHandle(),
            expanders = self.getExpander();

        this.handlers = {
            off: function(event){
                if ((typeof event.data.not !== 'undefined' && ($(event.data.not).is($(this)) || $(event.target).parents(event.data.not).length > 0)) || (typeof event.data.which !== 'undefined' && event.data.which.indexOf(event.which) === -1) || ($(event.target).is(self.getExpander(event.data.index)) || $(event.target).parents(self.options.dropdownExpanderSelector).length > 0) && !$(event.target).is($(this))) {
                    return true;
                }

                event.preventDefault();

                self.collapse(event.data.index, event.data.delay);
            },

            on: function(event){
                var index = event.data.index || parseInt($(this).attr('data-dropdown-index'), 10),
                    delay = event.data.delay,
                    handle = $(this);

                if ((typeof event.data.not !== 'undefined' && ($(event.data.not).is($(this)) || $(event.target).parents(event.data.not).length > 0)) || typeof event.data.which !== 'undefined' && event.data.which.indexOf(event.which) === -1) {
                    return true;
                }

                event.preventDefault();

                self.expand(index, delay);
            }
        };

        this.timers = {
            expand: [],
            collapse: [],
            throttle: []
        };

        this.addHandlers('on');

        handles.on('dropdownExpand', function(event, index){
            self.removeHandlers('on', index);

            self.addHandlers('off', index);
        });

        handles.on('dropdownCollapse', function(event, index){
            self.removeHandlers('off', index);

            self.addHandlers('on', index);
        });

        handles.each(function(index){
            var handle = $(this),
                expander = expanders.eq(index);

            handle.attr('data-dropdown-index', index);
            expander.attr('data-dropdown-index', index);
        });

        expanders.on('mouseover focus', function(){
            var index = parseInt($(this).attr('data-dropdown-index'), 10);

            if (self.timers.collapse[index]){
                self.timers.collapse[index] = clearTimeout(self.timers.collapse[index]);

                $(this).on('mouseleave blur', {index: index}, function(event){
                    self.collapse(event.data.index, 0);
                    $(this).unbind(event);
                });
            }
        });

    });

    Dropdown.setDefaultOptions({
        dropdownHandleSelector: '[data-role="dropdown-handle"]',
        dropdownExpanderSelector: '[data-role="dropdown-content"]',

        activeDropdownClass: 'is-dropdown-active',

        throttleDelay: 300,
        triggers: {
            on: {
                focus: {
                    delay: 0
                }
            },
            off: {
                blur: {
                    delay: 0
                }
            }
        }

    });

    Dropdown.prototype.getTriggerHandle = function(triggerData, index){
        var handles = this.getHandle(index);

        if (triggerData.selector) {
            return triggerData.selector === 'document' ? $(document) : $(triggerData.selector);
        } else {
            return handles;
        }
    };

    Dropdown.prototype.addHandlers = function(state, index){
        var trigger, handle, triggerData, countName;

        triggerData = this.options.triggers[state];

        for (trigger in triggerData) {
            if (typeof triggerData[trigger].which !== 'undefined') {
                triggerData[trigger].which = parseWhich(triggerData[trigger].which);
            }

            countName = [trigger,state,'count'].join('-');

            handle = this.getTriggerHandle(triggerData[trigger], index);

            handle.data(countName, handle.data(countName) + 1 || 1);

            handle.on(trigger, $.extend({delay: 0, index: index}, triggerData[trigger]), this.handlers[state]);
        }
    };

    Dropdown.prototype.removeHandlers = function(state, index){
        var trigger, handle, triggerData, countName, eventCount;

        triggerData = this.options.triggers[state];

        for (trigger in triggerData) {
            handle = this.getTriggerHandle(triggerData[trigger], index);

            countName = [trigger,state,'count'].join('-');

            eventCount = handle.data(countName) - 1;

            if (eventCount <= 0) {
                handle.unbind(trigger, this.handlers[state]);

                handle.data(countName, 0);
            } else {
                handle.data(countName, eventCount);
            }
        }
    };

    Dropdown.prototype.getHandle = function(index){
        var handles = this.root.find(this.options.dropdownHandleSelector);

        return (typeof index !== 'undefined' && index >= 0) ? handles.eq(index) : handles;
    };

    Dropdown.prototype.getExpander = function(index){
        var expanders = this.root.find(this.options.dropdownExpanderSelector);

        return (typeof index !== 'undefined' && index >= 0) ? expanders.eq(index) : expanders;
    };

    Dropdown.prototype.setState = function(index, delay, active){
        if (typeof index === 'undefined' || isNaN(index)) {
            return;
        }

        var state = active ? 'expand' : 'collapse',
            counterState = active ? 'collapse' : 'expand';

        this.timers[counterState][index] = clearTimeout(this.timers[counterState][index]);

        if (this.timers.throttle[index] || this.timers[state][index]) {
            return;
        }

        this.timers[state][index] = setTimeout(function(i, _state, _active) {
            var expander = this.getExpander(i),
                handle = this.getHandle(i),
                self = this;

            this.timers[_state][i] = clearTimeout(this.timers[_state][i]);

            expander.toggleClass(this.options.activeDropdownClass, _active);
            this.getHandle(i).toggleClass(this.options.activeDropdownClass, _active);

            if (_active){
                handle.trigger('dropdownExpand', i);
                this.setFocus(expander);
            } else {
                handle.trigger('dropdownCollapse', i);
            }

            if (this.options.throttleDelay > 0){
                this.timers.throttle[i] = setTimeout(function(){
                    self.timers.throttle[i] = clearTimeout(self.timers.throttle[i]);
                }, this.options.throttleDelay);
            }

        }.bind(this, index, state, active), delay);
    };

    Dropdown.prototype.expand = function(index, delay) {
        if (!this.getHandle(index).hasClass(this.options.activeDropdownClass)) {
            this.setState(index, delay, true);
        }
    };

    Dropdown.prototype.collapse = function(index, delay) {
        if (this.getHandle(index).hasClass(this.options.activeDropdownClass)) {
            this.setState(index, delay, false);
        }
    };

    Dropdown.prototype.setFocus = function(element){
        element.find('a,input,textarea,button,select,iframe,[tabindex][tabindex!=-1]')
               .first()
               .focus();
    };

    return Dropdown;
});<|endoftext|>


<commit_before>import React from 'react';
import classnames from 'classnames';
import _ from 'underscore';

import m from '../services/materialService.js';
import v from '../services/vendorService.js';
import sign from '../services/sign.js';
import h from '../helpers.js';

import Table from './Table.js';
import Column from './Column.js';
import Cell from './Cell.js';
import AddMaterialForm from './Form.AddMaterial.js';
import SelectCell from './Cell.Select.js';

class Materials extends React.Component {
  constructor() {
    super();

    this.state = {
      filteredMaterials: [],
      isFormOpen: false,
      materials: [],
      removeMode: false, // If true, display removal column in table
      types: [],
      vendors: []
    };
  }

  //-----------------------------------
  // LIFECYCLE METHODS
  //-----------------------------------
  componentDidMount() {
    this._getMaterials().then(materials => {
      this._orderedContractorNames = materials[0].contractors.map(contractor => contractor.name);

      this.setState({
        materials,
        filteredMaterials: materials
      });
    });

    m.getTypes().then(types => {
      this.setState({ types });
    }).catch(() => {
      sign.setError('Failed to retrieve material types. Try refreshing.');
    });

    v.getVendors().then(vendors => {
      this.setState({ vendors });
    }).catch(() => {
      sign.setError('Failed to retrieve vendors. Try refreshing.');
    });
  }

  //-----------------------------------
  // RENDERING
  //-----------------------------------
  render() {
    let state = this.state;

    let removeClasses = {
      'remove-button': true,
      active: state.removeMode
    };

    return (

            All
            {state.types.map(type => {
              if (type.name === 'none') {
                return null;
              }

              return {type.name};
            })}
            Low Stock
            Out of Stock

            <button className="add-button" onClick={this._handleAddClick.bind(this)}>+</button>
            <button className={classnames(removeClasses)} onClick={this._handleRemoveClick.bind(this)}>--</button>

            <Column header="Item #" cell={material => (
                <Cell modifyField={this._modifyField.bind(this, material.id, 'item')}>{material.item}</Cell>
              )}
            />
            <Column classes="extra-wide" header="Description" cell={material => (
                <Cell modifyField={this._modifyField.bind(this, material.id, 'description')}>{material.description}</Cell>
              )}
            />
            <Column header="Type" cell={material => (
                <SelectCell modifyField={this._modifyField.bind(this, material.id, 'type')}
                  options={state.types.map(type => type.name)}
                  defaultValue={h.findTypeName(state.types, material.typeId)}
                />
              )}
            />
            <Column header="Vendor" cell={material => (
                <SelectCell modifyField={this._modifyField.bind(this, material.id, 'vendor')}
                  options={state.vendors.map(vendor => vendor.company)}
                  defaultValue={h.findVendorCompany(state.vendors, material.vendorId)}
                />
              )}
            />
            <Column header="Cost / Unit" cell={material => {
              let type = _.findWhere(state.types, { id: material.typeId });

              if (!type) {
                return <Cell />;
              }

              return (
                <Cell modifyField={this._modifyField.bind(this, material.id, 'costPerUnit')} pricePerUnit>
                  {h.displayPricePerUnit(material.costPerUnit, type.unit)}
                </Cell>
              );
            }}
            />
            <Column header="Qty on Order" cell={material => (
                <Cell modifyField={this._modifyField.bind(this, material.id, 'qtyOnOrder')} integer>{material.qtyOnOrder}</Cell>
              )}
            />
            {this._renderContractorQtys()}
            <Column header="Qty in Stock" cell={material => (
                <Cell modifyField={this._modifyField.bind(this, material.id, 'qtyInStock')} integer>{material.qtyInStock}</Cell>
              )}
            />
            {this._renderRemoveColumn()}

        {this._renderForm()}

    );
  }

  _renderContractorQtys() {
    if (this._orderedContractorNames) {
      return this._orderedContractorNames.map(name => {
        return (
          <Column key={name} header={`Qty with ${name}`} cell={material => {
            let contractor = material.contractors.find(c => c.name === name);

            return (
              <Cell integer>{contractor.ContractorMaterial.qty}</Cell>
            );
          }}
          />
        );
      });
    }
  }

  _renderRemoveColumn() {
    if (this.state.removeMode) {
      return (
        <Column header="Remove" cell={material => (
            <Cell className="remove">
X
</Cell>
          )}
        />
      );
    }
  }

  _renderForm() {
    if (this.state.isFormOpen) {
      return (
        <AddMaterialForm
          cancel={this._handleAddClick.bind(this)}
          submit={this._handleFormSubmit.bind(this)}
        />
      );
    }
  }

  //-----------------------------------
  // PRIVATE METHODS
  //-----------------------------------
  _clearFilter() {
    this.setState({ filteredMaterials: this.state.materials });
  }

  _filterByLowStock() {
    let filteredMaterials = this.state.materials.filter(material => {
      let type = _.findWhere(this.state.types, { id: material.typeId });

      return material.qtyInStock <= type.lowStock;
    });

    this.setState({ filteredMaterials });
  }

  _filterByOutOfStock() {
    let filteredMaterials = this.state.materials.filter(material => material.qtyInStock <= 0);

    this.setState({ filteredMaterials });
  }

  _filterByType(typeId) {
    let filteredMaterials = this.state.materials.filter(material => material.typeId === typeId);

    this.setState({ filteredMaterials });
  }

  _handleAddClick(event) {
    if (event) {
      event.preventDefault();
    }

    this.setState({ isFormOpen: !this.state.isFormOpen });
  }

  _handleFormSubmit(item, description) {
    m.addMaterial({
      item,
      description
    }).then(() => {
      this._getMaterials().then(materials => {
        // Revert to "All" filter when new material is added.
        this.setState({
          materials,
          filteredMaterials: materials
        });

        sign.setMessage('Showing all materials');
      });
    }).catch(() => {
      sign.setError('Failed to add material. Try refreshing.');
    });
  }

  _handleRemoveClick() {
    this.setState({ removeMode: !this.state.removeMode });
  }

  _modifyField(materialId, field, value) {
    let state = this.state;
    let materials = state.materials;

    for (let i = 0; i < materials.length; i++) {
      if (materials[i].id === materialId) {
        if (field === 'type') {
          materials[i].typeId = h.findTypeId(state.types, value);
        } else if (field === 'vendor') {
          materials[i].vendorId = h.findVendorId(state.vendors, value);
        } else {
          materials[i][field] = value;
        }

        this.setState({ materials });
        break;
      }
    }

    m.modifyMaterial(materialId, field, value)
      .catch(() => {
        sign.setError('Failed to modify material.');
        this.setState({ materials: [] });
      });
  }

  _removeMaterial(material) {
    let confirmed = confirm(`Are you sure you want to remove ${material.description}?`);

    if (confirmed) {
      m.removeMaterial(material.id).then(() => {
        // Remove material from filtered set.
        this._getMaterials().then(materials => {
          let filteredMaterials = this.state.filteredMaterials.slice(0);

          for (let i = 0; i < filteredMaterials.length; i++) {
            if (filteredMaterials[i].id === material.id) {
              filteredMaterials.splice(i, 1);
              break;
            }
          }

          this.setState({
            materials,
            filteredMaterials
          });
        });
      }).catch(() => {
        sign.setError('Failed to remove material.');
      });
    }
  }

  _getMaterials() {
    return m.getAllMaterials().catch(error => {
      console.log('[Component] Error retrieving materials: ', error);
      sign.setError('Failed to retrieve materials. Try refreshing.');
      this.setState({ materials: [] });
    });
  }
}

export default Materials;
<commit_msg>Implement transferring of materials to contractors<commit_after>import React from 'react';
import classnames from 'classnames';
import _ from 'underscore';

import m from '../services/materialService.js';
import v from '../services/vendorService.js';
import c from '../services/contractorService.js';
import sign from '../services/sign.js';
import h from '../helpers.js';

import Table from './Table.js';
import Column from './Column.js';
import Cell from './Cell.js';
import SelectCell from './Cell.Select.js';
import AddMaterialForm from './Form.AddMaterial.js';
import TransferMaterialForm from './Form.TransferMaterial.js';

class Materials extends React.Component {
  constructor() {
    super();

    this.state = {
      filteredMaterials: [],
      isAddMaterialFormOpen: false,
      isTransferMaterialFormOpen: false,
      materials: [],
      removeMode: false, // If true, display removal column in table
      transferContractor: null,
      transferMaterial: null,
      types: [],
      vendors: [],
    };
  }

  //-----------------------------------
  // LIFECYCLE METHODS
  //-----------------------------------
  componentDidMount() {
    this._getMaterials().then(materials => {
      this._orderedContractorNames = materials[0].contractors.map(contractor => contractor.name);

      this.setState({
        materials,
        filteredMaterials: materials,
      });
    });

    m.getTypes().then(types => {
      this.setState({ types });
    }).catch(() => {
      sign.setError('Failed to retrieve material types. Try refreshing.');
    });

    v.getVendors().then(vendors => {
      this.setState({ vendors });
    }).catch(() => {
      sign.setError('Failed to retrieve vendors. Try refreshing.');
    });
  }

  //-----------------------------------
  // RENDERING
  //-----------------------------------
  render() {
    let state = this.state;

    let removeClasses = {
      'remove-button': true,
      active: state.removeMode,
    };

    return (

            All
            {state.types.map(type => {
              if (type.name === 'none') {
                return null;
              }

              return {type.name};
            })}
            Low Stock
            Out of Stock

            <button className="add-button" onClick={this._handleAddMaterialClick.bind(this)}>+</button>
            <button className={classnames(removeClasses)} onClick={this._handleRemoveClick.bind(this)}>--</button>

            <Column header="Item #" cell={material => (
                <Cell modifyField={this._modifyField.bind(this, material.id, 'item')}>{material.item}</Cell>
              )}
            />
            <Column classes="extra-wide" header="Description" cell={material => (
                <Cell modifyField={this._modifyField.bind(this, material.id, 'description')}>{material.description}</Cell>
              )}
            />
            <Column header="Type" cell={material => (
                <SelectCell modifyField={this._modifyField.bind(this, material.id, 'type')}
                  options={state.types.map(type => type.name)}
                  defaultValue={h.findTypeName(state.types, material.typeId)}
                />
              )}
            />
            <Column header="Vendor" cell={material => (
                <SelectCell modifyField={this._modifyField.bind(this, material.id, 'vendor')}
                  options={state.vendors.map(vendor => vendor.company)}
                  defaultValue={h.findVendorCompany(state.vendors, material.vendorId)}
                />
              )}
            />
            <Column header="Cost / Unit" cell={material => {
              let type = _.findWhere(state.types, { id: material.typeId });

              if (!type) {
                return <Cell />;
              }

              return (
                <Cell modifyField={this._modifyField.bind(this, material.id, 'costPerUnit')} pricePerUnit>
                  {h.displayPricePerUnit(material.costPerUnit, type.unit)}
                </Cell>
              );
            }}
            />
            <Column header="Qty on Order" cell={material => (
                <Cell modifyField={this._modifyField.bind(this, material.id, 'qtyOnOrder')} integer>{material.qtyOnOrder}</Cell>
              )}
            />
            {this._renderContractorQtys()}
            <Column header="Qty in Stock" cell={material => (
                <Cell modifyField={this._modifyField.bind(this, material.id, 'qtyInStock')} integer>{material.qtyInStock}</Cell>
              )}
            />
            {this._renderRemoveColumn()}

        {this._renderAddMaterialForm()}
        {this._renderTransferMaterialForm()}

    );
  }

  _renderContractorQtys() {
    if (this._orderedContractorNames) {
      return this._orderedContractorNames.map(name => {
        return (
          <Column key={name} header={`Qty with ${name}`} cell={material => {
            let contractor = material.contractors.find(con => con.name === name);

            return (
              <Cell className="editable"
                integer
                onClick={this._handleTransferMaterialClick.bind(this, material, contractor)}
              >
                {contractor.ContractorMaterial.qty}
              </Cell>
            );
          }}
          />
        );
      });
    }
  }

  _renderRemoveColumn() {
    if (this.state.removeMode) {
      return (
        <Column header="Remove" cell={material => (
            <Cell className="remove">
X
</Cell>
          )}
        />
      );
    }
  }

  _renderAddMaterialForm() {
    if (this.state.isAddMaterialFormOpen) {
      return (
        <AddMaterialForm
          cancel={this._handleAddMaterialClick.bind(this)}
          submit={this._submitAddForm.bind(this)}
        />
      );
    }
  }

  _renderTransferMaterialForm() {
    if (this.state.isTransferMaterialFormOpen) {
      return (
        <TransferMaterialForm
          cancel={this._closeTransferMaterialForm.bind(this)}
          contractor={this.state.transferContractor}
          material={this.state.transferMaterial}
          submit={this._submitTransferForm.bind(this)}
        />
      );
    }
  }

  //-----------------------------------
  // PRIVATE METHODS
  //-----------------------------------
  _clearFilter() {
    this.setState({ filteredMaterials: this.state.materials });
  }

  _closeTransferMaterialForm(event) {
    if (event) {
      event.preventDefault();
    }

    this.setState({ isTransferMaterialFormOpen: false });
  }

  _filterByLowStock() {
    let filteredMaterials = this.state.materials.filter(material => {
      let type = _.findWhere(this.state.types, { id: material.typeId });

      return material.qtyInStock <= type.lowStock;
    });

    this.setState({ filteredMaterials });
  }

  _filterByOutOfStock() {
    let filteredMaterials = this.state.materials.filter(material => material.qtyInStock <= 0);

    this.setState({ filteredMaterials });
  }

  _filterByType(typeId) {
    let filteredMaterials = this.state.materials.filter(material => material.typeId === typeId);

    this.setState({ filteredMaterials });
  }

  _getMaterials() {
    return m.getAllMaterials().catch(error => {
      console.log('[Component] Error retrieving materials: ', error);
      sign.setError('Failed to retrieve materials. Try refreshing.');
      this.setState({ materials: [] });
    });
  }

  _handleAddMaterialClick(event) {
    if (event) {
      event.preventDefault();
    }

    this.setState({ isAddMaterialFormOpen: !this.state.isAddMaterialFormOpen });
  }

  _handleTransferMaterialClick(material, contractor) {
    this.setState({
      isTransferMaterialFormOpen: true,
      transferContractor: contractor,
      transferMaterial: material,
    });
  }

  _handleRemoveClick() {
    this.setState({ removeMode: !this.state.removeMode });
  }

  _modifyField(materialId, field, value) {
    let state = this.state;
    let materials = state.materials;

    for (let i = 0; i < materials.length; i++) {
      if (materials[i].id === materialId) {
        if (field === 'type') {
          materials[i].typeId = h.findTypeId(state.types, value);
        } else if (field === 'vendor') {
          materials[i].vendorId = h.findVendorId(state.vendors, value);
        } else {
          materials[i][field] = value;
        }

        this.setState({ materials });
        break;
      }
    }

    m.modifyMaterial(materialId, field, value)
      .catch(() => {
        sign.setError('Failed to modify material.');
        this.setState({ materials: [] });
      });
  }

  _removeMaterial(material) {
    let confirmed = confirm(`Are you sure you want to remove ${material.description}?`);

    if (confirmed) {
      m.removeMaterial(material.id).then(() => {
        // Remove material from filtered set.
        this._getMaterials().then(materials => {
          let filteredMaterials = this.state.filteredMaterials.slice(0);

          for (let i = 0; i < filteredMaterials.length; i++) {
            if (filteredMaterials[i].id === material.id) {
              filteredMaterials.splice(i, 1);
              break;
            }
          }

          this.setState({
            materials,
            filteredMaterials,
          });
        });
      }).catch(() => {
        sign.setError('Failed to remove material.');
      });
    }
  }

  _submitAddForm(item, description) {
    m.addMaterial({
      item,
      description,
    }).then(() => {
      this._getMaterials().then(materials => {
        // Revert to "All" filter when new material is added.
        this.setState({
          materials,
          filteredMaterials: materials,
        });

        sign.setMessage('Showing all materials');
      });
    }).catch(() => {
      sign.setError('Failed to add material. Try refreshing.');
    });
  }

  _submitTransferForm(qty) {
    let { transferContractor, transferMaterial } = this.state;

    let materials = this.state.materials.slice(0);
    let material = this.state.materials.find(mat => mat.id === transferMaterial.id);
    let contractor = material.contractors.find(con => con.id === transferContractor.id);

    material.qtyInStock -= qty;
    contractor.ContractorMaterial.qty += qty;

    this.setState({ materials });

    c.transferMaterial(transferContractor.id, transferMaterial.id, qty).then(() => {
      sign.setMessage(`Transferred materials to ${transferContractor.name}`);
    }).catch(() => {
      sign.setError(`Failed to transfer materials to ${transferContractor.name}. Try refreshing.`);
    });
  }
}

export default Materials;
<|endoftext|>


<commit_before>var Promise = require('bluebird');
var tmp = require('tmp');
var exec = require('child-process').exec;

var serviceLocator = require('../../service-locator');

function RtpbroadcastRecordingHandler() {
}

/**
 * @returns {String}
 */
RtpbroadcastRecordingHandler.prototype.getPlugin = function() {
  return 'janus.plugin.cm.rtpbroadcast';
};

/**
 * @returns {String}
 */
RtpbroadcastRecordingHandler.prototype.getEvent = function() {
  return 'recording-finished';
};

/**
 * @param {Object} jobData
 * @returns {Promise}
 */
RtpbroadcastRecordingHandler.prototype.handle = function(jobData) {
  var streamChannelId = jobData.streamChannelId;
  var audioFile = jobData.audio;
  var videoFile = jobData.video;

  var mpegFile = tmp.tmpNameSync({postfix: '.mp4'});

  var gstreamerResult = new Promise(function(resolve, reject) {
    exec('gst-launch-1.0', [
      'filesrc',
      'locationAudion=' + audioFile,
      '! locationVideo=' + videoFile,
      '! decodebin',
      '! videoconvert',
      '! pngenc snapshot=true',
      '! filesink location=' + mpegFile
    ], function(error) {
      if (null === error) {
        resolve();
      }
      else {
        reject(error);
      }
    })
  });
  //TODO fix gstreamer pipeline

  return gstreamerResult
    .then(function() {
      serviceLocator.get('cm-application').importMediaStreamArchive(streamChannelId, mpegFile)
    })
    .catch(function(error) {
      serviceLocator.get('logger').error('exec error: ' + error);
    });
};

module.exports = RtpbroadcastRecordingHandler;
<commit_msg>Promisify tmp<commit_after>var Promise = require('bluebird');
var tmpName = Promise.promisify(require('tmp').tmpName);
var exec = require('child-process').exec;

var serviceLocator = require('../../service-locator');

function RtpbroadcastRecordingHandler() {
}

/**
 * @returns {String}
 */
RtpbroadcastRecordingHandler.prototype.getPlugin = function() {
  return 'janus.plugin.cm.rtpbroadcast';
};

/**
 * @returns {String}
 */
RtpbroadcastRecordingHandler.prototype.getEvent = function() {
  return 'recording-finished';
};

/**
 * @param {Object} jobData
 * @returns {Promise}
 */
RtpbroadcastRecordingHandler.prototype.handle = function(jobData) {
  var streamChannelId = jobData.streamChannelId;
  var audioFile = jobData.audio;
  var videoFile = jobData.video;

  var mpegFilePromise = tmpName({postfix: '.mp4'});

  var executeGstreamer = function(audioFile, videoFile, mpegFile) {
    return new Promise(function(resolve, reject) {
      exec('gst-launch-1.0', [
        'filesrc',
        'locationAudion=' + audioFile,
        '! locationVideo=' + videoFile,
        '! decodebin',
        '! videoconvert',
        '! pngenc snapshot=true',
        '! filesink location=' + mpegFile
      ], function(error) {
        if (null === error) {
          resolve(mpegFile);
        }
        else {
          reject(error);
        }
      })
    });
  };
  //TODO fix gstreamer pipeline

  return mpegFilePromise
    .then(function(fileName) {
      return executeGstreamer(audioFile, videoFile, fileName);
    })
    .then(function(fileName) {
      serviceLocator.get('cm-application').importMediaStreamArchive(streamChannelId, fileName);
    });
};

module.exports = RtpbroadcastRecordingHandler;
<|endoftext|>


<commit_before>import ns from 'imajs/client/core/namespace.js';

ns.namespace('Core.Interface');

/**
 * The {@codelink HttpAgent} defines unifying API for simple sending of HTTP
 * requests at both client-side and server-side.
 *
 * @interface HttpAgent
 * @namespace Core.Interface
 * @module Core
 * @submodule Core.Interface
 */
export default class HttpAgent {
	/**
	 * Sends an HTTP GET request to the specified URL, sending the provided data
	 * as query parameters.
	 *
	 * @method get
	 * @param {string} url The URL to which the request should be made.
	 * @param {Object<string, (boolean|number|string|Date)>} data The data to
	 *        send to the server as query parameters.
	 * @param {{timeout: number=, ttl: number=, repeatRequest: number=,
	 *        headers: Object<string, string>=, cache: boolean=}=} options
	 *        Optional request options. The {@code timeout} specifies the request
	 *        timeout in milliseconds, the {@code ttl} specified how long the
	 *        request may be cached in milliseconds, the
	 *        {@code repeatRequest} specifies the maximum number of tries to
	 *        repeat the request if the request fails, The {@code headers} set
	 *        request headers. The {@code cache} can be used to bypass the cache
	 *        of pending and finished HTTP requests.
	 * @return {Promise<*>} A promise that resolves to the response body parsed
	 *         as JSON.
	 */
	get(url, data, options = {}) {}

	/**
	 * Sends an HTTP POST request to the specified URL, sending the provided data
	 * as a request body.
	 *
	 * @method post
	 * @param {string} url The URL to which the request should be made.
	 * @param {Object<string, (boolean|number|string|Date)>} data The data to
	 *        send to the server as request body.
	 * @param {{timeout: number=, ttl: number=, repeatRequest: number=,
	 *        headers: Object<string, string>=, cache: boolean=}=} options
	 *        Optional request options. The {@code timeout} specifies the request
	 *        timeout in milliseconds, the {@code ttl} specified how long the
	 *        request may be cached in milliseconds, the
	 *        {@code repeatRequest} specifies the maximum number of tries to
	 *        repeat the request if the request fails, The {@code headers} set
	 *        request headers. The {@code cache} can be used to bypass the cache
	 *        of pending and finished HTTP requests.
	 * @return {Promise<*>} A promise that resolves to the response body parsed
	 *         as JSON.
	 */
	post(url, data, options = {}) {}

	/**
	 * Sends an HTTP PUT request to the specified URL, sending the provided data
	 * as a request body.
	 *
	 * @method put
	 * @param {string} url The URL to which the request should be made.
	 * @param {Object<string, (boolean|number|string|Date)>} data The data to
	 *        send to the server as request body.
	 * @param {{timeout: number=, ttl: number=, repeatRequest: number=,
	 *        headers: Object<string, string>=, cache: boolean=}=} options
	 *        Optional request options. The {@code timeout} specifies the request
	 *        timeout in milliseconds, the {@code ttl} specified how long the
	 *        request may be cached in milliseconds, the
	 *        {@code repeatRequest} specifies the maximum number of tries to
	 *        repeat the request if the request fails, The {@code headers} set
	 *        request headers. The {@code cache} can be used to bypass the cache
	 *        of pending and finished HTTP requests.
	 * @return {Promise<*>} A promise that resolves to the response body parsed
	 *         as JSON.
	 */
	put(url, data, options = {}) {}

	/**
	 * Sends an HTTP PATCH request to the specified URL, sending the provided
	 * data as a request body.
	 *
	 * @method patch
	 * @param {string} url The URL to which the request should be made.
	 * @param {Object<string, (boolean|number|string|Date)>} data The data to
	 *        send to the server as request body.
	 * @param {{timeout: number=, ttl: number=, repeatRequest: number=,
	 *        headers: Object<string, string>=, cache: boolean=}=} options
	 *        Optional request options. The {@code timeout} specifies the request
	 *        timeout in milliseconds, the {@code ttl} specified how long the
	 *        request may be cached in milliseconds, the
	 *        {@code repeatRequest} specifies the maximum number of tries to
	 *        repeat the request if the request fails, The {@code headers} set
	 *        request headers. The {@code cache} can be used to bypass the cache
	 *        of pending and finished HTTP requests.
	 * @return {Promise<*>} A promise that resolves to the response body parsed
	 *         as JSON.
	 */
	patch(url, data, options = {}) {}

	/**
	 * Sends an HTTP DELETE request to the specified URL, sending the provided
	 * data as a request body.
	 *
	 * @method delete
	 * @param {string} url The URL to which the request should be made.
	 * @param {Object<string, (boolean|number|string|Date)>} data The data to
	 *        send to the server as request body.
	 * @param {{timeout: number=, ttl: number=, repeatRequest: number=,
	 *        headers: Object<string, string>=, cache: boolean=}=} options
	 *        Optional request options. The {@code timeout} specifies the request
	 *        timeout in milliseconds, the {@code ttl} specified how long the
	 *        request may be cached in milliseconds, the
	 *        {@code repeatRequest} specifies the maximum number of tries to
	 *        repeat the request if the request fails, The {@code headers} set
	 *        request headers. The {@code cache} can be used to bypass the cache
	 *        of pending and finished HTTP requests.
	 * @return {Promise<*>} A promise that resolves to the response body parsed
	 *         as JSON.
	 */
	delete(url, data, options = {}) {}

	/**
	 * Generates a cache key to use for identifying a request to the specified
	 * URL and submitted data.
	 *
	 * @method getCacheKey
	 * @param {string} method The HTTP method used by the request.
	 * @param {string} url The URL to which the request is sent.
	 * @param {Object<string, string>} data The data associated with the request.
	 *        These can be either the query parameters of request body
	 *        parameters.
	 * @return {string} Key to use for identifying a request to the specifed URL
	 *         with the specified request data in the cache.
	 */
	getCacheKey(method, url, data) {}

	/**
	 * Set constant header to all request.
	 *
	 * @method setDefaultHeader
	 * @chainable
	 * @param {string} header The name of the header.
	 * @param {string} value The header value. To provide multiple values,
	 *        separate them with commas
	 *        (see http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2).
	 * @return {Core.Interface.HttpAgent} This instance.
	 */
	setDefaultHeader(header, value) {}

	/**
	 * Clears all defaults headers sent with all requests.
	 *
	 * @method clearDefaultHeaders
	 * @chainable
	 * @return {Core.Interface.HttpAgent} This instance.
	 */
	clearDefaultHeaders() {}
}

ns.Core.Interface.HttpAgent = HttpAgent;
<commit_msg>#! update doc<commit_after>import ns from 'imajs/client/core/namespace.js';

ns.namespace('Core.Interface');

/**
 * The {@codelink HttpAgent} defines unifying API for simple sending of HTTP
 * requests at both client-side and server-side.
 *
 * @interface HttpAgent
 * @namespace Core.Interface
 * @module Core
 * @submodule Core.Interface
 */
export default class HttpAgent {
	/**
	 * Sends an HTTP GET request to the specified URL, sending the provided data
	 * as query parameters.
	 *
	 * @method get
	 * @param {string} url The URL to which the request should be made.
	 * @param {Object<string, (boolean|number|string|Date)>} data The data to
	 *        send to the server as query parameters.
	 * @param {{timeout: number=, ttl: number=, repeatRequest: number=,
	 *        headers: Object<string, string>=, cache: boolean=}=} options
	 *        Optional request options. The {@code timeout} specifies the request
	 *        timeout in milliseconds, the {@code ttl} specified how long the
	 *        request may be cached in milliseconds, the
	 *        {@code repeatRequest} specifies the maximum number of tries to
	 *        repeat the request if the request fails, The {@code headers} set
	 *        request headers. The {@code cache} can be used to bypass the cache
	 *        of pending and finished HTTP requests.
	 * @return {Promise<*>} A promise that resolves to the response body parsed
	 *         as JSON.
	 */
	get(url, data, options = {}) {}

	/**
	 * Sends an HTTP POST request to the specified URL, sending the provided data
	 * as a request body.
	 *
	 * @method post
	 * @param {string} url The URL to which the request should be made.
	 * @param {Object<string, (boolean|number|string|Date)>} data The data to
	 *        send to the server as request body.
	 * @param {{timeout: number=, ttl: number=, repeatRequest: number=,
	 *        headers: Object<string, string>=}=} options
	 *        Optional request options. The {@code timeout} specifies the request
	 *        timeout in milliseconds, the {@code ttl} specified how long the
	 *        request may be cached in milliseconds, the
	 *        {@code repeatRequest} specifies the maximum number of tries to
	 *        repeat the request if the request fails, The {@code headers} set
	 *        request headers. The {@code cache} can be used to bypass the cache
	 *        of pending and finished HTTP requests.
	 * @return {Promise<*>} A promise that resolves to the response body parsed
	 *         as JSON.
	 */
	post(url, data, options = {}) {}

	/**
	 * Sends an HTTP PUT request to the specified URL, sending the provided data
	 * as a request body.
	 *
	 * @method put
	 * @param {string} url The URL to which the request should be made.
	 * @param {Object<string, (boolean|number|string|Date)>} data The data to
	 *        send to the server as request body.
	 * @param {{timeout: number=, ttl: number=, repeatRequest: number=,
	 *        headers: Object<string, string>=}=} options
	 *        Optional request options. The {@code timeout} specifies the request
	 *        timeout in milliseconds, the {@code ttl} specified how long the
	 *        request may be cached in milliseconds, the
	 *        {@code repeatRequest} specifies the maximum number of tries to
	 *        repeat the request if the request fails, The {@code headers} set
	 *        request headers. The {@code cache} can be used to bypass the cache
	 *        of pending and finished HTTP requests.
	 * @return {Promise<*>} A promise that resolves to the response body parsed
	 *         as JSON.
	 */
	put(url, data, options = {}) {}

	/**
	 * Sends an HTTP PATCH request to the specified URL, sending the provided
	 * data as a request body.
	 *
	 * @method patch
	 * @param {string} url The URL to which the request should be made.
	 * @param {Object<string, (boolean|number|string|Date)>} data The data to
	 *        send to the server as request body.
	 * @param {{timeout: number=, ttl: number=, repeatRequest: number=,
	 *        headers: Object<string, string>=}=} options
	 *        Optional request options. The {@code timeout} specifies the request
	 *        timeout in milliseconds, the {@code ttl} specified how long the
	 *        request may be cached in milliseconds, the
	 *        {@code repeatRequest} specifies the maximum number of tries to
	 *        repeat the request if the request fails, The {@code headers} set
	 *        request headers. The {@code cache} can be used to bypass the cache
	 *        of pending and finished HTTP requests.
	 * @return {Promise<*>} A promise that resolves to the response body parsed
	 *         as JSON.
	 */
	patch(url, data, options = {}) {}

	/**
	 * Sends an HTTP DELETE request to the specified URL, sending the provided
	 * data as a request body.
	 *
	 * @method delete
	 * @param {string} url The URL to which the request should be made.
	 * @param {Object<string, (boolean|number|string|Date)>} data The data to
	 *        send to the server as request body.
	 * @param {{timeout: number=, ttl: number=, repeatRequest: number=,
	 *        headers: Object<string, string>=}=} options
	 *        Optional request options. The {@code timeout} specifies the request
	 *        timeout in milliseconds, the {@code ttl} specified how long the
	 *        request may be cached in milliseconds, the
	 *        {@code repeatRequest} specifies the maximum number of tries to
	 *        repeat the request if the request fails, The {@code headers} set
	 *        request headers. The {@code cache} can be used to bypass the cache
	 *        of pending and finished HTTP requests.
	 * @return {Promise<*>} A promise that resolves to the response body parsed
	 *         as JSON.
	 */
	delete(url, data, options = {}) {}

	/**
	 * Generates a cache key to use for identifying a request to the specified
	 * URL and submitted data.
	 *
	 * @method getCacheKey
	 * @param {string} method The HTTP method used by the request.
	 * @param {string} url The URL to which the request is sent.
	 * @param {Object<string, string>} data The data associated with the request.
	 *        These can be either the query parameters of request body
	 *        parameters.
	 * @return {string} Key to use for identifying a request to the specifed URL
	 *         with the specified request data in the cache.
	 */
	getCacheKey(method, url, data) {}

	/**
	 * Set constant header to all request.
	 *
	 * @method setDefaultHeader
	 * @chainable
	 * @param {string} header The name of the header.
	 * @param {string} value The header value. To provide multiple values,
	 *        separate them with commas
	 *        (see http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2).
	 * @return {Core.Interface.HttpAgent} This instance.
	 */
	setDefaultHeader(header, value) {}

	/**
	 * Clears all defaults headers sent with all requests.
	 *
	 * @method clearDefaultHeaders
	 * @chainable
	 * @return {Core.Interface.HttpAgent} This instance.
	 */
	clearDefaultHeaders() {}
}

ns.Core.Interface.HttpAgent = HttpAgent;
<|endoftext|>