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