<commit_before>/**
 * Core widget library, every widget has to be derived from the widget.
 *
 * @octdoc      ui/widget
 * @copyright   copyright (c) 2010-2012 by Harald Lapp
 * @author      Harald Lapp <harald@octris.org>
 */
/**/

;(function() {
    if ('widget' in oui) return;

    var registry = {};      // Global widget registry.

    /**
     * Constructor.
     *
     * @octdoc      widget/
     * @public
     * @param       string      name            Name to set for widget.
     * @param       object      options         Optional options for widget.
     * @return      oui.widget                  Widget instance.
     */
    oui.widget = function(name, options)
    /**/
    {
        /**
         * Main DOM node of widget.
         *
         * @octdoc      widget/node
         * @private
         * @var         DOMElement
         */
        var node = null;
        /**/

        /**
         * Name of widget.
         *
         * @octdoc      widget/name
         * @private
         * @var         string
         */
        var name = name || '';
        /**/

        /**
         * Options of widget.
         *
         * @octdoc      widget/options
         * @private
         * @var         object
         */
        var options = options || {};
        /**/

        /**
         * Whether the widget is disabled.
         *
         * @octdoc      widget/disabled
         * @private
         * @var         bool
         */
        var disabled = false;
        /**/

        /**
         * Child widgets.
         *
         * @octdoc      widget/children
         * @private
         * @var         array
         */
        var children = [];
        /**/

        /**
         * Return name of the widget.
         *
         * @octdoc      widget/getName
         * @public
         * @return      string                  The name of the widget.
         */
        this.getName = function()
        /**/
        {
            return name;
        }

        /**
         * Return main DOM node of the widget.
         *
         * @octdoc      widget/getNode
         * @public
         * @return      DOMElement
         */
        this.getNode = function()
        /**/
        {
            return node;
        }

        /**
         * Return value of a widget.
         *
         * @octdoc      widget/getValue
         * @public
         * @return      null|mixed
         */
        this.getValue = function()
        /**/
        {
            return null;
        }

        /**
         * Enable or disable the widget and all it's child widgets.
         *
         * @octdoc      widget/setEnabled
         * @public
         * @param       bool            enabled             True enables the widget, false disables it.
         */
        this.setEnabled = function(enabled)
        /**/
        {
            if (disabled = !enabled) {
                return;
            }

            disabled = !enabled;

            for (var i = 0, cnt = children.length; i < cnt; ++i) {
                children[i].setEnabled(enabled);
            }
        }

        /**
         * Add child widget
         *
         * @octdoc      widget/addChild
         * @public
         * @param       oui.widget      instance            Instance of a widget.
         * @return      oui.widget                          The widget instance specified as parameter.
         */
        this.addChild = function(instance)
        /**/
        {
            if (!(instance instanceof oui.widget)) {
                throw 'The parameter specified is not an instance of \'oui.widget\'!';
            }

            // TODO: check, if instance is allowed to add (eg.: by checking options [eg.: container must not be
            //       a child of tile])

            var me = this;

            instance.getDialog = function() {
                return me.getDialog();
            }

            children.push(instance);

            return instance;
        }

        /**
         * Create widget. This method is normally called from within the attach method to create
         * the widget container.
         *
         * @octdoc      widget/create
         * @public
         * @param       DOMElement      parent              Parent node to create widget in.
         * @param       object          def                 Widget definition.
         * @return      DOMElement                          Node of new created widget.
         */
        this.create = function(parent, def)
        /**/
        {
            node = oui.$(document.createElement(this.container));
            node.css(
                this.cssclass + ('class' in def
                                 ? ' ' + def['class']
                                 : '')
            );

            parent.append(node);

            return node;
        }
    }

    /**
     * Default container type of a widget.
     *
     * @octdoc      widget/container
     * @public
     * @var         string
     */
    oui.widget.prototype.container = 'DIV';
    /**/

    /**
     * Default css class of a widget.
     *
     * @octdoc      widget/cssclass
     * @public
     * @var         string
     */
    oui.widget.prototype.cssclass = 'oui_widget';
    /**/

    /**
     * Return dialog, the widget is assigned to. Returns false, if the widget is not assigned
     * to any dialog.
     *
     * @octdoc      widget/getDialog
     * @public
     * @var         bool|oui.dialog
     */
    oui.widget.prototype.getDialog = function()
    /**/
    {
        return false;
    }

    /**
     * Build a widget and attach it to a parent node.
     *
     * @octdoc      widget/attach
     * @public
     * @param       DOMElement      parent          Parent node to attach widget to.
     * @param       object          def             Widget definitions.
     */
    oui.widget.prototype.attach = function(parent, def)
    /**/
    {
        this.create(parent, def);

        this.processChildren(def, function(parent, instance, def) {
            instance.attach(parent, def);
        });
    }

    /**
     * Assimilate a part of a page and try to wrap OUI functionality around page elements.
     *
     * @octdoc      widget/assimilate
     * @public
     * @param       DOMElement      node            Node to assimilate.
     */
    oui.widget.prototype.assimilate = function(node)
    /**/
    {
        var me = this;

        (function _assimilate(node) {
            // TODO: implementation
        })(node);
    }

    /**
     * Add a widget object to the registry.
     *
     * @octdoc      widget/register
     * @static
     * @param       string          name            Name of widget to register.
     * @param       object          widget          Widget object.
     * @param       object          options         Optional options for widget creation.
     */
    oui.widget.register = function(name, widget, options)
    /**/
    {
        if (name in registry) {
            throw 'Widget was registered before!';
        } else if (name == 'widget') {
            throw 'A widget cannot have the name \'widget\'!';
        } else {
            registry[name] = {
                'widget':  widget,
                'options': options || {}
            }
        }
    }

    /**
     * Tests if something is registered with a specified widget name.
     *
     * @octdoc      widget/isRegistered
     * @static
     * @param       string          name            Name of widget to test if it's registered.
     */
    oui.widget.isRegistered = function(name)
    /**/
    {
        return (name in registry);
    }
})();
<commit_msg>work on base widget<commit_after>/**
 * Core widget library, every widget has to be derived from the widget.
 *
 * @octdoc      ui/widget
 * @copyright   copyright (c) 2010-2012 by Harald Lapp
 * @author      Harald Lapp <harald@octris.org>
 */
/**/

;(function() {
    if ('widget' in oui) return;

    var registry = {};      // Global widget registry.

    /**
     * Constructor.
     *
     * @octdoc      widget/
     * @public
     * @param       string      name            Name to set for widget.
     * @param       object      options         Optional options for widget.
     * @return      oui.widget                  Widget instance.
     */
    oui.widget = function(name, options)
    /**/
    {
        /**
         * Main DOM node of widget.
         *
         * @octdoc      widget/node
         * @private
         * @var         DOMElement
         */
        var node = null;
        /**/

        /**
         * Name of widget.
         *
         * @octdoc      widget/name
         * @private
         * @var         string
         */
        var name = name || '';
        /**/

        /**
         * Options of widget.
         *
         * @octdoc      widget/options
         * @private
         * @var         object
         */
        var options = options || {};
        /**/

        /**
         * Whether the widget is disabled.
         *
         * @octdoc      widget/disabled
         * @private
         * @var         bool
         */
        var disabled = false;
        /**/

        /**
         * Child widgets.
         *
         * @octdoc      widget/children
         * @private
         * @var         array
         */
        var children = [];
        /**/

        /**
         * Return name of the widget.
         *
         * @octdoc      widget/getName
         * @public
         * @return      string                  The name of the widget.
         */
        this.getName = function()
        /**/
        {
            return name;
        }

        /**
         * Return main DOM node of the widget.
         *
         * @octdoc      widget/getNode
         * @public
         * @return      DOMElement
         */
        this.getNode = function()
        /**/
        {
            return node;
        }

        /**
         * Return value of a widget.
         *
         * @octdoc      widget/getValue
         * @public
         * @return      null|mixed
         */
        this.getValue = function()
        /**/
        {
            return null;
        }

        /**
         * Enable or disable the widget and all it's child widgets.
         *
         * @octdoc      widget/setEnabled
         * @public
         * @param       bool            enabled             True enables the widget, false disables it.
         */
        this.setEnabled = function(enabled)
        /**/
        {
            if (disabled = !enabled) {
                return;
            }

            if ((disabled = !enabled)) {
                this.onDisable();
            } else {
                this.onEnable();
            }

            for (var i = 0, cnt = children.length; i < cnt; ++i) {
                children[i].setEnabled(enabled);
            }
        }

        /**
         * Add child widget
         *
         * @octdoc      widget/addChild
         * @public
         * @param       oui.widget      instance            Instance of a widget.
         * @return      oui.widget                          The widget instance specified as parameter.
         */
        this.addChild = function(instance)
        /**/
        {
            if (!(instance instanceof oui.widget)) {
                throw 'The parameter specified is not an instance of \'oui.widget\'!';
            }

            // TODO: check, if instance is allowed to add (eg.: by checking options [eg.: container must not be
            //       a child of tile])

            var me = this;

            instance.getDialog = function() {
                return me.getDialog();
            }

            children.push(instance);

            return instance;
        }

        /**
         * Create widget. This method is normally called from within the attach method to create
         * the widget container.
         *
         * @octdoc      widget/create
         * @public
         * @param       DOMElement      parent              Parent node to create widget in.
         * @param       object          def                 Widget definition.
         * @return      DOMElement                          Node of new created widget.
         */
        this.create = function(parent, def)
        /**/
        {
            node = oui.$(document.createElement(this.container));
            node.css(
                this.cssclass + ('class' in def
                                 ? ' ' + def['class']
                                 : '')
            );

            parent.append(node);

            return node;
        }
    }

    /**
     * Default container type of a widget.
     *
     * @octdoc      widget/container
     * @public
     * @var         string
     */
    oui.widget.prototype.container = 'DIV';
    /**/

    /**
     * Default css class of a widget.
     *
     * @octdoc      widget/cssclass
     * @public
     * @var         string
     */
    oui.widget.prototype.cssclass = 'oui_widget';
    /**/

    /**
     * Return dialog, the widget is assigned to. Returns false, if the widget is not assigned
     * to any dialog.
     *
     * @octdoc      widget/getDialog
     * @public
     * @var         bool|oui.dialog
     */
    oui.widget.prototype.getDialog = function()
    /**/
    {
        return false;
    }

    /**
     * Build a widget and attach it to a parent node.
     *
     * @octdoc      widget/attach
     * @public
     * @param       DOMElement      parent          Parent node to attach widget to.
     * @param       object          def             Widget definitions.
     */
    oui.widget.prototype.attach = function(parent, def)
    /**/
    {
        this.create(parent, def);

        this.processChildren(def, function(parent, instance, def) {
            instance.attach(parent, def);
        });
    }

    /**
     * Assimilate a part of a page and try to wrap OUI functionality around page elements.
     *
     * @octdoc      widget/assimilate
     * @public
     * @param       DOMElement      node            Node to assimilate.
     */
    oui.widget.prototype.assimilate = function(node)
    /**/
    {
        var me = this;

        (function _assimilate(node) {
            // TODO: implementation
        })(node);
    }

    /**
     * Add a widget object to the registry.
     *
     * @octdoc      widget/register
     * @static
     * @param       string          name            Name of widget to register.
     * @param       object          widget          Widget object.
     * @param       object          options         Optional options for widget creation.
     */
    oui.widget.register = function(name, widget, options)
    /**/
    {
        if (name in registry) {
            throw 'Widget was registered before!';
        } else if (name == 'widget') {
            throw 'A widget cannot have the name \'widget\'!';
        } else {
            registry[name] = {
                'widget':  widget,
                'options': options || {}
            }
        }
    }

    /*
     * event handlers to be overwritten by children
     */

    /**
     * Event handler get's called, when widget get's enabled
     *
     * @octdoc      widget/onEnable
     * @public
     */
    oui.widget.prototype.onEnable = function()
    /**/
    {
    }

    /**
     * Event handler get's called, when widget get's disabled.
     *
     * @octdoc      widget/onDisable
     * @public
     */
    oui.widget.prototype.onDisable = function()
    /**/
    {
    }

    /*
     * static methods
     */

    /**
     * Tests if something is registered with a specified widget name.
     *
     * @octdoc      widget/isRegistered
     * @static
     * @param       string          name            Name of widget to test if it's registered.
     */
    oui.widget.isRegistered = function(name)
    /**/
    {
        return (name in registry);
    }
})();
<|endoftext|>


<commit_before><commit_msg>Use the channel token provided in appOptions when loading Big Game<commit_after><|endoftext|>


<commit_before>const stopEvent = function(e) {

	if (typeof e.stopPropagation === 'function') e.stopPropagation()
	if (typeof e.preventDefault === 'function')  e.preventDefault()

}

const bindShow = function(elem, opts) {

	elem.onclick = function(e) {

		let id          = this.getAttribute('data-basicLightbox-show')
		let contentElem = document.querySelector(`[data-basicLightbox="${ id }"]`)

		stopEvent(e)
		show(contentElem.outerHTML, opts)

	}

}

const bindClose = function(elem, opts) {

	elem.onclick = function(e) {

		stopEvent(e)
		close(opts)

	}

}

const validate = function(opts = {}) {

	if (opts.closable!==false) opts.closable = true

	if (typeof opts.beforeShow !== 'function') opts.beforeShow = () => {}
	if (typeof opts.afterShow !== 'function')  opts.afterShow = () => {}

	if (typeof opts.beforeClose !== 'function') opts.beforeClose = () => {}
	if (typeof opts.afterClose !== 'function')  opts.afterClose = () => {}

	if (typeof opts.beforeHTML === 'function') opts.beforeHTML = opts.beforeHTML()
	if (typeof opts.afterHTML === 'function')  opts.afterHTML = opts.afterHTML()

	if (typeof opts.beforeHTML !== 'string') opts.beforeHTML = ''
	if (typeof opts.afterHTML !== 'string')  opts.afterHTML = ''

	if (typeof opts.beforePlaceholder === 'function') opts.beforePlaceholder = opts.beforePlaceholder()
	if (typeof opts.afterPlaceholder === 'function')  opts.afterPlaceholder = opts.afterPlaceholder()

	if (typeof opts.beforePlaceholder !== 'string') opts.beforePlaceholder = ''
	if (typeof opts.afterPlaceholder !== 'string')  opts.afterPlaceholder = ''

	return opts

}

const render = function(html = '', opts) {

	return (`

			${ opts.beforePlaceholder }

				${ opts.beforeHTML }
				${ html }
				${ opts.afterHTML }

			${ opts.afterPlaceholder }

	`)

}

export const exists = function() {

	let elem = document.querySelector('.basicLightbox')

	return (elem==null ? false : true)

}

export const visible = function() {

	let elem = document.querySelector('.basicLightbox--visible')

	return (elem==null ? false : true)

}

export const show = function(html, opts) {

	// Validate options
	opts = validate(opts)

	// Run beforeShow event
	// Stop execution when function returns false
	if (opts.beforeShow()===false) return false

	// Append lightbox to DOM
	document.body.insertAdjacentHTML('beforeend', render(html, opts))

	// Get the newly created lightbox element
	let elem = document.querySelector('.basicLightbox')

	// Bind close element
	if (opts.closable===true) bindClose(elem.querySelector('.basicLightbox__close'), opts)

	// Wait a while to ensure that the class change triggers the animation
	setTimeout(() => {
		requestAnimationFrame(() => {

			// Show lightbox
			elem.classList.add('basicLightbox--visible')

			// Run afterShow event
			opts.afterShow()

		})
	}, 10)

}

export const close = function(opts) {

	// Validate options
	opts = validate(opts)

	// Run beforeClose event
	// Stop execution when function returns false
	if (opts.beforeClose()===false) return false

	// Get the lightbox element
	let elem = document.querySelector('.basicLightbox')

	// Don't continue to hide lightbox when element not visible
	if (visible()===false) return false

	// Hide lightbox
	elem.classList.remove('basicLightbox--visible')

	setTimeout(() => {
		requestAnimationFrame(() => {

			// Don't continue to remove lightbox when element missing
			if (exists()===false) return false

			// Remove lightbox from DOM
			elem.parentElement.removeChild(elem)

			// Run afterClose event
			opts.afterClose()

		})
	}, 410)

}

export const init = function(elems, opts) {

	if (typeof elems === 'string') elems = document.querySelectorAll(elems)
	if (elems==null)               elems = document.querySelectorAll('[data-basicLightbox-show]')

	Array.prototype.forEach.call(elems, (elem) => bindShow(elem, opts))

}<commit_msg>Code adjustment<commit_after>const stopEvent = function(e) {

	if (typeof e.stopPropagation === 'function') e.stopPropagation()
	if (typeof e.preventDefault === 'function')  e.preventDefault()

}

const bindShow = function(elem, opts) {

	elem.onclick = function(e) {

		let id          = this.getAttribute('data-basicLightbox-show')
		let contentElem = document.querySelector(`[data-basicLightbox="${ id }"]`)
		let html        = contentElem.outerHTML

		stopEvent(e)
		show(html, opts)

	}

}

const bindClose = function(elem, opts) {

	elem.onclick = function(e) {

		stopEvent(e)
		close(opts)

	}

}

const validate = function(opts = {}) {

	if (opts.closable!==false) opts.closable = true

	if (typeof opts.beforeShow !== 'function') opts.beforeShow = () => {}
	if (typeof opts.afterShow !== 'function')  opts.afterShow = () => {}

	if (typeof opts.beforeClose !== 'function') opts.beforeClose = () => {}
	if (typeof opts.afterClose !== 'function')  opts.afterClose = () => {}

	if (typeof opts.beforeHTML === 'function') opts.beforeHTML = opts.beforeHTML()
	if (typeof opts.afterHTML === 'function')  opts.afterHTML = opts.afterHTML()

	if (typeof opts.beforeHTML !== 'string') opts.beforeHTML = ''
	if (typeof opts.afterHTML !== 'string')  opts.afterHTML = ''

	if (typeof opts.beforePlaceholder === 'function') opts.beforePlaceholder = opts.beforePlaceholder()
	if (typeof opts.afterPlaceholder === 'function')  opts.afterPlaceholder = opts.afterPlaceholder()

	if (typeof opts.beforePlaceholder !== 'string') opts.beforePlaceholder = ''
	if (typeof opts.afterPlaceholder !== 'string')  opts.afterPlaceholder = ''

	return opts

}

const render = function(html = '', opts) {

	return (`

			${ opts.beforePlaceholder }

				${ opts.beforeHTML }
				${ html }
				${ opts.afterHTML }

			${ opts.afterPlaceholder }

	`)

}

export const exists = function() {

	let elem = document.querySelector('.basicLightbox')

	return (elem==null ? false : true)

}

export const visible = function() {

	let elem = document.querySelector('.basicLightbox--visible')

	return (elem==null ? false : true)

}

export const show = function(html, opts) {

	// Validate options
	opts = validate(opts)

	// Run beforeShow event
	// Stop execution when function returns false
	if (opts.beforeShow()===false) return false

	// Append lightbox to DOM
	document.body.insertAdjacentHTML('beforeend', render(html, opts))

	// Get the newly created lightbox element
	let elem = document.querySelector('.basicLightbox')

	// Bind close element
	if (opts.closable===true) bindClose(elem.querySelector('.basicLightbox__close'), opts)

	// Wait a while to ensure that the class change triggers the animation
	setTimeout(() => {
		requestAnimationFrame(() => {

			// Show lightbox
			elem.classList.add('basicLightbox--visible')

			// Run afterShow event
			opts.afterShow()

		})
	}, 10)

}

export const close = function(opts) {

	// Validate options
	opts = validate(opts)

	// Run beforeClose event
	// Stop execution when function returns false
	if (opts.beforeClose()===false) return false

	// Get the lightbox element
	let elem = document.querySelector('.basicLightbox')

	// Don't continue to hide lightbox when element not visible
	if (visible()===false) return false

	// Hide lightbox
	elem.classList.remove('basicLightbox--visible')

	setTimeout(() => {
		requestAnimationFrame(() => {

			// Don't continue to remove lightbox when element missing
			if (exists()===false) return false

			// Remove lightbox from DOM
			elem.parentElement.removeChild(elem)

			// Run afterClose event
			opts.afterClose()

		})
	}, 410)

}

export const init = function(elems, opts) {

	if (typeof elems === 'string') elems = document.querySelectorAll(elems)
	if (elems==null)               elems = document.querySelectorAll('[data-basicLightbox-show]')

	Array.prototype.forEach.call(elems, (elem) => bindShow(elem, opts))

}<|endoftext|>


<commit_before>/**
 * AJAX form creation
 * @class cowboy.FormAjax
 * @implements {cowboy.Options}
 */
cowboy.FormAjax = new Class ({
	Implements: cowboy.Options,

	options: {
		invalidFieldMessage: 'Please fill this field',
		redirectDelay: 1000,
		onRequest: function() { return; },
		onSuccess: function(response) { return; },
		onFailure: function() { return; },
		redirect: null,
		dataContainer: null,
		beforeRequest: function() { return; }
	},

	/**
	 * Create a FormAjax
	 * @constructor
	 * @param  {Element}	form		Form element
	 * @param  {Object}		options		Form options
	 */
	initialize: function(form, options) {
		var _this = this;
		if (form instanceof HTMLElement) {
			this.form = form;

			this.options = Object.merge(this.options, options);

			// Set Options and overload options by properties in the form
			this.setElementOptions(this.options, form);

			this.form.setProperty('autocomplete', 'off');
			this.form.addEvent('submit', this.submit.bind(this));

			this.form.getElements('.required').each(function(el){
				el.addEvent('focus', _this.focus);
				el.addEvent('blur', _this.blur.bind(_this));
			});

			this.uploadReq = new cowboy.Request({
				onRequest: function() {
					return _this.options.onRequest();
				},

				onSuccess: function(response) {
					return _this.options.onSuccess(JSON.decode(response));
				},

				onFailure: function() {
					return _this.options.onFailure();
				}
			});
		}
		else if (form instanceof Object) {
			for (var i = form.length - 1; i >= 0; i--) {
				new cowboy.FormAjax(form[i], options);
			}
		}
	},

	/**
	 * Submit the form
	 * @method submit
	 * @param  {Event}	e	Event that triggers the submit
	 */
	submit: function(e) {
		e.stop();

		this.showErrors();

		if (this.form.getElements('.error').length === 0) {
			this.getFormData();

			this.options.beforeRequest();

			this.uploadReq.send({ url: this.form.getProperty('action') });
		}

		this.uploadReq.reset();
	},

	/**
	 * Event triggered on input focus
	 * @method focus
	 * @param  {Event}	e	Event when an input is focused
	 */
	focus: function(e){
		if(e.target.hasClass('error')) {
			this.removeClass('error');
			this.erase('placeholder');
		}
	},

	/**
	 * Event triggered on input blur
	 * @method blur
	 * @param  {Event}	e	Event when an input is blured
	 */
	blur: function(e){
		if (e.target.value === '') {
			e.target.setProperty('placeholder',this.options.invalidFieldMessage);
			e.target.addClass('error');
		}
	},

	/**
	 * Show the form errors
	 * @method showErrors
	 */
	showErrors: function() {
		_this = this;
		this.form.getElements('.required').each(function(el) {
			if (el.value === '') {
				el.addClass('error');
				el.setProperty('placeholder',_this.options.invalidFieldMessage);
			}
		});
	},

	/**
	 * Get data to submit
	 * @method getFormData
	 */
	getFormData: function() {
		var _this = this;

		var data = {};

		this.form.getElements('input[name]').each(function(el) {
			if (el.getProperty('type') == 'checkbox') {
				if (el.checked === true) {
					data[el.name] = el.value;
				}
				else {
					data[el.name] = 0;
				}
			}
			else if (el.getProperty('type') == 'radio') {
				if (el.checked === true) {
					data[el.name] = el.value;
				}
			}
			else if(el.getProperty('type') == 'file') {
				data[el.name] = el.files[0];
			}
			else {
				data[el.name] = el.value;
			}
		});

		this.form.getElements('select[name]').each(function(el){
			data[el.name] = el.value;
		});

		this.form.getElements('textarea[name]').each(function(el){
			data[el.name] = el.value;
		});

		if (this.options.dataContainer !== null) {
			Object.each(data, function(value, key) {
				_this.uploadReq.append(_this.options.dataContainer + '[' + key + ']', value);
			});
		}
		else {
			Object.each(data, function(value, key) {
				_this.uploadReq.append(key, value);
			});
		}
	}
});
<commit_msg>Allow specific callbacks from an external object<commit_after>/**
 * AJAX form creation
 * @class cowboy.FormAjax
 * @implements {cowboy.Options}
 */
cowboy.FormAjax = new Class ({
	Implements: cowboy.Options,

	options: {
		invalidFieldMessage: 'Please fill this field',
		redirectDelay: 1000,
		onRequest: function() { return; },
		onSuccess: function(response) { return; },
		onFailure: function() { return; },
		redirect: null,
		dataContainer: null,
		beforeRequest: function() { return; }
	},

	/**
	 * Create a FormAjax
	 * @constructor
	 * @param  {Element}	form		Form element
	 * @param  {Object}		options		Form options
	 * @param  {Object}		callbacks
	 */
	initialize: function(form, options, callbacks) {
		var _this = this;
		if (form instanceof HTMLElement) {
			this.form = form;
			this.callbacks = callbacks;

			this.options = Object.merge(this.options, options);

			// Set Options and overload options by properties in the form
			this.setElementOptions(this.options, form);

			this.form.setProperty('autocomplete', 'off');
			this.form.addEvent('submit', this.submit.bind(this));

			this.form.getElements('.required').each(function(el){
				el.addEvent('focus', _this.focus);
				el.addEvent('blur', _this.blur.bind(_this));
			});

			this.uploadReq = new cowboy.Request({
				onRequest: function() {
					return _this.options.onRequest();
				},

				onSuccess: function(response) {
					var decodeResponse = JSON.decode(response);
					if (typeof _this.callbacks != 'undefined') {
						var name = _this.form.getAttribute('name');
						if (typeof _this.callbacks[name] == 'function') {
							_this.callbacks[name](decodeResponse);
						}
					}
					return _this.options.onSuccess(decodeResponse);
				},

				onFailure: function() {
					return _this.options.onFailure();
				}
			});
		}
		else if (form instanceof Object) {
			for (var i = form.length - 1; i >= 0; i--) {
				new cowboy.FormAjax(form[i], options, callbacks);
			}
		}
	},

	/**
	 * Submit the form
	 * @method submit
	 * @param  {Event}	e	Event that triggers the submit
	 */
	submit: function(e) {
		e.stop();

		this.showErrors();

		if (this.form.getElements('.error').length === 0) {
			this.getFormData();

			this.options.beforeRequest();

			this.uploadReq.send({ url: this.form.getProperty('action') });
		}

		this.uploadReq.reset();
	},

	/**
	 * Event triggered on input focus
	 * @method focus
	 * @param  {Event}	e	Event when an input is focused
	 */
	focus: function(e){
		if(e.target.hasClass('error')) {
			this.removeClass('error');
			this.erase('placeholder');
		}
	},

	/**
	 * Event triggered on input blur
	 * @method blur
	 * @param  {Event}	e	Event when an input is blured
	 */
	blur: function(e){
		if (e.target.value === '') {
			e.target.setProperty('placeholder',this.options.invalidFieldMessage);
			e.target.addClass('error');
		}
	},

	/**
	 * Show the form errors
	 * @method showErrors
	 */
	showErrors: function() {
		_this = this;
		this.form.getElements('.required').each(function(el) {
			if (el.value === '') {
				el.addClass('error');
				el.setProperty('placeholder',_this.options.invalidFieldMessage);
			}
		});
	},

	/**
	 * Get data to submit
	 * @method getFormData
	 */
	getFormData: function() {
		var _this = this;

		var data = {};

		this.form.getElements('input[name]').each(function(el) {
			if (el.getProperty('type') == 'checkbox') {
				if (el.checked === true) {
					data[el.name] = el.value;
				}
				else {
					data[el.name] = 0;
				}
			}
			else if (el.getProperty('type') == 'radio') {
				if (el.checked === true) {
					data[el.name] = el.value;
				}
			}
			else if(el.getProperty('type') == 'file') {
				data[el.name] = el.files[0];
			}
			else {
				data[el.name] = el.value;
			}
		});

		this.form.getElements('select[name]').each(function(el){
			data[el.name] = el.value;
		});

		this.form.getElements('textarea[name]').each(function(el){
			data[el.name] = el.value;
		});

		if (this.options.dataContainer !== null) {
			Object.each(data, function(value, key) {
				_this.uploadReq.append(_this.options.dataContainer + '[' + key + ']', value);
			});
		}
		else {
			Object.each(data, function(value, key) {
				_this.uploadReq.append(key, value);
			});
		}
	}
});
<|endoftext|>


<commit_before>angular.module('cesium.app.controllers', ['ngIdle', 'cesium.platform', 'cesium.services'])

  .config(function($httpProvider) {
    'ngInject';

    //Enable cross domain calls
    $httpProvider.defaults.useXDomain = true;

    //Remove the header used to identify ajax call  that would prevent CORS from working
    delete $httpProvider.defaults.headers.common['X-Requested-With'];
  })

  .config(function($stateProvider, $urlRouterProvider) {
    'ngInject';

    $stateProvider

      .state('app', {
        url: "/app",
        abstract: true,
        templateUrl: "templates/menu.html",
        controller: 'AppCtrl',
        data: {
          large: false
        }
      })

      .state('app.home', {
        url: "/home?error",
        views: {
          'menuContent': {
            templateUrl: "templates/home/home.html",
            controller: 'HomeCtrl'
          }
        }
      })

      .state('app.lock', {
        cache: false,
        url: "/lock",
        views: {
          'menuContent': {
            templateUrl: "templates/common/view_passcode.html",
            controller: 'PassCodeCtrl'
          }
        }
      })
    ;

    // if none of the above states are matched, use this as the fallback
    $urlRouterProvider.otherwise('/app/home');

  })

  .controller('AppCtrl', AppController)

  .controller('HomeCtrl', HomeController)

  .controller('PluginExtensionPointCtrl', PluginExtensionPointController)

  .controller('EmptyModalCtrl', EmptyModalController)

  .controller('AboutCtrl', AboutController)

;

/**
 * Useful for modal with no controller (see Modal service)
 */
function EmptyModalController($scope, parameters) {

}

/**
 * Useful controller that could be reuse in plugin, using $scope.extensionPoint for condition rendered in templates
 */
function PluginExtensionPointController($scope, PluginService) {
  'ngInject';
  $scope.extensionPoint = PluginService.extensions.points.current.get();
}

/**
 * Abstract controller (inherited by other controllers)
 */
function AppController($scope, $rootScope, $state, $ionicSideMenuDelegate, $q, $timeout,
                       $ionicHistory, $controller, $window, csPlatform,
                       UIUtils, BMA, csWallet, csCurrency, Device, Modals, csSettings, csConfig
  ) {
  'ngInject';

  $scope.search = {};
  $scope.login = csWallet.isLogin();
  $scope.motion = UIUtils.motion.default;

  $scope.showHome = function() {
    $ionicHistory.nextViewOptions({
      historyRoot: true
    });
    return $state.go('app.home')
      .then(UIUtils.loading.hide);
  };

  ////////////////////////////////////////
  // Device Methods
  ////////////////////////////////////////

  $scope.scanQrCodeAndGo = function() {
    if (!Device.barcode.enable) {
      return;
    }
    Device.barcode.scan()
    .then(function(uri) {
      if (!uri) {
        return;
      }
      BMA.uri.parse(uri)
      .then(function(result){
        // If pubkey
        if (result && result.pubkey) {
          $state.go('app.wot_identity', {
            pubkey: result.pubkey,
            node: result.host ? result.host: null}
          );
        }
        else {
          UIUtils.alert.error(result, 'ERROR.SCAN_UNKNOWN_FORMAT');
        }
      })
      .catch(UIUtils.onError('ERROR.SCAN_UNKNOWN_FORMAT'));
    })
    .catch(UIUtils.onError('ERROR.SCAN_FAILED'));
  };

  ////////////////////////////////////////
  // Show Help tour
  ////////////////////////////////////////

  $scope.createHelptipScope = function(isTour) {
    if (!isTour && ($rootScope.tour || !$rootScope.settings.helptip.enable || UIUtils.screen.isSmall())) {
      return; // avoid other helptip to be launched (e.g. csWallet)
    }
    // Create a new scope for the tour controller
    var helptipScope = $scope.$new();
    $controller('HelpTipCtrl', { '$scope': helptipScope});
    return helptipScope;
  };

  $scope.startHelpTour = function(skipClearCache) {
    $rootScope.tour = true; // to avoid other helptip to be launched (e.g. csWallet)

    //
    if (!skipClearCache) {
      $ionicHistory.clearHistory();
      return $ionicHistory.clearCache()
        .then(function() {
          $scope.startHelpTour(true/*continue*/);
        });
    }

    var helptipScope = $scope.createHelptipScope(true);
    return helptipScope.startHelpTour()
    .then(function() {
      helptipScope.$destroy();
      delete $rootScope.tour;
    })
    .catch(function(err){
      delete $rootScope.tour;
    });
  };

  ////////////////////////////////////////
  // Login & wallet
  ////////////////////////////////////////

  $scope.isLogin = function() {
    return $scope.login;
  };

  $scope.showProfilePopover = function(event) {
    return UIUtils.popover.show(event, {
      templateUrl :'templates/common/popover_profile.html',
      scope: $scope,
      autoremove: true,
      afterShow: function(popover) {
        $scope.profilePopover = popover;
        $timeout(function() {
          UIUtils.ink({selector: '#profile-popover .ink, #profile-popover .ink-dark'});
        }, 100);
      }
    });
  };

  $scope.closeProfilePopover = function() {
    if ($scope.profilePopover && $scope.profilePopover.isShown()) {
      $timeout(function(){$scope.profilePopover.hide();});
    }
  };

  // Load wallet data (after login)
  $scope.loadWalletData = function(options) {
    return csWallet.loadData(options)
      /*.catch(UIUtils.onError('ERROR.LOAD_WALLET_DATA_ERROR'))*/

      .then(function(walletData) {
        // Warn if wallet has been never used - see #167
        var showAlert = !csCurrency.data.initPhase && !csWallet.isNew() && csWallet.isNeverUsed() && (!csSettings.data.wallet || csSettings.data.wallet.alertIfUnusedWallet);
        if (!showAlert) return walletData;

        // Alert: wallet is empty !
        return UIUtils.loading.hide()
          .then(function(){
            return UIUtils.alert.confirm('CONFIRM.LOGIN_UNUSED_WALLET', 'CONFIRM.LOGIN_UNUSED_WALLET_TITLE',
              {
                okText: 'COMMON.BTN_CONTINUE'
              });
          })
          .then(function(confirm) {
            if (confirm) return walletData;
            return csWallet.logout();
          });
      })

      .then(function(walletData) {
        if (walletData) {
          $rootScope.walletData = walletData;
          return walletData;
        }
        else { // cancel login
          throw 'CANCELLED';
        }
      });
  };

  // Login and load wallet
  $scope.loadWallet = function(options) {

    // Make sure the platform is ready
    if (!csPlatform.isStarted()) {
      return csPlatform.ready().then(function(){
        return $scope.loadWallet(options);
      });
    }

    options = options || {};

    // If need auth
    if (options.auth && !csWallet.isAuth()) {
      return csWallet.auth(options)
        .then(function (walletData) {
          if (walletData) {
            // Force full load, even if min data asked
            // Because user can wait when just filled login (by modal)
            if (options && options.minData) options.minData = false;
            return $scope.loadWalletData(options);
          }
          else { // failed to auth
            throw 'CANCELLED';
          }
        });
    }

    // If need login
    else if (!csWallet.isLogin()) {
      return csWallet.login(options)
        .then(function (walletData) {
          if (walletData) {
            // Force full load, even if min data asked
            // Because user can wait when just filled login (by modal)
            if (options && options.minData) options.minData = false;
            return $scope.loadWalletData(options);
          }
          else { // failed to login
            throw 'CANCELLED';
          }
        });
    }

    // Laready login ro auth
    else if (!csWallet.data.loaded) {
      return $scope.loadWalletData(options);
    }
    else {
      return $q.when(csWallet.data);
    }
  };

  // Login and go to a state (or wallet if not)
  $scope.loginAndGo = function(state, options) {
    $scope.closeProfilePopover();

    state = state || 'app.view_wallet';

    if (!csWallet.isLogin()) {

      // Make sure to protect login modal, if HTTPS enable - fix #340
      if (csConfig.httpsMode && $window.location && $window.location.protocol !== 'https:') {
        var href = $window.location.href;
        var hashIndex = href.indexOf('#');
        var rootPath = (hashIndex != -1) ? href.substr(0, hashIndex) : href;
        rootPath = 'https' + rootPath.substr(4);
        href = rootPath + $state.href(state);
        if (csConfig.httpsModeDebug) {
          console.debug('[httpsMode] --- Should redirect to: ' + href);
          // continue
        }
        else {
          $window.location.href = href;
          return;
        }

      }

      return csWallet.login(options)
        .then(function(){
          return $state.go(state, options);
        })
        .then(UIUtils.loading.hide);
    }
    else {
      return $state.go(state, options);
    }
  };

  // Logout
  $scope.logout = function(options) {
    options = options || {};
    if (!options.force && $scope.profilePopover) {
      // Make the popover if really closed, to avoid UI refresh on popover buttons
      return $scope.profilePopover.hide()
        .then(function(){
          options.force = true;
          return $scope.logout(options);
        });
    }
    if (options.askConfirm) {
      return UIUtils.alert.confirm('CONFIRM.LOGOUT')
        .then(function(confirm) {
          if (confirm) {
            options.askConfirm=false;
            return $scope.logout(options);
          }
        });
    }

    UIUtils.loading.show();
    return csWallet.logout()
      .then(function() {
        $ionicSideMenuDelegate.toggleLeft();
        $ionicHistory.clearHistory();

        return $ionicHistory.clearCache()
          .then(function() {
            return $scope.showHome();
          });
      })
      .catch(UIUtils.onError());
  };

  // If connected and same pubkey
  $scope.isUserPubkey = function(pubkey) {
    return csWallet.isUserPubkey(pubkey);
  };

  // add listener on wallet event
  csWallet.api.data.on.login($scope, function(walletData, deferred) {
    $scope.login = true;
    $rootScope.walletData = walletData || {};
    return deferred ? deferred.resolve() : $q.when();
  });
  csWallet.api.data.on.logout($scope, function() {
    $scope.login = false;
    $rootScope.walletData = {};
  });
  csWallet.api.data.on.auth($scope, function() {
    $scope.auth = true;
  });
  csWallet.api.data.on.unauth($scope, function() {
    $scope.auth = false;
  });

  ////////////////////////////////////////
  // Useful modals
  ////////////////////////////////////////

  // Open transfer modal
  $scope.showTransferModal = function(parameters) {
    return $scope.loadWallet()
    .then(function(walletData){
      UIUtils.loading.hide();
      if (walletData) {
        return Modals.showTransfer(parameters);
      }
    })
    .then(function(result){
      if (result){
        return $timeout(function(){
          return UIUtils.toast.show('INFO.TRANSFER_SENT');
        }, 10);
      }
    });
  };

  $scope.showAboutModal = function() {
    return Modals.showAbout();
  };

  $scope.showJoinModal = function() {
    $scope.closeProfilePopover();
    return Modals.showJoin()
      .then(function(res){
        if (!res) return;
        return (res.accountType == 'member') ?
          Modals.showJoinMember(res) :
          Modals.showJoinWallet(res);
      });
  };

  $scope.showSettings = function() {
    $scope.closeProfilePopover();
    return $state.go('app.settings');
  };

  $scope.showHelpModal = function(parameters) {
    return Modals.showHelp(parameters);
  };

  ////////////////////////////////////////
  // Change node (expert mode)
  ////////////////////////////////////////

  $scope.showNodeListPopover = function(event) {
    return UIUtils.popover.show(event, {
      templateUrl: 'templates/network/popover_peer_info.html',
      autoremove: true,
      scope: $scope.$new(true)
    });
  };

  ////////////////////////////////////////
  // Layout Methods
  ////////////////////////////////////////
  $scope.showFab = function(id, timeout) {
    UIUtils.motion.toggleOn({selector: '#'+id + '.button-fab'}, timeout);
  };

  $scope.hideFab = function(id, timeout) {
    UIUtils.motion.toggleOff({selector: '#'+id + '.button-fab'}, timeout);
  };

  // Could be override by subclass
  $scope.doMotion = function(options) {
    return $scope.motion.show(options);
  };
}

function AboutController($scope, csConfig) {
  'ngInject';
  $scope.config = csConfig;
}

function HomeController($scope, $state, $timeout, $ionicHistory, csPlatform, csCurrency) {
  'ngInject';

  $scope.loading = true;

  $scope.enter = function(e, state) {
    if (state && state.stateParams && state.stateParams.error) { // Query parameter
      $scope.error = state.stateParams.error;
      $scope.node =  csCurrency.data.node;
      $scope.loading = false;
      $ionicHistory.nextViewOptions({
        disableAnimate: true,
        disableBack: true,
        historyRoot: true
      });
      $state.go('app.home', {error: undefined}, {
        reload: false,
        inherit: true,
        notify: false});
    }
    else {
      // Start platform
      csPlatform.ready()
        .then(function() {
          $scope.loading = false;
        })
        .catch(function(err) {
          $scope.node =  csCurrency.data.node;
          $scope.loading = false;
          $scope.error = err;
        });
    }
  };
  $scope.$on('$ionicView.enter', $scope.enter);

  $scope.reload = function() {
    $scope.loading = true;
    delete $scope.error;

    $timeout($scope.enter, 200);
  };

  /**
   * Catch click for quick fix
   * @param event
   */
  $scope.doQuickFix = function(event) {
    if (event == 'settings') {
      $ionicHistory.nextViewOptions({
        historyRoot: true
      });
      $state.go('app.settings');
    }
  };

  // For DEV ONLY
  /*$timeout(function() {
    $scope.loginAndGo();
  }, 500);*/
}
<commit_msg>[fix] Display warning on empty wallet only once (in wallet-service)<commit_after>angular.module('cesium.app.controllers', ['ngIdle', 'cesium.platform', 'cesium.services'])

  .config(function($httpProvider) {
    'ngInject';

    //Enable cross domain calls
    $httpProvider.defaults.useXDomain = true;

    //Remove the header used to identify ajax call  that would prevent CORS from working
    delete $httpProvider.defaults.headers.common['X-Requested-With'];
  })

  .config(function($stateProvider, $urlRouterProvider) {
    'ngInject';

    $stateProvider

      .state('app', {
        url: "/app",
        abstract: true,
        templateUrl: "templates/menu.html",
        controller: 'AppCtrl',
        data: {
          large: false
        }
      })

      .state('app.home', {
        url: "/home?error",
        views: {
          'menuContent': {
            templateUrl: "templates/home/home.html",
            controller: 'HomeCtrl'
          }
        }
      })

      .state('app.lock', {
        cache: false,
        url: "/lock",
        views: {
          'menuContent': {
            templateUrl: "templates/common/view_passcode.html",
            controller: 'PassCodeCtrl'
          }
        }
      })
    ;

    // if none of the above states are matched, use this as the fallback
    $urlRouterProvider.otherwise('/app/home');

  })

  .controller('AppCtrl', AppController)

  .controller('HomeCtrl', HomeController)

  .controller('PluginExtensionPointCtrl', PluginExtensionPointController)

  .controller('EmptyModalCtrl', EmptyModalController)

  .controller('AboutCtrl', AboutController)

;

/**
 * Useful for modal with no controller (see Modal service)
 */
function EmptyModalController($scope, parameters) {

}

/**
 * Useful controller that could be reuse in plugin, using $scope.extensionPoint for condition rendered in templates
 */
function PluginExtensionPointController($scope, PluginService) {
  'ngInject';
  $scope.extensionPoint = PluginService.extensions.points.current.get();
}

/**
 * Abstract controller (inherited by other controllers)
 */
function AppController($scope, $rootScope, $state, $ionicSideMenuDelegate, $q, $timeout,
                       $ionicHistory, $controller, $window, csPlatform,
                       UIUtils, BMA, csWallet, csCurrency, Device, Modals, csSettings, csConfig
  ) {
  'ngInject';

  $scope.search = {};
  $scope.login = csWallet.isLogin();
  $scope.motion = UIUtils.motion.default;

  $scope.showHome = function() {
    $ionicHistory.nextViewOptions({
      historyRoot: true
    });
    return $state.go('app.home')
      .then(UIUtils.loading.hide);
  };

  ////////////////////////////////////////
  // Device Methods
  ////////////////////////////////////////

  $scope.scanQrCodeAndGo = function() {
    if (!Device.barcode.enable) {
      return;
    }
    Device.barcode.scan()
    .then(function(uri) {
      if (!uri) {
        return;
      }
      BMA.uri.parse(uri)
      .then(function(result){
        // If pubkey
        if (result && result.pubkey) {
          $state.go('app.wot_identity', {
            pubkey: result.pubkey,
            node: result.host ? result.host: null}
          );
        }
        else {
          UIUtils.alert.error(result, 'ERROR.SCAN_UNKNOWN_FORMAT');
        }
      })
      .catch(UIUtils.onError('ERROR.SCAN_UNKNOWN_FORMAT'));
    })
    .catch(UIUtils.onError('ERROR.SCAN_FAILED'));
  };

  ////////////////////////////////////////
  // Show Help tour
  ////////////////////////////////////////

  $scope.createHelptipScope = function(isTour) {
    if (!isTour && ($rootScope.tour || !$rootScope.settings.helptip.enable || UIUtils.screen.isSmall())) {
      return; // avoid other helptip to be launched (e.g. csWallet)
    }
    // Create a new scope for the tour controller
    var helptipScope = $scope.$new();
    $controller('HelpTipCtrl', { '$scope': helptipScope});
    return helptipScope;
  };

  $scope.startHelpTour = function(skipClearCache) {
    $rootScope.tour = true; // to avoid other helptip to be launched (e.g. csWallet)

    //
    if (!skipClearCache) {
      $ionicHistory.clearHistory();
      return $ionicHistory.clearCache()
        .then(function() {
          $scope.startHelpTour(true/*continue*/);
        });
    }

    var helptipScope = $scope.createHelptipScope(true);
    return helptipScope.startHelpTour()
    .then(function() {
      helptipScope.$destroy();
      delete $rootScope.tour;
    })
    .catch(function(err){
      delete $rootScope.tour;
    });
  };

  ////////////////////////////////////////
  // Login & wallet
  ////////////////////////////////////////

  $scope.isLogin = function() {
    return $scope.login;
  };

  $scope.showProfilePopover = function(event) {
    return UIUtils.popover.show(event, {
      templateUrl :'templates/common/popover_profile.html',
      scope: $scope,
      autoremove: true,
      afterShow: function(popover) {
        $scope.profilePopover = popover;
        $timeout(function() {
          UIUtils.ink({selector: '#profile-popover .ink, #profile-popover .ink-dark'});
        }, 100);
      }
    });
  };

  $scope.closeProfilePopover = function() {
    if ($scope.profilePopover && $scope.profilePopover.isShown()) {
      $timeout(function(){$scope.profilePopover.hide();});
    }
  };

  // Load wallet data (after login)
  $scope.loadWalletData = function(options) {
    return csWallet.loadData(options)

      .then(function(walletData) {
        if (walletData) {
          $rootScope.walletData = walletData;
          return walletData;
        }
        else { // cancel login
          throw 'CANCELLED';
        }
      });
  };

  // Login and load wallet
  $scope.loadWallet = function(options) {

    // Make sure the platform is ready
    if (!csPlatform.isStarted()) {
      return csPlatform.ready().then(function(){
        return $scope.loadWallet(options);
      });
    }

    options = options || {};

    // If need auth
    if (options.auth && !csWallet.isAuth()) {
      return csWallet.auth(options)
        .then(function (walletData) {
          if (walletData) {
            // Force full load, even if min data asked
            // Because user can wait when just filled login (by modal)
            if (options && options.minData) options.minData = false;
            return $scope.loadWalletData(options);
          }
          else { // failed to auth
            throw 'CANCELLED';
          }
        });
    }

    // If need login
    else if (!csWallet.isLogin()) {
      return csWallet.login(options)
        .then(function (walletData) {
          if (walletData) {
            // Force full load, even if min data asked
            // Because user can wait when just filled login (by modal)
            if (options && options.minData) options.minData = false;
            return $scope.loadWalletData(options);
          }
          else { // failed to login
            throw 'CANCELLED';
          }
        });
    }

    // Laready login ro auth
    else if (!csWallet.data.loaded) {
      return $scope.loadWalletData(options);
    }
    else {
      return $q.when(csWallet.data);
    }
  };

  // Login and go to a state (or wallet if not)
  $scope.loginAndGo = function(state, options) {
    $scope.closeProfilePopover();

    state = state || 'app.view_wallet';

    if (!csWallet.isLogin()) {

      // Make sure to protect login modal, if HTTPS enable - fix #340
      if (csConfig.httpsMode && $window.location && $window.location.protocol !== 'https:') {
        var href = $window.location.href;
        var hashIndex = href.indexOf('#');
        var rootPath = (hashIndex != -1) ? href.substr(0, hashIndex) : href;
        rootPath = 'https' + rootPath.substr(4);
        href = rootPath + $state.href(state);
        if (csConfig.httpsModeDebug) {
          console.debug('[httpsMode] --- Should redirect to: ' + href);
          // continue
        }
        else {
          $window.location.href = href;
          return;
        }

      }

      return csWallet.login(options)
        .then(function(){
          return $state.go(state, options);
        })
        .then(UIUtils.loading.hide);
    }
    else {
      return $state.go(state, options);
    }
  };

  // Logout
  $scope.logout = function(options) {
    options = options || {};
    if (!options.force && $scope.profilePopover) {
      // Make the popover if really closed, to avoid UI refresh on popover buttons
      return $scope.profilePopover.hide()
        .then(function(){
          options.force = true;
          return $scope.logout(options);
        });
    }
    if (options.askConfirm) {
      return UIUtils.alert.confirm('CONFIRM.LOGOUT')
        .then(function(confirm) {
          if (confirm) {
            options.askConfirm=false;
            return $scope.logout(options);
          }
        });
    }

    UIUtils.loading.show();
    return csWallet.logout()
      .then(function() {
        $ionicSideMenuDelegate.toggleLeft();
        $ionicHistory.clearHistory();

        return $ionicHistory.clearCache()
          .then(function() {
            return $scope.showHome();
          });
      })
      .catch(UIUtils.onError());
  };

  // If connected and same pubkey
  $scope.isUserPubkey = function(pubkey) {
    return csWallet.isUserPubkey(pubkey);
  };

  // add listener on wallet event
  csWallet.api.data.on.login($scope, function(walletData, deferred) {
    $scope.login = true;
    $rootScope.walletData = walletData || {};
    return deferred ? deferred.resolve() : $q.when();
  });
  csWallet.api.data.on.logout($scope, function() {
    $scope.login = false;
    $rootScope.walletData = {};
  });
  csWallet.api.data.on.auth($scope, function() {
    $scope.auth = true;
  });
  csWallet.api.data.on.unauth($scope, function() {
    $scope.auth = false;
  });

  ////////////////////////////////////////
  // Useful modals
  ////////////////////////////////////////

  // Open transfer modal
  $scope.showTransferModal = function(parameters) {
    return $scope.loadWallet()
    .then(function(walletData){
      UIUtils.loading.hide();
      if (walletData) {
        return Modals.showTransfer(parameters);
      }
    })
    .then(function(result){
      if (result){
        return $timeout(function(){
          return UIUtils.toast.show('INFO.TRANSFER_SENT');
        }, 10);
      }
    });
  };

  $scope.showAboutModal = function() {
    return Modals.showAbout();
  };

  $scope.showJoinModal = function() {
    $scope.closeProfilePopover();
    return Modals.showJoin()
      .then(function(res){
        if (!res) return;
        return (res.accountType == 'member') ?
          Modals.showJoinMember(res) :
          Modals.showJoinWallet(res);
      });
  };

  $scope.showSettings = function() {
    $scope.closeProfilePopover();
    return $state.go('app.settings');
  };

  $scope.showHelpModal = function(parameters) {
    return Modals.showHelp(parameters);
  };

  ////////////////////////////////////////
  // Change node (expert mode)
  ////////////////////////////////////////

  $scope.showNodeListPopover = function(event) {
    return UIUtils.popover.show(event, {
      templateUrl: 'templates/network/popover_peer_info.html',
      autoremove: true,
      scope: $scope.$new(true)
    });
  };

  ////////////////////////////////////////
  // Layout Methods
  ////////////////////////////////////////
  $scope.showFab = function(id, timeout) {
    UIUtils.motion.toggleOn({selector: '#'+id + '.button-fab'}, timeout);
  };

  $scope.hideFab = function(id, timeout) {
    UIUtils.motion.toggleOff({selector: '#'+id + '.button-fab'}, timeout);
  };

  // Could be override by subclass
  $scope.doMotion = function(options) {
    return $scope.motion.show(options);
  };
}

function AboutController($scope, csConfig) {
  'ngInject';
  $scope.config = csConfig;
}

function HomeController($scope, $state, $timeout, $ionicHistory, csPlatform, csCurrency) {
  'ngInject';

  $scope.loading = true;

  $scope.enter = function(e, state) {
    if (state && state.stateParams && state.stateParams.error) { // Query parameter
      $scope.error = state.stateParams.error;
      $scope.node =  csCurrency.data.node;
      $scope.loading = false;
      $ionicHistory.nextViewOptions({
        disableAnimate: true,
        disableBack: true,
        historyRoot: true
      });
      $state.go('app.home', {error: undefined}, {
        reload: false,
        inherit: true,
        notify: false});
    }
    else {
      // Start platform
      csPlatform.ready()
        .then(function() {
          $scope.loading = false;
        })
        .catch(function(err) {
          $scope.node =  csCurrency.data.node;
          $scope.loading = false;
          $scope.error = err;
        });
    }
  };
  $scope.$on('$ionicView.enter', $scope.enter);

  $scope.reload = function() {
    $scope.loading = true;
    delete $scope.error;

    $timeout($scope.enter, 200);
  };

  /**
   * Catch click for quick fix
   * @param event
   */
  $scope.doQuickFix = function(event) {
    if (event == 'settings') {
      $ionicHistory.nextViewOptions({
        historyRoot: true
      });
      $state.go('app.settings');
    }
  };

  // For DEV ONLY
  /*$timeout(function() {
    $scope.loginAndGo();
  }, 500);*/
}
<|endoftext|>


<commit_before>// For an introduction to the Blank template, see the following documentation:
// http://go.microsoft.com/fwlink/?LinkId=232509
(function () {
    "use strict";

    WinJS.Binding.optimizeBindingReferences = true;

    var app = WinJS.Application;
    var activation = Windows.ApplicationModel.Activation;

    app.onactivated = function (args) {
        if (args.detail.kind === activation.ActivationKind.launch) {
            if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                // TODO: This application has been newly launched. Initialize
                // your application here.
            } else {
                // TODO: This application has been reactivated from suspension.
                // Restore application state here.
            }
            args.setPromise(WinJS.UI.processAll());
        }
    };

    app.oncheckpoint = function (args) {
        // TODO: This application is about to be suspended. Save any state
        // that needs to persist across suspensions here. You might use the
        // WinJS.Application.sessionState object, which is automatically
        // saved and restored across suspension. If you need to complete an
        // asynchronous operation before your application is suspended, call
        // args.setPromise().
    };

    var x = new ToTypeScriptD.Native.ClassWithEventHandler();
    x.onsomethinghappened;

    app.start();
})();
//# sourceMappingURL=default.js.map
<commit_msg>removing js file that was converted to a ts file<commit_after><|endoftext|>


<commit_before>(function($){var el;var settings={};var methods={init:function(options){el=this;settings={token:false,query_param:'query'};if(options){$.extend(settings,options);}
if(!settings.token||settings.query_param==''){return this;}
$.getJSON('http://tapirgo.com/api/1/search.json?token='+settings.token+'&query='+paramValue(settings.query_param)+'&callback=?',function(data){if(settings['complete']){settings.complete()}
$.each(data,function(key,val){el.append('

'+val.title+'

'+val.summary+'

');});});return this;}};function paramValue(query_param){var results=new RegExp('[\\?&]'+query_param+'=([^&#]*)').exec(window.location.href);return results?results[1]:false;}
$.fn.tapir=function(method){if(methods[method]){return methods[method].apply(this,Array.prototype.slice.call(arguments,1));}else if(typeof method==='object'||!method){return methods.init.apply(this,arguments);}else{$.error('Method '+method+' does not exist on jQuery.tapir');}};})(jQuery);
<commit_msg>Update jquery-tapir.min.js<commit_after>(function($){var el;var settings={};var methods={init:function(options){el=this;settings={token:false,query_param:'query'};if(options){$.extend(settings,options);}
if(!settings.token||settings.query_param==''){return this;}
$.getJSON('http://tapirgo.com/api/1/search.json?token='+570e9e6314ad6644b943ab78+'&query='+paramValue(settings.query_param)+'&callback=?',function(data){if(settings['complete']){settings.complete()}
$.each(data,function(key,val){el.append('

'+val.title+'

'+val.summary+'

');});});return this;}};function paramValue(query_param){var results=new RegExp('[\\?&]'+query_param+'=([^&#]*)').exec(window.location.href);return results?results[1]:false;}
$.fn.tapir=function(method){if(methods[method]){return methods[method].apply(this,Array.prototype.slice.call(arguments,1));}else if(typeof method==='object'||!method){return methods.init.apply(this,arguments);}else{$.error('Method '+method+' does not exist on jQuery.tapir');}};})(jQuery);
<|endoftext|>


<commit_before>/**
 * @package assets
 */

(function($) {

	/**
	 * Notify combines multiple system messages to an interface that focusses
	 * on a single message at a time and offers a navigation to move between message.
	 *
	 * @name $.symphonyNotify
	 * @class
	 *
	 * @param {Object} options An object specifying containing the attributes specified below
	 * @param {String} [options.items='p.notice'] Selector to find messages
	 * @param {String} [options.storage='symphony.notify.root'] Namespace used for local storage
	 *
	 * @example

			$('#messages').symphonyNotify();
	 */
	$.fn.symphonyNotify = function(options) {
		var objects = this,
			settings = {
				items: 'p.notice',
				storage: 'symphony.notify.' + Symphony.Context.get('root').replace('http://', '')
			};

		$.extend(settings, options);

	/*-----------------------------------------------------------------------*/

		Symphony.Language.add({
			'Ignore?': false,
			'next': false,
			'at': false
		});

	/*-------------------------------------------------------------------------
		Events
	-------------------------------------------------------------------------*/

		// Attach message
		objects.on('attach.notify', function attachMessage(event, message, type) {
			var object = $(this),
				notifier = object.find('div.notifier'),
				items = notifier.find(settings.items),
				item, storage;

			notifier.trigger('attachstart.notify');

			// Create item
			item = $('
', {
				html: message.replace(Symphony.Language.get('at') + ' ', ''),
				'class': type
			}).addClass('notice active').symphonyTimeAgo();

			// Add ignore link to notices)
			if(!item.is('.error') && !item.is('.success') && !item.is('.protected')) {
				item.html(item.html() + ' ' + Symphony.Language.get('Ignore?') + '');
			}

			// Add navigator
			$('', {
				text: Symphony.Language.get('next')
			}).hide().appendTo(item);

			// Load exclusion rules
			if(Symphony.Support.localStorage === true) {
				storage = $.parseJSON(window.localStorage[settings.storage]) || [];
			}

			// Prepend item
			if($.inArray(item.text(), storage) == -1) {
				items.removeClass('active');
				item.addClass('active').prependTo(notifier);
				notifier.scrollTop(0);

				notifier.trigger('attachstop.notify', [item]);
			}
			else {
				notifier.trigger('attachcancel.notify', [item]);
			}
		});

		// Detach message
		objects.on('detach.notify', settings.items, function detachMessage(event) {
			var item = $(this),
				notifier = item.parents('div.notifier');

			notifier.trigger('detachstart.notify', [item]);

			// Prepare item removal
			notifier.one('movestop.notify', function(event) {
				var notifier = $(this),
					offset = notifier.scrollTop();

				// Adjust offset
				if(offset > 0) {
					notifier.scrollTop(offset - item.outerHeight());
				}

				// Remove item
				item.remove();

				notifier.trigger('detachstop.notify', [item]);
			});

			// Fade item
			item.animate({
				opacity: 0
			}, 'normal', function removeItem() {

				// No other items
				if(item.siblings().length == 0) {
					notifier.trigger('resize.notify');
				}

				// More item
				else {
					notifier.trigger('move.notify');
				}

				// Remove item
				item.remove();
				notifier.trigger('detachstop.notify', [item]);
			});
		});

		// Resize notifier
		objects.on('resize.notify attachstop.notify', 'div.notifier', function resizeNotifer(event, item) {
			var notifier = $(this),
				active = item || notifier.find('.active:not(:animated)');

			// Adjust height
			if(!notifier.is('.constructing')) {
				notifier.show().animate({
					height: active.innerHeight() || 0
				}, 100);
			}
		});

		// Count messages
		objects.on('attachstop.notify detachstop.notify', 'div.notifier', function toggleNavigator(event) {
			var notifier = $(this),
				items = notifier.find(settings.items);

			// Hide navigator
			if(items.length == 1) {
				items.find('nav').hide();
			}

			// Show navigator
			else {
				items.find('nav').show();
			}
		});

		// Next message
		objects.on('click', 'nav', function switchMessage(event) {
			var nav = $(this),
				notifier = $(this).parents('div.notifier');

			// Move messages
			notifier.trigger('move.notify');
		});

		// Move messages
		objects.on('move.notify', 'div.notifier', function moveMessage(event) {
			var notifier = $(this),
				current = notifier.find('.active'),
				next = current.next(settings.items),
				from = current.outerHeight(),
				offset;

			notifier.trigger('movestart.notify');

			// Deactivate current message
			current.removeClass('active');

			// Activate next message and get offset
			if(next.length > 0) {
				next.addClass('active');
				offset = notifier.scrollTop() + from;
			}
			else {
				next = notifier.find(settings.items).first().addClass('active');
				offset = 0;
			}

			// If next's height is smaller, resize first
			if(next.outerHeight() < from) {
				notifier.trigger('resize.notify');
			}

			// Move to next message
			notifier.animate({
				scrollTop: offset
			}, 'fast', function stopMovingMessage() {
				notifier.trigger('movestop.notify');
			});
		});

		// Ignore message
		objects.on('click', 'a.ignore', function ignoreMessage(event) {
			var ignore = $(this),
				item = ignore.parents(settings.items),
				notifier = item.parents('div.notifier'),
				text = item.text(),
				storage;

			// Store exclusion rule
			if(Symphony.Support.localStorage === true) {
				// Put in a try/catch incase we exceed storage space
				try {
					storage = $.parseJSON(window.localStorage[settings.storage]) || [];
					storage.push(text);
					window.localStorage[settings.storage] = JSON.stringify(storage);
				}
				catch(e) {
					window.onerror(e.message);
				}
			}

			// Remove item
			item.trigger('detach.notify');
		});

	/*-------------------------------------------------------------------------
		Initialisation
	-------------------------------------------------------------------------*/

		// Build interface
		objects.each(function initNotify() {
			var object = $(this),
				notifier = $('
').prependTo(object),
				items = $(object.find(settings.items).get().reverse());

			// Construct notifier
			notifier.addClass('constructing');
			notifier.height(items.last().innerHeight());
			items.each(function buildMessages() {
				var item = $(this).remove(),
					message = item.html(),
					type = item.attr('class');

				object.trigger('attach.notify', [message, type]);
			});

			// No messages (based on exclusion list)
			if(notifier.find(settings.items).length == 0) {
				notifier.removeClass('constructing').hide();
			}

			// Finish construction
			else {
				notifier.removeClass('constructing').trigger('resize.notify');
			}

			// Update relative times in system messages
			setInterval(function updateRelativeTimes() {
				$('header p.notice').symphonyTimeAgo();
			}, 60000);
		});

	/*-----------------------------------------------------------------------*/

		return objects;
	};

})(jQuery.noConflict());
<commit_msg>Change logic of Notify initialisation<commit_after>/**
 * @package assets
 */

(function($) {

	/**
	 * Notify combines multiple system messages to an interface that focusses
	 * on a single message at a time and offers a navigation to move between message.
	 *
	 * @name $.symphonyNotify
	 * @class
	 *
	 * @param {Object} options An object specifying containing the attributes specified below
	 * @param {String} [options.items='p.notice'] Selector to find messages
	 * @param {String} [options.storage='symphony.notify.root'] Namespace used for local storage
	 *
	 * @example

			$('#messages').symphonyNotify();
	 */
	$.fn.symphonyNotify = function(options) {
		var objects = this,
			settings = {
				items: 'p.notice',
				storage: 'symphony.notify.' + Symphony.Context.get('root').replace('http://', '')
			};

		$.extend(settings, options);

	/*-----------------------------------------------------------------------*/

		Symphony.Language.add({
			'Ignore?': false,
			'next': false,
			'at': false
		});

	/*-------------------------------------------------------------------------
		Events
	-------------------------------------------------------------------------*/

		// Attach message
		objects.on('attach.notify', function attachMessage(event, message, type) {
			var object = $(this),
				notifier = object.find('div.notifier'),
				items = notifier.find(settings.items),
				item, storage;

			notifier.trigger('attachstart.notify');

			// Create item
			item = $('
', {
				html: message.replace(Symphony.Language.get('at') + ' ', ''),
				'class': type
			}).addClass('notice active').symphonyTimeAgo();

			// Add ignore link to notices)
			if(!item.is('.error') && !item.is('.success') && !item.is('.protected')) {
				item.html(item.html() + ' ' + Symphony.Language.get('Ignore?') + '');
			}

			// Add navigator
			$('', {
				text: Symphony.Language.get('next')
			}).hide().appendTo(item);

			// Load exclusion rules
			if(Symphony.Support.localStorage === true) {
				storage = $.parseJSON(window.localStorage[settings.storage]) || [];
			}

			// Prepend item
			if($.inArray(item.text(), storage) == -1) {
				items.removeClass('active');
				item.addClass('active').prependTo(notifier);
				notifier.scrollTop(0);

				notifier.trigger('attachstop.notify', [item]);
			}
			else {
				notifier.trigger('attachcancel.notify', [item]);
			}
		});

		// Detach message
		objects.on('detach.notify', settings.items, function detachMessage(event) {
			var item = $(this),
				notifier = item.parents('div.notifier');

			notifier.trigger('detachstart.notify', [item]);

			// Prepare item removal
			notifier.one('movestop.notify', function(event) {
				var notifier = $(this),
					offset = notifier.scrollTop();

				// Adjust offset
				if(offset > 0) {
					notifier.scrollTop(offset - item.outerHeight());
				}

				// Remove item
				item.remove();

				notifier.trigger('detachstop.notify', [item]);
			});

			// Fade item
			item.animate({
				opacity: 0
			}, 'normal', function removeItem() {

				// No other items
				if(item.siblings().length == 0) {
					notifier.trigger('resize.notify');
				}

				// More item
				else {
					notifier.trigger('move.notify');
				}

				// Remove item
				item.remove();
				notifier.trigger('detachstop.notify', [item]);
			});
		});

		// Resize notifier
		objects.on('resize.notify attachstop.notify', 'div.notifier', function resizeNotifer(event, item) {
			var notifier = $(this),
				active = item || notifier.find('.active:not(:animated)');

			// Adjust height
			if(!notifier.is('.constructing')) {
				notifier.show().animate({
					height: active.innerHeight() || 0
				}, 100);
			}
		});

		// Count messages
		objects.on('attachstop.notify detachstop.notify', 'div.notifier', function toggleNavigator(event) {
			var notifier = $(this),
				items = notifier.find(settings.items);

			// Hide navigator
			if(items.length == 1) {
				items.find('nav').hide();
			}

			// Show navigator
			else {
				items.find('nav').show();
			}
		});

		// Next message
		objects.on('click', 'nav', function switchMessage(event) {
			var nav = $(this),
				notifier = $(this).parents('div.notifier');

			// Move messages
			notifier.trigger('move.notify');
		});

		// Move messages
		objects.on('move.notify', 'div.notifier', function moveMessage(event) {
			var notifier = $(this),
				current = notifier.find('.active'),
				next = current.next(settings.items),
				from = current.outerHeight(),
				offset;

			notifier.trigger('movestart.notify');

			// Deactivate current message
			current.removeClass('active');

			// Activate next message and get offset
			if(next.length > 0) {
				next.addClass('active');
				offset = notifier.scrollTop() + from;
			}
			else {
				next = notifier.find(settings.items).first().addClass('active');
				offset = 0;
			}

			// If next's height is smaller, resize first
			if(next.outerHeight() < from) {
				notifier.trigger('resize.notify');
			}

			// Move to next message
			notifier.animate({
				scrollTop: offset
			}, 'fast', function stopMovingMessage() {
				notifier.trigger('movestop.notify');
			});
		});

		// Ignore message
		objects.on('click', 'a.ignore', function ignoreMessage(event) {
			var ignore = $(this),
				item = ignore.parents(settings.items),
				notifier = item.parents('div.notifier'),
				text = item.text(),
				storage;

			// Store exclusion rule
			if(Symphony.Support.localStorage === true) {
				// Put in a try/catch incase we exceed storage space
				try {
					storage = $.parseJSON(window.localStorage[settings.storage]) || [];
					storage.push(text);
					window.localStorage[settings.storage] = JSON.stringify(storage);
				}
				catch(e) {
					window.onerror(e.message);
				}
			}

			// Remove item
			item.trigger('detach.notify');
		});

	/*-------------------------------------------------------------------------
		Initialisation
	-------------------------------------------------------------------------*/

		// Build interface
		objects.each(function initNotify() {
			var object = $(this),
				notifier = $('
').hide().prependTo(object),
				items = $(object.find(settings.items).get().reverse());

			// Construct notifier
			notifier.addClass('constructing');
			notifier.height(items.last().innerHeight());
			items.each(function buildMessages() {
				var item = $(this).remove(),
					message = item.html(),
					type = item.attr('class');

				object.trigger('attach.notify', [message, type]);
			});

			// Resize notifier
			if(notifier.find(settings.items).length > 0) {
				notifier.removeClass('constructing').trigger('resize.notify');
			}

			notifier.removeClass('constructing');

			// Update relative times in system messages
			setInterval(function updateRelativeTimes() {
				$('header p.notice').symphonyTimeAgo();
			}, 60000);
		});

	/*-----------------------------------------------------------------------*/

		return objects;
	};

})(jQuery.noConflict());
<|endoftext|>


<commit_before>'use strict';

describe('Controller: AdminAccountCtrl', function () {

  // load the controller's module
  beforeEach(module('fahrtenbuchApp'));
  var AdminAccountCtrl, $scope, $location, $httpBackend, fakeResponse;

  // Initialize the controller and a mock scope
  beforeEach(inject(function ($controller, $rootScope, _$location_, _$httpBackend_) {

    $scope = $rootScope.$new();
    $location = _$location_;
    $httpBackend = _$httpBackend_;
    fakeResponse = '';

    AdminAccountCtrl = $controller('AdminAccountCtrl', {
      $scope: $scope
    });

    $location.path('/admin/account');
    expect($location.path()).toBe('/admin/account');

  	$httpBackend.expectGET('/api/accounts').respond([{_id: 1}, {_id: 2}, {_id: 3}]);
  	$httpBackend.when('GET', 'app/admin/admin.account.html').respond(fakeResponse);
    $httpBackend.flush();
  }));

	it('call AdminAccountCtrl', function () {
	  expect($scope.accounts).toBeDefined();
	  expect($scope.accounts).toEqual([{_id: 1}, {_id: 2}, {_id: 3}]);
	});

	it('test add function', function () {
    $scope.addAccount({ name: "test" });
  	$httpBackend.expectPOST('/api/accounts').respond(fakeResponse);
    $httpBackend.flush();
	});

	it('test delete function', function () {
    $scope.deleteAccount($scope.accounts[0]);
    $httpBackend.expectDELETE('/api/accounts/1').respond(fakeResponse);
    $httpBackend.flush();

    expect($scope.accounts).toEqual([{_id: 2}, {_id: 3}]);
	});
});

describe('Controller: AdminUserCtrl', function () {

  // load the controller's module
  beforeEach(module('fahrtenbuchApp'));
  var AdminUserCtrl, $scope, $location, $httpBackend, fakeResponse;

  // Initialize the controller and a mock scope
  beforeEach(inject(function ($controller, $rootScope, _$location_, _$httpBackend_) {

    $scope = $rootScope.$new();
    $location = _$location_;
    $httpBackend = _$httpBackend_;
    fakeResponse = '';

    AdminUserCtrl = $controller('AdminUserCtrl', {
      $scope: $scope
    });

    $location.path('/admin/user');
    expect($location.path()).toBe('/admin/user');

  	$httpBackend.expectGET('/api/users').respond([{_id: 1}, {_id: 2}, {_id: 3}]);
  	$httpBackend.when('GET', 'app/admin/admin.user.html').respond(fakeResponse);
    $httpBackend.flush();
  }));

// 	it('call AdminUserCtrl', function () {
// 	  expect($scope.users).toBeDefined();
// 	  expect($scope.users).toEqual([{_id: 1}, {_id: 2}, {_id: 3}]);
// 	});

// 	it('test delete function', function () {
//     $scope.delete($scope.users[0]);
//     $httpBackend.expectDELETE('/api/users/1').respond(fakeResponse);
//     $httpBackend.flush();

//     expect($scope.users).toEqual([{_id: 2}, {_id: 3}]);
// 	});
});

//
// @todo AdminCarCtrl
// @todo AdminCarAddCtrl

<commit_msg>push test 6<commit_after>'use strict';

describe('Controller: AdminAccountCtrl', function () {

  // load the controller's module
  beforeEach(module('fahrtenbuchApp'));
  var AdminAccountCtrl, $scope, $location, $httpBackend, fakeResponse;

  // Initialize the controller and a mock scope
  beforeEach(inject(function ($controller, $rootScope, _$location_, _$httpBackend_) {

    $scope = $rootScope.$new();
    $location = _$location_;
    $httpBackend = _$httpBackend_;
    fakeResponse = '';

    AdminAccountCtrl = $controller('AdminAccountCtrl', {
      $scope: $scope
    });

    $location.path('/admin/account');
    expect($location.path()).toBe('/admin/account');

  	$httpBackend.expectGET('/api/accounts').respond([{_id: 1}, {_id: 2}, {_id: 3}]);
  	$httpBackend.when('GET', 'app/admin/admin.account.html').respond(fakeResponse);
    $httpBackend.flush();
  }));

	it('call AdminAccountCtrl', function () {
	  expect($scope.accounts).toBeDefined();
	  expect($scope.accounts).toEqual([{_id: 1}, {_id: 2}, {_id: 3}]);
	});

	it('test add function', function () {
    $scope.addAccount({ name: "test" });
  	$httpBackend.expectPOST('/api/accounts').respond(fakeResponse);
    $httpBackend.flush();
	});

	it('test delete function', function () {
    $scope.deleteAccount($scope.accounts[0]);
    $httpBackend.expectDELETE('/api/accounts/1').respond(fakeResponse);
    $httpBackend.flush();

    expect($scope.accounts).toEqual([{_id: 2}, {_id: 3}]);
	});
});

describe('Controller: AdminUserCtrl', function () {

  // load the controller's module
  beforeEach(module('fahrtenbuchApp'));
  var AdminUserCtrl, $scope, $location, $httpBackend, fakeResponse;

  // Initialize the controller and a mock scope
  beforeEach(inject(function ($controller, $rootScope, _$location_, _$httpBackend_) {

    $scope = $rootScope.$new();
    $location = _$location_;
    $httpBackend = _$httpBackend_;
    fakeResponse = '';

    AdminUserCtrl = $controller('AdminUserCtrl', {
      $scope: $scope
    });

    $location.path('/admin/user');
    expect($location.path()).toBe('/admin/user');

  	$httpBackend.expectGET('/api/users').respond([{_id: 1}, {_id: 2}, {_id: 3}]);
  	$httpBackend.when('GET', 'app/admin/admin.user.html').respond(fakeResponse);
    $httpBackend.flush();
  }));

// 	it('call AdminUserCtrl', function () {
// 	  expect($scope.users).toBeDefined();
// 	  expect($scope.users).toEqual([{_id: 1}, {_id: 2}, {_id: 3}]);
// 	});

// 	it('test delete function', function () {
//     $scope.delete($scope.users[0]);
//     $httpBackend.expectDELETE('/api/users/1').respond(fakeResponse);
//     $httpBackend.flush();

//     expect($scope.users).toEqual([{_id: 2}, {_id: 3}]);
// 	});
});

// @todo AdminCarCtrl
// @todo AdminCarAddCtrl

<|endoftext|>


<commit_before>(function( $ ){

	$.fn.clickHold = function( callback ) {

		var intervalTimer;

		return this.mousedown(function(){
			callback();
			intervalTimer = setInterval(function(){ callback(); }, 100);
		}).bind('mouseup mouseout', function(){
			clearInterval(intervalTimer);
		});

	}

})( jQuery );<commit_msg>Exit bind() being called twice - once on mouseup, again on mouseout so added active flag to prevent double-running Added completeCallback - gets executed on mouseup/mouseout<commit_after>(function( $ ){

	$.fn.clickHold = function( callback, completeCallback ) {

		var intervalTimer;
		var active;

		return this.mousedown(function(){
			active = true;
			callback();
			intervalTimer = setInterval(function(){ callback(); }, 100);
		}).bind('mouseup mouseout', function(){
			if(active)
			{
				active = false;
				clearInterval(intervalTimer);

				if(typeof completeCallback !== 'undefined')
				{
					completeCallback();
				}
			}
		});

	}

})( jQuery );<|endoftext|>


<commit_before>import tld_txt from 'raw-loader!../data/tlds-alpha-by-domain.txt'

const tldInFile = /^[a-zA-Z]/;

const protocol = /^(about:|.*:\/\/)/;
const urlPattern = /.+\.(\w+)(?:[\/:?#]*)?/;
const tlds = tld_txt.split('\n').filter(t => t && tldInFile.test(t)).map(t => t.toLowerCase());

function isUrl(term)
{
  if(!term || term.includes(' ')) return false;
  if(protocol.test(term)) return true;
  let [,tld] = urlPattern.exec(term)||[];
  return tld && tlds.includes(tld)
};

export { isUrl, protocol}<commit_msg>improved url recognition<commit_after>import tld_txt from 'raw-loader!../data/tlds-alpha-by-domain.txt'

const tldInFile = /^[a-zA-Z]/;

const protocol = /^(about:|.*:\/\/)/;
const tlds = tld_txt.split('\n').filter(t => t && tldInFile.test(t)).map(t => t.toLowerCase());

function isUrl(term)
{
  if(!term || term.includes(' ')) return false;
  if(protocol.test(term)) return true;
  try {
    const {hostname, port} = new URL('http://'+term);
    if(port) return true;
    const tldDot = hostname.lastIndexOf('.');
    if(tldDot < 0) return false;
    let tld = hostname.substr(tldDot+1);
    console.log(tld);
    return tlds.includes(tld)
  }
  catch(err) {
    return false;
  }
}

export { isUrl, protocol}<|endoftext|>