<commit_before>/**
 * @copyright   2010-2014, The Titon Project
 * @license     http://opensource.org/licenses/BSD-3-Clause
 * @link        http://titon.io
 */

Toolkit.Showcase = Toolkit.Component.extend(function(nodes, options) {
    var element;

    this.component = 'Showcase';
    this.version = '1.4.0';
    this.options = options = this.setOptions(options);
    this.element = element = this.createElement();

    // Nodes found in the page on initialization
    this.nodes = $(nodes);

    // The wrapping items element
    this.items = element.find('.' + vendor + 'showcase-items');

    // The wrapping tabs element
    this.tabs = element.find('.' + vendor + 'showcase-tabs');

    // The caption element
    this.caption = element.find('.' + vendor + 'showcase-caption');

    // Items gathered when node was activated
    this.data = [];

    // Current index of the item being shown
    this.index = -1;

    // Blackout element if enabled
    this.blackout = options.blackout ? Toolkit.Blackout.factory() : null;

    // Initialize events
    this.events = {
        'clickout element': 'onHide',
        'clickout document {selector}': 'onHide',
        'swipeleft element': 'next',
        'swiperight element': 'prev',
        'keydown window': 'onKeydown',
        'click document {selector}': 'onShow',
        'click element .@showcase-hide': 'onHide',
        'click element .@showcase-next': 'next',
        'click element .@showcase-prev': 'prev',
        'click element .@showcase-tabs a': 'onJump'
    };

    this.initialize();
}, {

    /**
     * Hide the showcase and reset inner elements.
     */
    hide: function() {
        if (this.blackout) {
            this.blackout.hide();
        }

        if (this.options.stopScroll) {
            $('body').removeClass('no-scroll');
        }

        this.element
            .conceal()
            .removeClass('is-single');

        this.items
            .removeAttr('style')
            .children('li')
                .conceal();

        this.fireEvent('hide');
    },

    /**
     * Jump to a specific item indicated by the index number.
     * If the index is too large, jump to the beginning.
     * If the index is too small, jump to the end.
     *
     * @param {Number} index
     */
    jump: function(index) {
        index = $.bound(index, this.data.length);

        // Exit since transitions don't occur
        if (index === this.index) {
            return;
        }

        var self = this,
            element = this.element,
            caption = this.caption,
            list = this.items,
            listItems = list.children('li'),
            listItem = listItems.eq(index),
            items = this.data,
            item = items[index];

        // Update tabs
        this.tabs.find('a')
            .removeClass('is-active')
            .eq(index)
                .addClass('is-active');

        // Reset previous styles
        listItems.conceal();
        caption.conceal();

        // Disable bubbling of transitionend
        listItems.on(Toolkit.transitionEnd, function(e) {
            e.stopPropagation();
        });

        // Reveal the image after the transition ends
        var callback = function() {
            caption.html(item.title).reveal();
            listItem.reveal();
            self.position();
        };

        list.one(Toolkit.transitionEnd, callback);

        // Image already exists
        if (listItem.data('width')) {
            this._resize(listItem.data('width'), listItem.data('height'));

            // IE9
            if (!Toolkit.hasTransition) {
                callback();
            }

        // Create image and animate
        } else {
            element
                .addClass('is-loading')
                .aria('busy', true);

            var img = new Image();
                img.src = item.image;

            // Render frame when image load
            img.onload = function() {
                self._resize(this.width, this.height); // Must be called 1st or FF fails

                element
                    .removeClass('is-loading')
                    .aria('busy', false);

                listItem
                    .data('width', this.width)
                    .data('height', this.height)
                    .append(img);

                // IE9
                if (!Toolkit.hasTransition) {
                    callback();
                }
            };

            // Display error message if load fails
            img.onerror = function() {
                element
                    .removeClass('is-loading')
                    .addClass('has-failed')
                    .aria('busy', false);

                listItem
                    .data('width', 150)
                    .data('height', 150)
                    .html(Toolkit.messages.error);

                self._resize(150, 150);

                // IE9
                if (!Toolkit.hasTransition) {
                    callback();
                }
            };
        }

        // Save state
        this.index = index;

        this.fireEvent('jump', index);
    },

    /**
     * Go to the next item.
     */
    next: function() {
        this.jump(this.index + 1);
    },

    /**<commit_msg>Refactor showcase to use Deferred<commit_after>/**
 * @copyright   2010-2014, The Titon Project
 * @license     http://opensource.org/licenses/BSD-3-Clause
 * @link        http://titon.io
 */

Toolkit.Showcase = Toolkit.Component.extend(function(nodes, options) {
    var element;

    this.component = 'Showcase';
    this.version = '1.4.0';
    this.options = options = this.setOptions(options);
    this.element = element = this.createElement();

    // Nodes found in the page on initialization
    this.nodes = $(nodes);

    // The wrapping items element
    this.items = element.find('.' + vendor + 'showcase-items');

    // The wrapping tabs element
    this.tabs = element.find('.' + vendor + 'showcase-tabs');

    // The caption element
    this.caption = element.find('.' + vendor + 'showcase-caption');

    // Items gathered when node was activated
    this.data = [];

    // Current index of the item being shown
    this.index = -1;

    // Blackout element if enabled
    this.blackout = options.blackout ? Toolkit.Blackout.factory() : null;

    // Initialize events
    this.events = {
        'clickout element': 'onHide',
        'clickout document {selector}': 'onHide',
        'swipeleft element': 'next',
        'swiperight element': 'prev',
        'keydown window': 'onKeydown',
        'click document {selector}': 'onShow',
        'click element .@showcase-hide': 'onHide',
        'click element .@showcase-next': 'next',
        'click element .@showcase-prev': 'prev',
        'click element .@showcase-tabs a': 'onJump'
    };

    // Stop `transitionend` events from bubbling up when the showcase is resized
    this.events[Toolkit.transitionEnd + ' element .showcase-items'] = function(e) {
        e.stopPropagation();
    };

    this.initialize();
}, {

    /**
     * Hide the showcase and reset inner elements.
     */
    hide: function() {
        if (this.blackout) {
            this.blackout.hide();
        }

        if (this.options.stopScroll) {
            $('body').removeClass('no-scroll');
        }

        this.element
            .conceal()
            .removeClass('is-single');

        this.items
            .removeAttr('style')
            .children('li')
                .conceal();

        this.fireEvent('hide');
    },

    /**
     * Jump to a specific item indicated by the index number.
     * If the index is too large, jump to the beginning.
     * If the index is too small, jump to the end.
     *
     * @param {Number} index
     */
    jump: function(index) {
        index = $.bound(index, this.data.length);

        // Exit since transitions don't occur
        if (index === this.index) {
            return;
        }

        var self = this,
            element = this.element,
            caption = this.caption,
            list = this.items,
            listItems = list.children('li'),
            listItem = listItems.eq(index),
            items = this.data,
            item = items[index],
            deferred = $.Deferred();

        // Update tabs
        this.tabs.find('a')
            .removeClass('is-active')
            .eq(index)
                .addClass('is-active');

        // Reset previous styles
        listItems.conceal();
        caption.conceal();
        element
            .addClass('is-loading')
            .aria('busy', true);

        // Setup deferred callbacks
        deferred.always(function(width, height) {
            list.transitionend(function() {
                caption.html(item.title).reveal();
                listItem.reveal();
                self.position();
            });

            self._resize(width, height);

            element
                .removeClass('is-loading')
                .aria('busy', false);

            listItem
                .data('width', width)
                .data('height', height);
        });

        deferred.fail(function() {
            element.addClass('has-failed');
            listItem.html(Toolkit.messages.error);
        });

        // Image already exists
        if (listItem.data('width')) {
            deferred.resolve(listItem.data('width'), listItem.data('height'));

        // Create image and animate
        } else {
            var img = new Image();
                img.src = item.image;
                img.onerror = function() {
                    deferred.reject(150, 150);
                };
                img.onload = function() {
                    deferred.resolve(this.width, this.height);
                    listItem.append(img);
                };
        }

        // Save state
        this.index = index;

        this.fireEvent('jump', index);
    },

    /**
     * Go to the next item.
     */
    next: function() {
        this.jump(this.index + 1);
    },

    /**
{'fraction_non_alphanumeric': 0.13175138999205718, 'fraction_numerical': 0.004964257347100874, 'mean_word_length': 1.5366406446738856, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '905918', 'n_tokens_mistral': 2843, 'n_tokens_neox': 2661, 'n_words': 649}