<commit_before>/*! jQuery printElement - v2.0.1 - 2014-08-22
* https://github.com/erikzaadi/jQuery.printElement
* Copyright (c) 2014 erikzaadi; Licensed MIT, GPL */
/*global window,focus,setTimeout,navigator*/
(function (window, undefined) {
    var document = window.document;
    var $ = window.jQuery;
    $.fn.printElement = function (options) {
        var mainOptions = $.extend({}, $.fn.printElement.defaults, options);
        //iframe mode is not supported for opera and chrome 3.0 (it prints the entire page).
        //http://www.google.com/support/forum/p/Webmasters/thread?tid=2cb0f08dce8821c3&hl=en
        if (mainOptions.printMode === 'iframe') {
            if (/chrome/.test(navigator.userAgent.toLowerCase())) {
                mainOptions.printMode = 'popup';
            }
        }
        //Remove previously printed iframe if exists
        $("[id^='printElement_']").remove();

        return this.each(function () {
            //Support Metadata Plug-in if available
            var opts = $.meta ? $.extend({}, mainOptions, $(this).data()) : mainOptions;
            _printElement($(this), opts);
        });
    };
    $.fn.printElement.defaults = {
        "printMode": 'iframe', //Usage : iframe / popup
        "pageTitle": '', //Print Page Title
        "overrideElementCSS": null,
        /* Can be one of the following 3 options:
        * 1 : boolean (pass true for stripping all css linked)
        * 2 : array of $.fn.printElement.cssElement (s)
        * 3 : array of strings with paths to alternate css files (optimized for print)
        */
        "printBodyOptions": {
            "styleToAdd": 'padding:10px;margin:10px;', //style attributes to add to the body of print document
            "classNameToAdd": '' //css class to add to the body of print document
        },
        "leaveOpen": false, // in case of popup, leave the print page open or not
        "iframeElementOptions": {
            "styleToAdd": 'border:none;position:absolute;width:0px;height:0px;bottom:0px;left:0px;', //style attributes to add to the iframe element
            "classNameToAdd": '' //css class to add to the iframe element
        }
    };
    $.fn.printElement.cssElement = {
        "href": '',
        "media": ''
    };
    function _printElement(element, opts) {
        //Create markup to be printed
        var html = _getMarkup(element, opts);

        var popupOrIframe = null;
        var documentToWriteTo = null;
        if (opts.printMode.toLowerCase() === 'popup') {
            popupOrIframe = window.open('about:blank', 'printElementWindow', 'width=650,height=440,scrollbars=yes');
            documentToWriteTo = popupOrIframe.document;
        }
        else {
            //The random ID is to overcome a safari bug http://www.cjboco.com.sharedcopy.com/post.cfm/442dc92cd1c0ca10a5c35210b8166882.html
            var printElementID = "printElement_" + (Math.round(Math.random() * 99999)).toString();
            //Native creation of the element is faster..
            var iframe = document.createElement('IFRAME');
            $(iframe).attr({
                style: opts.iframeElementOptions.styleToAdd,
                id: printElementID,
                className: opts.iframeElementOptions.classNameToAdd,
                frameBorder: 0,
                scrolling: 'no',
                src: 'about:blank'
            });
            document.body.appendChild(iframe);
            documentToWriteTo = (iframe.contentWindow || iframe.contentDocument);
            if (documentToWriteTo.document) {
                documentToWriteTo = documentToWriteTo.document;
            }
            iframe = document.frames ? document.frames[printElementID] : document.getElementById(printElementID);
            popupOrIframe = iframe.contentWindow || iframe;
        }
        focus();
        documentToWriteTo.open();
        documentToWriteTo.write(html);
        documentToWriteTo.close();
        _callPrint(popupOrIframe);
    }

    function _callPrint(element) {
        if (element && element.printPage) {
            element.printPage();
        }
        else {
            setTimeout(function () {
                _callPrint(element);
            }, 50);
        }
    }

    function _getElementHTMLIncludingFormElements(element) {
        var $element = $(element);
        //Radiobuttons and checkboxes
        $(":checked", $element).each(function () {
            this.setAttribute('checked', 'checked');
        });
        //simple text inputs
        $("input[type='text'],input[type='number']", $element).each(function () {
            this.setAttribute('value', $(this).val());
        });
        $("select", $element).each(function () {
            var $select = $(this);
            $("option", $select).each(function () {
                if ($select.val() === $(this).val()) {
                    this.setAttribute('selected', 'selected');
                }
            });
        });
        $("textarea", $element).each(function () {
            //Thanks http://blog.ekini.net/2009/02/24/jquery-getting-the-latest-textvalue-inside-a-textarea/
            var value = $(this).attr('value');
            //fix for issue 7 (http://plugins.jquery.com/node/13503 and http://github.com/erikzaadi/jQueryPlugins/issues#issue/7)
            if (this.firstChild) {
                this.firstChild.textContent = value;
            }
            else {
                this.innerHTML = value;
            }
        });
        //http://dbj.org/dbj/?p=91
        var elementHtml = $('

').append($element.clone()).html();
        return elementHtml;
    }

    function _getBaseHref() {
        var port = (window.location.port) ? ':' + window.location.port : '';
        return window.location.protocol + '//' + window.location.hostname + port + window.location.pathname;
    }

    function _getMarkup(element, opts) {
        var $element = $(element);
        var elementHtml = _getElementHTMLIncludingFormElements(element);

        var html = [];
        html.push('<title>' + opts.pageTitle + '</title>');
        if (opts.overrideElementCSS) {
            if (opts.overrideElementCSS.length > 0) {
                for (var x = 0; x < opts.overrideElementCSS.length; x += 1) {
                    var current = opts.overrideElementCSS[x];
                    if (typeof (current) === 'string') {
                        html.push('<link type="text/css" rel="stylesheet" href="' + current + '" >');
                    }
                    else {
                        var media = current.media || '';
                        html.push('<link type="text/css" rel="stylesheet" href="' + current.href + '" media="' + media + '" >');
                    }
                }
            }
        }
        else {
            $("link", document).filter(function () {
                return $(this).attr("rel").toLowerCase() === "stylesheet";
            }).each(function () {
                var media = $(this).attr('media') || '';
                html.push('<link type="text/css" rel="stylesheet" href="' + $(this).attr("href") + '" media="' + media + '" >');
            });
        }
        //Ensure that relative links work
        html.push('<base href="' + _getBaseHref() + '" />');
        html.push('');
        html.push('
' + elementHtml + '
');
        html.push('');
        html.push('');

        return html.join('');
    }
}(window));
<commit_msg>reformatted the else statements.. one line please<commit_after>/*! jQuery printElement - v2.0.1 - 2014-08-22
* https://github.com/erikzaadi/jQuery.printElement
* Copyright (c) 2014 erikzaadi; Licensed MIT, GPL */
/*global window,focus,setTimeout,navigator*/
(function (window, undefined) {
    var document = window.document;
    var $ = window.jQuery;
    $.fn.printElement = function (options) {
        var mainOptions = $.extend({}, $.fn.printElement.defaults, options);
        //iframe mode is not supported for opera and chrome 3.0 (it prints the entire page).
        //http://www.google.com/support/forum/p/Webmasters/thread?tid=2cb0f08dce8821c3&hl=en
        if (mainOptions.printMode === 'iframe') {
            if (/chrome/.test(navigator.userAgent.toLowerCase())) {
                mainOptions.printMode = 'popup';
            }
        }
        //Remove previously printed iframe if exists
        $("[id^='printElement_']").remove();

        return this.each(function () {
            //Support Metadata Plug-in if available
            var opts = $.meta ? $.extend({}, mainOptions, $(this).data()) : mainOptions;
            _printElement($(this), opts);
        });
    };
    $.fn.printElement.defaults = {
        "printMode": 'iframe', //Usage : iframe / popup
        "pageTitle": '', //Print Page Title
        "overrideElementCSS": null,
        /* Can be one of the following 3 options:
        * 1 : boolean (pass true for stripping all css linked)
        * 2 : array of $.fn.printElement.cssElement (s)
        * 3 : array of strings with paths to alternate css files (optimized for print)
        */
        "printBodyOptions": {
            "styleToAdd": 'padding:10px;margin:10px;', //style attributes to add to the body of print document
            "classNameToAdd": '' //css class to add to the body of print document
        },
        "leaveOpen": false, // in case of popup, leave the print page open or not
        "iframeElementOptions": {
            "styleToAdd": 'border:none;position:absolute;width:0px;height:0px;bottom:0px;left:0px;', //style attributes to add to the iframe element
            "classNameToAdd": '' //css class to add to the iframe element
        }
    };
    $.fn.printElement.cssElement = {
        "href": '',
        "media": ''
    };
    function _printElement(element, opts) {
        //Create markup to be printed
        var html = _getMarkup(element, opts);

        var popupOrIframe = null;
        var documentToWriteTo = null;
        if (opts.printMode.toLowerCase() === 'popup') {
            popupOrIframe = window.open('about:blank', 'printElementWindow', 'width=650,height=440,scrollbars=yes');
            documentToWriteTo = popupOrIframe.document;
        } else {
            //The random ID is to overcome a safari bug http://www.cjboco.com.sharedcopy.com/post.cfm/442dc92cd1c0ca10a5c35210b8166882.html
            var printElementID = "printElement_" + (Math.round(Math.random() * 99999)).toString();
            //Native creation of the element is faster..
            var iframe = document.createElement('IFRAME');
            $(iframe).attr({
                style: opts.iframeElementOptions.styleToAdd,
                id: printElementID,
                className: opts.iframeElementOptions.classNameToAdd,
                frameBorder: 0,
                scrolling: 'no',
                src: 'about:blank'
            });
            document.body.appendChild(iframe);
            documentToWriteTo = (iframe.contentWindow || iframe.contentDocument);
            if (documentToWriteTo.document) {
                documentToWriteTo = documentToWriteTo.document;
            }
            iframe = document.frames ? document.frames[printElementID] : document.getElementById(printElementID);
            popupOrIframe = iframe.contentWindow || iframe;
        }
        focus();
        documentToWriteTo.open();
        documentToWriteTo.write(html);
        documentToWriteTo.close();
        _callPrint(popupOrIframe);
    }

    function _callPrint(element) {
        if (element && element.printPage) {
            element.printPage();
        } else {
            setTimeout(function () {
                _callPrint(element);
            }, 50);
        }
    }

    function _getElementHTMLIncludingFormElements(element) {
        var $element = $(element);
        //Radiobuttons and checkboxes
        $(":checked", $element).each(function () {
            this.setAttribute('checked', 'checked');
        });
        //simple text inputs
        $("input[type='text'],input[type='number']", $element).each(function () {
            this.setAttribute('value', $(this).val());
        });
        $("select", $element).each(function () {
            var $select = $(this);
            $("option", $select).each(function () {
                if ($select.val() === $(this).val()) {
                    this.setAttribute('selected', 'selected');
                }
            });
        });
        $("textarea", $element).each(function () {
            //Thanks http://blog.ekini.net/2009/02/24/jquery-getting-the-latest-textvalue-inside-a-textarea/
            var value = $(this).attr('value');
            //fix for issue 7 (http://plugins.jquery.com/node/13503 and http://github.com/erikzaadi/jQueryPlugins/issues#issue/7)
            if (this.firstChild) {
                this.firstChild.textContent = value;
            } else {
                this.innerHTML = value;
            }
        });
        //http://dbj.org/dbj/?p=91
        var elementHtml = $('

').append($element.clone()).html();
        return elementHtml;
    }

    function _getBaseHref() {
        var port = (window.location.port) ? ':' + window.location.port : '';
        return window.location.protocol + '//' + window.location.hostname + port + window.location.pathname;
    }

    function _getMarkup(element, opts) {
        var $element = $(element);
        var elementHtml = _getElementHTMLIncludingFormElements(element);

        var html = [];
        html.push('<title>' + opts.pageTitle + '</title>');
        if (opts.overrideElementCSS) {
            if (opts.overrideElementCSS.length > 0) {
                for (var x = 0; x < opts.overrideElementCSS.length; x += 1) {
                    var current = opts.overrideElementCSS[x];
                    if (typeof (current) === 'string') {
                        html.push('<link type="text/css" rel="stylesheet" href="' + current + '" >');
                    } else {
                        var media = current.media || '';
                        html.push('<link type="text/css" rel="stylesheet" href="' + current.href + '" media="' + media + '" >');
                    }
                }
            }
        } else {
            $("link", document).filter(function () {
                return $(this).attr("rel").toLowerCase() === "stylesheet";
            }).each(function () {
                var media = $(this).attr('media') || '';
                html.push('<link type="text/css" rel="stylesheet" href="' + $(this).attr("href") + '" media="' + media + '" >');
            });
        }
        //Ensure that relative links work
        html.push('<base href="' + _getBaseHref() + '" />');
        html.push('');
        html.push('
' + elementHtml + '
');
        html.push('');
        html.push('');

        return html.join('');
    }
}(window));
<|endoftext|>


<commit_before>/**
 * Copyright (C) 2011 Instructure, Inc.
 *
 * This file is part of Canvas.
 *
 * Canvas is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License as published by the Free
 * Software Foundation, version 3 of the License.
 *
 * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

var lastAnswerSelected = null;
var quizSubmission;
I18n.scoped('quizzes.take_quiz', function(I18n) {

  $(document).mousedown(function(event) {
    lastAnswerSelected = $(event.target).parents(".answer")[0];
  }).keydown(function() {
    lastAnswerSelected = null;
  });
  $(document).ready(function() {
    $.scrollSidebar();
    $("#questions").delegate('.group_top,.question,.answer_select', 'mouseover', function(event) {
      $(this).addClass('hover');
    }).delegate('.group_top,.question,.answer_select', 'mouseout', function(event) {
      $(this).removeClass('hover');
    });
    if($("#preview_mode_link").length == 0) {
      window.onbeforeunload = function() {
        quizSubmission.updateSubmission();
        if(!quizSubmission.submitting && !quizSubmission.alreadyAcceptedNavigatingAway) {
          return I18n.t('confirms.unfinished_quiz', "You're about to leave the quiz unfinished.  Continue anyway?");
        }
      };
      $(document).delegate('a', 'click', function(event) {
        if($(this).closest('.ui-dialog,.mceToolbar').length > 0) { return; }
        if(!event.isDefaultPrevented()) {
          var url = $(this).attr('href') || "";
          var hashStripped = location.href;
          if(hashStripped.indexOf('#')) {
            hashStripped = hashStripped.substring(0, hashStripped.indexOf('#'));
          }
          if(url.indexOf('#') == 0 || url.indexOf(hashStripped + "#") == 0) {
            return;
          }
          var result = confirm(I18n.t('confirms.navigate_away', "You're about to navigate away from this page.  Continue anyway?"));
          if(!result) {
            event.preventDefault();
          } else {
            quizSubmission.alreadyAcceptedNavigatingAway = true
          }
        }
      });
    }
    $(".list_question").live('mouseover', function(event) {
      if($(this).hasClass('marked')) {
        $(this).attr('title', I18n.t('titles.come_back_later', "You marked this question to come back to later"));
      } else if($(this).hasClass('answered')) {
        $(this).attr('title', I18n.t('titles.answered', "Answered"));
      } else {
        $(this).attr('title', I18n.t('titles.not_answered', "Haven't Answered yet"));
      }
      $("#" + $(this).attr('id').substring(5)).addClass('related');
    }).live('mouseout', function(event) {
      $("#questions .question_holder .question").removeClass('related');
    });
    $(".jump_to_question_link").live('click', function(event) {
      event.preventDefault();
      var $obj = $($(this).attr('href'));
      $("html,body").scrollTo($obj.parent());
      $obj.find(":input:first").focus().select();
    });
    $("#questions").delegate(":checkbox,:radio,label", 'change mouseup', function(event) {
      if(lastAnswerSelected == $(this).parents(".answer")[0]) {
        $(this).parents(".answer").find(":checkbox,:radio").blur();
        quizSubmission.updateSubmission();
      }
    }).delegate(":text,textarea", 'change blur', function(event, update) {
      if(update !== false) {
        quizSubmission.updateSubmission();
      }
    });
    $(".numerical_question_input").live('keypress', function(event) {
      var string = String.fromCharCode(event.charCode || event.keyCode);
      if(event.charCode == 0 || string == "-" || string == "." || string == "0" || parseInt(string, 10)) {
        $(this).triggerHandler('focus');
      } else {
        $(this).errorBox(I18n.t('errors.only_numerical_values', "only numerical values are accepted"));
        event.preventDefault();
        event.stopPropagation();
      }
    }).live('change blur', function() {
      var val = parseFloat($(this).val());
      if(isNaN(val)) { val = ""; }
      $(this).val(val);
    });
    $(".flag_question").live('click', function() {
      $(this).parents(".question").toggleClass('marked');
      $("#list_" + $(this).parents(".question").attr('id')).toggleClass('marked');
    });
    setInterval(function() {
      $("textarea.question_input").each(function() {
        $(this).triggerHandler('change', false);
      });
    }, 2500);
    $(".question_input").live('change', function() {
      var tagName = $(this)[0].tagName.toUpperCase();
      var val = "";
      if(tagName == "TEXTAREA") {
        val = $(this).editorBox('get_code');
      } else if(tagName == "TEXTAREA" || tagName == "SELECT" || $(this).attr('type') == "text") {
        val = $(this).val();
      } else {
        $(this).parents(".question").find(".question_input").each(function() {
          if($(this).attr('checked') || $(this).attr('selected')) {
            val = true;
          }
        });
      }
      if(val) {
        $("#list_" + $(this).parents(".question").attr('id')).addClass('answered');
      } else {
        $("#list_" + $(this).parents(".question").attr('id')).removeClass('answered');
      }
    }).change();
    $(".hide_time_link").click(function(event) {
      event.preventDefault();
      if($(".time_running").css('visibility') != 'hidden') {
        $(".time_running").css('visibility', 'hidden');
        $(this).text(I18n.t('show_time_link', "Show"));
      } else {
        $(".time_running").css('visibility', 'visible');
        $(this).text(I18n.t('hide_time_link', "Hide"));
      }
    });
    setTimeout(function() {
      $("#question_list .list_question").each(function() {
        var $this = $(this);
        if($this.find(".jump_to_question_link").text() == "Spacer") {
          $this.remove();
        }
      });
    }, 1000);
    $("#submit_quiz_form").submit(function(event) {
      $(".question_holder textarea.question_input").each(function() { $(this).change(); });
      unanswered = $("#question_list .list_question:not(.answered)").length;
      if(unanswered && !quizSubmission.submitting) {
        var result = confirm(I18n.t('confirms.unanswered_questions', {'one': "You have 1 unanswered question (see the right sidebar for details).  Submit anyway?", 'other': "You have %{count} unanswered questions (see the right sidebar for details).  Submit anyway?"}, {'count': unanswered}));
        if(!result) {
          event.preventDefault();
          event.stopPropagation();
          return false;
        }
      }
      quizSubmission.submitting = true;
    });
    $(".submit_quiz_button").click(function(event) {
      event.preventDefault();
      $("#times_up_dialog").dialog('close');
    });
    setTimeout(function() {
      $(".question_holder textarea.question_input").each(function() {
        $(this).attr('id', 'question_input_' + quizSubmission.contentBoxCounter++);
        $(this).editorBox();
      });
    }, 2000);
    setInterval(quizSubmission.updateTime, 400);
    var current_user_id = $("#identity .user_id").text() || "none";
    setInterval(function() {
      $.ajaxJSON(location.protocol + '//' + location.host + "/simple_response.json?user_id=" + current_user_id + "&rnd=" + Math.round(Math.random() * 9999999), 'GET', {}, function() {
      }, function() {
        ajaxErrorFlash(I18n.t('errors.connection_lost', "Connection to %{host} was lost.  Please make sure you're connected to the Internet before continuing.", {'host': location.host}), request);
      }, {skipDefaultError: true});
    }, 30000);
    setTimeout(function() { quizSubmission.updateSubmission(true) }, 15000);
  });
  quizSubmission = (function() {
    var timeMod = 0,
        started_at =  $(".started_at"),
        end_at = $(".end_at"),
        startedAtText = started_at.text(),
        endAtText = end_at.text(),
        endAtParsed = endAtText && new Date(endAtText),
        $countdown_seconds = $(".countdown_seconds"),
        $time_running_time_remaining = $(".time_running,.time_remaining");

    return {
      referenceDate: null,
      countDown: null,
      isDeadline: true,
      fiveMinuteDeadline: false,
      oneMinuteDeadline: false,
      submitting: false,
      dialogged: false,
      contentBoxCounter: 0,
      lastSubmissionUpdate: new Date(),
      currentlyBackingUp: false,
      started_at: started_at,
      end_at: end_at,
      time_limit: parseInt($(".time_limit").text(), 10) || null,
      updateSubmission: function(repeat) {
        if(quizSubmission.submitting && !repeat) { return; }
        var now = new Date();
        if((now - quizSubmission.lastSubmissionUpdate) < 1000) { return }
        if(quizSubmission.currentlyBackingUp) { return; }
        quizSubmission.currentlyBackingUp = true;
        quizSubmission.lastSubmissionUpdate = new Date();
        var data = $("#submit_quiz_form").getFormData();
        $(".question_holder .question.marked").each(function() {
          data[$(this).attr('id') + "_marked"] = "1";
        });
        $.ajaxJSON($(".backup_quiz_submission_url").attr('href'), 'PUT', data, function(data) {
          quizSubmission.currentlyBackingUp = false;
          if(repeat) {
            setTimeout(function() {quizSubmission.updateSubmission(true) }, 30000);
          }
          if(data && data.end_at) {
            quizSubmission.end_at.text(data.end_at);
            quizSubmission.referenceDate = null;
            if(data.end_at > quizSubmission.end_at.text()) {
              $.flashMessage(I18n.t('notices.extra_time', 'You have been given extra time on this attempt'));
            }
          }
        }, function() {
          var current_user_id = $("#identity .user_id").text() || "none";
          quizSubmission.currentlyBackingUp = false;
          $.ajaxJSON(location.protocol + '//' + location.host + "/simple_response.json?user_id=" + current_user_id + "&rnd=" + Math.round(Math.random() * 9999999), 'GET', {}, function() {
          }, function() {
            ajaxErrorFlash(I18n.t('errors.connection_lost', "Connection to %{host} was lost.  Please make sure you're connected to the Internet before continuing.", {'host': location.host}), request);
          }, {skipDefaultError: true});

          if(repeat) {
            setTimeout(function() {quizSubmission.updateSubmission(true) }, 30000);
          }
        }, {timeout: 5000, skipDefaultError: true});
      },
      updateTime: function() {
        var now = new Date();
        var end_at = quizSubmission.time_limit ? endAtText : null;
        timeMod = (timeMod + 1) % 120;
        if(timeMod == 0 && !end_at && !quizSubmission.twelveHourDeadline) {
          quizSubmission.referenceDate = null;
          var end = endAtParsed;
          if(!quizSubmission.time_limit && (end - now) < 43200000) {
            end_at = endAtText;
          }
        }
        if(!quizSubmission.referenceDate) {
          $.extend(quizSubmission, timing.setReferenceDate(startedAtText, end_at, now));
        }
        if(quizSubmission.countDown) {
          var diff = quizSubmission.countDown.getTime() - now.getTime() - quizSubmission.clientServerDiff;
          if(diff <= 0) {
            diff = 0;
          }
          var d = new Date(diff);
          $countdown_seconds.text(d.getUTCSeconds());
          if(diff <= 0 && !quizSubmission.submitting) {
            quizSubmission.submitting = true;
            $("#submit_quiz_form").submit();
          }
        }
        var diff = quizSubmission.referenceDate.getTime() - now.getTime() - quizSubmission.clientServerDiff;
        if(quizSubmission.isDeadline) {
          if(diff < 1000) {
            diff = 0;
          }
          if(diff < 1000 && !quizSubmission.dialogged) {
            quizSubmission.dialogged = true;
            quizSubmission.countDown = new Date(now.getTime() + 10000);
            $("#times_up_dialog").show().dialog({
              title: I18n.t('titles.times_up', "Time's Up!"),
              width: "auto",
              height: "auto",
              modal: true,
              overlay: {
                backgroundColor: "#000",
                opacity: 0.7
              },
              close: function() {
                if(!quizSubmission.submitting) {
                  quizSubmission.submitting = true;
                  $("#submit_quiz_form").submit();
                }
              }
            });
          } else if(diff >    30000 && diff <    60000 && !quizSubmission.oneMinuteDeadline) {
            quizSubmission.oneMinuteDeadline = true;
            $.flashMessage(I18n.t('notices.one_minute_left', "One Minute Left"));
          } else if(diff >   250000 && diff <   300000 && !quizSubmission.fiveMinuteDeadline) {
            quizSubmission.fiveMinuteDeadline = true;
            $.flashMessage(I18n.t('notices.five_minutes_left', "Five Minutes Left"));
          } else if(diff >  1800000 && diff <  1770000 && !quizSubmission.thirtyMinuteDeadline) {
            quizSubmission.thirtyMinuteDeadline = true;
            $.flashMessage(I18n.t('notices.thirty_minutes_left', "Thirty Minutes Left"));
          } else if(diff > 43200000 && diff < 43170000 && !quizSubmission.twelveHourDeadline) {
            quizSubmission.twelveHourDeadline = true;
            $.flashMessage(I18n.t('notices.twelve_hours_left', "Twelve Hours Left"));
          }
        }
        quizSubmission.updateTimeString(diff);
      },
      updateTimeString: function(diff) {
        var date = new Date(Math.abs(diff));
        var yr = date.getUTCFullYear() - 1970;
        var mon = date.getUTCMonth();
        var day = date.getUTCDate() - 1;
        var hr = date.getUTCHours();
        var min = date.getUTCMinutes();
        var sec = date.getUTCSeconds();
        var times = [];
        if(yr) { times.push(I18n.t('years_count', "Year", {'count': yr})); }
        if(mon) { times.push(I18n.t('months_count', "Month", {'count': mon})); }
        if(day) { times.push(I18n.t('days_count', "Day", {'count': day})); }
        if(hr) { times.push(I18n.t('hours_count', "Hour", {'count': hr})); }
        if(true || min) { times.push(I18n.t('minutes_count', "Minute", {'count': min})); }
        if(true || sec) { times.push(I18n.t('seconds_count', "Second", {'count': sec})); }
        $time_running_time_remaining.text(times.join(", "));
      }
    };
  })();
  function updateTime() {
  }
});
<commit_msg>make take_quiz faster on domready<commit_after>/**
 * Copyright (C) 2011 Instructure, Inc.
 *
 * This file is part of Canvas.
 *
 * Canvas is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License as published by the Free
 * Software Foundation, version 3 of the License.
 *
 * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

var lastAnswerSelected = null;
var quizSubmission;
I18n.scoped('quizzes.take_quiz', function(I18n) {

  $(document).mousedown(function(event) {
    lastAnswerSelected = $(event.target).parents(".answer")[0];
  }).keydown(function() {
    lastAnswerSelected = null;
  });

  $(function() {
    $.scrollSidebar();

    if($("#preview_mode_link").length == 0) {
      window.onbeforeunload = function() {
        quizSubmission.updateSubmission();
        if(!quizSubmission.submitting && !quizSubmission.alreadyAcceptedNavigatingAway) {
          return I18n.t('confirms.unfinished_quiz', "You're about to leave the quiz unfinished.  Continue anyway?");
        }
      };
      $(document).delegate('a', 'click', function(event) {
        if($(this).closest('.ui-dialog,.mceToolbar').length > 0) { return; }
        if(!event.isDefaultPrevented()) {
          var url = $(this).attr('href') || "";
          var hashStripped = location.href;
          if(hashStripped.indexOf('#')) {
            hashStripped = hashStripped.substring(0, hashStripped.indexOf('#'));
          }
          if(url.indexOf('#') == 0 || url.indexOf(hashStripped + "#") == 0) {
            return;
          }
          var result = confirm(I18n.t('confirms.navigate_away', "You're about to navigate away from this page.  Continue anyway?"));
          if(!result) {
            event.preventDefault();
          } else {
            quizSubmission.alreadyAcceptedNavigatingAway = true
          }
        }
      });
    }
    var $questions = $("#questions");
    $("#question_list")
      .delegate(".jump_to_question_link", 'click', function(event) {
        event.preventDefault();
        var $obj = $($(this).attr('href'));
        $("html,body").scrollTo($obj.parent());
        $obj.find(":input:first").focus().select();
      })
      .find(".list_question").bind({
        mouseenter: function(event) {
          var $this = $(this),
              data = $this.data(),
              title = I18n.t('titles.not_answered', "Haven't Answered yet");

          if ($this.hasClass('marked')) {
            title = I18n.t('titles.come_back_later', "You marked this question to come back to later");
          } else if ($this.hasClass('answered')) {
            title = I18n.t('titles.answered', "Answered");
          }
          $this.attr('title', title);
          data.relatedQuestion || (data.relatedQuestion = $("#" + $this.attr('id').substring(5)));
          data.relatedQuestion.addClass('related');
        },
        mouseleave: function(event) {
          var relatedQuestion = $(this).data('relatedQuestion')
          relatedQuestion && relatedQuestion.removeClass('related');
        }
      });

    $questions.find('.group_top,.question,.answer_select').bind({
      mouseenter: function(event) {
        $(this).addClass('hover');
      },
      mouseleave: function(event) {
        $(this).removeClass('hover');
      }
    });

    $questions
      .delegate(":checkbox,:radio,label", 'change mouseup', function(event) {
        var $answer = $(this).parents(".answer");
        if (lastAnswerSelected == $answer[0]) {
          $answer.find(":checkbox,:radio").blur();
          quizSubmission.updateSubmission();
        }
      })
      .delegate(":text,textarea", 'change blur', function(event, update) {
        if (update !== false) {
          quizSubmission.updateSubmission();
        }
      })
      .delegate(".numerical_question_input", {
        keypress: function(event) {
          var string = String.fromCharCode(event.charCode || event.keyCode);
          if(event.charCode == 0 || string == "-" || string == "." || string == "0" || parseInt(string, 10)) {
            $(this).triggerHandler('focus');
          } else {
            $(this).errorBox(I18n.t('errors.only_numerical_values', "only numerical values are accepted"));
            event.preventDefault();
            event.stopPropagation();
          }
        },
        'change blur': function() {
          var val = parseFloat($(this).val());
          if(isNaN(val)) { val = ""; }
          $(this).val(val);
        }
      })
      .delegate(".flag_question", 'click', function() {
        var $question = $(this).parents(".question");
        $question.toggleClass('marked');
        $("#list_" + $question.attr('id')).toggleClass('marked');
      })
      .delegate(".question_input", 'change', function() {
        var $this = $(this),
            tagName = $(this)[0].tagName.toUpperCase(),
            val = "";

        if (tagName == "TEXTAREA") {
          val = $this.editorBox('get_code');
        } else if (tagName == "TEXTAREA" || tagName == "SELECT" || $this.attr('type') == "text") {
          val = $this.val();
        } else {
          $this.parents(".question").find(".question_input").each(function() {
            if($(this).attr('checked') || $(this).attr('selected')) {
              val = true;
            }
          });
        }
        $("#list_" + $this.parents(".question").attr('id'))[val ? 'addClass' : 'removeClass']('answered');
      })
      .find(".question_input").change();

    setInterval(function() {
      $("textarea.question_input").each(function() {
        $(this).triggerHandler('change', false);
      });
    }, 2500);

    $(".hide_time_link").click(function(event) {
      event.preventDefault();
      if($(".time_running").css('visibility') != 'hidden') {
        $(".time_running").css('visibility', 'hidden');
        $(this).text(I18n.t('show_time_link', "Show"));
      } else {
        $(".time_running").css('visibility', 'visible');
        $(this).text(I18n.t('hide_time_link', "Hide"));
      }
    });

    setTimeout(function() {
      $("#question_list .list_question").each(function() {
        var $this = $(this);
        if($this.find(".jump_to_question_link").text() == "Spacer") {
          $this.remove();
        }
      });
    }, 1000);

    $("#submit_quiz_form").submit(function(event) {
      $(".question_holder textarea.question_input").each(function() { $(this).change(); });
      unanswered = $("#question_list .list_question:not(.answered)").length;
      if(unanswered && !quizSubmission.submitting) {
        var result = confirm(I18n.t('confirms.unanswered_questions', {'one': "You have 1 unanswered question (see the right sidebar for details).  Submit anyway?", 'other': "You have %{count} unanswered questions (see the right sidebar for details).  Submit anyway?"}, {'count': unanswered}));
        if(!result) {
          event.preventDefault();
          event.stopPropagation();
          return false;
        }
      }
      quizSubmission.submitting = true;
    });

    $(".submit_quiz_button").click(function(event) {
      event.preventDefault();
      $("#times_up_dialog").dialog('close');
    });

    setTimeout(function() {
      $(".question_holder textarea.question_input").each(function() {
        $(this).attr('id', 'question_input_' + quizSubmission.contentBoxCounter++);
        $(this).editorBox();
      });
    }, 2000);

    setInterval(quizSubmission.updateTime, 400);

    var current_user_id = $("#identity .user_id").text() || "none";
    setInterval(function() {
      $.ajaxJSON(location.protocol + '//' + location.host + "/simple_response.json?user_id=" + current_user_id + "&rnd=" + Math.round(Math.random() * 9999999), 'GET', {}, function() {
      }, function() {
        ajaxErrorFlash(I18n.t('errors.connection_lost', "Connection to %{host} was lost.  Please make sure you're connected to the Internet before continuing.", {'host': location.host}), request);
      }, {skipDefaultError: true});
    }, 30000);

    setTimeout(function() { quizSubmission.updateSubmission(true) }, 15000);
  });

  quizSubmission = (function() {
    var timeMod = 0,
        started_at =  $(".started_at"),
        end_at = $(".end_at"),
        startedAtText = started_at.text(),
        endAtText = end_at.text(),
        endAtParsed = endAtText && new Date(endAtText),
        $countdown_seconds = $(".countdown_seconds"),
        $time_running_time_remaining = $(".time_running,.time_remaining");

    return {
      referenceDate: null,
      countDown: null,
      isDeadline: true,
      fiveMinuteDeadline: false,
      oneMinuteDeadline: false,
      submitting: false,
      dialogged: false,
      contentBoxCounter: 0,
      lastSubmissionUpdate: new Date(),
      currentlyBackingUp: false,
      started_at: started_at,
      end_at: end_at,
      time_limit: parseInt($(".time_limit").text(), 10) || null,
      updateSubmission: function(repeat) {
        if(quizSubmission.submitting && !repeat) { return; }
        var now = new Date();
        if((now - quizSubmission.lastSubmissionUpdate) < 1000) { return }
        if(quizSubmission.currentlyBackingUp) { return; }
        quizSubmission.currentlyBackingUp = true;
        quizSubmission.lastSubmissionUpdate = new Date();
        var data = $("#submit_quiz_form").getFormData();
        $(".question_holder .question.marked").each(function() {
          data[$(this).attr('id') + "_marked"] = "1";
        });
        $.ajaxJSON($(".backup_quiz_submission_url").attr('href'), 'PUT', data, function(data) {
          quizSubmission.currentlyBackingUp = false;
          if(repeat) {
            setTimeout(function() {quizSubmission.updateSubmission(true) }, 30000);
          }
          if(data && data.end_at) {
            quizSubmission.end_at.text(data.end_at);
            quizSubmission.referenceDate = null;
            if(data.end_at > quizSubmission.end_at.text()) {
              $.flashMessage(I18n.t('notices.extra_time', 'You have been given extra time on this attempt'));
            }
          }
        }, function() {
          var current_user_id = $("#identity .user_id").text() || "none";
          quizSubmission.currentlyBackingUp = false;
          $.ajaxJSON(location.protocol + '//' + location.host + "/simple_response.json?user_id=" + current_user_id + "&rnd=" + Math.round(Math.random() * 9999999), 'GET', {}, function() {
          }, function() {
            ajaxErrorFlash(I18n.t('errors.connection_lost', "Connection to %{host} was lost.  Please make sure you're connected to the Internet before continuing.", {'host': location.host}), request);
          }, {skipDefaultError: true});

          if(repeat) {
            setTimeout(function() {quizSubmission.updateSubmission(true) }, 30000);
          }
        }, {timeout: 5000, skipDefaultError: true});
      },
      updateTime: function() {
        var now = new Date();
        var end_at = quizSubmission.time_limit ? endAtText : null;
        timeMod = (timeMod + 1) % 120;
        if(timeMod == 0 && !end_at && !quizSubmission.twelveHourDeadline) {
          quizSubmission.referenceDate = null;
          var end = endAtParsed;
          if(!quizSubmission.time_limit && (end - now) < 43200000) {
            end_at = endAtText;
          }
        }
        if(!quizSubmission.referenceDate) {
          $.extend(quizSubmission, timing.setReferenceDate(startedAtText, end_at, now));
        }
        if(quizSubmission.countDown) {
          var diff = quizSubmission.countDown.getTime() - now.getTime() - quizSubmission.clientServerDiff;
          if(diff <= 0) {
            diff = 0;
          }
          var d = new Date(diff);
          $countdown_seconds.text(d.getUTCSeconds());
          if(diff <= 0 && !quizSubmission.submitting) {
            quizSubmission.submitting = true;
            $("#submit_quiz_form").submit();
          }
        }
        var diff = quizSubmission.referenceDate.getTime() - now.getTime() - quizSubmission.clientServerDiff;
        if(quizSubmission.isDeadline) {
          if(diff < 1000) {
            diff = 0;
          }
          if(diff < 1000 && !quizSubmission.dialogged) {
            quizSubmission.dialogged = true;
            quizSubmission.countDown = new Date(now.getTime() + 10000);
            $("#times_up_dialog").show().dialog({
              title: I18n.t('titles.times_up', "Time's Up!"),
              width: "auto",
              height: "auto",
              modal: true,
              overlay: {
                backgroundColor: "#000",
                opacity: 0.7
              },
              close: function() {
                if(!quizSubmission.submitting) {
                  quizSubmission.submitting = true;
                  $("#submit_quiz_form").submit();
                }
              }
            });
          } else if(diff >    30000 && diff <    60000 && !quizSubmission.oneMinuteDeadline) {
            quizSubmission.oneMinuteDeadline = true;
            $.flashMessage(I18n.t('notices.one_minute_left', "One Minute Left"));
          } else if(diff >   250000 && diff <   300000 && !quizSubmission.fiveMinuteDeadline) {
            quizSubmission.fiveMinuteDeadline = true;
            $.flashMessage(I18n.t('notices.five_minutes_left', "Five Minutes Left"));
          } else if(diff >  1800000 && diff <  1770000 && !quizSubmission.thirtyMinuteDeadline) {
            quizSubmission.thirtyMinuteDeadline = true;
            $.flashMessage(I18n.t('notices.thirty_minutes_left', "Thirty Minutes Left"));
          } else if(diff > 43200000 && diff < 43170000 && !quizSubmission.twelveHourDeadline) {
            quizSubmission.twelveHourDeadline = true;
            $.flashMessage(I18n.t('notices.twelve_hours_left', "Twelve Hours Left"));
          }
        }
        quizSubmission.updateTimeString(diff);
      },
      updateTimeString: function(diff) {
        var date = new Date(Math.abs(diff));
        var yr = date.getUTCFullYear() - 1970;
        var mon = date.getUTCMonth();
        var day = date.getUTCDate() - 1;
        var hr = date.getUTCHours();
        var min = date.getUTCMinutes();
        var sec = date.getUTCSeconds();
        var times = [];
        if(yr) { times.push(I18n.t('years_count', "Year", {'count': yr})); }
        if(mon) { times.push(I18n.t('months_count', "Month", {'count': mon})); }
        if(day) { times.push(I18n.t('days_count', "Day", {'count': day})); }
        if(hr) { times.push(I18n.t('hours_count', "Hour", {'count': hr})); }
        if(true || min) { times.push(I18n.t('minutes_count', "Minute", {'count': min})); }
        if(true || sec) { times.push(I18n.t('seconds_count', "Second", {'count': sec})); }
        $time_running_time_remaining.text(times.join(", "));
      }
    };
  })();

});
<|endoftext|>


<commit_before>import d3 from 'd3';
import _ from 'underscore';
import Grapher from './grapher';
import * as Helpers from './visualisation_helpers';

class Graph {

  static name() {
    return 'Alignments Overview';
  }

  static className() {
    return 'alignment-overview collapse';
  }

  static collapseId(props) {
    return 'alignment_'+props.query.number;
  }

  static dataName(props) {
      return 'Alignment-Overview-'+props.query.id;
  }

  constructor($svgContainer, props) {
    $queryDiv = $svgContainer.parents('.resultn')
    hits = this.extractData(props.query.hits, props.query.number)
    this.graphIt($queryDiv, $svgContainer, 0, 20, null, hits);
  }

  extractData(query_hits, number) {
    var hits = [];
    query_hits.map(function (hit) {
        var _hsps = [];
        var hsps = hit.hsps;
        _.each(hsps, function (hsp) {
            var _hsp = {};
            _hsp.hspEvalue = hsp.evalue;
            _hsp.hspStart = hsp.qstart;
            _hsp.hspEnd = hsp.qend;
            _hsp.hspFrame = hsp.sframe;
            _hsp.hspId = "Query_"+number+"_hit_"+hit.number+"_hsp_"+hsp.number;
            _hsps.push(_hsp);
        });
        _hsps.hitId = hit.id;
        _hsps.hitDef = "Query_"+number+"_hit_"+hit.number;
        _hsps.hitEvalue = hit.evalue;
        hits.push(_hsps);
    });
    return hits;
  }

  setupTooltip() {
      this.svg_container.find('[data-toggle="tooltip"]').tooltip({
          'placement': 'top', 'container': 'body', 'html': 'true',
          'delay': 0, 'white-space': 'nowrap'
      });
  }

  setupClick($graphDiv) {
    $('a', $graphDiv).click(function (evt) {
        evt.preventDefault();
        evt.stopPropagation();
        window.location.hash = $(this).attr('href');
    });
  }

  setupResponsiveness($queryDiv, $graphDiv, index, opts, hits) {
    var currentWidth = $(window).width();
    var debounced_draw = _.debounce(_.bind(function () {
        if (currentWidth !== $(window).width()) {
            var shownHits = $queryDiv.find('.ghit > g').length;
            this.graphIt($queryDiv, $graphDiv, shownHits, index, opts, hits);
            currentWidth = $(window).width();
        }
    },this), 125);
    $(window).resize(debounced_draw);
  }

  graphControls($queryDiv, $graphDiv, isInit, opts, hits) {
    var MIN_HITS_TO_SHOW = 20;

    var totalHits, shownHits, lessButton, moreButton;

    var countHits = function () {
        totalHits = hits.length;
        shownHits = $queryDiv.find('.ghit > g').length;
    };

    var setupButtons = function($queryDiv, $graphDiv) {
        $graphDiv
        .append(
            $('<button/>')
            .addClass('btn btn-link more')
            .attr('type', 'button')
            .attr('data-parent-query', $queryDiv.attr('id'))
            .html('View More ')
            .append(
                $('')
                .html('  ')
                .addClass('fa fa-angle-double-down')
            ),
            $('<button/>')
            .addClass('btn btn-link less')
            .attr('type', 'button')
            .attr('data-parent-query', $queryDiv.attr('id'))
            .html('View Less ')
            .append(
                $('')
                .html('  ')
                .addClass('fa fa-angle-double-up')
            )
        );

        lessButton = $('.less', $graphDiv);
        moreButton = $('.more', $graphDiv);
    };

    var initButtons = function () {
        countHits();
        if (totalHits === MIN_HITS_TO_SHOW ||
            shownHits < MIN_HITS_TO_SHOW) {
            lessButton.hide();
            moreButton.hide();
        }
        else if (shownHits === totalHits) {
            moreButton.hide();
            lessButton.show();
        }
        else if (shownHits === MIN_HITS_TO_SHOW) {
            lessButton.hide();
            moreButton.show();
        }
        else {
            lessButton.show();
            moreButton.show();
        }
    };

    // Setup view buttons' state properly if called for first time.
    if (isInit === true) {
        setupButtons($queryDiv, $graphDiv);
        initButtons();
    }

    moreButton.on('click', _.bind(function (e) {
        countHits();
        this.graphIt($queryDiv, $graphDiv, shownHits, MIN_HITS_TO_SHOW, opts, hits);
        initButtons();
        this.setupTooltip();
        e.stopPropagation();
    },this));

    lessButton.on('click', _.bind(function (e) {
        countHits();
        var diff = shownHits - MIN_HITS_TO_SHOW;

        // Decrease number of shown hits by defined constant.
        if (diff >= MIN_HITS_TO_SHOW) {
            this.graphIt($queryDiv, $graphDiv, shownHits, -MIN_HITS_TO_SHOW, opts, hits);
            initButtons();
        }
        else if (diff !== 0) {
            // Ensure a certain number of hits always stay in graph.
            this.graphIt($queryDiv, $graphDiv, shownHits, MIN_HITS_TO_SHOW - shownHits, opts, hits);
            initButtons();
        }
        this.setupTooltip();
        e.stopPropagation();
    },this));
  }

  drawLegend(svg, options, width, height, hits) {
    var svg_legend = svg.append('g')
        .attr('transform',
            'translate(0,' + (height - 1.88 * options.margin) + ')');

    svg_legend.append('rect')
        .attr('x', 7 * (width - 2 * options.margin) / 10)
        .attr('width', 2 * (width - 4 * options.margin) / 10)
        .attr('height', options.legend)
        .attr('fill', 'url(#legend-grad)');

    svg_legend.append('text')
        .attr('class',' legend-text')
        .attr('transform', 'translate(0, ' +options.legend +')')
        .attr('x', 6 * (width - 2 * options.margin) / 10 - options.margin / 2)
        .text("Weaker hits");
        // .text(function() {
        //   return Helpers.prettify_evalue(hits[hits.length-1].hitEvalue);
        // })

    svg_legend.append('text')
        .attr('class',' legend-text')
        .attr('transform', 'translate(0, ' + options.legend + ')')
        .attr('x', 9 * (width - 2 * options.margin) / 10 + options.margin / 2)
        .text("Stronger hits");
        // .text(function () {
        //   return Helpers.prettify_evalue(hits[0].hitEvalue);
        // })

    svg.append('linearGradient')
        .attr('id', 'legend-grad')
    .selectAll('stop')
    .data([
        {offset: "0%", color: "#ccc"},
        {offset: '50%', color: '#888'},
        {offset: "100%", color: "#000"}
    ])
    .enter()
    .append('stop')
        .attr('offset', function (d) {
            return d.offset;
        })
        .attr('stop-color', function (d) {
            return d.color;
        });
  }

  graphIt($queryDiv, $graphDiv, index, howMany, opts, inhits) {
    /* barHeight: Height of each hit track.
     * barPadding: Padding around each hit track.
     * legend: Height reserved for the overview legend.
     * margin: Margin around the svg element.
     */
    var defaults = {
        barHeight: 2,
        barPadding: 1,
        legend: 5,
        margin: 20
    },
        options = $.extend(defaults, opts);
        var hits = inhits.slice(0 , index + howMany);

    // Don't draw anything when no hits are obtained.
    if (hits.length < 1) return false;

    if (index !== 0) {
        // Currently, we have no good way to extend pre-existing graph
        // and hence, are removing the old one and redrawing.
        $graphDiv.find('svg').remove();
    }

    var queryLen = $queryDiv.data().queryLen;
    var q_i = $queryDiv.attr('id');

    var width = $graphDiv.width();
    var height = hits.length * (options.barHeight + options.barPadding) +
        2 * options.legend + 5 * options.margin;
    // var height = $graphDiv.height();

    var SEQ_TYPES = {
        blastn: 'nucleic_acid',
        blastp: 'amino_acid',
        blastx: 'nucleic_acid',
        tblastx: 'nucleic_acid',
        tblastn: 'amino_acid'
    };

    var svg = d3.select($graphDiv[0])
        .selectAll('svg')
        .data([hits])
        .enter()
        .insert('svg', ':first-child')
            .attr('width', width)
            .attr('height', height)
        .append('g')
            .attr('transform', 'translate(' + options.margin / 2 + ', ' + (1.5 * options.margin) + ')');

    var x = d3.scale
        .linear()
        .range([0, width - options.margin]);

    x.domain([1, queryLen]);

    var algorithm = $queryDiv.data().algorithm;
    var formatter = Helpers.tick_formatter(x, SEQ_TYPES[algorithm]);

    var _tValues = x.ticks(11);
    _tValues.pop();

    var xAxis = d3.svg
        .axis()
        .scale(x)
        .orient('top')
        .tickValues(_tValues.concat([1, queryLen]))
        .tickFormat(formatter);

    // Attach the axis to DOM (<svg> element)
    var container = svg.append('g')
        .attr('transform', 'translate(0, ' + options.margin + ')')
        .append('g')
            .attr('class', 'x axis')
            .call(xAxis);

    // Vertical alignment of ticks
    container.selectAll('text')
            .attr('x','25px')
            .attr('y','2px')
            .attr('transform','rotate(-90)');

    var y = d3.scale
        .ordinal()
        .rangeBands([0, height - 3 * options.margin - 2 * options.legend], 0.3);

    y.domain(hits.map(function (d) {
        return d.hitId;
    }));

    var gradScale = d3.scale
        .log()
        .domain([
            d3.min([1e-5, d3.min(hits.map(function (d) {
                if (parseFloat(d.hitEvalue) === 0.0) return undefined;
                return d.hitEvalue;
                }))
            ]),
            d3.max(hits.map(function (d) {
                return d.hitEvalue;
            }))
        ])
        .range([40,150]);

    svg.append('g')
        .attr('class', 'ghit')
        .attr('transform', 'translate(0, ' + 1.65 * (options.margin - options.legend) + ')')
        .selectAll('.hits')
        .data(hits)
        .enter()
        .append('g')
            .each(function (d,i) {
                // TODO: Avoid too many variables and improve naming.

                d3.select(this)
                .selectAll('.hsp')
                .data(d).enter()
                .append('a')
                .each(function (v, j) {
                    // Drawing the HSPs connector line using the same
                    // color as that of the hit track (using lookahead).
                    var yHspline = y(d.hitId) + options.barHeight / 2;
                    var hsplineColor = d3.rgb(gradScale(v.hspEvalue),
                                              gradScale(v.hspEvalue),
                                              gradScale(v.hspEvalue));

                    if (j+1 < d.length) {
                        if (d[j].hspEnd <= d[j+1].hspStart) {
                            d3.select(this.parentNode)
                            .append('line')
                                .attr('x1', x(d[j].hspEnd))
                                .attr('y1', yHspline)
                                .attr('x2', x(d[j+1].hspStart))
                                .attr('y2', yHspline)
                                .attr('stroke', hsplineColor);
                        }
                        else if (d[j].hspStart > d[j+1].hspEnd) {
                            d3.select(this.parentNode)
                            .append('line')
                                .attr('x1', x(d[j+1].hspEnd))
                                .attr('y1', yHspline)
                                .attr('x2', x(d[j].hspStart))
                                .attr('y2', yHspline)
                                .attr('stroke', hsplineColor);
                        }
                    }

                    // Draw the rectangular hit tracks itself.
                    d3.select(this)
                        .attr('xlink:href', '#' + q_i + '_hit_' + (i+1))
                        .append('rect')
                            .attr('data-toggle', 'tooltip')
                            .attr('title', d.hitId + '
E value: '+Helpers.prettify_evalue(v.hspEvalue))
                            .attr('class','bar')
                            .attr('x', function (d) {
                                return x(d.hspStart);
                            })
                            .attr('y', y(d.hitId))
                            .attr('width', function (d) {
                                return x(d.hspEnd - d.hspStart + 1);
                            })
                            .attr('height', options.barHeight)
                            .attr('fill', d3.rgb(hsplineColor));
                });
            });

    // Draw legend only when more than one hit present
    if (hits.length > 1) {
        this.drawLegend(svg, options, width, height, inhits);
    }
    // Bind listener events once all the graphical elements have
    // been drawn for first time.
    if (index === 0) {
        this.graphControls($queryDiv, $graphDiv, true, opts, inhits);
        // Redraw the SVG on a browser resize...
        // this.setupResponsiveness($queryDiv, $graphDiv, index, opts, inhits);
    }
    // Refresh tooltip each time graph is redrawn.
    this.setupTooltip();
    // Ensure clicking on 'rect' takes user to the relevant hit on all
    // browsers.
    this.setupClick($graphDiv);
  }
}

var AlignmentOverview = Grapher(Graph);
export default AlignmentOverview;
<commit_msg>Remove some more dead code<commit_after>import d3 from 'd3';
import _ from 'underscore';
import Grapher from './grapher';
import * as Helpers from './visualisation_helpers';

class Graph {

  static name() {
    return 'Alignments Overview';
  }

  static className() {
    return 'alignment-overview collapse';
  }

  static collapseId(props) {
    return 'alignment_'+props.query.number;
  }

  static dataName(props) {
      return 'Alignment-Overview-'+props.query.id;
  }

  constructor($svgContainer, props) {
    $queryDiv = $svgContainer.parents('.resultn')
    hits = this.extractData(props.query.hits, props.query.number)
    this.graphIt($queryDiv, $svgContainer, 0, 20, null, hits);
  }

  extractData(query_hits, number) {
    var hits = [];
    query_hits.map(function (hit) {
        var _hsps = [];
        var hsps = hit.hsps;
        _.each(hsps, function (hsp) {
            var _hsp = {};
            _hsp.hspEvalue = hsp.evalue;
            _hsp.hspStart = hsp.qstart;
            _hsp.hspEnd = hsp.qend;
            _hsp.hspFrame = hsp.sframe;
            _hsp.hspId = "Query_"+number+"_hit_"+hit.number+"_hsp_"+hsp.number;
            _hsps.push(_hsp);
        });
        _hsps.hitId = hit.id;
        _hsps.hitDef = "Query_"+number+"_hit_"+hit.number;
        _hsps.hitEvalue = hit.evalue;
        hits.push(_hsps);
    });
    return hits;
  }

  setupTooltip() {
      this.svg_container.find('[data-toggle="tooltip"]').tooltip({
          'placement': 'top', 'container': 'body', 'html': 'true',
          'delay': 0, 'white-space': 'nowrap'
      });
  }

  setupClick($graphDiv) {
    $('a', $graphDiv).click(function (evt) {
        evt.preventDefault();
        evt.stopPropagation();
        window.location.hash = $(this).attr('href');
    });
  }

  graphControls($queryDiv, $graphDiv, isInit, opts, hits) {
    var MIN_HITS_TO_SHOW = 20;

    var totalHits, shownHits, lessButton, moreButton;

    var countHits = function () {
        totalHits = hits.length;
        shownHits = $queryDiv.find('.ghit > g').length;
    };

    var setupButtons = function($queryDiv, $graphDiv) {
        $graphDiv
        .append(
            $('<button/>')
            .addClass('btn btn-link more')
            .attr('type', 'button')
            .attr('data-parent-query', $queryDiv.attr('id'))
            .html('View More ')
            .append(
                $('')
                .html('  ')
                .addClass('fa fa-angle-double-down')
            ),
            $('<button/>')
            .addClass('btn btn-link less')
            .attr('type', 'button')
            .attr('data-parent-query', $queryDiv.attr('id'))
            .html('View Less ')
            .append(
                $('')
                .html('  ')
                .addClass('fa fa-angle-double-up')
            )
        );

        lessButton = $('.less', $graphDiv);
        moreButton = $('.more', $graphDiv);
    };

    var initButtons = function () {
        countHits();
        if (totalHits === MIN_HITS_TO_SHOW ||
            shownHits < MIN_HITS_TO_SHOW) {
            lessButton.hide();
            moreButton.hide();
        }
        else if (shownHits === totalHits) {
            moreButton.hide();
            lessButton.show();
        }
        else if (shownHits === MIN_HITS_TO_SHOW) {
            lessButton.hide();
            moreButton.show();
        }
        else {
            lessButton.show();
            moreButton.show();
        }
    };

    // Setup view buttons' state properly if called for first time.
    if (isInit === true) {
        setupButtons($queryDiv, $graphDiv);
        initButtons();
    }

    moreButton.on('click', _.bind(function (e) {
        countHits();
        this.graphIt($queryDiv, $graphDiv, shownHits, MIN_HITS_TO_SHOW, opts, hits);
        initButtons();
        this.setupTooltip();
        e.stopPropagation();
    },this));

    lessButton.on('click', _.bind(function (e) {
        countHits();
        var diff = shownHits - MIN_HITS_TO_SHOW;

        // Decrease number of shown hits by defined constant.
        if (diff >= MIN_HITS_TO_SHOW) {
            this.graphIt($queryDiv, $graphDiv, shownHits, -MIN_HITS_TO_SHOW, opts, hits);
            initButtons();
        }
        else if (diff !== 0) {
            // Ensure a certain number of hits always stay in graph.
            this.graphIt($queryDiv, $graphDiv, shownHits, MIN_HITS_TO_SHOW - shownHits, opts, hits);
            initButtons();
        }
        this.setupTooltip();
        e.stopPropagation();
    },this));
  }

  drawLegend(svg, options, width, height, hits) {
    var svg_legend = svg.append('g')
        .attr('transform',
            'translate(0,' + (height - 1.88 * options.margin) + ')');

    svg_legend.append('rect')
        .attr('x', 7 * (width - 2 * options.margin) / 10)
        .attr('width', 2 * (width - 4 * options.margin) / 10)
        .attr('height', options.legend)
        .attr('fill', 'url(#legend-grad)');

    svg_legend.append('text')
        .attr('class',' legend-text')
        .attr('transform', 'translate(0, ' +options.legend +')')
        .attr('x', 6 * (width - 2 * options.margin) / 10 - options.margin / 2)
        .text("Weaker hits");
        // .text(function() {
        //   return Helpers.prettify_evalue(hits[hits.length-1].hitEvalue);
        // })

    svg_legend.append('text')
        .attr('class',' legend-text')
        .attr('transform', 'translate(0, ' + options.legend + ')')
        .attr('x', 9 * (width - 2 * options.margin) / 10 + options.margin / 2)
        .text("Stronger hits");
        // .text(function () {
        //   return Helpers.prettify_evalue(hits[0].hitEvalue);
        // })

    svg.append('linearGradient')
        .attr('id', 'legend-grad')
    .selectAll('stop')
    .data([
        {offset: "0%", color: "#ccc"},
        {offset: '50%', color: '#888'},
        {offset: "100%", color: "#000"}
    ])
    .enter()
    .append('stop')
        .attr('offset', function (d) {
            return d.offset;
        })
        .attr('stop-color', function (d) {
            return d.color;
        });
  }

  graphIt($queryDiv, $graphDiv, index, howMany, opts, inhits) {
    /* barHeight: Height of each hit track.
     * barPadding: Padding around each hit track.
     * legend: Height reserved for the overview legend.
     * margin: Margin around the svg element.
     */
    var defaults = {
        barHeight: 2,
        barPadding: 1,
        legend: 5,
        margin: 20
    },
        options = $.extend(defaults, opts);
        var hits = inhits.slice(0 , index + howMany);

    // Don't draw anything when no hits are obtained.
    if (hits.length < 1) return false;

    if (index !== 0) {
        // Currently, we have no good way to extend pre-existing graph
        // and hence, are removing the old one and redrawing.
        $graphDiv.find('svg').remove();
    }

    var queryLen = $queryDiv.data().queryLen;
    var q_i = $queryDiv.attr('id');

    var width = $graphDiv.width();
    var height = hits.length * (options.barHeight + options.barPadding) +
        2 * options.legend + 5 * options.margin;
    // var height = $graphDiv.height();

    var SEQ_TYPES = {
        blastn: 'nucleic_acid',
        blastp: 'amino_acid',
        blastx: 'nucleic_acid',
        tblastx: 'nucleic_acid',
        tblastn: 'amino_acid'
    };

    var svg = d3.select($graphDiv[0])
        .selectAll('svg')
        .data([hits])
        .enter()
        .insert('svg', ':first-child')
            .attr('width', width)
            .attr('height', height)
        .append('g')
            .attr('transform', 'translate(' + options.margin / 2 + ', ' + (1.5 * options.margin) + ')');

    var x = d3.scale
        .linear()
        .range([0, width - options.margin]);

    x.domain([1, queryLen]);

    var algorithm = $queryDiv.data().algorithm;
    var formatter = Helpers.tick_formatter(x, SEQ_TYPES[algorithm]);

    var _tValues = x.ticks(11);
    _tValues.pop();

    var xAxis = d3.svg
        .axis()
        .scale(x)
        .orient('top')
        .tickValues(_tValues.concat([1, queryLen]))
        .tickFormat(formatter);

    // Attach the axis to DOM (<svg> element)
    var container = svg.append('g')
        .attr('transform', 'translate(0, ' + options.margin + ')')
        .append('g')
            .attr('class', 'x axis')
            .call(xAxis);

    // Vertical alignment of ticks
    container.selectAll('text')
            .attr('x','25px')
            .attr('y','2px')
            .attr('transform','rotate(-90)');

    var y = d3.scale
        .ordinal()
        .rangeBands([0, height - 3 * options.margin - 2 * options.legend], 0.3);

    y.domain(hits.map(function (d) {
        return d.hitId;
    }));

    var gradScale = d3.scale
        .log()
        .domain([
            d3.min([1e-5, d3.min(hits.map(function (d) {
                if (parseFloat(d.hitEvalue) === 0.0) return undefined;
                return d.hitEvalue;
                }))
            ]),
            d3.max(hits.map(function (d) {
                return d.hitEvalue;
            }))
        ])
        .range([40,150]);

    svg.append('g')
        .attr('class', 'ghit')
        .attr('transform', 'translate(0, ' + 1.65 * (options.margin - options.legend) + ')')
        .selectAll('.hits')
        .data(hits)
        .enter()
        .append('g')
            .each(function (d,i) {
                // TODO: Avoid too many variables and improve naming.

                d3.select(this)
                .selectAll('.hsp')
                .data(d).enter()
                .append('a')
                .each(function (v, j) {
                    // Drawing the HSPs connector line using the same
                    // color as that of the hit track (using lookahead).
                    var yHspline = y(d.hitId) + options.barHeight / 2;
                    var hsplineColor = d3.rgb(gradScale(v.hspEvalue),
                                              gradScale(v.hspEvalue),
                                              gradScale(v.hspEvalue));

                    if (j+1 < d.length) {
                        if (d[j].hspEnd <= d[j+1].hspStart) {
                            d3.select(this.parentNode)
                            .append('line')
                                .attr('x1', x(d[j].hspEnd))
                                .attr('y1', yHspline)
                                .attr('x2', x(d[j+1].hspStart))
                                .attr('y2', yHspline)
                                .attr('stroke', hsplineColor);
                        }
                        else if (d[j].hspStart > d[j+1].hspEnd) {
                            d3.select(this.parentNode)
                            .append('line')
                                .attr('x1', x(d[j+1].hspEnd))
                                .attr('y1', yHspline)
                                .attr('x2', x(d[j].hspStart))
                                .attr('y2', yHspline)
                                .attr('stroke', hsplineColor);
                        }
                    }

                    // Draw the rectangular hit tracks itself.
                    d3.select(this)
                        .attr('xlink:href', '#' + q_i + '_hit_' + (i+1))
                        .append('rect')
                            .attr('data-toggle', 'tooltip')
                            .attr('title', d.hitId + '
E value: '+Helpers.prettify_evalue(v.hspEvalue))
                            .attr('class','bar')
                            .attr('x', function (d) {
                                return x(d.hspStart);
                            })
                            .attr('y', y(d.hitId))
                            .attr('width', function (d) {
                                return x(d.hspEnd - d.hspStart + 1);
                            })
                            .attr('height', options.barHeight)
                            .attr('fill', d3.rgb(hsplineColor));
                });
            });

    // Draw legend only when more than one hit present
    if (hits.length > 1) {
        this.drawLegend(svg, options, width, height, inhits);
    }
    // Bind listener events once all the graphical elements have
    // been drawn for first time.
    if (index === 0) {
        this.graphControls($queryDiv, $graphDiv, true, opts, inhits);
    }
    // Refresh tooltip each time graph is redrawn.
    this.setupTooltip();
    // Ensure clicking on 'rect' takes user to the relevant hit on all
    // browsers.
    this.setupClick($graphDiv);
  }
}

var AlignmentOverview = Grapher(Graph);
export default AlignmentOverview;
<|endoftext|>


<commit_before>tchatroomApp = angular.module('tchatroomApp', []);

tchatroomApp.controller('tchatroomCtrl', function ($scope, $window) {

    var socket = io(HOST_URL);

    $scope.clearText = function () {
        $scope.mychat = "";
    }

    function init() {
        // 변수 초기화
        $scope.clearText();

        $scope.chatroomid = location.search.substring(1);
        //$scope.chatContent = "";
        console.log($scope.chatroomid);

        // event handler 추가
        socket.on('left', function (nickname) {
            $('#messages').append($('<li>').text(nickname + ': has left'));
        });

        socket.on('history', function (texts) {
            $('#messages').append($('<li>').text('history'));
            for (t of texts) {

                console.log(t);

                $('#messages').append($('<li>').text(t.uid.nickname + ': ' + t.message));
            }
            $('#messages').append($('<li>').text('-----------------------'));
        });

        socket.on('participants', function (participants) {
            $('#messages').append($('<li>').text('list of participants: '));
            for (p of participants) {
                $('#messages').append($('<li>').text(p.nickname));
            }
            $('#messages').append($('<li>').text('-----------------------'));

        });

        socket.on('errorToCli', function (msg) {
            $('#messages').append($('<li>').text('error occured on socket!: ' + msg));
        });

        socket.on('newMsg', function (user, msg) {
            console.log(user);
            console.log(msg);
            $('#messages').append($('<li>').text(msg.message));
        });

        socket.on('joined', function (nickname) {
            $('#messages').append($('<li>').text(nickname + ': has joined'));
            socket.emit('getTexts', 0, 100);
        });

        // join chat room

        socket.emit('joinRoom', $window.localStorage.token, $scope.chatroomid);
    }

    $scope.sendChat = function () {
        console.log($scope.mychat);

        socket.emit('sendText', $scope.mychat);

        $scope.clearText();

        return false;
    }

    $scope.getChat = function () {
        socket.emit('getTexts', 0, 100);
    }

    init();
});
<commit_msg>print list<commit_after>tchatroomApp = angular.module('tchatroomApp', []);

tchatroomApp.controller('tchatroomCtrl', function ($scope, $window) {

    var socket = io(HOST_URL);

    $scope.clearText = function () {
        $scope.mychat = "";
    }

    function init() {
        // 변수 초기화
        $scope.clearText();

        console.log(location.search);

        $scope.chatroomid = location.search.substring(1);
        console.log($scope.chatroomid);

        // event handler 추가
        socket.on('left', function (nickname) {
            $('#messages').append($('<li>').text(nickname + ': has left'));
        });

        socket.on('history', function (texts) {
            $('#messages').append($('<li>').text('history'));
            for (t of texts) {

                console.log(t);

                $('#messages').append($('<li>').text(t.uid.nickname + ': ' + t.message));
            }
            $('#messages').append($('<li>').text('-----------------------'));
        });

        socket.on('participants', function (participants) {
            $('#messages').append($('<li>').text('list of participants: '));
            for (p of participants) {
                $('#messages').append($('<li>').text(p.nickname));
            }
            $('#messages').append($('<li>').text('-----------------------'));

        });

        socket.on('errorToCli', function (msg) {
            $('#messages').append($('<li>').text('error occured on socket!: ' + msg));
        });

        socket.on('newMsg', function (user, msg) {
            console.log(user);
            console.log(msg);
            var text = "stranger: ";

            if (user === localStorage.uid) {
                text = "me: ";
            }

            text = text + msg.message;
            $('#messages').append($('<li>').text(text));
        });

        socket.on('joined', function (nickname) {
            $('#messages').append($('<li>').text(nickname + ': has joined'));
            socket.emit('getTexts', 0, 100);
        });

        // join chat room

        socket.emit('joinRoom', $window.localStorage.token, $scope.chatroomid);
    }

    $scope.sendChat = function () {
        console.log($scope.mychat);

        socket.emit('sendText', $scope.mychat);

        $scope.clearText();

        return false;
    }

    $scope.getChat = function () {
        socket.emit('getTexts', 0, 100);
    }

    init();
});
<|endoftext|>


<commit_before>var st = sessionStorage;
var keepValueFields = document.getElementsByClassName('keepInputValue'); // Every element with the tag "keep value field" will be save/load.
var form = document.getElementsByClassName('contactForm'); // Every element with the tag "keep value field" will be save/load.
var saveTime = 1000;	// Time in miliseconds for saving user text input on session storage
var sessionStorageName = 'contactForm_';

	loadUserText(); // Calling the function the first time we open the page
	setInterval(saveUserText, saveTime); // Saving user inputs text each "saveTime" miliseconds
	form.onsubmit = function() { clearFormData; };

	// Clear data when the user send a form

	function clearFormData() {
		var stkey, stValue, total = keepValueFields.length;

		// Traversing all the session storage elements and
		// clearing the current value for our inputs files.

		for (i = 0; i < total; i++) {
			stkey 	= sessionStorageName + i; 		// Setting the key name. Change this for a different name
			st.setItem(stkey, '');					// Clearing session storage for that name
		}

	}

	// Load values to the inputs field.
	// We load all the values when the user access this page for the firts time.

	function loadUserText() {
		var stkey, total = keepValueFields.length;

	 	// Traversing all the session storage elements and
	 	// setting the session storage value to our inputs files.

		for (i = 0; i < total; i++) {
			stkey 	= sessionStorageName + i; 			// Setting the key name. Change this for a different name
			keepValueFields[i].value = st.getItem(stkey);	// getting the value from session storage and setting the input text with dat value
		}
	}

	// Save user Text function.
	// Keeps every second the valus of the text introduces by the user.

	function saveUserText() {
		var stkey, stValue, total = keepValueFields.length;

	 	// Traversing all the session storage elements and
	 	// keeping the current value for our inputs files.

		for (i = 0; i < total; i++) {
			stkey 	= sessionStorageName + i; 		// Setting the key name. Change this for a different name
			stValue = keepValueFields[i].value;	// The value is getting for the element input value.
			st.setItem(stkey, stValue);			// Setting key and value to Session storage.
		}
	}

<commit_msg>Setting empty text after sending form<commit_after>var st = sessionStorage;
var keepValueFields = document.getElementsByClassName('keepInputValue'); // Every element with the tag "keep value field" will be save/load.
var form = document.getElementsByClassName('contactForm'); // Every element with the tag "keep value field" will be save/load.
var saveTime = 1000;	// Time in miliseconds for saving user text input on session storage
var sessionStorageName = 'contactForm_';

	loadUserText(); // Calling the function the first time we open the page
	setInterval(saveUserText, saveTime); // Saving user inputs text each "saveTime" miliseconds
	form.onsubmit = function() { clearFormData; };

	// Clear data when the user send a form

	function clearFormData() {
		var stkey, stValue, total = keepValueFields.length;

		// Traversing all the session storage elements and
		// clearing the current value for our inputs files.

		for (i = 0; i < total; i++) {
			stkey 	= sessionStorageName + i; 		// Setting the key name. Change this for a different name
			st.setItem(stkey, '');					// Clearing session storage for that name
		}

 		loadUserText();		// Setting empty texts again
	}

	// Load values to the inputs field.
	// We load all the values when the user access this page for the firts time.

	function loadUserText() {
		var stkey, total = keepValueFields.length;

	 	// Traversing all the session storage elements and
	 	// setting the session storage value to our inputs files.

		for (i = 0; i < total; i++) {
			stkey 	= sessionStorageName + i; 			// Setting the key name. Change this for a different name
			keepValueFields[i].value = st.getItem(stkey);	// getting the value from session storage and setting the input text with dat value
		}
	}

	// Save user Text function.
	// Keeps every second the valus of the text introduces by the user.

	function saveUserText() {
		var stkey, stValue, total = keepValueFields.length;

	 	// Traversing all the session storage elements and
	 	// keeping the current value for our inputs files.

		for (i = 0; i < total; i++) {
			stkey 	= sessionStorageName + i; 		// Setting the key name. Change this for a different name
			stValue = keepValueFields[i].value;	// The value is getting for the element input value.
			st.setItem(stkey, stValue);			// Setting key and value to Session storage.
		}
	}

<|endoftext|>


<commit_before>var DiskoApp = angular.module('DiskoApp', ['ui.bootstrap']);

DiskoApp.service('playlistService', function() {

});

DiskoApp.service('playerService', function() {

});

DiskoApp.service('userService', function() {

});

DiskoApp.controller('playerController', function($scope, $sce) {

  $scope.isCollapsed = false;

  $.get('/data/playlists.json', function(data) {
    $scope.$apply(function(){
      $scope.playlist = {};
      $scope.playlist.owner = data.content[0].owner;
      $scope.playlist.name = data.content[0].id;
      $scope.playlist.content = data.content[0].content;
    });
  });

  $scope.addNewTrack = function() {
    //toastr options -> put in another file ?
    toastr.options = {
      "closeButton": false,
      "debug": false,
      "positionClass": "toast-top-right",
      "onclick": null,
      "showDuration": "300",
      "hideDuration": "700",
      "timeOut": "3000",
      "extendedTimeOut": "1000",
      "showEasing": "swing",
      "hideEasing": "linear",
      "showMethod": "fadeIn",
      "hideMethod": "fadeOut"
    }
    toastr.options.onHidden = function() {
      $("span.glyphicon.form-control-feedback").addClass("hide");
      $("div.form-group.has-feedback").removeClass("has-success has-warning");
      $scope.$apply(function() {
        $scope.newTrackUrl = null;
      });
    };
    $("div.form-group.has-feedback").removeClass('has-error has-success has-warning');
    $("span.glyphicon.form-control-feedback").removeClass("glyphicon-ok glyphicon-remove hide");

    if($scope.newTrackUrl == undefined) {
        $("span.glyphicon.form-control-feedback").addClass("glyphicon-remove");
        $("div.form-group.has-feedback").addClass("has-error");
    } else {

      $.get('/data/getter/' + $scope.playlist.name, {url: $scope.newTrackUrl}, function(answer) {
        if(answer.code != 0) {
          $scope.appendTrack(answer);
        }
        else {
          $("span.glyphicon.form-control-feedback").addClass("glyphicon-remove");
          $("div.form-group.has-feedback").addClass("has-error");
        }
      });
    }
  };
  $scope.appendTrack = function (track) {
    var stop = false;
    $scope.playlist.content.forEach(function(element, index) {
      if(track.src == element.src)
        stop = true;
    });
    if(!stop) {
      track.addedDate = new Date();
      track.addeBy = 'user';  //TEMP
      track.order = ($scope.playlist.content).length;
      //Notifications
      toastr.success('Track added to the playlist');
      $("span.glyphicon.form-control-feedback").addClass("glyphicon-ok");
      $("div.form-group.has-feedback").addClass("has-success");
      $scope.$apply(function() {
        $scope.playlist.content.push(track);
      });
    } else {
      $("div.form-group.has-feedback").addClass("has-warning");
      $("span.glyphicon.form-control-feedback").addClass("glyphicon-remove");
      toastr.warning("Track already in playlist");
    }
  };

  $scope.savePlaylist = function() {
    $.ajax({
      type: "PUT",
      url: '/data/' + $scope.playlist.owner + '/' + $scope.playlist.name + '.json',
      data: {content: $scope.playlist.content}
    });
    console.log("Saving playlist: " + $scope.playlist.name);
    toastr.success('YESSS');
  };
  //manages the player
  $scope.playing = {};
  $scope.playing.soundcloud = 'https://w.soundcloud.com/player/?auto_play=false&hide_related=false&visual=true&url=https%3A//api.soundcloud.com/tracks/';
  $scope.playing.youtube = 'http://www.youtube.com/embed/';
  $scope.playing.current = $sce.trustAsResourceUrl($scope.playing.youtube + '5RdjiJP4yg4');
  $scope.playing.changeTrack = function(track) {
    console.log(track);
    $scope.playing.current = $sce.trustAsResourceUrl($scope.playing[track.service.toLowerCase()] + track.src);
  };
});
//http://jqueryui.com/sortable/
//http://stackoverflow.com/questions/5957916/how-to-handle-youtube-video-events-started-finished-etc-in-uiwebview-ios
//from shufflecloud
//DONT FORGET script(src="http://connect.soundcloud.com/sdk.js")
// var tracks = null;
// var id = 0;
// var precedent_action = 'next';
// var playing = null;

// function getXMLHttpRequest() {
//   var xhr = null;
//   if (window.XMLHttpRequest || window.ActiveXObject) {
//     if (window.ActiveXObject) {
//       try {
//         xhr = new ActiveXObject("Msxml2.XMLHTTP");
//       } catch(e) {
//         xhr = new ActiveXObject("Microsoft.XMLHTTP");
//       }
//     } else {
//       xhr = new XMLHttpRequest();
//     }
//   } else {
//     alert("Pas d'Ajax, dommage!");
//     return null;
//   }
//   return xhr;
// }

// //asynchronous call to the update process
// function shuffle(exist_url) {
//   stop_all();

//   var req = getXMLHttpRequest();
//   //var url ='https://soundcloud.com/florian-quattrocchi/sets/chiiiilllll';
//   if(exist_url == null)
//     var url = document.getElementById("url").value;
//   else
//     var url = exist_url;

//   req.onreadystatechange = function() {
//     if (req.readyState == 4 && (req.status == 200 )) {

//       if(req.responseText == "This is not a playlist" || req.responseText == "Add an URL") {

//         document.getElementById("div_url").className = "form-group has-feedback has-error";
//         document.getElementById("span_glyph_url").className = "glyphicon glyphicon-remove form-control-feedback";

//         document.getElementById("button_error").className = "btn btn-danger pull-right";
//         document.getElementById("button_error").innerHTML = req.responseText;
//       } else {
//         if(( navigator.userAgent.match(/(iPad|iPhone|iPod)/g) ? true : false )) {
//           document.getElementById("iphone_play").className = "row";
//         }
//         document.getElementById("div_url").className = "form-group has-feedback";
//         document.getElementById("span_glyph_url").className = "hidden";

//         document.getElementById("button_error").className = "btn btn-success pull-right";
//         document.getElementById("button_error").innerHTML = "Playlist shuffled"

//         tracks = JSON.parse(req.responseText);
//         list_played();
//         next();
//       }
//     }
//   };
//   req.open("GET", "add.php?url=" + url , true);
//   req.send(null);
// }

// function playTrack() {
//   display_control();

//   SC.stream("/tracks/" + tracks[id]['sc_id'], {

//     onfinish: function(){
//       next();
//     }
//   }, function(sound){

//     playing = sound.id;
//     sound.start();
//   });
// }

// function next(){
//   play();
//   soundManager.stopAll();

//   if(precedent_action == 'previous')
//     id++;
//   playTrack();
//   precedent_action = 'next';
//   if(id != tracks.length)
//     id++;
//   else
//     stop_all();
// }
// function previous(){
//   play();
//   soundManager.stopAll();

//   if(id>0)
//     id--;
//   playTrack();
//   precedent_action = 'previous';
// }

// function play(){
//   soundManager.resume(playing);

//   document.getElementById("img_play").className = "hidden";
//   document.getElementById("img_pause").className = "";
// }
// function pause(){
//   soundManager.pause(playing);

//   document.getElementById("img_play").className = "";
//   document.getElementById("img_pause").className = "hidden";
// }
// function stop_all() {
//   soundManager.stopAll();
//   id = 0;
//   hide_control();
// }

// function display_control(){
//   document.getElementById("div_control_panel").className = "row";
//   document.getElementById("img_artwork").src = tracks[id]['picture'];
//   document.getElementById("track_name").innerHTML = tracks[id]['title'] + ' - by ' + tracks[id]['artist'];
// }

// function hide_control(){
//   document.getElementById("div_control_panel").className = "hidden";
// }

// function hide_play_iphone() {
//   id--;
//   next();
//   document.getElementById("iphone_play").className = "hidden";
// }

// function list_played() {

//   var req = getXMLHttpRequest();

//   req.onreadystatechange = function() {
//     if (req.readyState == 4 && (req.status == 200 )) {
//       var result = JSON.parse(req.responseText);

//       if(document.getElementById("list_top"))
//         document.getElementById("list_top").remove();
//       if(document.getElementById("list_low"))
//         document.getElementById("list_low").remove();

//       var listTop = document.createElement("ol");
//       listTop.id = "list_top";
//       var listLow = document.createElement("ol");
//       listLow.id = "list_low";

//       for( var i =  0 ; i < Math.min(result.length, 5) ; i++){
//         var listItem = document.createElement("li");
//         listItem.innerHTML = '' + result[i][1] + '';
//         listTop.appendChild(listItem);
//       }
//       for(var i =  result.length-1 ; i >= Math.max(result.length-5, 0) ; i--){
//         var listItem = document.createElement("li");
//         listItem.innerHTML = '' + result[i][1] + '';
//         listLow.appendChild(listItem);
//       }

//       document.getElementById("col_top").appendChild(listTop);
//       document.getElementById("col_low").appendChild(listLow);

//     }
//   };
//   req.open("GET", "get_lists.php", true);
//   req.send(null);

// }<commit_msg>save after adding track<commit_after>var DiskoApp = angular.module('DiskoApp', ['ui.bootstrap']);

DiskoApp.service('playlistService', function() {

});

DiskoApp.service('playerService', function() {

});

DiskoApp.service('userService', function() {

});

DiskoApp.controller('playerController', function($scope, $sce) {

  $scope.isCollapsed = false;

  $.get('/data/playlists.json', function(data) {
    $scope.$apply(function(){
      $scope.playlist = {};
      $scope.playlist.owner = data.content[0].owner;
      $scope.playlist.name = data.content[0].id;
      $scope.playlist.content = data.content[0].content;
    });
  });

  $scope.addNewTrack = function() {
    //toastr options -> put in another file ?
    toastr.options = {
      "closeButton": false,
      "debug": false,
      "positionClass": "toast-top-right",
      "onclick": null,
      "showDuration": "300",
      "hideDuration": "700",
      "timeOut": "3000",
      "extendedTimeOut": "1000",
      "showEasing": "swing",
      "hideEasing": "linear",
      "showMethod": "fadeIn",
      "hideMethod": "fadeOut"
    }
    toastr.options.onHidden = function() {
      $("span.glyphicon.form-control-feedback").addClass("hide");
      $("div.form-group.has-feedback").removeClass("has-success has-warning");
      $scope.$apply(function() {
        $scope.newTrackUrl = null;
      });
    };
    $("div.form-group.has-feedback").removeClass('has-error has-success has-warning');
    $("span.glyphicon.form-control-feedback").removeClass("glyphicon-ok glyphicon-remove hide");

    if($scope.newTrackUrl == undefined) {
        $("span.glyphicon.form-control-feedback").addClass("glyphicon-remove");
        $("div.form-group.has-feedback").addClass("has-error");
    } else {

      $.get('/data/getter/' + $scope.playlist.name, {url: $scope.newTrackUrl}, function(answer) {
        if(answer.code != 0) {
          $scope.appendTrack(answer);
          $scope.savePlaylist();
        }
        else {
          $("span.glyphicon.form-control-feedback").addClass("glyphicon-remove");
          $("div.form-group.has-feedback").addClass("has-error");
        }
      });
    }
  };
  $scope.appendTrack = function (track) {
    var stop = false;
    $scope.playlist.content.forEach(function(element, index) {
      if(track.src == element.src)
        stop = true;
    });
    if(!stop) {
      track.addedDate = new Date();
      track.addeBy = 'user';  //TEMP
      track.order = ($scope.playlist.content).length;
      //Notifications
      toastr.success('Track added to the playlist');
      $("span.glyphicon.form-control-feedback").addClass("glyphicon-ok");
      $("div.form-group.has-feedback").addClass("has-success");
      $scope.$apply(function() {
        $scope.playlist.content.push(track);
      });
    } else {
      $("div.form-group.has-feedback").addClass("has-warning");
      $("span.glyphicon.form-control-feedback").addClass("glyphicon-remove");
      toastr.warning("Track already in playlist");
    }
  };

  $scope.savePlaylist = function() {
    $.ajax({
      type: "PUT",
      url: '/data/' + $scope.playlist.owner + '/' + $scope.playlist.name + '.json',
      data: {content: $scope.playlist.content}
    });
    console.log("Saving playlist: " + $scope.playlist.name);
    toastr.success('YESSS');
  };
  //manages the player
  $scope.playing = {};
  $scope.playing.soundcloud = 'https://w.soundcloud.com/player/?auto_play=false&hide_related=false&visual=true&url=https%3A//api.soundcloud.com/tracks/';
  $scope.playing.youtube = 'http://www.youtube.com/embed/';
  $scope.playing.current = $sce.trustAsResourceUrl($scope.playing.youtube + '5RdjiJP4yg4');
  $scope.playing.changeTrack = function(track) {
    console.log(track);
    $scope.playing.current = $sce.trustAsResourceUrl($scope.playing[track.service.toLowerCase()] + track.src);
  };
});
//http://jqueryui.com/sortable/
//http://stackoverflow.com/questions/5957916/how-to-handle-youtube-video-events-started-finished-etc-in-uiwebview-ios
//from shufflecloud
//DONT FORGET script(src="http://connect.soundcloud.com/sdk.js")
// var tracks = null;
// var id = 0;
// var precedent_action = 'next';
// var playing = null;

// function getXMLHttpRequest() {
//   var xhr = null;
//   if (window.XMLHttpRequest || window.ActiveXObject) {
//     if (window.ActiveXObject) {
//       try {
//         xhr = new ActiveXObject("Msxml2.XMLHTTP");
//       } catch(e) {
//         xhr = new ActiveXObject("Microsoft.XMLHTTP");
//       }
//     } else {
//       xhr = new XMLHttpRequest();
//     }
//   } else {
//     alert("Pas d'Ajax, dommage!");
//     return null;
//   }
//   return xhr;
// }

// //asynchronous call to the update process
// function shuffle(exist_url) {
//   stop_all();

//   var req = getXMLHttpRequest();
//   //var url ='https://soundcloud.com/florian-quattrocchi/sets/chiiiilllll';
//   if(exist_url == null)
//     var url = document.getElementById("url").value;
//   else
//     var url = exist_url;

//   req.onreadystatechange = function() {
//     if (req.readyState == 4 && (req.status == 200 )) {

//       if(req.responseText == "This is not a playlist" || req.responseText == "Add an URL") {

//         document.getElementById("div_url").className = "form-group has-feedback has-error";
//         document.getElementById("span_glyph_url").className = "glyphicon glyphicon-remove form-control-feedback";

//         document.getElementById("button_error").className = "btn btn-danger pull-right";
//         document.getElementById("button_error").innerHTML = req.responseText;
//       } else {
//         if(( navigator.userAgent.match(/(iPad|iPhone|iPod)/g) ? true : false )) {
//           document.getElementById("iphone_play").className = "row";
//         }
//         document.getElementById("div_url").className = "form-group has-feedback";
//         document.getElementById("span_glyph_url").className = "hidden";

//         document.getElementById("button_error").className = "btn btn-success pull-right";
//         document.getElementById("button_error").innerHTML = "Playlist shuffled"

//         tracks = JSON.parse(req.responseText);
//         list_played();
//         next();
//       }
//     }
//   };
//   req.open("GET", "add.php?url=" + url , true);
//   req.send(null);
// }

// function playTrack() {
//   display_control();

//   SC.stream("/tracks/" + tracks[id]['sc_id'], {

//     onfinish: function(){
//       next();
//     }
//   }, function(sound){

//     playing = sound.id;
//     sound.start();
//   });
// }

// function next(){
//   play();
//   soundManager.stopAll();

//   if(precedent_action == 'previous')
//     id++;
//   playTrack();
//   precedent_action = 'next';
//   if(id != tracks.length)
//     id++;
//   else
//     stop_all();
// }
// function previous(){
//   play();
//   soundManager.stopAll();

//   if(id>0)
//     id--;
//   playTrack();
//   precedent_action = 'previous';
// }

// function play(){
//   soundManager.resume(playing);

//   document.getElementById("img_play").className = "hidden";
//   document.getElementById("img_pause").className = "";
// }
// function pause(){
//   soundManager.pause(playing);

//   document.getElementById("img_play").className = "";
//   document.getElementById("img_pause").className = "hidden";
// }
// function stop_all() {
//   soundManager.stopAll();
//   id = 0;
//   hide_control();
// }

// function display_control(){
//   document.getElementById("div_control_panel").className = "row";
//   document.getElementById("img_artwork").src = tracks[id]['picture'];
//   document.getElementById("track_name").innerHTML = tracks[id]['title'] + ' - by ' + tracks[id]['artist'];
// }

// function hide_control(){
//   document.getElementById("div_control_panel").className = "hidden";
// }

// function hide_play_iphone() {
//   id--;
//   next();
//   document.getElementById("iphone_play").className = "hidden";
// }

// function list_played() {

//   var req = getXMLHttpRequest();

//   req.onreadystatechange = function() {
//     if (req.readyState == 4 && (req.status == 200 )) {
//       var result = JSON.parse(req.responseText);

//       if(document.getElementById("list_top"))
//         document.getElementById("list_top").remove();
//       if(document.getElementById("list_low"))
//         document.getElementById("list_low").remove();

//       var listTop = document.createElement("ol");
//       listTop.id = "list_top";
//       var listLow = document.createElement("ol");
//       listLow.id = "list_low";

//       for( var i =  0 ; i < Math.min(result.length, 5) ; i++){
//         var listItem = document.createElement("li");
//         listItem.innerHTML = '' + result[i][1] + '';
//         listTop.appendChild(listItem);
//       }
//       for(var i =  result.length-1 ; i >= Math.max(result.length-5, 0) ; i--){
//         var listItem = document.createElement("li");
//         listItem.innerHTML = '' + result[i][1] + '';
//         listLow.appendChild(listItem);
//       }

//       document.getElementById("col_top").appendChild(listTop);
//       document.getElementById("col_low").appendChild(listLow);

//     }
//   };
//   req.open("GET", "get_lists.php", true);
//   req.send(null);

// }<|endoftext|>