<commit_before>var hotkeys = (function () {

var exports = {};

function do_narrow_action(action) {
    if (current_msg_list.empty()) {
        return false;
    }
    action(current_msg_list.selected_id(), {trigger: 'hotkey'});
    return true;
}

var actions_dropdown_hotkeys = [
    'down_arrow',
    'up_arrow',
    'vim_up',
    'vim_down',
    'enter'
];

function get_event_name(e) {
    // Note that multiple keys can map to the same event_name, which
    // we'll do in cases where they have the exact same semantics.
    // DON'T FORGET: update keyboard_shortcuts.html

    if ((e.which === 9) && e.shiftKey) {
        return 'shift_tab';
    }

    // We're in the middle of a combo; stop processing because
    // we want the browser to handle it (to avoid breaking
    // things like Ctrl-C or Command-C for copy).
    if (e.metaKey || e.ctrlKey) {
        return 'ignore';
    }

    if (!e.shiftKey) {
        switch (e.keyCode) {
        case 33: // Page Up
            return 'page_up';
        case 34: // Page Down
            return 'page_down';
        case 35:
            return 'end';
        case 36:
            return 'home';
        case 38:
            return 'up_arrow';
        case 40:
            return 'down_arrow';
        }
    }

    switch (e.which) {
    case 8:
        return 'backspace';
    case 9:
        return 'tab';
    case 13:
        return 'enter';
    case 27:
        return 'escape';
    case 32: // Spacebar
        if (e.shiftKey) {
            return 'page_up';
        } else {
            return 'page_down';
        }
    case 47: // '/': initiate search
        return 'search';
    case 63: // '?': Show keyboard shortcuts page
        return 'show_shortcuts';
    case 67: // 'C'
        return 'compose_private_message';
    case 74: // 'J'
        return 'page_down';
    case 75: // 'K'
        return 'page_up';
    case 82: // 'R': respond to author
        return 'respond_to_author';
    case 83: //'S'
        return 'narrow_by_subject';
    case 99: // 'c'
        return 'compose';
    case 105: // 'i'
        return 'message_actions';
    case 106: // 'j'
        return 'vim_down';
    case 107: // 'k'
        return 'vim_up';
    case 114: // 'r': respond to message
        return 'reply_message';
    case 115: // 's'
        return 'narrow_by_recipient';
    case 118: // 'v'
        return 'narrow_private';
    }
    return 'ignore';
}

// Process a keydown or keypress event.
//
// Returns true if we handled it, false if the browser should.
function process_hotkey(e) {
    var row;

    // Disable hotkeys on settings page etc., and when a modal pop-up
    // is visible.
    if (ui.home_tab_obscured()) {
        return false;
    }

    var event_name = get_event_name(e);

    if (event_name === 'ignore') {
        return false;
    }

    if (popovers.actions_popped() && actions_dropdown_hotkeys.indexOf(event_name) !== -1) {
        popovers.actions_menu_handle_keyboard(event_name);
        return true;
    }

    // Handle a few keys specially when the send button is focused.
    if ($('#compose-send-button').is(':focus')) {
        if (event_name === 'backspace') {
            // Ignore backspace; don't navigate back a page.
            return true;
        } else if (event_name === 'shift_tab') {
            // Shift-Tab: go back to content textarea and restore
            // cursor position.
            ui.restore_compose_cursor();
            return true;
        }
    }

    // In Safari and the desktop app, we can't tab to buttons. Intercept the
    // tab from the message edit content box to Save and then Cancel.
    if (event_name === "tab") {
        if ($("#message_edit_content").is(":focus")) {
            $(".message_edit_save").focus();
            return true;
        } else if ($(".message_edit_save").is(":focus")) {
            $(".message_edit_cancel").focus();
            return true;
        }
    }

    // Process hotkeys specially when in an input, textarea, or send button
    if ($('input:focus,textarea:focus,#compose-send-button:focus').length > 0) {
        if (event_name === 'escape') {
            // If one of our typeaheads is open, do nothing so that the Esc
            // will go to close it
            if ($("#subject").data().typeahead.shown ||
                $("#stream").data().typeahead.shown ||
                $("#private_message_recipient").data().typeahead.shown ||
                $("#new_message_content").data().typeahead.shown ||
                $("#search_query").data().typeahead.shown) {
                // For some reason this code is only needed in Firefox;
                // in Chrome our typeahead is able to intercept the Esc
                // event before we even get it.
                // Regardless, we do nothing in this case.
                return true;
            } else if ($(".message_edit_content").filter(":focus").length > 0) {
                row = $(".message_edit_content").filter(":focus").closest(".message_row");
                message_edit.end(row);
            } else if (compose.composing()) {
                // If the user hit the escape key, cancel the current compose
                compose.cancel();
                return true;
            } else {
                // We pressed Esc and something was focused, and the composebox
                // wasn't open. In that case, we should blur the input.
                // (this is almost certainly the searchbar)
                $("input:focus,textarea:focus").blur();
                return true;
            }
        }

        if ((event_name === 'up_arrow' || event_name === 'down_arrow')
            && compose.composing()
            && compose.message_content() === ""
            && $('#new_message_content').is(':focus')) {
                compose.cancel();
                // don't return, as we still want it to be picked up by the code below
        } else {
            // Let the browser handle the key normally.
            return false;
        }
    }

    // If we're on a button or a link and have pressed enter, let the
    // browser handle the keypress
    //
    // This is subtle and here's why: Suppose you have the focus on a
    // stream name in your left sidebar. j and k will still move your
    // cursor up and down, but Enter won't reply -- it'll just trigger
    // the link on the sidebar! So you keep pressing enter over and
    // over again. Until you click somewhere or press r.
    if ($('a:focus,button:focus').length > 0 && event_name === 'enter') {
        return false;
    }

    switch (event_name) {
    case 'message_actions':
        var id = current_msg_list.selected_id();
        popovers.show_actions_popover($(".selected_message .actions_hover")[0], id);
        return true;
    case 'narrow_by_recipient':
        return do_narrow_action(narrow.by_recipient);
    case 'narrow_by_subject':
        return do_narrow_action(narrow.by_subject);
    case 'narrow_private':
        return do_narrow_action(function (target, opts) {
            narrow.by('is', 'private', opts);
        });
    }

    switch (event_name) {
    case 'escape': // Esc: close actions popup, cancel compose, clear a find, or un-narrow
        if (popovers.any_active()) {
            popovers.hide_all();
        } else if (compose.composing()) {
            compose.cancel();
        } else {
            search.clear_search();
        }
        return true;
    case 'compose': // 'c': compose
        compose.start('stream');
        return true;
    case 'compose_private_message':
        compose.start('private');
        return true;
    case  'enter': // Enter: respond to message (unless we need to do something else)
        respond_to_cursor = true;
        respond_to_message({trigger: 'hotkey enter'});
        return true;
    case 'reply_message': // 'r': respond to message
        respond_to_cursor = true;
        respond_to_message({trigger: 'hotkey'});
        return true;
    case 'respond_to_author': // 'R': respond to author
        respond_to_message({reply_type: "personal", trigger: 'hotkey pm'});
        return true;
    case 'search':
        search.initiate_search();
        return true;
    case 'show_shortcuts': // Show keyboard shortcuts page
        $('#keyboard-shortcuts').modal('show');
        return true;
    }

    if (current_msg_list.empty()) {
        return false;
    }

    switch (event_name) {
        case 'down_arrow':
        case 'vim_down':
            navigate.down();
            return true;
        case 'up_arrow':
        case 'vim_up':
            navigate.up();
            return true;
        case 'home':
            navigate.to_home();
            return true;
        case 'end':
            navigate.to_end();
            return true;
        case 'page_up':
            navigate.page_up();
            return true;
        case 'page_down':
            navigate.page_down();
            return true;
    }

    return false;
}

/* We register both a keydown and a keypress function because
   we want to intercept pgup/pgdn, escape, etc, and process them
   as they happen on the keyboard. However, if we processed
   letters/numbers in keydown, we wouldn't know what the case of
   the letters were.

   We want case-sensitive hotkeys (such as in the case of r vs R)
   so we bail in .keydown if the event is a letter or number and
   instead just let keypress go for it. */

$(document).keydown(function (e) {
    // Restrict to non-alphanumeric keys
    if (48 > e.which || 90 < e.which) {
        if (process_hotkey(e)) {
            e.preventDefault();
        }
    }
});

$(document).keypress(function (e) {
    // What exactly triggers .keypress may vary by browser.
    // Welcome to compatability hell.
    //
    // In particular, when you press tab in Firefox, it fires a
    // keypress event with keycode 0 after processing the original
    // event.
    if (e.which !== 0 && e.charCode !== 0) {
        if (process_hotkey(e)) {
            e.preventDefault();
        }
    }
});

return exports;

}());
<commit_msg>Make tab code handle the case that >1 msgs are being edited<commit_after>var hotkeys = (function () {

var exports = {};

function do_narrow_action(action) {
    if (current_msg_list.empty()) {
        return false;
    }
    action(current_msg_list.selected_id(), {trigger: 'hotkey'});
    return true;
}

var actions_dropdown_hotkeys = [
    'down_arrow',
    'up_arrow',
    'vim_up',
    'vim_down',
    'enter'
];

function get_event_name(e) {
    // Note that multiple keys can map to the same event_name, which
    // we'll do in cases where they have the exact same semantics.
    // DON'T FORGET: update keyboard_shortcuts.html

    if ((e.which === 9) && e.shiftKey) {
        return 'shift_tab';
    }

    // We're in the middle of a combo; stop processing because
    // we want the browser to handle it (to avoid breaking
    // things like Ctrl-C or Command-C for copy).
    if (e.metaKey || e.ctrlKey) {
        return 'ignore';
    }

    if (!e.shiftKey) {
        switch (e.keyCode) {
        case 33: // Page Up
            return 'page_up';
        case 34: // Page Down
            return 'page_down';
        case 35:
            return 'end';
        case 36:
            return 'home';
        case 38:
            return 'up_arrow';
        case 40:
            return 'down_arrow';
        }
    }

    switch (e.which) {
    case 8:
        return 'backspace';
    case 9:
        return 'tab';
    case 13:
        return 'enter';
    case 27:
        return 'escape';
    case 32: // Spacebar
        if (e.shiftKey) {
            return 'page_up';
        } else {
            return 'page_down';
        }
    case 47: // '/': initiate search
        return 'search';
    case 63: // '?': Show keyboard shortcuts page
        return 'show_shortcuts';
    case 67: // 'C'
        return 'compose_private_message';
    case 74: // 'J'
        return 'page_down';
    case 75: // 'K'
        return 'page_up';
    case 82: // 'R': respond to author
        return 'respond_to_author';
    case 83: //'S'
        return 'narrow_by_subject';
    case 99: // 'c'
        return 'compose';
    case 105: // 'i'
        return 'message_actions';
    case 106: // 'j'
        return 'vim_down';
    case 107: // 'k'
        return 'vim_up';
    case 114: // 'r': respond to message
        return 'reply_message';
    case 115: // 's'
        return 'narrow_by_recipient';
    case 118: // 'v'
        return 'narrow_private';
    }
    return 'ignore';
}

// Process a keydown or keypress event.
//
// Returns true if we handled it, false if the browser should.
function process_hotkey(e) {
    var row, focused_message_edit_content, focused_message_edit_save, message_edit_form;

    // Disable hotkeys on settings page etc., and when a modal pop-up
    // is visible.
    if (ui.home_tab_obscured()) {
        return false;
    }

    var event_name = get_event_name(e);

    if (event_name === 'ignore') {
        return false;
    }

    if (popovers.actions_popped() && actions_dropdown_hotkeys.indexOf(event_name) !== -1) {
        popovers.actions_menu_handle_keyboard(event_name);
        return true;
    }

    // Handle a few keys specially when the send button is focused.
    if ($('#compose-send-button').is(':focus')) {
        if (event_name === 'backspace') {
            // Ignore backspace; don't navigate back a page.
            return true;
        } else if (event_name === 'shift_tab') {
            // Shift-Tab: go back to content textarea and restore
            // cursor position.
            ui.restore_compose_cursor();
            return true;
        }
    }

    // In Safari and the desktop app, we can't tab to buttons. Intercept the
    // tab from the message edit content box to Save and then Cancel.
    if (event_name === "tab") {
        focused_message_edit_content = $(".message_edit_content").filter(":focus");
        if (focused_message_edit_content.length > 0) {
            message_edit_form = focused_message_edit_content.closest(".message_edit_form");
            message_edit_form.find(".message_edit_save").focus();
            return true;
        }

        focused_message_edit_save = $(".message_edit_save").filter(":focus");
        if (focused_message_edit_save.length > 0) {
            message_edit_form = focused_message_edit_save.closest(".message_edit_form");
            message_edit_form.find(".message_edit_cancel").focus();
            return true;
        }
    }

    // Process hotkeys specially when in an input, textarea, or send button
    if ($('input:focus,textarea:focus,#compose-send-button:focus').length > 0) {
        if (event_name === 'escape') {
            // If one of our typeaheads is open, do nothing so that the Esc
            // will go to close it
            if ($("#subject").data().typeahead.shown ||
                $("#stream").data().typeahead.shown ||
                $("#private_message_recipient").data().typeahead.shown ||
                $("#new_message_content").data().typeahead.shown ||
                $("#search_query").data().typeahead.shown) {
                // For some reason this code is only needed in Firefox;
                // in Chrome our typeahead is able to intercept the Esc
                // event before we even get it.
                // Regardless, we do nothing in this case.
                return true;
            } else if ($(".message_edit_content").filter(":focus").length > 0) {
                row = $(".message_edit_content").filter(":focus").closest(".message_row");
                message_edit.end(row);
            } else if (compose.composing()) {
                // If the user hit the escape key, cancel the current compose
                compose.cancel();
                return true;
            } else {
                // We pressed Esc and something was focused, and the composebox
                // wasn't open. In that case, we should blur the input.
                // (this is almost certainly the searchbar)
                $("input:focus,textarea:focus").blur();
                return true;
            }
        }

        if ((event_name === 'up_arrow' || event_name === 'down_arrow')
            && compose.composing()
            && compose.message_content() === ""
            && $('#new_message_content').is(':focus')) {
                compose.cancel();
                // don't return, as we still want it to be picked up by the code below
        } else {
            // Let the browser handle the key normally.
            return false;
        }
    }

    // If we're on a button or a link and have pressed enter, let the
    // browser handle the keypress
    //
    // This is subtle and here's why: Suppose you have the focus on a
    // stream name in your left sidebar. j and k will still move your
    // cursor up and down, but Enter won't reply -- it'll just trigger
    // the link on the sidebar! So you keep pressing enter over and
    // over again. Until you click somewhere or press r.
    if ($('a:focus,button:focus').length > 0 && event_name === 'enter') {
        return false;
    }

    switch (event_name) {
    case 'message_actions':
        var id = current_msg_list.selected_id();
        popovers.show_actions_popover($(".selected_message .actions_hover")[0], id);
        return true;
    case 'narrow_by_recipient':
        return do_narrow_action(narrow.by_recipient);
    case 'narrow_by_subject':
        return do_narrow_action(narrow.by_subject);
    case 'narrow_private':
        return do_narrow_action(function (target, opts) {
            narrow.by('is', 'private', opts);
        });
    }

    switch (event_name) {
    case 'escape': // Esc: close actions popup, cancel compose, clear a find, or un-narrow
        if (popovers.any_active()) {
            popovers.hide_all();
        } else if (compose.composing()) {
            compose.cancel();
        } else {
            search.clear_search();
        }
        return true;
    case 'compose': // 'c': compose
        compose.start('stream');
        return true;
    case 'compose_private_message':
        compose.start('private');
        return true;
    case  'enter': // Enter: respond to message (unless we need to do something else)
        respond_to_cursor = true;
        respond_to_message({trigger: 'hotkey enter'});
        return true;
    case 'reply_message': // 'r': respond to message
        respond_to_cursor = true;
        respond_to_message({trigger: 'hotkey'});
        return true;
    case 'respond_to_author': // 'R': respond to author
        respond_to_message({reply_type: "personal", trigger: 'hotkey pm'});
        return true;
    case 'search':
        search.initiate_search();
        return true;
    case 'show_shortcuts': // Show keyboard shortcuts page
        $('#keyboard-shortcuts').modal('show');
        return true;
    }

    if (current_msg_list.empty()) {
        return false;
    }

    switch (event_name) {
        case 'down_arrow':
        case 'vim_down':
            navigate.down();
            return true;
        case 'up_arrow':
        case 'vim_up':
            navigate.up();
            return true;
        case 'home':
            navigate.to_home();
            return true;
        case 'end':
            navigate.to_end();
            return true;
        case 'page_up':
            navigate.page_up();
            return true;
        case 'page_down':
            navigate.page_down();
            return true;
    }

    return false;
}

/* We register both a keydown and a keypress function because
   we want to intercept pgup/pgdn, escape, etc, and process them
   as they happen on the keyboard. However, if we processed
   letters/numbers in keydown, we wouldn't know what the case of
   the letters were.

   We want case-sensitive hotkeys (such as in the case of r vs R)
   so we bail in .keydown if the event is a letter or number and
   instead just let keypress go for it. */

$(document).keydown(function (e) {
    // Restrict to non-alphanumeric keys
    if (48 > e.which || 90 < e.which) {
        if (process_hotkey(e)) {
            e.preventDefault();
        }
    }
});

$(document).keypress(function (e) {
    // What exactly triggers .keypress may vary by browser.
    // Welcome to compatability hell.
    //
    // In particular, when you press tab in Firefox, it fires a
    // keypress event with keycode 0 after processing the original
    // event.
    if (e.which !== 0 && e.charCode !== 0) {
        if (process_hotkey(e)) {
            e.preventDefault();
        }
    }
});

return exports;

}());
<|endoftext|>


<commit_before><commit_msg>removing useless empty script<commit_after><|endoftext|>


<commit_before>(function activateSlider() {
  var sliderContainer = document.getElementById('videos');
  if (!sliderContainer) { return; }  // fail fast
  u.on(sliderContainer, 'click', function(evt) {
    stopAutoSlide();
  });

  function showSlide(slideAnchor, targetPager) {
    var showing = sliderContainer.querySelector('.videos-slider .selected'),
        toShow = sliderContainer.querySelector('.videos-slider ' + slideAnchor);
    if (toShow === showing) { return; }
    var showingPager = sliderContainer.querySelector('.videos-pager .selected');

    u.removeClass(showing, 'selected');
    u.removeClass(showingPager, 'selected');
    u.addClass(toShow, 'selected');
    u.addClass(targetPager, 'selected');
  }

  var pagers = sliderContainer.querySelectorAll('.videos-pager li > a');
  u.eachNode(pagers, function(node) {
    u.on(node, 'click', function(evt) {
      u.stop(evt);
      var targetSlideAnchor = evt.target.hash;
      showSlide(targetSlideAnchor, evt.target);
    });
  });

  var slides = sliderContainer.querySelectorAll('.videos-slider .slide');
  u.eachNode(slides, function(node) {
    var vidActivator = node.querySelector('.video a');
    u.on(vidActivator, 'click', function(e) {
      if (!this.dataset.youtubeid) {
        return;  // not an embedded video, let what happens, happen.
      }
      u.stop(e);
      var videoID = this.dataset.youtubeid;
      if (! videoID) { return; }
      var vidMarkup = '';
      vidActivator.innerHTML = vidMarkup;
      u.addClass(node, 'activated');
    });
  });

  var currentSlide = 0;
  var sliderInterval = setInterval(function(){ autoSlide() }, 4000);

  function autoSlide() {
    currentSlide = (currentSlide + 1) % pagers.length;
    showSlide(pagers[currentSlide].hash, pagers[currentSlide]);
  }

  function stopAutoSlide() {
    clearInterval(sliderInterval);
  }
})();
<commit_msg>Don't autoslide if the slider is not in the view<commit_after>(function activateSlider() {
  var sliderContainer = document.getElementById('videos');
  if (!sliderContainer) { return; }  // fail fast
  u.on(sliderContainer, 'click', function(evt) {
    stopAutoSlide();
  });

  function showSlide(slideAnchor, targetPager) {
    var showing = sliderContainer.querySelector('.videos-slider .selected'),
        toShow = sliderContainer.querySelector('.videos-slider ' + slideAnchor);
    if (toShow === showing) { return; }
    var showingPager = sliderContainer.querySelector('.videos-pager .selected');

    u.removeClass(showing, 'selected');
    u.removeClass(showingPager, 'selected');
    u.addClass(toShow, 'selected');
    u.addClass(targetPager, 'selected');
  }

  var pagers = sliderContainer.querySelectorAll('.videos-pager li > a');
  u.eachNode(pagers, function(node) {
    u.on(node, 'click', function(evt) {
      u.stop(evt);
      var targetSlideAnchor = evt.target.hash;
      showSlide(targetSlideAnchor, evt.target);
    });
  });

  var slides = sliderContainer.querySelectorAll('.videos-slider .slide');
  u.eachNode(slides, function(node) {
    var vidActivator = node.querySelector('.video a');
    u.on(vidActivator, 'click', function(e) {
      if (!this.dataset.youtubeid) {
        return;  // not an embedded video, let what happens, happen.
      }
      u.stop(e);
      var videoID = this.dataset.youtubeid;
      if (! videoID) { return; }
      var vidMarkup = '';
      vidActivator.innerHTML = vidMarkup;
      u.addClass(node, 'activated');
    });
  });

  var currentSlide = 0;
  var sliderInterval = setInterval(function(){ autoSlide() }, 4000);

  function autoSlide() {
    var middle = (sliderContainer.getBoundingClientRect().bottom + sliderContainer.getBoundingClientRect().top)/2;
    if (middle > 100) {
        currentSlide = (currentSlide + 1) % pagers.length;
        showSlide(pagers[currentSlide].hash, pagers[currentSlide]);
    }
  }

  function stopAutoSlide() {
    clearInterval(sliderInterval);
  }
})();
<|endoftext|>


<commit_before>if (document.getElementById("editor") && window.hasOwnProperty("ace")) {
  // has a editor
  var map = {
    'c': 'c_cpp',
    'c11': 'c_cpp',
    'cpp98': 'c_cpp',
    'cpp': 'c_cpp',
    'cpp14': 'c_cpp',
    'cc14': 'c_cpp',
    'csharp': 'csharp',
    'python2': 'python',
    'python': 'python',
    'java': 'java',
    'php': 'php',
    'fortran': 'fortran',
    'perl': 'perl',
    'ruby': 'ruby',
    'objc': 'objectivec',
    'haskell': 'haskell',
    'scala': 'scala',
    'lua': 'lua',
    'lisp': 'lisp',
    'js': 'javascript',
    'go': 'golang',
    'ocaml': 'ocaml',
    'fsharp': 'text',
    'pypy2': 'python',
    'swift': 'swift',
    'pascal': 'pascal',
    'rust': 'rust',
    'r': 'r'
  };
  if (window.localStorage) {
    $('.ui.search.dropdown.language').dropdown('set selected', localStorage.getItem('lang') || 'cpp');
  }
  var editor = ace.edit("editor");
  var lang = $("#id_lang");
  var code = $("#id_code");
  var problem = $("*[name='problem']");
  var code_param = "", code_in_storage_key = "";
  code.on("change", function (event) {
    editor.getSession().setValue(code.val());
  });

  function updateStorageKey() {
    var problem_val = problem.val();
    if (problem_val) {
      code_param = "?c=" + $("#default-contest").val() + "&p=" + problem_val;
      code_in_storage_key = "code" + code_param;
      if (window.sessionStorage && window.sessionStorage.getItem(code_in_storage_key)) {
        code.val(window.sessionStorage.getItem(code_in_storage_key));
        code.trigger("change");
      } else {
        $.get("/api/submission/" + code_param, function (data) {
          code.val(data);
          code.trigger("change");
        });
      }
    } else {
      code_in_storage_key = "";
    }
  }
  updateStorageKey();

  editor.setTheme("ace/theme/chrome");
  editor.getSession().setMode("ace/mode/" + map[lang.val()]);
  editor.setOptions({
    fontFamily: ["Consolas", "Courier", "Courier New", "monospace"],
    fontSize: "11pt"
  });
  lang.on("change", function (event) {
    editor.getSession().setMode("ace/mode/" + map[event.target.value]);
    if (window.localStorage) {
      localStorage.setItem("lang", event.target.value);
    }
  });
  problem.on("change", function (event) {
    updateStorageKey();
  });

  editor.getSession().on("change", function () {
    var my_code = editor.getSession().getValue();
    code.val(my_code);
    if (window.sessionStorage && code_in_storage_key)
      window.sessionStorage.setItem(code_in_storage_key, my_code);
  });
}

function scrollToCurrentSubmission () {
  $('html, body').animate({
    scrollTop: $("#current-submission").offset().top - $("#navbar").height() - 15
  }, 500);
}

function updateSubmission (url, scroll, preset_timeout) {
  $.get(url, function (data) {
    var submissionBox = $("#current-submission");
    submissionBox.html(data);
    var status = submissionBox.find(".status-span.with-icon").attr("data-status");
    if (status == "-3" || status == "-2") {
      setTimeout(function() {
        updateSubmission(url, false, (preset_timeout || 500) + 50);
      }, preset_timeout || 500);
    } else {
      updatePastSubmissions();
    }
    if (scroll)
      scrollToCurrentSubmission();
    $.parseStatusDisplay();
  });
}

function updatePastSubmissions () {
  var pastSubmissionBox = $("#past-submissions");
  if (pastSubmissionBox.length > 0) {
    $.get(pastSubmissionBox.data("url"), function (data) {
      pastSubmissionBox.html(data);
      $.parseStatusDisplay();
    });
  }
}

$("#problem-submit").click(function (event) {
  var button = $(event.currentTarget);
  var form = button.closest("form");
  form.removeClass("error");
  form.addClass("loading");
  $.post(form.attr("action"), form.serialize())
    .done(function (data) {
      updateSubmission(data.url, true);
      form.removeClass("loading");
    })
    .fail(function (xhr) {
      form.addClass("error");
      if (xhr.hasOwnProperty("responseText") && xhr.responseText) {
        form.find("#error-message-goes-here").html(xhr.responseText);
      } else {
        form.find("#error-message-goes-here").html("Submit failed. Try again later.");
      }
      form.removeClass("loading");
    });
  return false;
});

updatePastSubmissions();<commit_msg>default lang (#23)<commit_after>if (document.getElementById("editor") && window.hasOwnProperty("ace")) {
  // has a editor
  var map = {
    'c': 'c_cpp',
    'c11': 'c_cpp',
    'cpp98': 'c_cpp',
    'cpp': 'c_cpp',
    'cpp14': 'c_cpp',
    'cc14': 'c_cpp',
    'csharp': 'csharp',
    'python2': 'python',
    'python': 'python',
    'java': 'java',
    'php': 'php',
    'fortran': 'fortran',
    'perl': 'perl',
    'ruby': 'ruby',
    'objc': 'objectivec',
    'haskell': 'haskell',
    'scala': 'scala',
    'lua': 'lua',
    'lisp': 'lisp',
    'js': 'javascript',
    'go': 'golang',
    'ocaml': 'ocaml',
    'fsharp': 'text',
    'pypy2': 'python',
    'swift': 'swift',
    'pascal': 'pascal',
    'rust': 'rust',
    'r': 'r'
  };
  const ele = $('.ui.search.dropdown.language');
  const all_lang = ele.find('.item').map(function() { return $(this).data('value'); }).get();
  if (window.localStorage && all_lang.indexOf(localStorage.getItem('lang')) >= 0) {
    ele.dropdown('set selected', localStorage.getItem('lang'));
  } else {
    ele.dropdown('set selected', all_lang[0]);
  }
  var editor = ace.edit("editor");
  var lang = $("#id_lang");
  var code = $("#id_code");
  var problem = $("*[name='problem']");
  var code_param = "", code_in_storage_key = "";
  code.on("change", function (event) {
    editor.getSession().setValue(code.val());
  });

  function updateStorageKey() {
    var problem_val = problem.val();
    if (problem_val) {
      code_param = "?c=" + $("#default-contest").val() + "&p=" + problem_val;
      code_in_storage_key = "code" + code_param;
      if (window.sessionStorage && window.sessionStorage.getItem(code_in_storage_key)) {
        code.val(window.sessionStorage.getItem(code_in_storage_key));
        code.trigger("change");
      } else {
        $.get("/api/submission/" + code_param, function (data) {
          code.val(data);
          code.trigger("change");
        });
      }
    } else {
      code_in_storage_key = "";
    }
  }
  updateStorageKey();

  editor.setTheme("ace/theme/chrome");
  editor.getSession().setMode("ace/mode/" + map[lang.val()]);
  editor.setOptions({
    fontFamily: ["Consolas", "Courier", "Courier New", "monospace"],
    fontSize: "11pt"
  });
  lang.on("change", function (event) {
    editor.getSession().setMode("ace/mode/" + map[event.target.value]);
    if (window.localStorage) {
      localStorage.setItem("lang", event.target.value);
    }
  });
  problem.on("change", function (event) {
    updateStorageKey();
  });

  editor.getSession().on("change", function () {
    var my_code = editor.getSession().getValue();
    code.val(my_code);
    if (window.sessionStorage && code_in_storage_key)
      window.sessionStorage.setItem(code_in_storage_key, my_code);
  });
}

function scrollToCurrentSubmission () {
  $('html, body').animate({
    scrollTop: $("#current-submission").offset().top - $("#navbar").height() - 15
  }, 500);
}

function updateSubmission (url, scroll, preset_timeout) {
  $.get(url, function (data) {
    var submissionBox = $("#current-submission");
    submissionBox.html(data);
    var status = submissionBox.find(".status-span.with-icon").attr("data-status");
    if (status == "-3" || status == "-2") {
      setTimeout(function() {
        updateSubmission(url, false, (preset_timeout || 500) + 50);
      }, preset_timeout || 500);
    } else {
      updatePastSubmissions();
    }
    if (scroll)
      scrollToCurrentSubmission();
    $.parseStatusDisplay();
  });
}

function updatePastSubmissions () {
  var pastSubmissionBox = $("#past-submissions");
  if (pastSubmissionBox.length > 0) {
    $.get(pastSubmissionBox.data("url"), function (data) {
      pastSubmissionBox.html(data);
      $.parseStatusDisplay();
    });
  }
}

$("#problem-submit").click(function (event) {
  var button = $(event.currentTarget);
  var form = button.closest("form");
  form.removeClass("error");
  form.addClass("loading");
  $.post(form.attr("action"), form.serialize())
    .done(function (data) {
      updateSubmission(data.url, true);
      form.removeClass("loading");
    })
    .fail(function (xhr) {
      form.addClass("error");
      if (xhr.hasOwnProperty("responseText") && xhr.responseText) {
        form.find("#error-message-goes-here").html(xhr.responseText);
      } else {
        form.find("#error-message-goes-here").html("Submit failed. Try again later.");
      }
      form.removeClass("loading");
    });
  return false;
});

updatePastSubmissions();<|endoftext|>


<commit_before>$(document).ready(function(){
	$(".show-search").on("click",function(){
		$("#search-box").fadeIn("slow");
		return false;
	});
})<commit_msg>Make search toggle into function<commit_after>$(document).ready(function(){
	function showSearch() {
		$(".show-search").on("click",function(){
			$("#search-box").fadeIn("slow");
			return false;
		});
	}
	showSearch();
})<|endoftext|>


<commit_before>/* Copyright 2012 The Go Authors.   All rights reserved.
 * Use of this source code is governed by a BSD-style
 * license that can be found in the LICENSE file.
 */
'use strict';

angular.module('tour.values', []).

// List of modules with description and lessons in it.
value('tableOfContents', [{
    'id': 'mechanics',
    'title': 'Utilisation du tour',
    'description': '
Bienvenue au tour du langage de programmation Go. Ce tour couvre les caractéristiques les plus importantes du langage, principalement:
',
    'lessons': ['welcome']
}, {
    'id': 'basics',
    'title': 'Principes de base',
    'description': '
Le point de départ, apprendre tous les rudiments du langage
Déclaration des variables, des fonctions d\'appel, et toutes les choses que vous devez savoir avant de passer aux prochaines leçons.
',
    'lessons': ['basics', 'flowcontrol', 'moretypes']
}, {
    'id': 'methods',
    'title': 'Methods et interfaces',
    'description': '
Savoir comment définir des méthodes sur les types, comment déclarer des interfaces, et comment assembler le tout.
',
    'lessons': ['methods']
}, {
    'id': 'concurrency',
    'title': 'Concurrency',
    'description': '
Go offre des primitives de simultanéité dans le cadre du langage de base.

Ce module les présentent et donne quelques exemples sur la façon de les utilisés pour mettre en œuvre différents modèles de concurrence.
',
    'lessons': ['concurrency']
}]).

// Translation
value('translation', {
    'off': 'Désactivé',
    'on': 'Activé',
    'syntax': 'Syntaxe',
    'lineno': 'Numéros de ligne',
    'reset': 'Réinitialiser',
    'format': 'Formater',
    'kill': 'Tuer',
    'run': 'Exécuter',
    'compile': 'Compiler et Exécuter',
    'more': 'Options',
    'toc': 'Menu',
    'prev': 'Précédent',
    'next': 'Suivant',
    'waiting': 'En attente du serveur distant...',
    'errcomm': 'Erreur de communication avec le serveur distant.',
    'submit-feedback': 'envoyer un commentaire sur cette page',

    // GitHub issue template: update repo and messaging when translating.
    'github-repo': 'github.com/dupoxy/go-tour-fr',
    'issue-title': 'tour-fr: [REMPLACER PAR UNE COURTE DESCRIPTION]',
    'issue-message': '',
    'context': 'Context',
}).

// Config for codemirror plugin
value('ui.config', {
    codemirror: {
        mode: 'text/x-go',
        matchBrackets: true,
        lineNumbers: true,
        autofocus: true,
        indentWithTabs: true,
        indentUnit: 4,
        tabSize: 4,
        lineWrapping: true,
        extraKeys: {
            'Shift-Enter': function() {
                $('#run').click();
            },
            'Ctrl-Enter': function() {
                $('#format').click();
            },
            'PageDown': function() {
                return false;
            },
            'PageUp': function() {
                return false;
            },
        },
        // TODO: is there a better way to do this?
        // AngularJS values can't depend on factories.
        onChange: function() {
            if (window.codeChanged !== null) window.codeChanged();
        }
    }
}).

// mapping from the old paths (#42) to the new organization.
// The values have been generated with the map.sh script in the tools directory.
value('mapping', {
    '#1': '/welcome/1', // Hello, 世界
    '#2': '/welcome/2', // Go local
    '#3': '/basics/1', // Packages
    '#4': '/basics/2', // Imports
    '#5': '/basics/3', // Exported names
    '#6': '/basics/4', // Functions
    '#7': '/basics/5', // Functions continued
    '#8': '/basics/6', // Multiple results
    '#9': undefined, // Named results
    '#10': '/basics/8', // Variables
    '#11': '/basics/9', // Variables with initializers
    '#12': '/basics/10', // Short variable declarations
    '#13': '/basics/11', // Basic types
    '#14': '/basics/13', // Type conversions
    '#15': '/basics/15', // Constants
    '#16': '/basics/16', // Numeric Constants
    '#17': '/flowcontrol/1', // For
    '#18': '/flowcontrol/2', // For continued
    '#19': '/flowcontrol/3', // For is Go's "while"
    '#20': '/flowcontrol/4', // Forever
    '#21': '/flowcontrol/5', // If
    '#22': '/flowcontrol/6', // If with a short statement
    '#23': '/flowcontrol/7', // If and else
    '#24': '/flowcontrol/8', // Exercise: Loops and Functions
    '#25': '/moretypes/2', // Structs
    '#26': '/moretypes/3', // Struct Fields
    '#27': '/moretypes/1', // Pointers
    '#28': '/moretypes/5', // Struct Literals
    '#29': undefined, // The new function
    '#30': '/moretypes/6', // Arrays
    '#31': '/moretypes/7', // Slices
    '#32': '/moretypes/8', // Slicing slices
    '#33': '/moretypes/9', // Making slices
    '#34': '/moretypes/10', // Nil slices
    '#35': '/moretypes/12', // Range
    '#36': '/moretypes/13', // Range continued
    '#37': '/moretypes/14', // Exercise: Slices
    '#38': '/moretypes/15', // Maps
    '#39': '/moretypes/16', // Map literals
    '#40': '/moretypes/17', // Map literals continued
    '#41': '/moretypes/18', // Mutating Maps
    '#42': '/moretypes/19', // Exercise: Maps
    '#43': '/moretypes/20', // Function values
    '#44': '/moretypes/21', // Function closures
    '#45': '/moretypes/22', // Exercise: Fibonacci closure
    '#46': '/flowcontrol/9', // Switch
    '#47': '/flowcontrol/10', // Switch evaluation order
    '#48': '/flowcontrol/11', // Switch with no condition
    '#49': undefined, // Advanced Exercise: Complex cube roots
    '#50': undefined, // Methods and Interfaces
    '#51': '/methods/1', // Methods
    '#52': '/methods/2', // Methods continued
    '#53': '/methods/3', // Methods with pointer receivers
    '#54': '/methods/4', // Interfaces
    '#55': '/methods/5', // Interfaces are satisfied implicitly
    '#56': '/methods/8', // Errors
    '#57': '/methods/9', // Exercise: Errors
    '#58': '/methods/13', // Web servers
    '#59': '/methods/14', // Exercise: HTTP Handlers
    '#60': '/methods/15', // Images
    '#61': '/methods/16', // Exercise: Images
    '#62': undefined, // Exercise: Rot13 Reader
    '#63': undefined, // Concurrency
    '#64': '/concurrency/1', // Goroutines
    '#65': '/concurrency/2', // Channels
    '#66': '/concurrency/3', // Buffered Channels
    '#67': '/concurrency/4', // Range and Close
    '#68': '/concurrency/5', // Select
    '#69': '/concurrency/6', // Default Selection
    '#70': '/concurrency/7', // Exercise: Equivalent Binary Trees
    '#71': '/concurrency/8', // Exercise: Equivalent Binary Trees
    '#72': '/concurrency/9', // Exercise: Web Crawler
    '#73': '/concurrency/10', // Where to Go from here...
});
<commit_msg>static/js: remove issue-title to desable submit<commit_after>/* Copyright 2012 The Go Authors.   All rights reserved.
 * Use of this source code is governed by a BSD-style
 * license that can be found in the LICENSE file.
 */
'use strict';

angular.module('tour.values', []).

// List of modules with description and lessons in it.
value('tableOfContents', [{
    'id': 'mechanics',
    'title': 'Utilisation du tour',
    'description': '
Bienvenue au tour du langage de programmation Go. Ce tour couvre les caractéristiques les plus importantes du langage, principalement:
',
    'lessons': ['welcome']
}, {
    'id': 'basics',
    'title': 'Principes de base',
    'description': '
Le point de départ, apprendre tous les rudiments du langage
Déclaration des variables, des fonctions d\'appel, et toutes les choses que vous devez savoir avant de passer aux prochaines leçons.
',
    'lessons': ['basics', 'flowcontrol', 'moretypes']
}, {
    'id': 'methods',
    'title': 'Methods et interfaces',
    'description': '
Savoir comment définir des méthodes sur les types, comment déclarer des interfaces, et comment assembler le tout.
',
    'lessons': ['methods']
}, {
    'id': 'concurrency',
    'title': 'Concurrency',
    'description': '
Go offre des primitives de simultanéité dans le cadre du langage de base.

Ce module les présentent et donne quelques exemples sur la façon de les utilisés pour mettre en œuvre différents modèles de concurrence.
',
    'lessons': ['concurrency']
}]).

// Translation
value('translation', {
    'off': 'Désactivé',
    'on': 'Activé',
    'syntax': 'Syntaxe',
    'lineno': 'Numéros de ligne',
    'reset': 'Réinitialiser',
    'format': 'Formater',
    'kill': 'Tuer',
    'run': 'Exécuter',
    'compile': 'Compiler et Exécuter',
    'more': 'Options',
    'toc': 'Menu',
    'prev': 'Précédent',
    'next': 'Suivant',
    'waiting': 'En attente du serveur distant...',
    'errcomm': 'Erreur de communication avec le serveur distant.',
    'submit-feedback': 'envoyer un commentaire sur cette page',

    // GitHub issue template: update repo and messaging when translating.
    'github-repo': 'github.com/dupoxy/go-tour-fr',
    'issue-title': '',
    'issue-message': '',
    'context': 'Context',
}).

// Config for codemirror plugin
value('ui.config', {
    codemirror: {
        mode: 'text/x-go',
        matchBrackets: true,
        lineNumbers: true,
        autofocus: true,
        indentWithTabs: true,
        indentUnit: 4,
        tabSize: 4,
        lineWrapping: true,
        extraKeys: {
            'Shift-Enter': function() {
                $('#run').click();
            },
            'Ctrl-Enter': function() {
                $('#format').click();
            },
            'PageDown': function() {
                return false;
            },
            'PageUp': function() {
                return false;
            },
        },
        // TODO: is there a better way to do this?
        // AngularJS values can't depend on factories.
        onChange: function() {
            if (window.codeChanged !== null) window.codeChanged();
        }
    }
}).

// mapping from the old paths (#42) to the new organization.
// The values have been generated with the map.sh script in the tools directory.
value('mapping', {
    '#1': '/welcome/1', // Hello, 世界
    '#2': '/welcome/2', // Go local
    '#3': '/basics/1', // Packages
    '#4': '/basics/2', // Imports
    '#5': '/basics/3', // Exported names
    '#6': '/basics/4', // Functions
    '#7': '/basics/5', // Functions continued
    '#8': '/basics/6', // Multiple results
    '#9': undefined, // Named results
    '#10': '/basics/8', // Variables
    '#11': '/basics/9', // Variables with initializers
    '#12': '/basics/10', // Short variable declarations
    '#13': '/basics/11', // Basic types
    '#14': '/basics/13', // Type conversions
    '#15': '/basics/15', // Constants
    '#16': '/basics/16', // Numeric Constants
    '#17': '/flowcontrol/1', // For
    '#18': '/flowcontrol/2', // For continued
    '#19': '/flowcontrol/3', // For is Go's "while"
    '#20': '/flowcontrol/4', // Forever
    '#21': '/flowcontrol/5', // If
    '#22': '/flowcontrol/6', // If with a short statement
    '#23': '/flowcontrol/7', // If and else
    '#24': '/flowcontrol/8', // Exercise: Loops and Functions
    '#25': '/moretypes/2', // Structs
    '#26': '/moretypes/3', // Struct Fields
    '#27': '/moretypes/1', // Pointers
    '#28': '/moretypes/5', // Struct Literals
    '#29': undefined, // The new function
    '#30': '/moretypes/6', // Arrays
    '#31': '/moretypes/7', // Slices
    '#32': '/moretypes/8', // Slicing slices
    '#33': '/moretypes/9', // Making slices
    '#34': '/moretypes/10', // Nil slices
    '#35': '/moretypes/12', // Range
    '#36': '/moretypes/13', // Range continued
    '#37': '/moretypes/14', // Exercise: Slices
    '#38': '/moretypes/15', // Maps
    '#39': '/moretypes/16', // Map literals
    '#40': '/moretypes/17', // Map literals continued
    '#41': '/moretypes/18', // Mutating Maps
    '#42': '/moretypes/19', // Exercise: Maps
    '#43': '/moretypes/20', // Function values
    '#44': '/moretypes/21', // Function closures
    '#45': '/moretypes/22', // Exercise: Fibonacci closure
    '#46': '/flowcontrol/9', // Switch
    '#47': '/flowcontrol/10', // Switch evaluation order
    '#48': '/flowcontrol/11', // Switch with no condition
    '#49': undefined, // Advanced Exercise: Complex cube roots
    '#50': undefined, // Methods and Interfaces
    '#51': '/methods/1', // Methods
    '#52': '/methods/2', // Methods continued
    '#53': '/methods/3', // Methods with pointer receivers
    '#54': '/methods/4', // Interfaces
    '#55': '/methods/5', // Interfaces are satisfied implicitly
    '#56': '/methods/8', // Errors
    '#57': '/methods/9', // Exercise: Errors
    '#58': '/methods/13', // Web servers
    '#59': '/methods/14', // Exercise: HTTP Handlers
    '#60': '/methods/15', // Images
    '#61': '/methods/16', // Exercise: Images
    '#62': undefined, // Exercise: Rot13 Reader
    '#63': undefined, // Concurrency
    '#64': '/concurrency/1', // Goroutines
    '#65': '/concurrency/2', // Channels
    '#66': '/concurrency/3', // Buffered Channels
    '#67': '/concurrency/4', // Range and Close
    '#68': '/concurrency/5', // Select
    '#69': '/concurrency/6', // Default Selection
    '#70': '/concurrency/7', // Exercise: Equivalent Binary Trees
    '#71': '/concurrency/8', // Exercise: Equivalent Binary Trees
    '#72': '/concurrency/9', // Exercise: Web Crawler
    '#73': '/concurrency/10', // Where to Go from here...
});
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import s from './Algorithms.css';
import classNames from 'classnames/bind';

class Dropdown extends Component {
  static propTypes = {
    title: PropTypes.string,
    algorithms: React.PropTypes.array.isRequired,
  };

  render() {
    return (
      {this.props.title}arrow_drop_down
    );
  }
}

class Algorithms extends Component {

  static contextTypes = {
    setTitle: PropTypes.func.isRequired,
  };

  static propTypes = {
    title: PropTypes.string,
    algorithms: React.PropTypes.object.isRequired,
  };

  constructor(props) {
    super(props);
    this.state = {
      categories: Object.keys(this.props.algorithms)
    }
    console.log(this.state);
  }

  componentWillMount() {
    this.context.setTitle(this.props.title);
  }

  categoryClick(category) {
    this.setState({
      currentCategory: category
    })
  }

  upperCaseFirst(value) {
    return value.charAt(0).toUpperCase() + value.slice(1)
  }

  render() {
    let cx = classNames.bind(s);

    let algorithms = this.state.categories.map((category) => {
      let className = cx({
        active: this.state.currentCategory === category
      });

      let algorithms = this.props.algorithms[category];

      return (

          <Dropdown title={this.upperCaseFirst(category)} algorithms={algorithms} />

      )
    })

    return (

                {algorithms}

    );
  }

}

export default withStyles(s)(Algorithms);
<commit_msg>dropdown done right<commit_after>import React, { Component, PropTypes } from 'react';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import s from './Algorithms.css';
import classNames from 'classnames/bind';

class Dropdown extends Component {
  static propTypes = {
    title: PropTypes.string,
    algorithms: React.PropTypes.array.isRequired,
  };

  render() {
    let list = this.props.algorithms.map((algorithm, i) => {
      return (

{algorithm.text}

      );
    });
    let triggerName = this.props.title + "-trigger";
    return (

        {this.props.title}arrow_drop_down

          {list}

    );
  }
}

class Algorithms extends Component {

  static contextTypes = {
    setTitle: PropTypes.func.isRequired,
  };

  static propTypes = {
    title: PropTypes.string,
    algorithms: React.PropTypes.object.isRequired,
  };

  constructor(props) {
    super(props);
    this.state = {
      categories: Object.keys(this.props.algorithms)
    }
    console.log(this.state);
  }

  componentWillMount() {
    this.context.setTitle(this.props.title);
  }

  categoryClick(category) {
    this.setState({
      currentCategory: category
    })
  }

  upperCaseFirst(value) {
    return value.charAt(0).toUpperCase() + value.slice(1)
  }

  render() {
    let cx = classNames.bind(s);

    let algorithms = this.state.categories.map((category) => {
      let className = cx({
        active: this.state.currentCategory === category
      });

      let algorithms = this.props.algorithms[category];

      return (

          <Dropdown title={this.upperCaseFirst(category)} algorithms={algorithms} />

      )
    })

    return (

                {algorithms}

    );
  }

}

export default withStyles(s)(Algorithms);
<|endoftext|>


<commit_before>/* menuitems.js
* Created by:
* Date: 03/07/14
* Menu item functionality
*
* TODO:
* - Make a version of examples that's on the same page
* - Take out the dropdown menu
* - Try adding a top bar above the app
* - (Possibly) separate the toggle function into 3
* parts: toggle, open, close
* - Make a version that pushes what's on top to the
* right as well as brings things out from the left
* (basically has multiple layers and top layers are
* removed first when appropriate)
*
* DONE:
* - [DONE] If we really do completely separate "panes" for
* each menu item, make a data value for each thing's
* "pane" so they can all be called the same way.
*
*/

// Just so I don't have to keep copying and pasting examples goddamnit
$(document).ready(function() {
	// *** SETUP ***\\
	// A way to toggle till I figure out how that works
	var count = 0;
	// Associate top menu options with panes
	$("#lessons-menu").data("pane", $("#lessons-pane"));
	$("#examples-menu").data("pane", $("#examples-pane"));

	// *** EVENT LISTENERS ***\\
	// -- All -- \\
	// Get rid of border?
	// Show panes on click
	$(".top-menu").not($(".menu-items"))
		.on("click", function (thisEv) {mItems.togglePane($(this), $(thisEv.target));})

	// This will go away
	// Highlight dropdown menu items on hover
	$("body").on("mouseenter", "li", function () {
			$(this).css({"background-color": props.activeText});
		})
	.on("mouseleave", "li", function () {
			$(this).css("background-color", "inherit");
		}
	);

	// --- Examples --- \\
	// Make dropdown appear and disappear on click
	$(".top-menu").on("click", function(thisEv) {
		var $target = $(thisEv.target);
		// If it's an "examples-menu"...
		if ($(this).children().attr("id") == "examples-menu"
			// ... list item
			&& $target.prop("tagName") != "LI") {
			$(".top-menu ul").toggle();
		}
		// If "alt" is pressed
		if ($(this).children().attr("id") == "alt-menu") {
			// Do the alternate examples stuff
			ex.exAlt();
		}
	});
	// On-page version (though wouldn't be dropdown)
	$(".menu-items li").on("click", function() {ex.pasteEx($(this));});
	// Examples page version
	$("body").on("click", ".examples li", function() {ex.pasteEx($(this));});

	// --- Lessons --- \\
	// // Show and hide references?
	// $("#reference").click(function () {})
	// // Make it bold when hovered over
	// .hover(function () {//$(this).toggleClass("bold");
	// });
});

var mItems = {
	// Is the simulator showing?
	isSim: true
	// Has one toggle animation completed?
// [Something to do with "width",["toggle","swing"]] Why isn't this working?
	, canToggle: true
	// // Animation times
	// , fadeTime: 200
	, slideTime: 600
	// // Remember the width of the visualizer
	// , visWidth: null
	// // Remember #reference's padding
	// , refPad: null

	, togglePane: function ($clickedItem, $thisTarget) {
		/* ($, $) -> None

		If previous pane toggles are finished, puts a
		border around $clickedItem, slides the pane
		associated with $thisTarget into or out of view,
		moves the other panes off screen if needed.
		*/

		if (mItems.canToggle) {
			// console.log("1 in mItems.canToggle");
			// Disallow toggling
			mItems.canToggle = false;
			// Get menu item's child (with the id)
			var $topMenuItem = $($clickedItem.children()[0]);
			// Get menu item's panel
			var $itemPane = $topMenuItem.data("pane");
			// Take the border off of every other item
			$(".top-menu").not($clickedItem).css("border", props.inactiveBorder);

			// Temporary till dropdown is gone make sure it's not a list item
			if ($thisTarget.prop("tagName") != "LI") {
				// console.log("  2 in prop name LI");
				// If it has a "pane" data value
				// If I combine these two if's, any non-pane
				// button will get rid of the other panes
				if ($itemPane) {
					// console.log("    3 in $itemPane");
					// If the pane is off screen
					if ($itemPane.css("left") != "0px") {
						// console.log("      4 in 'left' not 0");
						// Indicate the item is active
						$clickedItem.css("border", props.activeBorder);
						// Put relevant pane on top and slide it left
						$(".not-sim").not($itemPane).css("z-index","50");
						$itemPane.css("z-index","100");
						$itemPane.animate({"left": "0"}, mItems.slideTime, "swing"
							, function () {
								// Slide the other panes right
								$(".not-sim").not($itemPane).css({"left": "100%"});
							});
						// Re-allow toggling now
						mItems.canToggle = true;
					}  // end of if $itemPane

					// If the pane is on screen
					else {
						// console.log("      4 in else");
						// Remove indication of active item
						$clickedItem.css("border", props.inactiveBorder);
						// Hide the pane
						$(".not-sim").animate({"left": "100%"}, mItems.slideTime, "swing");
						// Re-allow toggling now
						mItems.canToggle = true;
					}
					// console.log("      4 out of 'left' not 0");
				}  // end of if $itemPane
				// Don't know if I need these else's
				else {mItems.canToggle = true;}
				// console.log("    3 out of $itemPane");
			}  // End of temporary target check
			else {mItems.canToggle = true;}
			// console.log("  2 out of if prop name LI");
		}  // end of canToggle
		// console.log("1 out of canToggle");
	},  // End togglePane()

	// Reveal a lower pane by removing all the panes above it:
	// If the top layer is removed
		// remove all layers
		// set layers var to 0 (1?)
	// If a bottom layer is requested
		// remove all layers above it
		// set their layer to null
	// If a layer is added, give it the next number

	closeLess: function ($topMenuItem) {
		/* (None) -> None

		*/

		// if (mItems.canToggle) {
		// 	// Disallow toggling
		// 	mItems.canToggle = false;
		// 	// For things that may want to get the simulator back
		// 	// and to prevent #reference from becoming bold
		// 	// though that doesn't work if it's right at the beginning
		// 	mItems.isSim = true;
		// 	// Get menu item's panel
		// 	var $itemPane = $topMenuItem.data("pane");

		// 	// Slide this element to the right again
		// 	$itemPane.animate({"left": "100%"}, 400);
		// 	// Restore menu item to unselected
		// 	$topMenuItem.css("border", props.inactiveBorder);
		// 	// Re-allow toggling now
		// 	mItems.canToggle = true;

		// }  // end of canToggle
	},  // End closeLess()
};  // End mItems

var ex = {
	exAlt: function () {
		/* (None) -> None

		A demo of an alternative to the examples pane.
		Instantiate or remove an examples div on the
		same page as the simulator
		*/
// http://stackoverflow.com/questions/3086068/how-do-i-check-whether-a-jquery-element-is-in-the-dom

		if ( $("#examples-box")[0] ) {
			$("#examples-box").remove();
		}
		else {
			var $examplesBox = $("
"
				+ "Some words of explaination about stuff:"
		    	+ "

"
				+ "
((u-theta 0.6 0))
"
				+ "
((u-theta 0.8 0))
"
				+ "
((u-theta 1.6 0))
"
				+ "
((u-theta 2.3 0))

");

			$("#editor").append($examplesBox);

			$("#examples-box").css({position:"absolute"
				, left:"0", top:"0", "z-index":"250"
				,"background-color":"white", width: "100%"
				, height: "100%", "font-size":"17px"
				, padding:"10px"
				, "-webkit-box-sizing": "border-box"
				, "-moz-box-sizing": "border-box"
				, "box-sizing": "border-box"});
			$("#examples-box .examples").css({padding:"10px"
				, margin: "10px 0"});
			$("#examples-box .examples li").css({
				margin: "5px", padding: "5px", border: props.activeBorder
			});
		}
	}

	, pasteEx: function ($thisElem) {
		/* ($ collection) -> None

		Copy the text in the $ collection, paste
		it into the editor, and evaluate. If needed,
		reveal the simulator first.
		*/

		var simShowing = true;

		// if any non-sim is showing
		$(".not-sim").each(function () {
			if ($(this).css("left") == "0px") {
				simShowing = false;
			}
		});

		// If there's a pane covering the sim
		if (!simShowing) {
			// Slide away all the panes
			$(".not-sim")
			.animate({"left": "100%"}, mItems.slideTime, "swing"
				, function () {
					// After that and a 75 ms delay
					setTimeout(function () {
						// Replace any text with new text, evaluate
						editor.getSession().setValue($thisElem.text());
						$("#evaluate").trigger("click");
						// Remove indication of active item
						$(".top-menu").css("border", props.inactiveBorder);
						}, 75);  // end setTimeout
			});  // end .animate
		}  // end if !simShowing

		//Otherwise don't wait to do the stuff
		else {
			// Replace any text with new text, evaluate
			editor.getSession().setValue($thisElem.text());
			$("#evaluate").trigger("click");
			// Remove indication of active item
			$(".top-menu").css("border", props.inactiveBorder);
		}
	}  // End pasteEx()
};
<commit_msg>Active border gone, dropdown remnants gone (I think)<commit_after>/* menuitems.js
* Created by:
* Date: 03/07/14
* Menu item functionality
*
* TODO:
* - Make a version of examples that's on the same page
* - Take out the dropdown menu
* - Try adding a top bar above the app
* - (Possibly) separate the toggle function into 3
* parts: toggle, open, close
* - Make a version that pushes what's on top to the
* right as well as brings things out from the left
* (basically has multiple layers and top layers are
* removed first when appropriate)
*
* DONE:
* - [DONE] If we really do completely separate "panes" for
* each menu item, make a data value for each thing's
* "pane" so they can all be called the same way.
*
*/

// Just so I don't have to keep copying and pasting examples goddamnit
$(document).ready(function() {
	// *** SETUP ***\\
	// A way to toggle till I figure out how that works
	var count = 0;
	// Associate top menu options with panes
	$("#lessons-menu").data("pane", $("#lessons-pane"));
	$("#examples-menu").data("pane", $("#examples-pane"));

	// *** EVENT LISTENERS ***\\
	// -- All -- \\
	// Get rid of border?
	// Show panes on click
	$(".top-menu").not($(".menu-items"))
		.on("click", function (thisEv) {mItems.togglePane($(this), $(thisEv.target));})

	// This will go away
	// Highlight dropdown menu items on hover
	$("body").on("mouseenter", "li", function () {
			$(this).css({"background-color": props.activeText});
		})
	.on("mouseleave", "li", function () {
			$(this).css("background-color", "inherit");
		}
	);

	// --- Examples --- \\
	// Make dropdown appear and disappear on click
	$(".top-menu").on("click", function (thisEv) {
		// If "alt" is pressed
		if ($(this).children().attr("id") == "alt-menu") {
			// Do the alternate examples stuff
			ex.exAlt();
		}
	});

	// Examples page version
	$("body").on("click", ".examples li", function() {ex.pasteEx($(this));});

	// --- Lessons --- \\
	// // Show and hide references?
	// $("#reference").click(function () {})
	// // Make it bold when hovered over
	// .hover(function () {//$(this).toggleClass("bold");
	// });
});

var mItems = {
	// Is the simulator showing?
	isSim: true
	// Has one toggle animation completed?
// [Something to do with "width",["toggle","swing"]] Why isn't this working?
	, canToggle: true
	// // Animation times
	// , fadeTime: 200
	, slideTime: 600
	// // Remember the width of the visualizer
	// , visWidth: null
	// // Remember #reference's padding
	// , refPad: null

	, togglePane: function ($clickedItem, $thisTarget) {
		/* ($, $) -> None

		If previous pane toggles are finished, puts a
		border around $clickedItem, slides the pane
		associated with $thisTarget into or out of view,
		moves the other panes off screen if needed.
		*/

		if (mItems.canToggle) {
			// console.log("1 in mItems.canToggle");
			// Disallow toggling
			mItems.canToggle = false;
			// Get menu item's child (with the id)
			var $topMenuItem = $($clickedItem.children()[0]);
			// Get menu item's panel
			var $itemPane = $topMenuItem.data("pane");
			// Somehow indicate item is inactive
			// // Take the border off of every other item
			// $(".top-menu").not($clickedItem).css("border", props.inactiveBorder);

			// Temporary till dropdown is gone make sure it's not a list item
			if ($thisTarget.prop("tagName") != "LI") {
				// console.log("  2 in prop name LI");
				// If it has a "pane" data value
				// If I combine these two if's, any non-pane
				// button will get rid of the other panes
				if ($itemPane) {
					// console.log("    3 in $itemPane");
					// If the pane is off screen
					if ($itemPane.css("left") != "0px") {
						// console.log("      4 in 'left' not 0");
						// Indicate the item is active
						// $clickedItem.css("border", props.activeBorder);
						// Put relevant pane on top and slide it left
						$(".not-sim").not($itemPane).css("z-index","50");
						$itemPane.css("z-index","100");
						$itemPane.animate({"left": "0"}, mItems.slideTime, "swing"
							, function () {
								// Slide the other panes right
								$(".not-sim").not($itemPane).css({"left": "100%"});
							});
						// Re-allow toggling now
						mItems.canToggle = true;
					}  // end of if $itemPane

					// If the pane is on screen
					else {
						// console.log("      4 in else");
						// Remove indication of active item
						// $clickedItem.css("border", props.inactiveBorder);
						// Hide the pane
						$(".not-sim").animate({"left": "100%"}, mItems.slideTime, "swing");
						// Re-allow toggling now
						mItems.canToggle = true;
					}
					// console.log("      4 out of 'left' not 0");
				}  // end of if $itemPane
				// Don't know if I need these else's
				else {mItems.canToggle = true;}
				// console.log("    3 out of $itemPane");
			}  // End of temporary target check
			else {mItems.canToggle = true;}
			// console.log("  2 out of if prop name LI");
		}  // end of canToggle
		// console.log("1 out of canToggle");
	},  // End togglePane()

	// Reveal a lower pane by removing all the panes above it:
	// If the top layer is removed
		// remove all layers
		// set layers var to 0 (1?)
	// If a bottom layer is requested
		// remove all layers above it
		// set their layer to null
	// If a layer is added, give it the next number

	closeLess: function ($topMenuItem) {
		/* (None) -> None

		*/

		// if (mItems.canToggle) {
		// 	// Disallow toggling
		// 	mItems.canToggle = false;
		// 	// For things that may want to get the simulator back
		// 	// and to prevent #reference from becoming bold
		// 	// though that doesn't work if it's right at the beginning
		// 	mItems.isSim = true;
		// 	// Get menu item's panel
		// 	var $itemPane = $topMenuItem.data("pane");

		// 	// Slide this element to the right again
		// 	$itemPane.animate({"left": "100%"}, 400);
		// 	// Restore menu item to unselected
		// 	$topMenuItem.css("border", props.inactiveBorder);
		// 	// Re-allow toggling now
		// 	mItems.canToggle = true;

		// }  // end of canToggle
	},  // End closeLess()
};  // End mItems

var ex = {
	exAlt: function () {
		/* (None) -> None

		A demo of an alternative to the examples pane.
		Instantiate or remove an examples div on the
		same page as the simulator
		*/
// http://stackoverflow.com/questions/3086068/how-do-i-check-whether-a-jquery-element-is-in-the-dom

		if ( $("#examples-box")[0] ) {
			$("#examples-box").remove();
		}
		else {
			var $examplesBox = $("
"
				+ "Some words of explaination about stuff:"
		    	+ "

"
				+ "
((u-theta 0.6 0))
"
				+ "
((u-theta 0.8 0))
"
				+ "
((u-theta 1.6 0))
"
				+ "
((u-theta 2.3 0))

");

			$("#editor").append($examplesBox);

			$("#examples-box").css({position:"absolute"
				, left:"0", top:"0", "z-index":"250"
				,"background-color":"white", width: "100%"
				, height: "100%", "font-size":"17px"
				, padding:"10px"
				, "-webkit-box-sizing": "border-box"
				, "-moz-box-sizing": "border-box"
				, "box-sizing": "border-box"});
			$("#examples-box .examples").css({padding:"10px"
				, margin: "10px 0"});
			$("#examples-box .examples li").css({
				margin: "5px", padding: "5px", border: props.activeBorder
			});
		}
	}

	, pasteEx: function ($thisElem) {
		/* ($ collection) -> None

		Copy the text in the $ collection, paste
		it into the editor, and evaluate. If needed,
		reveal the simulator first.
		*/

		var simShowing = true;

		// if any non-sim is showing
		$(".not-sim").each(function () {
			if ($(this).css("left") == "0px") {
				simShowing = false;
			}
		});

		// If there's a pane covering the sim
		if (!simShowing) {
			// Slide away all the panes
			$(".not-sim")
			.animate({"left": "100%"}, mItems.slideTime, "swing"
				, function () {
					// After that and a 75 ms delay
					setTimeout(function () {
						// Replace any text with new text, evaluate
						editor.getSession().setValue($thisElem.text());
						$("#evaluate").trigger("click");
						// Remove indication of active item
						$(".top-menu").css("border", props.inactiveBorder);
						}, 75);  // end setTimeout
			});  // end .animate
		}  // end if !simShowing

		//Otherwise don't wait to do the stuff
		else {
			// Replace any text with new text, evaluate
			editor.getSession().setValue($thisElem.text());
			$("#evaluate").trigger("click");
			// Remove indication of active item
			$(".top-menu").css("border", props.inactiveBorder);
		}
	}  // End pasteEx()
};
<|endoftext|>


<commit_before>/*!
 * ${copyright}
 */

// Provides control sap.m.StandardTile.
sap.ui.define(['jquery.sap.global', './Tile', './library', 'sap/ui/core/IconPool'],
	function(jQuery, Tile, library, IconPool) {
	"use strict";

	/**
	 * Constructor for a new StandardTile.
	 *
	 * @param {string} [sId] ID for the new control, generated automatically if no ID is given
	 * @param {object} [mSettings] Initial settings for the new control
	 *
	 * @class
	 * The StandardTile control is displayed in the tile container.
	 * @extends sap.m.Tile
	 *
	 * @author SAP SE
	 * @version ${version}
	 *
	 * @constructor
	 * @public
	 * @since 1.12
	 * @alias sap.m.StandardTile
	 * @ui5-metamodel This control/element also will be described in the UI5 (legacy) designtime metamodel
	 */
	var StandardTile = Tile.extend("sap.m.StandardTile", /** @lends sap.m.StandardTile.prototype */ { metadata : {

		library : "sap.m",
		properties : {

			/**
			 * Defines the title of the StandardTile.
			 */
			title : {type : "string", group : "Misc", defaultValue : null},

			/**
			 * Defines the description of the StandardTile.
			 */
			info : {type : "string", group : "Misc", defaultValue : null},

			/**
			 * Defines the icon of the StandardTile.
			 */
			icon : {type : "sap.ui.core.URI", group : "Misc", defaultValue : null},

			/**
			 * Defines the active icon of the StandardTile.
			 */
			activeIcon : {type : "sap.ui.core.URI", group : "Misc", defaultValue : null},

			/**
			 * Defines the number field of the StandardTile.
			 */
			number : {type : "string", group : "Misc", defaultValue : null},

			/**
			 * Defines the number units qualifier of the StandardTile.
			 */
			numberUnit : {type : "string", group : "Misc", defaultValue : null},

			/**
			 * Defines the color of the info text. Possible values are Error, Warning, Success and so on.
			 */
			infoState : {type : "sap.ui.core.ValueState", group : "Misc", defaultValue : sap.ui.core.ValueState.None},

			/**
			 * Defines the type of the StandardTile.
			 */
			type : {type : "sap.m.StandardTileType", group : "Misc", defaultValue : sap.m.StandardTileType.None},

			/**
			 * By default, this is set to true but then one or more requests are sent trying to get the density perfect version of image if this version of image doesn't exist on the server.
			 *
			 * If bandwidth is key for the application, set this value to false.
			 */
			iconDensityAware : {type : "boolean", group : "Appearance", defaultValue : true}
		},
		associations : {

			/**
			 * Association to controls / IDs, which describe this control (see WAI-ARIA attribute aria-describedby).
			 */
			ariaDescribedBy : {type : "sap.ui.core.Control", multiple : true, singularName : "ariaDescribedBy"}
		}
	}});

	/**
	 * Called when the control is destroyed.
	 *
	 * @private
	 */
	StandardTile.prototype.exit = function() {
		if (this._oImageControl) {
			this._oImageControl.destroy();
			this._oImageControl = null;
		}
	};

	/**
	 * Overrides the icon property of the StandardTile control.
	 *
	 * @private
	 */
	StandardTile.prototype.getIcon = function() {
		if (!this.getProperty("icon") && this.getType() === "Create") {
			return IconPool.getIconURI("add");
		} else {
			return this.getProperty("icon");
		}
	};

	/**
	 * Lazy loads StandardTile icon image.
	 *
	 * @private
	 */
	StandardTile.prototype._getImage = function() {

		var sImgId = this.getId() + "-img";
		var sSize = sap.ui.Device.system.phone ? "1.3rem" : "2rem";

		var mProperties = {
			src : this.getIcon(),
			height : sSize,
			width : sSize,
			size: sSize,
			densityAware : this.getIconDensityAware(),
			useIconTooltip : false
		};

		this._oImageControl = sap.m.ImageHelper.getImageControl(sImgId, this._oImageControl, this, mProperties);

		return this._oImageControl;
	};

	return StandardTile;

}, /* bExport= */ true);
<commit_msg>[FIX] m.StandardTile: getIcon documentation corrected<commit_after>/*!
 * ${copyright}
 */

// Provides control sap.m.StandardTile.
sap.ui.define(['jquery.sap.global', './Tile', './library', 'sap/ui/core/IconPool'],
	function(jQuery, Tile, library, IconPool) {
	"use strict";

	/**
	 * Constructor for a new StandardTile.
	 *
	 * @param {string} [sId] ID for the new control, generated automatically if no ID is given
	 * @param {object} [mSettings] Initial settings for the new control
	 *
	 * @class
	 * The StandardTile control is displayed in the tile container.
	 * @extends sap.m.Tile
	 *
	 * @author SAP SE
	 * @version ${version}
	 *
	 * @constructor
	 * @public
	 * @since 1.12
	 * @alias sap.m.StandardTile
	 * @ui5-metamodel This control/element also will be described in the UI5 (legacy) designtime metamodel
	 */
	var StandardTile = Tile.extend("sap.m.StandardTile", /** @lends sap.m.StandardTile.prototype */ { metadata : {

		library : "sap.m",
		properties : {

			/**
			 * Defines the title of the StandardTile.
			 */
			title : {type : "string", group : "Misc", defaultValue : null},

			/**
			 * Defines the description of the StandardTile.
			 */
			info : {type : "string", group : "Misc", defaultValue : null},

			/**
			 * Defines the icon of the StandardTile.
			 */
			icon : {type : "sap.ui.core.URI", group : "Misc", defaultValue : null},

			/**
			 * Defines the active icon of the StandardTile.
			 */
			activeIcon : {type : "sap.ui.core.URI", group : "Misc", defaultValue : null},

			/**
			 * Defines the number field of the StandardTile.
			 */
			number : {type : "string", group : "Misc", defaultValue : null},

			/**
			 * Defines the number units qualifier of the StandardTile.
			 */
			numberUnit : {type : "string", group : "Misc", defaultValue : null},

			/**
			 * Defines the color of the info text. Possible values are Error, Warning, Success and so on.
			 */
			infoState : {type : "sap.ui.core.ValueState", group : "Misc", defaultValue : sap.ui.core.ValueState.None},

			/**
			 * Defines the type of the StandardTile.
			 */
			type : {type : "sap.m.StandardTileType", group : "Misc", defaultValue : sap.m.StandardTileType.None},

			/**
			 * By default, this is set to true but then one or more requests are sent trying to get the density perfect version of image if this version of image doesn't exist on the server.
			 *
			 * If bandwidth is key for the application, set this value to false.
			 */
			iconDensityAware : {type : "boolean", group : "Appearance", defaultValue : true}
		},
		associations : {

			/**
			 * Association to controls / IDs, which describe this control (see WAI-ARIA attribute aria-describedby).
			 */
			ariaDescribedBy : {type : "sap.ui.core.Control", multiple : true, singularName : "ariaDescribedBy"}
		}
	}});

	/**
	 * Called when the control is destroyed.
	 *
	 * @private
	 */
	StandardTile.prototype.exit = function() {
		if (this._oImageControl) {
			this._oImageControl.destroy();
			this._oImageControl = null;
		}
	};

	/**
	 * Gets the icon of the StandardTile control.
	 *
	 * @public
	 */
	StandardTile.prototype.getIcon = function() {
		if (!this.getProperty("icon") && this.getType() === "Create") {
			return IconPool.getIconURI("add");
		} else {
			return this.getProperty("icon");
		}
	};

	/**
	 * Lazy loads StandardTile icon image.
	 *
	 * @private
	 */
	StandardTile.prototype._getImage = function() {

		var sImgId = this.getId() + "-img";
		var sSize = sap.ui.Device.system.phone ? "1.3rem" : "2rem";

		var mProperties = {
			src : this.getIcon(),
			height : sSize,
			width : sSize,
			size: sSize,
			densityAware : this.getIconDensityAware(),
			useIconTooltip : false
		};

		this._oImageControl = sap.m.ImageHelper.getImageControl(sImgId, this._oImageControl, this, mProperties);

		return this._oImageControl;
	};

	return StandardTile;

}, /* bExport= */ true);
<|endoftext|>


<commit_before>goog.provide('annotorious.plugins.selection.RectDragSelector');

goog.require('goog.events');

goog.require('annotorious.events.ui');

/**
 * The default selector: a simple click-and-drag rectangle selection tool.
 * @constructor
 */
annotorious.plugins.selection.RectDragSelector = function() { }

/**
 * Initializes the selector.
 * @param {Element} canvas the canvas to draw on
 * @param {Object} annotator reference to the annotator
 */
annotorious.plugins.selection.RectDragSelector.prototype.init = function(canvas, annotator) {
  /** @private **/
  this._canvas = canvas;

  /** @private **/
  this._annotator = annotator;

  /** @private **/
  this._g2d = canvas.getContext('2d');
  this._g2d.lineWidth = 1;

  /** @private **/
  this._anchor;

  /** @private **/
  this._opposite;

  /** @private **/
  this._enabled = false;

  /** @private **/
  this._mouseMoveListener;

  /** @private **/
  this._mouseUpListener;
}

/**
 * Attaches MOUSEUP and MOUSEMOVE listeners to the editing canvas.
 * @private
 */
annotorious.plugins.selection.RectDragSelector.prototype._attachListeners = function(startPoint) {
  var self = this;
  var canvas = this._canvas;

  this._mouseMoveListener = goog.events.listen(this._canvas, annotorious.events.ui.EventType.MOVE, function(event) {
    var points = annotorious.events.ui.sanitizeCoordinates(event, canvas);
    if (self._enabled) {
      self._opposite = { x: points.x, y: points.y };

      self._g2d.clearRect(0, 0, canvas.width, canvas.height);

      var width = self._opposite.x - self._anchor.x;
      var height = self._opposite.y - self._anchor.y;

      self._g2d.strokeStyle = '#000000';
      self._g2d.strokeRect(self._anchor.x + 0.5, self._anchor.y + 0.5, width, height);
      self._g2d.strokeStyle = '#ffffff';

      if (width > 0 && height > 0) {
        self._g2d.strokeRect(self._anchor.x + 1.5, self._anchor.y + 1.5, width - 2, height - 2);
      } else if (width > 0 && height < 0) {
        self._g2d.strokeRect(self._anchor.x + 1.5, self._anchor.y - 0.5, width - 2, height + 2);
      } else if (width < 0 && height < 0) {
        self._g2d.strokeRect(self._anchor.x - 0.5, self._anchor.y - 0.5, width + 2, height + 2);
      } else {
        self._g2d.strokeRect(self._anchor.x - 0.5, self._anchor.y + 1.5, width + 2, height - 2);
      }
    }
  });

  this._mouseUpListener = goog.events.listen(canvas, annotorious.events.ui.EventType.UP, function(event) {
    var points = annotorious.events.ui.sanitizeCoordinates(event, canvas);
    var shape = self.getShape();
    event = (event.event_) ? event.event_ : event;

    self._enabled = false;
    if (shape) {
      self._detachListeners();
      self._annotator.fireEvent(annotorious.events.EventType.SELECTION_COMPLETED,
        { mouseEvent: event, shape: shape, viewportBounds: self.getViewportBounds() });
    } else {
      self._annotator.fireEvent(annotorious.events.EventType.SELECTION_CANCELED);
      if (annotorious.events.ui.hasTouch) {
        // In touch mode, we use this to "relay" the selection event
        var annotations = self._annotator.getAnnotationsAt(points.x, points.y);
        if (annotations.length > 0)
          self._annotator.highlightAnnotation(annotations[0]);
      }
    }
  });
}

/**
 * Detaches MOUSEUP and MOUSEMOVE listeners from the editing canvas.
 * @private
 */
annotorious.plugins.selection.RectDragSelector.prototype._detachListeners = function() {
  if (this._mouseMoveListener) {
    goog.events.unlistenByKey(this._mouseMoveListener);
    delete this._mouseMoveListener;
  }

  if (this._mouseUpListener) {
    goog.events.unlistenByKey(this._mouseUpListener);
    delete this._mouseUpListener;
  }
}

/**
 * Selector API method: returns the selector name.
 * @returns the selector name
 */
annotorious.plugins.selection.RectDragSelector.prototype.getName = function() {
  return 'rect_drag';
}

/**
 * Selector API method: returns the supported shape type.
 *
 * TODO support for multiple shape types?
 *
 * @return the supported shape type
 */
annotorious.plugins.selection.RectDragSelector.prototype.getSupportedShapeType = function() {
  return annotorious.shape.ShapeType.RECTANGLE;
}

/**
 * Selector API method: starts the selection at the specified coordinates.
 * @param {number} x the X coordinate
 * @param {number} y the Y coordinate
 */
annotorious.plugins.selection.RectDragSelector.prototype.startSelection = function(x, y) {
  var startPoint = {
    x: x,
    y: y
  };
  this._enabled = true;
  this._attachListeners(startPoint);
  this._anchor = new annotorious.shape.geom.Point(x, y);
  this._annotator.fireEvent(annotorious.events.EventType.SELECTION_STARTED, {
    offsetX: x, offsetY: y});

  goog.style.setStyle(document.body, '-webkit-user-select', 'none');
}

/**
 * Selector API method: stops the selection.
 */
annotorious.plugins.selection.RectDragSelector.prototype.stopSelection = function() {
  this._detachListeners();
  this._g2d.clearRect(0, 0, this._canvas.width, this._canvas.height);
  goog.style.setStyle(document.body, '-webkit-user-select', 'auto');
  delete this._opposite;
}

/**
 * Selector API method: returns the currently edited shape.
 * @return {annotorious.shape.Shape | undefined} the shape
 */
annotorious.plugins.selection.RectDragSelector.prototype.getShape = function() {
  if (this._opposite &&
     (Math.abs(this._opposite.x - this._anchor.x) > 3) &&
     (Math.abs(this._opposite.y - this._anchor.y) > 3)) {

    var viewportBounds = this.getViewportBounds();
    var item_anchor = this._annotator.toItemCoordinates({x: viewportBounds.left, y: viewportBounds.top});
    var item_opposite = this._annotator.toItemCoordinates({x: viewportBounds.right - 1, y: viewportBounds.bottom - 1});

    var rect = new annotorious.shape.geom.Rectangle(
      item_anchor.x,
      item_anchor.y,
      item_opposite.x - item_anchor.x,
      item_opposite.y - item_anchor.y
    );

    return new annotorious.shape.Shape(annotorious.shape.ShapeType.RECTANGLE, rect);
  } else {
    return undefined;
  }
}

/**
 * Selector API method: returns the bounds of the selected shape, in viewport (= pixel) coordinates.
 * @returns {Object} the shape viewport bounds
 */
annotorious.plugins.selection.RectDragSelector.prototype.getViewportBounds = function() {
  var right, left;
  if (this._opposite.x > this._anchor.x) {
    right = this._opposite.x;
    left = this._anchor.x;
  } else {
    right = this._anchor.x;
    left = this._opposite.x;
  }

  var top, bottom;
  if (this._opposite.y > this._anchor.y) {
    top = this._anchor.y;
    bottom = this._opposite.y;
  } else {
    top = this._opposite.y;
    bottom = this._anchor.y;
  }

  return {top: top, right: right, bottom: bottom, left: left};
}

/**
 * TODO not sure if this is really the best way/architecture to handle viewer shape drawing
 * @param {Object} g2d graphics context
 * @param {annotorious.shape.Shape} shape the shape to draw
 * @param {boolean=} highlight if true, shape will be drawn highlighted
 */
annotorious.plugins.selection.RectDragSelector.prototype.drawShape = function(g2d, shape, highlight) {
  if (shape.type == annotorious.shape.ShapeType.RECTANGLE) {
    var color, lineWidth;
    if (highlight) {
      color = '#fff000';
      lineWidth = 1.2;
    } else {
      color = '#ffffff';
      lineWidth = 1;
    }

    var geom = shape.geometry;
    g2d.strokeStyle = '#000000';
    g2d.lineWidth = lineWidth;
    g2d.strokeRect(geom.x + 0.5, geom.y + 0.5, geom.width + 1, geom.height + 1);
    g2d.strokeStyle = color;
    g2d.strokeRect(geom.x + 1.5, geom.y + 1.5, geom.width - 1, geom.height - 1);
  }
}
<commit_msg>Issue #68<commit_after>goog.provide('annotorious.plugins.selection.RectDragSelector');

goog.require('goog.events');

goog.require('annotorious.events.ui');

/**
 * The default selector: a simple click-and-drag rectangle selection tool.
 * @constructor
 */
annotorious.plugins.selection.RectDragSelector = function() { }

/**
 * Initializes the selector.
 * @param {Element} canvas the canvas to draw on
 * @param {Object} annotator reference to the annotator
 */
annotorious.plugins.selection.RectDragSelector.prototype.init = function(canvas, annotator) {
  /** @private **/
  this._canvas = canvas;

  /** @private **/
  this._annotator = annotator;

  /** @private **/
  this._g2d = canvas.getContext('2d');
  this._g2d.lineWidth = 1;

  /** @private **/
  this._anchor;

  /** @private **/
  this._opposite;

  /** @private **/
  this._enabled = false;

  /** @private **/
  this._mouseMoveListener;

  /** @private **/
  this._mouseUpListener;
}

/**
 * Attaches MOUSEUP and MOUSEMOVE listeners to the editing canvas.
 * @private
 */
annotorious.plugins.selection.RectDragSelector.prototype._attachListeners = function(startPoint) {
  var self = this;
  var canvas = this._canvas;

  this._mouseMoveListener = goog.events.listen(this._canvas, annotorious.events.ui.EventType.MOVE, function(event) {
    var points = annotorious.events.ui.sanitizeCoordinates(event, canvas);
    if (self._enabled) {
      self._opposite = { x: points.x, y: points.y };

      self._g2d.clearRect(0, 0, canvas.width, canvas.height);

      var width = self._opposite.x - self._anchor.x;
      var height = self._opposite.y - self._anchor.y;

      self._g2d.strokeStyle = '#000000';
      self._g2d.strokeRect(self._anchor.x + 0.5, self._anchor.y + 0.5, width, height);
      self._g2d.strokeStyle = '#ffffff';

      if (width > 0 && height > 0) {
        self._g2d.strokeRect(self._anchor.x + 1.5, self._anchor.y + 1.5, width - 2, height - 2);
      } else if (width > 0 && height < 0) {
        self._g2d.strokeRect(self._anchor.x + 1.5, self._anchor.y - 0.5, width - 2, height + 2);
      } else if (width < 0 && height < 0) {
        self._g2d.strokeRect(self._anchor.x - 0.5, self._anchor.y - 0.5, width + 2, height + 2);
      } else {
        self._g2d.strokeRect(self._anchor.x - 0.5, self._anchor.y + 1.5, width + 2, height - 2);
      }
    }
  });

  this._mouseUpListener = goog.events.listen(canvas, annotorious.events.ui.EventType.UP, function(event) {
    var points = annotorious.events.ui.sanitizeCoordinates(event, canvas);
    var shape = self.getShape();
    event = (event.event_) ? event.event_ : event;

    self._enabled = false;
    if (shape) {
      self._detachListeners();
      self._annotator.fireEvent(annotorious.events.EventType.SELECTION_COMPLETED,
        { mouseEvent: event, shape: shape, viewportBounds: self.getViewportBounds() });
    } else {
      self._annotator.fireEvent(annotorious.events.EventType.SELECTION_CANCELED);

      // On cancel, we "relay" the selection event to the annotator
      var annotations = self._annotator.getAnnotationsAt(points.x, points.y);
      if (annotations.length > 0)
        self._annotator.highlightAnnotation(annotations[0]);
    }
  });
}

/**
 * Detaches MOUSEUP and MOUSEMOVE listeners from the editing canvas.
 * @private
 */
annotorious.plugins.selection.RectDragSelector.prototype._detachListeners = function() {
  if (this._mouseMoveListener) {
    goog.events.unlistenByKey(this._mouseMoveListener);
    delete this._mouseMoveListener;
  }

  if (this._mouseUpListener) {
    goog.events.unlistenByKey(this._mouseUpListener);
    delete this._mouseUpListener;
  }
}

/**
 * Selector API method: returns the selector name.
 * @returns the selector name
 */
annotorious.plugins.selection.RectDragSelector.prototype.getName = function() {
  return 'rect_drag';
}

/**
 * Selector API method: returns the supported shape type.
 *
 * TODO support for multiple shape types?
 *
 * @return the supported shape type
 */
annotorious.plugins.selection.RectDragSelector.prototype.getSupportedShapeType = function() {
  return annotorious.shape.ShapeType.RECTANGLE;
}

/**
 * Selector API method: starts the selection at the specified coordinates.
 * @param {number} x the X coordinate
 * @param {number} y the Y coordinate
 */
annotorious.plugins.selection.RectDragSelector.prototype.startSelection = function(x, y) {
  var startPoint = {
    x: x,
    y: y
  };
  this._enabled = true;
  this._attachListeners(startPoint);
  this._anchor = new annotorious.shape.geom.Point(x, y);
  this._annotator.fireEvent(annotorious.events.EventType.SELECTION_STARTED, {
    offsetX: x, offsetY: y});

  goog.style.setStyle(document.body, '-webkit-user-select', 'none');
}

/**
 * Selector API method: stops the selection.
 */
annotorious.plugins.selection.RectDragSelector.prototype.stopSelection = function() {
  this._detachListeners();
  this._g2d.clearRect(0, 0, this._canvas.width, this._canvas.height);
  goog.style.setStyle(document.body, '-webkit-user-select', 'auto');
  delete this._opposite;
}

/**
 * Selector API method: returns the currently edited shape.
 * @return {annotorious.shape.Shape | undefined} the shape
 */
annotorious.plugins.selection.RectDragSelector.prototype.getShape = function() {
  if (this._opposite &&
     (Math.abs(this._opposite.x - this._anchor.x) > 3) &&
     (Math.abs(this._opposite.y - this._anchor.y) > 3)) {

    var viewportBounds = this.getViewportBounds();
    var item_anchor = this._annotator.toItemCoordinates({x: viewportBounds.left, y: viewportBounds.top});
    var item_opposite = this._annotator.toItemCoordinates({x: viewportBounds.right - 1, y: viewportBounds.bottom - 1});

    var rect = new annotorious.shape.geom.Rectangle(
      item_anchor.x,
      item_anchor.y,
      item_opposite.x - item_anchor.x,
      item_opposite.y - item_anchor.y
    );

    return new annotorious.shape.Shape(annotorious.shape.ShapeType.RECTANGLE, rect);
  } else {
    return undefined;
  }
}

/**
 * Selector API method: returns the bounds of the selected shape, in viewport (= pixel) coordinates.
 * @returns {Object} the shape viewport bounds
 */
annotorious.plugins.selection.RectDragSelector.prototype.getViewportBounds = function() {
  var right, left;
  if (this._opposite.x > this._anchor.x) {
    right = this._opposite.x;
    left = this._anchor.x;
  } else {
    right = this._anchor.x;
    left = this._opposite.x;
  }

  var top, bottom;
  if (this._opposite.y > this._anchor.y) {
    top = this._anchor.y;
    bottom = this._opposite.y;
  } else {
    top = this._opposite.y;
    bottom = this._anchor.y;
  }

  return {top: top, right: right, bottom: bottom, left: left};
}

/**
 * TODO not sure if this is really the best way/architecture to handle viewer shape drawing
 * @param {Object} g2d graphics context
 * @param {annotorious.shape.Shape} shape the shape to draw
 * @param {boolean=} highlight if true, shape will be drawn highlighted
 */
annotorious.plugins.selection.RectDragSelector.prototype.drawShape = function(g2d, shape, highlight) {
  if (shape.type == annotorious.shape.ShapeType.RECTANGLE) {
    var color, lineWidth;
    if (highlight) {
      color = '#fff000';
      lineWidth = 1.2;
    } else {
      color = '#ffffff';
      lineWidth = 1;
    }

    var geom = shape.geometry;
    g2d.strokeStyle = '#000000';
    g2d.lineWidth = lineWidth;
    g2d.strokeRect(geom.x + 0.5, geom.y + 0.5, geom.width + 1, geom.height + 1);
    g2d.strokeStyle = color;
    g2d.strokeRect(geom.x + 1.5, geom.y + 1.5, geom.width - 1, geom.height - 1);
  }
}
<|endoftext|>


<commit_before>const send = require( "./actions" );
const clh = require( "../db/ModelHelpers/chatlogHelpers" );
const uh = require( "../db/ModelHelpers/userHelpers" );
const tdh = require( "../db/ModelHelpers/todoHelpers" );
const actions = require( "../helpers/actions" );

const sendTextMessage = send.sendTextMessage;

const ifTextIncludeTerm = ( text, term ) => {
    const messageText = text.toLowerCase().trim();
    return !!messageText.includes( term );
};

const receivedMessage = ( event ) => {
    const senderID = event.sender.id;
    const recipientID = event.recipient.id;
    const timeOfMessage = event.timestamp;
    const message = event.message;

    console.log( "Received message for user %d and page %d at %d with message:",
    senderID, recipientID, timeOfMessage );

    const messageText = message.text;
    const messageAttachments = message.attachments;
    const messageID = message.mid;
    const isEcho = event.message.is_echo;

    actions.createGetStartedButton( senderID );

    const saveUserIfNew = userID => uh.ifUserIDExist( userID )
        .then( ( bool ) => {
            if ( !bool ) {
                return uh.saveUser( userID );
            }
            return true;
        } )
        .catch( ( err ) => {
            console.log( `Error in saving if user is new: ${ err }` );
        } );

    const saveChatlogIfNew = () => clh.ifMessageIDExist( messageID )
        .then( ( bool ) => {
            if ( !bool ) {
                return clh.saveChatlog( senderID, recipientID, timeOfMessage, messageText, messageID );
            }
            return true;
        } )
        .catch( ( err ) => {
            console.log( `Erorr in saving if message is new: ${ err }` );
        } );

    // TODO: Ignore messages sent by the bot (is_echo)
    if ( messageText ) {
        // Store received message to database
        saveUserIfNew( senderID )
        .then( () => saveUserIfNew( recipientID ) )
        .then( () => {
            // Database doesn't store messages sent by the bot
            if ( !isEcho ) {
                saveChatlogIfNew();
            }
        } );

        /**
         * Check if messageText is for ADDing or LISTing onto the todo list
         */
        if ( ifTextIncludeTerm( messageText, "add " ) ) {
            tdh.saveTodo( messageText, timeOfMessage );
        } else if ( ifTextIncludeTerm( messageText, "list" ) ) {
            return tdh.getAllTodo()
            .then( ( list ) => {
                const subject = "This is your grocery list: \n";
                const todo = subject.concat( "- ", list.join( "\n- " ) );
                sendTextMessage( senderID, todo );
            } )
            .catch( ( err ) => {
                console.log( `Error in parsing todo list: ${ err }` );
            } );
        } else {
            console.log( "Message text doesn't contain add or list." );
        }

        switch ( messageText ) {
        default:
            sendTextMessage( senderID, "Your message is received." );
        }
    } else if ( messageAttachments ) {
        sendTextMessage( senderID, "Thanks for your message! We'll let you know when we support non-text content." );
    }
};

const receivedPostback = ( event ) => {
    const senderID = event.sender.id;
    const recipientID = event.recipient.id;
    const timeOfPostback = event.timestamp;
    const payload = event.postback.payload;

    console.log( "Received postback for user %d and page %d with payload '%s' " +
    "at %d", senderID, recipientID, payload, timeOfPostback );

    actions.createGetStartedButton( senderID );

    if ( payload !== "GET_STARTED_PAYLOAD" ) {
        sendTextMessage( senderID, "Postback called" );
    } else {
        // TODO: Use Facebook's in-built setGreetingText
        sendTextMessage( senderID, "Hey, ask me anything!" );
    }
};

module.exports = {
    receivedMessage,
    receivedPostback,
};
<commit_msg>(feat) Respond with appropriate messages on various input<commit_after>const send = require( "./actions" );
const clh = require( "../db/ModelHelpers/chatlogHelpers" );
const uh = require( "../db/ModelHelpers/userHelpers" );
const tdh = require( "../db/ModelHelpers/todoHelpers" );
const actions = require( "../helpers/actions" );

const sendTextMessage = send.sendTextMessage;

const ifTextIncludeTerm = ( text, term ) => {
    const messageText = text.toLowerCase().trim();
    return !!messageText.includes( term );
};

const receivedMessage = ( event ) => {
    const senderID = event.sender.id;
    const recipientID = event.recipient.id;
    const timeOfMessage = event.timestamp;
    const message = event.message;

    console.log( "Received message for user %d and page %d at %d with message:",
    senderID, recipientID, timeOfMessage );

    const messageText = message.text;
    const messageAttachments = message.attachments;
    const messageID = message.mid;
    const isEcho = event.message.is_echo;

    actions.createGetStartedButton( senderID );

    const saveUserIfNew = userID => uh.ifUserIDExist( userID )
        .then( ( bool ) => {
            if ( !bool ) {
                return uh.saveUser( userID );
            }
            return true;
        } )
        .catch( ( err ) => {
            console.log( `Error in saving if user is new: ${ err }` );
        } );

    const saveChatlogIfNew = () => clh.ifMessageIDExist( messageID )
        .then( ( bool ) => {
            if ( !bool ) {
                return clh.saveChatlog( senderID, recipientID, timeOfMessage, messageText, messageID );
            }
            return true;
        } )
        .catch( ( err ) => {
            console.log( `Erorr in saving if message is new: ${ err }` );
        } );

    // TODO: Ignore messages sent by the bot (is_echo)
    if ( messageText ) {
        // Store received message to database
        saveUserIfNew( senderID )
        .then( () => saveUserIfNew( recipientID ) )
        .then( () => {
            // Database doesn't store messages sent by the bot
            if ( !isEcho && messageText !== "list" ) {
                saveChatlogIfNew();
            }
        } );

        /**
         * Check if messageText is for ADDing or LISTing onto the todo list
         */
        if ( ifTextIncludeTerm( messageText, "add " ) ) {
            tdh.saveTodo( messageText, timeOfMessage );
            sendTextMessage( senderID, "Your item is added to the grocery list." );
        } else if ( ifTextIncludeTerm( messageText, "list" ) ) {
            return tdh.getAllTodo()
            .then( ( list ) => {
                const subject = "This is your grocery list: \n";
                const todo = subject.concat( "- ", list.join( "\n- " ) );
                sendTextMessage( senderID, todo );
            } )
            .catch( ( err ) => {
                console.log( `Error in parsing todo list: ${ err }` );
            } );
        } else {
            sendTextMessage( senderID, "Thanks for your message. Try adding groceries and then list them out." );
        }
    } else if ( messageAttachments ) {
        sendTextMessage( senderID, "Thanks for your message! We'll let you know when we support non-text content." );
    }
};

const receivedPostback = ( event ) => {
    const senderID = event.sender.id;
    const recipientID = event.recipient.id;
    const timeOfPostback = event.timestamp;
    const payload = event.postback.payload;

    console.log( "Received postback for user %d and page %d with payload '%s' " +
    "at %d", senderID, recipientID, payload, timeOfPostback );

    actions.createGetStartedButton( senderID );

    if ( payload !== "GET_STARTED_PAYLOAD" ) {
        sendTextMessage( senderID, "Postback called" );
    } else {
        // TODO: Use Facebook's in-built setGreetingText
        sendTextMessage( senderID, "Hey, ask me anything!" );
    }
};

module.exports = {
    receivedMessage,
    receivedPostback,
};
<|endoftext|>