<commit_before>/**
 *
 * api bind
 *  calendar|sendData //Отобразить окно с пользователями
 *
 * api event
 *  calendar|applyPressed  //Пользователь нажал на apply и выбрал пользователей
 *  calendar|calendarSelected
 *  calendar|calendarDeselected
 */

(function ($) {
    $.fn.app.calendar = function (method) {

        var sandbox, self;
        var methods = {
            init: function (options) {
                self = $(this);
                sandbox = $.extend(true, {}, this.app.calendar.defaults, options);
                return this.each(function () {
                    var $this = $(this);
                    helpers.initCalendar($this);
                    helpers.initNewEventPopup($this);
                });
            }
        };

        var calendar = $('#full-calendar-popup');
        var simpleFullCalendar = $('.info-block-wrapper');

        var viewName, selectedDate;

        var $addEventPopup = $("#popup-add-event");

        var popupIds = {
            title: 'calendarEvent_title',
            eventType: 'calendarEvent_eventType',
        };

        var customCalendarOptions = {
            'eventTypes': CalendarEventTypes !== undefined ? CalendarEventTypes : {}
        }

        var settings = {
            calendar: {
                simpleOptions: {
                    header: false,
                    defaultView: 'basicDay',
                    timeFormat: 'H:mm',
                    height: 339,
                    editable: false,
                    selectable: false,
                    editableLocked: true,

                    columnFormat: {
                        month: 'ddd',
                        week: 'ddd d MMM',
                        day: 'dddd d MMM yyyy'
                    },

                    titleFormat: {
                        month: 'MMMM yyyy',
                        week: 'MMMM yyyy',
                        day: ''                  // Tuesday, Sep 8, 2009
                    },

                    eventAfterAllRender: function() {
                        $('.scroll-pane', '.block.info').jScrollPane({
                            mouseWheelSpeed: 60
                        });
                    },
                    eventRender: function (event, element) {

                        var url = Routing.getCalendarEventDetails;

                        if ($(element).hasClass('birthday')) {
                            url = Routing.getBirthdayEventDetails;
                        }

                        var id = event.id;

                        if (id) {

                            element.qtip({
                                content: {
                                    text: function (event, api) {

                                        $element = $(this);

                                        $.ajax({
                                            url: url.replace('__id__', id), // URL to the JSON file
                                            type: 'GET', // POST or GET
                                            dataType: 'json' // Tell it we're retrieving JSON

                                        }).then(function (data) {
                                                /* Process the retrieved JSON object
                                                 *    Retrieve a specific attribute from our parsed
                                                 *    JSON string and set the tooltip content.
                                                 */
                                                var content = data.view;

                                                // Now we set the content manually (required!)
                                                api.set('content.text', content);
                                            }, function (xhr, status, error) {
                                                // Upon failure... set the tooltip content to the status and error value
                                                api.set('content.text', status + ': ' + error);
                                            });

                                        return 'Loading...' // Set some initial loading text
                                    }
                                },
                                position: {
                                    target: 'mouse', // Track the mouse as the positioning target
                                    adjust: { x: 8, y: 8 }, // Offset it slightly from under the mouse
                                    at: 'bottom right',
                                    my: 'top left'
                                },
                                style: {
                                    classes: 'qtip-blue qtip-shadow qtip-rounded'
                                }
                            });
                        }
                    },
                    eventSources: [
                        {
                            url: Routing.getCalendarEvents, // use the `url` property
                            className: 'all-events'
                        },
                        {
                            url: Routing.getMyCalendarEvents, // use the `url` property
                            className: 'my-events'
                        },
                        {
                            url: Routing.getBirthdayCalendarEvents, // use the `url` property
                            className: 'birthday'
                        }

                    ]
                },

                defaultOptions: {
                    header: {
                        left: 'prev,next today',
                        center: 'save changeMode title',
                        right: 'month,basicWeek,basicDay'
                    },
                    buttonText: {
                        changeMode: 'Edit',
                        save: 'Save'
                    },
                    unselectAuto: false,
                    dayClick: function (date, allDay, jsEvent, view) {

                        if (allDay) {
                            calendar.fullCalendar('gotoDate', date);
                        }
                    },
                    changeMode: function (editMode) {

                        if (editMode) {
                            helpers.setEditMode(calendar);
                        } else {
                            helpers.setViewMode(calendar);
                        }
                    },

                    width: 900,
                    height: 400,
                    selectable: true,
                    editableLocked: true,
                    slotEventOverlap: false
                },

                editOptions: {
                    header: {
                        left: 'prev,next today, custom',
                        center: 'save changeMode title',
                        right: 'month,agendaWeek,agendaDay'
                    },
                    defaultView: 'agendaDay',
                    currentMode: 'edit',
                    saveUrl: Routing.saveCalendarEvents,

                    selectable: true,
                    selectHelper: true,
                    select: function (start, end, allDay) {
                        helpers.showPopup($addEventPopup);
                        $addEventPopup.find('.add-event').off('click').on('click', function() {
                            var data = helpers.getPopupData();
                            if (data.title) {
                                calendar.fullCalendar('renderEvent',
                                    {
                                        title: data.title,
                                        eventType: data.eventType,
                                        start: start,
                                        end: end,
                                        allDay: allDay,
                                        className: 'my-events',
                                        isNew: true
                                    },
                                    true // make the event "stick"
                                );
                                helpers.closePopup();
                                calendar.fullCalendar('reportEventChange');
                            }
                        });
                        calendar.fullCalendar('unselect');
                    },
                    eventDrop: function (event, dayDelta, minuteDelta, allDay, revertFunc) {
                        event.isModified = true;
                    },
                    eventResize: function (event, dayDelta, minuteDelta, revertFunc) {
                        event.isModified = true;
                    },
                    saveAfter: function () {
                        simpleFullCalendar.fullCalendar('refetchEvents');
                        self.trigger('updateWall');
                    },
                    eventAfterAllRender: function (view) {

                        $('.my-events .fc-additional-content ').on('click', function () {

                            var $element = $(this);
                            if (confirm(Translating.doYouReallyWantRemove)) {

                                var id = $element.attr('rel');

                                if (id != '' + parseInt(id)) {

                                } else {
                                    $.ajax({
                                        url: Routing.deleteCalendarEvents.replace('__id__', id),
                                        method: 'get',
                                        success: function () {

                                            simpleFullCalendar.fullCalendar('refetchEvents');
                                        }

                                    });
                                }

                                calendar.fullCalendar('removeEvents', id);

                            }
                        });

                        $('.my-events .fc-edit-content ').on('click', function () {
                            var $element = $(this);
                            var id = $element.attr('rel');

                            var event = calendar.fullCalendar('clientEvents', id).pop();

                            helpers.setPopupData(event);
                            helpers.showPopup($addEventPopup);
                            $addEventPopup.find('.add-event').off('click').on('click', function() {
                                var data = helpers.getPopupData();
                                if (data.title) {
                                    event.title = data.title;
                                    event.eventType = data.eventType;
                                    event.isModified = true;
                                    calendar.fullCalendar('updateEvent', event);
                                    calendar.fullCalendar('reportEventChange');
                                    helpers.closePopup();
                                }
                            });
                        })
                    },
                    dayEventAdditionalContent: function (event) {

                        var additionalHtml = '';
                        additionalHtml += '

';

                        additionalHtml += '

';

                        return additionalHtml;

                    },
                    editable: true,
                    editableLocked: false
                },

                viewOptions: {
                    header: {
                        left: 'prev,next today, custom',
                        center: 'save changeMode',
                        right: 'month,basicWeek,basicDay'
                    },
                    defaultView: 'basicDay',
                    currentMode: 'view',
                    selectable: false,
                    selectHelper: false,
                    editableLocked: true
                }
            }
        }

        var helpers = {
            initCalendar: function (document) {

                simpleFullCalendar.fullCalendar(settings.calendar.simpleOptions);

                $('a.i.icon-calendar').on('click', function () {
                    helpers.initCalendarPopup(simpleFullCalendar.fullCalendar("getOptions"), customCalendarOptions);
                })

                helpers.initAddPopup();
            },

            showPopup: function($box) {
                $box.show();
                $('.overlay').show();
            },

            closePopup: function() {
                $('.overlay, #popup-add-event').hide();
            },

            initAddPopup: function() {
                $('.popup-add-event-close, .overlay, .cancel-event').click(function() {
                    helpers.closePopup();
                });
            },

            getPopupData: function() {
                var data=[];
                $.each(popupIds, function(i, val){
                    var $elm = $addEventPopup.find("#"+val);
                    data[i] = $elm.val();
                    $elm.val('');
                });

                return data;
            },

            setPopupData: function(event) {
                $("#"+popupIds.title).val(event.title);
                if (event.event_type) {
                    $("#"+popupIds.eventType).val(event.event_type.id);
                }
            },

            initCalendarPopup: function (options, customOptions) {
                if (!calendar.data('fullCalendar')) {

                    var defaults = settings.calendar.defaultOptions;

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

                    if (customOptions) {
                        options = $.extend(true, {},
                            options,
                            customOptions
                        );
                    }

                    calendar.fullCalendar(options);
                }

                $.fancybox('#full-calendar-popup', {
                    padding: 50,
                    scrolling: 'no',
                    beforeClose: function () {
                        return calendar.fullCalendar('confirmViewMode')
                    },
                    helpers: {
                        overlay: {
                            locked: false
                        }
                    }
                });
            },

            setEditMode: function (calendar) {

                var options = calendar.fullCalendar('getOptions');

                helpers.stashCalendarDate();

                calendar.fullCalendar('destroy');
                helpers.initCalendarPopup(options, settings.calendar.editOptions);

                helpers.popCalendarDate();

            },

            stashCalendarDate: function() {

                selectedDate = calendar.fullCalendar('getDate');
                viewName = calendar.fullCalendar('getView').name;
            },

            popCalendarDate: function() {

                if (viewName != calendar.fullCalendar('getView').name) {
                    switch (viewName) {
                        case 'basicWeek':
                            viewName = 'agendaWeek';
                            break;
                        case 'basicDay':
                            viewName = 'agendaDay';
                            break;
                        case 'agendaWeek':
                            viewName = 'basicWeek';
                            break;
                        case 'agendaDay':
                            viewName = 'basicDay';
                            break;
                    }
                }

                calendar.fullCalendar('changeView', viewName);
                calendar.fullCalendar('gotoDate', selectedDate);
            },

            setViewMode: function (calendar) {

                var options = calendar.fullCalendar('getOptions');

                helpers.stashCalendarDate();

                calendar.fullCalendar('destroy');
                helpers.initCalendarPopup(options, settings.calendar.viewOptions);

                helpers.popCalendarDate();
            },

            initNewEventPopup: function () {

            }
        };

        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 in app.calendar plugin.');
        }
    };

    $.fn.app.calendar.defaults = {
    };
})(jQuery);

var app = app || {};

$(document).ready(function () {
    if (typeof app.calendar === 'undefined') {
        $('body').app('calendar', app.calendar);
    }
});
<commit_msg>popup календарь<commit_after>/**
 *
 * api bind
 *  calendar|sendData //Отобразить окно с пользователями
 *
 * api event
 *  calendar|applyPressed  //Пользователь нажал на apply и выбрал пользователей
 *  calendar|calendarSelected
 *  calendar|calendarDeselected
 */

(function ($) {
    $.fn.app.calendar = function (method) {

        var sandbox, self;
        var methods = {
            init: function (options) {
                self = $(this);
                sandbox = $.extend(true, {}, this.app.calendar.defaults, options);
                return this.each(function () {
                    var $this = $(this);
                    helpers.initCalendar($this);
                    helpers.initNewEventPopup($this);
                });
            }
        };

        var calendar = $('#full-calendar-popup');
        var simpleFullCalendar = $('.info-block-wrapper');

        var viewName, selectedDate;

        var $addEventPopup = $("#popup-add-event");

        var popupIds = {
            title: 'calendarEvent_title',
            eventType: 'calendarEvent_eventType',
        };

        var customCalendarOptions = {
            'eventTypes': CalendarEventTypes !== undefined ? CalendarEventTypes : {}
        }

        var settings = {
            calendar: {
                simpleOptions: {
                    header: false,
                    defaultView: 'basicDay',
                    timeFormat: 'H:mm',
                    height: 339,
                    editable: false,
                    selectable: false,
                    editableLocked: true,

                    columnFormat: {
                        month: 'ddd',
                        week: 'ddd d MMM',
                        day: 'dddd d MMM yyyy'
                    },

                    titleFormat: {
                        month: 'MMMM yyyy',
                        week: 'MMMM yyyy',
                        day: ''                  // Tuesday, Sep 8, 2009
                    },

                    eventAfterAllRender: function () {
                        $('.scroll-pane', '.block.info').jScrollPane({
                            mouseWheelSpeed: 60
                        });
                    },
                    eventRender: function (event, element) {

                        var url = Routing.getCalendarEventDetails;

                        if ($(element).hasClass('birthday')) {
                            url = Routing.getBirthdayEventDetails;
                        }

                        var id = event.id;

                        if (id) {

                            element.qtip({
                                content: {
                                    text: function (event, api) {

                                        $element = $(this);

                                        $.ajax({
                                            url: url.replace('__id__', id), // URL to the JSON file
                                            type: 'GET', // POST or GET
                                            dataType: 'json' // Tell it we're retrieving JSON

                                        }).then(function (data) {
                                            /* Process the retrieved JSON object
                                             *    Retrieve a specific attribute from our parsed
                                             *    JSON string and set the tooltip content.
                                             */
                                            var content = data.view;

                                            // Now we set the content manually (required!)
                                            api.set('content.text', content);
                                        }, function (xhr, status, error) {
                                            // Upon failure... set the tooltip content to the status and error value
                                            api.set('content.text', status + ': ' + error);
                                        });

                                        return 'Loading...' // Set some initial loading text
                                    }
                                },
                                position: {
                                    target: 'mouse', // Track the mouse as the positioning target
                                    adjust: { x: 8, y: 8 }, // Offset it slightly from under the mouse
                                    at: 'bottom right',
                                    my: 'top left'
                                },
                                style: {
                                    classes: 'qtip-blue qtip-shadow qtip-rounded'
                                }
                            });
                        }
                    },
                    eventSources: [
                        {
                            url: Routing.getCalendarEvents, // use the `url` property
                            className: 'all-events'
                        },
                        {
                            url: Routing.getMyCalendarEvents, // use the `url` property
                            className: 'my-events'
                        },
                        {
                            url: Routing.getBirthdayCalendarEvents, // use the `url` property
                            className: 'birthday'
                        }

                    ]
                },

                defaultOptions: {
                    header: {
                        left: 'prev,next today',
                        center: 'save changeMode title',
                        right: 'month,basicWeek,basicDay'
                    },
                    buttonText: {
                        changeMode: 'Edit',
                        save: 'Save'
                    },
                    unselectAuto: false,
                    dayClick: function (date, allDay, jsEvent, view) {

                        if (allDay) {
                            calendar.fullCalendar('gotoDate', date);
                        }
                    },
                    changeMode: function (editMode) {

                        if (editMode) {
                            helpers.setEditMode(calendar);
                        } else {
                            helpers.setViewMode(calendar);
                        }
                    },

                    width: 900,
                    height: 400,
                    selectable: true,
                    editableLocked: true,
                    slotEventOverlap: false
                },

                editOptions: {
                    header: {
                        left: 'prev,next today, custom',
                        center: 'save changeMode title',
                        right: 'month,agendaWeek,agendaDay'
                    },
                    defaultView: 'agendaDay',
                    currentMode: 'edit',
                    saveUrl: Routing.saveCalendarEvents,

                    selectable: true,
                    selectHelper: true,
                    select: function (start, end, allDay) {
                        helpers.showPopup($addEventPopup);
                        $addEventPopup.find('.add-event').off('click').on('click', function () {
                            var data = helpers.getPopupData();
                            if (data.title) {
                                calendar.fullCalendar('renderEvent',
                                    {
                                        title: data.title,
                                        eventType: data.eventType,
                                        start: start,
                                        end: end,
                                        allDay: allDay,
                                        className: 'my-events',
                                        isNew: true
                                    },
                                    true // make the event "stick"
                                );
                                helpers.closePopup();
                                calendar.fullCalendar('reportEventChange');
                            }
                        });
                        calendar.fullCalendar('unselect');
                    },
                    eventDrop: function (event, dayDelta, minuteDelta, allDay, revertFunc) {
                        event.isModified = true;
                    },
                    eventResize: function (event, dayDelta, minuteDelta, revertFunc) {
                        event.isModified = true;
                    },
                    saveAfter: function () {
                        simpleFullCalendar.fullCalendar('refetchEvents');
                        self.trigger('updateWall');
                    },
                    eventAfterAllRender: function (view) {

                        $('.my-events .fc-additional-content ').on('click', function () {

                            var $element = $(this);
                            if (confirm(Translating.doYouReallyWantRemove)) {

                                var id = $element.attr('rel');

                                if (id != '' + parseInt(id)) {

                                } else {
                                    $.ajax({
                                        url: Routing.deleteCalendarEvents.replace('__id__', id),
                                        method: 'get',
                                        success: function () {

                                            simpleFullCalendar.fullCalendar('refetchEvents');
                                        }
                                    });
                                }
                                calendar.fullCalendar('removeEvents', id);
                            }
                        });

                        $('.my-events .fc-edit-content ').on('click', function () {
                            var $element = $(this);
                            var id = $element.attr('rel');

                            var event = calendar.fullCalendar('clientEvents', id).pop();

                            helpers.setPopupData(event);
                            helpers.showPopup($addEventPopup);
                            $addEventPopup.find('.add-event').off('click').on('click', function () {
                                var data = helpers.getPopupData();
                                if (data.title) {
                                    event.title = data.title;
                                    event.eventType = data.eventType;
                                    event.isModified = true;
                                    calendar.fullCalendar('updateEvent', event);
                                    calendar.fullCalendar('reportEventChange');
                                    helpers.closePopup();
                                }
                            });
                        })
                    },
                    dayEventAdditionalContent: function (event) {

                        var additionalHtml = '';
                        additionalHtml += '

';

                        additionalHtml += '

';

                        return additionalHtml;

                    },
                    editable: true,
                    editableLocked: false
                },

                viewOptions: {
                    header: {
                        left: 'prev,next today, custom',
                        center: 'save changeMode',
                        right: 'month,basicWeek,basicDay'
                    },
                    defaultView: 'basicDay',
                    currentMode: 'view',
                    selectable: false,
                    selectHelper: false,
                    editableLocked: true
                }
            }
        }

        var helpers = {
            initCalendar: function (document) {

                simpleFullCalendar.fullCalendar(settings.calendar.simpleOptions);

                $('a.i.icon-calendar').on('click', function () {
                    helpers.initCalendarPopup(simpleFullCalendar.fullCalendar("getOptions"), customCalendarOptions);
                })

                helpers.initAddPopup();
            },

            showPopup: function ($box) {
                $box.show();
                $('.overlay').show();
            },

            closePopup: function () {
                $('.overlay, #popup-add-event').hide();
            },

            initAddPopup: function () {
                $('.popup-add-event-close, .overlay, .cancel-event').click(function () {
                    helpers.closePopup();
                });
            },

            getPopupData: function () {
                var data = [];
                $.each(popupIds, function (i, val) {
                    var $elm = $addEventPopup.find("#" + val);
                    data[i] = $elm.val();
                    $elm.val('');
                });

                return data;
            },

            setPopupData: function (event) {
                $("#" + popupIds.title).val(event.title);
                if (event.event_type) {
                    $("#" + popupIds.eventType).val(event.event_type.id);
                }
            },

            initCalendarPopup: function (options, customOptions) {
                if (!calendar.data('fullCalendar')) {

                    var defaults = settings.calendar.defaultOptions;

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

                    if (customOptions) {
                        options = $.extend(true, {},
                            options,
                            customOptions
                        );
                    }

                    calendar.fullCalendar(options);
                }

                $.fancybox('#full-calendar-popup', {
                    padding: 50,
                    openEffect: 'elastic',
                    closeEffect: 'elastic',
                    beforeClose: function () {
                        return calendar.fullCalendar('confirmViewMode');
                    }
                });

                setInterval(function(){$.fancybox.update()},500)
            },

            setEditMode: function (calendar) {

                var options = calendar.fullCalendar('getOptions');

                helpers.stashCalendarDate();

                calendar.fullCalendar('destroy');
                helpers.initCalendarPopup(options, settings.calendar.editOptions);

                helpers.popCalendarDate();

            },

            stashCalendarDate: function () {

                selectedDate = calendar.fullCalendar('getDate');
                viewName = calendar.fullCalendar('getView').name;
            },

            popCalendarDate: function () {

                if (viewName != calendar.fullCalendar('getView').name) {
                    switch (viewName) {
                        case 'basicWeek':
                            viewName = 'agendaWeek';
                            break;
                        case 'basicDay':
                            viewName = 'agendaDay';
                            break;
                        case 'agendaWeek':
                            viewName = 'basicWeek';
                            break;
                        case 'agendaDay':
                            viewName = 'basicDay';
                            break;
                    }
                }

                calendar.fullCalendar('changeView', viewName);
                calendar.fullCalendar('gotoDate', selectedDate);
            },

            setViewMode: function (calendar) {

                var options = calendar.fullCalendar('getOptions');

                helpers.stashCalendarDate();

                calendar.fullCalendar('destroy');
                helpers.initCalendarPopup(options, settings.calendar.viewOptions);

                helpers.popCalendarDate();
            },

            initNewEventPopup: function () {

            }
        };

        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 in app.calendar plugin.');
        }
    };

    $.fn.app.calendar.defaults = {
    };
})(jQuery);

var app = app || {};

$(document).ready(function () {
    if (typeof app.calendar === 'undefined') {
        $('body').app('calendar', app.calendar);
    }
});
<|endoftext|>


<commit_before>function popinOpen(e) {
    // Stop propagation
    e.preventDefault();

    document.getElementById('background').style.display = 'block';
    document.getElementById('popin').addEventListener('click', popinClose);
    document.querySelector('#popin [data-type=close]').addEventListener('click', popinClose);
    document.getElementById('popin').style.display = 'flex';
    document.querySelector('#popin [data-type=progress]').style.display = 'flex';

    var node = e.target;
    var url = node.getAttribute('href');
    if (url.indexOf('?') !== false) {
        url += '?popin';
    }
    else {
        url += '&popin';
    }

    // Call ajax
    var oReq = new XMLHttpRequest();
    oReq.addEventListener("progress", popinContentProgress);
    oReq.addEventListener("load", popinContentLoaded);
    oReq.open('GET', url);
    oReq.send();
}

function popinReset() {
    var nodeProgress = document.querySelector('#popin [data-type=progress]');
    if (nodeProgress.childNodes.length > 1) {
        nodeProgress.removeChild(nodeProgress.lastChild);
    }
    document.querySelector('#popin [data-type=content]').innerHTML = '';
}

function popinClose(event) {
    if (event.target.id != 'popin' && event.target.dataset.type != 'close'
        && event.target.type != 'reset') {
        return;
    }
    document.getElementById('background').style.display = 'none';
    document.getElementById('popin').removeEventListener('click', popinClose);
    popinReset();
    document.querySelector('#popin [data-type=close]').removeEventListener('click', popinClose);
    document.getElementById('popin').style.display = 'none';
}

function popinContentLoaded(event) {
    document.querySelector('#popin [data-type=progress]').style.display = 'none';
    document.querySelector('#popin [data-type=content]').insertAdjacentHTML('afterbegin', this.responseText);
    var scriptNodes = document.querySelectorAll('#popin [data-type=content] script');
    Array.prototype.filter.call(scriptNodes, function (node) {
        eval(node.innerHTML);
    });

    //console.log(document.querySelector('#popin [data-type=content]'));
    //eval(document.querySelector('#popin [data-type=content]'));
}

function popinContentProgress(event) {
    if (event.lengthComputable) {
        var percentComplete = event.loaded / event.total;
        var percentText = (percentComplete * 100) + '%';
        var nodeProgress = document.querySelector('#popin [data-type=progress]');
        if (nodeProgress.childNodes.length > 1) {
            nodeProgress.lastChild.innerHTML = percentText;
        }
        else {
            nodeProgress.insertAdjacentHTML('beforeend', '' + percentText + '');
        }
    }
}

var popinElements = document.querySelectorAll('a[data-target=popin]');
Array.prototype.filter.call(popinElements, function (link) {
    link.addEventListener('click', popinOpen);
});<commit_msg>Add keycode manager to detect escape to close popin<commit_after>function popinOpen(e) {
    // Stop propagation
    e.preventDefault();

    document.getElementById('background').style.display = 'block';
    document.getElementById('popin').style.display = 'flex';
    document.querySelector('#popin [data-type=progress]').style.display = 'flex';
    document.getElementById('popin').addEventListener('click', popinClose);
    document.querySelector('#popin [data-type=close]').addEventListener('click', popinClose);
    document.addEventListener('keydown', popinClose);

    var node = e.target;
    var url = node.getAttribute('href');
    if (url.indexOf('?') !== false) {
        url += '?popin';
    }
    else {
        url += '&popin';
    }

    // Call ajax
    var oReq = new XMLHttpRequest();
    oReq.addEventListener("progress", popinContentProgress);
    oReq.addEventListener("load", popinContentLoaded);
    oReq.open('GET', url);
    oReq.send();
}

function popinReset() {
    var nodeProgress = document.querySelector('#popin [data-type=progress]');
    if (nodeProgress.childNodes.length > 1) {
        nodeProgress.removeChild(nodeProgress.lastChild);
    }
    document.querySelector('#popin [data-type=content]').innerHTML = '';
}

function popinClose(event) {
    if (event.target.id != 'popin' && event.target.dataset.type != 'close'
        && event.target.type != 'reset' && event.keyCode != 27) {
        return;
    }
    popinReset();
    document.getElementById('background').style.display = 'none';
    document.getElementById('popin').style.display = 'none';
    document.getElementById('popin').removeEventListener('click', popinClose);
    document.querySelector('#popin [data-type=close]').removeEventListener('click', popinClose);
    document.removeEventListener('keydown', popinClose);
}

function popinContentLoaded(event) {
    document.querySelector('#popin [data-type=progress]').style.display = 'none';
    document.querySelector('#popin [data-type=content]').insertAdjacentHTML('afterbegin', this.responseText);
    var scriptNodes = document.querySelectorAll('#popin [data-type=content] script');
    Array.prototype.filter.call(scriptNodes, function (node) {
        eval(node.innerHTML);
    });

    //console.log(document.querySelector('#popin [data-type=content]'));
    //eval(document.querySelector('#popin [data-type=content]'));
}

function popinContentProgress(event) {
    if (event.lengthComputable) {
        var percentComplete = event.loaded / event.total;
        var percentText = (percentComplete * 100) + '%';
        var nodeProgress = document.querySelector('#popin [data-type=progress]');
        if (nodeProgress.childNodes.length > 1) {
            nodeProgress.lastChild.innerHTML = percentText;
        }
        else {
            nodeProgress.insertAdjacentHTML('beforeend', '' + percentText + '');
        }
    }
}

var popinElements = document.querySelectorAll('a[data-target=popin]');
Array.prototype.filter.call(popinElements, function (link) {
    link.addEventListener('click', popinOpen);
});<|endoftext|>


<commit_before>'use strict';

const spawn = require('child_process').spawn, // eslint-disable-line security/detect-child-process
	fs = require('fs'),
	path = require('path'),
	async = require('async'),
	ROOT_DIR = path.join(__dirname, '..'),
	DOC_DIR = path.join(ROOT_DIR, 'apidoc');

/**
 * @param       {string} outputDir output directory for generated documentation
 * @constructor
 */
function Documentation(outputDir) {
	this.outputDir = outputDir;
	this.hasWindows = fs.existsSync(path.join(ROOT_DIR, 'windows'));
}

Documentation.prototype.prepare = function (next) {
	// no-op now...
	next();
};

Documentation.prototype.generateParityReport = function (next) {
	let args = [ path.join(DOC_DIR, 'docgen.js'), '-f', 'parity' ];
	if (this.hasWindows) {
		args = args.concat([
			'-a', path.join(ROOT_DIR, 'windows', 'doc', 'Titanium'),
			'-a', path.join(ROOT_DIR, 'windows', 'doc', 'WindowsOnly')
		]);
	}

	console.log('Generating parity report...');

	const prc = spawn('node', args, { cwd: DOC_DIR });
	prc.stdout.on('data', function (data) {
		console.log(data.toString().trim());
	});
	prc.stderr.on('data', function (data) {
		console.error(data.toString().trim());
	});
	prc.on('close', function (code) {
		if (code !== 0) {
			return next('Failed');
		}
		next();
	});
};

Documentation.prototype.generateJSCA = function (next) {
	let args = [ path.join(DOC_DIR, 'docgen.js'), '-f', 'jsca', '-o', this.outputDir + path.sep ];
	if (this.hasWindows) {
		args = args.concat([
			'-a', path.join(ROOT_DIR, 'windows', 'doc', 'Titanium'),
			'-a', path.join(ROOT_DIR, 'windows', 'doc', 'WindowsOnly')
		]);
	}
	console.log('Generating JSCA...');

	const prc = spawn('node', args, { cwd: DOC_DIR });
	prc.stdout.on('data', function (data) {
		console.log(data.toString().trim());
	});
	prc.stderr.on('data', function (data) {
		console.error(data.toString().trim());
	});
	prc.on('close', function (code) {
		if (code !== 0) {
			return next('Failed to generate JSCA JSON.');
		}
		next(null, path.join(this.outputDir, 'api.jsca'));
	}.bind(this));
};

Documentation.prototype.generate = function (next) {
	this.prepare(function (err) {
		if (err) {
			return next(err);
		}
		async.parallel([
			this.generateParityReport.bind(this),
			this.generateJSCA.bind(this)
		], next);
	}.bind(this));
};
module.exports = Documentation;
<commit_msg>[TIMOB-25216] Include Windows Modules docs<commit_after>'use strict';

const spawn = require('child_process').spawn, // eslint-disable-line security/detect-child-process
	fs = require('fs'),
	path = require('path'),
	async = require('async'),
	ROOT_DIR = path.join(__dirname, '..'),
	DOC_DIR = path.join(ROOT_DIR, 'apidoc');

/**
 * @param       {string} outputDir output directory for generated documentation
 * @constructor
 */
function Documentation(outputDir) {
	this.outputDir = outputDir;
	this.hasWindows = fs.existsSync(path.join(ROOT_DIR, 'windows'));
}

Documentation.prototype.prepare = function (next) {
	// no-op now...
	next();
};

Documentation.prototype.generateParityReport = function (next) {
	let args = [ path.join(DOC_DIR, 'docgen.js'), '-f', 'parity' ];
	if (this.hasWindows) {
		args = args.concat([
			'-a', path.join(ROOT_DIR, 'windows', 'doc', 'Titanium'),
			'-a', path.join(ROOT_DIR, 'windows', 'doc', 'WindowsOnly'),
			'-a', path.join(ROOT_DIR, 'windows', 'doc', 'Modules')
		]);
	}

	console.log('Generating parity report...');

	const prc = spawn('node', args, { cwd: DOC_DIR });
	prc.stdout.on('data', function (data) {
		console.log(data.toString().trim());
	});
	prc.stderr.on('data', function (data) {
		console.error(data.toString().trim());
	});
	prc.on('close', function (code) {
		if (code !== 0) {
			return next('Failed');
		}
		next();
	});
};

Documentation.prototype.generateJSCA = function (next) {
	let args = [ path.join(DOC_DIR, 'docgen.js'), '-f', 'jsca', '-o', this.outputDir + path.sep ];
	if (this.hasWindows) {
		args = args.concat([
			'-a', path.join(ROOT_DIR, 'windows', 'doc', 'Titanium'),
			'-a', path.join(ROOT_DIR, 'windows', 'doc', 'WindowsOnly')
		]);
	}
	console.log('Generating JSCA...');

	const prc = spawn('node', args, { cwd: DOC_DIR });
	prc.stdout.on('data', function (data) {
		console.log(data.toString().trim());
	});
	prc.stderr.on('data', function (data) {
		console.error(data.toString().trim());
	});
	prc.on('close', function (code) {
		if (code !== 0) {
			return next('Failed to generate JSCA JSON.');
		}
		next(null, path.join(this.outputDir, 'api.jsca'));
	}.bind(this));
};

Documentation.prototype.generate = function (next) {
	this.prepare(function (err) {
		if (err) {
			return next(err);
		}
		async.parallel([
			this.generateParityReport.bind(this),
			this.generateJSCA.bind(this)
		], next);
	}.bind(this));
};
module.exports = Documentation;
<|endoftext|>


<commit_before>require('traceur/bin/traceur-runtime');

class BaseObject {
  constructor(options) {
    this.id = options.id;
    this.type = options.type;
    this.radius = options.radius;

    // The position that the object will always move back to once no longer
    // held/moved
    this.homePosition = options.homePosition;
    // Set to true when moving back to home
    this.movingHome = false;

    this.shouldAutoRotate = options.shouldAutoRotate || true;
    this.autoRotationSpeed = options.autoRotationSpeed || -0.005;

    this.group = new THREE.Group();

    var video = document.getElementById(options.videoId);
    var texture = new THREE.VideoTexture(video);
    texture.minFilter = THREE.LinearFilter;
    texture.magFilter = THREE.LinearFilter;
    texture.format = THREE.RGBFormat;

    this.infoView = new THREE.Mesh(
      new THREE.BoxGeometry(160 * 0.6, 90 * 0.8, 2),
      new THREE.MeshLambertMaterial({color: 0xffffff, map: texture, transparent: true})
    );
    this.infoView.shouldCastShadow = true;
    this.infoView.castShadow = false;
    this.infoView.material.opacity = 0;
    this.infoViewVisible = false;
    this.infoViewOffset = new THREE.Vector3(
      options.radius,
      0,
      options.radius + 10
    );

    this.group.position.copy(this.homePosition);
  }

  attachToScene(scene) {
    scene.add(this.group);
    scene.add(this.infoView);
  }

  moveToHomePosition(options) {
    var startPosition = new THREE.Vector3();
    startPosition.copy(this.group.position);

    this.movingHome = true;

    // Face the home destination while moving home
    this.group.lookAt(startPosition);
    this.group.rotateY(Math.PI);

    var groupDistance = this.homePosition.clone().sub(startPosition);

    var deltaPercentPerTick = 1 / (options.duration / 16);
    var t = 0;

    var interval = setInterval(() => {
      t += deltaPercentPerTick;

      this.group.position.addVectors(startPosition, groupDistance.clone().multiplyScalar(t));
      this.infoView.position.addVectors(this.group.position, this.infoViewOffset);

      if (t >= 1) {
        clearInterval(interval);
        this.movingHome = false;
      }
    }, 16);
  }

  positionRelativeToHand(hand) {
    var palm = hand.palm;

    var yDistance = (this.radius || 100) + 30;

    this.group.position.addVectors(palm.position, hand.normal.multiplyScalar(yDistance));
    this.infoView.position.addVectors(this.group.position, this.infoViewOffset);
  }

  determineIfShowInfoView() {
    var showThreshold = 50;
    var zPosition = this.group.position.z;
    if (zPosition >= showThreshold && !this.infoViewVisible) {
      this.infoViewVisible = true;
      this.fadeInInfoView(200);
    } else if (zPosition < showThreshold && this.infoViewVisible) {
      this.infoViewVisible = false;
      this.fadeOutInfoView(200);
    }
  }

  update() {
    if(!this.movingHome) {
      this.rotate();
    }
  }

  rotate() {
    this.group.rotateY(this.autoRotationSpeed);
  }

  fadeInInfoView(duration) {
    if (this.infoView.material.opacity >= 1) return;

    var fade = setInterval(() => {
      this.infoView.material.opacity += 0.05;
      if (this.infoView.material.opacity >= 1) {
        if (this.infoView.shouldCastShadow) {
          this.infoView.castShadow = true;
        }
        clearInterval(fade);
      }
    }, duration / 20);
  }

  fadeOutInfoView(duration) {
    if (this.infoView.material.opacity <= 0) return;

    var fade = setInterval(() => {
      this.infoView.material.opacity -= 0.05;
      if (this.infoView.material.opacity <= 0) {
        this.infoView.castShadow = false;
        clearInterval(fade);
      }
    }, duration / 20);
  }

  hideInfoViewImmediately() {
    this.infoViewVisible = false;
    this.infoView.material.opacity = 0;
    this.infoView.castShadow = false;
  }

}

module.exports = BaseObject;
<commit_msg>make video texture always have full lighting<commit_after>require('traceur/bin/traceur-runtime');

class BaseObject {
  constructor(options) {
    this.id = options.id;
    this.type = options.type;
    this.radius = options.radius;

    // The position that the object will always move back to once no longer
    // held/moved
    this.homePosition = options.homePosition;
    // Set to true when moving back to home
    this.movingHome = false;

    this.shouldAutoRotate = options.shouldAutoRotate || true;
    this.autoRotationSpeed = options.autoRotationSpeed || -0.005;

    this.group = new THREE.Group();

    var video = document.getElementById(options.videoId);
    var texture = new THREE.VideoTexture(video);
    texture.minFilter = THREE.LinearFilter;
    texture.magFilter = THREE.LinearFilter;
    texture.format = THREE.RGBFormat;

    this.infoView = new THREE.Mesh(
      new THREE.BoxGeometry(160 * 0.6, 90 * 0.8, 2),
      new THREE.MeshBasicMaterial({color: 0xffffff, map: texture, transparent: true})
    );
    this.infoView.shouldCastShadow = true;
    this.infoView.castShadow = false;
    this.infoView.material.opacity = 0;
    this.infoViewVisible = false;
    this.infoViewOffset = new THREE.Vector3(
      options.radius,
      0,
      options.radius + 10
    );

    this.group.position.copy(this.homePosition);
  }

  attachToScene(scene) {
    scene.add(this.group);
    scene.add(this.infoView);
  }

  moveToHomePosition(options) {
    var startPosition = new THREE.Vector3();
    startPosition.copy(this.group.position);

    this.movingHome = true;

    // Face the home destination while moving home
    this.group.lookAt(startPosition);
    this.group.rotateY(Math.PI);

    var groupDistance = this.homePosition.clone().sub(startPosition);

    var deltaPercentPerTick = 1 / (options.duration / 16);
    var t = 0;

    var interval = setInterval(() => {
      t += deltaPercentPerTick;

      this.group.position.addVectors(startPosition, groupDistance.clone().multiplyScalar(t));
      this.infoView.position.addVectors(this.group.position, this.infoViewOffset);

      if (t >= 1) {
        clearInterval(interval);
        this.movingHome = false;
      }
    }, 16);
  }

  positionRelativeToHand(hand) {
    var palm = hand.palm;

    var yDistance = (this.radius || 100) + 30;

    this.group.position.addVectors(palm.position, hand.normal.multiplyScalar(yDistance));
    this.infoView.position.addVectors(this.group.position, this.infoViewOffset);
  }

  determineIfShowInfoView() {
    var showThreshold = 50;
    var zPosition = this.group.position.z;
    if (zPosition >= showThreshold && !this.infoViewVisible) {
      this.infoViewVisible = true;
      this.fadeInInfoView(200);
    } else if (zPosition < showThreshold && this.infoViewVisible) {
      this.infoViewVisible = false;
      this.fadeOutInfoView(200);
    }
  }

  update() {
    if(!this.movingHome) {
      this.rotate();
    }
  }

  rotate() {
    this.group.rotateY(this.autoRotationSpeed);
  }

  fadeInInfoView(duration) {
    if (this.infoView.material.opacity >= 1) return;

    var fade = setInterval(() => {
      this.infoView.material.opacity += 0.05;
      if (this.infoView.material.opacity >= 1) {
        if (this.infoView.shouldCastShadow) {
          this.infoView.castShadow = true;
        }
        clearInterval(fade);
      }
    }, duration / 20);
  }

  fadeOutInfoView(duration) {
    if (this.infoView.material.opacity <= 0) return;

    var fade = setInterval(() => {
      this.infoView.material.opacity -= 0.05;
      if (this.infoView.material.opacity <= 0) {
        this.infoView.castShadow = false;
        clearInterval(fade);
      }
    }, duration / 20);
  }

  hideInfoViewImmediately() {
    this.infoViewVisible = false;
    this.infoView.material.opacity = 0;
    this.infoView.castShadow = false;
  }

}

module.exports = BaseObject;
<|endoftext|>


<commit_before>var TCM = TCM || {};

(function($) {

    var autoFocus = function(trigger) {
        $(trigger).click(function() {
            if ($(this).parent().hasClass('open')) {
                $(this).parent().find('textarea').focus();
            }
        });
    };

    var testCaseButtons = function(context) {
        $(context).find("button").click(
            function(event) {
                event.preventDefault();
                event.stopPropagation();
                var button = $(this),
                    testcase = button.closest(context),
                    container = button.closest("div.form"),
                    data = {
                        action: button.attr("data-action")
                    },
                    inputs = container.find("input"),
                    post = true;
                container.find("textarea").add(inputs).each(
                    function() {
                        var val = $(this).val();
                        if (val) {
                            data[$(this).attr("name")] = val;
                        } else {
                            $(this).siblings("ul.errorlist").remove();
                            $(this).before(
                                "

" +
                                    "This field is required." +
                                    "

"
                            );
                            $('.loadingCSS').detach();
                            $('.loading').removeClass("loading");
                            post = false;
                        }
                    }
                );
                if ( post ) {
                    $.post(
                        testcase.attr("data-action-url"),
                        data,
                        function(data) {
                            var id = testcase.attr("id");
                            testcase.replaceWith(data);
                            var newCase = "#" + id;
                            $(newCase).find('details').andSelf().html5accordion('summary');
                            testCaseButtons(newCase);
                            TCM.addLoading('button, a', testcase);
                            $('.loadingCSS').detach();
                            autoFocus('details.stepfail > summary');
                            autoFocus('details.testinvalid > summary');
                        }
                    );
                }
            }
        );
    };

    var selectRuns = function(context) {
        var context = $(context),
            environments = $('#environment').hide(),
            products = context.find('input[name="product"]'),
            cycles = context.find('input[name="cycle"]'),
            runs = context.find('input[name="run"]'),
            headers = context.find('h3 > a').click(function() {
                context.find('section').removeClass('focus');
                $(this).closest('section').addClass('focus');
            });
            context.find('header').each(function() {
                var scrollbarWidth = $(this).closest('section').css('width') - $(this).children('li').css('width');
                $(this).css('right', scrollbarWidth);
            });
        products.live('click', function() {
            var product = $(this).data('id'),
                fakeAjaxCall = function(product, callback) {
                    var response =
                        '
' +
                            '<input type="radio" name="cycle" value="" id="' + product + '_cycle_name_01" data-product="' + product + '" data-cycle="01">' +
                            '' +
                                '75%' +
                                '' + product + ' cycle name 01' +
                                '<time class="start">01/07/2011</time>' +
                                '<time class="end">11/10/2011</time>' +
                            '' +
                        '
' +
                        '
' +
                            '<input type="radio" name="cycle" value="" id="' + product + '_cycle_name_02" data-product="' + product + '" data-cycle="02">' +
                            '' +
                                '100%' +
                                '' + product + ' cycle name 02' +
                                '<time class="start">01/07/2011</time>' +
                                '<time class="end">11/10/2011</time>' +
                            '' +
                        '
' +
                        '
' +
                            '<input type="radio" name="cycle" value="" id="' + product + '_cycle_name_03" data-product="' + product + '" data-cycle="03">' +
                            '' +
                                '25%' +
                                '' + product + ' cycle name 03' +
                                '<time class="start">01/07/2011</time>' +
                                '<time class="end">11/10/2011</time>' +
                            '' +
                        '
' +
                        '
' +
                            '<input type="radio" name="cycle" value="" id="' + product + '_cycle_name_04" data-product="' + product + '" data-cycle="04">' +
                            '' +
                                '17%' +
                                '' + product + ' cycle name 04' +
                                '<time class="start">01/07/2011</time>' +
                                '<time class="end">11/10/2011</time>' +
                            '' +
                        '
' +
                        '
' +
                            '<input type="radio" name="cycle" value="" id="' + product + '_cycle_name_05" data-product="' + product + '" data-cycle="05">' +
                            '' +
                                '50%' +
                                '' + product + ' cycle name 05' +
                                '<time class="start">01/07/2011</time>' +
                                '<time class="end">11/10/2011</time>' +
                            '' +
                        '
' +
                        '
' +
                            '<input type="radio" name="cycle" value="" id="' + product + '_cycle_name_06" data-product="' + product + '" data-cycle="06">' +
                            '' +
                                '83%' +
                                '' + product + ' cycle name 06' +
                                '<time class="start">01/07/2011</time>' +
                                '<time class="end">11/10/2011</time>' +
                            '' +
                        '
';
                    callback(response);
                };
            fakeAjaxCall(
                product,
                function(data) {
                    $('section.cycles ul').html(data);
                    $('section.runs ul').html('');
                }
            );
            $(this).closest('section.products').removeClass('focus');
            context.find('section.runs').removeClass('focus');
            context.find('section.cycles').addClass('focus');
            environments.slideUp();
        });
        cycles.live('click', function() {
            var product = $(this).data('product'),
                cycleNumber = $(this).data('cycle'),
                fakeAjaxCall = function(product, cycleNumber, callback) {
                    var response =
                        '
' +
                            '<input type="radio" name="run" value="" id="' + product + '_run_0' + cycleNumber + '_01">' +
                            '' +
                                '' + product + ' run 0' + cycleNumber + '-01' +
                                '<time class="start">01/07/2011</time>' +
                                '<time class="end">11/10/2011</time>' +
                            '' +
                        '
' +
                        '
' +
                            '<input type="radio" name="run" value="" id="' + product + '_run_0' + cycleNumber + '_02">' +
                            '' +
                                '' + product + ' run 0' + cycleNumber + '-02' +
                                '<time class="start">01/07/2011</time>' +
                                '<time class="end">11/10/2011</time>' +
                            '' +
                        '
' +
                        '
' +
                            '<input type="radio" name="run" value="" id="' + product + '_run_0' + cycleNumber + '_03">' +
                            '' +
                                '' + product + ' run 0' + cycleNumber + '-03' +
                                '<time class="start">01/07/2011</time>' +
                                '<time class="end">11/10/2011</time>' +
                            '' +
                        '
' +
                        '
' +
                            '<input type="radio" name="run" value="" id="' + product + '_run_0' + cycleNumber + '_04">' +
                            '' +
                                '' + product + ' run 0' + cycleNumber + '-04' +
                                '<time class="start">01/07/2011</time>' +
                                '<time class="end">11/10/2011</time>' +
                            '' +
                        '
' +
                        '
' +
                            '<input type="radio" name="run" value="" id="' + product + '_run_0' + cycleNumber + '_05">' +
                            '' +
                                '' + product + ' run 0' + cycleNumber + '-05' +
                                '<time class="start">01/07/2011</time>' +
                                '<time class="end">11/10/2011</time>' +
                            '' +
                        '
' +
                        '
' +
                            '<input type="radio" name="run" value="" id="' + product + '_run_0' + cycleNumber + '_06">' +
                            '' +
                                '' + product + ' run 0' + cycleNumber + '-06' +
                                '<time class="start">01/07/2011</time>' +
                                '<time class="end">11/10/2011</time>' +
                            '' +
                        '
';
                    callback(response);
                };
            fakeAjaxCall(
                product,
                cycleNumber,
                function(data) {
                    $('section.runs ul').html(data);
                }
            );
            $(this).closest('section.cycles').removeClass('focus');
            context.find('section.products').removeClass('focus');
            context.find('section.runs').addClass('focus');
            environments.slideUp();
        });
        runs.live('click', function() {
            environments.slideDown();
        });
    };

    $(function() {
        autoFocus('details.stepfail > summary');
        autoFocus('details.testinvalid > summary');
        testCaseButtons("details.test");
        $("div[role=main]").ajaxError(
            function(event, request, settings) {
                $(this).prepend(
                    '' + request.responseText + ''
                );
                $('.loadingCSS').detach();
                $('.loading').removeClass("loading");
            }
        );
        selectRuns('#selectruns');
    });

})(jQuery);<commit_msg>js cleanup<commit_after>var TCM = TCM || {};

(function($) {

    var autoFocus = function(trigger) {
        $(trigger).click(function() {
            if ($(this).parent().hasClass('open')) {
                $(this).parent().find('textarea').focus();
            }
        });
    };

    var testCaseButtons = function(context) {
        $(context).find("button").click(
            function(event) {
                event.preventDefault();
                event.stopPropagation();
                var button = $(this),
                    testcase = button.closest(context),
                    container = button.closest("div.form"),
                    data = {
                        action: button.attr("data-action")
                    },
                    inputs = container.find("input"),
                    post = true;
                container.find("textarea").add(inputs).each(
                    function() {
                        var val = $(this).val();
                        if (val) {
                            data[$(this).attr("name")] = val;
                        } else {
                            $(this).siblings("ul.errorlist").remove();
                            $(this).before(
                                "

" +
                                    "This field is required." +
                                    "

"
                            );
                            $('.loadingCSS').detach();
                            $('.loading').removeClass("loading");
                            post = false;
                        }
                    }
                );
                if ( post ) {
                    $.post(
                        testcase.attr("data-action-url"),
                        data,
                        function(data) {
                            var id = testcase.attr("id");
                            testcase.replaceWith(data);
                            var newCase = "#" + id;
                            $(newCase).find('details').andSelf().html5accordion('summary');
                            testCaseButtons(newCase);
                            TCM.addLoading('button, a', testcase);
                            $('.loadingCSS').detach();
                            autoFocus('details.stepfail > summary');
                            autoFocus('details.testinvalid > summary');
                        }
                    );
                }
            }
        );
    };

    var selectRuns = function(context) {
        var context = $(context),
            environments = $('#environment').hide(),
            products = context.find('input[name="product"]'),
            cycles = context.find('input[name="cycle"]'),
            runs = context.find('input[name="run"]'),
            headers = context.find('h3 > a').click(function() {
                context.find('section').removeClass('focus');
                $(this).closest('section').addClass('focus');
            });
            context.find('header').each(function() {
                var scrollbarWidth = $(this).closest('section').css('width') - $(this).children('li').css('width');
                $(this).css('right', scrollbarWidth);
            });
        products.live('click', function() {
            var productName = $(this).data('id'),
                fakeAjaxCall = function(productName, callback) {
                    var response =
                        '
' +
                            '<input type="radio" name="cycle" value="" id="' + productName + '_cycle_name_01" data-product="' + productName + '" data-cycle="01">' +
                            '' +
                                '75%' +
                                '' + productName + ' cycle name 01' +
                                '<time class="start">01/07/2011</time>' +
                                '<time class="end">11/10/2011</time>' +
                            '' +
                        '
' +
                        '
' +
                            '<input type="radio" name="cycle" value="" id="' + productName + '_cycle_name_02" data-product="' + productName + '" data-cycle="02">' +
                            '' +
                                '100%' +
                                '' + productName + ' cycle name 02' +
                                '<time class="start">01/07/2011</time>' +
                                '<time class="end">11/10/2011</time>' +
                            '' +
                        '
' +
                        '
' +
                            '<input type="radio" name="cycle" value="" id="' + productName + '_cycle_name_03" data-product="' + productName + '" data-cycle="03">' +
                            '' +
                                '25%' +
                                '' + productName + ' cycle name 03' +
                                '<time class="start">01/07/2011</time>' +
                                '<time class="end">11/10/2011</time>' +
                            '' +
                        '
' +
                        '
' +
                            '<input type="radio" name="cycle" value="" id="' + productName + '_cycle_name_04" data-product="' + productName + '" data-cycle="04">' +
                            '' +
                                '17%' +
                                '' + productName + ' cycle name 04' +
                                '<time class="start">01/07/2011</time>' +
                                '<time class="end">11/10/2011</time>' +
                            '' +
                        '
' +
                        '
' +
                            '<input type="radio" name="cycle" value="" id="' + productName + '_cycle_name_05" data-product="' + productName + '" data-cycle="05">' +
                            '' +
                                '50%' +
                                '' + productName + ' cycle name 05' +
                                '<time class="start">01/07/2011</time>' +
                                '<time class="end">11/10/2011</time>' +
                            '' +
                        '
' +
                        '
' +
                            '<input type="radio" name="cycle" value="" id="' + productName + '_cycle_name_06" data-product="' + productName + '" data-cycle="06">' +
                            '' +
                                '83%' +
                                '' + productName + ' cycle name 06' +
                                '<time class="start">01/07/2011</time>' +
                                '<time class="end">11/10/2011</time>' +
                            '' +
                        '
';
                    callback(response);
                };
            fakeAjaxCall(
                productName,
                function(data) {
                    $('section.cycles ul').html(data);
                    $('section.runs ul').html('');
                }
            );
            $(this).closest('section.products').removeClass('focus');
            context.find('section.runs').removeClass('focus');
            context.find('section.cycles').addClass('focus');
            environments.slideUp();
        });
        cycles.live('click', function() {
            var productName = $(this).data('product'),
                cycleNumber = $(this).data('cycle'),
                fakeAjaxCall = function(productName, cycleNumber, callback) {
                    var response =
                        '
' +
                            '<input type="radio" name="run" value="" id="' + productName + '_run_0' + cycleNumber + '_01">' +
                            '' +
                                '' + productName + ' run 0' + cycleNumber + '-01' +
                                '<time class="start">01/07/2011</time>' +
                                '<time class="end">11/10/2011</time>' +
                            '' +
                        '
' +
                        '
' +
                            '<input type="radio" name="run" value="" id="' + productName + '_run_0' + cycleNumber + '_02">' +
                            '' +
                                '' + productName + ' run 0' + cycleNumber + '-02' +
                                '<time class="start">01/07/2011</time>' +
                                '<time class="end">11/10/2011</time>' +
                            '' +
                        '
' +
                        '
' +
                            '<input type="radio" name="run" value="" id="' + productName + '_run_0' + cycleNumber + '_03">' +
                            '' +
                                '' + productName + ' run 0' + cycleNumber + '-03' +
                                '<time class="start">01/07/2011</time>' +
                                '<time class="end">11/10/2011</time>' +
                            '' +
                        '
' +
                        '
' +
                            '<input type="radio" name="run" value="" id="' + productName + '_run_0' + cycleNumber + '_04">' +
                            '' +
                                '' + productName + ' run 0' + cycleNumber + '-04' +
                                '<time class="start">01/07/2011</time>' +
                                '<time class="end">11/10/2011</time>' +
                            '' +
                        '
' +
                        '
' +
                            '<input type="radio" name="run" value="" id="' + productName + '_run_0' + cycleNumber + '_05">' +
                            '' +
                                '' + productName + ' run 0' + cycleNumber + '-05' +
                                '<time class="start">01/07/2011</time>' +
                                '<time class="end">11/10/2011</time>' +
                            '' +
                        '
' +
                        '
' +
                            '<input type="radio" name="run" value="" id="' + productName + '_run_0' + cycleNumber + '_06">' +
                            '' +
                                '' + productName + ' run 0' + cycleNumber + '-06' +
                                '<time class="start">01/07/2011</time>' +
                                '<time class="end">11/10/2011</time>' +
                            '' +
                        '
';
                    callback(response);
                };
            fakeAjaxCall(
                productName,
                cycleNumber,
                function(data) {
                    $('section.runs ul').html(data);
                }
            );
            $(this).closest('section.cycles').removeClass('focus');
            context.find('section.products').removeClass('focus');
            context.find('section.runs').addClass('focus');
            environments.slideUp();
        });
        runs.live('click', function() {
            environments.slideDown();
        });
    };

    $(function() {
        autoFocus('details.stepfail > summary');
        autoFocus('details.testinvalid > summary');
        testCaseButtons("details.test");
        $("div[role=main]").ajaxError(
            function(event, request, settings) {
                $(this).prepend(
                    '' + request.responseText + ''
                );
                $('.loadingCSS').detach();
                $('.loading').removeClass("loading");
            }
        );
        selectRuns('#selectruns');
    });

})(jQuery);<|endoftext|>


<commit_before>/**
 * @file Structure Representation
 * @author Alexander Rose <alexander.rose@weirdbyte.de>
 * @private
 */

import { ExtensionFragDepth, Mobile } from '../globals'
import { defaults } from '../utils'
import Representation from './representation.js'
import Selection from '../selection/selection.js'
import RadiusFactory, { RadiusFactoryTypes } from '../utils/radius-factory.js'

/**
 * Structure representation parameter object.
 * @typedef {Object} StructureRepresentationParameters - structure representation parameters
 * @mixes RepresentationParameters
 *
 * @property {String} radiusType - A list of possible sources of the radius used for rendering the representation. The radius can be based on the *vdW radius*, the *covalent radius* or the *B-factor* value of the corresponding atom. Additionally the radius can be based on the *secondary structure*. Alternatively, when set to *size*, the value from the *radius* parameter is used for all atoms.
 * @property {Float} radius - A number providing a fixed radius used for rendering the representation.
 * @property {Float} scale - A number that scales the value defined by the *radius* or the *radiusType* parameter.
 * @property {String} assembly - name of an assembly object. Included are the asymmetric unit (*AU*) corresponding to the coordinates given in the structure file, biological assemblies from *PDB*, *mmCIF* or *MMTF* files (*BU1*, *BU2*, ...), a filled (crystallographic) unitcell of a given space group (*UNITCELL*), a supercell consisting of a center unitcell and its 26 direct neighbors (*SUPERCELL*). Set to *default* to use the default asemmbly of the structure object.
 */

/**
 * Structure representation
 * @interface
 */
class StructureRepresentation extends Representation {
  /**
   * Create Structure representation object
   * @param {Structure} structure - the structure to be represented
   * @param {Viewer} viewer - a viewer object
   * @param {StructureRepresentationParameters} params - structure representation parameters
   */
  constructor (structure, viewer, params) {
    const p = params || {}

    super(structure, viewer, p)

    this.type = 'structure'

    this.parameters = Object.assign({
      radiusType: {
        type: 'select', options: RadiusFactory.types
      },
      radiusData: {
        type: 'hidden'
      },
      radiusSize: {
        type: 'number', precision: 3, max: 10.0, min: 0.001
      },
      radiusScale: {
        type: 'number', precision: 3, max: 10.0, min: 0.001
      },
      assembly: null,
      defaultAssembly: {
        type: 'hidden'
      }
    }, this.parameters)

    /**
     * @type {Selection}
     * @private
     */
    this.selection = new Selection(p.sele)

    /**
     * @type {Array}
     * @private
     */
    this.dataList = []

    /**
     * @type {Structure}
     */
    this.structure = structure

    /**
     * @type {StructureView}
     */
    this.structureView = this.structure.getView(this.selection)

    if (structure.biomolDict) {
      const biomolOptions = {
        'default': 'default',
        '': (structure.unitcell ? 'AU' : 'FULL')
      }
      Object.keys(structure.biomolDict).forEach(function (k) {
        biomolOptions[ k ] = k
      })
      this.parameters.assembly = {
        type: 'select',
        options: biomolOptions,
        rebuild: true
      }
    } else {
      this.parameters.assembly = null
    }
  }

  get defaultScale () {
    return {
      'vdw': 1.0,
      'covalent': 1.0,
      'bfactor': 0.01,
      'sstruc': 1.0
    }
  }

  init (params) {
    const p = params || {}
    p.colorScheme = defaults(p.colorScheme, 'element')

    this.setRadius(p.radius, p)

    this.radiusType = defaults(p.radiusType, 'vdw')
    this.radiusData = defaults(p.radiusData, {})
    this.radiusSize = defaults(p.radiusSize, 1.0)
    this.radiusScale = defaults(p.radiusScale, 1.0)
    this.assembly = defaults(p.assembly, 'default')
    this.defaultAssembly = defaults(p.defaultAssembly, '')

    if (p.quality === 'auto') {
      p.quality = this.getQuality()
    }

    super.init(p)

    this.selection.signals.stringChanged.add(function (/* sele */) {
      this.build()
    }, this)

    this.build()
  }

  setRadius (value, p) {
    const types = Object.keys(RadiusFactoryTypes)

    if (typeof value === 'string' && types.includes(value.toLowerCase())) {
      p.radiusType = value
    } else if (value !== undefined) {
      p.radiusType = 'size'
      p.radiusSize = value
    }

    return this
  }

  getAssembly () {
    const name = this.assembly === 'default' ? this.defaultAssembly : this.assembly
    return this.structure.biomolDict[ name ]
  }

  getQuality () {
    let atomCount
    const s = this.structureView
    const assembly = this.getAssembly()
    if (assembly) {
      atomCount = assembly.getAtomCount(s)
    } else {
      atomCount = s.atomCount
    }
    if (Mobile) {
      atomCount *= 4
    }
    const backboneOnly = s.atomStore.count / s.residueStore.count < 2
    if (backboneOnly) {
      atomCount *= 10
    }

    if (atomCount < 15000) {
      return 'high'
    } else if (atomCount < 80000) {
      return 'medium'
    } else {
      return 'low'
    }
  }

  create () {
    if (this.structureView.atomCount === 0) return

    if (!this.structureView.hasCoords()) {
      this.needsBuild = true
      return
    } else {
      this.needsBuild = false
    }

    const assembly = this.getAssembly()

    if (assembly) {
      assembly.partList.forEach(function (part, i) {
        const sview = part.getView(this.structureView)
        if (sview.atomCount === 0) return
        const data = this.createData(sview, i)
        if (data) {
          data.sview = sview
          data.instanceList = part.getInstanceList()
          this.dataList.push(data)
        }
      }, this)
    } else {
      const data = this.createData(this.structureView, 0)
      if (data) {
        data.sview = this.structureView
        this.dataList.push(data)
      }
    }
  }

  createData (/* sview */) {
    console.error('createData not implemented')
  }

  update (what) {
    if (this.lazy && !this.visible) {
      Object.assign(this.lazyProps.what, what)
      return
    }

    if (this.needsBuild) {
      this.build()
      return
    }

    this.dataList.forEach(function (data) {
      if (data.bufferList.length > 0) {
        this.updateData(what, data)
      }
    }, this)
  }

  updateData (/* what, data */) {
    this.build()
  }

  getColorParams () {
    const p = super.getColorParams()
    p.structure = this.structure

    return p
  }

  getRadiusParams () {
    return {
      type: this.radiusType,
      scale: this.radiusScale,
      size: this.radiusSize,
      data: this.radiusData
    }
  }

  getAtomParams (what, params) {
    return Object.assign({
      what: what,
      colorParams: this.getColorParams(),
      radiusParams: this.getRadiusParams()
    }, params)
  }

  getBondParams (what, params) {
    return Object.assign({
      what: what,
      colorParams: this.getColorParams(),
      radiusParams: this.getRadiusParams()
    }, params)
  }

  getAtomRadius (atom) {
    if (this.structureView.atomSet.isSet(atom.index)) {
      const radiusFactory = new RadiusFactory(this.getRadiusParams())
      return radiusFactory.atomRadius(atom)
    }
    return 0
  }

  /**
   * Set representation parameters
   * @alias StructureRepresentation#setSelection
   * @param {String} string - selection string, see {@tutorial selection-language}
   * @param {Boolean} [silent] - don't trigger a change event in the selection
   * @return {StructureRepresentation} this object
   */
  setSelection (string, silent) {
    this.selection.setString(string, silent)

    return this
  }

  /**
   * Set representation parameters
   * @alias StructureRepresentation#setParameters
   * @param {StructureRepresentationParameters} params - structure parameter object
   * @param {Object} [what] - buffer data attributes to be updated,
   *                        note that this needs to be implemented in the
   *                        derived classes. Generally it allows more
   *                        fine-grained control over updating than
   *                        forcing a rebuild.
   * @param {Boolean} what.position - update position data
   * @param {Boolean} what.color - update color data
   * @param {Boolean} [rebuild] - whether or not to rebuild the representation
   * @return {StructureRepresentation} this object
   */
  setParameters (params, what = {}, rebuild = false) {
    const p = params || {}

    this.setRadius(p.radius, p)

    if (p.radiusData !== undefined || p.radiusSize !== undefined || p.radiusScale !== undefined) {
      what.radius = true
      if (!ExtensionFragDepth || this.disableImpostor) {
        rebuild = true
      }
    }

    if (p.defaultAssembly !== undefined &&
        p.defaultAssembly !== this.defaultAssembly &&
        ((this.assembly === 'default' && p.assembly === undefined) ||
          p.assembly === 'default')
    ) {
      rebuild = true
    }

    super.setParameters(p, what, rebuild)

    return this
  }

  getParameters () {
    const params = Object.assign(
      super.getParameters(),
      {
        sele: this.selection ? this.selection.string : undefined,
        defaultAssembly: this.defaultAssembly
      }
    )

    return params
  }

  attach (callback) {
    const viewer = this.viewer
    const bufferList = this.bufferList

    this.dataList.forEach(function (data) {
      data.bufferList.forEach(function (buffer) {
        bufferList.push(buffer)
        viewer.add(buffer, data.instanceList)
      })
    })

    this.setVisibility(this.visible)
    callback()
  }

  clear () {
    this.dataList.length = 0

    super.clear()
  }

  dispose () {
    this.structureView.dispose()

    delete this.structure
    delete this.structureView

    super.dispose()
  }
}

export default StructureRepresentation
<commit_msg>fix representation not update on radiusType change, #453<commit_after>/**
 * @file Structure Representation
 * @author Alexander Rose <alexander.rose@weirdbyte.de>
 * @private
 */

import { ExtensionFragDepth, Mobile } from '../globals'
import { defaults } from '../utils'
import Representation from './representation.js'
import Selection from '../selection/selection.js'
import RadiusFactory, { RadiusFactoryTypes } from '../utils/radius-factory.js'

/**
 * Structure representation parameter object.
 * @typedef {Object} StructureRepresentationParameters - structure representation parameters
 * @mixes RepresentationParameters
 *
 * @property {String} radiusType - A list of possible sources of the radius used for rendering the representation. The radius can be based on the *vdW radius*, the *covalent radius* or the *B-factor* value of the corresponding atom. Additionally the radius can be based on the *secondary structure*. Alternatively, when set to *size*, the value from the *radius* parameter is used for all atoms.
 * @property {Float} radius - A number providing a fixed radius used for rendering the representation.
 * @property {Float} scale - A number that scales the value defined by the *radius* or the *radiusType* parameter.
 * @property {String} assembly - name of an assembly object. Included are the asymmetric unit (*AU*) corresponding to the coordinates given in the structure file, biological assemblies from *PDB*, *mmCIF* or *MMTF* files (*BU1*, *BU2*, ...), a filled (crystallographic) unitcell of a given space group (*UNITCELL*), a supercell consisting of a center unitcell and its 26 direct neighbors (*SUPERCELL*). Set to *default* to use the default asemmbly of the structure object.
 */

/**
 * Structure representation
 * @interface
 */
class StructureRepresentation extends Representation {
  /**
   * Create Structure representation object
   * @param {Structure} structure - the structure to be represented
   * @param {Viewer} viewer - a viewer object
   * @param {StructureRepresentationParameters} params - structure representation parameters
   */
  constructor (structure, viewer, params) {
    const p = params || {}

    super(structure, viewer, p)

    this.type = 'structure'

    this.parameters = Object.assign({
      radiusType: {
        type: 'select', options: RadiusFactory.types
      },
      radiusData: {
        type: 'hidden'
      },
      radiusSize: {
        type: 'number', precision: 3, max: 10.0, min: 0.001
      },
      radiusScale: {
        type: 'number', precision: 3, max: 10.0, min: 0.001
      },
      assembly: null,
      defaultAssembly: {
        type: 'hidden'
      }
    }, this.parameters)

    /**
     * @type {Selection}
     * @private
     */
    this.selection = new Selection(p.sele)

    /**
     * @type {Array}
     * @private
     */
    this.dataList = []

    /**
     * @type {Structure}
     */
    this.structure = structure

    /**
     * @type {StructureView}
     */
    this.structureView = this.structure.getView(this.selection)

    if (structure.biomolDict) {
      const biomolOptions = {
        'default': 'default',
        '': (structure.unitcell ? 'AU' : 'FULL')
      }
      Object.keys(structure.biomolDict).forEach(function (k) {
        biomolOptions[ k ] = k
      })
      this.parameters.assembly = {
        type: 'select',
        options: biomolOptions,
        rebuild: true
      }
    } else {
      this.parameters.assembly = null
    }
  }

  get defaultScale () {
    return {
      'vdw': 1.0,
      'covalent': 1.0,
      'bfactor': 0.01,
      'sstruc': 1.0
    }
  }

  init (params) {
    const p = params || {}
    p.colorScheme = defaults(p.colorScheme, 'element')

    this.setRadius(p.radius, p)

    this.radiusType = defaults(p.radiusType, 'vdw')
    this.radiusData = defaults(p.radiusData, {})
    this.radiusSize = defaults(p.radiusSize, 1.0)
    this.radiusScale = defaults(p.radiusScale, 1.0)
    this.assembly = defaults(p.assembly, 'default')
    this.defaultAssembly = defaults(p.defaultAssembly, '')

    if (p.quality === 'auto') {
      p.quality = this.getQuality()
    }

    super.init(p)

    this.selection.signals.stringChanged.add(function (/* sele */) {
      this.build()
    }, this)

    this.build()
  }

  setRadius (value, p) {
    const types = Object.keys(RadiusFactoryTypes)

    if (typeof value === 'string' && types.includes(value.toLowerCase())) {
      p.radiusType = value
    } else if (value !== undefined) {
      p.radiusType = 'size'
      p.radiusSize = value
    }

    return this
  }

  getAssembly () {
    const name = this.assembly === 'default' ? this.defaultAssembly : this.assembly
    return this.structure.biomolDict[ name ]
  }

  getQuality () {
    let atomCount
    const s = this.structureView
    const assembly = this.getAssembly()
    if (assembly) {
      atomCount = assembly.getAtomCount(s)
    } else {
      atomCount = s.atomCount
    }
    if (Mobile) {
      atomCount *= 4
    }
    const backboneOnly = s.atomStore.count / s.residueStore.count < 2
    if (backboneOnly) {
      atomCount *= 10
    }

    if (atomCount < 15000) {
      return 'high'
    } else if (atomCount < 80000) {
      return 'medium'
    } else {
      return 'low'
    }
  }

  create () {
    if (this.structureView.atomCount === 0) return

    if (!this.structureView.hasCoords()) {
      this.needsBuild = true
      return
    } else {
      this.needsBuild = false
    }

    const assembly = this.getAssembly()

    if (assembly) {
      assembly.partList.forEach(function (part, i) {
        const sview = part.getView(this.structureView)
        if (sview.atomCount === 0) return
        const data = this.createData(sview, i)
        if (data) {
          data.sview = sview
          data.instanceList = part.getInstanceList()
          this.dataList.push(data)
        }
      }, this)
    } else {
      const data = this.createData(this.structureView, 0)
      if (data) {
        data.sview = this.structureView
        this.dataList.push(data)
      }
    }
  }

  createData (/* sview */) {
    console.error('createData not implemented')
  }

  update (what) {
    if (this.lazy && !this.visible) {
      Object.assign(this.lazyProps.what, what)
      return
    }

    if (this.needsBuild) {
      this.build()
      return
    }

    this.dataList.forEach(function (data) {
      if (data.bufferList.length > 0) {
        this.updateData(what, data)
      }
    }, this)
  }

  updateData (/* what, data */) {
    this.build()
  }

  getColorParams () {
    const p = super.getColorParams()
    p.structure = this.structure

    return p
  }

  getRadiusParams () {
    return {
      type: this.radiusType,
      scale: this.radiusScale,
      size: this.radiusSize,
      data: this.radiusData
    }
  }

  getAtomParams (what, params) {
    return Object.assign({
      what: what,
      colorParams: this.getColorParams(),
      radiusParams: this.getRadiusParams()
    }, params)
  }

  getBondParams (what, params) {
    return Object.assign({
      what: what,
      colorParams: this.getColorParams(),
      radiusParams: this.getRadiusParams()
    }, params)
  }

  getAtomRadius (atom) {
    if (this.structureView.atomSet.isSet(atom.index)) {
      const radiusFactory = new RadiusFactory(this.getRadiusParams())
      return radiusFactory.atomRadius(atom)
    }
    return 0
  }

  /**
   * Set representation parameters
   * @alias StructureRepresentation#setSelection
   * @param {String} string - selection string, see {@tutorial selection-language}
   * @param {Boolean} [silent] - don't trigger a change event in the selection
   * @return {StructureRepresentation} this object
   */
  setSelection (string, silent) {
    this.selection.setString(string, silent)

    return this
  }

  /**
   * Set representation parameters
   * @alias StructureRepresentation#setParameters
   * @param {StructureRepresentationParameters} params - structure parameter object
   * @param {Object} [what] - buffer data attributes to be updated,
   *                        note that this needs to be implemented in the
   *                        derived classes. Generally it allows more
   *                        fine-grained control over updating than
   *                        forcing a rebuild.
   * @param {Boolean} what.position - update position data
   * @param {Boolean} what.color - update color data
   * @param {Boolean} [rebuild] - whether or not to rebuild the representation
   * @return {StructureRepresentation} this object
   */
  setParameters (params, what = {}, rebuild = false) {
    const p = params || {}

    this.setRadius(p.radius, p)

    if (p.radiusType !== undefined || p.radiusData !== undefined || p.radiusSize !== undefined || p.radiusScale !== undefined) {
      what.radius = true
      if (!ExtensionFragDepth || this.disableImpostor) {
        rebuild = true
      }
    }

    if (p.defaultAssembly !== undefined &&
        p.defaultAssembly !== this.defaultAssembly &&
        ((this.assembly === 'default' && p.assembly === undefined) ||
          p.assembly === 'default')
    ) {
      rebuild = true
    }

    super.setParameters(p, what, rebuild)

    return this
  }

  getParameters () {
    const params = Object.assign(
      super.getParameters(),
      {
        sele: this.selection ? this.selection.string : undefined,
        defaultAssembly: this.defaultAssembly
      }
    )

    return params
  }

  attach (callback) {
    const viewer = this.viewer
    const bufferList = this.bufferList

    this.dataList.forEach(function (data) {
      data.bufferList.forEach(function (buffer) {
        bufferList.push(buffer)
        viewer.add(buffer, data.instanceList)
      })
    })

    this.setVisibility(this.visible)
    callback()
  }

  clear () {
    this.dataList.length = 0

    super.clear()
  }

  dispose () {
    this.structureView.dispose()

    delete this.structure
    delete this.structureView

    super.dispose()
  }
}

export default StructureRepresentation
<|endoftext|>


<commit_before>const backgroundVideo = document.querySelector('.js-background-video');

if (backgroundVideo) {
  const backgroundVideoContainer = document.querySelector('.js-background-video-container');
  const stopButton = document.querySelector('.js-stop-button');
  const timesToLoop = 1;
  const videoCredit = document.querySelector('.js-background-video-credit');
  const imageCredit = document.querySelector('.js-background-image-credit');
  let playCounter = 0;

  const showVideoCredit = () => {
    if (videoCredit) {
      videoCredit.classList.remove('hidden');
    }
    if (imageCredit) {
      imageCredit.classList.add('hidden');
    }
  };

  const hideVideoCredit = () => {
    if (videoCredit) {
      videoCredit.classList.add('hidden');
    }
    if (imageCredit) {
      imageCredit.classList.remove('hidden');
    }
  };

  // Looping videos do not trigger ended events and manually looping
  // videos from JS is disabled in many browsers. The canplaythrough event here
  // is (approximately) mimicking an ended event for loops.
  backgroundVideo.addEventListener('canplaythrough', () => {
    if (playCounter >= timesToLoop) {
      backgroundVideoContainer.classList.remove('b-video-background--fade');
      backgroundVideo.pause();
      hideVideoCredit();
    } else {
      backgroundVideoContainer.classList.add('b-video-background--fade');
      playCounter += 1;
      showVideoCredit();
    }
  });

  const pauseHiddenVideo = () => {
    // offsetHeight always equals 0 if an element is hidden
    if (backgroundVideoContainer.offsetHeight === 0) {
      backgroundVideo.pause();
      hideVideoCredit();
    } else {
      backgroundVideo.play();
      showVideoCredit();
    }
  };

  window.addEventListener('load', () => {
    pauseHiddenVideo();
  });

  window.addEventListener('resize', () => {
    pauseHiddenVideo();
  });

  if (stopButton) {
    stopButton.onclick = () => {
      backgroundVideo.pause();
      backgroundVideoContainer.classList.remove('b-video-background--fade');
      if (backgroundVideo.paused) {
        stopButton.classList.add('hidden');
        hideVideoCredit();
      }
    };
  }
}
<commit_msg>reverts bg video loop number to 20<commit_after>const backgroundVideo = document.querySelector('.js-background-video');

if (backgroundVideo) {
  const backgroundVideoContainer = document.querySelector('.js-background-video-container');
  const stopButton = document.querySelector('.js-stop-button');
  const timesToLoop = 20;
  const videoCredit = document.querySelector('.js-background-video-credit');
  const imageCredit = document.querySelector('.js-background-image-credit');
  let playCounter = 0;

  const showVideoCredit = () => {
    if (videoCredit) {
      videoCredit.classList.remove('hidden');
    }
    if (imageCredit) {
      imageCredit.classList.add('hidden');
    }
  };

  const hideVideoCredit = () => {
    if (videoCredit) {
      videoCredit.classList.add('hidden');
    }
    if (imageCredit) {
      imageCredit.classList.remove('hidden');
    }
  };

  // Looping videos do not trigger ended events and manually looping
  // videos from JS is disabled in many browsers. The canplaythrough event here
  // is (approximately) mimicking an ended event for loops.
  backgroundVideo.addEventListener('canplaythrough', () => {
    if (playCounter >= timesToLoop) {
      backgroundVideoContainer.classList.remove('b-video-background--fade');
      backgroundVideo.pause();
      hideVideoCredit();
    } else {
      backgroundVideoContainer.classList.add('b-video-background--fade');
      playCounter += 1;
      showVideoCredit();
    }
  });

  const pauseHiddenVideo = () => {
    // offsetHeight always equals 0 if an element is hidden
    if (backgroundVideoContainer.offsetHeight === 0) {
      backgroundVideo.pause();
      hideVideoCredit();
    } else {
      backgroundVideo.play();
      showVideoCredit();
    }
  };

  window.addEventListener('load', () => {
    pauseHiddenVideo();
  });

  window.addEventListener('resize', () => {
    pauseHiddenVideo();
  });

  if (stopButton) {
    stopButton.onclick = () => {
      backgroundVideo.pause();
      backgroundVideoContainer.classList.remove('b-video-background--fade');
      if (backgroundVideo.paused) {
        stopButton.classList.add('hidden');
        hideVideoCredit();
      }
    };
  }
}
<|endoftext|>