Changeset - 77f13ea8ad3b
[Not reviewed]
default
0 2 0
Thomas De Schampheleire - 8 years ago 2017-10-25 09:10:30
thomas.de.schampheleire@gmail.com
Grafted from: a77373ff8f7b
style: mark failed comment submissions with red panel heading

Make it more obvious to the user that a comment submission failed: mark the
panel of the failed comment as "panel-danger" so the color of the comment panel
heading changes to red.

Previously, only the user and comment text would fade a bit.
2 files changed with 2 insertions and 6 deletions:
0 comments (0 inline, 0 general)
kallithea/front-end/style.less
Show inline comments
 
@@ -183,772 +183,768 @@ table.dataTable .dt_repo_pending {
 
.expand_commit .icon-align-left {
 
  cursor: pointer;
 
  color: #999;
 
}
 

	
 
/* don't break author, date and comment cells into multiple lines in changeset table */
 
table.changesets {
 
  .author,
 
  .date,
 
  .comments {
 
    white-space: nowrap;
 
  }
 
}
 

	
 
/* textareas should be at least 100px high and 400px wide */
 
textarea.form-control {
 
  font-family: @font-family-monospace;
 
  min-height: 100px;
 
  min-width: 400px;
 
}
 

	
 
/* add some space between the code-browser icons and the file names */
 
.browser-dir > i[class^='icon-'],
 
.submodule-dir > i[class^='icon-'],
 
.browser-file > i[class^='icon-'] {
 
  padding-right: 0.3em;
 
}
 

	
 
div.panel-primary {
 
  border: none;
 
}
 

	
 
/* no extra vertical margin */
 
#content div.panel ul.pagination {
 
  margin: 0;
 
}
 

	
 
/* remove margin below footer */
 
.navbar.footer {
 
  margin-bottom: 0;
 
}
 

	
 
.user-menu {
 
  padding: 0 !important;
 
}
 
#quick_login {
 
  width: 360px;
 
  margin-top: 15px;
 
  min-height: 110px;
 
}
 
#quick_login input#username,
 
#quick_login input#password {
 
  display: block;
 
  margin: 5px 0 10px;
 
}
 
#quick_login .password_forgotten a,
 
#quick_login .register a {
 
  padding: 0 !important;
 
  line-height: 25px !important;
 
  float: left;
 
  clear: both;
 
}
 
#quick_login .submit {
 
  float: right;
 
}
 
#quick_login .submit input#sign_in {
 
  margin-top: 5px;
 
}
 
#quick_login > .pull-left {
 
  width: 170px;
 
}
 
#quick_login > .pull-right {
 
  width: 140px;
 
}
 
#quick_login .full_name {
 
  font-weight: bold;
 
  padding: 3px;
 
}
 
#quick_login .email {
 
  padding: 3px 3px 3px 0;
 
}
 
#quick_login :not(input) {
 
  color: @kallithea-theme-inverse-color;
 
  padding-bottom: 3px;
 
}
 

	
 
#journal .journal_user {
 
  color: #747474;
 
  font-size: 14px;
 
  font-weight: bold;
 
  height: 30px;
 
}
 
#journal .journal_user.deleted {
 
  color: #747474;
 
  font-size: 14px;
 
  font-weight: normal;
 
  height: 30px;
 
  font-style: italic;
 
}
 
#journal .journal_icon {
 
  clear: both;
 
  float: left;
 
  padding-right: 4px;
 
  padding-top: 3px;
 
}
 
#journal .journal_action {
 
  padding-top: 4px;
 
  min-height: 2px;
 
  float: left;
 
}
 
#journal .journal_action_params {
 
  clear: left;
 
  padding-left: 22px;
 
}
 
#journal .date {
 
  clear: both;
 
  color: #777777;
 
  font-size: 11px;
 
  padding-left: 22px;
 
}
 
#journal .journal_repo_name {
 
  font-weight: bold;
 
  font-size: 1.1em;
 
}
 
#journal .compare_view {
 
  padding: 5px 0px 5px 0px;
 
  width: 95px;
 
}
 
.trending_language_tbl,
 
.trending_language_tbl td {
 
  border: 0 !important;
 
  margin: 0 !important;
 
  padding: 0 !important;
 
}
 
.trending_language_tbl,
 
.trending_language_tbl tr {
 
  border-spacing: 1px;
 
}
 
h3.files_location {
 
  font-size: 1.8em;
 
  font-weight: 700;
 
  border-bottom: none !important;
 
  margin: 10px 0 !important;
 
}
 
.file_history {
 
  padding-top: 10px;
 
  font-size: 16px;
 
}
 
.file_author {
 
  float: left;
 
}
 
.file_author .item {
 
  float: left;
 
  padding: 5px;
 
  color: #888;
 
}
 
table#updaterevs-table tr.mergerow,
 
table#updaterevs-table tr.out-of-range,
 
table#changesets tr.mergerow,
 
table#changesets tr.out-of-range {
 
  opacity: 0.6;
 
}
 
.issue-tracker-link {
 
  color: #3F6F9F;
 
  font-weight: bold !important;
 
}
 
/* changeset statuses (must be the same name as the status) */
 
.changeset-status-not_reviewed {
 
  color: #bababa;
 
}
 
.changeset-status-approved {
 
  color: #81ba51;
 
}
 
.changeset-status-rejected {
 
  color: #d06060;
 
}
 
.changeset-status-under_review {
 
  color: #ffc71e;
 
}
 

	
 
#repo_size {
 
  display: block;
 
  margin-top: 4px;
 
  color: #666;
 
  float: right;
 
}
 
.currently_following {
 
  padding-left: 10px;
 
  padding-bottom: 5px;
 
}
 
#switch_repos {
 
  position: absolute;
 
  height: 25px;
 
  z-index: 1;
 
}
 
#switch_repos select {
 
  min-width: 150px;
 
  max-height: 250px;
 
  z-index: 1;
 
}
 
table#permissions_manage span.private_repo_msg {
 
  font-size: 0.8em;
 
  opacity: 0.6;
 
}
 
table#permissions_manage td.private_repo_msg {
 
  font-size: 0.8em;
 
}
 
table#permissions_manage tr#add_perm_input td {
 
  vertical-align: middle;
 
}
 
div.gravatar {
 
  float: left;
 
  background-color: #FFF;
 
  margin-right: 0.7em;
 
  padding: 1px 1px 1px 1px;
 
  line-height: 0;
 
  border-radius: 3px;
 
}
 
div.gravatar img {
 
  border-radius: 2px;
 
}
 
.panel-body.settings .nav-pills > :not(.active) > a {
 
  color: inherit;
 
}
 
.panel-body.no-padding {
 
  padding: 0;
 
}
 
.panel-body ~ .panel-body {
 
  padding-top: 0;
 
}
 
.panel-body.no-padding ~ .panel-body {
 
  padding-top: 15px;
 
}
 
.panel-body > :last-child {
 
  margin-bottom: 0;
 
}
 
.panel-body.settings .text-muted {
 
  margin: 5px 0;
 
}
 
ins,
 
div.options a:hover {
 
  text-decoration: none;
 
}
 
img,
 
nav.navbar #quick li a:hover span.normal,
 
#clone_url,
 
#clone_url_id {
 
  border: none;
 
}
 
img.icon,
 
.right .merge img {
 
  vertical-align: bottom;
 
}
 
#content div.panel div.panel-heading ul.links,
 
#content div.panel div.message div.dismiss {
 
  float: right;
 
  margin: 0;
 
  padding: 0;
 
}
 
nav.navbar #home,
 
#content div.panel ul.left,
 
#content div.panel ol.left,
 
div#commit_history,
 
div#legend_data,
 
div#legend_container,
 
div#legend_choices {
 
  float: left;
 
}
 

	
 
/* set size for statistics charts */
 
#commit_history {
 
  width: 450px;
 
  height: 300px;
 
}
 
#overview {
 
  clear: both;
 
  width: 450px;
 
  height: 100px;
 
}
 

	
 
#content #left #menu ul.closed,
 
#content #left #menu li ul.collapsed {
 
  display: none;
 
}
 
#content #left #menu ul.opened,
 
#content #left #menu li ul.expanded {
 
  display: block !important;
 
}
 

	
 
#content div.panel ol.lower-roman,
 
#content div.panel ol.upper-roman,
 
#content div.panel ol.lower-alpha,
 
#content div.panel ol.upper-alpha,
 
#content div.panel ol.decimal {
 
  margin: 10px 24px 10px 44px;
 
}
 

	
 
div.form div.form-group div.button input,
 
#content div.panel div.form div.buttons input,
 
div.form div.buttons input,
 
#content div.panel div.action div.button input {
 
  font-size: 11px;
 
  font-weight: 700;
 
  margin: 0;
 
}
 
div.form div.form-group div.highlight,
 
#content div.panel div.form div.buttons div.highlight {
 
  display: inline;
 
}
 
#content div.panel table td.user,
 
#content div.panel table td.address {
 
  width: 10%;
 
  text-align: center;
 
}
 
#content div.panel div.action div.button {
 
  text-align: right;
 
  margin: 6px 0 0;
 
  padding: 0;
 
}
 
.ac .match {
 
  font-weight: 700;
 
  padding-top: 5px;
 
  padding-bottom: 5px;
 
}
 
.q_filter_box {
 
  border-radius: 4px;
 
  border: 0 none;
 
  margin-bottom: -4px;
 
  margin-top: -4px;
 
  padding-left: 3px;
 
}
 
#node_filter {
 
  border: 0px solid #545454;
 
  color: #AAAAAA;
 
  padding-left: 3px;
 
}
 
/** comment main **/
 
.comment .panel,
 
.comment-inline-form {
 
  max-width: 978px;
 
}
 
.comment .panel-body {
 
  background-color: #FAFAFA;
 
}
 
.comments-number {
 
  padding: 10px 0;
 
  color: #666;
 
}
 
.automatic-comment {
 
  font-style: italic;
 
}
 
/** comment form **/
 
.status-block {
 
  margin: 5px;
 
  clear: both;
 
}
 
.panel-heading .pull-left input[type=checkbox],
 
.panel-heading .pull-right input[type=checkbox] {
 
  position: relative;
 
  top: 4px;
 
  margin: -10px 2px 0;
 
}
 
/** indent actual inline comments - not general comments **/
 
td.inline-comments {
 
  padding: @kallithea-panel-margin;
 
}
 
.inline-comments .comments-number {
 
  padding: 0px 0px 10px 0px;
 
}
 
.comment-inline-well {
 
  margin-bottom: @kallithea-panel-margin;
 
}
 
input.status_change_checkbox,
 
input.status_change_radio {
 
  margin: 0 0 5px 15px;
 
}
 
@keyframes animated-comment-background {
 
  0% {
 
    background-position: 0 0;
 
  }
 
  100% {
 
    background-position: 20px 0;
 
  }
 
}
 
.comment-preview.failed .user,
 
.comment-preview.failed .panel-body {
 
  color: #666;
 
}
 
.comment-preview .comment-submission-status {
 
  float: right;
 
}
 
.comment-preview .comment-submission-status .btn-group {
 
  margin-left: 10px;
 
}
 
.comment-preview.submitting .panel-body {
 
  background-image: linear-gradient(-45deg, #FAFAFA, #FAFAFA 25%, #FFF 25%, #FFF 50%, #FAFAFA 50%, #FAFAFA 75%, #FFF 75%, #FFF 100%);
 
  background-size: 20px 20px;
 
  animation: animated-comment-background 0.4s linear infinite;
 
}
 
/****
 
PULL REQUESTS
 
*****/
 
div.pr-details-title.closed {
 
  color: #555;
 
  background: #eee;
 
}
 
div.pr {
 
  margin: 0px 15px;
 
  padding: 4px 4px;
 
}
 
tr.pr-closed td {
 
  background-color: #eee !important;
 
  color: #555 !important;
 
}
 
span.pr-closed-tag {
 
  margin-bottom: 1px;
 
  margin-right: 1px;
 
  padding: 1px 3px;
 
  font-size: 10px;
 
  color: @kallithea-theme-main-color;
 
  white-space: nowrap;
 
  border-radius: 4px;
 
  border: 1px solid #d9e8f8;
 
  line-height: 1.5em;
 
}
 
#s2id_org_ref,
 
#s2id_other_ref,
 
#s2id_org_repo,
 
#s2id_other_repo {
 
  min-width: 150px;
 
  margin: 5px;
 
}
 
#pr-summary > .pr-not-edit {
 
  min-height: 50px !important;
 
}
 
/* make 'next iteration' changeset table smaller and scrollable */
 
#pr-summary #updaterevs {
 
  max-height: 200px;
 
  overflow-y: auto;
 
  overflow-x: hidden;
 
}
 

	
 
/****
 
  PERMS
 
*****/
 
.perm-gravatar-ac {
 
  vertical-align: middle;
 
  padding: 2px;
 
  width: 14px;
 
  height: 14px;
 
}
 

	
 
/* avoid gaps between the navbar and browser */
 
.navbar.mainmenu {
 
  border-top-left-radius: 0;
 
  border-top-right-radius: 0;
 
}
 
.navbar.footer {
 
  border-bottom-left-radius: 0;
 
  border-bottom-right-radius: 0;
 
}
 

	
 
/* show some context of link targets - but only works when the link target
 
   can be extended with any visual difference */
 
div.comment:target:before {
 
  display: block;
 
  height: 100px;
 
  margin: -100px 0 0;
 
  content: "";
 
}
 
div.comment:target > .panel {
 
  border: solid 2px #ee0 !important;
 
}
 
.lineno:target a {
 
  border: solid 2px #ee0 !important;
 
  margin: -2px;
 
}
 
.btn-image-diff-show,
 
.btn-image-diff-swap {
 
  margin: 5px;
 
}
 
.img-diff {
 
  max-width: 45%;
 
  height: auto;
 
  margin: 5px;
 
  /* http://lea.verou.me/demos/css3-patterns.html */
 
  background-image: linear-gradient(45deg, #888 25%, transparent 25%, transparent), linear-gradient(-45deg, #888 25%, transparent 25%, transparent), linear-gradient(45deg, transparent 75%, #888 75%), linear-gradient(-45deg, transparent 75%, #888 75%);
 
  background-size: 10px 10px;
 
  background-color: #999;
 
}
 
.img-preview {
 
  max-width: 100%;
 
  height: auto;
 
  margin: 5px;
 
}
 
div.comment-prev-next-links div.prev-comment,
 
div.comment-prev-next-links div.next-comment {
 
  display: inline-block;
 
  min-width: 150px;
 
  margin: 3px 15px;
 
}
 
#comments-general-comments div.comment-prev-next-links div.prev-comment,
 
#comments-general-comments div.comment-prev-next-links div.next-comment {
 
  margin-left: 0;
 
}
 

	
 
/* changelog graph */
 
#graph_nodes,
 
#updaterevs-graph {
 
  .make-xs-column(1);
 
  height: 0;
 
}
 
#graph_content,
 
#graph_content_pr,
 
#updaterevs-table {
 
  .make-xs-column-offset(1);
 
  .make-xs-column(11);
 
  padding: 0;
 
}
 

	
 
/* use bootstrap grid columns for centered columns */
 
.centered-column {
 
  .make-sm-column-offset(3);
 
  .make-sm-column(6);
 
  .form {
 
    .form-horizontal;
 
    .form-group > label {
 
      .make-sm-column(4);
 
    }
 
    .form-group > div {
 
      .make-sm-column(8);
 
    }
 
    .form-group > div:first-child { /* in case there is no label */
 
      .make-sm-column-offset(4);
 
      .make-sm-column(8);
 
    }
 
  }
 
}
 

	
 
/* use columns and form-horizontal for settings pages ... on wide screens */
 
@media (min-width: @screen-sm-min) {
 
  .settings {
 
    max-width: @container-md;
 
    > ul.nav-stacked {
 
      .make-sm-column(2);
 
      max-width: (@container-md/12)*2;
 
    }
 
    > div {
 
      .make-sm-column(10);
 
      max-width: (@container-md/12)*10;
 
    }
 
    .form {
 
      .form-horizontal;
 
    }
 
    .form-group {
 
      .clearfix;
 
      > label {
 
        .make-xs-column(3);
 
        overflow: hidden;
 
        text-overflow: ellipsis;
 
        input {
 
          width: 100%;
 
        }
 
      }
 
      > div {
 
        .make-xs-column(9);
 
      }
 
      .buttons {
 
        .make-xs-column-offset(3);
 
      }
 
    }
 
  }
 
}
 

	
 
/* use columns and form-horizontal for summary page */
 
#summary {
 
  max-width: @container-md;
 
  .form-horizontal;
 
  .make-sm-column(10);
 
  padding-left: 0;
 
  .form-group > label {
 
    .make-sm-column(2);
 
  }
 
  .form-group > div {
 
    .make-sm-column(10);
 
  }
 
}
 
#summary-menu-stats {
 
  .make-sm-column(2);
 
  padding-right: 0;
 
}
 

	
 
/* use columns and form-horizontal for pull request page */
 
.pr-box {
 
  .make-sm-column(9);
 
  padding-left: 0;
 
  max-width: @container-md;
 
  #pr-summary {
 
    .form-horizontal;
 
    .form-group > label {
 
      .make-sm-column(3);
 
    }
 
    .form-group > div {
 
      .make-sm-column(9);
 
    }
 
    .form-group > .buttons {
 
      .make-sm-column-offset(3);
 
      .make-sm-column(9);
 
    }
 
  }
 
}
 
.pr-reviewers-box {
 
  .make-sm-column(3);
 
  padding-right: 0;
 
}
 

	
 
/* repo table icons */
 
#repos_list_wrap_wrapper {
 
  /* make icon-folder and repotag the same width */
 
  .icon-folder:before {
 
    margin: 0; // default margin would otherwise add to the total width
 
    width: 24px;
 
    text-align: left;
 
  }
 
  .label-repo {
 
    display: inline-block;
 
    width: 24px;
 
  }
 
}
 

	
 
/* changelog table columns */
 
.table#changesets {
 
  table-layout: fixed;
 
  td {
 
    overflow: hidden;
 
    text-overflow: ellipsis;
 
    white-space: nowrap;
 
    vertical-align: baseline;
 
    &:last-child {
 
      padding-right: 0;
 
    }
 
  }
 
  .checkbox-column {
 
    width: 20px;
 
    padding: 0;
 
    /* the optional second checkbox will be inline-block but should wrap to a new line */
 
    white-space: normal;
 
    > input[type=checkbox] {
 
      margin-top: inherit;
 
      vertical-align: text-bottom;
 
    }
 
  }
 
  .changeset-logical-index {
 
    color: @gray-light;
 
    font-style: italic;
 
    font-size: 85%;
 
    text-align: right;
 
    overflow: visible;
 
  }
 
  .changeset-logical-index,
 
  .expand_commit,
 
  .status {
 
    width: 28px;
 
  }
 
  .author {
 
    width: 200px;
 
    @media (max-width: @screen-sm-max) {
 
      width: 120px;
 
    }
 
    @media (max-width: @screen-xs-max) {
 
      width: 20px;
 
      /* keep gravatar but hide name on tiny screens to give important columns more room */
 
      span {
 
        .hidden;
 
      }
 
    }
 
    > .icon-user::before {
 
      margin: 0;
 
    }
 
  }
 
  .hash {
 
    .small;
 
    width: 110px;
 
    @media (max-width: @screen-xs-max) {
 
      width: 48px;
 
    }
 
  }
 
  .date {
 
    .small;
 
    width: 100px;
 
  }
 
  /* hide on small screens to give important columns more room */
 
  .status,
 
  .expand_commit,
 
  .comments,
 
  .extra-container {
 
    .hidden-xs;
 
  }
 
  .mid > .log-container {
 
    position: relative;
 
    overflow: hidden;
 
    > .extra-container {
 
      position: absolute;
 
      top: 0;
 
      right: 0;
 
      background: white;
 
      box-shadow: -10px 0px 10px 0px white;
 
    }
 
  }
 
}
 

	
 
/* undo Bootstrap chrome/webkit blue outline on focus in navbar */
 
.navbar-inverse .navbar-nav > li > a:focus {
 
  outline: 0;
 
}
 

	
 
/* use same badge coloring in navbar inverse as in panel-heading */
 
.navbar-inverse {
 
  .badge {
 
    color: @navbar-inverse-bg;
 
    background-color: @navbar-inverse-color;
 
  }
 
}
 

	
 
/* pygments style */
 
div.search-code-body pre .match {
 
  background-color: @highlight-color;
 
}
 
div.search-code-body pre .break {
 
  background-color: @highlight-line-color;
 
  width: 100%;
 
  color: #747474;
 
  display: block;
 
}
 
div.annotatediv {
 
  margin-left: 2px;
 
  margin-right: 4px;
 
}
 
.code-highlight {
 
  border-left: 1px solid #ccc;
 
}
 
.code-highlight pre,
 
.annotatediv pre,
 
.linenodiv pre {
 
  padding: 5px 2px 0px 5px;
 
  margin: 0;
 
}
 
.code-highlight pre div:target {
 
  background-color: #FFFFBE !important;
 
}
 
.linenos a { text-decoration: none; }
 

	
 
/* Stylesheets for the context bar */
 
#quick_login > .pull-right .list-group-item {
 
  background-color: @kallithea-theme-main-color;
 
  border: 0;
 
}
 
#content .follow .show-following,
 
#content .following .show-follow {
 
  display: none;
 
}
 

	
 
nav.navbar #quick > li > a,
 
#context-pages > ul > li > a {
 
  height: @navbar-height;
 
}
 

	
 
/* align with panel-heading */
 
nav.navbar#context-bar > .container-fluid {
 
  padding-left: 15px;
 
}
 

	
kallithea/public/js/base.js
Show inline comments
 
@@ -286,783 +286,783 @@ var pyroutes = (function() {
 
            var result = route_name;
 
            if (typeof(params) != 'object'){
 
                params = {};
 
            }
 
            if (matchlist.hasOwnProperty(route_name)) {
 
                var route = matchlist[route_name];
 
                // param substitution
 
                for(var i=0; i < route[1].length; i++) {
 
                   if (!params.hasOwnProperty(route[1][i]))
 
                        throw new Error(route[1][i] + ' missing in "' + route_name + '" route generation');
 
                }
 
                result = sprintf(route[0], params);
 

	
 
                var ret = [];
 
                //extra params => GET
 
                for(var param in params){
 
                    if (route[1].indexOf(param) == -1){
 
                        ret.push(encodeURIComponent(param) + "=" + encodeURIComponent(params[param]));
 
                    }
 
                }
 
                var _parts = ret.join("&");
 
                if(_parts){
 
                    result = result +'?'+ _parts
 
                }
 
            }
 

	
 
            return result;
 
        },
 
        'register': function(route_name, route_tmpl, req_params) {
 
            if (typeof(req_params) != 'object') {
 
                req_params = [];
 
            }
 
            var keys = [];
 
            for (var i=0; i < req_params.length; i++) {
 
                keys.push(req_params[i]);
 
            }
 
            matchlist[route_name] = [
 
                unescape(route_tmpl),
 
                keys
 
            ]
 
        },
 
        '_routes': function(){
 
            return matchlist;
 
        }
 
    }
 
})();
 

	
 

	
 
/**
 
 * turns objects into GET query string
 
 */
 
function _toQueryString(o) {
 
    if(typeof o !== 'object') {
 
        return false;
 
    }
 
    var _p, _qs = [];
 
    for(_p in o) {
 
        _qs.push(encodeURIComponent(_p) + '=' + encodeURIComponent(o[_p]));
 
    }
 
    return _qs.join('&');
 
}
 

	
 
/**
 
 * Load HTML into DOM using Ajax
 
 *
 
 * @param $target: load html async and place it (or an error message) here
 
 * @param success: success callback function
 
 * @param args: query parameters to pass to url
 
 */
 
function asynchtml(url, $target, success, args){
 
    if(args===undefined){
 
        args=null;
 
    }
 
    $target.html(_TM['Loading ...']).css('opacity','0.3');
 

	
 
    return $.ajax({url: url, data: args, headers: {'X-PARTIAL-XHR': '1'}, cache: false, dataType: 'html'})
 
        .done(function(html) {
 
                $target.html(html);
 
                $target.css('opacity','1.0');
 
                //execute the given original callback
 
                if (success !== undefined && success) {
 
                    success();
 
                }
 
            })
 
        .fail(function(jqXHR, textStatus) {
 
                if (textStatus == "abort")
 
                    return;
 
                $target.html('<span class="bg-danger">ERROR: {0}</span>'.format(textStatus));
 
                $target.css('opacity','1.0');
 
            })
 
        ;
 
}
 

	
 
function ajaxGET(url, success, failure) {
 
    if(failure === undefined) {
 
        failure = function(jqXHR, textStatus) {
 
                if (textStatus != "abort")
 
                    alert("Ajax GET error: " + textStatus);
 
            };
 
    }
 
    return $.ajax({url: url, headers: {'X-PARTIAL-XHR': '1'}, cache: false})
 
        .done(success)
 
        .fail(failure);
 
}
 

	
 
function ajaxPOST(url, postData, success, failure) {
 
    postData['_session_csrf_secret_token'] = _session_csrf_secret_token;
 
    if(failure === undefined) {
 
        failure = function(jqXHR, textStatus) {
 
                if (textStatus != "abort")
 
                    alert("Error posting to server: " + textStatus);
 
            };
 
    }
 
    return $.ajax({url: url, data: _toQueryString(postData), type: 'POST', headers: {'X-PARTIAL-XHR': '1'}, cache: false})
 
        .done(success)
 
        .fail(failure);
 
}
 

	
 

	
 
/**
 
 * activate .show_more links
 
 * the .show_more must have an id that is the the id of an element to hide prefixed with _
 
 * the parentnode will be displayed
 
 */
 
function show_more_event(){
 
    $('.show_more').click(function(e){
 
        var el = e.currentTarget;
 
        $('#' + el.id.substring(1)).hide();
 
        $(el.parentNode).show();
 
    });
 
}
 

	
 

	
 
function _onSuccessFollow(target){
 
    var $target = $(target);
 
    var $f_cnt = $('#current_followers_count');
 
    if ($target.hasClass('follow')) {
 
        $target.removeClass('follow').addClass('following');
 
        $target.prop('title', _TM['Stop following this repository']);
 
        if ($f_cnt.html()) {
 
            const cnt = Number($f_cnt.html())+1;
 
            $f_cnt.html(cnt);
 
        }
 
    } else {
 
        $target.removeClass('following').addClass('follow');
 
        $target.prop('title', _TM['Start following this repository']);
 
        if ($f_cnt.html()) {
 
            const cnt = Number($f_cnt.html())-1;
 
            $f_cnt.html(cnt);
 
        }
 
    }
 
}
 

	
 
function toggleFollowingRepo(target, follows_repository_id){
 
    var args = {
 
        'follows_repository_id': follows_repository_id,
 
        '_session_csrf_secret_token': _session_csrf_secret_token
 
    }
 
    $.post(TOGGLE_FOLLOW_URL, args, function(){
 
            _onSuccessFollow(target);
 
        });
 
    return false;
 
}
 

	
 
function showRepoSize(target, repo_name){
 
    var args = '_session_csrf_secret_token=' + _session_csrf_secret_token;
 

	
 
    if(!$("#" + target).hasClass('loaded')){
 
        $("#" + target).html(_TM['Loading ...']);
 
        var url = pyroutes.url('repo_size', {"repo_name":repo_name});
 
        $.post(url, args, function(data) {
 
            $("#" + target).html(data);
 
            $("#" + target).addClass('loaded');
 
        });
 
    }
 
    return false;
 
}
 

	
 
/**
 
 * load tooltips dynamically based on data attributes, used for .lazy-cs changeset links
 
 */
 
function get_changeset_tooltip() {
 
    var $target = $(this);
 
    var tooltip = $target.data('tooltip');
 
    if (!tooltip) {
 
        var raw_id = $target.data('raw_id');
 
        var repo_name = $target.data('repo_name');
 
        var url = pyroutes.url('changeset_info', {"repo_name": repo_name, "revision": raw_id});
 

	
 
        $.ajax(url, {
 
            async: false,
 
            success: function(data) {
 
                tooltip = data["message"];
 
            }
 
        });
 
        $target.data('tooltip', tooltip);
 
    }
 
    return tooltip;
 
}
 

	
 
/**
 
 * activate tooltips and popups
 
 */
 
function tooltip_activate(){
 
    function placement(p, e){
 
        if(e.getBoundingClientRect().top > 2*$(window).height()/3){
 
            return 'top';
 
        }else{
 
            return 'bottom';
 
        }
 
    }
 
    $(document).ready(function(){
 
        $('[data-toggle="tooltip"]').tooltip({
 
            container: 'body',
 
            placement: placement
 
        });
 
        $('[data-toggle="popover"]').popover({
 
            html: true,
 
            container: 'body',
 
            placement: placement,
 
            trigger: 'hover',
 
            template: '<div class="popover cs-popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
 
        });
 
        $('.lazy-cs').tooltip({
 
            title: get_changeset_tooltip,
 
            placement: placement
 
        });
 
    });
 
}
 

	
 

	
 
/**
 
 * Comment handling
 
 */
 

	
 
// move comments to their right location, inside new trs
 
function move_comments($anchorcomments) {
 
    $anchorcomments.each(function(i, anchorcomment) {
 
        var $anchorcomment = $(anchorcomment);
 
        var target_id = $anchorcomment.data('target-id');
 
        var $comment_div = _get_add_comment_div(target_id);
 
        var f_path = $anchorcomment.data('f_path');
 
        var line_no = $anchorcomment.data('line_no');
 
        if ($comment_div[0]) {
 
            $comment_div.append($anchorcomment.children());
 
            if (f_path && line_no) {
 
                _comment_div_append_add($comment_div, f_path, line_no);
 
            } else {
 
                _comment_div_append_form($comment_div, f_path, line_no);
 
            }
 
        } else {
 
            $anchorcomment.before("<span class='bg-warning'>Comment to {0} line {1} which is outside the diff context:</span>".format(f_path || '?', line_no || '?'));
 
        }
 
    });
 
    linkInlineComments($('.firstlink'), $('.comment:first-child'));
 
}
 

	
 
// comment bubble was clicked - insert new tr and show form
 
function show_comment_form($bubble) {
 
    var children = $bubble.closest('tr.line').children('[id]');
 
    var line_td_id = children[children.length - 1].id;
 
    var $comment_div = _get_add_comment_div(line_td_id);
 
    var f_path = $bubble.closest('[data-f_path]').data('f_path');
 
    var parts = line_td_id.split('_');
 
    var line_no = parts[parts.length-1];
 
    comment_div_state($comment_div, f_path, line_no, true);
 
}
 

	
 
// return comment div for target_id - add it if it doesn't exist yet
 
function _get_add_comment_div(target_id) {
 
    var comments_box_id = 'comments-' + target_id;
 
    var $comments_box = $('#' + comments_box_id);
 
    if (!$comments_box.length) {
 
        var html = '<tr><td id="{0}" colspan="3" class="inline-comments"></td></tr>'.format(comments_box_id);
 
        $('#' + target_id).closest('tr').after(html);
 
        $comments_box = $('#' + comments_box_id);
 
    }
 
    return $comments_box;
 
}
 

	
 
// Set $comment_div state - showing or not showing form and Add button.
 
// An Add button is shown on non-empty forms when no form is shown.
 
// The form is controlled by show_form_opt - if undefined, form is only shown for general comments.
 
function comment_div_state($comment_div, f_path, line_no, show_form_opt) {
 
    var show_form = show_form_opt !== undefined ? show_form_opt : !f_path && !line_no;
 
    var $forms = $comment_div.children('.comment-inline-form');
 
    var $buttonrow = $comment_div.children('.add-button-row');
 
    var $comments = $comment_div.children('.comment:not(.submitting)');
 
    $forms.remove();
 
    $buttonrow.remove();
 
    if (show_form) {
 
        _comment_div_append_form($comment_div, f_path, line_no);
 
    } else if ($comments.length) {
 
        _comment_div_append_add($comment_div, f_path, line_no);
 
    } else {
 
        $comment_div.parent('tr').remove();
 
    }
 
}
 

	
 
// append an Add button to $comment_div and hook it up to show form
 
function _comment_div_append_add($comment_div, f_path, line_no) {
 
    var addlabel = TRANSLATION_MAP['Add Another Comment'];
 
    var $add = $('<div class="add-button-row"><span class="btn btn-default btn-xs add-button">{0}</span></div>'.format(addlabel));
 
    $comment_div.append($add);
 
    $add.children('.add-button').click(function() {
 
        comment_div_state($comment_div, f_path, line_no, true);
 
    });
 
}
 

	
 
// append a comment form to $comment_div
 
// Note: var AJAX_COMMENT_URL must have been defined before invoking this function
 
function _comment_div_append_form($comment_div, f_path, line_no) {
 
    var $form_div = $('#comment-inline-form-template').children()
 
        .clone()
 
        .addClass('comment-inline-form');
 
    $comment_div.append($form_div);
 
    var $preview = $comment_div.find("div.comment-preview");
 
    var $form = $comment_div.find("form");
 
    var $textarea = $form.find('textarea');
 

	
 
    $form.submit(function(e) {
 
        e.preventDefault();
 

	
 
        var text = $textarea.val();
 
        var review_status = $form.find('input:radio[name=changeset_status]:checked').val();
 
        var pr_close = $form.find('input:checkbox[name=save_close]:checked').length ? 'on' : '';
 
        var pr_delete = $form.find('input:checkbox[name=save_delete]:checked').length ? 'delete' : '';
 

	
 
        if (!text && !review_status && !pr_close && !pr_delete) {
 
            alert("Please provide a comment");
 
            return false;
 
        }
 

	
 
        if (pr_delete) {
 
            if (text || review_status || pr_close) {
 
                alert('Cannot delete pull request while making other changes');
 
                return false;
 
            }
 
            if (!confirm('Confirm to delete this pull request')) {
 
                return false;
 
            }
 
            var comments = $('.comment').length;
 
            if (comments > 0 &&
 
                !confirm('Confirm again to delete this pull request with {0} comments'.format(comments))) {
 
                return false;
 
            }
 
        }
 

	
 
        if (review_status) {
 
            var $review_status = $preview.find('.automatic-comment');
 
            var review_status_lbl = $("#comment-inline-form-template input.status_change_radio[value='" + review_status + "']").parent().text().strip();
 
            $review_status.find('.comment-status-label').text(review_status_lbl);
 
            $review_status.show();
 
        }
 
        $preview.find('.comment-text div').text(text);
 
        $preview.show();
 
        $textarea.val('');
 
        if (f_path && line_no) {
 
            $form.hide();
 
        }
 

	
 
        var postData = {
 
            'text': text,
 
            'f_path': f_path,
 
            'line': line_no,
 
            'changeset_status': review_status,
 
            'save_close': pr_close,
 
            'save_delete': pr_delete
 
        };
 
        function success(json_data) {
 
            if (pr_delete) {
 
                location = json_data['location'];
 
            } else {
 
                $comment_div.append(json_data['rendered_text']);
 
                comment_div_state($comment_div, f_path, line_no);
 
                linkInlineComments($('.firstlink'), $('.comment:first-child'));
 
                if ((review_status || pr_close) && !f_path && !line_no) {
 
                    // Page changed a lot - reload it after closing the submitted form
 
                    comment_div_state($comment_div, f_path, line_no, false);
 
                    location.reload(true);
 
                }
 
            }
 
        }
 
        function failure(x, s, e) {
 
            $preview.removeClass('submitting').addClass('failed');
 
            $preview.removeClass('submitting').children('.panel').addClass('panel-danger');
 
            var $status = $preview.find('.comment-submission-status');
 
            $('<span>', {
 
                'title': e,
 
                text: _TM['Unable to post']
 
            }).replaceAll($status.contents());
 
            $('<div>', {
 
                'class': 'btn-group'
 
            }).append(
 
                $('<button>', {
 
                    'class': 'btn btn-default btn-xs',
 
                    text: _TM['Retry']
 
                }).click(function() {
 
                    $status.text(_TM['Submitting ...']);
 
                    $preview.addClass('submitting').removeClass('failed');
 
                    $preview.addClass('submitting').children('.panel').removeClass('panel-danger');
 
                    ajaxPOST(AJAX_COMMENT_URL, postData, success, failure);
 
                }),
 
                $('<button>', {
 
                    'class': 'btn btn-default btn-xs',
 
                    text: _TM['Cancel']
 
                }).click(function() {
 
                    comment_div_state($comment_div, f_path, line_no);
 
                })
 
            ).appendTo($status);
 
        }
 
        ajaxPOST(AJAX_COMMENT_URL, postData, success, failure);
 
    });
 

	
 
    // add event handler for hide/cancel buttons
 
    $form.find('.hide-inline-form').click(function() {
 
        comment_div_state($comment_div, f_path, line_no);
 
    });
 

	
 
    tooltip_activate();
 
    if ($textarea.length > 0) {
 
        MentionsAutoComplete($textarea);
 
    }
 
    if (f_path) {
 
        $textarea.focus();
 
    }
 
}
 

	
 

	
 
// Note: var AJAX_COMMENT_URL must have been defined before invoking this function
 
function deleteComment(comment_id) {
 
    var url = AJAX_COMMENT_DELETE_URL.replace('__COMMENT_ID__', comment_id);
 
    var postData = {};
 
    function success() {
 
        $('#comment-'+comment_id).remove();
 
        // Ignore that this might leave a stray Add button (or have a pending form with another comment) ...
 
    }
 
    ajaxPOST(url, postData, success);
 
}
 

	
 

	
 
/**
 
 * Double link comments
 
 */
 
function linkInlineComments($firstlinks, $comments){
 
    if ($comments.length > 0) {
 
        $firstlinks.html('<a href="#{0}">First comment</a>'.format($comments.prop('id')));
 
    }
 
    if ($comments.length <= 1) {
 
        return;
 
    }
 

	
 
    $comments.each(function(i){
 
            var prev = '';
 
            if (i > 0){
 
                var prev_anchor = $($comments.get(i-1)).prop('id');
 
                prev = '<a href="#{0}">Previous comment</a>'.format(prev_anchor);
 
            }
 
            var next = '';
 
            if (i+1 < $comments.length){
 
                var next_anchor = $($comments.get(i+1)).prop('id');
 
                next = '<a href="#{0}">Next comment</a>'.format(next_anchor);
 
            }
 
            $(this).find('.comment-prev-next-links').html(
 
                '<div class="prev-comment">{0}</div>'.format(prev) +
 
                '<div class="next-comment">{0}</div>'.format(next));
 
        });
 
}
 

	
 
/* activate files.html stuff */
 
function fileBrowserListeners(node_list_url, url_base){
 
    var $node_filter = $('#node_filter');
 

	
 
    var filterTimeout = null;
 
    var nodes = null;
 

	
 
    function initFilter(){
 
        $('#node_filter_box_loading').show();
 
        $('#search_activate_id').hide();
 
        $('#add_node_id').hide();
 
        $.ajax({url: node_list_url, headers: {'X-PARTIAL-XHR': '1'}, cache: false})
 
            .done(function(json) {
 
                    nodes = json.nodes;
 
                    $('#node_filter_box_loading').hide();
 
                    $('#node_filter_box').show();
 
                    $node_filter.focus();
 
                    if($node_filter.hasClass('init')){
 
                        $node_filter.val('');
 
                        $node_filter.removeClass('init');
 
                    }
 
                })
 
            .fail(function() {
 
                    console.log('fileBrowserListeners initFilter failed to load');
 
                })
 
        ;
 
    }
 

	
 
    function updateFilter(e) {
 
        return function(){
 
            // Reset timeout
 
            filterTimeout = null;
 
            var query = e.currentTarget.value.toLowerCase();
 
            var match = [];
 
            var matches = 0;
 
            var matches_max = 20;
 
            if (query != ""){
 
                for(var i=0;i<nodes.length;i++){
 
                    var pos = nodes[i].name.toLowerCase().indexOf(query);
 
                    if(query && pos != -1){
 
                        matches++
 
                        //show only certain amount to not kill browser
 
                        if (matches > matches_max){
 
                            break;
 
                        }
 

	
 
                        var n = nodes[i].name;
 
                        var t = nodes[i].type;
 
                        var n_hl = n.substring(0,pos)
 
                            + "<b>{0}</b>".format(n.substring(pos,pos+query.length))
 
                            + n.substring(pos+query.length);
 
                        var new_url = url_base.replace('__FPATH__',n);
 
                        match.push('<tr><td><a class="browser-{0}" href="{1}">{2}</a></td><td colspan="5"></td></tr>'.format(t,new_url,n_hl));
 
                    }
 
                    if(match.length >= matches_max){
 
                        match.push('<tr><td>{0}</td><td colspan="5"></td></tr>'.format(_TM['Search truncated']));
 
                        break;
 
                    }
 
                }
 
            }
 
            if(query != ""){
 
                $('#tbody').hide();
 
                $('#tbody_filtered').show();
 

	
 
                if (match.length==0){
 
                  match.push('<tr><td>{0}</td><td colspan="5"></td></tr>'.format(_TM['No matching files']));
 
                }
 

	
 
                $('#tbody_filtered').html(match.join(""));
 
            }
 
            else{
 
                $('#tbody').show();
 
                $('#tbody_filtered').hide();
 
            }
 
        }
 
    }
 

	
 
    $('#filter_activate').click(function(){
 
            initFilter();
 
        });
 
    $node_filter.click(function(){
 
            if($node_filter.hasClass('init')){
 
                $node_filter.val('');
 
                $node_filter.removeClass('init');
 
            }
 
        });
 
    $node_filter.keyup(function(e){
 
            clearTimeout(filterTimeout);
 
            filterTimeout = setTimeout(updateFilter(e),600);
 
        });
 
}
 

	
 

	
 
function initCodeMirror(textarea_id, baseUrl, resetUrl){
 
    var myCodeMirror = CodeMirror.fromTextArea($('#' + textarea_id)[0], {
 
            mode: "null",
 
            lineNumbers: true,
 
            indentUnit: 4,
 
            autofocus: true
 
        });
 
    CodeMirror.modeURL = baseUrl + "/codemirror/mode/%N/%N.js";
 

	
 
    $('#reset').click(function(){
 
            window.location=resetUrl;
 
        });
 

	
 
    $('#file_enable').click(function(){
 
            $('#upload_file_container').hide();
 
            $('#filename_container').show();
 
            $('#body').show();
 
        });
 

	
 
    $('#upload_file_enable').click(function(){
 
            $('#upload_file_container').show();
 
            $('#filename_container').hide();
 
            $('#body').hide();
 
        });
 

	
 
    return myCodeMirror
 
}
 

	
 
function setCodeMirrorMode(codeMirrorInstance, mode) {
 
    CodeMirror.autoLoadMode(codeMirrorInstance, mode);
 
}
 

	
 

	
 
function _getIdentNode(n){
 
    //iterate thrugh nodes until matching interesting node
 

	
 
    if (typeof n == 'undefined'){
 
        return -1
 
    }
 

	
 
    if(typeof n.id != "undefined" && n.id.match('L[0-9]+')){
 
        return n
 
    }
 
    else{
 
        return _getIdentNode(n.parentNode);
 
    }
 
}
 

	
 
/* generate links for multi line selects that can be shown by files.html page_highlights.
 
 * This is a mouseup handler for hlcode from CodeHtmlFormatter and pygmentize */
 
function getSelectionLink() {
 
    //get selection from start/to nodes
 
    if (typeof window.getSelection != "undefined") {
 
        var s = window.getSelection();
 

	
 
        var from = _getIdentNode(s.anchorNode);
 
        var till = _getIdentNode(s.focusNode);
 

	
 
        //var f_int = parseInt(from.id.replace('L',''));
 
        //var t_int = parseInt(till.id.replace('L',''));
 

	
 
        var yoffset = 35;
 
        var ranges = [parseInt(from.id.replace('L','')), parseInt(till.id.replace('L',''))];
 
        if (ranges[0] > ranges[1]){
 
            //highlight from bottom
 
            yoffset = -yoffset;
 
            ranges = [ranges[1], ranges[0]];
 
        }
 
        var $hl_div = $('div#linktt');
 
        // if we select more than 2 lines
 
        if (ranges[0] != ranges[1]){
 
            if ($hl_div.length) {
 
                $hl_div.html('');
 
            } else {
 
                $hl_div = $('<div id="linktt" class="hl-tip-box">');
 
                $('body').prepend($hl_div);
 
            }
 

	
 
            $hl_div.append($('<a>').html(_TM['Selection Link']).prop('href', location.href.substring(0, location.href.indexOf('#')) + '#L' + ranges[0] + '-'+ranges[1]));
 
            var xy = $(till).offset();
 
            $hl_div.css('top', (xy.top + yoffset) + 'px').css('left', xy.left + 'px');
 
            $hl_div.show();
 
        }
 
        else{
 
            $hl_div.hide();
 
        }
 
    }
 
}
 

	
 
/**
 
 * Autocomplete functionality
 
 */
 

	
 
// Highlight the snippet if it is found in the full text, while escaping any existing markup.
 
// Snippet must be lowercased already.
 
function autocompleteHighlightMatch(full, snippet) {
 
    var matchindex = full.toLowerCase().indexOf(snippet);
 
    if (matchindex <0)
 
        return full.html_escape();
 
    return full.substring(0, matchindex).html_escape()
 
        + '<span class="select2-match">'
 
        + full.substr(matchindex, snippet.length).html_escape()
 
        + '</span>'
 
        + full.substring(matchindex + snippet.length).html_escape();
 
}
 

	
 
// Return html snippet for showing the provided gravatar url
 
function gravatar(gravatar_lnk, size, cssclass) {
 
    if (!gravatar_lnk) {
 
        return '';
 
    }
 
    if (gravatar_lnk == 'default') {
 
        return '<i class="icon-user {1}" style="font-size: {0}px;"></i>'.format(size, cssclass);
 
    }
 
    return ('<i class="icon-gravatar {2}"' +
 
            ' style="font-size: {0}px;background-image: url(\'{1}\'); background-size: {0}px"' +
 
            '></i>').format(size, gravatar_lnk, cssclass);
 
}
 

	
 
function autocompleteGravatar(res, gravatar_lnk, size, group) {
 
    var elem;
 
    if (group !== undefined) {
 
        elem = '<i class="perm-gravatar-ac icon-users"></i>';
 
    } else {
 
        elem = gravatar(gravatar_lnk, size, "perm-gravatar-ac");
 
    }
 
    return '<div class="ac-container-wrap">{0}{1}</div>'.format(elem, res);
 
}
 

	
 
// Custom formatter to highlight the matching letters and do HTML escaping
 
function autocompleteFormatter(oResultData, sQuery, sResultMatch) {
 
    var query;
 
    if (sQuery && sQuery.toLowerCase) // YAHOO AutoComplete
 
        query = sQuery.toLowerCase();
 
    else if (sResultMatch && sResultMatch.term) // select2 - parameter names doesn't match
 
        query = sResultMatch.term.toLowerCase();
 

	
 
    // group
 
    if (oResultData.type == "group") {
 
        return autocompleteGravatar(
 
            "{0}: {1}".format(
 
                _TM['Group'],
 
                autocompleteHighlightMatch(oResultData.grname, query)),
 
            null, null, true);
 
    }
 

	
 
    // users
 
    if (oResultData.nname) {
 
        var displayname = autocompleteHighlightMatch(oResultData.nname, query);
 
        if (oResultData.fname && oResultData.lname) {
 
            displayname = "{0} {1} ({2})".format(
 
                autocompleteHighlightMatch(oResultData.fname, query),
 
                autocompleteHighlightMatch(oResultData.lname, query),
 
                displayname);
 
        }
 

	
 
        return autocompleteGravatar(displayname, oResultData.gravatar_lnk, oResultData.gravatar_size);
 
    }
 

	
 
    return '';
 
}
 

	
 
function SimpleUserAutoComplete($inputElement) {
 
    $inputElement.select2({
 
        formatInputTooShort: $inputElement.attr('placeholder'),
 
        initSelection : function (element, callback) {
 
            $.ajax({
 
                url: pyroutes.url('users_and_groups_data'),
 
                dataType: 'json',
 
                data: {
 
                    key: element.val()
 
                },
 
                success: function(data){
 
                  callback(data.results[0]);
 
                }
 
            });
 
        },
 
        minimumInputLength: 1,
 
        ajax: {
 
            url: pyroutes.url('users_and_groups_data'),
 
            dataType: 'json',
 
            data: function(term){
 
              return {
 
                query: term
 
              };
 
            },
 
            results: function (data){
 
              return data;
 
            },
 
            cache: true
 
        },
 
        formatSelection: autocompleteFormatter,
 
        formatResult: autocompleteFormatter,
 
        id: function(item) { return item.nname; },
 
    });
 
}
 

	
 
function MembersAutoComplete($inputElement, $typeElement) {
 

	
 
    $inputElement.select2({
 
        placeholder: $inputElement.attr('placeholder'),
 
        minimumInputLength: 1,
 
        ajax: {
 
            url: pyroutes.url('users_and_groups_data'),
 
            dataType: 'json',
 
            data: function(term){
 
              return {
 
                query: term,
 
                types: 'users,groups'
 
              };
 
            },
 
            results: function (data){
 
              return data;
 
            },
 
            cache: true
 
        },
 
        formatSelection: autocompleteFormatter,
 
        formatResult: autocompleteFormatter,
 
        id: function(item) { return item.type == 'user' ? item.nname : item.grname },
 
    }).on("select2-selecting", function(e) {
 
        // e.choice.id is automatically used as selection value - just set the type of the selection
 
        $typeElement.val(e.choice.type);
 
    });
0 comments (0 inline, 0 general)