1"use strict"; 2 3var csrf; 4var suburl; 5 6function initCommentPreviewTab($form) { 7 var $tabMenu = $form.find(".tabular.menu"); 8 $tabMenu.find(".item").tab(); 9 $tabMenu 10 .find('.item[data-tab="' + $tabMenu.data("preview") + '"]') 11 .click(function() { 12 var $this = $(this); 13 $.post( 14 $this.data("url"), 15 { 16 _csrf: csrf, 17 mode: "gfm", 18 context: $this.data("context"), 19 text: $form 20 .find( 21 '.tab.segment[data-tab="' + $tabMenu.data("write") + '"] textarea' 22 ) 23 .val() 24 }, 25 function(data) { 26 var $previewPanel = $form.find( 27 '.tab.segment[data-tab="' + $tabMenu.data("preview") + '"]' 28 ); 29 $previewPanel.html(data); 30 emojify.run($previewPanel[0]); 31 $("pre code", $previewPanel[0]).each(function(i, block) { 32 hljs.highlightBlock(block); 33 }); 34 } 35 ); 36 }); 37 38 buttonsClickOnEnter(); 39} 40 41var previewFileModes; 42 43function initEditPreviewTab($form) { 44 var $tabMenu = $form.find(".tabular.menu"); 45 $tabMenu.find(".item").tab(); 46 var $previewTab = $tabMenu.find( 47 '.item[data-tab="' + $tabMenu.data("preview") + '"]' 48 ); 49 if ($previewTab.length) { 50 previewFileModes = $previewTab.data("preview-file-modes").split(","); 51 $previewTab.click(function() { 52 var $this = $(this); 53 $.post( 54 $this.data("url"), 55 { 56 _csrf: csrf, 57 context: $this.data("context"), 58 text: $form 59 .find( 60 '.tab.segment[data-tab="' + $tabMenu.data("write") + '"] textarea' 61 ) 62 .val() 63 }, 64 function(data) { 65 var $previewPanel = $form.find( 66 '.tab.segment[data-tab="' + $tabMenu.data("preview") + '"]' 67 ); 68 $previewPanel.html(data); 69 emojify.run($previewPanel[0]); 70 $("pre code", $previewPanel[0]).each(function(i, block) { 71 hljs.highlightBlock(block); 72 }); 73 } 74 ); 75 }); 76 } 77} 78 79function initEditDiffTab($form) { 80 var $tabMenu = $form.find(".tabular.menu"); 81 $tabMenu.find(".item").tab(); 82 $tabMenu 83 .find('.item[data-tab="' + $tabMenu.data("diff") + '"]') 84 .click(function() { 85 var $this = $(this); 86 $.post( 87 $this.data("url"), 88 { 89 _csrf: csrf, 90 content: $form 91 .find( 92 '.tab.segment[data-tab="' + $tabMenu.data("write") + '"] textarea' 93 ) 94 .val() 95 }, 96 function(data) { 97 var $diffPreviewPanel = $form.find( 98 '.tab.segment[data-tab="' + $tabMenu.data("diff") + '"]' 99 ); 100 $diffPreviewPanel.html(data); 101 emojify.run($diffPreviewPanel[0]); 102 } 103 ); 104 }); 105} 106 107function initEditForm() { 108 if ($(".edit.form").length == 0) { 109 return; 110 } 111 112 initEditPreviewTab($(".edit.form")); 113 initEditDiffTab($(".edit.form")); 114} 115
116function initCommentForm() { 117 if ($(".comment.form").length == 0) { 118 return; 119 } 120 121 initCommentPreviewTab($(".comment.form")); 122 123 // Labels 124 var $list = $(".ui.labels.list"); 125 var $noSelect = $list.find(".no-select"); 126 var $labelMenu = $(".select-label .menu"); 127 var hasLabelUpdateAction = $labelMenu.data("action") == "update"; 128 129 function updateIssueMeta(url, action, id) { 130 $.post(url, { 131 _csrf: csrf, 132 action: action, 133 id: id 134 }); 135 } 136 137 // Add to each unselected label to keep UI looks good. 138 // This should be added directly to HTML but somehow just get empty <span> on this page. 139 $labelMenu 140 .find(".item:not(.no-select) .octicon:not(.octicon-check)") 141 .each(function() { 142 $(this).html(" "); 143 }); 144 $labelMenu.find(".item:not(.no-select)").click(function() { 145 if ($(this).hasClass("checked")) { 146 $(this).removeClass("checked"); 147 $(this) 148 .find(".octicon") 149 .removeClass("octicon-check") 150 .html(" "); 151 if (hasLabelUpdateAction) { 152 updateIssueMeta( 153 $labelMenu.data("update-url"), 154 "detach", 155 $(this).data("id") 156 ); 157 } 158 } else { 159 $(this).addClass("checked"); 160 $(this) 161 .find(".octicon") 162 .addClass("octicon-check") 163 .html(""); 164 if (hasLabelUpdateAction) { 165 updateIssueMeta( 166 $labelMenu.data("update-url"), 167 "attach", 168 $(this).data("id") 169 ); 170 } 171 } 172 173 var labelIds = ""; 174 $(this) 175 .parent() 176 .find(".item") 177 .each(function() { 178 if ($(this).hasClass("checked")) { 179 labelIds += $(this).data("id") + ","; 180 $($(this).data("id-selector")).removeClass("hide"); 181 } else { 182 $($(this).data("id-selector")).addClass("hide"); 183 } 184 }); 185 if (labelIds.length == 0) { 186 $noSelect.removeClass("hide"); 187 } else { 188 $noSelect.addClass("hide"); 189 } 190 $( 191 $(this) 192 .parent() 193 .data("id") 194 ).val(labelIds); 195 return false; 196 }); 197 $labelMenu.find(".no-select.item").click(function() { 198 if (hasLabelUpdateAction) { 199 updateIssueMeta($labelMenu.data("update-url"), "clear", ""); 200 } 201 202 $(this) 203 .parent() 204 .find(".item") 205 .each(function() { 206 $(this).removeClass("checked"); 207 $(this) 208 .find(".octicon") 209 .removeClass("octicon-check") 210 .html(" "); 211 }); 212 213 $list.find(".item").each(function() { 214 $(this).addClass("hide"); 215 }); 216 $noSelect.removeClass("hide"); 217 $( 218 $(this) 219 .parent() 220 .data("id") 221 ).val(""); 222 }); 223 224 function selectItem(select_id, input_id) { 225 var $menu = $(select_id + " .menu"); 226 var $list = $(".ui" + select_id + ".list"); 227 var hasUpdateAction = $menu.data("action") == "update"; 228 229 $menu.find(".item:not(.no-select)").click(function() { 230 $(this) 231 .parent() 232 .find(".item") 233 .each(function() { 234 $(this).removeClass("selected active"); 235 }); 236 237 $(this).addClass("selected active"); 238 if (hasUpdateAction) { 239 updateIssueMeta($menu.data("update-url"), "", $(this).data("id")); 240 } 241 switch (input_id) { 242 case "#milestone_id": 243 var $milestoneAnchor = $('<a class="item"></a>'); 244 $milestoneAnchor.attr("href", $(this).data("href")); 245 $milestoneAnchor.text($(this).text()); 246 $list.find(".selected").empty().append($milestoneAnchor); 247 break; 248 case "#assignee_id": 249 var $assigneeAnchor = $('<a class="item"></a>'); 250 $assigneeAnchor.attr("href", $(this).data("href")); 251 $assigneeAnchor.append( 252 $('<img class="ui avatar image">').attr("src", $(this).data("avatar")) 253 ); 254 $assigneeAnchor.append($("<span></span>").text($(this).text())); 255 $list.find(".selected").empty().append($assigneeAnchor); 256 } 257 $(".ui" + select_id + ".list .no-select").addClass("hide"); 258 $(input_id).val($(this).data("id")); 259 }); 260 $menu.find(".no-select.item").click(function() { 261 $(this) 262 .parent()
263 .find(".item:not(.no-select)") 264 .each(function() { 265 $(this).removeClass("selected active"); 266 }); 267 268 if (hasUpdateAction) { 269 updateIssueMeta($menu.data("update-url"), "", ""); 270 } 271 272 $list.find(".selected").html(""); 273 $list.find(".no-select").removeClass("hide"); 274 $(input_id).val(""); 275 }); 276 } 277 278 // Milestone and assignee 279 selectItem(".select-milestone", "#milestone_id"); 280 selectItem(".select-assignee", "#assignee_id"); 281} 282 283function initRepository() { 284 if ($(".repository").length == 0) { 285 return; 286 } 287 288 function initFilterSearchDropdown(selector) { 289 var $dropdown = $(selector); 290 $dropdown.dropdown({ 291 fullTextSearch: true, 292 onChange: function(text, value, $choice) { 293 window.location.href = $choice.data("url"); 294 console.log($choice.data("url")); 295 }, 296 message: { noResults: $dropdown.data("no-results") } 297 }); 298 } 299 300 // File list and commits 301 if ( 302 $(".repository.file.list").length > 0 || 303 ".repository.commits".length > 0 304 ) { 305 initFilterSearchDropdown(".choose.reference .dropdown"); 306 307 $(".reference.column").click(function() { 308 $(".choose.reference .scrolling.menu").css("display", "none"); 309 $(".choose.reference .text").removeClass("black"); 310 $($(this).data("target")).css("display", "block"); 311 $(this) 312 .find(".text") 313 .addClass("black"); 314 return false; 315 }); 316 } 317 318 // Wiki 319 if ($(".repository.wiki.view").length > 0) { 320 initFilterSearchDropdown(".choose.page .dropdown"); 321 } 322 323 // Options 324 if ($(".repository.settings.options").length > 0) { 325 $("#repo_name").keyup(function() { 326 var $prompt = $("#repo-name-change-prompt"); 327 if ( 328 $(this) 329 .val() 330 .toString() 331 .toLowerCase() != 332 $(this) 333 .data("repo-name") 334 .toString() 335 .toLowerCase() 336 ) { 337 $prompt.show(); 338 } else { 339 $prompt.hide(); 340 } 341 }); 342 } 343 344 // Branches 345 if ($(".repository.settings.branches").length > 0) { 346 initFilterSearchDropdown(".protected-branches .dropdown"); 347 $(".enable-protection, .enable-whitelist").change(function() { 348 if (this.checked) { 349 $($(this).data("target")).removeClass("disabled"); 350 } else { 351 $($(this).data("target")).addClass("disabled"); 352 } 353 }); 354 } 355 356 // Labels 357 if ($(".repository.labels").length > 0) { 358 // Create label 359 var $newLabelPanel = $(".new-label.segment"); 360 $(".new-label.button").click(function() { 361 $newLabelPanel.show(); 362 }); 363 $(".new-label.segment .cancel").click(function() { 364 $newLabelPanel.hide(); 365 }); 366 367 $(".color-picker").each(function() { 368 $(this).minicolors(); 369 }); 370 $(".precolors .color").click(function() { 371 var color_hex = $(this).data("color-hex"); 372 $(".color-picker").val(color_hex); 373 $(".minicolors-swatch-color").css("background-color", color_hex); 374 }); 375 $(".edit-label-button").click(function() { 376 $("#label-modal-id").val($(this).data("id")); 377 $(".edit-label .new-label-input").val($(this).data("title")); 378 $(".edit-label .color-picker").val($(this).data("color")); 379 $(".minicolors-swatch-color").css( 380 "background-color", 381 $(this).data("color") 382 ); 383 $(".edit-label.modal") 384 .modal({ 385 onApprove: function() { 386 $(".edit-label.form").submit(); 387 } 388 }) 389 .modal("show"); 390 return false; 391 }); 392 } 393 394 // Milestones 395 if ($(".repository.milestones").length > 0) { 396 } 397 if ($(".repository.new.milestone").length > 0) { 398 var $datepicker = $(".milestone.datepicker"); 399 $datepicker.datetimepicker({ 400 lang: $datepicker.data("lang"), 401 inline: true, 402 timepicker: false, 403 startDate: $datepicker.data("start-date"), 404 formatDate: "Y-m-d", 405 onSelectDate: function(ct) { 406 $("#deadline").val(ct.dateFormat("Y-m-d")); 407 } 408 }); 409 $("#clear-date").click(function() { 410 $("#deadline").val(""); 411 return false; 412 }); 413 } 414 415 // Issues 416 if ($(".repository.view.issue").length > 0) { 417 // Edit issue title 418 var $issueTitle = $("#issue-title"); 419 var $editInput = $("#edit-title-input").find("input"); 420 var editTitleToggle = function() {
421 $issueTitle.toggle(); 422 $(".not-in-edit").toggle(); 423 $("#edit-title-input").toggle(); 424 $(".in-edit").toggle(); 425 $editInput.focus(); 426 return false; 427 }; 428 $("#edit-title").click(editTitleToggle); 429 $("#cancel-edit-title").click(editTitleToggle); 430 $("#save-edit-title") 431 .click(editTitleToggle) 432 .click(function() { 433 if ( 434 $editInput.val().length == 0 || 435 $editInput.val() == $issueTitle.text() 436 ) { 437 $editInput.val($issueTitle.text()); 438 return false; 439 } 440 441 $.post( 442 $(this).data("update-url"), 443 { 444 _csrf: csrf, 445 title: $editInput.val() 446 }, 447 function(data) { 448 $editInput.val(data.title); 449 $issueTitle.text(data.title); 450 } 451 ); 452 return false; 453 }); 454 455 // Edit issue or comment content 456 $(".edit-content").click(function() { 457 var $segment = $(this) 458 .parent() 459 .parent() 460 .parent() 461 .next(); 462 var $editContentZone = $segment.find(".edit-content-zone"); 463 var $renderContent = $segment.find(".render-content"); 464 var $rawContent = $segment.find(".raw-content"); 465 var $textarea; 466 467 // Setup new form 468 if ($editContentZone.html().length == 0) { 469 $editContentZone.html($("#edit-content-form").html()); 470 $textarea = $segment.find("textarea"); 471 472 // Give new write/preview data-tab name to distinguish from others 473 var $editContentForm = $editContentZone.find(".ui.comment.form"); 474 var $tabMenu = $editContentForm.find(".tabular.menu"); 475 $tabMenu.attr("data-write", $editContentZone.data("write")); 476 $tabMenu.attr("data-preview", $editContentZone.data("preview")); 477 $tabMenu 478 .find(".write.item") 479 .attr("data-tab", $editContentZone.data("write")); 480 $tabMenu 481 .find(".preview.item") 482 .attr("data-tab", $editContentZone.data("preview")); 483 $editContentForm 484 .find(".write.segment") 485 .attr("data-tab", $editContentZone.data("write")); 486 $editContentForm 487 .find(".preview.segment") 488 .attr("data-tab", $editContentZone.data("preview")); 489 490 initCommentPreviewTab($editContentForm); 491 492 $editContentZone.find(".cancel.button").click(function() { 493 $renderContent.show(); 494 $editContentZone.hide(); 495 }); 496 $editContentZone.find(".save.button").click(function() { 497 $renderContent.show(); 498 $editContentZone.hide(); 499 500 $.post( 501 $editContentZone.data("update-url"), 502 { 503 _csrf: csrf, 504 content: $textarea.val(), 505 context: $editContentZone.data("context") 506 }, 507 function(data) { 508 if (data.length == 0) { 509 $renderContent.html($("#no-content").html()); 510 } else { 511 $renderContent.html(data.content); 512 emojify.run($renderContent[0]); 513 $("pre code", $renderContent[0]).each(function(i, block) { 514 hljs.highlightBlock(block); 515 }); 516 } 517 } 518 ); 519 }); 520 } else { 521 $textarea = $segment.find("textarea"); 522 } 523 524 // Show write/preview tab and copy raw content as needed 525 $editContentZone.show(); 526 $renderContent.hide(); 527 if ($textarea.val().length == 0) { 528 $textarea.val($rawContent.text()); 529 } 530 $textarea.focus(); 531 return false; 532 }); 533 534 // Delete comment 535 $(".delete-comment").click(function() { 536 var $this = $(this); 537 if (confirm($this.data("locale"))) { 538 $.post($this.data("url"), { 539 _csrf: csrf 540 }).done(function() { 541 $("#" + $this.data("comment-id")).remove(); 542 }); 543 } 544 return false; 545 }); 546 547 // Change status 548 var $statusButton = $("#status-button"); 549 $("#comment-form .edit_area").keyup(function() { 550 if ($(this).val().length == 0) { 551 $statusButton.text($statusButton.data("status")); 552 } else { 553 $statusButton.text($statusButton.data("status-and-comment")); 554 } 555 }); 556 $statusButton.click(function() { 557 $("#status").val($statusButton.data("status-val")); 558 $("#comment-form").submit(); 559 }); 560 } 561 562 // Diff 563 if ($(".repository.diff").length > 0) { 564 var $counter = $(".diff-counter"); 565 if ($counter.length >= 1) { 566 $counter.each(function(i, item) { 567 var $item = $(item); 568 var addLine = $item.find("span[data-line].add").data("line"); 569 var delLine = $item.find("span[data-line].del").data("line"); 570 var addPercent = 571 (parseFloat(addLine) / (parseFloat(addLine) + parseFloat(delLine))) * 572 100; 573 $item.find(".bar .add").css("width", addPercent + "%"); 574 }); 575 } 576 577 $(".diff-file-box .lines-num").click(function() { 578 if ($(this).attr("id")) { 579 window.location.href = "#" + $(this).attr("id"); 580 } 581 }); 582 583 $(window) 584 .on("hashchange", function(e) { 585 $(".diff-file-box .lines-code.active").removeClass("active"); 586 var m = window.location.hash.match(/^#diff-.+$/); 587 if (m) { 588 $(m[0]) 589 .siblings(".lines-code") 590 .addClass("active"); 591 } 592 }) 593 .trigger("hashchange"); 594 } 595 596 // Quick start and repository home 597 $("#repo-clone-ssh").click(function() { 598 $(".clone-url").text($(this).data("link")); 599 $("#repo-clone-url").val($(this).data("link")); 600 $(this).addClass("blue"); 601 $("#repo-clone-https").removeClass("blue"); 602 localStorage.setItem("repo-clone-protocol", "ssh"); 603 }); 604 $("#repo-clone-https").click(function() { 605 $(".clone-url").text($(this).data("link")); 606 $("#repo-clone-url").val($(this).data("link")); 607 $(this).addClass("blue"); 608 $("#repo-clone-ssh").removeClass("blue"); 609 localStorage.setItem("repo-clone-protocol", "https"); 610 }); 611 $("#repo-clone-url").click(function() { 612 $(this).select(); 613 }); 614 615 // Pull request 616 if ($(".repository.compare.pull").length > 0) { 617 initFilterSearchDropdown(".choose.branch .dropdown"); 618 } 619 if ($(".repository.view.pull").length > 0) { 620 $(".comment.merge.box input[name=merge_style]").change(function() {
621 if ($(this).val() === "create_merge_commit") { 622 $(".commit.description.field").show(); 623 } else { 624 $(".commit.description.field").hide(); 625 } 626 }); 627 } 628} 629 630function initWikiForm() { 631 var $editArea = $(".repository.wiki textarea#edit_area"); 632 if ($editArea.length > 0) { 633 new SimpleMDE({ 634 autoDownloadFontAwesome: false, 635 element: $editArea[0], 636 forceSync: true, 637 previewRender: function(plainText, preview) { 638 // Async method 639 setTimeout(function() { 640 // FIXME: still send render request when return back to edit mode 641 $.post( 642 $editArea.data("url"), 643 { 644 _csrf: csrf, 645 mode: "gfm", 646 context: $editArea.data("context"), 647 text: plainText 648 }, 649 function(data) { 650 preview.innerHTML = '<div class="markdown">' + data + "</div>"; 651 emojify.run($(".editor-preview")[0]); 652 } 653 ); 654 }, 0); 655 656 return "Loading..."; 657 }, 658 renderingConfig: { 659 singleLineBreaks: false 660 }, 661 indentWithTabs: false, 662 tabSize: 4, 663 spellChecker: false, 664 toolbar: [ 665 "bold", 666 "italic", 667 "strikethrough", 668 "|", 669 "heading-1", 670 "heading-2", 671 "heading-3", 672 "heading-bigger", 673 "heading-smaller", 674 "|", 675 "code", 676 "quote", 677 "|", 678 "unordered-list", 679 "ordered-list", 680 "|", 681 "link", 682 "image", 683 "table", 684 "horizontal-rule", 685 "|", 686 "clean-block", 687 "preview", 688 "fullscreen" 689 ] 690 }); 691 } 692} 693 694var simpleMDEditor; 695var codeMirrorEditor; 696 697// For IE 698String.prototype.endsWith = function(pattern) { 699 var d = this.length - pattern.length; 700 return d >= 0 && this.lastIndexOf(pattern) === d; 701}; 702 703// Adding function to get the cursor position in a text field to jQuery object. 704(function($, undefined) { 705 $.fn.getCursorPosition = function() { 706 var el = $(this).get(0); 707 var pos = 0; 708 if ("selectionStart" in el) { 709 pos = el.selectionStart; 710 } else if ("selection" in document) { 711 el.focus(); 712 var Sel = document.selection.createRange(); 713 var SelLength = document.selection.createRange().text.length; 714 Sel.moveStart("character", -el.value.length); 715 pos = Sel.text.length - SelLength; 716 } 717 return pos; 718 }; 719})(jQuery); 720 721function setSimpleMDE($editArea) { 722 if (codeMirrorEditor) { 723 codeMirrorEditor.toTextArea(); 724 codeMirrorEditor = null; 725 } 726 727 if (simpleMDEditor) { 728 return true; 729 } 730 731 simpleMDEditor = new SimpleMDE({ 732 autoDownloadFontAwesome: false, 733 element: $editArea[0], 734 forceSync: true, 735 renderingConfig: { 736 singleLineBreaks: false 737 }, 738 indentWithTabs: false, 739 tabSize: 4, 740 spellChecker: false, 741 previewRender: function(plainText, preview) { 742 // Async method 743 setTimeout(function() { 744 // FIXME: still send render request when return back to edit mode 745 $.post( 746 $editArea.data("url"), 747 { 748 _csrf: csrf, 749 mode: "gfm", 750 context: $editArea.data("context"), 751 text: plainText 752 }, 753 function(data) { 754 preview.innerHTML = '<div class="markdown">' + data + "</div>"; 755 emojify.run($(".editor-preview")[0]); 756 } 757 ); 758 }, 0); 759 760 return "Loading..."; 761 }, 762 toolbar: [ 763 "bold", 764 "italic", 765 "strikethrough", 766 "|", 767 "heading-1", 768 "heading-2", 769 "heading-3", 770 "heading-bigger", 771 "heading-smaller", 772 "|", 773 "code", 774 "quote", 775 "|", 776 "unordered-list", 777 "ordered-list", 778 "|", 779 "link", 780 "image", 781 "table", 782 "horizontal-rule", 783 "|", 784 "clean-block" 785 ] 786 }); 787 788 return true; 789} 790 791function setCodeMirror($editArea) { 792 if (simpleMDEditor) { 793 simpleMDEditor.toTextArea(); 794 simpleMDEditor = null; 795 } 796 797 if (codeMirrorEditor) { 798 return true; 799 } 800 801 codeMirrorEditor = CodeMirror.fromTextArea($editArea[0], { 802 lineNumbers: true 803 });
804 codeMirrorEditor.on("change", function(cm, change) { 805 $editArea.val(cm.getValue()); 806 }); 807 808 return true; 809} 810 811function initEditor() { 812 $(".js-quick-pull-choice-option").change(function() { 813 if ($(this).val() == "commit-to-new-branch") { 814 $(".quick-pull-branch-name").show(); 815 $(".quick-pull-branch-name input").prop("required", true); 816 } else { 817 $(".quick-pull-branch-name").hide(); 818 $(".quick-pull-branch-name input").prop("required", false); 819 } 820 }); 821 822 var $editFilename = $("#file-name"); 823 $editFilename 824 .keyup(function(e) { 825 var $section = $(".breadcrumb span.section"); 826 var $divider = $(".breadcrumb div.divider"); 827 if (e.keyCode == 8) { 828 if ($(this).getCursorPosition() == 0) { 829 if ($section.length > 0) { 830 var value = $section 831 .last() 832 .find("a") 833 .text(); 834 $(this).val(value + $(this).val()); 835 $(this)[0].setSelectionRange(value.length, value.length); 836 $section.last().remove(); 837 $divider.last().remove(); 838 } 839 } 840 } 841 if (e.keyCode == 191) { 842 var parts = $(this) 843 .val() 844 .split("/"); 845 for (var i = 0; i < parts.length; ++i) { 846 var value = parts[i]; 847 if (i < parts.length - 1) { 848 if (value.length) { 849 $( 850 '<span class="section"><a href="#">' + value + "</a></span>" 851 ).insertBefore($(this)); 852 $('<div class="divider"> / </div>').insertBefore($(this)); 853 } 854 } else { 855 $(this).val(value); 856 } 857 $(this)[0].setSelectionRange(0, 0); 858 } 859 } 860 var parts = []; 861 $(".breadcrumb span.section").each(function(i, element) { 862 element = $(element); 863 if (element.find("a").length) { 864 parts.push(element.find("a").text()); 865 } else { 866 parts.push(element.text()); 867 } 868 }); 869 if ($(this).val()) { 870 parts.push($(this).val()); 871 } 872 873 var tree_path = parts.join("/"); 874 $("#tree_path").val(tree_path); 875 $("#preview-tab").data( 876 "context", 877 $("#preview-tab").data("root-context") + 878 tree_path.substring(0, tree_path.lastIndexOf("/") + 1) 879 ); 880 }) 881 .trigger("keyup"); 882 883 var $editArea = $(".repository.editor textarea#edit_area"); 884 if (!$editArea.length) return; 885 886 var markdownFileExts = $editArea.data("markdown-file-exts").split(","); 887 var lineWrapExtensions = $editArea.data("line-wrap-extensions").split(","); 888 889 $editFilename 890 .on("keyup", function(e) { 891 var val = $editFilename.val(), 892 m, 893 mode, 894 spec, 895 extension, 896 extWithDot, 897 previewLink, 898 dataUrl, 899 apiCall; 900 extension = extWithDot = ""; 901 if ((m = /.+\.([^.]+)$/.exec(val))) { 902 extension = m[1].toLowerCase(); 903 extWithDot = "." + extension; 904 } 905 906 var info = CodeMirror.findModeByExtension(extension); 907 previewLink = $("a[data-tab=preview]"); 908 if (info) { 909 mode = info.mode; 910 spec = info.mime; 911 apiCall = mode; 912 } else { 913 apiCall = extension; 914 } 915 916 if ( 917 previewLink.length && 918 apiCall && 919 previewFileModes && 920 previewFileModes.length && 921 previewFileModes.indexOf(apiCall) >= 0 922 ) { 923 dataUrl = previewLink.data("url"); 924 previewLink.data("url", dataUrl.replace(/(.*)\/.*/i, "$1/" + mode)); 925 previewLink.show(); 926 } else { 927 previewLink.hide(); 928 } 929 930 // If this file is a Markdown extensions, we will load that editor and return 931 if (markdownFileExts.indexOf(extWithDot) >= 0) { 932 if (setSimpleMDE($editArea)) { 933 return; 934 } 935 } 936 937 // Else we are going to use CodeMirror 938 if (!codeMirrorEditor && !setCodeMirror($editArea)) { 939 return; 940 } 941 942 if (mode) { 943 codeMirrorEditor.setOption("mode", spec); 944 CodeMirror.autoLoadMode(codeMirrorEditor, mode); 945 } 946 947 if (lineWrapExtensions.indexOf(extWithDot) >= 0) { 948 codeMirrorEditor.setOption("lineWrapping", true); 949 } else { 950 codeMirrorEditor.setOption("lineWrapping", false); 951 } 952 953 // get the filename without any folder 954 var value = $editFilename.val(); 955 if (value.length === 0) { 956 return; 957 } 958 value = value.split("/"); 959 value = value[value.length - 1]; 960 961 $.getJSON($editFilename.data("ec-url-prefix") + value, function( 962 editorconfig 963 ) { 964 if (editorconfig.indent_style === "tab") { 965 codeMirrorEditor.setOption("indentWithTabs", true); 966 codeMirrorEditor.setOption("extraKeys", {}); 967 } else { 968 codeMirrorEditor.setOption("indentWithTabs", false); 969 // required because CodeMirror doesn't seems to use spaces correctly for {"indentWithTabs": false}: 970 // - https://github.com/codemirror/CodeMirror/issues/988 971 // - https://codemirror.net/doc/manual.html#keymaps 972 codeMirrorEditor.setOption("extraKeys", { 973 Tab: function(cm) { 974 var spaces = Array(parseInt(cm.getOption("indentUnit")) + 1).join( 975 " " 976 ); 977 cm.replaceSelection(spaces); 978 } 979 }); 980 } 981 codeMirrorEditor.setOption("indentUnit", editorconfig.indent_size || 4); 982 codeMirrorEditor.setOption("tabSize", editorconfig.tab_width || 4); 983 }); 984 }) 985 .trigger("keyup"); 986} 987 988function initOrganization() { 989 if ($(".organization").length == 0) { 990 return; 991 } 992 993 // Options 994 if ($(".organization.settings.options").length > 0) { 995 $("#org_name").keyup(function() { 996 var $prompt = $("#org-name-change-prompt"); 997 if ( 998 $(this) 999 .val() 1000 .toString() 1001 .toLowerCase() != 1002 $(this) 1003 .data("org-name") 1004 .toString() 1005 .toLowerCase() 1006 ) { 1007 $prompt.show(); 1008 } else { 1009 $prompt.hide(); 1010 } 1011 }); 1012 } 1013} 1014 1015function initAdmin() { 1016 if ($(".admin").length == 0) { 1017 return; 1018 } 1019 1020 // New user 1021 if ($(".admin.new.user").length > 0 || $(".admin.edit.user").length > 0) { 1022 $("#login_type").change(function() { 1023 if ( 1024 $(this) 1025 .val() 1026 .substring(0, 1) == "0" 1027 ) { 1028 $("#login_name").removeAttr("required"); 1029 $(".non-local").hide(); 1030 $(".local").show(); 1031 $("#user_name").focus(); 1032 1033 if ($(this).data("password") == "required") { 1034 $("#password").attr("required", "required"); 1035 } 1036 } else { 1037 $("#login_name").attr("required", "required"); 1038 $(".non-local").show(); 1039 $(".local").hide(); 1040 $("#login_name").focus(); 1041 1042 $("#password").removeAttr("required"); 1043 } 1044 }); 1045 } 1046 1047 function onSecurityProtocolChange() { 1048 if ($("#security_protocol").val() > 0) { 1049 $(".has-tls").show(); 1050 } else { 1051 $(".has-tls").hide(); 1052 } 1053 } 1054 1055 // New authentication 1056 if ($(".admin.new.authentication").length > 0) { 1057 $("#auth_type").change(function() { 1058 $(".ldap").hide(); 1059 $(".dldap").hide(); 1060 $(".smtp").hide(); 1061 $(".pam").hide(); 1062 $(".github").hide(); 1063 $(".has-tls").hide(); 1064 1065 var authType = $(this).val(); 1066 switch (authType) { 1067 case "2": // LDAP 1068 $(".ldap").show(); 1069 break; 1070 case "3": // SMTP 1071 $(".smtp").show(); 1072 $(".has-tls").show(); 1073 break; 1074 case "4": // PAM 1075 $(".pam").show(); 1076 break; 1077 case "5": // LDAP 1078 $(".dldap").show(); 1079 break; 1080 case "6": //GITHUB 1081 $(".github").show(); 1082 $(".has-tls").show(); 1083 break; 1084 } 1085 1086 if (authType == "2" || authType == "5") { 1087 onSecurityProtocolChange(); 1088 } 1089 }); 1090 $("#security_protocol").change(onSecurityProtocolChange); 1091 } 1092 // Edit authentication 1093 if ($(".admin.edit.authentication").length > 0) { 1094 var authType = $("#auth_type").val(); 1095 if (authType == "2" || authType == "5") { 1096 $("#security_protocol").change(onSecurityProtocolChange); 1097 } 1098 } 1099 1100 // Notice 1101 if ($(".admin.notice")) { 1102 var $detailModal = $("#detail-modal"); 1103 1104 // Attach view detail modals 1105 $(".view-detail").click(function() {
1106 $detailModal.find(".content p").text($(this).data("content")); 1107 $detailModal.modal("show"); 1108 return false; 1109 }); 1110 1111 // Select actions 1112 var $checkboxes = $(".select.table .ui.checkbox"); 1113 $(".select.action").click(function() { 1114 switch ($(this).data("action")) { 1115 case "select-all": 1116 $checkboxes.checkbox("check"); 1117 break; 1118 case "deselect-all": 1119 $checkboxes.checkbox("uncheck"); 1120 break; 1121 case "inverse": 1122 $checkboxes.checkbox("toggle"); 1123 break; 1124 } 1125 }); 1126 $("#delete-selection").click(function() { 1127 var $this = $(this); 1128 $this.addClass("loading disabled"); 1129 var ids = []; 1130 $checkboxes.each(function() { 1131 if ($(this).checkbox("is checked")) { 1132 ids.push($(this).data("id")); 1133 } 1134 }); 1135 $.post($this.data("link"), { 1136 _csrf: csrf, 1137 ids: ids 1138 }).done(function() { 1139 window.location.href = $this.data("redirect"); 1140 }); 1141 }); 1142 } 1143} 1144 1145function buttonsClickOnEnter() { 1146 $(".ui.button").keypress(function(e) { 1147 if (e.keyCode == 13 || e.keyCode == 32) 1148 // enter key or space bar 1149 $(this).click(); 1150 }); 1151} 1152 1153function hideWhenLostFocus(body, parent) { 1154 $(document).click(function(e) { 1155 var target = e.target; 1156 if ( 1157 !$(target).is(body) && 1158 !$(target) 1159 .parents() 1160 .is(parent) 1161 ) { 1162 $(body).hide(); 1163 } 1164 }); 1165} 1166 1167function searchUsers() { 1168 if (!$("#search-user-box .results").length) { 1169 return; 1170 } 1171 1172 var $searchUserBox = $("#search-user-box"); 1173 var $results = $searchUserBox.find(".results"); 1174 $searchUserBox.keyup(function() { 1175 var $this = $(this); 1176 var keyword = $this.find("input").val(); 1177 if (keyword.length < 2) { 1178 $results.hide(); 1179 return; 1180 } 1181 1182 $.ajax({ 1183 url: suburl + "/api/v1/users/search?q=" + keyword, 1184 dataType: "json", 1185 success: function(response) { 1186 var notEmpty = function(str) { 1187 return str && str.length > 0; 1188 }; 1189 1190 $results.html(""); 1191 1192 if (response.ok && response.data.length) { 1193 var html = ""; 1194 $.each(response.data, function(i, item) { 1195 html += 1196 '<div class="item"><img class="ui avatar image" src="' + 1197 item.avatar_url + 1198 '"><span class="username">' + 1199 item.username + 1200 "</span>"; 1201 if (notEmpty(item.full_name)) { 1202 html += " (" + item.full_name + ")"; 1203 } 1204 html += "</div>"; 1205 }); 1206 $results.html(html); 1207 $this.find(".results .item").click(function() { 1208 $this.find("input").val( 1209 $(this) 1210 .find(".username") 1211 .text() 1212 ); 1213 $results.hide(); 1214 }); 1215 $results.show(); 1216 } else { 1217 $results.hide(); 1218 } 1219 } 1220 }); 1221 }); 1222 $searchUserBox.find("input").focus(function() { 1223 $searchUserBox.keyup(); 1224 }); 1225 hideWhenLostFocus("#search-user-box .results", "#search-user-box"); 1226} 1227 1228// FIXME: merge common parts in two functions 1229function searchRepositories() { 1230 if (!$("#search-repo-box .results").length) { 1231 return; 1232 } 1233 1234 var $searchRepoBox = $("#search-repo-box"); 1235 var $results = $searchRepoBox.find(".results"); 1236 $searchRepoBox.keyup(function() { 1237 var $this = $(this); 1238 var keyword = $this.find("input").val(); 1239 if (keyword.length < 2) { 1240 $results.hide(); 1241 return; 1242 } 1243 1244 $.ajax({ 1245 url: 1246 suburl + 1247 "/api/v1/repos/search?q=" + 1248 keyword + 1249 "&uid=" + 1250 $searchRepoBox.data("uid"), 1251 dataType: "json", 1252 success: function(response) { 1253 var notEmpty = function(str) { 1254 return str && str.length > 0; 1255 }; 1256 1257 $results.html(""); 1258 1259 if (response.ok && response.data.length) { 1260 var html = ""; 1261 $.each(response.data, function(i, item) { 1262 html += 1263 '<div class="item"><i class="octicon octicon-repo"></i> <span class="fullname">' + 1264 item.full_name + 1265 "</span></div>"; 1266 }); 1267 $results.html(html); 1268 $this.find(".results .item").click(function() { 1269 $this.find("input").val( 1270 $(this) 1271 .find(".fullname") 1272 .text() 1273 .split("/")[1] 1274 ); 1275 $results.hide(); 1276 }); 1277 $results.show(); 1278 } else { 1279 $results.hide(); 1280 } 1281 } 1282 }); 1283 }); 1284 $searchRepoBox.find("input").focus(function() { 1285 $searchRepoBox.keyup(); 1286 }); 1287 hideWhenLostFocus("#search-repo-box .results", "#search-repo-box"); 1288} 1289 1290function initCodeView() { 1291 if ($(".code-view .linenums").length > 0) { 1292 $(document).on("click", ".lines-num span", function(e) { 1293 var $select = $(this); 1294 var $list = $select 1295 .parent() 1296 .siblings(".lines-code") 1297 .find("ol.linenums > li"); 1298 selectRange( 1299 $list, 1300 $list.filter("[rel=" + $select.attr("id") + "]"), 1301 e.shiftKey ? $list.filter(".active").eq(0) : null 1302 ); 1303 deSelect(); 1304 }); 1305 1306 $(window) 1307 .on("hashchange", function(e) { 1308 var m = window.location.hash.match(/^#(L\d+)\-(L\d+)$/); 1309 var $list = $(".code-view ol.linenums > li"); 1310 var $first; 1311 if (m) { 1312 $first = $list.filter("." + m[1]); 1313 selectRange($list, $first, $list.filter("." + m[2])); 1314 $("html, body").scrollTop($first.offset().top - 200); 1315 return; 1316 } 1317 m = window.location.hash.match(/^#(L\d+)$/); 1318 if (m) { 1319 $first = $list.filter("." + m[1]); 1320 selectRange($list, $first); 1321 $("html, body").scrollTop($first.offset().top - 200); 1322 } 1323 }) 1324 .trigger("hashchange"); 1325 } 1326} 1327 1328function initUserSettings() { 1329 console.log("initUserSettings"); 1330 1331 // Options 1332 if ($(".user.settings.profile").length > 0) { 1333 $("#username").keyup(function() { 1334 var $prompt = $("#name-change-prompt"); 1335 if ( 1336 $(this) 1337 .val() 1338 .toString() 1339 .toLowerCase() != 1340 $(this) 1341 .data("name") 1342 .toString() 1343 .toLowerCase() 1344 ) { 1345 $prompt.show(); 1346 } else { 1347 $prompt.hide(); 1348 } 1349 }); 1350 } 1351} 1352 1353function initRepositoryCollaboration() { 1354 console.log("initRepositoryCollaboration"); 1355 1356 // Change collaborator access mode 1357 $(".access-mode.menu .item").click(function() { 1358 var $menu = $(this).parent(); 1359 $.post($menu.data("url"), { 1360 _csrf: csrf, 1361 uid: $menu.data("uid"), 1362 mode: $(this).data("value") 1363 }); 1364 }); 1365} 1366 1367function initWebhookSettings() { 1368 $(".events.checkbox input").change(function() { 1369 if ($(this).is(":checked")) { 1370 $(".events.fields").show(); 1371 } 1372 }); 1373 $(".non-events.checkbox input").change(function() { 1374 if ($(this).is(":checked")) { 1375 $(".events.fields").hide(); 1376 } 1377 }); 1378 1379 // Highlight payload on first click 1380 $(".hook.history.list .toggle.button").click(function() { 1381 $($(this).data("target") + " .nohighlight").each(function() { 1382 var $this = $(this); 1383 $this.removeClass("nohighlight"); 1384 setTimeout(function() { 1385 hljs.highlightBlock($this[0]); 1386 }, 500); 1387 }); 1388 }); 1389 1390 // Trigger delivery 1391 $(".delivery.button, .redelivery.button").click(function() { 1392 var $this = $(this); 1393 $this.addClass("loading disabled"); 1394 $.post($this.data("link"), { 1395 _csrf: csrf 1396 }).done( 1397 setTimeout(function() { 1398 window.location.href = $this.data("redirect"); 1399 }, 5000) 1400 ); 1401 }); 1402} 1403 1404$(document).ready(function() { 1405 csrf = $("meta[name=_csrf]").attr("content"); 1406 suburl = $("meta[name=_suburl]").attr("content"); 1407 1408 // Set cursor to the end of autofocus input string 1409 $("input[autofocus]").each(function() { 1410 $(this).val($(this).val()); 1411 }); 1412 1413 // Show exact time 1414 $(".time-since").each(function() { 1415 $(this) 1416 .addClass("poping up") 1417 .attr("data-content", $(this).attr("title")) 1418 .attr("data-variation", "inverted tiny") 1419 .attr("title", ""); 1420 }); 1421 1422 // Semantic UI modules. 1423 $(".ui.dropdown").dropdown({ 1424 forceSelection: false 1425 }); 1426 $(".jump.dropdown").dropdown({ 1427 action: "select", 1428 onShow: function() { 1429 $(".poping.up").popup("hide"); 1430 } 1431 }); 1432 $(".slide.up.dropdown").dropdown({ 1433 transition: "slide up" 1434 }); 1435 $(".upward.dropdown").dropdown({ 1436 direction: "upward" 1437 }); 1438 $(".ui.accordion").accordion(); 1439 $(".ui.checkbox").checkbox(); 1440 $(".ui.progress").progress({ 1441 showActivity: false 1442 }); 1443 $(".poping.up").popup(); 1444 $(".top.menu .poping.up").popup({ 1445 onShow: function() { 1446 if ($(".top.menu .menu.transition").hasClass("visible")) { 1447 return false;
1448 } 1449 } 1450 }); 1451 $(".tabular.menu .item").tab(); 1452 $(".tabable.menu .item").tab(); 1453 1454 $(".toggle.button").click(function() { 1455 $($(this).data("target")).slideToggle(100); 1456 }); 1457 1458 // Dropzone 1459 var $dropzone = $("#dropzone"); 1460 if ($dropzone.length > 0) { 1461 var filenameDict = {}; 1462 $dropzone.dropzone({ 1463 url: $dropzone.data("upload-url"), 1464 headers: { "X-CSRF-Token": csrf }, 1465 maxFiles: $dropzone.data("max-file"), 1466 maxFilesize: $dropzone.data("max-size"), 1467 timeout: 0, 1468 acceptedFiles: 1469 $dropzone.data("accepts") === "*/*" ? null : $dropzone.data("accepts"), 1470 addRemoveLinks: true, 1471 dictDefaultMessage: $dropzone.data("default-message"), 1472 dictInvalidFileType: $dropzone.data("invalid-input-type"), 1473 dictFileTooBig: $dropzone.data("file-too-big"), 1474 dictRemoveFile: $dropzone.data("remove-file"), 1475 init: function() { 1476 this.on("success", function(file, data) { 1477 filenameDict[file.name] = data.uuid; 1478 var input = $( 1479 '<input id="' + data.uuid + '" name="files" type="hidden">' 1480 ).val(data.uuid); 1481 $(".files").append(input); 1482 }); 1483 this.on("removedfile", function(file) { 1484 if (file.name in filenameDict) { 1485 $("#" + filenameDict[file.name]).remove(); 1486 } 1487 if ($dropzone.data("remove-url") && $dropzone.data("csrf")) { 1488 $.post($dropzone.data("remove-url"), { 1489 file: filenameDict[file.name], 1490 _csrf: $dropzone.data("csrf") 1491 }); 1492 } 1493 }); 1494 } 1495 }); 1496 } 1497 1498 // Emojify 1499 emojify.setConfig({ 1500 img_dir: suburl + "/img/emoji", 1501 ignore_emoticons: true 1502 }); 1503 var hasEmoji = document.getElementsByClassName("has-emoji"); 1504 for (var i = 0; i < hasEmoji.length; i++) { 1505 emojify.run(hasEmoji[i]); 1506 } 1507 1508 // Clipboard JS 1509 var clipboard = new ClipboardJS(".clipboard"); 1510 clipboard.on("success", function(e) { 1511 e.clearSelection(); 1512 1513 $("#" + e.trigger.getAttribute("id")).popup("destroy"); 1514 e.trigger.setAttribute( 1515 "data-content", 1516 e.trigger.getAttribute("data-success") 1517 ); 1518 $("#" + e.trigger.getAttribute("id")).popup("show"); 1519 e.trigger.setAttribute( 1520 "data-content", 1521 e.trigger.getAttribute("data-original") 1522 ); 1523 }); 1524 1525 clipboard.on("error", function(e) { 1526 $("#" + e.trigger.getAttribute("id")).popup("destroy"); 1527 e.trigger.setAttribute( 1528 "data-content", 1529 e.trigger.getAttribute("data-error") 1530 ); 1531 $("#" + e.trigger.getAttribute("id")).popup("show"); 1532 e.trigger.setAttribute( 1533 "data-content", 1534 e.trigger.getAttribute("data-original") 1535 ); 1536 }); 1537 1538 // Autosize 1539 if ($("#description.autosize").length > 0) { 1540 autosize($("#description")); 1541 showMessageMaxLength(512, "description", "descLength"); 1542 } 1543 1544 // AJAX load buttons 1545 $(".ajax-load-button").click(function() { 1546 var $this = $(this); 1547 $this.addClass("disabled"); 1548 1549 $.ajax({ 1550 url: $this.data("url"), 1551 headers: { 1552 "X-AJAX": "true" 1553 } 1554 }).done(function(data, status, request) { 1555 $(data).insertBefore($this); 1556 1557 // Update new URL or remove self if no more feeds 1558 var url = request.getResponseHeader("X-AJAX-URL"); 1559 if (url) { 1560 $this.data("url", url); 1561 $this.removeClass("disabled"); 1562 } else { 1563 $this.remove(); 1564 } 1565 }); 1566 }); 1567 1568 // Helpers 1569 $(".delete-button").click(function() { 1570 var $this = $(this); 1571 $(".delete.modal") 1572 .modal({ 1573 closable: false, 1574 onApprove: function() { 1575 if ($this.data("type") == "form") { 1576 $($this.data("form")).submit(); 1577 return; 1578 } 1579 1580 $.post($this.data("url"), { 1581 _csrf: csrf, 1582 id: $this.data("id") 1583 }).done(function(data) { 1584 window.location.href = data.redirect; 1585 }); 1586 } 1587 }) 1588 .modal("show"); 1589 return false; 1590 }); 1591 $(".show-panel.button").click(function() { 1592 $($(this).data("panel")).show(); 1593 }); 1594 $(".show-modal.button").click(function() { 1595 $($(this).data("modal")).modal("show"); 1596 }); 1597 $(".delete-post.button").click(function() { 1598 var $this = $(this); 1599 $.post($this.data("request-url"), {
1600 _csrf: csrf 1601 }).done(function() { 1602 window.location.href = $this.data("done-url"); 1603 }); 1604 }); 1605 // To make arbitrary form element to behave like a submit button 1606 $(".submit-button").click(function() { 1607 $($(this).data("form")).submit(); 1608 }); 1609 1610 // Check or select on option to enable/disable target region 1611 $(".enable-system").change(function() { 1612 if (this.checked) { 1613 $($(this).data("target")).removeClass("disabled"); 1614 } else { 1615 $($(this).data("target")).addClass("disabled"); 1616 $($(this).data("uncheck")).prop("checked", false); 1617 } 1618 }); 1619 $(".enable-system-radio").change(function() { 1620 $($(this).data("enable")).removeClass("disabled"); 1621 $($(this).data("disable")).addClass("disabled"); 1622 $($(this).data("uncheck")).prop("checked", false); 1623 }); 1624 1625 // Set anchor. 1626 $(".markdown").each(function() { 1627 var headers = {}; 1628 $(this) 1629 .find("h1, h2, h3, h4, h5, h6") 1630 .each(function() { 1631 var node = $(this); 1632 var val = encodeURIComponent( 1633 node 1634 .text() 1635 .toLowerCase()
1636 .replace(/[^\u00C0-\u1FFF\u2C00-\uD7FF\w\- ]/g, "") 1637 .replace(/[ ]/g, "-") 1638 ); 1639 var name = val; 1640 if (headers[val] > 0) { 1641 name = val + "-" + headers[val]; 1642 } 1643 if (headers[val] == undefined) { 1644 headers[val] = 1; 1645 } else { 1646 headers[val] += 1; 1647 } 1648 node = node.wrap('<div id="' + name + '" class="anchor-wrap" ></div>'); 1649 node.append( 1650 '<a class="anchor" href="#' + 1651 name + 1652 '"><span class="octicon octicon-link"></span></a>' 1653 ); 1654 }); 1655 }); 1656 1657 buttonsClickOnEnter(); 1658 searchUsers(); 1659 searchRepositories(); 1660 1661 initCommentForm(); 1662 initRepository(); 1663 initWikiForm(); 1664 initEditForm(); 1665 initEditor(); 1666 initOrganization(); 1667 initAdmin(); 1668 initCodeView(); 1669 1670 // Repo clone url. 1671 if ($("#repo-clone-url").length > 0) { 1672 switch (localStorage.getItem("repo-clone-protocol")) { 1673 case "ssh": 1674 if ($("#repo-clone-ssh").click().length === 0) { 1675 $("#repo-clone-https").click(); 1676 } 1677 break; 1678 default: 1679 $("#repo-clone-https").click(); 1680 break; 1681 } 1682 } 1683 1684 var routes = { 1685 "div.user.settings": initUserSettings, 1686 "div.repository.settings.collaboration": initRepositoryCollaboration, 1687 "div.webhook.settings": initWebhookSettings 1688 }; 1689 1690 var selector; 1691 for (selector in routes) { 1692 if ($(selector).length > 0) { 1693 routes[selector](); 1694 break; 1695 } 1696 } 1697}); 1698 1699function changeHash(hash) { 1700 if (history.pushState) { 1701 history.pushState(null, null, hash); 1702 } else { 1703 location.hash = hash; 1704 } 1705} 1706 1707function deSelect() { 1708 if (window.getSelection) { 1709 window.getSelection().removeAllRanges(); 1710 } else { 1711 document.selection.empty(); 1712 } 1713} 1714 1715function selectRange($list, $select, $from) { 1716 $list.removeClass("active"); 1717 if ($from) { 1718 var a = parseInt($select.attr("rel").substr(1)); 1719 var b = parseInt($from.attr("rel").substr(1)); 1720 var c; 1721 if (a != b) { 1722 if (a > b) { 1723 c = a; 1724 a = b; 1725 b = c; 1726 } 1727 var classes = []; 1728 for (var i = a; i <= b; i++) { 1729 classes.push(".L" + i); 1730 } 1731 $list.filter(classes.join(",")).addClass("active"); 1732 changeHash("#L" + a + "-" + "L" + b); 1733 return; 1734 } 1735 } 1736 $select.addClass("active"); 1737 changeHash("#" + $select.attr("rel")); 1738} 1739 1740$(function() { 1741 if ($(".user.signin").length > 0) return; 1742 $("form").areYouSure(); 1743}); 1744 1745// getByteLen counts bytes in a string's UTF-8 representation. 1746function getByteLen(normalVal) { 1747 // Force string type 1748 normalVal = String(normalVal); 1749 1750 var byteLen = 0; 1751 for (var i = 0; i < normalVal.length; i++) { 1752 var c = normalVal.charCodeAt(i); 1753 byteLen += 1754 c < 1 << 7 1755 ? 1 1756 : c < 1 << 11 1757 ? 2 1758 : c < 1 << 16 1759 ? 3 1760 : c < 1 << 21 1761 ? 4 1762 : c < 1 << 26 1763 ? 5 1764 : c < 1 << 31 1765 ? 6 1766 : Number.NaN; 1767 } 1768 return byteLen; 1769} 1770 1771function showMessageMaxLength(maxLen, textElemId, counterId) { 1772 var $msg = $("#" + textElemId); 1773 $("#" + counterId).html(maxLen - getByteLen($msg.val())); 1774 1775 var onMessageKey = function(e) { 1776 var $msg = $(this); 1777 var text = $msg.val(); 1778 var len = getByteLen(text); 1779 var remainder = maxLen - len; 1780 1781 if (len >= maxLen) { 1782 $msg.val($msg.val().substr(0, maxLen)); 1783 remainder = 0; 1784 } 1785 1786 $("#" + counterId).html(remainder); 1787 }; 1788 1789 $msg.keyup(onMessageKey).keydown(onMessageKey); 1790}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.