Changes for page Service Navigator
Last modified by Veronika Kocher on Thursday, 03 Sep 2026 14:15
From version 22.15
edited by Veronika Kocher
on Thursday, 03 Sep 2026 10:09
on Thursday, 03 Sep 2026 10:09
Change comment:
There is no comment for this version
To version 22.13
edited by Veronika Kocher
on Thursday, 03 Sep 2026 9:18
on Thursday, 03 Sep 2026 9:18
Change comment:
There is no comment for this version
Summary
-
Page properties (1 modified, 0 added, 0 removed)
Details
- Page properties
-
- Content
-
... ... @@ -285,115 +285,22 @@ 285 285 </div> 286 286 {{/html}} 287 287 288 -\n\n 289 -\n\n{{html clean="false"}} 288 +{{html clean="false"}} 290 290 <!-- SN_HORIZONTAL_BOX_HARMONIZER_START --> 291 - 292 -<style data-sn-horizontal-box-harmonizer="7"> 293 -/* ---------- Typography: never justify headings ---------- */ 294 -#xwikicontent h1, 295 -#xwikicontent h2, 296 -#xwikicontent h3, 297 -#xwikicontent h4, 298 -#xwikicontent h5, 299 -#xwikicontent h6, 300 -#xwikicontent .box-title, 301 -#xwikicontent [role="heading"], 302 -#xwikicontent h1 a, 303 -#xwikicontent h2 a, 304 -#xwikicontent h3 a, 305 -#xwikicontent h4 a, 306 -#xwikicontent h5 a, 307 -#xwikicontent h6 a, 308 -#xwikicontent .box-title a, 309 -#xwikicontent [role="heading"] a{ 310 - text-align:left!important; 311 - text-justify:auto!important; 312 - word-spacing:normal!important; 290 +<style data-sn-horizontal-box-harmonizer="1"> 291 +[data-sn-equal-height-managed="1"]{box-sizing:border-box} 292 +@media(max-width:767px){ 293 + [data-sn-equal-height-managed="1"]{min-height:0!important} 313 313 } 314 - 315 -/* ---------- Native XWiki semantic callouts ---------- */ 316 -#xwikicontent .box.infomessage, 317 -#xwikicontent .infomessage, 318 -#xwikicontent .box.warningmessage, 319 -#xwikicontent .warningmessage, 320 -#xwikicontent .box.successmessage, 321 -#xwikicontent .successmessage, 322 -#xwikicontent .box.errormessage, 323 -#xwikicontent .errormessage, 324 -#xwikicontent [data-sn-callout-harmonized="1"]{ 325 - box-sizing:border-box!important; 326 - border-radius:8px!important; 327 - border-top:1px solid rgba(0,0,0,.08)!important; 328 - border-right:1px solid rgba(0,0,0,.08)!important; 329 - border-bottom:1px solid rgba(0,0,0,.08)!important; 330 - border-left:4px solid var(--sn-callout-accent,#21b6d7)!important; 331 - padding:14px 16px!important; 332 - text-align:left!important; 333 - text-justify:auto!important; 334 - word-spacing:normal!important; 335 - box-shadow:none!important; 336 -} 337 - 338 -#xwikicontent .box.infomessage, 339 -#xwikicontent .infomessage{ 340 - --sn-callout-accent:#21b6d7; 341 - background:#eaf7fb!important; 342 -} 343 - 344 -#xwikicontent .box.warningmessage, 345 -#xwikicontent .warningmessage{ 346 - --sn-callout-accent:#f0aa00; 347 - background:#fff8e7!important; 348 -} 349 - 350 -#xwikicontent .box.successmessage, 351 -#xwikicontent .successmessage{ 352 - --sn-callout-accent:#38b76a; 353 - background:#edf9f1!important; 354 -} 355 - 356 -#xwikicontent .box.errormessage, 357 -#xwikicontent .errormessage{ 358 - --sn-callout-accent:#e94b13; 359 - background:#fff1ec!important; 360 -} 361 - 362 -#xwikicontent [data-sn-callout-harmonized="1"] > :first-child, 363 -#xwikicontent .infomessage > :first-child, 364 -#xwikicontent .warningmessage > :first-child, 365 -#xwikicontent .successmessage > :first-child, 366 -#xwikicontent .errormessage > :first-child{ 367 - margin-top:0!important; 368 -} 369 - 370 -#xwikicontent [data-sn-callout-harmonized="1"] > :last-child, 371 -#xwikicontent .infomessage > :last-child, 372 -#xwikicontent .warningmessage > :last-child, 373 -#xwikicontent .successmessage > :last-child, 374 -#xwikicontent .errormessage > :last-child{ 375 - margin-bottom:0!important; 376 -} 377 - 378 -#xwikicontent [data-sn-equal-height-managed], 379 -#xwikicontent [data-sn-first-section-aligned], 380 -#xwikicontent [data-sn-first-content-aligned]{ 381 - box-sizing:border-box; 382 -} 383 383 </style> 384 - 385 -<script data-sn-horizontal-box-harmonizer="7"> 296 +<script data-sn-horizontal-box-harmonizer="1"> 386 386 (function(){ 387 387 "use strict"; 388 388 389 389 var MOBILE_MAX=767; 390 - var ROW_TOLERANCE= 6;301 + var ROW_TOLERANCE=4; 391 391 var MIN_W=150; 392 392 var MIN_H=36; 393 - var MAX_PARENT_CHILDREN=18; 394 - var SEARCH_DEPTH=5; 395 - var RESIZE_DEBOUNCE=220; 396 - var MIN_WIDTH_CHANGE=2; 397 397 398 398 var root= 399 399 document.getElementById("xwikicontent")|| ... ... @@ -403,297 +403,72 @@ 403 403 404 404 if(!root)return; 405 405 406 - var heightManaged=new Set(); 407 - var sectionManaged=new Set(); 408 - var contentManaged=new Set(); 313 + var managed=new Set(); 314 + var raf=0; 409 409 410 - var originalMinHeight=new WeakMap(); 411 - var originalMarginTop=new WeakMap(); 412 - 413 - var resizeTimer=0; 414 - var lastWidth=-1; 415 - var hasApplied=false; 416 - var applying=false; 417 - 418 418 function num(v){ 419 419 var n=parseFloat(v); 420 420 return Number.isFinite(n)?n:0; 421 421 } 422 422 423 - function visible(el ,minW,minH){321 + function visible(el){ 424 424 if(!el||el.nodeType!==1)return false; 425 - 426 426 var s=getComputedStyle(el); 427 - 428 - if( 429 - s.display==="none"|| 430 - s.visibility==="hidden"|| 431 - Number(s.opacity)===0 432 - ){ 433 - return false; 434 - } 435 - 324 + if(s.display==="none"||s.visibility==="hidden"||Number(s.opacity)===0)return false; 436 436 var r=el.getBoundingClientRect(); 437 - 438 - return ( 439 - r.width>=(minW||1)&& 440 - r.height>=(minH||1) 441 - ); 326 + return r.width>=MIN_W&&r.height>=MIN_H; 442 442 } 443 443 444 - function normalizeText(text){ 445 - return String(text||"") 446 - .replace(/\s+/g," ") 447 - .trim() 448 - .toUpperCase(); 449 - } 450 - 451 451 function excluded(el){ 452 - return ( 453 - !el.matches|| 454 - el.matches( 455 - "button,input,select,textarea,option,label,img,svg,canvas,table,thead,tbody,tfoot,tr,td,th,summary,script,style,noscript,template,.btn,.chip,[role=button]" 456 - ) 330 + return !el.matches||el.matches( 331 + "button,input,select,textarea,option,label,img,svg,canvas,table,thead,tbody,tfoot,tr,td,th,summary,script,style,noscript,template,.btn,.chip,[role=button]" 457 457 ); 458 458 } 459 459 460 - /* ---------- Custom coloured callouts ---------- */ 461 - 462 - function nativeCallout(el){ 463 - var c= 464 - typeof el.className==="string" 465 - ? el.className.toLowerCase() 466 - : ""; 467 - 468 - return ( 469 - /(^|\s)(infomessage|warningmessage|successmessage|errormessage)(\s|$)/.test(c) 470 - ); 471 - } 472 - 473 - function customCallout(el){ 474 - if(!visible(el,220,42)||excluded(el))return false; 475 - 476 - var r=el.getBoundingClientRect(); 477 - 478 - if(r.height>520)return false; 479 - 480 - var s=getComputedStyle(el); 481 - 482 - var bg= 483 - s.backgroundColor&& 484 - s.backgroundColor!=="rgba(0, 0, 0, 0)"&& 485 - s.backgroundColor!=="transparent"&& 486 - s.backgroundColor!=="rgb(255, 255, 255)"; 487 - 488 - var left= 489 - num(s.borderLeftWidth); 490 - 491 - return ( 492 - bg&& 493 - left>=2 494 - ); 495 - } 496 - 497 - function harmoniseCustomCallouts(){ 498 - Array.from( 499 - root.querySelectorAll( 500 - "div,aside,section" 501 - ) 502 - ).forEach(function(el){ 503 - if(nativeCallout(el))return; 504 - if(!customCallout(el))return; 505 - 506 - var s=getComputedStyle(el); 507 - 508 - el.setAttribute( 509 - "data-sn-callout-harmonized", 510 - "1" 511 - ); 512 - 513 - if( 514 - s.borderLeftColor 515 - ){ 516 - el.style.setProperty( 517 - "--sn-callout-accent", 518 - s.borderLeftColor 519 - ); 520 - } 521 - }); 522 - } 523 - 524 - /* ---------- Restore only values V7 itself changed ---------- */ 525 - 526 - function saveOriginal(el,map,property){ 527 - if(map.has(el))return; 528 - 529 - map.set(el,{ 530 - value: 531 - el.style.getPropertyValue( 532 - property 533 - ), 534 - priority: 535 - el.style.getPropertyPriority( 536 - property 537 - ) 538 - }); 539 - } 540 - 541 - function restoreOriginal(el,map,property){ 542 - var original=map.get(el); 543 - 544 - if(original&&original.value){ 545 - el.style.setProperty( 546 - property, 547 - original.value, 548 - original.priority||"" 549 - ); 550 - }else{ 551 - el.style.removeProperty( 552 - property 553 - ); 554 - } 555 - } 556 - 557 - function resetRuntime(){ 558 - heightManaged.forEach(function(el){ 559 - restoreOriginal( 560 - el, 561 - originalMinHeight, 562 - "min-height" 563 - ); 564 - 565 - el.removeAttribute( 566 - "data-sn-equal-height-managed" 567 - ); 568 - }); 569 - 570 - sectionManaged.forEach(function(el){ 571 - restoreOriginal( 572 - el, 573 - originalMarginTop, 574 - "margin-top" 575 - ); 576 - 577 - el.removeAttribute( 578 - "data-sn-first-section-aligned" 579 - ); 580 - }); 581 - 582 - contentManaged.forEach(function(el){ 583 - restoreOriginal( 584 - el, 585 - originalMarginTop, 586 - "margin-top" 587 - ); 588 - 589 - el.removeAttribute( 590 - "data-sn-first-content-aligned" 591 - ); 592 - }); 593 - 594 - heightManaged.clear(); 595 - sectionManaged.clear(); 596 - contentManaged.clear(); 597 - } 598 - 599 - /* ---------- Card detection ---------- */ 600 - 601 601 function namedLikeBox(el){ 602 - var c= 603 - typeof el.className==="string" 604 - ? el.className 605 - : ""; 606 - 336 + var c=typeof el.className==="string"?el.className:""; 607 607 return /(^|[\s_-])(box|card|tile|panel|role|check|service|source|call|area|detail|resource|topic|warn|info)([\s_-]|$)/i.test(c); 608 608 } 609 609 610 610 function boxLike(el){ 611 - if( 612 - !visible(el,MIN_W,MIN_H)|| 613 - excluded(el) 614 - ){ 615 - return false; 616 - } 617 - 341 + if(!visible(el)||excluded(el))return false; 618 618 var s=getComputedStyle(el); 619 619 var r=el.getBoundingClientRect(); 620 - 621 621 var border= 622 - num(s.borderTopWidth)+ 623 - num(s.borderRightWidth)+ 624 - num(s.borderBottomWidth)+ 625 - num(s.borderLeftWidth); 626 - 345 + num(s.borderTopWidth)+num(s.borderRightWidth)+ 346 + num(s.borderBottomWidth)+num(s.borderLeftWidth); 627 627 var radius=Math.max( 628 - num(s.borderTopLeftRadius), 629 - num(s.borderTopRightRadius), 630 - num(s.borderBottomLeftRadius), 631 - num(s.borderBottomRightRadius) 348 + num(s.borderTopLeftRadius),num(s.borderTopRightRadius), 349 + num(s.borderBottomLeftRadius),num(s.borderBottomRightRadius) 632 632 ); 633 - 634 - var bg= 635 - s.backgroundColor&& 636 - s.backgroundColor!=="rgba(0, 0, 0, 0)"&& 637 - s.backgroundColor!=="transparent"; 638 - 639 - var shadow= 640 - s.boxShadow&& 641 - s.boxShadow!=="none"; 642 - 643 - return ( 644 - namedLikeBox(el)|| 645 - border>=1|| 646 - (bg&&radius>=3)|| 647 - (shadow&&r.width>=180) 648 - ); 351 + var bg=s.backgroundColor&&s.backgroundColor!=="rgba(0, 0, 0, 0)"&&s.backgroundColor!=="transparent"; 352 + var shadow=s.boxShadow&&s.boxShadow!=="none"; 353 + return namedLikeBox(el)||border>=1||(bg&&radius>=3)||(shadow&&r.width>=180); 649 649 } 650 650 651 651 function pickTarget(child){ 652 - if(!visible(child,MIN_W,MIN_H))return null; 653 - 357 + if(!visible(child))return null; 654 654 if(boxLike(child))return child; 655 655 656 656 var cr=child.getBoundingClientRect(); 657 657 var q=[]; 658 - 659 659 Array.from(child.children||[]).forEach(function(el){ 660 660 q.push({el:el,depth:1}); 661 661 }); 662 662 663 - var best=null; 664 - var bestScore=-Infinity; 366 + var best=null,bestScore=-1; 665 665 666 666 while(q.length){ 667 667 var item=q.shift(); 668 668 var el=item.el; 371 + if(!visible(el))continue; 669 669 670 - if(!visible(el,MIN_W,MIN_H))continue; 671 - 672 672 var r=el.getBoundingClientRect(); 673 673 674 - if( 675 - r.width>=cr.width*.68&& 676 - boxLike(el) 677 - ){ 678 - var widthFit= 679 - 1-Math.min( 680 - 1, 681 - Math.abs(cr.width-r.width)/ 682 - Math.max(1,cr.width) 683 - ); 684 - 685 - var topFit= 686 - 1-Math.min( 687 - 1, 688 - Math.abs(cr.top-r.top)/100 689 - ); 690 - 691 - var score= 692 - widthFit*6+ 693 - topFit*3+ 694 - Math.min(r.height,900)/450+ 695 - Math.min(r.width*r.height,900000)/900000; 696 - 375 + if(r.width>=cr.width*.72&&boxLike(el)){ 376 + var widthFit=1-Math.min(1,Math.abs(cr.width-r.width)/Math.max(1,cr.width)); 377 + var topFit=1-Math.min(1,Math.abs(cr.top-r.top)/80); 378 + var score=widthFit*5+topFit*2+Math.min(r.height,600)/600; 697 697 if(score>bestScore){ 698 698 best=el; 699 699 bestScore=score; ... ... @@ -700,12 +700,9 @@ 700 700 } 701 701 } 702 702 703 - if(item.depth< SEARCH_DEPTH){385 + if(item.depth<3){ 704 704 Array.from(el.children||[]).forEach(function(next){ 705 - q.push({ 706 - el:next, 707 - depth:item.depth+1 708 - }); 387 + q.push({el:next,depth:item.depth+1}); 709 709 }); 710 710 } 711 711 } ... ... @@ -713,692 +713,130 @@ 713 713 return best; 714 714 } 715 715 716 - function groupRows(entries){ 717 - var groups=[]; 718 - 719 - entries 720 - .slice() 721 - .sort(function(a,b){ 722 - return ( 723 - a.rect.top-b.rect.top|| 724 - a.rect.left-b.rect.left 725 - ); 726 - }) 727 - .forEach(function(entry){ 728 - var group=null; 729 - 730 - for(var i=0;i<groups.length;i++){ 731 - if( 732 - Math.abs( 733 - groups[i].top- 734 - entry.rect.top 735 - )<=ROW_TOLERANCE 736 - ){ 737 - group=groups[i]; 738 - break; 739 - } 740 - } 741 - 742 - if(!group){ 743 - group={ 744 - top:entry.rect.top, 745 - entries:[] 746 - }; 747 - groups.push(group); 748 - } 749 - 750 - group.entries.push(entry); 751 - }); 752 - 753 - return groups; 395 + function reset(){ 396 + managed.forEach(function(el){ 397 + el.style.removeProperty("min-height"); 398 + el.removeAttribute("data-sn-equal-height-managed"); 399 + }); 400 + managed.clear(); 754 754 } 755 755 756 - function validRow(group){ 757 - if(group.entries.length<2)return false; 758 - 759 - var lefts= 760 - group.entries 761 - .map(function(e){return e.rect.left;}) 762 - .sort(function(a,b){return a-b;}); 763 - 764 - if( 765 - lefts[lefts.length-1]- 766 - lefts[0]< 767 - 80 768 - ){ 769 - return false; 403 + function horizontalLayout(parent){ 404 + if(!visible(parent))return false; 405 + var s=getComputedStyle(parent); 406 + if(s.display==="grid"||s.display==="inline-grid")return true; 407 + if(s.display==="flex"||s.display==="inline-flex"){ 408 + return s.flexDirection==="row"||s.flexDirection==="row-reverse"; 770 770 } 771 - 772 - var widths= 773 - group.entries 774 - .map(function(e){return e.rect.width;}) 775 - .filter(function(w){return w>0;}); 776 - 777 - if(widths.length<2)return false; 778 - 779 - var minW= 780 - Math.min.apply(Math,widths); 781 - 782 - var maxW= 783 - Math.max.apply(Math,widths); 784 - 785 - return ( 786 - maxW/ 787 - Math.max(1,minW)<= 788 - 1.9 789 - ); 410 + return false; 790 790 } 791 791 792 - /* ---------- Known ARSN first section bars ---------- */ 793 - 794 - function knownBar(el){ 795 - var text= 796 - normalizeText( 797 - el.textContent 798 - ); 799 - 800 - return ( 801 - text==="HIER STARTEN"|| 802 - text==="ORGANISIEREN & DOKUMENTIEREN"|| 803 - text==="ENTSCHEIDEN"|| 804 - text==="START HERE"|| 805 - text==="GET STARTED"|| 806 - text==="ORGANISE & DOCUMENT"|| 807 - text==="ORGANIZE & DOCUMENT"|| 808 - text==="DECIDE" 809 - ); 810 - } 811 - 812 - function findKnownBar(card){ 813 - var cardRect= 814 - card.getBoundingClientRect(); 815 - 816 - var rows= 817 - Array.from( 818 - card.querySelectorAll( 819 - "div,p,span,strong,h3,h4,h5,h6" 820 - ) 821 - ) 822 - .filter(function(el){ 823 - if(!visible(el,20,6))return false; 824 - if(!knownBar(el))return false; 825 - 826 - var r=el.getBoundingClientRect(); 827 - 828 - var rel= 829 - r.top- 830 - cardRect.top; 831 - 832 - return ( 833 - rel>=35&& 834 - rel<= 835 - cardRect.height*.75 836 - ); 837 - }) 838 - .sort(function(a,b){ 839 - return ( 840 - a.getBoundingClientRect().top- 841 - b.getBoundingClientRect().top 842 - ); 843 - }); 844 - 845 - return rows[0]||null; 846 - } 847 - 848 - function alignKnownBars(cards){ 849 - var rows= 850 - cards.map(function(card){ 851 - var bar= 852 - findKnownBar(card); 853 - 854 - if(!bar)return null; 855 - 856 - var cr= 857 - card.getBoundingClientRect(); 858 - 859 - var br= 860 - bar.getBoundingClientRect(); 861 - 862 - return { 863 - bar:bar, 864 - relativeTop: 865 - br.top- 866 - cr.top 867 - }; 868 - }); 869 - 870 - if( 871 - rows.some(function(row){ 872 - return !row; 873 - }) 874 - ){ 875 - return false; 876 - } 877 - 878 - var target= 879 - Math.max.apply( 880 - Math, 881 - rows.map(function(row){ 882 - return row.relativeTop; 883 - }) 884 - ); 885 - 886 - rows.forEach(function(row){ 887 - var delta= 888 - target- 889 - row.relativeTop; 890 - 891 - if(delta<=1)return; 892 - 893 - saveOriginal( 894 - row.bar, 895 - originalMarginTop, 896 - "margin-top" 897 - ); 898 - 899 - var current= 900 - num( 901 - getComputedStyle( 902 - row.bar 903 - ).marginTop 904 - ); 905 - 906 - row.bar.style.setProperty( 907 - "margin-top", 908 - ( 909 - current+ 910 - delta 911 - )+"px" 912 - ); 913 - 914 - row.bar.setAttribute( 915 - "data-sn-first-section-aligned", 916 - "7" 917 - ); 918 - 919 - sectionManaged.add( 920 - row.bar 921 - ); 922 - }); 923 - 924 - return true; 925 - } 926 - 927 - /* ---------- Generic first content after heading ---------- */ 928 - 929 - function heading(card){ 930 - var cr= 931 - card.getBoundingClientRect(); 932 - 933 - var rows= 934 - Array.from( 935 - card.querySelectorAll( 936 - "h1,h2,h3,h4,h5,h6,.box-title,[role=heading]" 937 - ) 938 - ) 939 - .filter(function(el){ 940 - if(!visible(el,20,8))return false; 941 - 942 - var r=el.getBoundingClientRect(); 943 - 944 - var rel= 945 - r.top- 946 - cr.top; 947 - 948 - return ( 949 - rel>=0&& 950 - rel<= 951 - Math.min( 952 - 160, 953 - cr.height*.45 954 - ) 955 - ); 956 - }) 957 - .sort(function(a,b){ 958 - return ( 959 - a.getBoundingClientRect().top- 960 - b.getBoundingClientRect().top 961 - ); 962 - }); 963 - 964 - return rows[0]||null; 965 - } 966 - 967 - function firstContent(card,h){ 968 - if(!h)return null; 969 - 970 - var cr= 971 - card.getBoundingClientRect(); 972 - 973 - var hr= 974 - h.getBoundingClientRect(); 975 - 976 - var rows= 977 - Array.from( 978 - card.querySelectorAll( 979 - "p,div,ul,ol,dl,blockquote" 980 - ) 981 - ) 982 - .filter(function(el){ 983 - if( 984 - el===h|| 985 - h.contains(el)|| 986 - el.contains(h) 987 - ){ 988 - return false; 413 + function rowGroups(entries){ 414 + var groups=[]; 415 + entries.slice().sort(function(a,b){ 416 + return a.rect.top-b.rect.top||a.rect.left-b.rect.left; 417 + }).forEach(function(entry){ 418 + var group=null; 419 + for(var i=0;i<groups.length;i++){ 420 + if(Math.abs(groups[i].top-entry.rect.top)<=ROW_TOLERANCE){ 421 + group=groups[i]; 422 + break; 989 989 } 990 - 991 - if(!visible(el,30,8))return false; 992 - 993 - var text= 994 - String(el.textContent||"") 995 - .replace(/\s+/g," ") 996 - .trim(); 997 - 998 - if(text.length<3)return false; 999 - 1000 - var r=el.getBoundingClientRect(); 1001 - 1002 - if( 1003 - r.top< 1004 - hr.bottom-1 1005 - ){ 1006 - return false; 1007 - } 1008 - 1009 - if( 1010 - r.top-cr.top> 1011 - Math.min( 1012 - 280, 1013 - cr.height*.65 1014 - ) 1015 - ){ 1016 - return false; 1017 - } 1018 - 1019 - if( 1020 - r.height> 1021 - cr.height*.58 1022 - ){ 1023 - return false; 1024 - } 1025 - 1026 - return true; 1027 - }) 1028 - .sort(function(a,b){ 1029 - var ar= 1030 - a.getBoundingClientRect(); 1031 - 1032 - var br= 1033 - b.getBoundingClientRect(); 1034 - 1035 - return ( 1036 - ar.top-br.top|| 1037 - ar.height-br.height 1038 - ); 1039 - }); 1040 - 1041 - return rows[0]||null; 1042 - } 1043 - 1044 - function alignGeneric(cards){ 1045 - var rows= 1046 - cards.map(function(card){ 1047 - var h= 1048 - heading(card); 1049 - 1050 - var c= 1051 - firstContent( 1052 - card, 1053 - h 1054 - ); 1055 - 1056 - if(!h||!c)return null; 1057 - 1058 - var cr= 1059 - card.getBoundingClientRect(); 1060 - 1061 - var rr= 1062 - c.getBoundingClientRect(); 1063 - 1064 - return { 1065 - content:c, 1066 - relativeTop: 1067 - rr.top-cr.top 1068 - }; 1069 - }); 1070 - 1071 - if( 1072 - rows.some(function(row){ 1073 - return !row; 1074 - }) 1075 - ){ 1076 - return false; 1077 - } 1078 - 1079 - var target= 1080 - Math.max.apply( 1081 - Math, 1082 - rows.map(function(row){ 1083 - return row.relativeTop; 1084 - }) 1085 - ); 1086 - 1087 - rows.forEach(function(row){ 1088 - var delta= 1089 - target- 1090 - row.relativeTop; 1091 - 1092 - if(delta<=1)return; 1093 - 1094 - saveOriginal( 1095 - row.content, 1096 - originalMarginTop, 1097 - "margin-top" 1098 - ); 1099 - 1100 - var current= 1101 - num( 1102 - getComputedStyle( 1103 - row.content 1104 - ).marginTop 1105 - ); 1106 - 1107 - row.content.style.setProperty( 1108 - "margin-top", 1109 - ( 1110 - current+ 1111 - delta 1112 - )+"px" 1113 - ); 1114 - 1115 - row.content.setAttribute( 1116 - "data-sn-first-content-aligned", 1117 - "7" 1118 - ); 1119 - 1120 - contentManaged.add( 1121 - row.content 1122 - ); 424 + } 425 + if(!group){ 426 + group={top:entry.rect.top,entries:[]}; 427 + groups.push(group); 428 + } 429 + group.entries.push(entry); 1123 1123 }); 1124 - 1125 - return true; 431 + return groups; 1126 1126 } 1127 1127 1128 - function applyRow(group){1129 - if(!validRow(group))return false;434 + function run(){ 435 + reset(); 1130 1130 1131 - var cards=[]; 1132 - var seen=new Set(); 437 + if(window.innerWidth<=MOBILE_MAX)return; 1133 1133 1134 - group.entries.forEach(function(entry){ 1135 - if(!seen.has(entry.target)){ 1136 - seen.add(entry.target); 1137 - cards.push(entry.target); 1138 - } 439 + var parents=Array.from(root.querySelectorAll("*")).filter(function(el){ 440 + return el.children&&el.children.length>=2&&horizontalLayout(el); 1139 1139 }); 1140 1140 1141 - if(cards.length<2)return false; 443 + parents.forEach(function(parent){ 444 + var entries=[]; 1142 1142 1143 - if( 1144 - !alignKnownBars(cards) 1145 - ){ 1146 - alignGeneric(cards); 1147 - } 446 + Array.from(parent.children).forEach(function(child){ 447 + if(!visible(child))return; 448 + var target=pickTarget(child); 449 + if(!target)return; 450 + entries.push({ 451 + target:target, 452 + rect:target.getBoundingClientRect() 453 + }); 454 + }); 1148 1148 1149 - varmaxHeight=0;456 + if(entries.length<2)return; 1150 1150 1151 - cards.forEach(function(card){ 1152 - maxHeight= 1153 - Math.max( 1154 - maxHeight, 1155 - card.getBoundingClientRect().height 1156 - ); 1157 - }); 458 + rowGroups(entries).forEach(function(group){ 459 + if(group.entries.length<2)return; 1158 1158 1159 - maxHeight= 1160 - Math.ceil( 1161 - maxHeight 1162 - ); 461 + var lefts=group.entries.map(function(e){return e.rect.left;}).sort(function(a,b){return a-b;}); 462 + if(lefts[lefts.length-1]-lefts[0]<80)return; 1163 1163 1164 - if(maxHeight<MIN_H)return false; 464 + var targets=[]; 465 + var seen=new Set(); 1165 1165 1166 - cards.forEach(function(card){ 1167 - saveOriginal( 1168 - card, 1169 - originalMinHeight, 1170 - "min-height" 1171 - ); 1172 - 1173 - card.style.setProperty( 1174 - "min-height", 1175 - maxHeight+"px" 1176 - ); 1177 - 1178 - card.setAttribute( 1179 - "data-sn-equal-height-managed", 1180 - "7" 1181 - ); 1182 - 1183 - heightManaged.add(card); 1184 - }); 1185 - 1186 - return true; 1187 - } 1188 - 1189 - function calculate(force){ 1190 - if(applying)return; 1191 - 1192 - var width= 1193 - Math.round( 1194 - window.innerWidth 1195 - ); 1196 - 1197 - var meaningful= 1198 - lastWidth<0|| 1199 - Math.abs( 1200 - width- 1201 - lastWidth 1202 - )>= 1203 - MIN_WIDTH_CHANGE; 1204 - 1205 - if( 1206 - hasApplied&& 1207 - !force&& 1208 - !meaningful 1209 - ){ 1210 - return; 1211 - } 1212 - 1213 - applying=true; 1214 - 1215 - try{ 1216 - harmoniseCustomCallouts(); 1217 - 1218 - if(width<=MOBILE_MAX){ 1219 - if(hasApplied){ 1220 - resetRuntime(); 1221 - } 1222 - 1223 - hasApplied=false; 1224 - lastWidth=width; 1225 - return; 1226 - } 1227 - 1228 - if(hasApplied){ 1229 - resetRuntime(); 1230 - } 1231 - 1232 - var parents= 1233 - Array.from( 1234 - root.querySelectorAll("*") 1235 - ) 1236 - .filter(function(parent){ 1237 - return ( 1238 - visible( 1239 - parent, 1240 - MIN_W, 1241 - MIN_H 1242 - )&& 1243 - parent.children&& 1244 - parent.children.length>=2&& 1245 - parent.children.length<= 1246 - MAX_PARENT_CHILDREN 1247 - ); 467 + group.entries.forEach(function(e){ 468 + if(!seen.has(e.target)){ 469 + seen.add(e.target); 470 + targets.push(e.target); 471 + } 1248 1248 }); 1249 1249 1250 - var touched= 1251 - new Set(); 474 + if(targets.length<2)return; 1252 1252 1253 - parents.forEach(function(parent){ 1254 - var entries=[]; 1255 - 1256 - Array.from( 1257 - parent.children 1258 - ).forEach(function(child){ 1259 - if( 1260 - !visible( 1261 - child, 1262 - MIN_W, 1263 - MIN_H 1264 - ) 1265 - ){ 1266 - return; 1267 - } 1268 - 1269 - var target= 1270 - pickTarget(child); 1271 - 1272 - if(!target)return; 1273 - 1274 - entries.push({ 1275 - target:target, 1276 - rect: 1277 - target.getBoundingClientRect() 1278 - }); 476 + var max=0; 477 + targets.forEach(function(el){ 478 + max=Math.max(max,el.getBoundingClientRect().height); 1279 1279 }); 1280 1280 1281 - groupRows( 1282 - entries 1283 - ).forEach(function(group){ 1284 - if(!validRow(group))return; 481 + max=Math.ceil(max); 482 + if(max<MIN_H)return; 1285 1285 1286 - var targets= 1287 - group.entries.map(function(entry){ 1288 - return entry.target; 1289 - }); 1290 - 1291 - if( 1292 - !targets.some(function(el){ 1293 - return !touched.has(el); 1294 - }) 1295 - ){ 1296 - return; 1297 - } 1298 - 1299 - if(applyRow(group)){ 1300 - targets.forEach(function(el){ 1301 - touched.add(el); 1302 - }); 1303 - } 484 + targets.forEach(function(el){ 485 + el.style.setProperty("min-height",max+"px"); 486 + el.setAttribute("data-sn-equal-height-managed","1"); 487 + managed.add(el); 1304 1304 }); 1305 1305 }); 1306 - 1307 - lastWidth=width; 1308 - hasApplied=true; 1309 - }finally{ 1310 - applying=false; 1311 - } 490 + }); 1312 1312 } 1313 1313 1314 - function resize(){ 1315 - if(resizeTimer){ 1316 - clearTimeout( 1317 - resizeTimer 1318 - ); 1319 - } 1320 - 1321 - resizeTimer= 1322 - setTimeout( 1323 - function(){ 1324 - resizeTimer=0; 1325 - calculate(false); 1326 - }, 1327 - RESIZE_DEBOUNCE 1328 - ); 493 + function schedule(){ 494 + if(raf)cancelAnimationFrame(raf); 495 + raf=requestAnimationFrame(function(){ 496 + raf=requestAnimationFrame(function(){ 497 + raf=0; 498 + run(); 499 + }); 500 + }); 1329 1329 } 1330 1330 1331 - function waitImages(){ 1332 - var images= 1333 - Array.from( 1334 - root.querySelectorAll("img") 1335 - ); 503 + addEventListener("resize",schedule,{passive:true}); 504 + addEventListener("load",schedule,{once:true}); 1336 1336 1337 - return Promise.all( 1338 - images.map(function(img){ 1339 - if(img.complete){ 1340 - return Promise.resolve(); 1341 - } 506 + root.addEventListener("click",function(){ 507 + setTimeout(schedule,0); 508 + },true); 1342 1342 1343 - return new Promise(function(resolve){ 1344 - var done=function(){ 1345 - resolve(); 1346 - }; 1347 - 1348 - img.addEventListener( 1349 - "load", 1350 - done, 1351 - {once:true} 1352 - ); 1353 - 1354 - img.addEventListener( 1355 - "error", 1356 - done, 1357 - {once:true} 1358 - ); 1359 - }); 1360 - }) 1361 - ); 510 + if(document.fonts&&document.fonts.ready){ 511 + document.fonts.ready.then(schedule); 1362 1362 } 1363 1363 1364 - async function initial(){ 1365 - if( 1366 - document.readyState!== 1367 - "complete" 1368 - ){ 1369 - await new Promise(function(resolve){ 1370 - addEventListener( 1371 - "load", 1372 - resolve, 1373 - {once:true} 1374 - ); 1375 - }); 1376 - } 1377 - 1378 - if( 1379 - document.fonts&& 1380 - document.fonts.ready 1381 - ){ 1382 - try{ 1383 - await document.fonts.ready; 1384 - }catch(error){} 1385 - } 1386 - 1387 - await waitImages(); 1388 - 1389 - // Exactly one initial layout calculation. 1390 - calculate(true); 1391 - } 1392 - 1393 - addEventListener( 1394 - "resize", 1395 - resize, 1396 - {passive:true} 1397 - ); 1398 - 1399 - initial(); 514 + schedule(); 515 + setTimeout(schedule,250); 516 + setTimeout(schedule,900); 1400 1400 })(); 1401 1401 </script> 1402 - 1403 1403 <!-- SN_HORIZONTAL_BOX_HARMONIZER_END --> 1404 -{{/html}}\n 520 +{{/html}} 521 +