Changes for page Service Navigator
Last modified by Veronika Kocher on Thursday, 03 Sep 2026 14:15
From version 22.16
edited by Veronika Kocher
on Thursday, 03 Sep 2026 13:04
on Thursday, 03 Sep 2026 13:04
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
-
... ... @@ -286,100 +286,21 @@ 286 286 {{/html}} 287 287 288 288 {{html clean="false"}} 289 -<!-- SN_SERVICE_NAVIGATOR_MASTER_STYLE_START --> 290 - 291 -<style data-sn-service-navigator-master="1"> 292 -/* ========================================================= 293 - MASTER TYPOGRAPHY 294 - ========================================================= */ 295 -#xwikicontent h1, 296 -#xwikicontent h2, 297 -#xwikicontent h3, 298 -#xwikicontent h4, 299 -#xwikicontent h5, 300 -#xwikicontent h6, 301 -#xwikicontent .box-title, 302 -#xwikicontent [role="heading"], 303 -#xwikicontent h1 a, 304 -#xwikicontent h2 a, 305 -#xwikicontent h3 a, 306 -#xwikicontent h4 a, 307 -#xwikicontent h5 a, 308 -#xwikicontent h6 a, 309 -#xwikicontent .box-title a, 310 -#xwikicontent [role="heading"] a{ 311 - text-align:left!important; 312 - text-justify:auto!important; 313 - word-spacing:normal!important; 289 +<!-- SN_HORIZONTAL_BOX_HARMONIZER_START --> 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} 314 314 } 315 - 316 -/* ========================================================= 317 - COMING SOON / IN VORBEREITUNG 318 - ========================================================= */ 319 -.sn-coming-soon-badge{ 320 - display:inline-block; 321 - vertical-align:middle; 322 - margin-left:10px; 323 - padding:4px 8px; 324 - border-radius:14px; 325 - border:1px solid #efd9cc; 326 - background:#fff4ee; 327 - color:#8a4d36; 328 - font-size:11px; 329 - font-weight:700; 330 - letter-spacing:.055em; 331 - line-height:1.2; 332 - white-space:nowrap; 333 -} 334 - 335 -/* ========================================================= 336 - NATIVE / DETAIL CALLOUT GEOMETRY 337 - Preserve existing backgrounds. 338 - ========================================================= */ 339 -#xwikicontent .arsn-info, 340 -#xwikicontent .dmp-info, 341 -#xwikicontent .ido-info, 342 -#xwikicontent .pp-info, 343 -#xwikicontent .infomessage{ 344 - box-sizing:border-box!important; 345 - border-left:4px solid #21b6d7!important; 346 - border-radius:8px; 347 - text-align:left!important; 348 - word-spacing:normal!important; 349 -} 350 - 351 -#xwikicontent .arsn-warn, 352 -#xwikicontent .dmp-warn, 353 -#xwikicontent .ido-warn, 354 -#xwikicontent .pp-warn, 355 -#xwikicontent .warn, 356 -#xwikicontent .warning, 357 -#xwikicontent .warningmessage, 358 -#xwikicontent .errormessage{ 359 - box-sizing:border-box!important; 360 - border-left:4px solid #e94b13!important; 361 - border-radius:8px; 362 - text-align:left!important; 363 - word-spacing:normal!important; 364 -} 365 - 366 -[data-sn-master-equal-height], 367 -[data-sn-master-first-row]{ 368 - box-sizing:border-box; 369 -} 370 370 </style> 371 - 372 -<script data-sn-service-navigator-master="1"> 296 +<script data-sn-horizontal-box-harmonizer="1"> 373 373 (function(){ 374 374 "use strict"; 375 375 376 - var PAGE_KIND="overview"; 377 - var PLACEHOLDER=false; 378 - var PLACEHOLDER_LABEL="COMING SOON"; 379 - 380 380 var MOBILE_MAX=767; 381 - var ROW_TOLERANCE=6; 382 - var RESIZE_DEBOUNCE=220; 301 + var ROW_TOLERANCE=4; 302 + var MIN_W=150; 303 + var MIN_H=36; 383 383 384 384 var root= 385 385 document.getElementById("xwikicontent")|| ... ... @@ -389,1044 +389,212 @@ 389 389 390 390 if(!root)return; 391 391 392 - var managedHeight=new Set(); 393 - var managedMargin=new Set(); 394 - var originalHeight=new WeakMap(); 395 - var originalMargin=new WeakMap(); 313 + var managed=new Set(); 314 + var raf=0; 396 396 397 - var resizeTimer=0; 398 - var running=false; 399 - 400 - var THEMES=[ 401 - { 402 - name:"BLUE", 403 - accent:"#21b6d7", 404 - bg:"#eaf7fb", 405 - text:"#315d68", 406 - labels:[ 407 - "HIER STARTEN", 408 - "ENTSCHEIDEN", 409 - "ÜBERPRÜFEN & ANPASSEN", 410 - "START HERE", 411 - "DECIDE", 412 - "REVIEW & ADAPT" 413 - ] 414 - }, 415 - { 416 - name:"RED", 417 - accent:"#e94b13", 418 - bg:"#fff1ec", 419 - text:"#8a4d36", 420 - labels:[ 421 - "PLANEN & ORGANISIEREN", 422 - "ORGANISIEREN & DOKUMENTIEREN", 423 - "PUBLIZIEREN & PRÄSENTIEREN", 424 - "PLAN & ORGANISE", 425 - "PLAN & ORGANIZE", 426 - "ORGANISE & DOCUMENT", 427 - "ORGANIZE & DOCUMENT", 428 - "PUBLISH & PRESENT" 429 - ] 430 - }, 431 - { 432 - name:"YELLOW", 433 - accent:"#f0aa00", 434 - bg:"#fff8e7", 435 - text:"#785b17", 436 - labels:[ 437 - "SCHÜTZEN & KLÄREN", 438 - "STANDARDISIEREN & IDENTIFIZIEREN", 439 - "ÖFFNEN, NACHNUTZEN & AUFFINDBAR MACHEN", 440 - "PROTECT & CLARIFY", 441 - "STANDARDISE & IDENTIFY", 442 - "STANDARDIZE & IDENTIFY", 443 - "OPEN, REUSE & MAKE FINDABLE" 444 - ] 445 - }, 446 - { 447 - name:"GREEN", 448 - accent:"#38b76a", 449 - bg:"#edf9f1", 450 - text:"#3f7451", 451 - labels:[ 452 - "INFRASTRUKTUR EINRICHTEN", 453 - "INFRASTRUKTUR & ZUSAMMENARBEIT EINRICHTEN", 454 - "SPEICHERN & ZUGRIFF STEUERN", 455 - "REPOSITORIUM, ERHALTEN & ÜBERGEBEN", 456 - "SET UP INFRASTRUCTURE", 457 - "SET UP INFRASTRUCTURE & COLLABORATION", 458 - "STORE & CONTROL ACCESS", 459 - "REPOSITORY, PRESERVE & HAND OVER" 460 - ] 461 - } 462 - ]; 463 - 464 - function num(value){ 465 - var n=parseFloat(value); 316 + function num(v){ 317 + var n=parseFloat(v); 466 466 return Number.isFinite(n)?n:0; 467 467 } 468 468 469 - function norm(value){ 470 - return String(value||"") 471 - .replace(/\s+/g," ") 472 - .trim() 473 - .toUpperCase(); 474 - } 475 - 476 476 function visible(el){ 477 477 if(!el||el.nodeType!==1)return false; 478 - 479 - var style=getComputedStyle(el); 480 - var rect=el.getBoundingClientRect(); 481 - 482 - return ( 483 - style.display!=="none"&& 484 - style.visibility!=="hidden"&& 485 - rect.width>20&& 486 - rect.height>4 487 - ); 323 + var s=getComputedStyle(el); 324 + if(s.display==="none"||s.visibility==="hidden"||Number(s.opacity)===0)return false; 325 + var r=el.getBoundingClientRect(); 326 + return r.width>=MIN_W&&r.height>=MIN_H; 488 488 } 489 489 490 - function saveStyle(el,map,property){ 491 - if(map.has(el))return; 492 - 493 - map.set(el,{ 494 - value:el.style.getPropertyValue(property), 495 - priority:el.style.getPropertyPriority(property) 496 - }); 497 - } 498 - 499 - function restoreStyle(el,map,property){ 500 - var original=map.get(el); 501 - 502 - if(original&&original.value){ 503 - el.style.setProperty( 504 - property, 505 - original.value, 506 - original.priority||"" 507 - ); 508 - }else{ 509 - el.style.removeProperty(property); 510 - } 511 - } 512 - 513 - function resetRuntime(){ 514 - managedHeight.forEach(function(el){ 515 - restoreStyle( 516 - el, 517 - originalHeight, 518 - "min-height" 519 - ); 520 - el.removeAttribute( 521 - "data-sn-master-equal-height" 522 - ); 523 - }); 524 - 525 - managedMargin.forEach(function(el){ 526 - restoreStyle( 527 - el, 528 - originalMargin, 529 - "margin-top" 530 - ); 531 - el.removeAttribute( 532 - "data-sn-master-first-row" 533 - ); 534 - }); 535 - 536 - managedHeight.clear(); 537 - managedMargin.clear(); 538 - } 539 - 540 - function themeFor(text){ 541 - var value=norm(text); 542 - 543 - for(var i=0;i<THEMES.length;i++){ 544 - for(var j=0;j<THEMES[i].labels.length;j++){ 545 - var label=THEMES[i].labels[j]; 546 - 547 - if( 548 - value===label|| 549 - value.indexOf(label+" ")===0|| 550 - value.indexOf(label+" -")===0|| 551 - value.indexOf(label+" ·")===0 552 - ){ 553 - return THEMES[i]; 554 - } 555 - } 556 - } 557 - 558 - return null; 559 - } 560 - 561 - /* ======================================================= 562 - PLACEHOLDER BADGE 563 - ======================================================= */ 564 - 565 - function applyPlaceholderBadge(){ 566 - if(!PLACEHOLDER)return; 567 - 568 - if( 569 - document.querySelector( 570 - ".sn-coming-soon-badge" 571 - ) 572 - ){ 573 - return; 574 - } 575 - 576 - var title= 577 - document.querySelector( 578 - "#document-title" 579 - )|| 580 - document.querySelector( 581 - "h1" 582 - ); 583 - 584 - if(!title)return; 585 - 586 - var badge= 587 - document.createElement( 588 - "span" 589 - ); 590 - 591 - badge.className= 592 - "sn-coming-soon-badge"; 593 - 594 - badge.textContent= 595 - PLACEHOLDER_LABEL; 596 - 597 - badge.setAttribute( 598 - "aria-label", 599 - PLACEHOLDER_LABEL 329 + function excluded(el){ 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]" 600 600 ); 601 - 602 - title.appendChild( 603 - badge 604 - ); 605 605 } 606 606 607 - /* ======================================================= 608 - DETAIL PAGE OWN-ACCENT PROPAGATION 609 - ======================================================= */ 610 - 611 - function parseRGB(value){ 612 - var match=String(value||"").match( 613 - /rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)/i 614 - ); 615 - 616 - if(!match)return null; 617 - 618 - return [ 619 - Number(match[1]), 620 - Number(match[2]), 621 - Number(match[3]) 622 - ]; 335 + function namedLikeBox(el){ 336 + var c=typeof el.className==="string"?el.className:""; 337 + return /(^|[\s_-])(box|card|tile|panel|role|check|service|source|call|area|detail|resource|topic|warn|info)([\s_-]|$)/i.test(c); 623 623 } 624 624 625 - function distance(a,b){ 626 - return Math.sqrt( 627 - Math.pow(a[0]-b[0],2)+ 628 - Math.pow(a[1]-b[1],2)+ 629 - Math.pow(a[2]-b[2],2) 340 + function boxLike(el){ 341 + if(!visible(el)||excluded(el))return false; 342 + var s=getComputedStyle(el); 343 + var r=el.getBoundingClientRect(); 344 + var border= 345 + num(s.borderTopWidth)+num(s.borderRightWidth)+ 346 + num(s.borderBottomWidth)+num(s.borderLeftWidth); 347 + var radius=Math.max( 348 + num(s.borderTopLeftRadius),num(s.borderTopRightRadius), 349 + num(s.borderBottomLeftRadius),num(s.borderBottomRightRadius) 630 630 ); 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); 631 631 } 632 632 633 - function paletteMatch(cssColor){ 634 - var rgb=parseRGB(cssColor); 356 + function pickTarget(child){ 357 + if(!visible(child))return null; 358 + if(boxLike(child))return child; 635 635 636 - if(!rgb)return null; 637 - 638 - var palette=[ 639 - {hex:"#21b6d7",rgb:[33,182,215]}, 640 - {hex:"#e94b13",rgb:[233,75,19]}, 641 - {hex:"#f0aa00",rgb:[240,170,0]}, 642 - {hex:"#38b76a",rgb:[56,183,106]} 643 - ]; 644 - 645 - var best=null; 646 - var bestDistance=Infinity; 647 - 648 - palette.forEach(function(item){ 649 - var d=distance(rgb,item.rgb); 650 - 651 - if(d<bestDistance){ 652 - best=item; 653 - bestDistance=d; 654 - } 360 + var cr=child.getBoundingClientRect(); 361 + var q=[]; 362 + Array.from(child.children||[]).forEach(function(el){ 363 + q.push({el:el,depth:1}); 655 655 }); 656 656 657 - return bestDistance<=30 658 - ?best 659 - :null; 660 - } 366 + var best=null,bestScore=-1; 661 661 662 - function propagateDetailAccents(){ 663 - if(PAGE_KIND!=="detail")return; 368 + while(q.length){ 369 + var item=q.shift(); 370 + var el=item.el; 371 + if(!visible(el))continue; 664 664 665 - Array.from( 666 - root.querySelectorAll( 667 - ".arsn-call,.dmp-call,.ido-call,.pp-call,"+ 668 - ".arsn-source,.dmp-source,.ido-source,.pp-source" 669 - ) 670 - ).forEach(function(el){ 671 - if(!visible(el))return; 373 + var r=el.getBoundingClientRect(); 672 672 673 - var style=getComputedStyle(el); 674 - 675 - if( 676 - num(style.borderTopWidth)>=2 677 - ){ 678 - var match= 679 - paletteMatch( 680 - style.borderTopColor 681 - ); 682 - 683 - if(match){ 684 - el.style.setProperty( 685 - "border-left", 686 - "4px solid "+match.hex, 687 - "important" 688 - ); 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; 379 + if(score>bestScore){ 380 + best=el; 381 + bestScore=score; 689 689 } 690 690 } 691 - }); 692 692 693 - // Warning families: explicit safety override. 694 - Array.from( 695 - root.querySelectorAll( 696 - ".arsn-warn,.dmp-warn,.ido-warn,.pp-warn,"+ 697 - ".warn,.warning,.warningmessage,.errormessage" 698 - ) 699 - ).forEach(function(el){ 700 - if(!visible(el))return; 701 - 702 - el.style.setProperty( 703 - "border-left", 704 - "4px solid #e94b13", 705 - "important" 706 - ); 707 - }); 708 - 709 - // Info families: explicit orientation override. 710 - Array.from( 711 - root.querySelectorAll( 712 - ".arsn-info,.dmp-info,.ido-info,.pp-info,.infomessage" 713 - ) 714 - ).forEach(function(el){ 715 - if(!visible(el))return; 716 - 717 - el.style.setProperty( 718 - "border-left", 719 - "4px solid #21b6d7", 720 - "important" 721 - ); 722 - }); 723 - } 724 - 725 - /* ======================================================= 726 - OVERVIEW SEMANTIC THEME PALETTE 727 - ======================================================= */ 728 - 729 - function smallestThemeHeaders(){ 730 - return Array.from( 731 - root.querySelectorAll( 732 - "div,span,p,strong,h3,h4,h5,h6" 733 - ) 734 - ).filter(function(el){ 735 - if(!visible(el))return false; 736 - if(!themeFor(el.textContent))return false; 737 - 738 - return !Array.from( 739 - el.children||[] 740 - ).some(function(child){ 741 - return !!themeFor( 742 - child.textContent 743 - ); 744 - }); 745 - }); 746 - } 747 - 748 - function findOverviewCard(header){ 749 - var node=header.parentElement; 750 - var candidates=[]; 751 - 752 - while(node&&node!==root){ 753 - var rect=node.getBoundingClientRect(); 754 - var style=getComputedStyle(node); 755 - 756 - var border= 757 - num(style.borderTopWidth)+ 758 - num(style.borderRightWidth)+ 759 - num(style.borderBottomWidth)+ 760 - num(style.borderLeftWidth); 761 - 762 - if( 763 - rect.width>=220&& 764 - rect.width<=800&& 765 - rect.height>=120&& 766 - border>=1 767 - ){ 768 - candidates.push(node); 385 + if(item.depth<3){ 386 + Array.from(el.children||[]).forEach(function(next){ 387 + q.push({el:next,depth:item.depth+1}); 388 + }); 769 769 } 770 - 771 - node=node.parentElement; 772 772 } 773 773 774 - if(!candidates.length)return null; 775 - 776 - candidates.sort(function(a,b){ 777 - return ( 778 - b.getBoundingClientRect().height- 779 - a.getBoundingClientRect().height 780 - ); 781 - }); 782 - 783 - return candidates[0]; 392 + return best; 784 784 } 785 785 786 - function rowCandidates(link,card){ 787 - var result=[]; 788 - var cardRect= 789 - card.getBoundingClientRect(); 790 - 791 - var node=link; 792 - 793 - while(node&&node!==card){ 794 - if(visible(node)){ 795 - var rect= 796 - node.getBoundingClientRect(); 797 - 798 - if( 799 - rect.height<=105&& 800 - rect.width>= 801 - cardRect.width*.50&& 802 - rect.width<= 803 - cardRect.width*1.03 804 - ){ 805 - result.push(node); 806 - } 807 - } 808 - 809 - node=node.parentElement; 810 - } 811 - 812 - return result; 813 - } 814 - 815 - function chooseOuterRow( 816 - candidates, 817 - link 818 - ){ 819 - if(!candidates.length){ 820 - return link; 821 - } 822 - 823 - var bordered= 824 - candidates.filter(function(el){ 825 - return ( 826 - num( 827 - getComputedStyle(el) 828 - .borderLeftWidth 829 - )>=1 830 - ); 831 - }); 832 - 833 - var pool= 834 - bordered.length 835 - ?bordered 836 - :candidates; 837 - 838 - pool.sort(function(a,b){ 839 - var ar= 840 - a.getBoundingClientRect(); 841 - 842 - var br= 843 - b.getBoundingClientRect(); 844 - 845 - return ( 846 - ar.left-br.left|| 847 - br.width-ar.width 848 - ); 395 + function reset(){ 396 + managed.forEach(function(el){ 397 + el.style.removeProperty("min-height"); 398 + el.removeAttribute("data-sn-equal-height-managed"); 849 849 }); 850 - 851 - return pool[0]||link; 400 + managed.clear(); 852 852 } 853 853 854 - function applyOverviewPalette(){ 855 - if(PAGE_KIND!=="overview"){ 856 - return []; 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"; 857 857 } 858 - 859 - var headers= 860 - smallestThemeHeaders() 861 - .map(function(el){ 862 - return { 863 - el:el, 864 - theme: 865 - themeFor( 866 - el.textContent 867 - ), 868 - card: 869 - findOverviewCard( 870 - el 871 - ) 872 - }; 873 - }) 874 - .filter(function(row){ 875 - return !!row.card; 876 - }); 877 - 878 - var unique=[]; 879 - var seenHeaders=new Set(); 880 - 881 - headers.forEach(function(row){ 882 - var key= 883 - row.theme.name+ 884 - "|"+ 885 - Math.round( 886 - row.card 887 - .getBoundingClientRect() 888 - .left 889 - )+ 890 - "|"+ 891 - Math.round( 892 - row.el 893 - .getBoundingClientRect() 894 - .top 895 - ); 896 - 897 - if(!seenHeaders.has(key)){ 898 - seenHeaders.add(key); 899 - unique.push(row); 900 - } 901 - }); 902 - 903 - unique.forEach(function(row){ 904 - var headerRect= 905 - row.el 906 - .getBoundingClientRect(); 907 - 908 - row.el.style.setProperty( 909 - "background", 910 - row.theme.bg, 911 - "important" 912 - ); 913 - 914 - row.el.style.setProperty( 915 - "color", 916 - row.theme.text, 917 - "important" 918 - ); 919 - 920 - row.el.style.setProperty( 921 - "text-align", 922 - "left", 923 - "important" 924 - ); 925 - 926 - row.el.style.setProperty( 927 - "word-spacing", 928 - "normal", 929 - "important" 930 - ); 931 - 932 - var later= 933 - unique 934 - .filter(function(other){ 935 - return ( 936 - other.card===row.card&& 937 - other.el 938 - .getBoundingClientRect() 939 - .top> 940 - headerRect.top+2 941 - ); 942 - }) 943 - .sort(function(a,b){ 944 - return ( 945 - a.el 946 - .getBoundingClientRect() 947 - .top- 948 - b.el 949 - .getBoundingClientRect() 950 - .top 951 - ); 952 - }); 953 - 954 - var stopTop= 955 - later.length 956 - ?later[0].el 957 - .getBoundingClientRect() 958 - .top 959 - :Infinity; 960 - 961 - Array.from( 962 - row.card.querySelectorAll("a") 963 - ).forEach(function(link){ 964 - if(!visible(link))return; 965 - 966 - var rect= 967 - link.getBoundingClientRect(); 968 - 969 - if( 970 - rect.top<= 971 - headerRect.bottom-2|| 972 - rect.top>= 973 - stopTop-2 974 - ){ 975 - return; 976 - } 977 - 978 - var candidates= 979 - rowCandidates( 980 - link, 981 - row.card 982 - ); 983 - 984 - var target= 985 - chooseOuterRow( 986 - candidates, 987 - link 988 - ); 989 - 990 - candidates.forEach(function(el){ 991 - el.style.setProperty( 992 - "border-left", 993 - "0 solid transparent", 994 - "important" 995 - ); 996 - }); 997 - 998 - target.style.setProperty( 999 - "border-left", 1000 - "3px solid "+ 1001 - row.theme.accent, 1002 - "important" 1003 - ); 1004 - 1005 - target.style.setProperty( 1006 - "box-sizing", 1007 - "border-box", 1008 - "important" 1009 - ); 1010 - }); 1011 - }); 1012 - 1013 - return unique; 410 + return false; 1014 1014 } 1015 1015 1016 - /* ======================================================= 1017 - OVERVIEW CARD HEIGHT + FIRST THEMATIC ROW 1018 - ======================================================= */ 1019 - 1020 - function alignOverviewCards(headers){ 1021 - if( 1022 - PAGE_KIND!=="overview"|| 1023 - window.innerWidth<=MOBILE_MAX 1024 - ){ 1025 - return; 1026 - } 1027 - 1028 - var cards=[]; 1029 - var seen=new Set(); 1030 - 1031 - headers.forEach(function(row){ 1032 - if(!seen.has(row.card)){ 1033 - seen.add(row.card); 1034 - cards.push(row.card); 1035 - } 1036 - }); 1037 - 1038 - if(cards.length<2){ 1039 - return; 1040 - } 1041 - 1042 - // Group cards by actual top position. 413 + function rowGroups(entries){ 1043 1043 var groups=[]; 1044 - 1045 - cards.forEach(function(card){ 1046 - var top= 1047 - card.getBoundingClientRect().top; 1048 - 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){ 1049 1049 var group=null; 1050 - 1051 1051 for(var i=0;i<groups.length;i++){ 1052 - if( 1053 - Math.abs( 1054 - groups[i].top-top 1055 - )<=ROW_TOLERANCE 1056 - ){ 420 + if(Math.abs(groups[i].top-entry.rect.top)<=ROW_TOLERANCE){ 1057 1057 group=groups[i]; 1058 1058 break; 1059 1059 } 1060 1060 } 1061 - 1062 1062 if(!group){ 1063 - group={ 1064 - top:top, 1065 - cards:[] 1066 - }; 426 + group={top:entry.rect.top,entries:[]}; 1067 1067 groups.push(group); 1068 1068 } 1069 - 1070 - group.cards.push(card); 429 + group.entries.push(entry); 1071 1071 }); 431 + return groups; 432 + } 1072 1072 1073 - groups.forEach(function(group){ 1074 - if(group.cards.length<2){ 1075 - return; 1076 - } 434 + function run(){ 435 + reset(); 1077 1077 1078 - var firstHeaders= 1079 - group.cards.map(function(card){ 1080 - var candidates= 1081 - headers 1082 - .filter(function(row){ 1083 - return row.card===card; 1084 - }) 1085 - .sort(function(a,b){ 1086 - return ( 1087 - a.el 1088 - .getBoundingClientRect() 1089 - .top- 1090 - b.el 1091 - .getBoundingClientRect() 1092 - .top 1093 - ); 1094 - }); 437 + if(window.innerWidth<=MOBILE_MAX)return; 1095 1095 1096 - return candidates.length 1097 - ?candidates[0] 1098 - :null; 1099 - }); 439 + var parents=Array.from(root.querySelectorAll("*")).filter(function(el){ 440 + return el.children&&el.children.length>=2&&horizontalLayout(el); 441 + }); 1100 1100 1101 - if( 1102 - !firstHeaders.some(function(row){ 1103 - return !row; 1104 - }) 1105 - ){ 1106 - var targetTop= 1107 - Math.max.apply( 1108 - Math, 1109 - firstHeaders.map(function(row){ 1110 - return ( 1111 - row.el 1112 - .getBoundingClientRect() 1113 - .top- 1114 - row.card 1115 - .getBoundingClientRect() 1116 - .top 1117 - ); 1118 - }) 1119 - ); 443 + parents.forEach(function(parent){ 444 + var entries=[]; 1120 1120 1121 - firstHeaders.forEach(function(row){ 1122 - var relativeTop= 1123 - row.el 1124 - .getBoundingClientRect() 1125 - .top- 1126 - row.card 1127 - .getBoundingClientRect() 1128 - .top; 1129 - 1130 - var delta= 1131 - targetTop-relativeTop; 1132 - 1133 - if(delta>1){ 1134 - saveStyle( 1135 - row.el, 1136 - originalMargin, 1137 - "margin-top" 1138 - ); 1139 - 1140 - var current= 1141 - num( 1142 - getComputedStyle( 1143 - row.el 1144 - ).marginTop 1145 - ); 1146 - 1147 - row.el.style.setProperty( 1148 - "margin-top", 1149 - ( 1150 - current+delta 1151 - )+"px" 1152 - ); 1153 - 1154 - row.el.setAttribute( 1155 - "data-sn-master-first-row", 1156 - "1" 1157 - ); 1158 - 1159 - managedMargin.add( 1160 - row.el 1161 - ); 1162 - } 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() 1163 1163 }); 1164 - } 1165 - 1166 - var maxHeight=0; 1167 - 1168 - group.cards.forEach(function(card){ 1169 - maxHeight= 1170 - Math.max( 1171 - maxHeight, 1172 - card 1173 - .getBoundingClientRect() 1174 - .height 1175 - ); 1176 1176 }); 1177 1177 1178 - maxHeight= 1179 - Math.ceil(maxHeight); 456 + if(entries.length<2)return; 1180 1180 1181 - group.cards.forEach(function(card){ 1182 - saveStyle( 1183 - card, 1184 - originalHeight, 1185 - "min-height" 1186 - ); 458 + rowGroups(entries).forEach(function(group){ 459 + if(group.entries.length<2)return; 1187 1187 1188 - card.style.setProperty( 1189 - "min-height", 1190 - maxHeight+"px" 1191 - ); 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; 1192 1192 1193 - card.setAttribute( 1194 - "data-sn-master-equal-height", 1195 - "1" 1196 - ); 464 + var targets=[]; 465 + var seen=new Set(); 1197 1197 1198 - managedHeight.add( 1199 - card 1200 - ); 1201 - }); 1202 - }); 1203 - } 1204 - 1205 - /* ======================================================= 1206 - DETAIL GRID EQUAL HEIGHT, DESKTOP ONLY 1207 - ======================================================= */ 1208 - 1209 - function equaliseDetailGrids(){ 1210 - if( 1211 - PAGE_KIND!=="detail"|| 1212 - window.innerWidth<=MOBILE_MAX 1213 - ){ 1214 - return; 1215 - } 1216 - 1217 - var selectors=[ 1218 - ".arsn-grid", 1219 - ".arsn-grid-2", 1220 - ".arsn-grid-3", 1221 - ".dmp-grid", 1222 - ".ido-grid", 1223 - ".pp-grid" 1224 - ]; 1225 - 1226 - selectors.forEach(function(selector){ 1227 - Array.from( 1228 - root.querySelectorAll(selector) 1229 - ).forEach(function(grid){ 1230 - var children= 1231 - Array.from( 1232 - grid.children||[] 1233 - ).filter(visible); 1234 - 1235 - if(children.length<2){ 1236 - return; 1237 - } 1238 - 1239 - var groups=[]; 1240 - 1241 - children.forEach(function(child){ 1242 - var top= 1243 - child 1244 - .getBoundingClientRect() 1245 - .top; 1246 - 1247 - var group=null; 1248 - 1249 - for(var i=0;i<groups.length;i++){ 1250 - if( 1251 - Math.abs( 1252 - groups[i].top-top 1253 - )<=ROW_TOLERANCE 1254 - ){ 1255 - group=groups[i]; 1256 - break; 1257 - } 467 + group.entries.forEach(function(e){ 468 + if(!seen.has(e.target)){ 469 + seen.add(e.target); 470 + targets.push(e.target); 1258 1258 } 472 + }); 1259 1259 1260 - if(!group){ 1261 - group={ 1262 - top:top, 1263 - items:[] 1264 - }; 1265 - groups.push(group); 1266 - } 474 + if(targets.length<2)return; 1267 1267 1268 - group.items.push(child); 476 + var max=0; 477 + targets.forEach(function(el){ 478 + max=Math.max(max,el.getBoundingClientRect().height); 1269 1269 }); 1270 1270 1271 - groups.forEach(function(group){ 1272 - if(group.items.length<2){ 1273 - return; 1274 - } 481 + max=Math.ceil(max); 482 + if(max<MIN_H)return; 1275 1275 1276 - var maxHeight=0; 1277 - 1278 - group.items.forEach(function(item){ 1279 - maxHeight= 1280 - Math.max( 1281 - maxHeight, 1282 - item 1283 - .getBoundingClientRect() 1284 - .height 1285 - ); 1286 - }); 1287 - 1288 - maxHeight= 1289 - Math.ceil(maxHeight); 1290 - 1291 - group.items.forEach(function(item){ 1292 - saveStyle( 1293 - item, 1294 - originalHeight, 1295 - "min-height" 1296 - ); 1297 - 1298 - item.style.setProperty( 1299 - "min-height", 1300 - maxHeight+"px" 1301 - ); 1302 - 1303 - item.setAttribute( 1304 - "data-sn-master-equal-height", 1305 - "1" 1306 - ); 1307 - 1308 - managedHeight.add(item); 1309 - }); 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); 1310 1310 }); 1311 1311 }); 1312 1312 }); 1313 1313 } 1314 1314 1315 - /* ======================================================= 1316 - RUN / RESPONSIVE SCHEDULING 1317 - ======================================================= */ 1318 - 1319 - function run(){ 1320 - if(running)return; 1321 - 1322 - running=true; 1323 - 1324 - try{ 1325 - resetRuntime(); 1326 - applyPlaceholderBadge(); 1327 - propagateDetailAccents(); 1328 - 1329 - var headers= 1330 - applyOverviewPalette(); 1331 - 1332 - if( 1333 - window.innerWidth> 1334 - MOBILE_MAX 1335 - ){ 1336 - alignOverviewCards( 1337 - headers 1338 - ); 1339 - 1340 - equaliseDetailGrids(); 1341 - } 1342 - }finally{ 1343 - running=false; 1344 - } 493 + function schedule(){ 494 + if(raf)cancelAnimationFrame(raf); 495 + raf=requestAnimationFrame(function(){ 496 + raf=requestAnimationFrame(function(){ 497 + raf=0; 498 + run(); 499 + }); 500 + }); 1345 1345 } 1346 1346 1347 - function onResize(){ 1348 - if(resizeTimer){ 1349 - clearTimeout( 1350 - resizeTimer 1351 - ); 1352 - } 503 + addEventListener("resize",schedule,{passive:true}); 504 + addEventListener("load",schedule,{once:true}); 1353 1353 1354 - resizeTimer= 1355 - setTimeout( 1356 - function(){ 1357 - resizeTimer=0; 1358 - run(); 1359 - }, 1360 - RESIZE_DEBOUNCE 1361 - ); 1362 - } 506 + root.addEventListener("click",function(){ 507 + setTimeout(schedule,0); 508 + },true); 1363 1363 1364 - async function waitForReady(){ 1365 - if( 1366 - document.readyState!=="complete" 1367 - ){ 1368 - await new Promise(function(resolve){ 1369 - window.addEventListener( 1370 - "load", 1371 - resolve, 1372 - {once:true} 1373 - ); 1374 - }); 1375 - } 1376 - 1377 - if( 1378 - document.fonts&& 1379 - document.fonts.ready 1380 - ){ 1381 - try{ 1382 - await document.fonts.ready; 1383 - }catch(error){} 1384 - } 1385 - 1386 - var images= 1387 - Array.from( 1388 - root.querySelectorAll("img") 1389 - ); 1390 - 1391 - await Promise.all( 1392 - images.map(function(img){ 1393 - if(img.complete){ 1394 - return Promise.resolve(); 1395 - } 1396 - 1397 - return new Promise(function(resolve){ 1398 - var done=function(){ 1399 - resolve(); 1400 - }; 1401 - 1402 - img.addEventListener( 1403 - "load", 1404 - done, 1405 - {once:true} 1406 - ); 1407 - 1408 - img.addEventListener( 1409 - "error", 1410 - done, 1411 - {once:true} 1412 - ); 1413 - }); 1414 - }) 1415 - ); 1416 - 1417 - run(); 510 + if(document.fonts&&document.fonts.ready){ 511 + document.fonts.ready.then(schedule); 1418 1418 } 1419 1419 1420 - window.addEventListener( 1421 - "resize", 1422 - onResize, 1423 - {passive:true} 1424 - ); 1425 - 1426 - waitForReady(); 514 + schedule(); 515 + setTimeout(schedule,250); 516 + setTimeout(schedule,900); 1427 1427 })(); 1428 1428 </script> 1429 - 1430 -<!-- SN_SERVICE_NAVIGATOR_MASTER_STYLE_END --> 519 +<!-- SN_HORIZONTAL_BOX_HARMONIZER_END --> 1431 1431 {{/html}} 1432 1432