<commit_before>;(function ($, window, document, undefined) {

    'use strict';

    /** Default values */
    var pluginName = 'mediumInsert',
        defaults = {
            editor: null,
            enabled: true,
            blocks: 'p, h1, h2, h3, h4, h5, h6, ol, ul, blockquote',
            addons: {
              images: {
                  label: ''
              }
            }
        };

    /**
     * Capitalize first character
     *
     * @param {string} str
     * @return {string}
     */

    function ucfirst (str) {
        return str.charAt(0).toUpperCase() + str.slice(1);
    }

    /**
     * Core plugin's object
     *
     * Sets options, variables and calls init() function
     *
     * @constructor
     * @param {DOM} el - DOM element to init the plugin on
     * @param {object} options - Options to override defaults
     * @return {void}
     */

    function Core (el, options) {
        this.el = el;
        this.$el = $(el);
        this.templates = window.MediumInsert.Templates;

        this.options = $.extend(true, {}, defaults, options);

        this._defaults = defaults;
        this._name = pluginName;

        // Extend editor's functions
        if (options && options.editor) {
            options.editor._serialize = options.editor.serialize;
            options.editor._deactivate = options.editor.deactivate;
            options.editor._activate = options.editor.activate;
            options.editor.serialize = this.editorSerialize;
            options.editor.deactivate = this.editorDeactivate;
            options.editor.activate = this.editorActivate;
        }

        this.init();
    }

    /**
     * Initialization
     *
     * @return {void}
     */

    Core.prototype.init = function () {
        this.$el.addClass('medium-editor-insert-plugin');

        if (typeof this.options.addons !== 'object' || Object.keys(this.options.addons).length === 0) {
            this.disable();
        }

        this.initAddons();
        this.clean();
        this.addButtons();
        this.events();
    };

    /**
     * Event listeners
     *
     * @return {void}
     */

    Core.prototype.events = function () {
        this.$el
            .on('dragover drop', function (e) {
                e.preventDefault();
            })
            .on('blur', $.proxy(this, 'addEditorPlaceholder'))
            .on('keyup click', $.proxy(this, 'showButtons'))
            .on('selectstart mousedown', '.medium-insert, .medium-insert-buttons', $.proxy(this, 'disableSelection'))
            .on('keydown', $.proxy(this, 'fixSelectAll'))
            .on('click', '.medium-insert-buttons-show', $.proxy(this, 'toggleAddons'))
            .on('click', '.medium-insert-action', $.proxy(this, 'addonAction'));
    };

    /**
     * Extend editor's serialize function
     *
     * @return {object} Serialized data
     */

    Core.prototype.editorSerialize = function () {
        var data = this._serialize();

        $.each(data, function (key) {
            var $data = $('
').html(data[key].value);

            $data.find('.medium-insert-buttons').remove();

            data[key].value = $data.html();
        });

        return data;
    };

    /**
     * Extend editor's deactivate function to deactivate this plugin too
     *
     * @return {void}
     */

    Core.prototype.editorDeactivate = function () {
        this._deactivate();

        $.each(this.elements, function (key, el) {
            $(el).data('plugin_' + pluginName).disable();
        });
    };

    /**
     * Extend editor's activate function to activate this plugin too
     *
     * @return {void}
     */

    Core.prototype.editorActivate = function () {
        this._activate();

        $.each(this.elements, function (key, el) {
            $(el).data('plugin_' + pluginName).enable();
        });
    };

    /**
     * Deselects selected text
     *
     * @return {void}
     */

    Core.prototype.deselect = function () {
        document.getSelection().removeAllRanges();
    };

    /**
     * Disables the plugin
     *
     * @return {void}
     */

    Core.prototype.disable = function () {
        this.options.enabled = false;

        this.$el.find('.medium-insert-buttons').addClass('hide');
    };

    /**
     * Enables the plugin
     *
     * @return {void}
     */

    Core.prototype.enable = function () {
        this.options.enabled = true;

        this.$el.find('.medium-insert-buttons').removeClass('hide');
    };

    /**
     * Disables selectstart mousedown events on plugin elements except images
     *
     * @return {void}
     */

    Core.prototype.disableSelection = function (e) {
        var $el = $(e.target);

        if ($el.is('img') === false || $el.hasClass('medium-insert-buttons-show')) {
            e.preventDefault();
        }
    };

    /**
     * Fix #39
     * For some reason Chrome doesn't "select-all", when the last placeholder is visible.
     * So it's needed to hide it when the user "selects all", and show it again when they presses any other key.
     *
     * @return {boolean} document.execCommand()
     */

    Core.prototype.fixSelectAll = function (e) {
        this.$el.children().last().removeClass('hide');

         if ((e.ctrlKey || e.metaKey) && e.which === 65) {
            e.preventDefault();

            if(this.$el.find('p').text().trim().length === 0) {
              return false;
            }

            this.$el.children().last().addClass('hide');

            return document.execCommand('selectAll', false, null);
        }
    };

    /**
     * Adds .medium-editor-placeholder class to the editor, when its content is empty
     *
     * @return {void}
     */

    Core.prototype.addEditorPlaceholder = function () {
        var $clone = this.$el.clone(),
            cloneHtml;

        $clone.find('.medium-insert').remove();
        cloneHtml = $clone.html().replace(/^\s+|\s+$/g, '');

        if (cloneHtml === '' || cloneHtml === '

') {
            this.$el.addClass('medium-editor-placeholder');
        }
    };

    /**
     * Initialize addons
     *
     * @return {void}
     */

    Core.prototype.initAddons = function () {
        var that = this;

        $.each(this.options.addons, function (addon, options) {
            that.$el[pluginName + ucfirst(addon)](options);
        });
    };

    /**
     * Cleans a content of the editor
     *
     * @return {void}
     */

    Core.prototype.clean = function () {
        var $lastChild = this.$el.children(':last');

        if (this.options.enabled === false) {
            return;
        }

        // Fix #39
        // After deleting all content (ctrl+A and delete) in Firefox, all content is deleted and only
 appears
        // To force placeholder to appear, set

 as content of the $el
        if (this.$el.html() === '' || this.$el.html() === '
') {
            this.$el.html(this.templates['src/js/templates/core-empty-line.hbs']().trim());
        }

        // Fix #29
        // Wrap content text in

 to avoid Firefox problems
        this.$el
            .contents()
            .filter(function () {
                return this.nodeName === '#text' && $.trim($(this).text()) !== '';
            })
            .wrap('
');

        // If last element is non-empty placeholder, add one empty line at the end to force placeholder to appear
        if ($lastChild.hasClass('medium-insert') && $lastChild.find('.medium-insert-placeholder').children().length > 0) {
            this.$el.append(this.templates['src/js/templates/core-empty-line.hbs']().trim());
        }

        // Fix not deleting placeholder in Firefox by removing all empty placeholders
        this.$el.find('.medium-insert-placeholder:empty').each(function () {
            $(this).parent().remove();
        });
    };

    /**
     * Returns HTML template of buttons
     *
     * @return {string} HTML template of buttons
     */

    Core.prototype.getButtons = function () {
        if (this.options.enabled === false) {
            return;
        }

        return this.templates['src/js/templates/core-buttons.hbs']({
            addons: this.options.addons
        }).trim();
    };

    /**
     * Appends buttons at the end of the $el
     *
     * @return {void}
     */

    Core.prototype.addButtons = function () {
        var $buttons = $(this.getButtons());

        this.$el.append($buttons);
    };

    /**
     * Move buttons to current active, empty paragraph and show them
     *
     * @return {void}
     */

    Core.prototype.showButtons = function (e) {
        var $el = $(e.target),
            selection = window.getSelection(),
            range = selection.getRangeAt(0),
            $current = $(range.commonAncestorContainer),
            $buttons = this.$el.find('.medium-insert-buttons'),
            isAddon = false,
            $p = $current.is('p') ? $current : $current.closest('p');

        if ($el.closest('.medium-insert-buttons').length === 0 && $current.closest('.medium-insert-buttons').length === 0) {

            this.$el.find('.medium-insert-active').removeClass('medium-insert-active');

            $.each(this.options.addons, function (addon) {
                if ($el.closest('.medium-insert-'+ addon).length) {
                    $current = $el;
                    $p = $el.closest('.medium-insert-'+ addon);
                    isAddon = true;
                    return;
                }
            });

            if ($p.text().trim() === '') {
                $p.addClass('medium-insert-active');
                $buttons.removeClass('medium-insert-buttons-vertical');

                // Left position is set according to parent paragraph
                // Top position is set according to current active element
                $buttons.css({
                    left: $p.offset().left - parseInt($buttons.find('.medium-insert-buttons-addons').css('left'), 10) - parseInt($buttons.find('.medium-insert-buttons-addons a:first').css('margin-left'), 10),
                    top: $current.offset().top
                });

                if (isAddon) {
                    $buttons.addClass('medium-insert-buttons-vertical');
                }

                $buttons.show();
            } else {
                this.hideButtons();
            }
        }
    };

    /**
     * Hides buttons
     *
     * @returns {void}
     */

    Core.prototype.hideButtons = function () {
        this.$el.find('.medium-insert-buttons').hide();
        this.$el.find('.medium-insert-buttons-addons').hide();
    };

    /**
     * Toggles addons buttons
     *
     * @return {void}
     */

    Core.prototype.toggleAddons = function () {
        this.$el.find('.medium-insert-buttons-addons').toggle();
    };

    /**
     * Hide addons buttons
     *
     * @return {void}
     */

    Core.prototype.hideAddons = function () {
        this.$el.find('.medium-insert-buttons-addons').hide();
    };

    /**
     * Call addon's action
     *
     * @param {Event} e
     * @return {void}
     */

    Core.prototype.addonAction = function (e) {
        var $a = $(e.target).is('a') ? $(e.target) : $(e.target).closest('a'),
            addon = $a.data('addon'),
            action = $a.data('action');

        this.$el.data('plugin_'+ pluginName + ucfirst(addon))[action]();
    };

    /** Plugin initialization */

    $.fn[pluginName] = function (options) {
        return this.each(function () {
            if (!$.data(this, 'plugin_' + pluginName)) {
                // Plugin initialization
                $.data(this, 'plugin_' + pluginName, new Core(this, options));
            } else if (typeof options === 'string' && $.data(this, 'plugin_' + pluginName)[options]) {
                // Method call
                $.data(this, 'plugin_' + pluginName)[options]();
            }
        });
    };

})(jQuery, window, document);
<commit_msg>fix hiding buttons after deleting paragraph<commit_after>;(function ($, window, document, undefined) {

    'use strict';

    /** Default values */
    var pluginName = 'mediumInsert',
        defaults = {
            editor: null,
            enabled: true,
            blocks: 'p, h1, h2, h3, h4, h5, h6, ol, ul, blockquote',
            addons: {
              images: {
                  label: ''
              }
            }
        };

    /**
     * Capitalize first character
     *
     * @param {string} str
     * @return {string}
     */

    function ucfirst (str) {
        return str.charAt(0).toUpperCase() + str.slice(1);
    }

    /**
     * Core plugin's object
     *
     * Sets options, variables and calls init() function
     *
     * @constructor
     * @param {DOM} el - DOM element to init the plugin on
     * @param {object} options - Options to override defaults
     * @return {void}
     */

    function Core (el, options) {
        this.el = el;
        this.$el = $(el);
        this.templates = window.MediumInsert.Templates;

        this.options = $.extend(true, {}, defaults, options);

        this._defaults = defaults;
        this._name = pluginName;

        // Extend editor's functions
        if (options && options.editor) {
            options.editor._serialize = options.editor.serialize;
            options.editor._deactivate = options.editor.deactivate;
            options.editor._activate = options.editor.activate;
            options.editor.serialize = this.editorSerialize;
            options.editor.deactivate = this.editorDeactivate;
            options.editor.activate = this.editorActivate;
        }

        this.init();
    }

    /**
     * Initialization
     *
     * @return {void}
     */

    Core.prototype.init = function () {
        this.$el.addClass('medium-editor-insert-plugin');

        if (typeof this.options.addons !== 'object' || Object.keys(this.options.addons).length === 0) {
            this.disable();
        }

        this.initAddons();
        this.clean();
        this.addButtons();
        this.events();
    };

    /**
     * Event listeners
     *
     * @return {void}
     */

    Core.prototype.events = function () {
        this.$el
            .on('dragover drop', function (e) {
                e.preventDefault();
            })
            .on('blur', $.proxy(this, 'addEditorPlaceholder'))
            .on('keyup click', $.proxy(this, 'showButtons'))
            .on('selectstart mousedown', '.medium-insert, .medium-insert-buttons', $.proxy(this, 'disableSelection'))
            .on('keydown', $.proxy(this, 'fixSelectAll'))
            .on('click', '.medium-insert-buttons-show', $.proxy(this, 'toggleAddons'))
            .on('click', '.medium-insert-action', $.proxy(this, 'addonAction'));
    };

    /**
     * Extend editor's serialize function
     *
     * @return {object} Serialized data
     */

    Core.prototype.editorSerialize = function () {
        var data = this._serialize();

        $.each(data, function (key) {
            var $data = $('
').html(data[key].value);

            $data.find('.medium-insert-buttons').remove();

            data[key].value = $data.html();
        });

        return data;
    };

    /**
     * Extend editor's deactivate function to deactivate this plugin too
     *
     * @return {void}
     */

    Core.prototype.editorDeactivate = function () {
        this._deactivate();

        $.each(this.elements, function (key, el) {
            $(el).data('plugin_' + pluginName).disable();
        });
    };

    /**
     * Extend editor's activate function to activate this plugin too
     *
     * @return {void}
     */

    Core.prototype.editorActivate = function () {
        this._activate();

        $.each(this.elements, function (key, el) {
            $(el).data('plugin_' + pluginName).enable();
        });
    };

    /**
     * Deselects selected text
     *
     * @return {void}
     */

    Core.prototype.deselect = function () {
        document.getSelection().removeAllRanges();
    };

    /**
     * Disables the plugin
     *
     * @return {void}
     */

    Core.prototype.disable = function () {
        this.options.enabled = false;

        this.$el.find('.medium-insert-buttons').addClass('hide');
    };

    /**
     * Enables the plugin
     *
     * @return {void}
     */

    Core.prototype.enable = function () {
        this.options.enabled = true;

        this.$el.find('.medium-insert-buttons').removeClass('hide');
    };

    /**
     * Disables selectstart mousedown events on plugin elements except images
     *
     * @return {void}
     */

    Core.prototype.disableSelection = function (e) {
        var $el = $(e.target);

        if ($el.is('img') === false || $el.hasClass('medium-insert-buttons-show')) {
            e.preventDefault();
        }
    };

    /**
     * Fix #39
     * For some reason Chrome doesn't "select-all", when the last placeholder is visible.
     * So it's needed to hide it when the user "selects all", and show it again when they presses any other key.
     *
     * @return {boolean} document.execCommand()
     */

    Core.prototype.fixSelectAll = function (e) {
        this.$el.children().last().removeClass('hide');

         if ((e.ctrlKey || e.metaKey) && e.which === 65) {
            e.preventDefault();

            if(this.$el.find('p').text().trim().length === 0) {
              return false;
            }

            this.$el.children().last().addClass('hide');

            return document.execCommand('selectAll', false, null);
        }
    };

    /**
     * Adds .medium-editor-placeholder class to the editor, when its content is empty
     *
     * @return {void}
     */

    Core.prototype.addEditorPlaceholder = function () {
        var $clone = this.$el.clone(),
            cloneHtml;

        $clone.find('.medium-insert').remove();
        cloneHtml = $clone.html().replace(/^\s+|\s+$/g, '');

        if (cloneHtml === '' || cloneHtml === '

') {
            this.$el.addClass('medium-editor-placeholder');
        }
    };

    /**
     * Initialize addons
     *
     * @return {void}
     */

    Core.prototype.initAddons = function () {
        var that = this;

        $.each(this.options.addons, function (addon, options) {
            that.$el[pluginName + ucfirst(addon)](options);
        });
    };

    /**
     * Cleans a content of the editor
     *
     * @return {void}
     */

    Core.prototype.clean = function () {
        var $lastChild = this.$el.children(':last');

        if (this.options.enabled === false) {
            return;
        }

        // Fix #39
        // After deleting all content (ctrl+A and delete) in Firefox, all content is deleted and only
 appears
        // To force placeholder to appear, set

 as content of the $el
        if (this.$el.html() === '' || this.$el.html() === '
') {
            this.$el.html(this.templates['src/js/templates/core-empty-line.hbs']().trim());
        }

        // Fix #29
        // Wrap content text in

 to avoid Firefox problems
        this.$el
            .contents()
            .filter(function () {
                return this.nodeName === '#text' && $.trim($(this).text()) !== '';
            })
            .wrap('
');

        // If last element is non-empty placeholder, add one empty line at the end to force placeholder to appear
        if ($lastChild.hasClass('medium-insert') && $lastChild.find('.medium-insert-placeholder').children().length > 0) {
            this.$el.append(this.templates['src/js/templates/core-empty-line.hbs']().trim());
        }

        // Fix not deleting placeholder in Firefox by removing all empty placeholders
        this.$el.find('.medium-insert-placeholder:empty').each(function () {
            $(this).parent().remove();
        });
    };

    /**
     * Returns HTML template of buttons
     *
     * @return {string} HTML template of buttons
     */

    Core.prototype.getButtons = function () {
        if (this.options.enabled === false) {
            return;
        }

        return this.templates['src/js/templates/core-buttons.hbs']({
            addons: this.options.addons
        }).trim();
    };

    /**
     * Appends buttons at the end of the $el
     *
     * @return {void}
     */

    Core.prototype.addButtons = function () {
        var $buttons = $(this.getButtons());

        this.$el.append($buttons);
    };

    /**
     * Move buttons to current active, empty paragraph and show them
     *
     * @return {void}
     */

    Core.prototype.showButtons = function (e) {
        var $el = $(e.target),
            selection = window.getSelection(),
            range = selection.getRangeAt(0),
            $current = $(range.commonAncestorContainer),
            $buttons = this.$el.find('.medium-insert-buttons'),
            isAddon = false,
            $p = $current.is('p') ? $current : $current.closest('p');

        if ($el.closest('.medium-insert-buttons').length === 0 && $current.closest('.medium-insert-buttons').length === 0) {

            this.$el.find('.medium-insert-active').removeClass('medium-insert-active');

            $.each(this.options.addons, function (addon) {
                if ($el.closest('.medium-insert-'+ addon).length) {
                    $current = $el;
                    $p = $el.closest('.medium-insert-'+ addon);
                    isAddon = true;
                    return;
                }
            });

            if ($p.length && $p.text().trim() === '') {
                $p.addClass('medium-insert-active');
                $buttons.removeClass('medium-insert-buttons-vertical');

                // Left position is set according to parent paragraph
                // Top position is set according to current active element
                $buttons.css({
                    left: $p.offset().left - parseInt($buttons.find('.medium-insert-buttons-addons').css('left'), 10) - parseInt($buttons.find('.medium-insert-buttons-addons a:first').css('margin-left'), 10),
                    top: $current.offset().top
                });

                if (isAddon) {
                    $buttons.addClass('medium-insert-buttons-vertical');
                }

                $buttons.show();
            } else {
                this.hideButtons();
            }
        }
    };

    /**
     * Hides buttons
     *
     * @returns {void}
     */

    Core.prototype.hideButtons = function () {
        this.$el.find('.medium-insert-buttons').hide();
        this.$el.find('.medium-insert-buttons-addons').hide();
    };

    /**
     * Toggles addons buttons
     *
     * @return {void}
     */

    Core.prototype.toggleAddons = function () {
        this.$el.find('.medium-insert-buttons-addons').toggle();
    };

    /**
     * Hide addons buttons
     *
     * @return {void}
     */

    Core.prototype.hideAddons = function () {
        this.$el.find('.medium-insert-buttons-addons').hide();
    };

    /**
     * Call addon's action
     *
     * @param {Event} e
     * @return {void}
     */

    Core.prototype.addonAction = function (e) {
        var $a = $(e.target).is('a') ? $(e.target) : $(e.target).closest('a'),
            addon = $a.data('addon'),
            action = $a.data('action');

        this.$el.data('plugin_'+ pluginName + ucfirst(addon))[action]();
    };

    /** Plugin initialization */

    $.fn[pluginName] = function (options) {
        return this.each(function () {
            if (!$.data(this, 'plugin_' + pluginName)) {
                // Plugin initialization
                $.data(this, 'plugin_' + pluginName, new Core(this, options));
            } else if (typeof options === 'string' && $.data(this, 'plugin_' + pluginName)[options]) {
                // Method call
                $.data(this, 'plugin_' + pluginName)[options]();
            }
        });
    };

})(jQuery, window, document);
<|endoftext|>


<commit_before>/**
  * @namespace
  */
var ui = window.ui = {

    version: "0.4.3",

    mode: "dev", // "dev" or "pub"

    components: "",

    internals: "",

    instances: {},

    init: function() {

        if (ui.mode=="dev") {
            var fns = ui.internals.split(",");
            var tot = fns.length;
            for (var i=0; i<tot; i++) {
                var x = fns[i];
                if (!ui[x]) ui.get("internal", x, function(){});
            }
        }

        ui.components = (window.components) ? ui.components+" "+window.components : ui.components ;

        ui.factory("create");

    },
/**
 *	@static Utils. Common usage functions.
 */
    utils: {
		body: $('body'),
		html: $('html'),
		window: $(window),
		document: $(document),
		ucfirst: function(s) { return (s + '').charAt(0).toUpperCase() + s.substr(1);
        }
	}
}

ui.environment = function (mode, config) {

    switch (mode) {

    case "pub":

    	return {
    		uri: "http://10.100.34.210:8080/content/chico/"+ ui.version + "/php/",
    		css: "css.php?q="+config,
    		js: "js.php?q="+config
    	}

    	break;

    case "dev":

    	return {
    		uri: "/src/",
    		css: "css/"+config+".css",
    		js: "js/"+config+".js"
    	}

    	break;

    }
}

/**
*	@static @class Factory
*/
ui.factory = function(method, x, callback) {

    /**
    *  @function configure
    *	@arguments conf {Object} This is an object parameter with components configuration
    *	@return A collection of object instances
    */
    switch(method) {

    case "create":

        // The method ui.get("all") DEPRECATED (???)
        //ui.get("all", ui.components, function(){});

        var fns = ui.components.split(",");
        var tot = fns.length;
        for (var i=0; i<tot; i++) {
            var x = fns[i];
            ui.factory("configure",x);
        }

        break;

	case "configure":

        // If component instances don't exists, create an empty array
        if (!ui.instances[x]) ui.instances[x] = [];

        var create = function(x) {

            // Send configuration to a component trough options object
            $.fn[x] = function(options) {

                var results = [];
                var that = this;
                var options = options || {};

                if (typeof options !== 'object') {
                    alert('UI: ' + x + ' configuration error.');
                    return;
                };

                that.each(function(i, e) {

                    var conf = {};
                        conf.name = x;
                        conf.element = e ;
                        conf.id = i;

                    $.extend( conf , options );

                    // Create a component from his constructor
                    var created = ui[x]( conf );

                    // Save results to return the created components
                    results.push( created );

                    // Map the instance
                    ui.instances[x].push( created );

                });

                // return the created components or component
                return ( results.length > 1 ) ? results : results[0];
            }

            // callback
            if (callback) callback();

        } // end create function

        if (ui[x]) {
            // script already here, just create
            create(x);
        } else {
            // get resurces and call create
            ui.get("component", x, create);
        }

        break;

    default:

        break;
    }
}

/**
*	@static @class Get
*/
ui.get = function(method, x, callback) {

    switch(method) {

	case "content":

		var result;

		x.$htmlContent.html('

');

		$.ajax({
			url: x.content.data,
			type: x.ajaxType || 'POST', // Because ajax.data is sent everytime, Solucion temporal por el modal
			data: x.ajaxParams || 'x=x', // Default: send {'x':'x'}, Solucion temporal por el modal
			cache: true,
			async: false, // Because getAjaxContent function returnaba before success and error
			success: function(data){
				result = data;
			},
			error: function(data){
				result = false;
			}
		});

		return result;

		break;

    case "all": // DEPRECATED (???)

        var c = x.split(" ");
        var x = c.join(",");

    case "internal":

        var internal = true;

	case "component":

        if (x.indexOf("http")==-1) {
            var url = ui.environment(ui.mode, x);
            var src = url.uri + url.js;
            var href = url.uri + url.css;
        } else {
            var src = x;
        }

        if (!internal) {
		var style = document.createElement('link');
    		style.href = href;
	    	style.rel = 'stylesheet';
        	style.type = 'text/css';
        }

	   	var script = document.createElement("script");
			script.src = src;

    default:

        var head = document.getElementsByTagName("head")[0] || document.documentElement;

		// Handle Script loading
		var done = false;

			// Attach handlers for all browsers
		script.onload = script.onreadystatechange = function() {

    	if ( !done && (!this.readyState ||
					this.readyState === "loaded" || this.readyState === "complete") ) {

				done = true;

                // save the script and style reference on the instances map
                if (method == "all") { // DEPRECATED (???)
                    for (var i=0;i<c.length;i++) {
                        ui.instances[c[i]] = [];
                        ui.instances[c[i]].script = script;
                        ui.instances[c[i]].style = style;
                    }
                }

                if (!internal) {
                    ui.instances[x].script = script;
                    ui.instances[x].style = style;
                }

	   			// fire callback
	   	        if (callback) callback(x);

		   		// Handle memory leak in IE
	   			script.onload = script.onreadystatechange = null;

		   		if ( head && script.parentNode ) {
	   				head.removeChild( script );
	   			}
			}
		};

		// Use insertBefore instead of appendChild  to circumvent an IE6 bug.
		// This arises when a base node is used.
		head.insertBefore( script, head.firstChild );
    	if (!internal) head.appendChild( style );

    	return x;

		break;
    }

}

ui.init();
<commit_msg>Se actualiza la version del chico a 0.4.4 en core.js<commit_after>/**
  * @namespace
  */
var ui = window.ui = {

    version: "0.4.4",

    mode: "dev", // "dev" or "pub"

    components: "",

    internals: "",

    instances: {},

    init: function() {

        if (ui.mode=="dev") {
            var fns = ui.internals.split(",");
            var tot = fns.length;
            for (var i=0; i<tot; i++) {
                var x = fns[i];
                if (!ui[x]) ui.get("internal", x, function(){});
            }
        }

        ui.components = (window.components) ? ui.components+" "+window.components : ui.components ;

        ui.factory("create");

    },
/**
 *	@static Utils. Common usage functions.
 */
    utils: {
		body: $('body'),
		html: $('html'),
		window: $(window),
		document: $(document),
		ucfirst: function(s) { return (s + '').charAt(0).toUpperCase() + s.substr(1);
        }
	}
}

ui.environment = function (mode, config) {

    switch (mode) {

    case "pub":

    	return {
    		uri: "http://10.100.34.210:8080/content/chico/"+ ui.version + "/php/",
    		css: "css.php?q="+config,
    		js: "js.php?q="+config
    	}

    	break;

    case "dev":

    	return {
    		uri: "/src/",
    		css: "css/"+config+".css",
    		js: "js/"+config+".js"
    	}

    	break;

    }
}

/**
*	@static @class Factory
*/
ui.factory = function(method, x, callback) {

    /**
    *  @function configure
    *	@arguments conf {Object} This is an object parameter with components configuration
    *	@return A collection of object instances
    */
    switch(method) {

    case "create":

        // The method ui.get("all") DEPRECATED (???)
        //ui.get("all", ui.components, function(){});

        var fns = ui.components.split(",");
        var tot = fns.length;
        for (var i=0; i<tot; i++) {
            var x = fns[i];
            ui.factory("configure",x);
        }

        break;

	case "configure":

        // If component instances don't exists, create an empty array
        if (!ui.instances[x]) ui.instances[x] = [];

        var create = function(x) {

            // Send configuration to a component trough options object
            $.fn[x] = function(options) {

                var results = [];
                var that = this;
                var options = options || {};

                if (typeof options !== 'object') {
                    alert('UI: ' + x + ' configuration error.');
                    return;
                };

                that.each(function(i, e) {

                    var conf = {};
                        conf.name = x;
                        conf.element = e ;
                        conf.id = i;

                    $.extend( conf , options );

                    // Create a component from his constructor
                    var created = ui[x]( conf );

                    // Save results to return the created components
                    results.push( created );

                    // Map the instance
                    ui.instances[x].push( created );

                });

                // return the created components or component
                return ( results.length > 1 ) ? results : results[0];
            }

            // callback
            if (callback) callback();

        } // end create function

        if (ui[x]) {
            // script already here, just create
            create(x);
        } else {
            // get resurces and call create
            ui.get("component", x, create);
        }

        break;

    default:

        break;
    }
}

/**
*	@static @class Get
*/
ui.get = function(method, x, callback) {

    switch(method) {

	case "content":

		var result;

		x.$htmlContent.html('

');

		$.ajax({
			url: x.content.data,
			type: x.ajaxType || 'POST', // Because ajax.data is sent everytime, Solucion temporal por el modal
			data: x.ajaxParams || 'x=x', // Default: send {'x':'x'}, Solucion temporal por el modal
			cache: true,
			async: false, // Because getAjaxContent function returnaba before success and error
			success: function(data){
				result = data;
			},
			error: function(data){
				result = false;
			}
		});

		return result;

		break;

    case "all": // DEPRECATED (???)

        var c = x.split(" ");
        var x = c.join(",");

    case "internal":

        var internal = true;

	case "component":

        if (x.indexOf("http")==-1) {
            var url = ui.environment(ui.mode, x);
            var src = url.uri + url.js;
            var href = url.uri + url.css;
        } else {
            var src = x;
        }

        if (!internal) {
		var style = document.createElement('link');
    		style.href = href;
	    	style.rel = 'stylesheet';
        	style.type = 'text/css';
        }

	   	var script = document.createElement("script");
			script.src = src;

    default:

        var head = document.getElementsByTagName("head")[0] || document.documentElement;

		// Handle Script loading
		var done = false;

			// Attach handlers for all browsers
		script.onload = script.onreadystatechange = function() {

    	if ( !done && (!this.readyState ||
					this.readyState === "loaded" || this.readyState === "complete") ) {

				done = true;

                // save the script and style reference on the instances map
                if (method == "all") { // DEPRECATED (???)
                    for (var i=0;i<c.length;i++) {
                        ui.instances[c[i]] = [];
                        ui.instances[c[i]].script = script;
                        ui.instances[c[i]].style = style;
                    }
                }

                if (!internal) {
                    ui.instances[x].script = script;
                    ui.instances[x].style = style;
                }

	   			// fire callback
	   	        if (callback) callback(x);

		   		// Handle memory leak in IE
	   			script.onload = script.onreadystatechange = null;

		   		if ( head && script.parentNode ) {
	   				head.removeChild( script );
	   			}
			}
		};

		// Use insertBefore instead of appendChild  to circumvent an IE6 bug.
		// This arises when a base node is used.
		head.insertBefore( script, head.firstChild );
    	if (!internal) head.appendChild( style );

    	return x;

		break;
    }

}

ui.init();
<|endoftext|>


<commit_before>/**
 * The user object.
 * Use this to do any user interaction.
 */
var user = new User();

/**
 * The Phaser game object.
 * Use this to add objects to the game engine.
 * Note: In game states, use 'this' instead.
 */
var game;

/**
 * Create the game when the browser has loaded everything.
 * Note: This is where all the states should be added.
 */
window.onload = function () {
	game = new Phaser.Game(1024, 768, Phaser.AUTO, 'game');
	game.state.add('Boot', BootState);
	game.state.add(GLOBAL.STATE.entry, EntryState);
	game.state.add(GLOBAL.STATE.garden, GardenState);
	game.state.add(GLOBAL.STATE.birdheroGame, BirdheroGame);

	game.state.start('Boot');
};

//  The Google WebFont Loader will look for this object, so create it before loading the script.
var WebFontConfig = {
	active: function() {
		game.time.events.add(Phaser.Timer.SECOND, function () {
			// TODO: What if this is loaded faster than the images?
			game.state.start(GLOBAL.STATE.entry);
		}, this);
	},
	google: { families: ['The Girl Next Door'] }
};
void(WebFontConfig); // workaround for jshint unused warning.

/**
 * The boot state will load the first parts of the game and common game assets.
 * Add assets that will be used by many states in this section.
 * The next state will be called when the web font has been loaded.
 */
function BootState () {}
/* Phaser state function */
BootState.prototype.preload = function () {
	/* Show loading progress accordingly */
	this.load.onFileComplete.add(function (progress) {
		document.querySelector('.progress').innerHTML = progress + '%';
		if (progress >= 100) {
			document.querySelector('.loading').style.display = 'none';
		} else {
			document.querySelector('.loading').style.display = 'block';
		}
	});

	/* Make sure the game scales according to resolution */
	this.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
	this.scale.pageAlignHorizontally = true;
	this.scale.pageAlignVertically = true;
	this.scale.setScreenSize(true);

	/* Load the Google WebFont Loader script */
	this.load.script('webfont', '//ajax.googleapis.com/ajax/libs/webfont/1.4.7/webfont.js');

	/* Agent related */
	this.load.image('panda',      'assets/img/agent/panda/standard.png');
	this.load.image('pandaTalk',  'assets/img/agent/panda/talking.png');
	this.load.image('pandaWalk1', 'assets/img/agent/panda/walking1.png');
	this.load.image('pandaWalk2', 'assets/img/agent/panda/walking2.png');
	this.load.image('pandaWave',  'assets/img/agent/panda/waving.png');
	this.load.image('pandaEye',   'assets/img/agent/panda/eye.png');
	this.load.image('pandaFlare', 'assets/img/agent/panda/flare.png');

	/* Common game elements */
	this.load.spritesheet('drop', 'assets/img/objects/drop.png', 35, 70, 2);
	this.load.spritesheet('wood', 'assets/img/objects/wood.png', 58, 56, 2);

	/* Load the entry state assets as well, no need to do two loaders. */
	this.load.image('entryBg', 'assets/img/jungle.png');
	this.load.audio('yeah', ['assets/audio/yeah.mp3', 'assets/audio/yeah.ogg']);
};<commit_msg>Bugfix for user instantiation<commit_after>/**
 * The user object.
 * Use this to do any user interaction.
 */
var user;

/**
 * The Phaser game object.
 * Use this to add objects to the game engine.
 * Note: In game states, use 'this' instead.
 */
var game;

/**
 * Create the game when the browser has loaded everything.
 * Note: This is where all the states should be added.
 */
window.onload = function () {
	user = new User();
	game = new Phaser.Game(1024, 768, Phaser.AUTO, 'game');
	game.state.add('Boot', BootState);
	game.state.add(GLOBAL.STATE.entry, EntryState);
	game.state.add(GLOBAL.STATE.garden, GardenState);
	game.state.add(GLOBAL.STATE.birdheroGame, BirdheroGame);

	game.state.start('Boot');
};

//  The Google WebFont Loader will look for this object, so create it before loading the script.
var WebFontConfig = {
	active: function() {
		game.time.events.add(Phaser.Timer.SECOND, function () {
			// TODO: What if this is loaded faster than the images?
			game.state.start(GLOBAL.STATE.entry);
		}, this);
	},
	google: { families: ['The Girl Next Door'] }
};
void(WebFontConfig); // workaround for jshint unused warning.

/**
 * The boot state will load the first parts of the game and common game assets.
 * Add assets that will be used by many states in this section.
 * The next state will be called when the web font has been loaded.
 */
function BootState () {}
/* Phaser state function */
BootState.prototype.preload = function () {
	/* Show loading progress accordingly */
	this.load.onFileComplete.add(function (progress) {
		document.querySelector('.progress').innerHTML = progress + '%';
		if (progress >= 100) {
			document.querySelector('.loading').style.display = 'none';
		} else {
			document.querySelector('.loading').style.display = 'block';
		}
	});

	/* Make sure the game scales according to resolution */
	this.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
	this.scale.pageAlignHorizontally = true;
	this.scale.pageAlignVertically = true;
	this.scale.setScreenSize(true);

	/* Load the Google WebFont Loader script */
	this.load.script('webfont', '//ajax.googleapis.com/ajax/libs/webfont/1.4.7/webfont.js');

	/* Agent related */
	this.load.image('panda',      'assets/img/agent/panda/standard.png');
	this.load.image('pandaTalk',  'assets/img/agent/panda/talking.png');
	this.load.image('pandaWalk1', 'assets/img/agent/panda/walking1.png');
	this.load.image('pandaWalk2', 'assets/img/agent/panda/walking2.png');
	this.load.image('pandaWave',  'assets/img/agent/panda/waving.png');
	this.load.image('pandaEye',   'assets/img/agent/panda/eye.png');
	this.load.image('pandaFlare', 'assets/img/agent/panda/flare.png');

	/* Common game elements */
	this.load.spritesheet('drop', 'assets/img/objects/drop.png', 35, 70, 2);
	this.load.spritesheet('wood', 'assets/img/objects/wood.png', 58, 56, 2);

	/* Load the entry state assets as well, no need to do two loaders. */
	this.load.image('entryBg', 'assets/img/jungle.png');
	this.load.audio('yeah', ['assets/audio/yeah.mp3', 'assets/audio/yeah.ogg']);
};<|endoftext|>


<commit_before>require('browsernizr/test/css/flexbox');
require('browsernizr');

// Hook into the PhantomJS test runner and instruct it to take a screenshot on load
// If PhantomJS isn't present this will have no effect
if (true || typeof window.callPhantom === 'function') {
  window.addEventListener('load', function() {
    // Poll to establish whether webfonts have loaded yet
    var count = 0;

    var poll = setInterval(function() {
      count++;

      if(document.body.classList.contains('wf-loading') && count < 100) {
        return;
      }

      clearInterval(poll);

      // Wait for things like Leaflet to load if they're present
      var hasMap = (document.querySelectorAll('.map').length > 0);

      setTimeout(function() {
        window.callPhantom('takeShot');
      }, (hasMap ? 10000 : 0))

    }, 100);
  });
}
<commit_msg>Remove debug code<commit_after>require('browsernizr/test/css/flexbox');
require('browsernizr');

// Hook into the PhantomJS test runner and instruct it to take a screenshot on load
// If PhantomJS isn't present this will have no effect
if (typeof window.callPhantom === 'function') {
  window.addEventListener('load', function() {
    // Poll to establish whether webfonts have loaded yet
    var count = 0;

    var poll = setInterval(function() {
      count++;

      if(document.body.classList.contains('wf-loading') && count < 100) {
        return;
      }

      clearInterval(poll);

      // Wait for things like Leaflet to load if they're present
      var hasMap = (document.querySelectorAll('.map').length > 0);

      setTimeout(function() {
        window.callPhantom('takeShot');
      }, (hasMap ? 10000 : 0))

    }, 100);
  });
}
<|endoftext|>


<commit_before>var messages = [];

var untranslated = {
  human: 'Human',
  computer: 'Computer',
  notConnected: 'Not connected',
  connectionError: 'Connection error',
  noInternetConnection: 'No internet connection',
  unauthorizedError: 'Access is unauthorized',
  lichessIsNotReachableError: 'lichess.org is unreachable',
  resourceNotFoundError: 'Resource not found',
  lichessIsUnavailableError: 'lichess.org is temporarily down for maintenance',
  serverError: 'The server encountered an error',
  color: 'Color',
  clock: 'Clock',
  disableSleepDuringGame: 'Disable sleep during game',
  sound: 'Sound',
  showCoordinates: 'Show board coordinates',
  animations: 'Pieces animations'
};

var defaultCode = 'en';

function loadFile(code, callback) {
  var i18nLoc = window.cordova ? (window.device.platform === 'Android' ?
    '/android_asset/www/i18n' : 'i18n') : 'i18n';
  m.request({
    url: i18nLoc + '/' + code + '.json',
    method: 'GET'
  }).then(function(data) {
    messages = data;
    callback();
  }, function(error) {
    // workaround for ios: because xhr for local file has a 0 status it will
    // reject the promise, but still have the response object
    // TODO find a better fix (in mithril?)
    if (typeof error.playWithAFriend === 'string') {
      messages = error;
      callback();
    } else {
      if (code === defaultCode) throw new Error(error);
      console.log(error, 'defaulting to ' + defaultCode);
      loadFile(defaultCode, callback);
    }
  });
}

function loadPreferredLanguage(callback) {
  window.navigator.globalization.getPreferredLanguage(
    function(language) {
      loadFile(language.value.split('-')[0], callback);
    },
    function() {
      loadFile(defaultCode, callback);
    });
}

module.exports = function(key) {
  var str = messages[key] || untranslated[key] || key;
  Array.prototype.slice.call(arguments, 1).forEach(function(arg) {
    str = str.replace('%s', arg);
  });
  return str;
};
module.exports.loadPreferredLanguage = loadPreferredLanguage;
<commit_msg>Tweak i18n workaround for ios<commit_after>var messages = [];

var untranslated = {
  human: 'Human',
  computer: 'Computer',
  notConnected: 'Not connected',
  connectionError: 'Connection error',
  noInternetConnection: 'No internet connection',
  unauthorizedError: 'Access is unauthorized',
  lichessIsNotReachableError: 'lichess.org is unreachable',
  resourceNotFoundError: 'Resource not found',
  lichessIsUnavailableError: 'lichess.org is temporarily down for maintenance',
  serverError: 'The server encountered an error',
  color: 'Color',
  clock: 'Clock',
  disableSleepDuringGame: 'Disable sleep during game',
  sound: 'Sound',
  showCoordinates: 'Show board coordinates',
  animations: 'Pieces animations'
};

var defaultCode = 'en';

function loadFile(code, callback) {
  var i18nLoc = window.cordova ? (window.device.platform === 'Android' ?
    '/android_asset/www/i18n' : 'i18n') : 'i18n';
  m.request({
    url: i18nLoc + '/' + code + '.json',
    method: 'GET'
  }).then(function(data) {
    messages = data;
    callback();
  }, function(error) {
    // workaround for iOS: because xhr for local file has a 0 status it will
    // reject the promise, but still have the response object
    if (error && error.playWithAFriend) {
      messages = error;
      callback();
    } else {
      if (code === defaultCode) throw new Error(error);
      console.log(error, 'defaulting to ' + defaultCode);
      loadFile(defaultCode, callback);
    }
  });
}

function loadPreferredLanguage(callback) {
  window.navigator.globalization.getPreferredLanguage(
    function(language) {
      loadFile(language.value.split('-')[0], callback);
    },
    function() {
      loadFile(defaultCode, callback);
    });
}

module.exports = function(key) {
  var str = messages[key] || untranslated[key] || key;
  Array.prototype.slice.call(arguments, 1).forEach(function(arg) {
    str = str.replace('%s', arg);
  });
  return str;
};
module.exports.loadPreferredLanguage = loadPreferredLanguage;
<|endoftext|>


<commit_before>require('browsernizr/test/css/flexbox');
require('browsernizr');

// Hook into the PhantomJS test runner and instruct it to take a screenshot on load
// If PhantomJS isn't present this will have no effect
if (typeof window.callPhantom === 'function') {
  window.addEventListener('load', function() {
    // Poll to establish whether webfonts have loaded yet
    var count = 0;

    var poll = setInterval(function() {
      count++;

      if(document.body.classList.contains('wf-loading') && count < 100) {
        return;
      }

      clearInterval(poll);

      // Wait for things like Leaflet to load if they're present
      var hasMap = (document.querySelectorAll('.map').length > 0);

      setTimeout(function() {
        window.callPhantom('takeShot');
      }, (hasMap ? 10000 : 0))

    }, 100);
  });
}
<commit_msg>Tweak webfont loading test<commit_after>require('browsernizr/test/css/flexbox');
require('browsernizr');

// Hook into the PhantomJS test runner and instruct it to take a screenshot on load
// If PhantomJS isn't present this will have no effect
if (typeof window.callPhantom === 'function') {
  window.addEventListener('load', function() {
    // Poll to establish whether webfonts have loaded yet
    var count = 0;

    var poll = setInterval(function() {
      count++;

      if(document.documentElement.classList.contains('wf-loading') && count < 100) {
        return;
      }

      clearInterval(poll);

      // Wait for things like Leaflet to load if they're present
      var hasMap = (document.querySelectorAll('.map').length > 0);

      setTimeout(function() {
        window.callPhantom('takeShot');
      }, (hasMap ? 10000 : 0))

    }, 100);
  });
}
<|endoftext|>


<commit_before>fixDivHeight();

/**
 * The VLV has a bad layout due to a single div containing a fixed height. This function fixes this by setting height to auto like it should be.
 */
function fixDivHeight() {
    document.getElementById("rechtespalte2").style.height = "auto";
}
<commit_msg>log all IDs of events<commit_after>fixDivHeight();
parse();

/*
 * Log the container that holds all relevant information
 */
console.log(document.getElementById("rechtespalte2"));

/**
 * The VLV has a bad layout due to a single div containing a fixed height. This function fixes this by setting height to auto like it should be.
 */
function fixDivHeight() {
    document.getElementById("rechtespalte2").style.height = "auto";
}
function parse() {
    var list = document.getElementById("rechtespalte2").getElementsByTagName("div");
    var i = 0;
    for ( item in list ) {
        console.log(document.getElementById("rechtespalte2").children[i].id);
        i = i + 1;
    }
}
<|endoftext|>


<commit_before>var EXPORTED_SYMBOLS = ["sl3uf"];

const Cc = Components.classes, Ci = Components.interfaces;

sl3uf = {
    list: function() {
        // Return sorted array of function names
        var entries = this.directory().directoryEntries;
        var array = [];
        while (entries.hasMoreElements()) {
            var entry = entries.getNext();
            entry.QueryInterface(Ci.nsIFile);
            if (entry.leafName.endsWith(".slj")) {
                array.push(entry.leafName.slice(0, -4));
            }
        }
        return array.sort();
    },

    load: function(name) {
        // Returns [name, help, body]
        var file = this.directory();
        file.append(name + ".slj");
        return this.import(file);
    },

    save: function(name, help, body) {
        // Returns nothing
        var file = this.file(name);
        this.export(name, help, body, file);
    },

    remove: function(name) {
        // Returns nothing
        var file = this.file(name);
        file.remove(false);
    },

    exists: function(name) {
        // Returns true or false
        return this.file(name).exists();
    },

    import: function(file) {
        // "file" is an nsIFile object
        // Returns [name, help, body]
        var data = "";
        var fstream = Cc["@mozilla.org/network/file-input-stream;1"].
            createInstance(Ci.nsIFileInputStream);
        var cstream = Cc["@mozilla.org/intl/converter-input-stream;1"].
            createInstance(Ci.nsIConverterInputStream);
        fstream.init(file, -1, 0, 0);
        cstream.init(fstream, "UTF-8", 0, 0);

        var read = 1;
        while (read != 0) {
            var str = {};
            read = cstream.readString(0xffffffff, str);
            data += str.value;
        }
        cstream.close();
        obj = JSON.parse(data);
        return [obj.name, obj.help, obj.body];
    },

    export: function(name, help, body, file) {
        // "file" is an nsIFile object
        // Returns nothing
        var obj = {
            version: 1,
            name: name,
            help: help,
            body: body
        };
        var data = JSON.stringify(obj);
        var foStream = Cc["@mozilla.org/network/file-output-stream;1"].
            createInstance(Ci.nsIFileOutputStream);
        foStream.init(file, 0x02 | 0x08 | 0x20, 0666, 0);
        var converter = Cc["@mozilla.org/intl/converter-output-stream;1"].
            createInstance(Ci.nsIConverterOutputStream);
        converter.init(foStream, "UTF-8", 0, 0);
        converter.writeString(data);
        converter.close();
    },

    call: function(name, body, time, args) {
        body = "var next, nextspec, nextargs;" + body +
            "; return([next, nextspec, nextargs]);"
        var f = Function.apply(null, ["specname", "prev", "args", body]);
        var next, nextspec, nextargs;
        [next, nextspec, nextargs] = f("ufunc:" + name, time, args);
        if (! nextspec)
            return next;
        if (! nextargs)
            return [next, nextspec];
        nextargs.splice(0, 0, next, nextspec);
        return nextargs;
    },

    callByName: function(name, time, args) {
        // Returns whatever the function returns
        var help, body;
        [name, help, body] = this.load(name);
        return this.call(name, body, time, args);
    },

    nameOk: function(name) {
        // Returns true or false
        return /^\w+$/.test(name);
    },

    bodyOk: function(body) {
        // Returns true or false
        try {
            return !!Function.apply(null, ["specname", "prev", "args", body]);
        } catch (ex) {
            return false;
        }
    },

    parseArgs: function(argstring) {
        if (argstring === "")
            return [];
        try {
            var args = JSON.parse("[" + argstring + "]");
            this.unparseArgs(args); // throws exception on bad args
            return args;
        }
        catch (ex) {
            return false;
        }
    },

    unparseArgs: function(args) {
        // Convert a list into its string representation, WITHOUT the square
        // braces around the entire list.
        //
        // We stringify the individual elements of the list and then join them
        // because we want spaces after the commas for readability, and JSON.
        // stringify won't do that, and when you try to make it do that by
        // specifying its "space" argument, it inserts newlines as well, which
        // we obviously don't want.
        if (! args.length)
            return "";
        var arglist = [];
        for (var i in args) {
            val = args[i];
            if (val && val.splice)
                arglist.push('[' + this.unparseArgs(val) + ']');
            else if (! (/^(?:number|boolean|string)$/.test(typeof(val)) ||
                        val === null))
                throw new Error("Function arguments can only contain arrays " +
                                "numbers, booleans, strings, and null.");
            arglist.push(JSON.stringify(val));
        }
        return arglist.join(', ');
    },

    directory: function() {
        // Returns an nsIFile for the ufuncs storage directory
        var directoryService =
            Cc["@mozilla.org/file/directory_service;1"].
            getService(Ci.nsIProperties);
        // this is a reference to the profile dir (ProfD) now.
        var localDir = directoryService.get("ProfD", Ci.nsIFile);

        localDir.append("sendlater3");
        if (!localDir.exists() || !localDir.isDirectory()) {
            localDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0774);
        }

        localDir.append("ufuncs");
        if (!localDir.exists() || !localDir.isDirectory()) {
            localDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0774);
        }

        return localDir;
    },

    file: function(name) {
        // Returns an nsIFile for a ufunc file within the storage directory
        var file = this.directory();
        file.append(name + ".slj");
        return file;
    }
};
<commit_msg>Thunderbird < 17 doesn't have String.endsWith<commit_after>var EXPORTED_SYMBOLS = ["sl3uf"];

const Cc = Components.classes, Ci = Components.interfaces;

// Compatibility with before Thunderbird 17. Ugh.
if (!String.prototype.endsWith) {
  String.prototype.endsWith = function(searchString, position) {
      var subjectString = this.toString();
      if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) {
        position = subjectString.length;
      }
      position -= searchString.length;
      var lastIndex = subjectString.indexOf(searchString, position);
      return lastIndex !== -1 && lastIndex === position;
  };
}

sl3uf = {
    list: function() {
        // Return sorted array of function names
        var entries = this.directory().directoryEntries;
        var array = [];
        while (entries.hasMoreElements()) {
            var entry = entries.getNext();
            entry.QueryInterface(Ci.nsIFile);
            if (entry.leafName.endsWith(".slj")) {
                array.push(entry.leafName.slice(0, -4));
            }
        }
        return array.sort();
    },

    load: function(name) {
        // Returns [name, help, body]
        var file = this.directory();
        file.append(name + ".slj");
        return this.import(file);
    },

    save: function(name, help, body) {
        // Returns nothing
        var file = this.file(name);
        this.export(name, help, body, file);
    },

    remove: function(name) {
        // Returns nothing
        var file = this.file(name);
        file.remove(false);
    },

    exists: function(name) {
        // Returns true or false
        return this.file(name).exists();
    },

    import: function(file) {
        // "file" is an nsIFile object
        // Returns [name, help, body]
        var data = "";
        var fstream = Cc["@mozilla.org/network/file-input-stream;1"].
            createInstance(Ci.nsIFileInputStream);
        var cstream = Cc["@mozilla.org/intl/converter-input-stream;1"].
            createInstance(Ci.nsIConverterInputStream);
        fstream.init(file, -1, 0, 0);
        cstream.init(fstream, "UTF-8", 0, 0);

        var read = 1;
        while (read != 0) {
            var str = {};
            read = cstream.readString(0xffffffff, str);
            data += str.value;
        }
        cstream.close();
        obj = JSON.parse(data);
        return [obj.name, obj.help, obj.body];
    },

    export: function(name, help, body, file) {
        // "file" is an nsIFile object
        // Returns nothing
        var obj = {
            version: 1,
            name: name,
            help: help,
            body: body
        };
        var data = JSON.stringify(obj);
        var foStream = Cc["@mozilla.org/network/file-output-stream;1"].
            createInstance(Ci.nsIFileOutputStream);
        foStream.init(file, 0x02 | 0x08 | 0x20, 0666, 0);
        var converter = Cc["@mozilla.org/intl/converter-output-stream;1"].
            createInstance(Ci.nsIConverterOutputStream);
        converter.init(foStream, "UTF-8", 0, 0);
        converter.writeString(data);
        converter.close();
    },

    call: function(name, body, time, args) {
        body = "var next, nextspec, nextargs;" + body +
            "; return([next, nextspec, nextargs]);"
        var f = Function.apply(null, ["specname", "prev", "args", body]);
        var next, nextspec, nextargs;
        [next, nextspec, nextargs] = f("ufunc:" + name, time, args);
        if (! nextspec)
            return next;
        if (! nextargs)
            return [next, nextspec];
        nextargs.splice(0, 0, next, nextspec);
        return nextargs;
    },

    callByName: function(name, time, args) {
        // Returns whatever the function returns
        var help, body;
        [name, help, body] = this.load(name);
        return this.call(name, body, time, args);
    },

    nameOk: function(name) {
        // Returns true or false
        return /^\w+$/.test(name);
    },

    bodyOk: function(body) {
        // Returns true or false
        try {
            return !!Function.apply(null, ["specname", "prev", "args", body]);
        } catch (ex) {
            return false;
        }
    },

    parseArgs: function(argstring) {
        if (argstring === "")
            return [];
        try {
            var args = JSON.parse("[" + argstring + "]");
            this.unparseArgs(args); // throws exception on bad args
            return args;
        }
        catch (ex) {
            return false;
        }
    },

    unparseArgs: function(args) {
        // Convert a list into its string representation, WITHOUT the square
        // braces around the entire list.
        //
        // We stringify the individual elements of the list and then join them
        // because we want spaces after the commas for readability, and JSON.
        // stringify won't do that, and when you try to make it do that by
        // specifying its "space" argument, it inserts newlines as well, which
        // we obviously don't want.
        if (! args.length)
            return "";
        var arglist = [];
        for (var i in args) {
            val = args[i];
            if (val && val.splice)
                arglist.push('[' + this.unparseArgs(val) + ']');
            else if (! (/^(?:number|boolean|string)$/.test(typeof(val)) ||
                        val === null))
                throw new Error("Function arguments can only contain arrays " +
                                "numbers, booleans, strings, and null.");
            arglist.push(JSON.stringify(val));
        }
        return arglist.join(', ');
    },

    directory: function() {
        // Returns an nsIFile for the ufuncs storage directory
        var directoryService =
            Cc["@mozilla.org/file/directory_service;1"].
            getService(Ci.nsIProperties);
        // this is a reference to the profile dir (ProfD) now.
        var localDir = directoryService.get("ProfD", Ci.nsIFile);

        localDir.append("sendlater3");
        if (!localDir.exists() || !localDir.isDirectory()) {
            localDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0774);
        }

        localDir.append("ufuncs");
        if (!localDir.exists() || !localDir.isDirectory()) {
            localDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0774);
        }

        return localDir;
    },

    file: function(name) {
        // Returns an nsIFile for a ufunc file within the storage directory
        var file = this.directory();
        file.append(name + ".slj");
        return file;
    }
};
<|endoftext|>


<commit_before>console.log('Ractive components', components.length)

components.forEach(function(component){

	var Component = Ractive.extend({
		template: component.template,
	 	magic: true,
		debug: true
	})

	var c = {}
	component.init(c, Ractive)
	exports = c.exports;

	if ( typeof exports === 'undefined' ) {
	  //just use default...
	} else if ( typeof exports === 'function' ) {
	  Component = exports( Component );
	} else if ( typeof exports === 'object' ) {
	  Component = Component.extend( exports );
	}

	Ractive.components[component.name] = Component
})

var data = {}
var hello = {
	name: 'hello',
	assets: {
		"template": {
			"code": {
				"jade": "p hello {{world}}\ninput(value='{{world}}')",
				"mustache": "",
				"ractive": ""
			},
			"error": null
		},
		"style": {
			"code": {
				"stylus": "p\n\tcolor: green",
				"css": ""
			},
			"error": null
		},
		"data": {
			"code": {
				"eval": "{ world: 'earth' }",
				"json": ""
			},
			"error": null
		},
		"script": {
			"code": {
				init: '',
				"js": ""
			},
			"error": null
		}
	}
}
var items = {
	name: 'items',
	assets: {
		"template": {
			"code": {
				"jade": "ul\n\t{{#items}}\n\tli {{.}}\n\t{{/items}}\n" +
						"input(value='{{new}}')\nbutton(on-click='add:{{new}}') add",
				"mustache": "",
				"ractive": ""
			},
			"error": null
		},
		"style": {
			"code": {
				"stylus": "li\n\tcolor saddlebrown\n\tfont-family fantasy",
				"css": ""
			},
			"error": null
		},
		"data": {
			"code": {
				"eval": "{ items: ['earth', 'mars','venus'] }",
				"json": ""
			},
			"error": null
		},
		"script": {
			"code": {
				"init": "component.exports = {\n\
		init: function(){\n\
			var items = this.data.items\n\
			this.on('add', function(e, item){\n\
				if(!item){ return }\n\
				items.push(item)\n\
				this.data.new = ''\n\
			})\n\
		}\n\
	}",
				"js": ""
			},
			"error": null
		}
	}
}
var empty = {
	name: 'empty',
	assets: {
		"template": {
			"code": {
				"jade": "",
				"mustache": "",
				"ractive": ""
			},
			"error": null
		},
		"style": {
			"code": {
				"stylus": "",
				"css": ""
			},
			"error": null
		},
		"data": {
			"code": {
				"eval": "",
				"json": ""
			},
			"error": null
		},
		"script": {
			"code": {
				"init": "",
				"js": ""
			},
			"error": null
		}
	}
}

data.project = {
	current: hello,
	components: [hello,items, empty]
}

var config = new ConfigService()

function ConfigService() {

	var defaultPane = {

		position: { x: 10, y: 50 },
		pane: {
			position: { x: 70, y: 50 },
			pane: {
				position: { x: 50, y: 50 }
			}
		}
	}

	return {
		get pane(){
			var ls = localStorage.paneConfig
			return ls ? JSON.parse(ls) : defaultPane
		},
		set pane(pc){
			localStorage.paneConfig = JSON.stringify(pc)
		}
	}
}

data.pane = config.pane

window.onbeforeunload = function(){
	config.pane = data.pane
}

setTimeout(function(){
	load(data)
})

function load(data){
	var main = 'flow'
	var template = '<' + main + ' '
	Object.keys(data).forEach(function(key){
		template += key + '="{{' + key + '}}" '
	})
	template += '/>'

	var Component = Ractive.components.flow
	try {
		var ractive = new Component({
			debug: true,
			el: document.body,
			// template: template,
			magic: true,
			data: data
		})

	} catch(error){
		document.body.innerHTML = error
	}
}
<commit_msg>adjust local storage of pane config. and test push to gh-pages<commit_after>console.log('Ractive components', components.length)

components.forEach(function(component){

	var Component = Ractive.extend({
		template: component.template,
	 	magic: true,
		debug: true
	})

	var c = {}
	component.init(c, Ractive)
	exports = c.exports;

	if ( typeof exports === 'undefined' ) {
	  //just use default...
	} else if ( typeof exports === 'function' ) {
	  Component = exports( Component );
	} else if ( typeof exports === 'object' ) {
	  Component = Component.extend( exports );
	}

	Ractive.components[component.name] = Component
})

var data = {}
var hello = {
	name: 'hello',
	assets: {
		"template": {
			"code": {
				"jade": "p hello {{world}}\ninput(value='{{world}}')",
				"mustache": "",
				"ractive": ""
			},
			"error": null
		},
		"style": {
			"code": {
				"stylus": "p\n\tcolor: green",
				"css": ""
			},
			"error": null
		},
		"data": {
			"code": {
				"eval": "{ world: 'earth' }",
				"json": ""
			},
			"error": null
		},
		"script": {
			"code": {
				init: '',
				"js": ""
			},
			"error": null
		}
	}
}
var items = {
	name: 'items',
	assets: {
		"template": {
			"code": {
				"jade": "ul\n\t{{#items}}\n\tli {{.}}\n\t{{/items}}\n" +
						"input(value='{{new}}')\nbutton(on-click='add:{{new}}') add",
				"mustache": "",
				"ractive": ""
			},
			"error": null
		},
		"style": {
			"code": {
				"stylus": "li\n\tcolor saddlebrown\n\tfont-family fantasy",
				"css": ""
			},
			"error": null
		},
		"data": {
			"code": {
				"eval": "{ items: ['earth', 'mars','venus'] }",
				"json": ""
			},
			"error": null
		},
		"script": {
			"code": {
				"init": "component.exports = {\n\
		init: function(){\n\
			var items = this.data.items\n\
			this.on('add', function(e, item){\n\
				if(!item){ return }\n\
				items.push(item)\n\
				this.data.new = ''\n\
			})\n\
		}\n\
	}",
				"js": ""
			},
			"error": null
		}
	}
}
var empty = {
	name: 'empty',
	assets: {
		"template": {
			"code": {
				"jade": "",
				"mustache": "",
				"ractive": ""
			},
			"error": null
		},
		"style": {
			"code": {
				"stylus": "",
				"css": ""
			},
			"error": null
		},
		"data": {
			"code": {
				"eval": "",
				"json": ""
			},
			"error": null
		},
		"script": {
			"code": {
				"init": "",
				"js": ""
			},
			"error": null
		}
	}
}

data.project = {
	current: hello,
	components: [hello,items, empty]
}

var config = new ConfigService()

function ConfigService() {

	var defaultPane = {
		version: '0.0.1',
		position: { x: 10, y: 50 },
		pane: {
			position: { x: 70, y: 50 },
			pane: {
				position: { x: 50, y: 50 }
			}
		}
	}

	return {
		get pane(){
			var ls = localStorage.paneConfig
			if(!ls) {
				ls = defaultPane
			} else {
				ls = JSON.parse(ls)
				if(!ls.version) {
					ls = defaultPane
				}
			}
			return ls
		},
		set pane(pc){
			localStorage.paneConfig = JSON.stringify(pc)
		}
	}
}

data.pane = config.pane

window.onbeforeunload = function(){
	config.pane = data.pane
}

setTimeout(function(){
	load(data)
})

function load(data){
	var main = 'flow'
	var template = '<' + main + ' '
	Object.keys(data).forEach(function(key){
		template += key + '="{{' + key + '}}" '
	})
	template += '/>'

	var Component = Ractive.components.flow
	try {
		var ractive = new Component({
			debug: true,
			el: document.body,
			// template: template,
			magic: true,
			data: data
		})

	} catch(error){
		document.body.innerHTML = error
	}
}
<|endoftext|>


<commit_before>/*jshint indent:2, curly:true eqeqeq:true, immed:true, latedef:true,
newcap:true, noarg:true, regexp:true, undef:true, strict:true, trailing:true
white:true*/
/*global XT:true, XM:true, Backbone:true, _:true, console:true */

(function () {
  "use strict";

  /**
    @class

    @extends XT.Model
  */
  XM.Country = XT.Model.extend({
    /** @scope XM.Country.prototype */

    recordType: 'XM.Country',

    privileges: {
      "all": {
        "create": "MaintainCountries",
        "read": true,
        "update": "MaintainCountries",
        "delete": "MaintainCountries"
      }
    },

    requiredAttributes: [
      "abbreviation",
      "currencyAbbreviation",
      "name"
    ],

    // ..........................................................
    // METHODS
    //

    validateEdit: function (attributes) {
      var params = {};

      if (attributes.abbreviation &&
          attributes.abbreviation.length !== 2) {
        params.attr = "_abbreviation".loc();
        params.length = "2";
        return XT.Error.clone('xt1006', { params: params });
      }

      if (attributes.currencyAbbreviation &&
          attributes.currencyAbbreviation.length !== 3) {
        params.attr = "_currencyAbbreviation".loc();
        params.length = "3";
        return XT.Error.clone('xt1006', { params: params });
      }
    }

  });

  /**
    @class

    @extends XT.Model
  */
  XM.State = XT.Model.extend({
    /** @scope XM.State.prototype */

    recordType: 'XM.State',

    privileges: {
      "all": {
        "create": "MaintainStates",
        "read": true,
        "update": "MaintainStates",
        "delete": "MaintainStates"
      }
    },

    requiredAttributes: [
      "abbreviation",
      "country",
      "name"
    ],

    relations: [{
      type: Backbone.HasOne,
      key: 'country',
      relatedModel: 'XM.Country',
      includeInJSON: 'guid'
    }]

  });

  /**
    @class

    @extends XM.Document
  */
  XM.Address = XM.Document.extend({
    /** @scope XM.Address.prototype */

    recordType: 'XM.Address',

    numberPolicy: XM.Document.AUTO_NUMBER,

    privileges: {
      "all": {
        "create": "MaintainAddresses",
        "read": "ViewAddresses",
        "update": "MaintainAddresses",
        "delete": "MaintainAddresses"
      }
    },

    relations: [{
      type: Backbone.HasMany,
      key: 'comments',
      relatedModel: 'XM.AddressComment',
      reverseRelation: {
        key: 'address'
      }
    }, {
      type: Backbone.HasMany,
      key: 'characteristics',
      relatedModel: 'XM.AddressCharacteristic',
      reverseRelation: {
        key: 'address'
      }
    }],

    // ..........................................................
    // METHODS
    //

    /**
      Formats the multiple lines of an address into a
      text block separating the elements of the address by line breaks.

      @params {Boolean} Is HTML
      @return {String}
    */
    format: function (isHtml) {
      return XM.Address.format(this, isHtml);
    },

    /**
      A formatted address that includes city, state and country.

      @return {String}
    */
    formatShort: function () {
      return XM.Address.formatShort(this);
    },

    /**
      Success response returns an integer from the server indicating how many times the address
      is used by other records.

      @param {Object} Options
      @returns Receiver
    */
    useCount: function (options) {
      console.log("XM.Address.useCount for: " + this.id);
      XT.dataSource.dispatch('XM.Address', 'useCount', this.id, options);
      return this;
    }

  });

  // ..........................................................
  // CLASS METHODS
  //

  _.extend(XM.Address, {

    /**
      Success response returns an address id for an address with the same fields
      as those passed.

      @param {String} Line1
      @param {String} Line2
      @param {String} Line3
      @param {String} City
      @param {String} State
      @param {String} Postal Code
      @param {String} Country
      @param {Object} Options
      @returns Receiver
    */
    findExisting: function (line1, line2, line3, city, state, postalcode, country, options) {
      var params = {
          type: 'Address',
          line1: line1,
          line2: line2,
          line3: line3,
          city: city,
          state: state,
          postalcode: postalcode,
          country: country
        };
      XT.dataSource.dispatch('XM.Address', 'findExisting', params, options);
      console.log("XM.Address.findExisting");
      return this;
    },

    /**
      This function formats the multiple lines of an address into a
      text block separating the elements of the address by line breaks.

      Address format accepts multiple argument formats:
        XM.Address.format(address);
        XM.Address.format(address, isHtml);
        XM.Address.format(name, line1, line2, line3, city, state, postalcode, country);
        XM.Address.format(name, line1, line2, line3, city, state, postalcode, country, isHtml);

      Where address is an XM.Address and isHtml determines whether to
      use HTML line breaks instead of ASCII new line characters. The
      default for isHtml is false. The longer signatures accept string
      components of an address.

      @return {String}
    */
    format: function () {
      var fmtlines   = [],
        name, line1, line2, line3,
        city, state, postalcode, country,
        breaks, result = '', csz;

      if (typeof arguments[0] === 'object') {
        name = '';
        line1 = arguments[0].get('line1');
        line2 = arguments[0].get('line2');
        line3 = arguments[0].get('line3');
        city = arguments[0].get('city');
        state = arguments[0].get('state');
        postalcode = arguments[0].get('postalcode');
        country = arguments[0].get('country');
        breaks = (arguments[1] === undefined ? false : arguments[1]) ? '
' : '\n';
      } else if (typeof arguments[0] === 'string')  {
        name = arguments[0];
        line1 = arguments[1];
        line2 = arguments[2];
        line3 = arguments[3];
        city = arguments[4];
        state = arguments[5];
        postalcode = arguments[6];
        country = arguments[7];
        breaks = (arguments[8] === undefined ? false : arguments[8]) ? '
' : '\n';
      } else { return false; }

      if (name) { fmtlines.push(name); }
      if (line1) { fmtlines.push(line1); }
      if (line2) { fmtlines.push(line2); }
      if (line3) { fmtlines.push(line3); }
      if (city || state || postalcode) {
        csz = (city || '') +
              (city && (state || postalcode) ? ', '  : '') +
              (state || '') +
              (state && postalcode ? ' '  : '') +
              (postalcode || '');
        fmtlines.push(csz);
      }
      if (country) { fmtlines.push(country); }

      if (fmtlines.length) { result = fmtlines.join(breaks); }

      return result;
    },

    /**
      A formatted address that includes city, state and country.

      @return {String}
    */
    formatShort: function (address) {
      var ret,
        city = address.get('city') || '',
        state = address.get('state') || '',
        country = address.get('country') || '';
      ret = city + (city && state ? ', ' : '') + state;
      ret += (ret ? ' ' : '') + country;
      return ret;
    }

  });

  /**
    @class

    @extends XT.Model
  */
  XM.AddressComment = XT.Model.extend({
    /** @scope XM.AddressComment.prototype */

    recordType: 'XM.AddressComment'

  });

  /**
    @class

    @extends XT.Model
  */
  XM.AddressCharacteristic = XT.Model.extend({
    /** @scope XM.AddressCharacteristic.prototype */

    recordType: 'XM.AddressCharacteristic'

  });

  /**
    @class

    @extends XT.Model
  */
  XM.AddressInfo = XT.Model.extend({
    /** @scope XM.AddressInfo.prototype */

    recordType: 'XM.AddressInfo',

    readOnly: true,

    privileges: {
      "all": {
        "create": false,
        "read": true,
        "update": false,
        "delete": false
      }
    },

    // ..........................................................
    // METHODS
    //

    /**
      Formats the multiple lines of an address into a
      text block separating the elements of the address by line breaks.

      @params {Boolean} Is HTML
      @return {String}
    */
    format: function (isHtml) {
      return XM.Address.format(this, isHtml);
    },

    /**
      A formatted address that includes city, state and country.

      @return {String}
    */
    formatShort: function () {
      return XM.Address.formatShort(this);
    }

  });

  // ..........................................................
  // COLLECTIONS
  //

  /**
    @class

    @extends XT.Collection
  */
  XM.AddressInfoCollection = XT.Collection.extend({
    /** @scope XM.AddressInfoCollection.prototype */

    model: XM.AddressInfo

  });

  /**
    @class

    @extends XT.Collection
  */
  XM.CountryCollection = XT.Collection.extend({
    /** @scope XM.CountryCollection.prototype */

    model: XM.Country

  });

  /**
    @class

    @extends XT.Collection
  */
  XM.StateCollection = XT.Collection.extend({
    /** @scope XM.StateCollection.prototype */

    model: XM.State

  });

}());
<commit_msg>Something's broken with findExisting.<commit_after>/*jshint indent:2, curly:true eqeqeq:true, immed:true, latedef:true,
newcap:true, noarg:true, regexp:true, undef:true, strict:true, trailing:true
white:true*/
/*global XT:true, XM:true, Backbone:true, _:true, console:true */

(function () {
  "use strict";

  /**
    @class

    @extends XT.Model
  */
  XM.Country = XT.Model.extend({
    /** @scope XM.Country.prototype */

    recordType: 'XM.Country',

    privileges: {
      "all": {
        "create": "MaintainCountries",
        "read": true,
        "update": "MaintainCountries",
        "delete": "MaintainCountries"
      }
    },

    requiredAttributes: [
      "abbreviation",
      "currencyAbbreviation",
      "name"
    ],

    // ..........................................................
    // METHODS
    //

    validateEdit: function (attributes) {
      var params = {};

      if (attributes.abbreviation &&
          attributes.abbreviation.length !== 2) {
        params.attr = "_abbreviation".loc();
        params.length = "2";
        return XT.Error.clone('xt1006', { params: params });
      }

      if (attributes.currencyAbbreviation &&
          attributes.currencyAbbreviation.length !== 3) {
        params.attr = "_currencyAbbreviation".loc();
        params.length = "3";
        return XT.Error.clone('xt1006', { params: params });
      }
    }

  });

  /**
    @class

    @extends XT.Model
  */
  XM.State = XT.Model.extend({
    /** @scope XM.State.prototype */

    recordType: 'XM.State',

    privileges: {
      "all": {
        "create": "MaintainStates",
        "read": true,
        "update": "MaintainStates",
        "delete": "MaintainStates"
      }
    },

    requiredAttributes: [
      "abbreviation",
      "country",
      "name"
    ],

    relations: [{
      type: Backbone.HasOne,
      key: 'country',
      relatedModel: 'XM.Country',
      includeInJSON: 'guid'
    }]

  });

  /**
    @class

    @extends XM.Document
  */
  XM.Address = XM.Document.extend({
    /** @scope XM.Address.prototype */

    recordType: 'XM.Address',

    numberPolicy: XM.Document.AUTO_NUMBER,

    privileges: {
      "all": {
        "create": "MaintainAddresses",
        "read": "ViewAddresses",
        "update": "MaintainAddresses",
        "delete": "MaintainAddresses"
      }
    },

    relations: [{
      type: Backbone.HasMany,
      key: 'comments',
      relatedModel: 'XM.AddressComment',
      reverseRelation: {
        key: 'address'
      }
    }, {
      type: Backbone.HasMany,
      key: 'characteristics',
      relatedModel: 'XM.AddressCharacteristic',
      reverseRelation: {
        key: 'address'
      }
    }],

    // ..........................................................
    // METHODS
    //

    /**
      Formats the multiple lines of an address into a
      text block separating the elements of the address by line breaks.

      @params {Boolean} Is HTML
      @return {String}
    */
    format: function (isHtml) {
      return XM.Address.format(this, isHtml);
    },

    /**
      A formatted address that includes city, state and country.

      @return {String}
    */
    formatShort: function () {
      return XM.Address.formatShort(this);
    },

    /**
      Success response returns an integer from the server indicating how many times the address
      is used by other records.

      @param {Object} Options
      @returns Receiver
    */
    useCount: function (options) {
      console.log("XM.Address.useCount for: " + this.id);
      XT.dataSource.dispatch('XM.Address', 'useCount', this.id, options);
      return this;
    }

  });

  // ..........................................................
  // CLASS METHODS
  //

  _.extend(XM.Address, {

    /**
      Success response returns an address id for an address with the same fields
      as those passed.

      @param {String} Line1
      @param {String} Line2
      @param {String} Line3
      @param {String} City
      @param {String} State
      @param {String} Postal Code
      @param {String} Country
      @param {Object} Options
      @returns Receiver
    */
    findExisting: function (line1, line2, line3, city, state, postalcode, country, options) {
      var params = {
          type: 'Address',
          line1: line1,
          line2: line2,
          line3: line3,
          city: city,
          state: state,
          postalcode: postalcode,
          country: country
        };
      XT.dataSource.dispatch('XM.Address', 'findExisting', params, options);
      console.log("XM.Address.findExisting");

      // TODO - Returns undefined??? WTF
      console.log('line3 works- ' + line3);
      console.log('City does not work - ' + city);
      return this;
    },

    /**
      This function formats the multiple lines of an address into a
      text block separating the elements of the address by line breaks.

      Address format accepts multiple argument formats:
        XM.Address.format(address);
        XM.Address.format(address, isHtml);
        XM.Address.format(name, line1, line2, line3, city, state, postalcode, country);
        XM.Address.format(name, line1, line2, line3, city, state, postalcode, country, isHtml);

      Where address is an XM.Address and isHtml determines whether to
      use HTML line breaks instead of ASCII new line characters. The
      default for isHtml is false. The longer signatures accept string
      components of an address.

      @return {String}
    */
    format: function () {
      var fmtlines   = [],
        name, line1, line2, line3,
        city, state, postalcode, country,
        breaks, result = '', csz;

      if (typeof arguments[0] === 'object') {
        name = '';
        line1 = arguments[0].get('line1');
        line2 = arguments[0].get('line2');
        line3 = arguments[0].get('line3');
        city = arguments[0].get('city');
        state = arguments[0].get('state');
        postalcode = arguments[0].get('postalcode');
        country = arguments[0].get('country');
        breaks = (arguments[1] === undefined ? false : arguments[1]) ? '
' : '\n';
      } else if (typeof arguments[0] === 'string')  {
        name = arguments[0];
        line1 = arguments[1];
        line2 = arguments[2];
        line3 = arguments[3];
        city = arguments[4];
        state = arguments[5];
        postalcode = arguments[6];
        country = arguments[7];
        breaks = (arguments[8] === undefined ? false : arguments[8]) ? '
' : '\n';
      } else { return false; }

      if (name) { fmtlines.push(name); }
      if (line1) { fmtlines.push(line1); }
      if (line2) { fmtlines.push(line2); }
      if (line3) { fmtlines.push(line3); }
      if (city || state || postalcode) {
        csz = (city || '') +
              (city && (state || postalcode) ? ', '  : '') +
              (state || '') +
              (state && postalcode ? ' '  : '') +
              (postalcode || '');
        fmtlines.push(csz);
      }
      if (country) { fmtlines.push(country); }

      if (fmtlines.length) { result = fmtlines.join(breaks); }

      return result;
    },

    /**
      A formatted address that includes city, state and country.

      @return {String}
    */
    formatShort: function (address) {
      var ret,
        city = address.get('city') || '',
        state = address.get('state') || '',
        country = address.get('country') || '';
      ret = city + (city && state ? ', ' : '') + state;
      ret += (ret ? ' ' : '') + country;
      return ret;
    }

  });

  /**
    @class

    @extends XT.Model
  */
  XM.AddressComment = XT.Model.extend({
    /** @scope XM.AddressComment.prototype */

    recordType: 'XM.AddressComment'

  });

  /**
    @class

    @extends XT.Model
  */
  XM.AddressCharacteristic = XT.Model.extend({
    /** @scope XM.AddressCharacteristic.prototype */

    recordType: 'XM.AddressCharacteristic'

  });

  /**
    @class

    @extends XT.Model
  */
  XM.AddressInfo = XT.Model.extend({
    /** @scope XM.AddressInfo.prototype */

    recordType: 'XM.AddressInfo',

    readOnly: true,

    privileges: {
      "all": {
        "create": false,
        "read": true,
        "update": false,
        "delete": false
      }
    },

    // ..........................................................
    // METHODS
    //

    /**
      Formats the multiple lines of an address into a
      text block separating the elements of the address by line breaks.

      @params {Boolean} Is HTML
      @return {String}
    */
    format: function (isHtml) {
      return XM.Address.format(this, isHtml);
    },

    /**
      A formatted address that includes city, state and country.

      @return {String}
    */
    formatShort: function () {
      return XM.Address.formatShort(this);
    }

  });

  // ..........................................................
  // COLLECTIONS
  //

  /**
    @class

    @extends XT.Collection
  */
  XM.AddressInfoCollection = XT.Collection.extend({
    /** @scope XM.AddressInfoCollection.prototype */

    model: XM.AddressInfo

  });

  /**
    @class

    @extends XT.Collection
  */
  XM.CountryCollection = XT.Collection.extend({
    /** @scope XM.CountryCollection.prototype */

    model: XM.Country

  });

  /**
    @class

    @extends XT.Collection
  */
  XM.StateCollection = XT.Collection.extend({
    /** @scope XM.StateCollection.prototype */

    model: XM.State

  });

}());
<|endoftext|>