<commit_before>///
/// LiveEditor jQuery plugin
///
/// $Header: http://svn.didit.se/public/Cosmo/Cosmo.latest/trunk/CosmoWeb/js/liveeditor.js 2004 2013-09-05 13:53:04Z mattias $
///
/// Copyright 2013 Trustfall AB
/// All rights reserved
///
;//Protection against other malformed scripts that can interfere
(function ($) {

    var defaultOptions = {

        debug: false,

        editor: {
            css: ''
        },

        combobox: {
            css: 'combo'
        },

        checkbox: {
            css: 'checkbox',
            checked: {
                value: 'true',
                html: 'X'
            },
            unchecked: {
                value: 'false',
                html: ''
            }
        },

        ///
        /// Container events
        ///

        onGetValue: null,

        onSetValue: null,

        /// Called (after any edit has been closed) when the container has changed its value. Also called by reset().
        onChanged: null,

        /// Called when an editor is being created to allow developers to implement their own editors for certain containers.
        onEditorCreating: null,

        /// Called to get valid options for a combobox Editor.
        /// this event must be overloaded if the comboboxes shall have any options.
        /// Return a string with <option /> elements to display.
        onEditorOptions: function (container) { return '<option value=""></option>'; },

        /// Called after the editor is visible.
        onEditorOpened: null,

        /// Called after the editor receives focus.
        onEditorFocused: null,

        /// Called after the editor has been closed.
        onEditorClosed: null,
    };

    var EDITOR_MARGIN = 5;//TODO: WHY do we need to remove this margin to make the input/select fit its parent container?

    ///
    /// Public LiveEditor Commands
    ///

    $.liveeditor = {
        //version: function () {
        //    return "0.0.1";
        //},

        ///
        /// Enables editing for an unregistered or previously disabled container.
        ///
        enable: function (container) {
            debug("jQuery.liveeditor.enable(container)");
            return enable(container);
        },

        ///
        /// Disables editing for a registered container.
        ///
        disable: function (container) {
            debug("jQuery.liveeditor.disable(container)");
            return disable(container);
        },

        ///
        /// Forces the open editor to save its changes back to its container and close.
        /// Call this method before saving to make sure all changes have been committed.
        ///
        closeEditor: function (container) {
            debug("jQuery.liveeditor.closeEditor(container)");
            //if (container || null === null)
            //    container = $(options.editor._focusedContainer);
            return commitEditor(container);
        },

        ///
        /// Changes the value of a container as if the user had edited it with the editor.
        ///
        set: function (container, value, html) {
            debug("jQuery.liveeditor.set(container, value, html)");
            var originalValue = getContainerValue(container);
            if (container.attr('liveold') === undefined) {
                container.attr('liveold', originalValue);
            }
            if (!updateContainer(container, value, html)) {
                return false;
            }
            if (value !== originalValue) {
                containerChanged(container);
            }
            return true;
        },

        ///
        /// Resets the container to consider its current value the unchanged state.
        /// Call this method for all containers after saving to setup new change-tracking without reloading the entire page.
        ///
        reset: function (container) {
            debug("jQuery.liveeditor.reset(container)");
            container.removeClass('changed');
            container.removeAttr('liveold');
            containerChanged(container);
            return container;
        }
    };

    ///
    /// Private Event Listeners
    ///

    //Display the editor when the user hovers over the container
    function container_mouseenter() {
        debug("liveeditor.container_mouseenter()");
        displayEditor($(this));
    }

    function container_mouseleave() {
        debug("liveeditor.container_mouseleave()");
        commitEditor(this);//TODO: Should call cancelEditor() instead to make sure the value doesn't change
    }

    //Make the editor "sticky" when focused so it doesn't disappear when the mouse is moved from the container
    function editor_focus() {
        debug('liveeditor.editor_focus()');

        var editor = $(this)
            .unbind('focus', editor_focus)
            .select();
        var container = editor.closest('.liveedit')
            .unbind('mouseleave', container_mouseleave);

        var options = container.data('liveeditor-options');
        if (container[0] === options.editor._focusedContainer) {
            debug('It is the current editing container that got focus. Ignore?!');
            return true; //Since the current containers editor is focused there is no other editor to close
        }

        if (options.editor._focusedContainer) {
            debug('Closing old editing container.');
            debug(options.editor._focusedContainer);
            if (!commitEditor(options.editor._focusedContainer))
                return false;
        }

        debug('Tracking the current editing container.');
        options.editor._focusedContainer = container[0];
        editor.keydown(editor_keydown);
        if ($.isFunction(options.onEditorFocused)) {
            debug("Calling onEditorFocused()");
            options.onEditorFocused.call(container, editor);
        }
        return true;
    }

    //Handle editor TAB and ESC keys
    function editor_keydown(e) {
        var keyCode = e.keyCode || e.which;
        if (keyCode == 27) {       // ESC
            e.preventDefault();
            var container = $(this).closest('.liveedit');
            var options = container.data('liveeditor-options');
            if (!options.editor._focusedContainer) {
                debug("Got ESC keydown for an editor without having a current container. Aborting!");
                return;
            }
            commitEditor(container);//options.editor._focusedContainer
        }
        else if (keyCode == 9) {    //TAB
            e.preventDefault();
            var container = $(this).closest('.liveedit');
            var options = container.data('liveeditor-options');
            if (!options.editor._focusedContainer) {
                debug("Got TAB keydown for an editor without having a current container. Aborting!");
                return;
            }

            //Close the current editor
            var nextContainer = container;//options.editor._focusedContainer; //TODO: Rewrite to use the initialized selector for stepping instead
            commitEditor(container);//options.editor._focusedContainer

            do {
                //Find previous/next editable container
                debug("Selecting next container for editing.");
                if (e.shiftKey) {
                    debug("TAB to prev container");
                    nextContainer = nextContainer.prevAll('.liveedit').eq(0);
                    if (nextContainer.length == 0) {
                        debug("Found no prev container. Moving to parents previous last");
                        nextContainer = $('.liveedit:last', nextContainer.parent().prev());
                    }
                } else {
                    debug("TAB to next container");
                    nextContainer = $("~ .liveedit", nextContainer).eq(0);
                    if (nextContainer.length == 0) {
                        debug("Found no next container. Moving to parents next first");
                        nextContainer = $('.liveedit:first', nextContainer.parent().next());
                    }
                }
                //Open the editor
                if (nextContainer.length > 0) {
                    try {
                        displayEditor(nextContainer).focus();
                        break;
                    } catch (e) {
                        debug("Failed to display editor. Move to the next container.");
                    }
                }
                else {
                    debug("No more containers to test. Not displaying any new editor.");
                    break;
                }
            } while (true);//Iterate through all editing containers until we find one that can be edited now
        }
    }

    ///
    /// Private methods
    ///
    function debug(msg) {
        //if (settings.debug && console)
        //    console.log(msg);
    }
    function enable(container) {
        if (!container.hasClass('liveedit')) {
            container
                .addClass('liveedit')
                .mouseenter(container_mouseenter);
        }
        return container;
    }
    function disable(container) {
        if (container.hasClass('liveedit')) {
            container
                .removeClass('liveedit')
                .unbind('mouseenter', container_mouseenter);
        }
        return container;
    }

    ///
    /// Method called to get the current value of a container before displaying its editor.
    /// Implement the events onGetValue() and onSetValue() if the container does not store its value in LiveEditors default way.
    /// Returns the containers current value as a string.
    ///
    function getContainerValue (container) {
        var value;
        var options = container.data('liveeditor-options');
        if ($.isFunction(options.onGetValue)) {
            debug('Calling onGetValue()');
            value = options.onGetValue.call(container);
        }
        if (!value) {
            debug('Looking up value from container');
            value = container.hasClass(options.combobox.css) || container.hasClass(options.checkbox.css)
                ? container.attr('value')
                : container.text();
        }
        debug('getContainerValue() returns: ' + value);
        return value;
    }

    ///
    /// Method called to set the new value of a container. If the container has an open editor it is closed by this commmand.
    /// Implement the events onGetValue() and onSetValue() if the container does not store its value in LiveEditors default way.
    /// Returns true if the value was written successfully and false if the operation was cancelled.
    ///
    function updateContainer(container, newValue, newHtml) {
        debug("liveeditor.updateContainer(container, newValue, newHtml)");
        var success;

        var oldValue = container.attr('liveold');

        //Let the user override the setting of the value to the container if he likes
        var options = container.data('liveeditor-options');
        if ($.isFunction(options.onSetValue)) {
            debug('Calling onSetValue()');
            var success = options.onSetValue.call(container, value, html);
            if (success === false)
                return false;
        }

        if (success === undefined) {
            //Set the new value to the container
            debug('Setting value for container');
            if (container.hasClass(options.combobox.css)) {
                container.attr('value', newValue);
            }
            else if (container.hasClass(options.checkbox.css)) {
                container.attr('value', newValue);
                newHtml = (newValue == options.checkbox.checked.value) ? options.checkbox.checked.html : options.checkbox.unchecked.html;
            }
            if (newHtml === null || newHtml === undefined)
                newHtml = newValue;
            container.html(newHtml);
        }

        container.unbind('mouseleave', container_mouseleave);

        if (container[0] === options.editor._focusedContainer) {
            debug("Closed the current editing container.");
            options.editor._focusedContainer = null;
        }

        //Update the containers change-status
        if (newValue != oldValue) {
            container.addClass('changed');
            debug("Flagged the container as changed");
        }
        else {
            container.removeClass('changed');
            container.removeAttr('liveold');
            debug("Flagged the container as unchanged");
        }
        return true;
    }

    function containerChanged (container) {
        var options = container.data('liveeditor-options');
        if ($.isFunction(options.onChanged)) {
            debug("Calling onChanged()");
            options.onChanged.call(container);
        }
    }

    ///
    /// Private Editor methods
    ///

    //Display editor when mouse hovers over an editable container
    function displayEditor(container) {
        debug('liveeditor.displayEditor(container)');
        var options = container.data('liveeditor-options');

        var editor = $('.liveeditor', container);
        if (editor.length) {
            debug("Using the existing editor for the requested container instead of creating a new.");
            return editor; //Already an editor in this container
        }

        var currentValue = getContainerValue(container);
        if (container.attr('liveold') === undefined) {
            container.attr('liveold', currentValue);
        }

        var editor = createEditor(container, currentValue);
        editor
            .addClass('liveeditor')
            .attr('original', currentValue);
        editor.focus(editor_focus);
        container
            .html(editor)
            .mouseleave(container_mouseleave);
        debug("Added editor to the container");

        if ($.isFunction(options.onEditorOpened)) {
            debug("Calling onEditorOpened");
            options.onEditorOpened.call(container, editor);
        }

        debug("liveeditor.displayEditor() DONE");
        return editor;
    }

    function createEditor(container, value) {
        var editor;
        var options = container.data('liveeditor-options');

        var event = options.onEditorCreating;
        if (event) {
            editor = event(container, value);
        }

        if (!editor) {
            if (container.hasClass(options.combobox.css)) {
                editor = $('<select>').width(container.width() - EDITOR_MARGIN);
                var select_options = options.onEditorOptions.call(container);
                switch ($.type(select_options)) {
                    case "string": editor.append($(select_options)); break;
                    default:
                        debug('appending ' + $.type(select_options) + ' options is not supported.');
                        break;
                }
                $('option[value="' + value + '"]', editor).prop('selected', true);
            } else if (container.hasClass(options.checkbox.css))
                editor = $('<input type="checkbox"/>').prop('checked', (value == options.checkbox.checked.value));
            else {
                editor = $('<input type="text"/>').width(container.width() - EDITOR_MARGIN).val(value);
            }
        }

        if (options.editor.css) {
            editor.addClass(options.editor.css);
        }

        return editor;
    }

    //Restore "label" in the container with the new value from the editor
    function commitEditor(obj) {
        debug("liveeditor.commitEditor(obj)");
        var container = $(obj);
        var editor = $('.liveeditor', container);
        if (!editor.length) {
            debug("Found no editor to hide for the requested container. Aborting!");
            return true; //No editor to hide
        }
        var originalValue = editor.attr('original');
        var newValue = getEditorValue(editor);
        var newHtml = getEditorHtml(editor);
        if (!updateContainer(container, newValue, newHtml))
            return false;

        var options = container.data('liveeditor-options');
        if (originalValue != newValue) {
            containerChanged(container);
        }
        //Throw the hidden event
        if ($.isFunction(options.onEditorClosed)) {
            debug("Calling onEditorClosed()");
            options.onEditorClosed.call(container);
        }
        return true;
    }

    ///
    /// Method to get the current value from the editor.
    /// Returns the editors value, which MAY differ from its displayed text (for checkboxes/comboboxes for instance).
    ///
    function getEditorValue(editor) {
        debug('liveeditor.getEditorValue()');
        var value;
        var container = editor.closest('.liveedit');
        var options = container.data('liveeditor-options');

        if ($.isFunction(options.onEditorGetValue)) {
            debug('Calling onEditorGetValue()');
            value = options.onEditorGetValue.call(editor);
        }

        if (!value) {
            debug('Getting editor value');
            if (editor.is(':checkbox'))
                value = (editor.prop('checked')
                    ? options.checkbox.checked.value
                    : options.checkbox.unchecked.value);
            else if (editor.is('select'))
                value = $('option:selected', editor).val();
            else
                value = editor.val();
        }

        debug('liveeditor.getEditorValue() returns ' + value);
        return value;
    }

    ///
    /// Method to get the current display text from the editor
    /// Returns the displayed text in the editor, which MAY differ from its value (for checkboxes/comboboxes for instance).
    ///
    function getEditorHtml (editor) {
        debug('liveeditor.getEditorHtml()');
        var html;
        var container = editor.closest('.liveedit');
        var options = container.data('liveeditor-options');

        if ($.isFunction(options.onEditorGetValue)) {
            debug('Calling onEditorGetHtml()');
            html = options.onEditorGetHtml.call(editor);
        }

        if (editor.is('select'))
            html = $(':selected', editor).text();
        else
            html = null;

        debug('liveeditor.getEditorHtml() returns ' + html);
        return html;
    }

    //called on the native object directly, wrap with $(obj) if needed.
    function initializeObject(obj, options) {
        //assign the options to the object instance.
        $(obj).data('liveeditor-options', options);

        //do other initialization tasks on the individual item here...
    }

    ///
    /// LiveEditor Initiator
    /// Use this method to unobtrusively initialize liveeditor for a group of containers.
    /// For example: $('table tbody tr td.editable').liveeditor();
    ///

    $.fn.liveeditor = function (options) {
        debug("jQuery.liveeditor initializing for selection");

        //Build options for the new instance
        var mergedOptions = $.extend({}, defaultOptions, options)
        mergedOptions.editor._focusedContainer = null; //This is just an internal state-variable, so DON'T expose it in defaultOptions!
        //Initialize all objects in the selection
        this.each(function () {
            initializeObject(this, mergedOptions);
        });
        //Enable all objects in the selection
        debug("Enabling selection");
        $.liveeditor.enable(this);

        //TODO: Consider iterating all items in the selector and updating their html if they are checkboxes or comboboxes, to make sure the server generated code isn't diffrent from client side
        //TODO: $('.combo,.checkbox', this).each(function(){ updateContainer(this, this.attr(value)); });

        debug("jQuery.liveeditor initializing DONE");
        return this;
    }

} (jQuery));
<commit_msg>Development version. Removing class-dependencies.<commit_after>///
/// LiveEditor jQuery plugin
///
/// $Header: http://svn.didit.se/public/Cosmo/Cosmo.latest/trunk/CosmoWeb/js/liveeditor.js 2004 2013-09-05 13:53:04Z mattias $
///
/// Copyright 2013 Trustfall AB
/// All rights reserved
///
;//Protection against other malformed scripts that can interfere
(function ($) {

    var defaultOptions = {

        debug: false,

        editor: {
            css: ''
        },

        combobox: {
            css: 'combo'
        },

        checkbox: {
            css: 'checkbox',
            checked: {
                value: 'true',
                html: 'X'
            },
            unchecked: {
                value: 'false',
                html: ''
            }
        },

        ///
        /// Container events
        ///

        onGetValue: null,

        onSetValue: null,

        /// Called (after any edit has been closed) when the container has changed its value. Also called by reset().
        onChanged: null,

        /// Called when an editor is being created to allow developers to implement their own editors for certain containers.
        onEditorCreating: null,

        /// Called to get valid options for a combobox Editor.
        /// this event must be overloaded if the comboboxes shall have any options.
        /// Return a string with <option /> elements to display.
        onEditorOptions: function (container) { return '<option value=""></option>'; },

        /// Called after the editor is visible.
        onEditorOpened: null,

        /// Called after the editor receives focus.
        onEditorFocused: null,

        /// Called after the editor has been closed.
        onEditorClosed: null,
    };

    var EDITOR_MARGIN = 5;//TODO: WHY do we need to remove this margin to make the input/select fit its parent container?

    ///
    /// Public LiveEditor Commands
    ///

    $.liveeditor = {
        //version: function () {
        //    return "0.0.1";
        //},

        ///
        /// Enables editing for an unregistered or previously disabled container.
        ///
        enable: function (container) {
            debug("jQuery.liveeditor.enable(container)");
            return enable(container);
        },

        ///
        /// Disables editing for a registered container.
        ///
        disable: function (container) {
            debug("jQuery.liveeditor.disable(container)");
            return disable(container);
        },

        ///
        /// Forces the open editor to save its changes back to its container and close.
        /// Call this method before saving to make sure all changes have been committed.
        ///
        closeEditor: function (container) {
            debug("jQuery.liveeditor.closeEditor(container)");
            //if (container || null === null)
            //    container = $(options.editor._focusedContainer);
            return commitEditor(container);
        },

        ///
        /// Changes the value of a container as if the user had edited it with the editor.
        ///
        set: function (container, value, html) {
            debug("jQuery.liveeditor.set(container, value, html)");
            var originalValue = getContainerValue(container);
            if (container.data('liveeditor-old') === undefined) {
                container.data('liveeditor-old', originalValue);
            }
            if (!updateContainer(container, value, html)) {
                return false;
            }
            if (value !== originalValue) {
                containerChanged(container);
            }
            return true;
        },

        ///
        /// Resets the container to consider its current value the unchanged state.
        /// Call this method for all containers after saving to setup new change-tracking without reloading the entire page.
        ///
        reset: function (container) {
            debug("jQuery.liveeditor.reset(container)");
            container.removeClass('changed');
            container.data('liveeditor-old', undefined);
            containerChanged(container);
            return container;
        }
    };

    ///
    /// Private Event Listeners
    ///

    //Display the editor when the user hovers over the container
    function container_mouseenter() {
        debug("liveeditor.container_mouseenter()");
        displayEditor($(this));
    }

    function container_mouseleave() {
        debug("liveeditor.container_mouseleave()");
        commitEditor(this);//TODO: Should call cancelEditor() instead to make sure the value doesn't change
    }

    //Make the editor "sticky" when focused so it doesn't disappear when the mouse is moved from the container
    function editor_focus() {
        debug('liveeditor.editor_focus()');

        var editor = $(this)
            .unbind('focus', editor_focus)
            .select();
        var container = editor.closest('.liveedit')
            .unbind('mouseleave', container_mouseleave);

        var options = container.data('liveeditor-options');
        if (container[0] === options.editor._focusedContainer) {
            debug('It is the current editing container that got focus. Ignore?!');
            return true; //Since the current containers editor is focused there is no other editor to close
        }

        if (options.editor._focusedContainer) {
            debug('Closing old editing container.');
            debug(options.editor._focusedContainer);
            if (!commitEditor(options.editor._focusedContainer))
                return false;
        }

        debug('Tracking the current editing container.');
        options.editor._focusedContainer = container[0];
        editor.keydown(editor_keydown);
        if ($.isFunction(options.onEditorFocused)) {
            debug("Calling onEditorFocused()");
            options.onEditorFocused.call(container, editor);
        }
        return true;
    }

    //Handle editor TAB and ESC keys
    function editor_keydown(e) {
        var keyCode = e.keyCode || e.which;
        if (keyCode == 27) {       // ESC
            e.preventDefault();
            var container = $(this).closest('.liveedit');
            var options = container.data('liveeditor-options');
            if (!options.editor._focusedContainer) {
                debug("Got ESC keydown for an editor without having a current container. Aborting!");
                return;
            }
            commitEditor(container);//options.editor._focusedContainer
        }
        else if (keyCode == 9) {    //TAB
            e.preventDefault();
            var container = $(this).closest('.liveedit');
            var options = container.data('liveeditor-options');
            if (!options.editor._focusedContainer) {
                debug("Got TAB keydown for an editor without having a current container. Aborting!");
                return;
            }

            //Close the current editor
            var nextContainer = container;//options.editor._focusedContainer; //TODO: Rewrite to use the initialized selector for stepping instead
            commitEditor(container);//options.editor._focusedContainer

            do {
                //Find previous/next editable container
                debug("Selecting next container for editing.");
                if (e.shiftKey) {
                    debug("TAB to prev container");
                    nextContainer = nextContainer.prevAll('.liveedit').eq(0);
                    if (nextContainer.length == 0) {
                        debug("Found no prev container. Moving to parents previous last");
                        nextContainer = $('.liveedit:last', nextContainer.parent().prev());
                    }
                } else {
                    debug("TAB to next container");
                    nextContainer = $("~ .liveedit", nextContainer).eq(0);
                    if (nextContainer.length == 0) {
                        debug("Found no next container. Moving to parents next first");
                        nextContainer = $('.liveedit:first', nextContainer.parent().next());
                    }
                }
                //Open the editor
                if (nextContainer.length > 0) {
                    try {
                        displayEditor(nextContainer).focus();
                        break;
                    } catch (e) {
                        debug("Failed to display editor. Move to the next container.");
                    }
                }
                else {
                    debug("No more containers to test. Not displaying any new editor.");
                    break;
                }
            } while (true);//Iterate through all editing containers until we find one that can be edited now
        }
    }

    ///
    /// Private methods
    ///
    function debug(msg) {
        //if (settings.debug && console)
        //    console.log(msg);
    }
    function enable(container) {
        if (!container.hasClass('liveedit')) {
            container
                .addClass('liveedit')
                .mouseenter(container_mouseenter);
        }
        return container;
    }
    function disable(container) {
        if (container.hasClass('liveedit')) {
            container
                .removeClass('liveedit')
                .unbind('mouseenter', container_mouseenter);
        }
        return container;
    }

    ///
    /// Method called to get the current value of a container before displaying its editor.
    /// Implement the events onGetValue() and onSetValue() if the container does not store its value in LiveEditors default way.
    /// Returns the containers current value as a string.
    ///
    function getContainerValue (container) {
        var value;
        var options = container.data('liveeditor-options');
        if ($.isFunction(options.onGetValue)) {
            debug('Calling onGetValue()');
            value = options.onGetValue.call(container);
        }
        if (!value) {
            debug('Looking up value from container');
            value = container.hasClass(options.combobox.css) || container.hasClass(options.checkbox.css)
                ? container.attr('value')
                : container.text();
        }
        debug('getContainerValue() returns: ' + value);
        return value;
    }

    ///
    /// Method called to set the new value of a container. If the container has an open editor it is closed by this commmand.
    /// Implement the events onGetValue() and onSetValue() if the container does not store its value in LiveEditors default way.
    /// Returns true if the value was written successfully and false if the operation was cancelled.
    ///
    function updateContainer(container, newValue, newHtml) {
        debug("liveeditor.updateContainer(container, newValue, newHtml)");
        var success;

        var oldValue = container.data('liveeditor-old');

        //Let the user override the setting of the value to the container if he likes
        var options = container.data('liveeditor-options');
        if ($.isFunction(options.onSetValue)) {
            debug('Calling onSetValue()');
            var success = options.onSetValue.call(container, value, html);
            if (success === false)
                return false;
        }

        if (success === undefined) {
            //Set the new value to the container
            debug('Setting value for container');
            if (container.hasClass(options.combobox.css)) {
                container.attr('value', newValue);
            }
            else if (container.hasClass(options.checkbox.css)) {
                container.attr('value', newValue);
                newHtml = (newValue == options.checkbox.checked.value) ? options.checkbox.checked.html : options.checkbox.unchecked.html;
            }
            if (newHtml === null || newHtml === undefined)
                newHtml = newValue;
            container.html(newHtml);
        }

        container.unbind('mouseleave', container_mouseleave);

        if (container[0] === options.editor._focusedContainer) {
            debug("Closed the current editing container.");
            options.editor._focusedContainer = null;
        }

        //Update the containers change-status
        if (newValue != oldValue) {
            container.addClass('changed');
            debug("Flagged the container as changed");
        }
        else {
            container.removeClass('changed');
            container.data('liveeditor-old', undefined);
            debug("Flagged the container as unchanged");
        }
        return true;
    }

    function containerChanged (container) {
        var options = container.data('liveeditor-options');
        if ($.isFunction(options.onChanged)) {
            debug("Calling onChanged()");
            options.onChanged.call(container);
        }
    }

    ///
    /// Private Editor methods
    ///

    //Display editor when mouse hovers over an editable container
    function displayEditor(container) {
        debug('liveeditor.displayEditor(container)');
        var options = container.data('liveeditor-options');

        var editor = $('.liveeditor', container);
        if (editor.length) {
            debug("Using the existing editor for the requested container instead of creating a new.");
            return editor; //Already an editor in this container
        }

        var currentValue = getContainerValue(container);
        if (container.data('liveeditor-old') === undefined) {
            container.data('liveeditor-old', currentValue);
        }

        var editor = createEditor(container, currentValue);
        editor.addClass('liveeditor').data('liveeditor-original', currentValue);
        editor.focus(editor_focus);
        container
            .html(editor)
            .mouseleave(container_mouseleave);
        debug("Added editor to the container");

        if ($.isFunction(options.onEditorOpened)) {
            debug("Calling onEditorOpened");
            options.onEditorOpened.call(container, editor);
        }

        debug("liveeditor.displayEditor() DONE");
        return editor;
    }

    function createEditor(container, value) {
        var editor;
        var options = container.data('liveeditor-options');

        var event = options.onEditorCreating;
        if (event) {
            editor = event(container, value);
        }

        if (!editor) {
            if (container.hasClass(options.combobox.css)) {
                editor = $('<select>').width(container.width() - EDITOR_MARGIN);
                var select_options = options.onEditorOptions.call(container);
                switch ($.type(select_options)) {
                    case "string": editor.append($(select_options)); break;
                    default:
                        debug('appending ' + $.type(select_options) + ' options is not supported.');
                        break;
                }
                $('option[value="' + value + '"]', editor).prop('selected', true);
            } else if (container.hasClass(options.checkbox.css))
                editor = $('<input type="checkbox"/>').prop('checked', (value == options.checkbox.checked.value));
            else {
                editor = $('<input type="text"/>').width(container.width() - EDITOR_MARGIN).val(value);
            }
        }

        if (options.editor.css) {
            editor.addClass(options.editor.css);
        }

        return editor;
    }

    //Restore "label" in the container with the new value from the editor
    function commitEditor(obj) {
        debug("liveeditor.commitEditor(obj)");
        var container = $(obj);
        var editor = $('.liveeditor', container);
        if (!editor.length) {
            debug("Found no editor to hide for the requested container. Aborting!");
            return true; //No editor to hide
        }
        var originalValue = editor.data('liveeditor-original');
        var newValue = getEditorValue(editor);
        var newHtml = getEditorHtml(editor);
        if (!updateContainer(container, newValue, newHtml))
            return false;

        var options = container.data('liveeditor-options');
        if (originalValue != newValue) {
            containerChanged(container);
        }
        //Throw the hidden event
        if ($.isFunction(options.onEditorClosed)) {
            debug("Calling onEditorClosed()");
            options.onEditorClosed.call(container);
        }
        return true;
    }

    ///
    /// Method to get the current value from the editor.
    /// Returns the editors value, which MAY differ from its displayed text (for checkboxes/comboboxes for instance).
    ///
    function getEditorValue(editor) {
        debug('liveeditor.getEditorValue()');
        var value;
        var container = editor.closest('.liveedit');
        var options = container.data('liveeditor-options');

        if ($.isFunction(options.onEditorGetValue)) {
            debug('Calling onEditorGetValue()');
            value = options.onEditorGetValue.call(editor);
        }

        if (!value) {
            debug('Getting editor value');
            if (editor.is(':checkbox'))
                value = (editor.prop('checked')
                    ? options.checkbox.checked.value
                    : options.checkbox.unchecked.value);
            else if (editor.is('select'))
                value = $('option:selected', editor).val();
            else
                value = editor.val();
        }

        debug('liveeditor.getEditorValue() returns ' + value);
        return value;
    }

    ///
    /// Method to get the current display text from the editor
    /// Returns the displayed text in the editor, which MAY differ from its value (for checkboxes/comboboxes for instance).
    ///
    function getEditorHtml (editor) {
        debug('liveeditor.getEditorHtml()');
        var html;
        var container = editor.closest('.liveedit');
        var options = container.data('liveeditor-options');

        if ($.isFunction(options.onEditorGetValue)) {
            debug('Calling onEditorGetHtml()');
            html = options.onEditorGetHtml.call(editor);
        }

        if (editor.is('select'))
            html = $(':selected', editor).text();
        else
            html = null;

        debug('liveeditor.getEditorHtml() returns ' + html);
        return html;
    }

    //called on the native object directly, wrap with $(obj) if needed.
    function initializeObject(obj, options) {
        //assign the options to the object instance.
        $(obj).data('liveeditor-options', options);

        //do other initialization tasks on the individual item here...
    }

    ///
    /// LiveEditor Initiator
    /// Use this method to unobtrusively initialize liveeditor for a group of containers.
    /// For example: $('table tbody tr td.editable').liveeditor();
    ///

    $.fn.liveeditor = function (options) {
        debug("jQuery.liveeditor initializing for selection");

        //Build options for the new instance
        var mergedOptions = $.extend({}, defaultOptions, options)
        mergedOptions.editor._focusedContainer = null; //This is just an internal state-variable, so DON'T expose it in defaultOptions!
        //Initialize all objects in the selection
        this.each(function () {
            initializeObject(this, mergedOptions);
        });
        //Enable all objects in the selection
        debug("Enabling selection");
        $.liveeditor.enable(this);

        //TODO: Consider iterating all items in the selector and updating their html if they are checkboxes or comboboxes, to make sure the server generated code isn't diffrent from client side
        //TODO: $('.combo,.checkbox', this).each(function(){ updateContainer(this, this.attr(value)); });

        debug("jQuery.liveeditor initializing DONE");
        return this;
    }

} (jQuery));
<|endoftext|>


<commit_before>var cdb = require('cartodb.js');
cdb.admin = require('cdb.admin');
var LocalStorage = require('../new_common/local_storage');
var HeaderView = require('../new_common/views/dashboard_header_view');
var SupportView = require('../new_common/support_view');
var MamufasImportView = require('./mamufas_import_view');
var ContentControllerView = require('./content_controller_view');
var BackgroundImporterView = require('./background_importer/background_importer_view');
var ImportsModel = require('./background_importer/imports_model');
var HeaderViewModel = require('./header_view_model');

module.exports = cdb.core.View.extend({

  events: {
    'click': '_onClick'
  },

  initialize: function() {
    this._initModels();
    this._initViews();
    this._initBindings();
  },

  _initBindings: function() {
    this.router.model.bind('change', this._onRouterChange, this);
    this.add_related_model(this.router.model);
  },

  _initModels: function() {
    // Why not have only one collection?
    this.collection =  new cdb.admin.Visualizations();

    this.user = this.options.user;
    this.router = this.options.router;
    this.localStorage = new LocalStorage();

    // Update order and category attribute to router model
    this.router.model.set('order',    this.localStorage.get('dashboard.order'), { silent: true });
    this.router.model.set('category', this.localStorage.get('dashboard.category'), { silent: true });
  },

  _onRouterChange: function(m, changes) {
    this._fetchCollection(m, changes);
  },

  _fetchCollection: function(m, changes) {
    var params = this.router.model.attributes;

    // Get order from localStorage if it is not defined or
    // come from other type (tables or visualizations)
    var order = this.localStorage.get("dashboard.order") || 'updated_at';
    var type = params.content_type === "datasets" ? 'table' : 'derived';
    if (params.library) { type = 'remote' }

    // TODO: review, should collection params really be set here?
    this.collection.options.set({
      q:              params.q,
      page:           params.page || 1,
      tags:           params.tag,
      per_page:       this.collection[ "_" + ( params.content_type === "datasets" ? 'TABLES' : 'ITEMS') + '_PER_PAGE'],
      only_shared:    params.shared,
      exclude_shared: !params.shared,
      category:       params.library ? params.category : '',
      locked:         params.locked,
      only_liked:     params.liked,
      order:          order,
      type:           type
    });

    this.collection.fetch();
  },

  _initViews: function() {
    var backgroundImporterView = new BackgroundImporterView({
      router: this.router,
      items: this.collection,
      user: this.user
    });

    this.$el.append(backgroundImporterView.render().el);
    backgroundImporterView.enable();

    var mamufasView = new MamufasImportView({
      el: this.$el,
      user: this.user
    });

    cdb.god.bind('dialogOpened', function() {
      mamufasView.disable();
    }, this);
    cdb.god.bind('dialogClosed', function() {
      mamufasView.enable();
    }, this);

    mamufasView.bind('onDrop', function(files) {
      backgroundImporterView.add(
        new ImportsModel({ upload: { type: 'file', value: files } }, { user: this.user })
      )
    }, this);
    mamufasView.render();
    mamufasView.enable();

    var headerView = new HeaderView({
      el:             this.$('#header'), //pre-rendered in DOM by Rails app
      model:          this.user,
      viewModel:      new HeaderViewModel(this.router),
      router:         this.router,
      localStorage:   this.localStorage
    });
    headerView.render();

    this.controllerView = new ContentControllerView({
      el:           this.$('#content-controller'),
      user:         this.user,
      router:       this.router,
      collection:   this.collection,
      localStorage: this.localStorage
    });

    this.controllerView.bind('datasetSelected', function(d) {
      backgroundImporterView.add(
        new ImportsModel({ upload: d }, { user: this.user })
      )
    }, this);
    this.controllerView.bind('remoteSelected', function(d) {
      backgroundImporterView.add(
        new ImportsModel({ upload: d }, { user: this.user })
      )
    }, this);
    this.controllerView.render();

    var supportView = new SupportView({
      el: this.$('#support-banner'),
      user: this.user
    });

    supportView.render();
  },

  // In case user clicks out of any dialog "body" will fire
  // a closeDialogs event
  _onClick: function() {
    cdb.god.trigger("closeDialogs");
  }

});
<commit_msg>Replaced shared parameter + added types parameter for collection items options<commit_after>var cdb = require('cartodb.js');
cdb.admin = require('cdb.admin');
var LocalStorage = require('../new_common/local_storage');
var HeaderView = require('../new_common/views/dashboard_header_view');
var SupportView = require('../new_common/support_view');
var MamufasImportView = require('./mamufas_import_view');
var ContentControllerView = require('./content_controller_view');
var BackgroundImporterView = require('./background_importer/background_importer_view');
var ImportsModel = require('./background_importer/imports_model');
var HeaderViewModel = require('./header_view_model');

module.exports = cdb.core.View.extend({

  events: {
    'click': '_onClick'
  },

  initialize: function() {
    this._initModels();
    this._initViews();
    this._initBindings();
  },

  _initBindings: function() {
    this.router.model.bind('change', this._onRouterChange, this);
    this.add_related_model(this.router.model);
  },

  _initModels: function() {
    // Why not have only one collection?
    this.collection =  new cdb.admin.Visualizations();

    this.user = this.options.user;
    this.router = this.options.router;
    this.localStorage = new LocalStorage();

    // Update order and category attribute to router model
    this.router.model.set('order',    this.localStorage.get('dashboard.order'), { silent: true });
    this.router.model.set('category', this.localStorage.get('dashboard.category'), { silent: true });
  },

  _onRouterChange: function(m, changes) {
    this._fetchCollection(m, changes);
  },

  _fetchCollection: function(m, changes) {
    var params = this.router.model.attributes;

    // Get order from localStorage if it is not defined or
    // come from other type (tables or visualizations)
    var order = this.localStorage.get("dashboard.order") || 'updated_at';
    var types = params.content_type === "datasets" ? 'table' : 'derived';

    // Requesting data library items?
    if (params.library) {
      types = 'remote';
    }

    // Supporting search in data library and user datasets at the same time
    if ((params.q || params.tag) && params.content_type === "datasets") {
      types = 'table,remote';
    }

    // TODO: review, should collection params really be set here?
    this.collection.options.set({
      q:              params.q,
      page:           params.page || 1,
      tags:           params.tag,
      per_page:       this.collection[ "_" + ( params.content_type === "datasets" ? 'TABLES' : 'ITEMS') + '_PER_PAGE'],
      shared:         params.shared,
      locked:         params.locked,
      only_liked:     params.liked,
      order:          order,
      types:          types,
      type:           ''
    });

    this.collection.fetch();
  },

  _initViews: function() {
    var backgroundImporterView = new BackgroundImporterView({
      router: this.router,
      items: this.collection,
      user: this.user
    });

    this.$el.append(backgroundImporterView.render().el);
    backgroundImporterView.enable();

    var mamufasView = new MamufasImportView({
      el: this.$el,
      user: this.user
    });

    cdb.god.bind('dialogOpened', function() {
      mamufasView.disable();
    }, this);
    cdb.god.bind('dialogClosed', function() {
      mamufasView.enable();
    }, this);

    mamufasView.bind('onDrop', function(files) {
      backgroundImporterView.add(
        new ImportsModel({ upload: { type: 'file', value: files } }, { user: this.user })
      )
    }, this);
    mamufasView.render();
    mamufasView.enable();

    var headerView = new HeaderView({
      el:             this.$('#header'), //pre-rendered in DOM by Rails app
      model:          this.user,
      viewModel:      new HeaderViewModel(this.router),
      router:         this.router,
      localStorage:   this.localStorage
    });
    headerView.render();

    this.controllerView = new ContentControllerView({
      el:           this.$('#content-controller'),
      user:         this.user,
      router:       this.router,
      collection:   this.collection,
      localStorage: this.localStorage
    });

    this.controllerView.bind('datasetSelected', function(d) {
      backgroundImporterView.add(
        new ImportsModel({ upload: d }, { user: this.user })
      )
    }, this);
    this.controllerView.bind('remoteSelected', function(d) {
      backgroundImporterView.add(
        new ImportsModel({ upload: d }, { user: this.user })
      )
    }, this);
    this.controllerView.render();

    var supportView = new SupportView({
      el: this.$('#support-banner'),
      user: this.user
    });

    supportView.render();
  },

  // In case user clicks out of any dialog "body" will fire
  // a closeDialogs event
  _onClick: function() {
    cdb.god.trigger("closeDialogs");
  }

});
<|endoftext|>


<commit_before>		(function( $ ){

			$.fn.noUiSlider = function( method, options ) {

				var settings = {
					'bar'			: true,			// Should the bar be used? Set to 'false' or LEGACY 'off'
					'dontActivate'	: '',			// Set to Upper or lower.
					'scale'			: '',			// NEW. Use like [0,50] or omit.
					'startMin'		: '25',
					'startMax'		: '75',

					'point'			: '',			// Accepts [array/both, lower, upper, 0, 1]
					'saveScale'		: false,
					'moveStyle'		: '',			// set To Animate!
					'setTo'			: '',			// INT, [INT,INT]

				// Callbacks	*/
					'change'		: '',
					'callback'		: '',			// Callback to be triggered on release of dot.
					'knobRelease'	: '',			// rename for Callback
					'tracker'		: '',			// Callback to be triggered on every dot movement.
					'clickmove'		: '',			// Callback to be triggered on movement by clicking.
				};

				function rebuildMidBar(element){
					var handles=new Array();
					if(element.find('.noUi_handle.noUi_lowerHandle').length){
						handles[0]=parseInt(element.find('.noUi_handle.noUi_lowerHandle').css('left'));
						if(isNaN(handles[0])){handles[0] = 0;}
					} else { handles[0] = 0; }
					if(element.find('.noUi_handle.noUi_upperHandle').length){
						handles[1]=(parseInt(element.css('width'))-parseInt(element.find('.noUi_handle.noUi_upperHandle').css('left')));
						if(isNaN(handles[1])){handles[1] = '100%';}
					} else { handles[1] = 0; }
					element.find('.noUi_midBar').css({'left':handles[0],'right':handles[1]});
				}

				function locToScale(element, input, knob, scale){
					var elementWidth = parseInt(element.css('width'));
					var knobWidth = parseInt(knob.css('width'));
					if(!scale){ scale=[0,100]; }
					return ((elementWidth/(scale[1]-scale[0]))*(parseInt(input)-scale[0]))-(knobWidth/2);
				}

				function scaleToLoc(element, knob, scale){
					var elementWidth = parseInt(element.css('width'));
					var knobWidth = parseInt(knob.css('width'));
					if(!scale){ scale=[0,100]; }

					var left=knob.css('left');
					// gitHub issue #6;
					if(left=='auto'){left=0;}

					var value = parseInt(left) + ( knobWidth/2 );
						value = value / ( elementWidth / (scale[1]-scale[0]) );
						value = value + scale[0];

					return value;
				}

				var methods = {

					init:		function init(){

									return this.each(function(){

										if(!settings.knobRelease && settings.callBack){
											settings.knobRelease=settings.callBack;
										}

										var element = $(this);
										var elementWidth = parseInt(element.css('width'));

										$.event.props = $.event.props.join('|').replace('layerX|layerY|', '').split('|');

										$(this).css('position','relative');

										if(settings.dontActivate.toLowerCase()!='lower'){
											$(this).append('

');
										}

										if(settings.bar && settings.bar!='off'){
											$(this).append('

');
										}

										if(settings.dontActivate.toLowerCase()!='upper'){
											$(this).append('

');
										}

										$(this).data('activated',[element.find('.noUi_handle.noUi_lowerHandle').length,element.find('.noUi_handle.noUi_upperHandle').length]);

										$(this)
											.children().css('position', 'absolute')
										;

										$(this)
											.data('change',options.change)
										;

										$(this)
											.find('.noUi_midBar')
											.css({'left':0,'right':0})
										;

										if(settings.scale){
											$(this).data('scale', settings.scale);
										}

										var knobs = $(this).find('.noUi_sliderKnob');

										knobs.each(function(){

											var knob = $(this).parent('.noUi_handle');

											if(knob.hasClass('noUi_lowerHandle')&&(settings.startMin || (settings.startMin===0))){
												if(typeof(settings.startMin)=='string' && (settings.startMin.indexOf('%')!=-1)){
													knob.css('left', locToScale(element,settings.startMin,knob));
												} else {
													knob.css('left', locToScale(element,settings.startMin,knob,settings.scale));
												}
											}

											if(knob.hasClass('noUi_upperHandle')&&settings.startMax){
												if(typeof(settings.startMax)=='string' && (settings.startMax.indexOf('%')!=-1)){
													knob.css('left', locToScale(element,settings.startMax,knob));
												} else {
													knob.css('left', locToScale(element,settings.startMax,knob,settings.scale));
												}
											}

										});

										if(settings.bar && settings.bar!='off'){rebuildMidBar(element);}

										knobs.bind('mousedown.noUiSlider',function(e){

											/* Fixes */
												e.preventDefault();
												$('body').bind('selectstart.noUiSlider', function(e){return false;});
												$(this).addClass('noUi_activeHandle');

											var knob = $(this).parent('.noUi_handle');

											var status = element.data('activated')[0] && element.data('activated')[1];

											$(document).bind('mousemove.noUiSlider', function(f){

												var knobCorrection=parseInt(knob.css('width'));
												var flattened = f.pageX-(element.offset().left);	// GitHub issue #5, fix by instanceoftom

												/* lower knob */

												if(knob.hasClass('noUi_lowerHandle')||!status){

													if(flattened<(-1*(parseInt(knob.css('width'))/2))){
														flattened=(-1*(parseInt(knob.css('width'))/2));
													}

													if(status){
														var l=(parseInt(knob.parent().find('.noUi_upperHandle').css('left'))-knobCorrection);
														if(flattened>l){
															flattened=l;
														}
													}

												}

												/* upper knob */

												if(knob.hasClass('noUi_upperHandle')||!status){

													var correctedElementWidth = (elementWidth-(knobCorrection/2));

													if(flattened>correctedElementWidth){
														flattened=correctedElementWidth;
													}

													if(status){
														var l=(parseInt(knob.parent().find('.noUi_lowerHandle').css('left'))+knobCorrection);
														if(flattened<l){
															flattened=l;
														}
													}

												}

												knob.css({'left':flattened});

												if(settings.bar&&settings.bar!='off'){
													rebuildMidBar(element);
												}

												if ( typeof(options.tracker) == "function" ){ options.tracker.call(this); }

											});

											$(document).bind('mouseup.noUiSlider',function(){

												$(this).unbind('mousemove.noUiSlider');
												knobs.removeClass('noUi_activeHandle');
												$('body').unbind('selectstart.noUiSlider');

												if ( typeof(options.knobRelease) == "function" ){ options.knobRelease.call(element); }
												if ( typeof(options.change) == "function" ){ options.change.call(element); }

												$(this).unbind('mouseup.noUiSlider');
											});

										});

										$(this).bind('click.noUiSlider',function(e){

											var dot0 = e.pageX;
											var thebar = $(this).offset().left;

											if($(this).data('activated')[0] && $(this).data('activated')[1]){

												var dot1 = $(this).children(".noUi_lowerHandle").offset().left;
												var dot2 = $(this).children(".noUi_upperHandle").offset().left;

												var z = (dot1 + dot2) / 2;

												if ( dot0 > z ){
													$(this).children(".noUi_upperHandle").css("left", (dot0 - thebar));
												} else {
													$(this).children(".noUi_lowerHandle").css("left", (dot0 - thebar));
												}

											} else {
												if ($(this).data('activated')[0]){
													$(this).children(".noUi_lowerHandle").css("left", (dot0 - thebar));
												}
												if ($(this).data('activated')[1]){
													$(this).children(".noUi_upperHandle").css("left", (dot0 - thebar));
												}
											}

											if(settings.bar&&settings.bar!='off'){
												rebuildMidBar(element);
											}

											if ( typeof(options.clickmove) == "function" ){ options.clickmove.call(this); }
											if ( typeof(options.change) == "function" ){ options.change.call(this); }

											e.stopPropagation();

										}).children().not('.noUi_midBar').click(function(e) {
											return false;	// issue 6
										});

									});

								},

					move:		function move(){

									var element = $(this);

									var ok = false;

									/* if point was omitted */
									if(!settings.point){
										if($(this).data('activated')[0] && $(this).data('activated')[1]){
											ok = true;
										} else {
											if($(this).data('activated')[0]){
												settings.point = 0;
											}
											if($(this).data('activated')[1]){
												settings.point = 1;
											}
										}
									}

									if(settings.saveScale){
										$(this).data('scale',settings.scale);
									}

									/* if scale was omitted */
									if(!settings.scale){
										if(!$(this).data('scale')){
											settings.scale=[0,100];
										} else {
											settings.scale=$(this).data('scale');
										}
									}

									/* It is not necessary to specify an array for one dot. */
									if(typeof(settings.setTo)!='object'){
										if(settings.point=='lower'||settings.point==0){
											settings.setTo = [settings.setTo,0]
										}
										if(settings.point=='upper'||settings.point==1){
											settings.setTo = [0,settings.setTo]
										}
									}

									if(settings.point=='lower'||settings.point==0 ||ok){
										var newKnob1 = $(this).find('.noUi_lowerHandle');
										var value1 = locToScale(element, settings.setTo[0], newKnob1, settings.scale);
										if(settings.moveStyle=='animate'){
											newKnob1.animate({'left':value1}, {step: function(){if(settings.bar&&settings.bar!='off'){ rebuildMidBar(element); }}});
										} else {
											newKnob1.css('left',value1);
										}
									}

									if(settings.point=='upper'||settings.point==1||ok){
										var newKnob2 = $(this).find('.noUi_upperHandle');
										var value2 = locToScale(element, settings.setTo[1],  newKnob2, settings.scale );
										if(settings.moveStyle=='animate'){
											newKnob2.animate({'left':value2}, {step: function(){if(settings.bar&&settings.bar!='off'){ rebuildMidBar(element); }}});
										} else {
											newKnob2.css('left',value2);
										}
									}

									var changeFunction=$(this).data('change');
									if(settings.bar&&settings.bar!='off'){ rebuildMidBar(element); }
									if ( typeof(changeFunction) == "function" ){ changeFunction.call(this); }

								},

					reset:		function reset(){

								},

					getValue:	function getValue(){

									if(!settings.point){ settings.point = 'array'; }

									if(!settings.scale){
										if($(this).data('scale')=='undefined'){
											settings.scale=[0,100];
										} else {
											settings.scale=$(this).data('scale');
										}
									}

									returnA = new Array();

									if($(this).data('activated')[0]){
										returnA.push(scaleToLoc($(this), $(this).find('.noUi_lowerHandle'), settings.scale));
									}

									if($(this).data('activated')[1]){
										returnA.push(scaleToLoc($(this), $(this).find('.noUi_upperHandle'), settings.scale));
									}

									if(settings.point=='lower'||settings.point==0){
										return returnA[0];
									}

									if(settings.point=='upper'||settings.point==1){
										return returnA[1];
									}

									if(settings.point=='array'){
										return returnA;
									}

								}

				};

				var options = $.extend( settings, options );

				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.noUiSlider' );
				}

			};

		})( jQuery );<commit_msg>Don't parse input in locToScale to int -- it may be float.<commit_after>		(function( $ ){

			$.fn.noUiSlider = function( method, options ) {

				var settings = {
					'bar'			: true,			// Should the bar be used? Set to 'false' or LEGACY 'off'
					'dontActivate'	: '',			// Set to Upper or lower.
					'scale'			: '',			// NEW. Use like [0,50] or omit.
					'startMin'		: '25',
					'startMax'		: '75',

					'point'			: '',			// Accepts [array/both, lower, upper, 0, 1]
					'saveScale'		: false,
					'moveStyle'		: '',			// set To Animate!
					'setTo'			: '',			// INT, [INT,INT]

				// Callbacks	*/
					'change'		: '',
					'callback'		: '',			// Callback to be triggered on release of dot.
					'knobRelease'	: '',			// rename for Callback
					'tracker'		: '',			// Callback to be triggered on every dot movement.
					'clickmove'		: '',			// Callback to be triggered on movement by clicking.
				};

				function rebuildMidBar(element){
					var handles=new Array();
					if(element.find('.noUi_handle.noUi_lowerHandle').length){
						handles[0]=parseInt(element.find('.noUi_handle.noUi_lowerHandle').css('left'));
						if(isNaN(handles[0])){handles[0] = 0;}
					} else { handles[0] = 0; }
					if(element.find('.noUi_handle.noUi_upperHandle').length){
						handles[1]=(parseInt(element.css('width'))-parseInt(element.find('.noUi_handle.noUi_upperHandle').css('left')));
						if(isNaN(handles[1])){handles[1] = '100%';}
					} else { handles[1] = 0; }
					element.find('.noUi_midBar').css({'left':handles[0],'right':handles[1]});
				}

				function locToScale(element, input, knob, scale){
					var elementWidth = parseInt(element.css('width'));
					var knobWidth = parseInt(knob.css('width'));
					if(!scale){ scale=[0,100]; }
					return ((elementWidth/(scale[1]-scale[0]))*(parseFloat(input)-scale[0]))-(knobWidth/2);
				}

				function scaleToLoc(element, knob, scale){
					var elementWidth = parseInt(element.css('width'));
					var knobWidth = parseInt(knob.css('width'));
					if(!scale){ scale=[0,100]; }

					var left=knob.css('left');
					// gitHub issue #6;
					if(left=='auto'){left=0;}

					var value = parseInt(left) + ( knobWidth/2 );
						value = value / ( elementWidth / (scale[1]-scale[0]) );
						value = value + scale[0];

					return value;
				}

				var methods = {

					init:		function init(){

									return this.each(function(){

										if(!settings.knobRelease && settings.callBack){
											settings.knobRelease=settings.callBack;
										}

										var element = $(this);
										var elementWidth = parseInt(element.css('width'));

										$.event.props = $.event.props.join('|').replace('layerX|layerY|', '').split('|');

										$(this).css('position','relative');

										if(settings.dontActivate.toLowerCase()!='lower'){
											$(this).append('

');
										}

										if(settings.bar && settings.bar!='off'){
											$(this).append('

');
										}

										if(settings.dontActivate.toLowerCase()!='upper'){
											$(this).append('

');
										}

										$(this).data('activated',[element.find('.noUi_handle.noUi_lowerHandle').length,element.find('.noUi_handle.noUi_upperHandle').length]);

										$(this)
											.children().css('position', 'absolute')
										;

										$(this)
											.data('change',options.change)
										;

										$(this)
											.find('.noUi_midBar')
											.css({'left':0,'right':0})
										;

										if(settings.scale){
											$(this).data('scale', settings.scale);
										}

										var knobs = $(this).find('.noUi_sliderKnob');

										knobs.each(function(){

											var knob = $(this).parent('.noUi_handle');

											if(knob.hasClass('noUi_lowerHandle')&&(settings.startMin || (settings.startMin===0))){
												if(typeof(settings.startMin)=='string' && (settings.startMin.indexOf('%')!=-1)){
													knob.css('left', locToScale(element,settings.startMin,knob));
												} else {
													knob.css('left', locToScale(element,settings.startMin,knob,settings.scale));
												}
											}

											if(knob.hasClass('noUi_upperHandle')&&settings.startMax){
												if(typeof(settings.startMax)=='string' && (settings.startMax.indexOf('%')!=-1)){
													knob.css('left', locToScale(element,settings.startMax,knob));
												} else {
													knob.css('left', locToScale(element,settings.startMax,knob,settings.scale));
												}
											}

										});

										if(settings.bar && settings.bar!='off'){rebuildMidBar(element);}

										knobs.bind('mousedown.noUiSlider',function(e){

											/* Fixes */
												e.preventDefault();
												$('body').bind('selectstart.noUiSlider', function(e){return false;});
												$(this).addClass('noUi_activeHandle');

											var knob = $(this).parent('.noUi_handle');

											var status = element.data('activated')[0] && element.data('activated')[1];

											$(document).bind('mousemove.noUiSlider', function(f){

												var knobCorrection=parseInt(knob.css('width'));
												var flattened = f.pageX-(element.offset().left);	// GitHub issue #5, fix by instanceoftom

												/* lower knob */

												if(knob.hasClass('noUi_lowerHandle')||!status){

													if(flattened<(-1*(parseInt(knob.css('width'))/2))){
														flattened=(-1*(parseInt(knob.css('width'))/2));
													}

													if(status){
														var l=(parseInt(knob.parent().find('.noUi_upperHandle').css('left'))-knobCorrection);
														if(flattened>l){
															flattened=l;
														}
													}

												}

												/* upper knob */

												if(knob.hasClass('noUi_upperHandle')||!status){

													var correctedElementWidth = (elementWidth-(knobCorrection/2));

													if(flattened>correctedElementWidth){
														flattened=correctedElementWidth;
													}

													if(status){
														var l=(parseInt(knob.parent().find('.noUi_lowerHandle').css('left'))+knobCorrection);
														if(flattened<l){
															flattened=l;
														}
													}

												}

												knob.css({'left':flattened});

												if(settings.bar&&settings.bar!='off'){
													rebuildMidBar(element);
												}

												if ( typeof(options.tracker) == "function" ){ options.tracker.call(this); }

											});

											$(document).bind('mouseup.noUiSlider',function(){

												$(this).unbind('mousemove.noUiSlider');
												knobs.removeClass('noUi_activeHandle');
												$('body').unbind('selectstart.noUiSlider');

												if ( typeof(options.knobRelease) == "function" ){ options.knobRelease.call(element); }
												if ( typeof(options.change) == "function" ){ options.change.call(element); }

												$(this).unbind('mouseup.noUiSlider');
											});

										});

										$(this).bind('click.noUiSlider',function(e){

											var dot0 = e.pageX;
											var thebar = $(this).offset().left;

											if($(this).data('activated')[0] && $(this).data('activated')[1]){

												var dot1 = $(this).children(".noUi_lowerHandle").offset().left;
												var dot2 = $(this).children(".noUi_upperHandle").offset().left;

												var z = (dot1 + dot2) / 2;

												if ( dot0 > z ){
													$(this).children(".noUi_upperHandle").css("left", (dot0 - thebar));
												} else {
													$(this).children(".noUi_lowerHandle").css("left", (dot0 - thebar));
												}

											} else {
												if ($(this).data('activated')[0]){
													$(this).children(".noUi_lowerHandle").css("left", (dot0 - thebar));
												}
												if ($(this).data('activated')[1]){
													$(this).children(".noUi_upperHandle").css("left", (dot0 - thebar));
												}
											}

											if(settings.bar&&settings.bar!='off'){
												rebuildMidBar(element);
											}

											if ( typeof(options.clickmove) == "function" ){ options.clickmove.call(this); }
											if ( typeof(options.change) == "function" ){ options.change.call(this); }

											e.stopPropagation();

										}).children().not('.noUi_midBar').click(function(e) {
											return false;	// issue 6
										});

									});

								},

					move:		function move(){

									var element = $(this);

									var ok = false;

									/* if point was omitted */
									if(!settings.point){
										if($(this).data('activated')[0] && $(this).data('activated')[1]){
											ok = true;
										} else {
											if($(this).data('activated')[0]){
												settings.point = 0;
											}
											if($(this).data('activated')[1]){
												settings.point = 1;
											}
										}
									}

									if(settings.saveScale){
										$(this).data('scale',settings.scale);
									}

									/* if scale was omitted */
									if(!settings.scale){
										if(!$(this).data('scale')){
											settings.scale=[0,100];
										} else {
											settings.scale=$(this).data('scale');
										}
									}

									/* It is not necessary to specify an array for one dot. */
									if(typeof(settings.setTo)!='object'){
										if(settings.point=='lower'||settings.point==0){
											settings.setTo = [settings.setTo,0]
										}
										if(settings.point=='upper'||settings.point==1){
											settings.setTo = [0,settings.setTo]
										}
									}

									if(settings.point=='lower'||settings.point==0 ||ok){
										var newKnob1 = $(this).find('.noUi_lowerHandle');
										var value1 = locToScale(element, settings.setTo[0], newKnob1, settings.scale);
										if(settings.moveStyle=='animate'){
											newKnob1.animate({'left':value1}, {step: function(){if(settings.bar&&settings.bar!='off'){ rebuildMidBar(element); }}});
										} else {
											newKnob1.css('left',value1);
										}
									}

									if(settings.point=='upper'||settings.point==1||ok){
										var newKnob2 = $(this).find('.noUi_upperHandle');
										var value2 = locToScale(element, settings.setTo[1],  newKnob2, settings.scale );
										if(settings.moveStyle=='animate'){
											newKnob2.animate({'left':value2}, {step: function(){if(settings.bar&&settings.bar!='off'){ rebuildMidBar(element); }}});
										} else {
											newKnob2.css('left',value2);
										}
									}

									var changeFunction=$(this).data('change');
									if(settings.bar&&settings.bar!='off'){ rebuildMidBar(element); }
									if ( typeof(changeFunction) == "function" ){ changeFunction.call(this); }

								},

					reset:		function reset(){

								},

					getValue:	function getValue(){

									if(!settings.point){ settings.point = 'array'; }

									if(!settings.scale){
										if($(this).data('scale')=='undefined'){
											settings.scale=[0,100];
										} else {
											settings.scale=$(this).data('scale');
										}
									}

									returnA = new Array();

									if($(this).data('activated')[0]){
										returnA.push(scaleToLoc($(this), $(this).find('.noUi_lowerHandle'), settings.scale));
									}

									if($(this).data('activated')[1]){
										returnA.push(scaleToLoc($(this), $(this).find('.noUi_upperHandle'), settings.scale));
									}

									if(settings.point=='lower'||settings.point==0){
										return returnA[0];
									}

									if(settings.point=='upper'||settings.point==1){
										return returnA[1];
									}

									if(settings.point=='array'){
										return returnA;
									}

								}

				};

				var options = $.extend( settings, options );

				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.noUiSlider' );
				}

			};

		})( jQuery );<|endoftext|>


<commit_before>const smash = require("../../../smash");
const logger = smash.logger();
const errorUtil = smash.errorUtil();
const Request = require("./lib/request");
const Response = require("./lib/response");
const Router = require("./lib/router");
const { RESPONSE_HEADERS_DEFAULT } = require("./lib/constant");

class ApiGatewayProxyRest {
	constructor() {
		this.router = new Router();
	}

	_buildRequest(event, context) {
		const request = new Request(event, context);
		return request;
	}

	_buildResponse(request) {
		const response = new Response(this, request);
		const headers = smash.config.get(RESPONSE_HEADERS_DEFAULT);
		response.addHeaders(headers);
		return response;
	}

	_buildErrorResponse({ requestContext }) {
		const request = {};
		if (requestContext.requestId) {
			request.requestId = requestContext.requestId;
		}
		return this._buildResponse(request);
	}

	handleEvent(event, context, callback) {
		if (typeof callback !== 'function') {
			throw new errorUtil.TypeError("Third parameter of handleEvent() must be a function, ", callback);
		}
		try {
			this._callback = callback;
			const request = this._buildRequest(event, context);
			const response = this._buildResponse(request);
			if (typeof event !== "object" || this.isEvent(event) === false) {
				response.handleError(errorUtil.internalServerError("Wrong type of event as argument to ApiGatewayProxy.handleEvent()"));
			} else {
				logger.info("RequestId: " + request.requestId);
				try {
					this.router.handleRequest(request, response);
				} catch (error) {
					return response.handleError(error);
				}
				this.handleRequest(request, response);
			}
		} catch (error) {
			const response = this._buildErrorResponse(event);
			response.handleError(error);
		}
	}

	async handleRequest(request, response) {
		logger.info("Matched route: " + request.route.method + " " + request.route.path + "/" + request.path + "; version: " + request.route.version + "; user: " + (request.user ? JSON.stringify(request.user) : "Anonymous"));
		smash.setCurrentEvent(request);
		try {
			if (smash.filter.hasInRule(request.route) === true) {
				await smash.filter.cleanIn(request.route, request);
			}
			await request.route.callback.call(smash, request, response);
		} catch (error) {
			response.handleError(error);
		}
		return this;
	}

	handleResponse(response) {
		logger.info("Response code: " + response.code);
		this._callback(null, {
			statusCode: response.code,
			headers: response.headers,
			body: response.stringifiedBody,
		});
		return this;
	}

	isEvent(event) {
		if (event.httpMethod && event.path && !event.type) {
			return true;
		}
		return false;
	}

	get(route, callback) {
		this.router.get(route, callback);
		return this;
	}

	post(route, callback) {
		this.router.post(route, callback);
		return this;
	}

	put(route, callback) {
		this.router.put(route, callback);
		return this;
	}

	delete(route, callback) {
		this.router.delete(route, callback);
		return this;
	}

	patch(route, callback) {
		this.router.patch(route, callback);
		return this;
	}

	options(route, callback) {
		this.router.options(route, callback);
		return this;
	}

	head(route, callback) {
		this.router.head(route, callback);
		return this;
	}

	getHandlers() {
		return this.getRoutes();
	}

	getRoutes() {
		return this.router.getRoutes();
	}

	expose() {
		return [
			{
				"functionName": "get",
				"function": "get",
			},
			{
				"functionName": "post",
				"function": "post",
			},
			{
				"functionName": "put",
				"function": "put",
			},
			{
				"functionName": "delete",
				"function": "delete",
			},
			{
				"functionName": "patch",
				"function": "patch",
			},
			{
				"functionName": "options",
				"function": "options",
			},
			{
				"functionName": "head",
				"function": "head",
			},
		];
	}
}

module.exports = ApiGatewayProxyRest;
<commit_msg>Fix log on rest api middleware<commit_after>const smash = require("../../../smash");
const logger = smash.logger();
const errorUtil = smash.errorUtil();
const Request = require("./lib/request");
const Response = require("./lib/response");
const Router = require("./lib/router");
const { RESPONSE_HEADERS_DEFAULT } = require("./lib/constant");

class ApiGatewayProxyRest {
	constructor() {
		this.router = new Router();
	}

	_buildRequest(event, context) {
		const request = new Request(event, context);
		return request;
	}

	_buildResponse(request) {
		const response = new Response(this, request);
		const headers = smash.config.get(RESPONSE_HEADERS_DEFAULT);
		response.addHeaders(headers);
		return response;
	}

	_buildErrorResponse({ requestContext }) {
		const request = {};
		if (requestContext.requestId) {
			request.requestId = requestContext.requestId;
		}
		return this._buildResponse(request);
	}

	handleEvent(event, context, callback) {
		if (typeof callback !== 'function') {
			throw new errorUtil.TypeError("Third parameter of handleEvent() must be a function, ", callback);
		}
		try {
			this._callback = callback;
			const request = this._buildRequest(event, context);
			const response = this._buildResponse(request);
			if (typeof event !== "object" || this.isEvent(event) === false) {
				response.handleError(errorUtil.internalServerError("Wrong type of event as argument to ApiGatewayProxy.handleEvent()"));
			} else {
				logger.info("RequestId: " + request.requestId);
				try {
					this.router.handleRequest(request, response);
				} catch (error) {
					return response.handleError(error);
				}
				this.handleRequest(request, response);
			}
		} catch (error) {
			const response = this._buildErrorResponse(event);
			response.handleError(error);
		}
	}

	getPrintableUser(request) {
		if (request.user) {
			const { id, account, username, region } = request.user;
			return JSON.stringify({ id, username, account, region });
		}
		return "Anonymous";
	}

	async handleRequest(request, response) {
		logger.info("Matched route: " + request.route.method + " " + request.route.path + " => " + request.path + "; version: " + request.route.version + "; user: " + this.getPrintableUser(request));
		smash.setCurrentEvent(request);
		try {
			if (smash.filter.hasInRule(request.route) === true) {
				await smash.filter.cleanIn(request.route, request);
			}
			await request.route.callback.call(smash, request, response);
		} catch (error) {
			response.handleError(error);
		}
		return this;
	}

	handleResponse(response) {
		logger.info("Response code: " + response.code);
		this._callback(null, {
			statusCode: response.code,
			headers: response.headers,
			body: response.stringifiedBody,
		});
		return this;
	}

	isEvent(event) {
		if (event.httpMethod && event.path && !event.type) {
			return true;
		}
		return false;
	}

	get(route, callback) {
		this.router.get(route, callback);
		return this;
	}

	post(route, callback) {
		this.router.post(route, callback);
		return this;
	}

	put(route, callback) {
		this.router.put(route, callback);
		return this;
	}

	delete(route, callback) {
		this.router.delete(route, callback);
		return this;
	}

	patch(route, callback) {
		this.router.patch(route, callback);
		return this;
	}

	options(route, callback) {
		this.router.options(route, callback);
		return this;
	}

	head(route, callback) {
		this.router.head(route, callback);
		return this;
	}

	getHandlers() {
		return this.getRoutes();
	}

	getRoutes() {
		return this.router.getRoutes();
	}

	expose() {
		return [
			{
				"functionName": "get",
				"function": "get",
			},
			{
				"functionName": "post",
				"function": "post",
			},
			{
				"functionName": "put",
				"function": "put",
			},
			{
				"functionName": "delete",
				"function": "delete",
			},
			{
				"functionName": "patch",
				"function": "patch",
			},
			{
				"functionName": "options",
				"function": "options",
			},
			{
				"functionName": "head",
				"function": "head",
			},
		];
	}
}

module.exports = ApiGatewayProxyRest;
<|endoftext|>


<commit_before>/**
 * JQuery plugin that scales and centers a block element inside its parent's
 * bounding box.  Mainly designed for images.  Scaling preserves aspect ratio,
 * and centering is both horizontal and vertical.
 *
 * Author: Seth Davenport, http://www.sethdavenport.com
 *
 *  Copyright 2013 Seth Davenport
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at

 *   http://www.apache.org/licenses/LICENSE-2.0

 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Shrinkwrap: scales and centers an image inside its container's box.
 *
 * Scaling preserves aspect ratio.
 * Centering is both horizontal and vertical.
 */
(function($) {
    $.fn.extend({
        shrinkWrap: function() {
            return $(this).fitToParentBox().centerInParentBox();
        },

        /**
         * Fits an item inside its container's box.  Scaling preserves aspect ratio.
         */
        fitToParentBox: function() {
            return this.each(function() {
                var item = $(this);
                var box = $(this).parent();

                // Figure out which dimension needs to be scaled the most.
                var widthDelta = box.width() - item.width();
                var heightDelta = box.height() - item.height();

                newWidth = item.width();
                newHeight = item.height();
                if (widthDelta > heightDelta) {
                    newWidth = 'auto';
                    newHeight = '100%';
                }
                else {
                    newWidth = '100%';
                    newHeight = 'auto';
                }

                item.css('position', 'relative');
                item.css('width', newWidth);
                item.css('height', newHeight);
            });
        },

        /**
         * Centres an item inside its container's box.
         */
        centerInParentBox: function() {
            return this.each(function() {
                var item = $(this);
                var box = $(this).parent();

                var widthDelta = box.width() - item.width();
                var heightDelta = box.height() - item.height();

                item.css('position', 'relative');
                item.css('left', (widthDelta / 2) + 'px');
                item.css('top', (heightDelta / 2)  + 'px');
            });
        }
    });
})(jQuery);
<commit_msg>Minor cleanup.<commit_after>/**
 * JQuery plugin that scales and centers a block element inside its parent's
 * bounding box.  Mainly designed for images.  Scaling preserves aspect ratio,
 * and centering is both horizontal and vertical.
 *
 * Author: Seth Davenport, http://www.sethdavenport.com
 *
 *  Copyright 2013 Seth Davenport
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at

 *   http://www.apache.org/licenses/LICENSE-2.0

 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Shrinkwrap: scales and centers an image inside its container's box.
 *
 * Scaling preserves aspect ratio.
 * Centering is both horizontal and vertical.
 */
(function($) {
    $.fn.extend({
        shrinkWrap: function() {
            return $(this).fitToParentBox().centerInParentBox();
        },

        /**
         * Fits an item inside its container's box.  Scaling preserves aspect
         * ratio.
         */
        fitToParentBox: function() {
            var item = $(this);
            var box = item.parent();

            // Figure out which dimension needs to be scaled the most.
            var widthDelta = box.width() - item.width();
            var heightDelta = box.height() - item.height();

            newWidth = item.width();
            newHeight = item.height();
            if (widthDelta > heightDelta) {
                newWidth = 'auto';
                newHeight = '100%';
            }
            else {
                newWidth = '100%';
                newHeight = 'auto';
            }

            item.css('position', 'relative');
            item.css('width', newWidth);
            item.css('height', newHeight);

            return item;
        },

        /**
         * Centres an item inside its container's box.
         */
        centerInParentBox: function() {
            return $(this).each(function() {
                var item = $(this);
                var box = item.parent();

                var widthDelta = box.width() - item.width();
                var heightDelta = box.height() - item.height();

                console.log(box.height() + ", " + item.height() + ", " + heightDelta);

                item.css('position', 'relative');
                item.css('left', (widthDelta / 2) + 'px');
                item.css('top', (heightDelta / 2)  + 'px');
            });
        }
    });
})(jQuery);
<|endoftext|>


<commit_before>/*! jQuery Ticker Plugin v1.2.0 | https://github.com/BenjaminRH/jquery-ticker | Copyright 2014 Benjamin Harris | Released under the MIT license */
(function(l){function B(c){for(var a=c.length-1;0<a;a--){var v=Math.floor(Math.random()*(a+1)),b=c[a];c[a]=c[v];c[v]=b}return c}function w(c,a){a=a||[];return c.replace(/\x3c!--.*?--\x3e/img,"").replace(/<\/?([a-z][a-z0-9]*)\b[^>]*>/img,function(c,b){return-1!==a.indexOf(b.toLowerCase())?c:""})}l.fn.ticker=function(c){var a=l.extend({},l.fn.ticker.defaults,c);return this.each(function(){function c(){t=!0;x?(x=!1,b()):y=setTimeout(function(){a.pauseOnHover&&d.hasClass("hover")?(clearTimeout(h),c()):b()},a.itemSpeed)}function b(){t?(t=!1,z()):a.finishOnHover&&a.pauseOnHover&&d.hasClass("hover")&&e<=k[f].length?(p.html(u()),e+=1,b()):h=setTimeout(function(){a.pauseOnHover&&d.hasClass("hover")?(clearTimeout(h),b()):(z(),e>k[f].length&&(f+=1,e=0,f==k.length&&(f=0),clearTimeout(h),clearTimeout(y),c()))},a.cursorSpeed)}function z(){0===e&&a.fade?(clearTimeout(h),p.fadeOut(a.fadeOutSpeed,function(){p.html(u());p.fadeIn(a.fadeInSpeed,function(){e+=1;b()})})):(p.html(u()),e+=1,clearTimeout(h),b())}function u(){var c,b,q,m;switch(e%2){case 1:c=a.cursorOne;break;case 0:c=a.cursorTwo}e>=k[f].length&&(c="");var n="",d=[];for(b=0;b<e;b++){m=null;for(q=0;q<r[f].length;q++)if(r[f][q]&&r[f][q].start===b){m=r[f][q];break}m&&(n+=m.tag,m.selfClosing||("/"===m.tag.charAt(1)?d.pop():d.push(m.name)));n+=k[f][b]}for(b=0;b<d.length;b++)n+="</"+d[b]+">";return n+c}var d=l(this),p,C=d.find("li"),k=[],r={},y,h,f=0,e=0,x=!0,t=!0,D="a b strong span i em u".split(" ");if(a.finishOnHover||a.pauseOnHover)d.removeClass("hover"),d.hover(function(){l(this).toggleClass("hover")});var s,A;C.each(function(a,c){var b=s=w(l(this).html(),D),d;d=[];for(var e=/<\/?([a-z][a-z0-9]*)\b[^>]*>/im,f=/\/\s{0,}>$/m,h=[],g;null!==(g=e.exec(b));)if(0===d.length||-1!==d.indexOf(g[1]))g={tag:g[0],name:g[1],selfClosing:f.test(g[0]),start:g.index,end:g.index+g[0].length-1},h.push(g),b=b.slice(0,g.start)+b.slice(g.end+1),e.lastIndex=0;A=h;s=w(s);k.push(s);r[k.length-1]=A});a.random&&B(k);d.find("ul").after("

").remove();p=d.find("div");c()})};l.fn.ticker.defaults={random:!1,itemSpeed:3E3,cursorSpeed:50,pauseOnHover:!0,finishOnHover:!0,cursorOne:"_",cursorTwo:"-",fade:!0,fadeInSpeed:600,fadeOutSpeed:300}})(jQuery);
<commit_msg>Update version<commit_after>/*! jQuery Ticker Plugin v1.0.0 | https://github.com/BenjaminRH/jquery-ticker | Copyright 2014 Benjamin Harris | Released under the MIT license */
(function(d){function s(b){for(var a=b.length-1;0<a;a--){var d=Math.floor(Math.random()*(a+1)),e=b[a];b[a]=b[d];b[d]=e}return b}d.fn.ticker=function(b){var a=d.extend({},d.fn.ticker.defaults,b);return this.each(function(){function b(){m=!0;p?(p=!1,e()):q=setTimeout(function(){a.pauseOnHover&&h.is(":hover")?(clearTimeout(k),b()):e()},a.itemSpeed)}function e(){m?(m=!1,r()):a.finishOnHover&&a.pauseOnHover&&h.is(":hover")&&c<=g[f].length?(l.text(n()),c+=1,e()):k=setTimeout(function(){a.pauseOnHover&&h.is(":hover")?(clearTimeout(k),e()):(r(),c>g[f].length&&(f+=1,c=0,f==g.length&&(f=0),clearTimeout(k),clearTimeout(q),b()))},a.cursorSpeed)}function r(){0==c&&a.fade?(clearTimeout(k),l.fadeOut(a.fadeOutSpeed,function(){l.text(n());l.fadeIn(a.fadeInSpeed,function(){c+=1;e()})})):(l.text(n()),c+=1,clearTimeout(k),e())}function n(){var b;switch(c%2){case 1:b=a.cursorOne;break;case 0:b=a.cursorTwo}c>=g[f].length&&(b="");return g[f].slice(0,c)+b}var h=d(this),l,g=[],q,k,f=0,c=0,p=!0,m=!0;h.find("li").each(function(a,b){g.push(d(this).text())});a.random&&s(g);h.find("ul").after("

").remove();l=h.find("div");b()})};d.fn.ticker.defaults={random:!1,itemSpeed:3E3,cursorSpeed:50,pauseOnHover:!0,finishOnHover:!0,cursorOne:"_",cursorTwo:"-",fade:!0,fadeInSpeed:600,fadeOutSpeed:300}})(jQuery);
<|endoftext|>