1/* 2# Mantis - a php based bugtracking system 3 4# Copyright 2000 - 2002 Kenzaburo Ito - [email protected] 5# Copyright 2002 MantisBT Team - [email protected] 6 7# Mantis is free software: you can redistribute it and/or modify 8# it under the terms of the GNU General Public License as published by 9# the Free Software Foundation, either version 2 of the License, or 10# (at your option) any later version. 11# 12# Mantis is distributed in the hope that it will be useful, 13# but WITHOUT ANY WARRANTY; without even the implied warranty of 14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15# GNU General Public License for more details. 16# 17# You should have received a copy of the GNU General Public License 18# along with Mantis. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21/* 22 * Collapsible element functions 23 */ 24var g_collapse_clear = 1; 25 26// global code to determine how to set visibility 27var a = navigator.userAgent.indexOf("MSIE"); 28var style_display; 29 30if (a!= -1) { 31 style_display = 'block'; 32} else { 33 style_display = 'table-row'; 34} 35style_display = 'block'; 36 37$(document).ready( function() { 38 $('.collapse-open').show(); 39 $('.collapse-closed').hide(); 40 $('.collapse-link').click( function(event) { 41 event.preventDefault(); 42 var id = $(this).attr('id'); 43 var t_pos = id.indexOf('_closed_link' ); 44 if( t_pos == -1 ) { 45 t_pos = id.indexOf('_open_link' ); 46 } 47 var t_div = id.substring(0, t_pos ); 48 ToggleDiv( t_div ); 49 }); 50 51 var options = { 52 valueNames: [ 'project-link' ] 53 }; 54 var list = new List('projects-list', options); 55 if(list.items.length <= 10) { 56 $('#projects-list .searchbox').hide(); 57 } 58 59 $('.widget-box').on('shown.ace.widget' , function(event) { 60 var t_id = $(this).attr('id'); 61 var t_cookie = GetCookie( "collapse_settings" ); 62 if ( 1 == g_collapse_clear ) { 63 t_cookie = ""; 64 g_collapse_clear = 0; 65 } 66 t_cookie = t_cookie.replace("|" + t_id + ":1", '' ); 67 t_cookie = t_cookie + "|" + t_id + ":0"; 68 SetCookie( "collapse_settings", t_cookie ); 69 }); 70 71 $('.widget-box').on('hidden.ace.widget' , function(event) { 72 var t_id = $(this).attr('id'); 73 var t_cookie = GetCookie( "collapse_settings" ); 74 if ( 1 == g_collapse_clear ) { 75 t_cookie = ""; 76 g_collapse_clear = 0; 77 } 78 t_cookie = t_cookie.replace( "|" + t_id + ":0", '' ); 79 t_cookie = t_cookie + "|" + t_id + ":1"; 80 SetCookie( "collapse_settings", t_cookie ); 81 }); 82 83 $('#sidebar.sidebar-toggle').on('click', function (event) { 84 var t_id = $(this).attr('id'); 85 var t_cookie = GetCookie("collapse_settings"); 86 if (1 == g_collapse_clear) { 87 t_cookie = ""; 88 g_collapse_clear = 0; 89 } 90 if( $(this).parent().hasClass( "menu-min" ) ) { 91 t_cookie = t_cookie.replace("|" + t_id + ":1", ''); 92 t_cookie = t_cookie + "|" + t_id + ":0"; 93 } else { 94 t_cookie = t_cookie.replace("|" + t_id + ":0", ''); 95 t_cookie = t_cookie + "|" + t_id + ":1"; 96 } 97 SetCookie("collapse_settings", t_cookie); 98 }); 99 100 $('input[type=text].typeahead').each(function() { 101 var $this = $(this); 102 $(this).typeahead({ 103 minLength: 1, 104 highlight: true 105 }, { 106 source: function (query, undefined, callback) { 107 var params = {}; 108 params['field'] = $this[0].id; 109 params['prefix'] = query; 110 $.getJSON('api/rest/internal/autocomplete', params, function (data) { 111 var results = []; 112 $.each(data, function (i, value) { 113 results.push(value); 114 }); 115 callback(results); 116 }); 117 } 118 }); 119 }); 120 121 $('a.dynamic-filter-expander').click(function(event) { 122 event.preventDefault(); 123 var fieldID = $(this).attr('id'); 124 var filter_id = $(this).data('filter_id'); 125 var filter_tmp_id = $(this).data('filter'); 126 var targetID = fieldID + '_target'; 127 var viewType = $('#filters_form_open input[name=view_type]').val(); 128 $('#' + targetID).html('<span class="dynamic-filter-loading">' + translations['loading'] + "</span>"); 129 var params = 'view_type=' + viewType + '&filter_target=' + fieldID; 130 if( undefined !== filter_id ) { 131 params += '&filter_id=' + filter_id; 132 } 133 if( undefined !== filter_tmp_id ) { 134 params += '&filter=' + filter_tmp_id; 135 } 136 $.ajax({ 137 url: 'return_dynamic_filters.php', 138 data: params, 139 cache: false, 140 context: $('#' + targetID), 141 success: function(html) { 142 $(this).html(html); 143 }, 144 error: function(obj,status,error) { 145 $(this).html('<span class="error-msg">' + status + ': ' + error + '</span>'); 146 } 147 }); 148 }); 149 150 $('input.autofocus:first, select.autofocus:first, textarea.autofocus:first').focus(); 151 152 var checkAllSelectors = ''; 153 $(':checkbox.check_all').each(function() { 154 var baseFieldName = $(this).attr('name').replace(/_all$/, ''); 155 if (checkAllSelectors.length > 0) { 156 checkAllSelectors += ', '; 157 } 158 checkAllSelectors += ':checkbox[name="' + baseFieldName + '[]"]'; 159 }); 160 if (checkAllSelectors.length > 0) { 161 $(checkAllSelectors).click(function() { 162 var fieldName = $(this).attr('name').replace(/\[\]/g, ''); 163 var checkedCount = $(this).closest('form').find(':checkbox[name="' + fieldName + '[]"]:checked').length; 164 var totalCount = $(this).closest('form').find(':checkbox[name="' + fieldName + '[]"]').length; 165 var allSelected = checkedCount == totalCount; 166 $(this).closest('form').find(':checkbox[name=' + fieldName + '_all]').prop('checked', allSelected); 167 }); 168 $(':checkbox.check_all').click(function() { 169 var baseFieldName = $(this).attr('name').replace(/_all$/, ''); 170 $(this).closest('form').find(':checkbox[name="' + baseFieldName + '[]"]').prop('checked', $(this).is(':checked')); 171 }); 172 } 173 174 var stopwatch = { 175 timerID: 0, 176 startTime: null, 177 zeroTime: moment('0', 's'), 178 tick: function() { 179 var elapsedDiff = moment().diff(this.startTime), 180 elapsedTime = this.zeroTime.clone().add(elapsedDiff); 181 182 $('input[type=text].stopwatch_time').val(elapsedTime.format('HH:mm:ss')); 183 }, 184 reset: function() { 185 this.stop(); 186 $('input[type=text].stopwatch_time').val(''); 187 }, 188 start: function() { 189 var self = this, 190 timeFormat = '', 191 stoppedTime = $('input[type=text].stopwatch_time').val(); 192 193 this.stop(); 194 195 if (stoppedTime) { 196 switch (stoppedTime.split(':').length) { 197 case 1: 198 timeFormat = 'ss'; 199 break; 200 201 case 2: 202 timeFormat = 'mm:ss'; 203 break; 204 205 default: 206 timeFormat = 'HH:mm:ss'; 207 } 208 209 this.startTime = moment().add(this.zeroTime.clone().diff(moment(stoppedTime, timeFormat))); 210 } else { 211 this.startTime = moment(); 212 } 213 214 this.timerID = window.setInterval(function() { 215 self.tick(); 216 }, 1000); 217 218 $('input[type=button].stopwatch_toggle').val(translations['time_tracking_stopwatch_stop']); 219 }, 220 stop: function() { 221 if (this.timerID) { 222 window.clearInterval(this.timerID); 223 this.timerID = 0; 224 } 225 226 $('input[type=button].stopwatch_toggle').val(translations['time_tracking_stopwatch_start']); 227 } 228 }; 229 230 $('input[type=button].stopwatch_toggle').click(function() { 231 if (!stopwatch.timerID) { 232 stopwatch.start(); 233 } else { 234 stopwatch.stop(); 235 } 236 }); 237 238 $('input[type=button].stopwatch_reset').click(function() { 239 stopwatch.reset(); 240 }); 241 242 $('input[type=text].datetimepicker').each(function(index, element) { 243 $(this).datetimepicker({ 244 locale: $(this).data('picker-locale'), 245 format: $(this).data('picker-format'), 246 useCurrent: false, 247 icons: { 248 time: 'fa fa-clock-o', 249 date: 'fa fa-calendar', 250 up: 'fa fa-chevron-up', 251 down: 'fa fa-chevron-down', 252 previous: 'fa fa-chevron-left', 253 next: 'fa fa-chevron-right', 254 today: 'fa fa-arrows ',
255 clear: 'fa fa-trash', 256 close: 'fa fa-times' 257 } 258 }).next().on(ace.click_event, function() { 259 $(this).prev().focus(); 260 }); 261 }); 262 263 $( 'form .dropzone' ).each(function(){ 264 var classPrefix = 'dropzone'; 265 var autoUpload = $(this).hasClass('auto-dropzone'); 266 enableDropzone( classPrefix, autoUpload ); 267 }); 268 269 $('.bug-jump').find('[name=bug_id]').focus( function() { 270 var bug_label = $('.bug-jump-form').find('[name=bug_label]').val(); 271 if( $(this).val() == bug_label ) { 272 $(this).val(''); 273 $(this).removeClass('field-default'); 274 } 275 }); 276 $('.bug-jump').find('[name=bug_id]').blur( function() { 277 var bug_label = $('.bug-jump-form').find('[name=bug_label]').val(); 278 if( $(this).val() == '' ) { 279 $(this).val(bug_label); 280 $(this).addClass('field-default'); 281 } 282 }); 283 $('[name=source_query_id]').change( function() { 284 $(this).parent().submit(); 285 }); 286 287 /* Project selector: auto-switch on select */ 288 $('#form-set-project-id').change( function() { 289 $('#form-set-project').submit(); 290 }); 291 $('#project-selector').children('.button').hide(); 292 293 setBugLabel(); 294 295 /* Handle standard filter date fields */ 296 $(document).on('change', '.js_switch_date_inputs_trigger', function() { 297 $(this).closest('table') 298 .find('select') 299 .prop('disabled', !$(this).prop('checked')); 300 }); 301 302 /* Handle custom field of date type */ 303 $(document).on('change', 'select[name^=custom_field_][name$=_control]', function() { 304 var table = $(this).closest('table'); 305 switch(this.value) { 306 case '2': // between 307 $(table).find("select[name*=_start_year]").prop('disabled', false); 308 $(table).find("select[name*=_start_month]").prop('disabled', false); 309 $(table).find("select[name*=_start_day]").prop('disabled', false); 310 $(table).find("select[name*=_end_year]").prop('disabled', false); 311 $(table).find("select[name*=_end_month]").prop('disabled', false); 312 $(table).find("select[name*=_end_day]").prop('disabled', false); 313 break; 314 315 case '3': // on or before 316 case '4': // before 317 case '5': // on 318 case '6': // after 319 case '7': // on or after 320 $(table).find("select[name*=_start_year]").prop('disabled', false); 321 $(table).find("select[name*=_start_month]").prop('disabled', false); 322 $(table).find("select[name*=_start_day]").prop('disabled', false); 323 $(table).find("select[name*=_end_year]").prop('disabled', true); 324 $(table).find("select[name*=_end_month]").prop('disabled', true); 325 $(table).find("select[name*=_end_day]").prop('disabled', true); 326 break; 327 328 case '0': // any 329 case '1': // none 330 default: 331 $(table).find("select[name*=_start_year]").prop('disabled', true); 332 $(table).find("select[name*=_start_month]").prop('disabled', true); 333 $(table).find("select[name*=_start_day]").prop('disabled', true); 334 $(table).find("select[name*=_end_year]").prop('disabled', true); 335 $(table).find("select[name*=_end_month]").prop('disabled', true); 336 $(table).find("select[name*=_end_day]").prop('disabled', true); 337 break; 338 } 339 }); 340 341 /* For Period.php bundled with the core MantisGraph plugin */ 342 $('#dates > input[type=image].datetime').hide(); 343 $('#period_menu > select#interval').change(function() { 344 if ($(this).val() == 10) { 345 $('#dates > input[type=text].datetime').prop('disabled', false); 346 $('#dates > input[type=image].datetime').show(); 347 } else { 348 $('#dates > input[type=text].datetime').prop('disabled', true); 349 $('#dates > input[type=image].datetime').hide(); 350 } 351 }); 352 353 $(document).on('change', '#tag_select', function() { 354 var tagSeparator = $('#tag_separator').val(); 355 var currentTagString = $('#tag_string').val(); 356 var newTagOptionID = $(this).val(); 357 var newTag = $('#tag_select option[value=' + newTagOptionID + ']').text(); 358 if (currentTagString.indexOf(newTag) == -1) { 359 if (currentTagString.length > 0) { 360 $('#tag_string').val(currentTagString + tagSeparator + newTag); 361 } else { 362 $('#tag_string').val(newTag); 363 } 364 } 365 $(this).val(0); 366 }); 367 368 $('a.click-url').bind("click", function() { 369 $(this).attr("href", $(this).attr("url")); 370 }); 371 372 $('input[name=private].ace').bind("click", function() { 373 if ($(this).is(":checked")){ 374 $('textarea[name=bugnote_text]').addClass("bugnote-private"); 375 $('tr[id=bugnote-attach-files]').hide(); 376 } else { 377 $('textarea[name=bugnote_text]').removeClass("bugnote-private"); 378 $('tr[id=bugnote-attach-files]').show(); 379 } 380 }); 381 382 $(document).on('shown.bs.dropdown', '#dropdown_projects_menu', function() { 383 $(this).find(".dropdown-menu li.active a").focus(); 384 }); 385 386 /** 387 * Manage visiblity on hover trigger objects 388 */ 389 if( $('.visible-on-hover-toggle').length ) { 390 $('.visible-on-hover-toggle').hover( 391 function(e){ // handlerIn 392 $(e.currentTarget).find('.visible-on-hover').removeClass('invisible'); 393 }, 394 function(e){ // handlerOut 395 $(e.currentTarget).find('.visible-on-hover').addClass('invisible'); 396 } 397 ); 398 $('.visible-on-hover').addClass('invisible'); 399 } 400}); 401 402function setBugLabel() { 403 var bug_label = $('.bug-jump-form').find('[name=bug_label]').val(); 404 var field = $('.bug-jump').find('[name=bug_id]'); 405 if( field.val() == '' ) { 406 field.val(bug_label); 407 field.addClass('field-default'); 408 } 409} 410 411/* 412 * String manipulation 413 */ 414function Trim( p_string ) { 415 if (typeof p_string != "string") { 416 return p_string; 417 } 418 419 var t_string = p_string; 420 var t_ch = ''; 421
422 // Trim beginning spaces 423 424 t_ch = t_string.substring( 0, 1 ); 425 while ( t_ch == " " ) { 426 t_string = t_string.substring( 1, t_string.length ); 427 t_ch = t_string.substring( 0, 1 ); 428 } 429 430 // Trim trailing spaces 431 432 t_ch = t_string.substring( t_string.length-1, t_string.length ); 433 while ( t_ch == " " ) { 434 t_string = t_string.substring( 0, t_string.length-1 ); 435 t_ch = t_string.substring( t_string.length-1, t_string.length ); 436 } 437 438 return t_string; 439} 440 441/* 442 * Cookie functions 443 */ 444function GetCookie( p_cookie ) { 445 var t_cookie_name = "MANTIS_" + p_cookie; 446 var t_cookies = document.cookie; 447 448 t_cookies = t_cookies.split( ";" ); 449 450 var i = 0; 451 while( i < t_cookies.length ) { 452 var t_cookie = t_cookies[ i ]; 453 454 t_cookie = t_cookie.split( "=" ); 455 456 if ( Trim( t_cookie[ 0 ] ) == t_cookie_name ) { 457 return( t_cookie[ 1 ] ); 458 } 459 i++; 460 } 461 462 return -1; 463} 464 465function SetCookie( p_cookie, p_value ) { 466 var t_cookie_name = "MANTIS_" + p_cookie; 467 var t_expires = new Date(); 468 469 t_expires.setTime( t_expires.getTime() + (365 * 24 * 60 * 60 * 1000)); 470 471 document.cookie = t_cookie_name + "=" + p_value + "; expires=" + t_expires.toUTCString() + ";"; 472} 473 474function ToggleDiv( p_div ) { 475 var t_open_div = '#' + p_div + "_open"; 476 var t_closed_div = '#' + p_div + "_closed"; 477 478 var t_cookie = GetCookie( "collapse_settings" ); 479 if ( 1 == g_collapse_clear ) { 480 t_cookie = ""; 481 g_collapse_clear = 0; 482 } 483 var t_open_display = $(t_open_div).css('display'); 484 $(t_open_div).toggle(); 485 486 if( $(t_closed_div).length ) { 487 $(t_closed_div).toggle(); 488 } 489 490 if ( t_open_display == "none" ) { 491 t_cookie = t_cookie.replace( "|" + p_div + ":0", '' ); 492 t_cookie = t_cookie + "|" + p_div + ":1"; 493 } else { 494 t_cookie = t_cookie.replace( "|" + p_div + ":1", '' ); 495 t_cookie = t_cookie + "|" + p_div + ":0"; 496 } 497 498 SetCookie( "collapse_settings", t_cookie ); 499} 500 501function setDisplay(idTag, state) 502{ 503 if(!document.getElementById(idTag)) alert('SetDisplay(): id '+idTag+' is empty'); 504 // change display visibility 505 if ( state != 0 ) { 506 document.getElementById(idTag).style.display = style_display; 507 } else { 508 document.getElementById(idTag).style.display = 'none'; 509 } 510} 511 512function toggleDisplay(idTag) 513{ 514 setDisplay( idTag, (document.getElementById(idTag).style.display == 'none')?1:0 ); 515} 516 517// Dropzone handler 518Dropzone.autoDiscover = false; 519function enableDropzone( classPrefix, autoUpload ) { 520 var zone_class = '.' + classPrefix; 521 var zone = $( zone_class ); 522 var form = zone.closest('form'); 523 try { 524 var zone_object = new Dropzone( form[0], { 525 forceFallback: zone.data('force-fallback'), 526 paramName: "ufile", 527 autoProcessQueue: autoUpload, 528 clickable: zone_class, 529 previewsContainer: '#' + classPrefix + '-previews-box', 530 uploadMultiple: true, 531 parallelUploads: 100, 532 maxFilesize: zone.data('max-filesize'), 533 addRemoveLinks: !autoUpload, 534 acceptedFiles: zone.data('accepted-files'), 535 previewTemplate: "<div class=\"dz-preview dz-file-preview\">\n <div class=\"dz-details\">\n <div class=\"dz-filename\"><span data-dz-name></span></div>\n <div class=\"dz-size\" data-dz-size></div>\n <img data-dz-thumbnail />\n </div>\n <div class=\"progress progress-small progress-striped active\"><div class=\"progress-bar progress-bar-success\" data-dz-uploadprogress></div></div>\n <div class=\"dz-success-mark\"><span></span></div>\n <div class=\"dz-error-mark\"><span></span></div>\n <div class=\"dz-error-message\"><span data-dz-errormessage></span></div>\n</div>", 536 dictDefaultMessage: zone.data('default-message'), 537 dictFallbackMessage: zone.data('fallback-message'), 538 dictFallbackText: zone.data('fallback-text'), 539 dictFileTooBig: zone.data('file-too-big'), 540 dictInvalidFileType: zone.data('invalid-file-type'), 541 dictResponseError: zone.data('response-error'), 542 dictCancelUpload: zone.data('cancel-upload'), 543 dictCancelUploadConfirmation: zone.data('cancel-upload-confirmation'), 544 dictRemoveFile: zone.data('remove-file'), 545 dictRemoveFileConfirmation: zone.data('remove-file-confirmation'), 546 dictMaxFilesExceeded: zone.data('max-files-exceeded'), 547 548 init: function () { 549 var dropzone = this; 550 var form = $( this.options.clickable ).closest('form'); 551 form.on('submit', function (e) { 552 if( dropzone.getQueuedFiles().length ) { 553 e.preventDefault(); 554 e.stopPropagation(); 555 dropzone.processQueue(); 556 } 557 }); 558 this.on( "successmultiple", function( files, response ) { 559 document.open(); 560 document.write( response ); 561 document.close(); 562 }); 563 }, 564 fallback: function() { 565 if( $( "." + classPrefix ).length ) { 566 $( "." + classPrefix ).hide(); 567 } 568 } 569 }); 570 } catch (e) { 571 alert( zone.data('dropzone-not-supported') ); 572 } 573}
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.