1const DATATABLE_OPTIONS = { 2 // responsive: true, 3 paging: false, 4 language: { 5 sProcessing: _t('DATATABLES_PROCESSING'), 6 sSearch: _t('DATATABLES_SEARCH'), 7 sLengthMenu: _t('DATATABLES_LENGTHMENU'), 8 sInfo: _t('DATATABLES_INFO'), 9 sInfoEmpty: _t('DATATABLES_INFOEMPTY'), 10 sInfoFiltered: _t('DATATABLES_INFOFILTERED'), 11 sInfoPostFix: '', 12 sLoadingRecords: _t('DATATABLES_LOADINGRECORDS'), 13 sZeroRecords: _t('DATATABLES_ZERORECORD'), 14 sEmptyTable: _t('DATATABLES_EMPTYTABLE'), 15 oPaginate: { 16 sFirst: _t('FIRST'), 17 sPrevious: _t('PREVIOUS'), 18 sNext: _t('NEXT'), 19 sLast: _t('LAST'), 20 }, 21 oAria: { 22 sSortAscending: _t('DATATABLES_SORTASCENDING'), 23 sSortDescending: _t('DATATABLES_SORTDESCENDING'), 24 }, 25 }, 26 fixedHeader: { 27 header: true, 28 footer: false, 29 }, 30 dom: 31 "<'row'<'col-sm-6'l><'col-sm-6'f>>" + 32 "<'row'<'col-sm-12'tr>>" + 33 "<'row'<'col-sm-6'i><'col-sm-6'<'pull-right'B>>>", 34 buttons: [ 35 { 36 extend: 'copy', 37 className: 'btn btn-default', 38 text: `<i class="far fa-copy"></i> ${_t('COPY')}`, 39 }, 40 { 41 extend: 'csv', 42 className: 'btn btn-default', 43 text: '<i class="fas fa-file-csv"></i> CSV', 44 }, 45 { 46 extend: 'print', 47 className: 'btn btn-default', 48 text: `<i class="fas fa-print"></i> ${_t('PRINT')}`, 49 }, 50 // { 51 // extend: 'colvis', 52 // text: _t('DATATABLES_COLS_TO_DISPLAY') 53 // }, 54 ], 55} 56 57function toastMessage( 58 message, 59 duration = 3000, 60 toastClass = 'alert alert-secondary-1', 61) { 62 const innerEl = document.createElement('div') 63 innerEl.className = toastClass 64 innerEl.textContent = message 65 const toastEl = document.createElement('div') 66 toastEl.className = 'toast-message' 67 toastEl.appendChild(innerEl) 68 const $toast = $(toastEl) 69 $('body').after($toast) 70 $toast.css('top', `${$('#yw-topnav').outerHeight(true) + 20}px`) 71 $toast.css('opacity', 1) 72 setTimeout(() => { 73 $toast.css('opacity', 0) 74 }, duration) 75 setTimeout(() => { 76 $toast.remove() 77 }, duration + 300) 78 $toast.addClass('visible') 79} 80// polyfill placeholder 81;(function ($) { 82 $('input[type=password]').each(function () { 83 const vMe = $(this) 84 85 $('<div>') 86 .addClass('far fa-eye') 87 .attr('title', _t('SHOW_PASSWORD')) 88 .css({ 89 position: 'absolute', 90 right: '0%', 91 top: '50%', 92 transform: 'translate(0px, -50%)', 93 paddingRight: '1em', 94 fontSize: '1em', 95 }) 96 .on('click', function () { 97 if (vMe.attr('type') == 'password') { 98 vMe.attr('type', 'text') 99 $(this) 100 .removeClass('fa-eye') 101 .attr('title', _t('HIDE_PASSWORD')) 102 .addClass('fa-eye-slash') 103 } else { 104 vMe.attr('type', 'password') 105 $(this) 106 .addClass('fa-eye') 107 .removeClass('fa-eye-slash') 108 .attr('title', _t('SHOW_PASSWORD')) 109 } 110 }) 111 .insertAfter($(this)) 112 }) 113 114 // gestion des classes actives pour les menus 115 $('a.active-link') 116 .parent() 117 .addClass('active-list') 118 .parents('ul') 119 .prev('a') 120 .addClass('active-parent-link') 121 .parent() 122 .addClass('active-list') 123 124 function addIframeHandlerTo(url) { 125 const regexHasHandler = new RegExp(/\??.*\/(edit)?iframe(&.*)?/g) 126 const regexOnDomain = new RegExp(`^${wiki.baseUrl}`) 127 if (regexHasHandler.test(url)) { 128 return url 129 } 130 if (regexOnDomain.test(url)) { 131 return `${url}/iframe` 132 } 133 return url 134 } 135 136 // fenetres modales 137 function openModal(e) { 138 e.stopPropagation() 139 e.preventDefault() 140 const $this = $(this) 141 const titleText = $this.attr('title') || '' 142 const size = ` ${$this.data('size')}` 143 const iframe = $this.data('iframe') 144 145 let $modal = $('#YesWikiModal') 146 const yesWikiModalHtml = ` 147 <div class="modal-dialog${size} ${$this.data('header') === false ? 'no-header' : ''}"> 148 <div class="modal-content"> 149 <div class="modal-header"> 150 <button type="button" class="close" data-dismiss="modal">×</button> 151 <h3></h3> 152 </div> 153 <div class="modal-body"></div> 154 <button type="button" class="no-header-btn-close" data-dismiss="modal">×</button> 155 </div> 156 </div>` 157 158 if ($modal.length === 0) { 159 $('body').append( 160 `<div class="modal fade" id="YesWikiModal">${yesWikiModalHtml}</div>`, 161 ) 162 $modal = $('#YesWikiModal') 163 } else { 164 $modal.html(yesWikiModalHtml) 165 } 166 if (titleText.length > 0) {
167 $modal.find('.modal-header h3').text($.trim(titleText)) 168 } 169 170 let link = $this.attr('href') 171 if (/\.(gif|jpg|jpeg|tiff|png)$/i.test(link)) { 172 $modal 173 .find('.modal-body') 174 .html( 175 `<img loading="lazy" class="center-block img-responsive" src="${link}" alt="" />`, 176 ) 177 } else if (iframe === 1) { 178 const modalTitle = $modal.find('.modal-header h3') 179 if (modalTitle.length > 0) { 180 const anchorText = 181 modalTitle[0].innerText === 0 182 ? link.substr(0, 128) 183 : modalTitle[0].innerText 184 $(modalTitle[0]) 185 .empty() 186 .append($('<a>').attr('href', link).text(anchorText)) 187 } 188 link = addIframeHandlerTo(link) 189 $modal 190 .find('.modal-body') 191 .html( 192 '<span id="yw-modal-loading" class="throbber"></span>' + 193 `<iframe id="yw-modal-iframe" src="${link}" referrerpolicy="no-referrer"></iframe>`, 194 ) 195 $('#yw-modal-iframe').on('load', () => { 196 $('#yw-modal-loading').hide() 197 }) 198 } else { 199 // incomingurl can be usefull (per example for deletepage handler) 200 try { 201 const url = document.createElement('a') 202 url.href = link 203 const queryString = url.search 204 let separator 205 if (!queryString || queryString.length === 0) { 206 separator = '?' 207 } else { 208 separator = '&' 209 } 210 link += `${separator}incomingurl=${encodeURIComponent( 211 window.location.toString(), 212 )}` 213 } catch (er) { 214 console.error(er) 215 } 216 // AJAX Request for javascripts 217 const xhttp = new XMLHttpRequest() 218 xhttp.onreadystatechange = function () { 219 if (this.readyState === 4 && this.status === 200) { 220 const xmlString = this.responseText 221 const doc = new DOMParser().parseFromString(xmlString, 'text/html') 222 // find scripts 223 const res = doc.scripts 224 const l = res.length 225 let i 226 for (i = 0; i < l; i++) { 227 const src = res[i].getAttribute('src') 228 if (src) { 229 var selection = document.querySelectorAll(`script[src="${src}"]`) 230 if (!selection || selection.length == 0) { 231 // append script and load it only if not present 232 if (res[i].type === 'module') { 233 const newScript = document.createElement('script') 234 newScript.type = 'module' 235 newScript.src = src 236 document.body.appendChild(newScript) 237 } else { 238 document.body.appendChild(document.importNode(res[i])) 239 $.getScript(src) 240 } 241 } 242 } else { 243 const script = res[i].innerHTML 244 // select all script of current page without src 245 const pageScripts = document.scripts 246 const selLenght = pageScripts.length 247 var j 248 for (j = 0; j < selLenght; j++) { 249 if ( 250 !pageScripts[j].hasAttribute('src') && 251 script != pageScripts[j].innerHTML 252 ) { 253 const newScript = document.importNode(res[i]) 254 document.body.appendChild(newScript) 255 } 256 } 257 } 258 } 259 // find css 260 const importedCSS = doc.querySelectorAll('link[rel="stylesheet"]') 261 const le = importedCSS.length 262 for (i = 0; i < le; i++) { 263 const href = importedCSS[i].getAttribute('href') 264 if (href) { 265 const existingLink = document.querySelector( 266 `link[href="${href}"]`, 267 ) 268 if (!existingLink || existingLink.length === 0) { 269 // append link 270 document.body.appendChild(document.importNode(importedCSS[i])) 271 } 272 } 273 } 274 // AJAX Request for content 275 $modal.find('.modal-body').load(`${link} .page`, () => { 276 $(document).trigger('yw-modal-open') 277 return false 278 }) 279 } 280 } 281 xhttp.open('GET', link, true) 282 xhttp.send() 283 } 284 $modal 285 .modal({ keyboard: false }) 286 .modal('show') 287 .on('hidden hidden.bs.modal', () => { 288 $modal.remove() 289 }) 290 291 return false 292 } 293 $(document).on('click', 'a.modalbox, a.modal, .modalbox a', openM
293odal) 294 295 $(document).on('click', 'a.newtab', function (e) { 296 e.preventDefault() 297 window.open($(this).attr('href'), '_blank') 298 }) 299 300 // on change l'icone de l'accordeon 301 $('.accordion-trigger').on('click', function () { 302 if ($(this).next().find('.collapse').hasClass('in')) { 303 $(this).find('.arrow').html('►') 304 } else { 305 $(this).find('.arrow').html('▼') 306 } 307 }) 308 309 // on enleve la fonction doubleclic dans des cas ou cela pourrait etre indesirable 310 $('.no-dblclick, form, .page a, button, .dropdown-menu').on( 311 'dblclick', 312 (_e) => false, 313 ) 314 315 // deplacer les fenetres modales en bas de body pour eviter que des styles s'appliquent 316 $('.modal').appendTo(document.body) 317 318 // Remove hidden div by ACL 319 $('.remove-this-div-on-page-load').remove() 320 321 /* tooltips */ 322 $("[data-toggle='tooltip']").tooltip() 323 $("[data-tooltip='tooltip']").tooltip() 324 325 // moteur de recherche utilisé dans un template 326 $('a[href="#search"]').on('click', function (e) { 327 e.preventDefault() 328 $(this).siblings('#search').addClass('open') 329 $(this).siblings('#search').find('.search-query').focus() 330 }) 331 332 $('#search, #search button.close-search').on('click keyup', function (e) { 333 if ( 334 e.target == this || 335 $(e.target).hasClass('close-search') || 336 e.keyCode == 27 337 ) { 338 $(this).removeClass('open') 339 } 340 }) 341 342 // se souvenir des tabs navigués 343 $.fn.historyTabs = function () { 344 const that = this 345 window.addEventListener('popstate', (event) => { 346 if (event.state) { 347 $(that).filter(`[href="${event.state.url}"]`).tab('show') 348 } 349 }) 350 return this.each(function (index, element) { 351 $(element).on('show.bs.tab', function () { 352 const stateObject = { url: $(this).attr('href') } 353 354 if (window.location.hash && stateObject.url !== window.location.hash) { 355 window.history.pushState( 356 stateObject, 357 document.title, 358 window.location.pathname + 359 window.location.search + 360 $(this).attr('href'), 361 ) 362 } else { 363 window.history.replaceState( 364 stateObject, 365 document.title, 366 window.location.pathname + 367 window.location.search + 368 $(this).attr('href'), 369 ) 370 } 371 }) 372 if (!window.location.hash && $(element).is('.active')) { 373 // Shows the first element if there are no query parameters. 374 $(element).tab('show') 375 } else if ($(this).attr('href') === window.location.hash) { 376 $(element).tab('show') 377 } 378 }) 379 } 380 $('a[data-toggle="tab"]').historyTabs() 381 382 // double clic 383 $('.navbar').on('dblclick', function (e) { 384 e.stopPropagation() 385 $('body').append( 386 '<div class="modal fade" id="YesWikiModal">' + 387 '<div class="modal-dialog">' + 388 '<div class="modal-content">' + 389 '<div class="modal-header">' + 390 '<button type="button" class="close" data-dismiss="modal">×</button>' + 391 `<h3>${_t('NAVBAR_EDIT_MESSAGE')}</h3>` + 392 '</div>' + 393 '<div class="modal-body">' + 394 '</div>' + 395 '</div>' + 396 '</div>' + 397 '</div>', 398 ) 399 400 const $editmodal = $('#YesWikiModal') 401 $(this) 402 .find('.include') 403 .each(function () { 404 const href = $(this) 405 .attr('ondblclick') 406 .replace("document.location='", '') 407 .replace("';", '') 408 const pagewiki = href 409 .replace('/edit', '') 410 .replace('http://yeswiki.dev/wakka.php?wiki=', '') 411 $editmodal 412 .find('.modal-body') 413 .append( 414 `<a href="${href}" class="btn btn-default btn-block">` + 415 `<i class="fa fa-pencil-alt"></i> ${_t( 416 'YESWIKIMODAL_EDIT_MSG', 417 )} ${pagewiki}</a>`, 418 ) 419 }) 420 421 $editmodal 422 .find('.modal-body') 423 .append( 424 `<a href="#" data-dismiss="modal" class="btn btn-warning btn-xs btn-block">${+_t( 425 'EDIT_OUPS_MSG', 426 )}</a>`, 427 ) 428 429 $editmodal 430 .modal({ keyboard: true }) 431 .modal('show') 432 .on('hidden hidden.bs.modal', () => { 433 $editmodal.remove() 434 }) 435 436 return false 437 }) 438 439 // AUTO RESIZE IFRAME 440 const iframes = $('iframe.auto-resize') 441 if (iframes.length > 0) { 442 $.getScript('javascripts/vendor/iframe-resizer/iframeResizer.min.js') 443 .done((_script, _textStatus) => { 444 iframes.iFrameResize() 445 }) 446 .fail((jqxhr, settings, exception) => { 447 console.log( 448 'Error getting script javascripts/vendor/iframe-resizer/iframeResizer.min.js', 449 exception, 450 ) 451 }) 452 } 453 454 // get the html from a yeswiki page 455 function getText(url, link) { 456 let html 457 $.get(url, (data) => { 458 html = data 459 }).done(() => { 460 link.attr('data-content', html) 461 }) 462 } 463 464 $('.modalbox-hover').each(function () { 465 getText(`${$(this).attr('href')}/html`, $(this)) 466 }) 467 $('.modalbox-hover').popover({ 468 trigger: 'hover', 469 html: true, // permet d'utiliser du html 470 placement: 'right', // position de la popover (top ou bottom ou left ou right) 471 }) 472 473 // ouvrir les liens dans une nouvelle fenetre 474 $('.new-window').attr('target', '_blank') 475 $(document).on('yw-modal-open', () => { 476 $('.new-window:not([target])').attr('target', '_blank') 477 }) 478 479 // acl switch 480 $('#acl-switch-mode') 481 .change(function () { 482 if ($(this).prop('checked')) { 483 // show advanced 484 $('.acl-simple').hide().val(null) 485 $('.acl-advanced').slideDown() 486 } else { 487 $('.acl-single-container label').each(function () { 488 $(this).after($(`select[name=${$(this).data('input')}]`)) 489 }) 490 $('.acl-simple').show() 491 $('.acl-advanced').hide().val(null) 492 } 493 }) 494 .trigger('change') 495 496 // tables 497 if (typeof $('.table').DataTable === 'function') { 498 $('.table:not(.prevent-auto-init)').DataTable(DATATABLE_OPTIONS) 499 } 500 501 /** comments */ 502 const $comments = $('.yeswiki-page-comments, #post-comment') 503 504 function resetCommentForm(form) { 505 form 506 .attr('id', 'post-comment') 507 .attr('class', '') 508 .attr( 509 'action', 510 form.attr('action').replace(/api\/comments(\/.*)/gm, 'api/comments'), 511 ) 512 .appendTo($('.yeswiki-page-comments').parent()) 513 .find('label') 514 .removeClass('hide') 515 $('.btn-cancel-comment').remove() 516 $('#post-comment').find('.btn-post-comment').text(_t('SAVE')) 517 window['aceditor-body'].editor.setValue('') 518 } 519 520 // ajax post comment 521 $comments.on('click', '.btn-post-comment', function (e) { 522 e.preventDefault() 523 const form = $(this).parent('form') 524 const urlpost = form.attr('action') 525 $.ajax({ 526 type: 'POST', 527 url: urlpost, 528 data: form.serialize(), 529 dataType: 'json', 530 success(e) { 531 form.trigger('reset') 532 window['aceditor-body'].editor.setValue('') 533 toastMessage(e.success, 3000, 'alert alert-success') 534 form.parents('.yw-comment').find('.comment-links').removeClass('hide') 535 // we place the new comment in different places if its an answer, a modification or a new comment 536 if (form.hasClass('comment-modify')) { 537 form 538 .closest('.yw-comment') 539 .html($('<div>').html(e.html).find('.yw-comment').html()) 540 resetCommentForm(form) 541 } else if (form.parent().hasClass('comment-reponses')) { 542 form.parent().append(e.html) 543 resetCommentForm(form) 544 } else { 545 $('.yeswiki-page-comments').append(e.html) 546 } 547 }, 548 error(e) { 549 toastMessage(e.responseJSON.error, 3000, 'alert alert-danger') 550 }, 551 }) 552 return false 553 }) 554 555 // ajax answer comment 556 $comments.on('click', '.btn-answer-comment', function (e) { 557 e.preventDefault() 558 const com = $(this).parent().parent() 559 $('.temporary-form') 560 .parents('.yw-comment') 561 .find('.comment-html:first') 562 .removeClass('hide') 563 $('.temporary-form') 564 .parents('.yw-comment') 565 .find('.comment-links:first') 566 .removeClass('hide') 567 // a comment-form is already opened 568 if ($('.temporary-form').length > 0) { 569 resetCommentForm($('.temporary-form')) 570 } 571 572 // clone comment form and change some options 573 const formAnswer = com.find('.comment-reponses:first') 574 $('#post-comment').appendTo(formAnswer) 575 formAnswer 576 .find('form') 577 .attr('id', `form-comment-${com.data('tag')}`) 578 .removeClass('hide') 579 .addClass('temporary-form') 580 formAnswer.find('[name="pagetag"]').val(com.data('tag')) 581 formAnswer 582 .find('form') 583 .append( 584 `<button class="btn-cancel-comment btn btn-sm btn-default">${_t('CANCEL')}</button>`, 585 ) 586 com.find('.comment-links').addClass('hide') 587 com.find('label').addClass('hide') 588 589 return false 590 }) 591 592 // ajax edit comment 593 $comments.on('click', '.btn-edit-comment', function (e) { 594 e.preventDefault() 595 const com = $(this).parent().parent() 596
597 // hide comment and comment links while editor is open 598 com.find('.comment-html:first').addClass('hide') 599 com.find('.comment-links:first').addClass('hide') 600 601 $('.temporary-form') 602 .parents('.yw-comment') 603 .find('.comment-html:first') 604 .removeClass('hide') 605 $('.temporary-form') 606 .parents('.yw-comment') 607 .find('.comment-links:first') 608 .removeClass('hide') 609 // a comment-form is already opened 610 if ($('.temporary-form').length > 0) { 611 resetCommentForm($('.temporary-form')) 612 } 613 614 // clone comment form and change some options 615 const formcom = com.find('.form-comment:first') 616 $('#post-comment').appendTo(formcom) 617 formcom 618 .find('form') 619 .attr('id', `form-comment-${com.data('tag')}`) 620 .attr( 621 'action', 622 `${formcom.find('form').attr('action')}/${com.data('tag')}`, 623 ) 624 .removeClass('hide') 625 .addClass('temporary-form') 626 .addClass('comment-modify') 627 formcom.find('label').addClass('hide') 628 window['aceditor-body'].editor.setValue(com.find('.comment-body').val()) 629 formcom.find('[name="pagetag"]').val(com.data('commenton')) 630 formcom.find('.btn-post-comment').text(_t('MODIFY')) 631 formcom 632 .find('form') 633 .append( 634 `<button class="btn-cancel-comment btn btn-sm btn-default">${_t('CANCEL')}</button>`, 635 ) 636 com.parents('.yw-comment').find('.comment-links').addClass('hide') 637 638 return false 639 }) 640 641 // cancel comment edit 642 $comments.on('click', '.btn-cancel-comment', function (e) { 643 e.preventDefault() 644 const com = $(this).parent().parent().parent() 645 // restore html comment and links 646 com.find('.comment-html:first').removeClass('hide') 647 com.find('.comment-links:first').removeClass('hide') 648 com.parents('.yw-comment').find('.comment-links').removeClass('hide') 649 resetCommentForm($(`#form-comment-${com.data('tag')}`)) 650 return false 651 }) 652 653 // ajax delete comment 654 $comments.on('click', '.btn-delete-comment', function (e) { 655 if (confirm(_t('DELETE_COMMENT_AND_ANSWERS'))) { 656 e.preventDefault() 657 const link = $(this) 658 $.ajax({ 659 type: 'POST', 660 url: link.attr('href'), 661 dataType: 'json', 662 success(e) { 663 link.closest('.yw-comment').slideUp(250, function () { 664 $(this).remove() 665 }) 666 toastMessage(e.success, 3000, 'alert alert-success') 667 }, 668 error(e) { 669 toastMessage(e.responseJSON.error, 3000, 'alert alert-danger') 670 }, 671 }) 672 } 673 return false 674 }) 675 // reaction 676 677 // init user reaction count 678 $('.reactions-container').each((i, val) => { 679 const userReaction = $(val).find('.user-reaction').length 680 const nbReactionLeft = $(val).find('.max-reaction').text() 681 $(val) 682 .find('.max-reaction') 683 .text(nbReactionLeft - userReaction) 684 }) 685 686 // Reaction Management Helper 687 const reactionManagementHelper = { 688 renderAjaxError(translation, jqXHR, textStatus, errorThrown) { 689 const message = _t(translation, { 690 error: `${textStatus} / ${errorThrown}${jqXHR.responseJSON.error != null ? `:${jqXHR.responseJSON.error}` : ''}`, 691 }) 692 if (typeof toastMessage == 'function') { 693 toastMessage(message, 3000, 'alert alert-danger') 694 } else { 695 alert(message) 696 } 697 if (jqXHR.responseJSON.exceptionMessage != null) { 698 console.warn(jqXHR.responseJSON.exceptionMessage) 699 } 700 }, 701 deleteATag(elem) { 702 const url = $(elem).attr('href') 703 $.ajax({ 704 method: 'GET', 705 url, 706 success() { 707 const table = $(elem).closest('table') 708 if (table.length != 0) { 709 console.log(table.DataTable()) 710 table.DataTable().row($(elem).closest('tr')).remove().draw() 711 } 712 }, 713 error(jqXHR, textStatus, errorThrown) { 714 reactionManagementHelper.renderAjaxError( 715 'REACTION_NOT_POSSIBLE_TO_DELETE_REACTION', 716 jqXHR, 717 textStatus, 718 errorThrown, 719 ) 720 }, 721 }) 722 }, 723 deleteTags(headElem) { 724 const table = $(headElem).closest('table') 725 if (table.length != 0) { 726 $(table) 727 .find('.btn-delete-reaction:not(.btn-delete-all)') 728 .each(function () { 729 reactionManagementHelper.deleteATag($(this)) 730 }) 731 } 732 }, 733 } 734 735 // handler reaction click 736 $('.link-reaction').click(function (event) { 737 event.preventDefault() 738 event.stopPropagation() 739 const extractData = (item) => { 740 const nb = $(item).find('.reaction-numbers') 741 return { 742 url: $(item).attr('href'), 743 data: $(item).data(), 744 nb, 745 nbInit: parseInt(nb.text()), 746 } 747 } 748 const { url, data, nb, nbInit } = extractData(this) 749 const deleteUserReaction = async (url, data, nb, nbInit, link) => { 750 const p = new Promise((resolve, reject) => { 751 let currentReactionId = data.reactionid 752 if ('oldId' in data && (data.oldId === true || data.oldId === 'true')) { 753 currentReactionId = 'reactionField' 754 } 755 $.ajax({ 756 method: 'GET', 757 url: `${url}/${currentReactionId}/${data.id}/${data.pagetag}/${data.username}/delete`, 758 success() { 759 nb.text(nbInit - 1) 760 $(link).removeClass('user-reaction') 761 const nbReactionLeft = parseFloat( 762 $(link) 763 .parents('.reactions-container') 764 .find('.max-reaction') 765 .text(), 766 ) 767 $(link) 768 .parents('.reactions-container') 769 .find('.max-reaction') 770 .text(nbReactionLeft + 1) 771 resolve() 772 }, 773 error(jqXHR, textStatus, errorThrown) { 774 reactionManagementHelper.renderAjaxError( 775 'REACTION_NOT_POSSIBLE_TO_DELETE_REACTION', 776 jqXHR, 777 textStatus, 778 errorThrown, 779 ) 780 reject() 781 }, 782 }) 783 }) 784 return await p.then((...args) => Promise.resolve(...args)) 785 } 786 if (url !== '#') { 787 if ($(this).hasClass('user-reaction')) { 788 // on supprime la reaction 789 if (typeof blockReactionRemove !== 'undefined' && blockReactionRemove) { 790 if (blockReactionRemoveMessage) { 791 if (typeof toastMessage == 'function') { 792 toastMessage( 793 blockReactionRemoveMessage, 794 3000, 795 'alert alert-warning', 796 ) 797 } else { 798 alert(blockReactionRemoveMessage) 799 } 800 } 801 return false 802 } 803 const link = $(this) 804 deleteUserReaction(url, data, nb, nbInit, link).catch((_e) => { 805 /* do nothing */ 806 }) 807 return false 808 } 809 // on ajoute la reaction si le max n'est pas dépassé 810 const nbReactionLeft = parseFloat( 811 $(this).parents('.reactions-container').find('.max-reaction').text(), 812 ) 813 if ( 814 url !== '#' && 815 nbReactionLeft == 0 && 816 typeof blockReactionRemove !== 'undefined' && 817 blockReactionRemove === true 818 ) { 819 const previous = $(this) 820 .closest('.reactions-flex') 821 .find('.user-reaction') 822 .first() 823 if ( 824 typeof previous === 'object' && 825 'length' in previous && 826 previous.length > 0 827 ) { 828 const { 829 url: previousUrl, 830 data: previousData, 831 nb: previousNb, 832 nbInit: previousNbInit, 833 } = extractData(previous) 834 if (previousUrl !== '#') { 835 deleteUserReaction( 836 previousUrl, 837 previousData, 838 previousNb, 839 previousNbInit, 840 $(previous), 841 ) 842 .then(() => { 843 $(this).click() 844 }) 845 .catch((_e) => { 846 /* do nothing */ 847 }) 848 return false 849 } 850 } 851 } 852 if (nbReactionLeft > 0) { 853 const link = $(this) 854 $.ajax({ 855 method: 'POST', 856 url, 857 data, 858 success() { 859 $(link) 860 .find('.reaction-numbers') 861 .text(nbReactionLeft - 1) 862 863 nb.text(nbInit + 1) 864 $(link).addClass('user-reaction') 865 $(link) 866 .parents('.reactions-container') 867 .find('.max-reaction') 868 .text(nbReactionLeft - 1) 869 }, 870 error(jqXHR, textStatus, errorThrown) { 871 reactionManagementHelper.renderAjaxError( 872 'REACTION_NOT_POSSIBLE_TO_ADD_REACTION', 873 jqXHR, 874 textStatus, 875 errorThrown, 876 ) 877 }, 878 }) 879 } else { 880 const message = 881 "Vous n'avez plus de choix possibles, vous pouvez retirer un choix existant pour changer" 882 if (typeof toastMessage == 'function') { 883 toastMessage(message, 3000, 'alert alert-warning') 884 } else { 885 alert(message) 886 } 887 } 888 return false 889 } 890 }) 891 892 $('.btn-delete-reaction').on('click', function (e) { 893 e.preventDefault() 894 if (!$(this).hasClass('btn-delete-all')) { 895 if (confirm(_t('REACTION_CONFIRM_DELETE'))) { 896 reactionManagementHelper.deleteATag($(this)) 897 } 898 } else if (confirm(_t('REACTION_CONFIRM_DELETE_ALL'))) { 899 reactionManagementHelper.deleteTags($(this)) 900 } 901 }) 902})(jQuery) 903 904// fot comments table 905$('#commentsTableDeleteModal.modal').on('shown.bs.modal', function (event) { 906 multiDeleteService.initProgressBar($(this))
907 $(this).find('.modal-body .multi-delete-results').html('') 908 const deleteButton = $(this).find('button.start-btn-delete-comment') 909 $(deleteButton).removeAttr('disabled') 910 const button = $(event.relatedTarget) // Button that triggered the modal 911 const name = $(button).data('name') 912 $(this).find('#commentToDelete').text(name) 913 $(deleteButton).data('name', name) 914 $(deleteButton).data('targetNode', button) 915 $(deleteButton).data('modal', this) 916 if (!$(deleteButton).hasClass('eventSet')) { 917 $(deleteButton).addClass('eventSet') 918 $(deleteButton).on('click', function () { 919 $(this).attr('disabled', 'disabled') 920 $(this).tooltip('hide') 921 const name = $(this).data('name') 922 const targetNode = $(this).data('targetNode') 923 const modal = $(this).data('modal') 924 925 $.ajax({ 926 method: 'post', 927 url: wiki.url(`api/comments/${name}/delete`), 928 timeout: 30000, // 30 seconds 929 error(e) { 930 multiDeleteService.addErrorMessage( 931 $(modal), 932 `${_t('COMMENT_NOT_DELETED', { comment: name })} : ${ 933 e.responseJSON && e.responseJSON.error ? e.responseJSON.error : '' 934 }`, 935 ) 936 }, 937 success() { 938 multiDeleteService.removeLine( 939 $(targetNode).closest('.dataTables_wrapper').prop('id'), 940 name, 941 ) 942 $(modal) 943 .find('.modal-body .multi-delete-results') 944 .first() 945 .append($('<div>').text(_t('COMMENT_DELETED'))) 946 }, 947 complete() { 948 multiDeleteService.updateProgressBar($(modal), ['test'], 0) 949 }, 950 }) 951 }) 952 } 953}) 954 955// function to check all checkbox in page. 956function checkAll(state) { 957 const checkboxes = document.querySelectorAll('input.selectpage') 958 const newState = [true, 'true', 1, '1'].includes(state) 959 checkboxes.forEach((checkbox) => { 960 if (checkbox.type == 'checkbox') { 961 checkbox.checked = newState 962 } 963 }) 964} 965 966// tabs 967// hack for next and previous buttons 968$('.tab-content [data-toggle="tab"]').on('click', function () { 969 const base = $(this).closest('.tab-content').prev() 970 $(base).find('.active').removeClass('active') 971 $(base) 972 .find(`[href="${$(this).attr('href')}"]`) 973 .parent() 974 .addClass('active') 975 $(base) 976 .find(`a[href="${$(this).attr('href')}"]`) 977 .tab('show') 978 // manage iframe case 979 if (window.location != parent.parent.location) { 980 $('html, body').animate({ scrollTop: $(base).offset().top }, 500) 981 try { 982 $(base).get(0).scrollIntoView() 983 window.parent.scrollBy(0, -80) 984 } catch (error) { 985 console.error(error) 986 } 987 } else { 988 $('html, body').animate({ scrollTop: $(base).offset().top - 80 }, 500) 989 } 990}) 991 992// a11y 993$('#yw-a11y-jump-content').click(() => { 994 setTimeout(() => { 995 $('#yw-topnav').removeClass('nav-down').addClass('nav-up') 996 $('body').removeClass('nav-down').addClass('nav-up') 997 }, 300) 998}) 999 1000window.checkAll = checkAll
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.