Änderungen von Dokument Art & Research Services Navigator
Zuletzt geändert von Veronika Kocher am Freitag, 18 Sep. 2026 16:47
Von Version 9.5
bearbeitet von Veronika Kocher
am Donnerstag, 03 Sep. 2026 13:04
am Donnerstag, 03 Sep. 2026 13:04
Änderungskommentar:
Es gibt keinen Kommentar für diese Version
Auf Version 9.4
bearbeitet von Veronika Kocher
am Donnerstag, 03 Sep. 2026 10:09
am Donnerstag, 03 Sep. 2026 10:09
Änderungskommentar:
Es gibt keinen Kommentar für diese Version
Zusammenfassung
-
Seiteneigenschaften (1 geändert, 0 hinzugefügt, 0 gelöscht)
Details
- Seiteneigenschaften
-
- Inhalt
-
... ... @@ -635,13 +635,12 @@ 635 635 {{/info}} 636 636 ))) 637 637 638 -{{html clean="false"}} 639 -<!-- SN_SERVICE_NAVIGATOR_MASTER_STYLE_START --> 638 +\n\n 639 +\n\n{{html clean="false"}} 640 +<!-- SN_HORIZONTAL_BOX_HARMONIZER_START --> 640 640 641 -<style data-sn-service-navigator-master="1"> 642 -/* ========================================================= 643 - MASTER TYPOGRAPHY 644 - ========================================================= */ 642 +<style data-sn-horizontal-box-harmonizer="7"> 643 +/* ---------- Typography: never justify headings ---------- */ 645 645 #xwikicontent h1, 646 646 #xwikicontent h2, 647 647 #xwikicontent h3, ... ... @@ -663,73 +663,88 @@ 663 663 word-spacing:normal!important; 664 664 } 665 665 666 -/* ========================================================= 667 - COMING SOON / IN VORBEREITUNG 668 - ========================================================= */ 669 -.sn-coming-soon-badge{ 670 - display:inline-block; 671 - vertical-align:middle; 672 - margin-left:10px; 673 - padding:4px 8px; 674 - border-radius:14px; 675 - border:1px solid #efd9cc; 676 - background:#fff4ee; 677 - color:#8a4d36; 678 - font-size:11px; 679 - font-weight:700; 680 - letter-spacing:.055em; 681 - line-height:1.2; 682 - white-space:nowrap; 683 -} 684 - 685 -/* ========================================================= 686 - NATIVE / DETAIL CALLOUT GEOMETRY 687 - Preserve existing backgrounds. 688 - ========================================================= */ 689 -#xwikicontent .arsn-info, 690 -#xwikicontent .dmp-info, 691 -#xwikicontent .ido-info, 692 -#xwikicontent .pp-info, 693 -#xwikicontent .infomessage{ 665 +/* ---------- Native XWiki semantic callouts ---------- */ 666 +#xwikicontent .box.infomessage, 667 +#xwikicontent .infomessage, 668 +#xwikicontent .box.warningmessage, 669 +#xwikicontent .warningmessage, 670 +#xwikicontent .box.successmessage, 671 +#xwikicontent .successmessage, 672 +#xwikicontent .box.errormessage, 673 +#xwikicontent .errormessage, 674 +#xwikicontent [data-sn-callout-harmonized="1"]{ 694 694 box-sizing:border-box!important; 695 - border-left:4px solid #21b6d7!important; 696 - border-radius:8px; 676 + border-radius:8px!important; 677 + border-top:1px solid rgba(0,0,0,.08)!important; 678 + border-right:1px solid rgba(0,0,0,.08)!important; 679 + border-bottom:1px solid rgba(0,0,0,.08)!important; 680 + border-left:4px solid var(--sn-callout-accent,#21b6d7)!important; 681 + padding:14px 16px!important; 697 697 text-align:left!important; 683 + text-justify:auto!important; 698 698 word-spacing:normal!important; 685 + box-shadow:none!important; 699 699 } 700 700 701 -#xwikicontent .arsn-warn, 702 -#xwikicontent .dmp-warn, 703 -#xwikicontent .ido-warn, 704 -#xwikicontent .pp-warn, 705 -#xwikicontent .warn, 706 -#xwikicontent .warning, 707 -#xwikicontent .warningmessage, 688 +#xwikicontent .box.infomessage, 689 +#xwikicontent .infomessage{ 690 + --sn-callout-accent:#21b6d7; 691 + background:#eaf7fb!important; 692 +} 693 + 694 +#xwikicontent .box.warningmessage, 695 +#xwikicontent .warningmessage{ 696 + --sn-callout-accent:#f0aa00; 697 + background:#fff8e7!important; 698 +} 699 + 700 +#xwikicontent .box.successmessage, 701 +#xwikicontent .successmessage{ 702 + --sn-callout-accent:#38b76a; 703 + background:#edf9f1!important; 704 +} 705 + 706 +#xwikicontent .box.errormessage, 708 708 #xwikicontent .errormessage{ 709 - box-sizing:border-box!important; 710 - border-left:4px solid #e94b13!important; 711 - border-radius:8px; 712 - text-align:left!important; 713 - word-spacing:normal!important; 708 + --sn-callout-accent:#e94b13; 709 + background:#fff1ec!important; 714 714 } 715 715 716 -[data-sn-master-equal-height], 717 -[data-sn-master-first-row]{ 712 +#xwikicontent [data-sn-callout-harmonized="1"] > :first-child, 713 +#xwikicontent .infomessage > :first-child, 714 +#xwikicontent .warningmessage > :first-child, 715 +#xwikicontent .successmessage > :first-child, 716 +#xwikicontent .errormessage > :first-child{ 717 + margin-top:0!important; 718 +} 719 + 720 +#xwikicontent [data-sn-callout-harmonized="1"] > :last-child, 721 +#xwikicontent .infomessage > :last-child, 722 +#xwikicontent .warningmessage > :last-child, 723 +#xwikicontent .successmessage > :last-child, 724 +#xwikicontent .errormessage > :last-child{ 725 + margin-bottom:0!important; 726 +} 727 + 728 +#xwikicontent [data-sn-equal-height-managed], 729 +#xwikicontent [data-sn-first-section-aligned], 730 +#xwikicontent [data-sn-first-content-aligned]{ 718 718 box-sizing:border-box; 719 719 } 720 720 </style> 721 721 722 -<script data-sn- service-navigator-master="1">735 +<script data-sn-horizontal-box-harmonizer="7"> 723 723 (function(){ 724 724 "use strict"; 725 725 726 - var PAGE_KIND="overview"; 727 - var PLACEHOLDER=false; 728 - var PLACEHOLDER_LABEL="IN VORBEREITUNG"; 729 - 730 730 var MOBILE_MAX=767; 731 731 var ROW_TOLERANCE=6; 741 + var MIN_W=150; 742 + var MIN_H=36; 743 + var MAX_PARENT_CHILDREN=18; 744 + var SEARCH_DEPTH=5; 732 732 var RESIZE_DEBOUNCE=220; 746 + var MIN_WIDTH_CHANGE=2; 733 733 734 734 var root= 735 735 document.getElementById("xwikicontent")|| ... ... @@ -739,114 +739,142 @@ 739 739 740 740 if(!root)return; 741 741 742 - var managedHeight=new Set(); 743 - var managedMargin=new Set(); 744 - var originalHeight=new WeakMap(); 745 - var originalMargin=new WeakMap(); 756 + var heightManaged=new Set(); 757 + var sectionManaged=new Set(); 758 + var contentManaged=new Set(); 746 746 760 + var originalMinHeight=new WeakMap(); 761 + var originalMarginTop=new WeakMap(); 762 + 747 747 var resizeTimer=0; 748 - var running=false; 764 + var lastWidth=-1; 765 + var hasApplied=false; 766 + var applying=false; 749 749 750 - var THEMES=[ 751 - { 752 - name:"BLUE", 753 - accent:"#21b6d7", 754 - bg:"#eaf7fb", 755 - text:"#315d68", 756 - labels:[ 757 - "HIER STARTEN", 758 - "ENTSCHEIDEN", 759 - "ÜBERPRÜFEN & ANPASSEN", 760 - "START HERE", 761 - "DECIDE", 762 - "REVIEW & ADAPT" 763 - ] 764 - }, 765 - { 766 - name:"RED", 767 - accent:"#e94b13", 768 - bg:"#fff1ec", 769 - text:"#8a4d36", 770 - labels:[ 771 - "PLANEN & ORGANISIEREN", 772 - "ORGANISIEREN & DOKUMENTIEREN", 773 - "PUBLIZIEREN & PRÄSENTIEREN", 774 - "PLAN & ORGANISE", 775 - "PLAN & ORGANIZE", 776 - "ORGANISE & DOCUMENT", 777 - "ORGANIZE & DOCUMENT", 778 - "PUBLISH & PRESENT" 779 - ] 780 - }, 781 - { 782 - name:"YELLOW", 783 - accent:"#f0aa00", 784 - bg:"#fff8e7", 785 - text:"#785b17", 786 - labels:[ 787 - "SCHÜTZEN & KLÄREN", 788 - "STANDARDISIEREN & IDENTIFIZIEREN", 789 - "ÖFFNEN, NACHNUTZEN & AUFFINDBAR MACHEN", 790 - "PROTECT & CLARIFY", 791 - "STANDARDISE & IDENTIFY", 792 - "STANDARDIZE & IDENTIFY", 793 - "OPEN, REUSE & MAKE FINDABLE" 794 - ] 795 - }, 796 - { 797 - name:"GREEN", 798 - accent:"#38b76a", 799 - bg:"#edf9f1", 800 - text:"#3f7451", 801 - labels:[ 802 - "INFRASTRUKTUR EINRICHTEN", 803 - "INFRASTRUKTUR & ZUSAMMENARBEIT EINRICHTEN", 804 - "SPEICHERN & ZUGRIFF STEUERN", 805 - "REPOSITORIUM, ERHALTEN & ÜBERGEBEN", 806 - "SET UP INFRASTRUCTURE", 807 - "SET UP INFRASTRUCTURE & COLLABORATION", 808 - "STORE & CONTROL ACCESS", 809 - "REPOSITORY, PRESERVE & HAND OVER" 810 - ] 768 + function num(v){ 769 + var n=parseFloat(v); 770 + return Number.isFinite(n)?n:0; 771 + } 772 + 773 + function visible(el,minW,minH){ 774 + if(!el||el.nodeType!==1)return false; 775 + 776 + var s=getComputedStyle(el); 777 + 778 + if( 779 + s.display==="none"|| 780 + s.visibility==="hidden"|| 781 + Number(s.opacity)===0 782 + ){ 783 + return false; 811 811 } 812 - ]; 813 813 814 - function num(value){ 815 - var n=parseFloat(value); 816 - return Number.isFinite(n)?n:0; 786 + var r=el.getBoundingClientRect(); 787 + 788 + return ( 789 + r.width>=(minW||1)&& 790 + r.height>=(minH||1) 791 + ); 817 817 } 818 818 819 - function norm (value){820 - return String( value||"")794 + function normalizeText(text){ 795 + return String(text||"") 821 821 .replace(/\s+/g," ") 822 822 .trim() 823 823 .toUpperCase(); 824 824 } 825 825 826 - function visible(el){ 827 - if(!el||el.nodeType!==1)return false; 801 + function excluded(el){ 802 + return ( 803 + !el.matches|| 804 + el.matches( 805 + "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]" 806 + ) 807 + ); 808 + } 828 828 829 - var style=getComputedStyle(el); 830 - var rect=el.getBoundingClientRect(); 810 + /* ---------- Custom coloured callouts ---------- */ 831 831 812 + function nativeCallout(el){ 813 + var c= 814 + typeof el.className==="string" 815 + ? el.className.toLowerCase() 816 + : ""; 817 + 832 832 return ( 833 - style.display!=="none"&& 834 - style.visibility!=="hidden"&& 835 - rect.width>20&& 836 - rect.height>4 819 + /(^|\s)(infomessage|warningmessage|successmessage|errormessage)(\s|$)/.test(c) 837 837 ); 838 838 } 839 839 840 - function saveStyle(el,map,property){ 823 + function customCallout(el){ 824 + if(!visible(el,220,42)||excluded(el))return false; 825 + 826 + var r=el.getBoundingClientRect(); 827 + 828 + if(r.height>520)return false; 829 + 830 + var s=getComputedStyle(el); 831 + 832 + var bg= 833 + s.backgroundColor&& 834 + s.backgroundColor!=="rgba(0, 0, 0, 0)"&& 835 + s.backgroundColor!=="transparent"&& 836 + s.backgroundColor!=="rgb(255, 255, 255)"; 837 + 838 + var left= 839 + num(s.borderLeftWidth); 840 + 841 + return ( 842 + bg&& 843 + left>=2 844 + ); 845 + } 846 + 847 + function harmoniseCustomCallouts(){ 848 + Array.from( 849 + root.querySelectorAll( 850 + "div,aside,section" 851 + ) 852 + ).forEach(function(el){ 853 + if(nativeCallout(el))return; 854 + if(!customCallout(el))return; 855 + 856 + var s=getComputedStyle(el); 857 + 858 + el.setAttribute( 859 + "data-sn-callout-harmonized", 860 + "1" 861 + ); 862 + 863 + if( 864 + s.borderLeftColor 865 + ){ 866 + el.style.setProperty( 867 + "--sn-callout-accent", 868 + s.borderLeftColor 869 + ); 870 + } 871 + }); 872 + } 873 + 874 + /* ---------- Restore only values V7 itself changed ---------- */ 875 + 876 + function saveOriginal(el,map,property){ 841 841 if(map.has(el))return; 842 842 843 843 map.set(el,{ 844 - value:el.style.getPropertyValue(property), 845 - priority:el.style.getPropertyPriority(property) 880 + value: 881 + el.style.getPropertyValue( 882 + property 883 + ), 884 + priority: 885 + el.style.getPropertyPriority( 886 + property 887 + ) 846 846 }); 847 847 } 848 848 849 - function restore Style(el,map,property){891 + function restoreOriginal(el,map,property){ 850 850 var original=map.get(el); 851 851 852 852 if(original&&original.value){ ... ... @@ -856,845 +856,770 @@ 856 856 original.priority||"" 857 857 ); 858 858 }else{ 859 - el.style.removeProperty(property); 901 + el.style.removeProperty( 902 + property 903 + ); 860 860 } 861 861 } 862 862 863 863 function resetRuntime(){ 864 - managedHeight.forEach(function(el){865 - restore Style(908 + heightManaged.forEach(function(el){ 909 + restoreOriginal( 866 866 el, 867 - originalHeight, 911 + originalMinHeight, 868 868 "min-height" 869 869 ); 914 + 870 870 el.removeAttribute( 871 - "data-sn- master-equal-height"916 + "data-sn-equal-height-managed" 872 872 ); 873 873 }); 874 874 875 - managedMargin.forEach(function(el){876 - restore Style(920 + sectionManaged.forEach(function(el){ 921 + restoreOriginal( 877 877 el, 878 - originalMargin, 923 + originalMarginTop, 879 879 "margin-top" 880 880 ); 926 + 881 881 el.removeAttribute( 882 - "data-sn- master-first-row"928 + "data-sn-first-section-aligned" 883 883 ); 884 884 }); 885 885 886 - managedHeight.clear(); 887 - managedMargin.clear(); 888 - } 932 + contentManaged.forEach(function(el){ 933 + restoreOriginal( 934 + el, 935 + originalMarginTop, 936 + "margin-top" 937 + ); 889 889 890 - function themeFor(text){ 891 - var value=norm(text); 939 + el.removeAttribute( 940 + "data-sn-first-content-aligned" 941 + ); 942 + }); 892 892 893 - for(var i=0;i<THEMES.length;i++){ 894 - for(var j=0;j<THEMES[i].labels.length;j++){ 895 - var label=THEMES[i].labels[j]; 896 - 897 - if( 898 - value===label|| 899 - value.indexOf(label+" ")===0|| 900 - value.indexOf(label+" -")===0|| 901 - value.indexOf(label+" ·")===0 902 - ){ 903 - return THEMES[i]; 904 - } 905 - } 906 - } 907 - 908 - return null; 944 + heightManaged.clear(); 945 + sectionManaged.clear(); 946 + contentManaged.clear(); 909 909 } 910 910 911 - /* ======================================================= 912 - PLACEHOLDER BADGE 913 - ======================================================= */ 949 + /* ---------- Card detection ---------- */ 914 914 915 - function applyPlaceholderBadge(){ 916 - if(!PLACEHOLDER)return; 951 + function namedLikeBox(el){ 952 + var c= 953 + typeof el.className==="string" 954 + ? el.className 955 + : ""; 917 917 957 + return /(^|[\s_-])(box|card|tile|panel|role|check|service|source|call|area|detail|resource|topic|warn|info)([\s_-]|$)/i.test(c); 958 + } 959 + 960 + function boxLike(el){ 918 918 if( 919 - document.querySelector( 920 - ".sn-coming-soon-badge" 921 - ) 962 + !visible(el,MIN_W,MIN_H)|| 963 + excluded(el) 922 922 ){ 923 - return; 965 + return false; 924 924 } 925 925 926 - var title= 927 - document.querySelector( 928 - "#document-title" 929 - )|| 930 - document.querySelector( 931 - "h1" 932 - ); 968 + var s=getComputedStyle(el); 969 + var r=el.getBoundingClientRect(); 933 933 934 - if(!title)return; 971 + var border= 972 + num(s.borderTopWidth)+ 973 + num(s.borderRightWidth)+ 974 + num(s.borderBottomWidth)+ 975 + num(s.borderLeftWidth); 935 935 936 - var badge= 937 - document.createElement( 938 - "span" 939 - ); 940 - 941 - badge.className= 942 - "sn-coming-soon-badge"; 943 - 944 - badge.textContent= 945 - PLACEHOLDER_LABEL; 946 - 947 - badge.setAttribute( 948 - "aria-label", 949 - PLACEHOLDER_LABEL 977 + var radius=Math.max( 978 + num(s.borderTopLeftRadius), 979 + num(s.borderTopRightRadius), 980 + num(s.borderBottomLeftRadius), 981 + num(s.borderBottomRightRadius) 950 950 ); 951 951 952 - title.appendChild(953 - ba dge954 - ) ;955 - }984 + var bg= 985 + s.backgroundColor&& 986 + s.backgroundColor!=="rgba(0, 0, 0, 0)"&& 987 + s.backgroundColor!=="transparent"; 956 956 957 - /*=======================================================958 - DETAILPAGE OWN-ACCENT PROPAGATION959 - == ===================================================== */989 + var shadow= 990 + s.boxShadow&& 991 + s.boxShadow!=="none"; 960 960 961 - function parseRGB(value){ 962 - var match=String(value||"").match( 963 - /rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)/i 993 + return ( 994 + namedLikeBox(el)|| 995 + border>=1|| 996 + (bg&&radius>=3)|| 997 + (shadow&&r.width>=180) 964 964 ); 965 - 966 - if(!match)return null; 967 - 968 - return [ 969 - Number(match[1]), 970 - Number(match[2]), 971 - Number(match[3]) 972 - ]; 973 973 } 974 974 975 - function distance(a,b){ 976 - return Math.sqrt( 977 - Math.pow(a[0]-b[0],2)+ 978 - Math.pow(a[1]-b[1],2)+ 979 - Math.pow(a[2]-b[2],2) 980 - ); 981 - } 1001 + function pickTarget(child){ 1002 + if(!visible(child,MIN_W,MIN_H))return null; 982 982 983 - function paletteMatch(cssColor){ 984 - var rgb=parseRGB(cssColor); 1004 + if(boxLike(child))return child; 985 985 986 - if(!rgb)return null; 1006 + var cr=child.getBoundingClientRect(); 1007 + var q=[]; 987 987 988 - var palette=[ 989 - {hex:"#21b6d7",rgb:[33,182,215]}, 990 - {hex:"#e94b13",rgb:[233,75,19]}, 991 - {hex:"#f0aa00",rgb:[240,170,0]}, 992 - {hex:"#38b76a",rgb:[56,183,106]} 993 - ]; 1009 + Array.from(child.children||[]).forEach(function(el){ 1010 + q.push({el:el,depth:1}); 1011 + }); 994 994 995 995 var best=null; 996 - var best Distance=Infinity;1014 + var bestScore=-Infinity; 997 997 998 - palette.forEach(function(item){ 999 - var d=distance(rgb,item.rgb); 1016 + while(q.length){ 1017 + var item=q.shift(); 1018 + var el=item.el; 1000 1000 1001 - if(d<bestDistance){ 1002 - best=item; 1003 - bestDistance=d; 1004 - } 1005 - }); 1020 + if(!visible(el,MIN_W,MIN_H))continue; 1006 1006 1007 - return bestDistance<=30 1008 - ?best 1009 - :null; 1010 - } 1022 + var r=el.getBoundingClientRect(); 1011 1011 1012 - function propagateDetailAccents(){ 1013 - if(PAGE_KIND!=="detail")return; 1014 - 1015 - Array.from( 1016 - root.querySelectorAll( 1017 - ".arsn-call,.dmp-call,.ido-call,.pp-call,"+ 1018 - ".arsn-source,.dmp-source,.ido-source,.pp-source" 1019 - ) 1020 - ).forEach(function(el){ 1021 - if(!visible(el))return; 1022 - 1023 - var style=getComputedStyle(el); 1024 - 1025 1025 if( 1026 - num(style.borderTopWidth)>=2 1025 + r.width>=cr.width*.68&& 1026 + boxLike(el) 1027 1027 ){ 1028 - var match= 1029 - paletteMatch( 1030 - style.borderTopColor 1028 + var widthFit= 1029 + 1-Math.min( 1030 + 1, 1031 + Math.abs(cr.width-r.width)/ 1032 + Math.max(1,cr.width) 1031 1031 ); 1032 1032 1033 - if(match){ 1034 - el.style.setProperty( 1035 - "border-left", 1036 - "4px solid "+match.hex, 1037 - "important" 1035 + var topFit= 1036 + 1-Math.min( 1037 + 1, 1038 + Math.abs(cr.top-r.top)/100 1038 1038 ); 1040 + 1041 + var score= 1042 + widthFit*6+ 1043 + topFit*3+ 1044 + Math.min(r.height,900)/450+ 1045 + Math.min(r.width*r.height,900000)/900000; 1046 + 1047 + if(score>bestScore){ 1048 + best=el; 1049 + bestScore=score; 1039 1039 } 1040 1040 } 1041 - }); 1042 1042 1043 - // Warning families: explicit safety override. 1044 - Array.from( 1045 - root.querySelectorAll( 1046 - ".arsn-warn,.dmp-warn,.ido-warn,.pp-warn,"+ 1047 - ".warn,.warning,.warningmessage,.errormessage" 1048 - ) 1049 - ).forEach(function(el){ 1050 - if(!visible(el))return; 1053 + if(item.depth<SEARCH_DEPTH){ 1054 + Array.from(el.children||[]).forEach(function(next){ 1055 + q.push({ 1056 + el:next, 1057 + depth:item.depth+1 1058 + }); 1059 + }); 1060 + } 1061 + } 1051 1051 1052 - el.style.setProperty( 1053 - "border-left", 1054 - "4px solid #e94b13", 1055 - "important" 1056 - ); 1057 - }); 1063 + return best; 1064 + } 1058 1058 1059 - // Info families: explicit orientation override. 1060 - Array.from( 1061 - root.querySelectorAll( 1062 - ".arsn-info,.dmp-info,.ido-info,.pp-info,.infomessage" 1063 - ) 1064 - ).forEach(function(el){ 1065 - if(!visible(el))return; 1066 + function groupRows(entries){ 1067 + var groups=[]; 1066 1066 1067 - el.style.setProperty( 1068 - "border-left", 1069 - "4px solid #21b6d7", 1070 - "important" 1071 - ); 1072 - }); 1073 - } 1069 + entries 1070 + .slice() 1071 + .sort(function(a,b){ 1072 + return ( 1073 + a.rect.top-b.rect.top|| 1074 + a.rect.left-b.rect.left 1075 + ); 1076 + }) 1077 + .forEach(function(entry){ 1078 + var group=null; 1074 1074 1075 - /* ======================================================= 1076 - OVERVIEW SEMANTIC THEME PALETTE 1077 - ======================================================= */ 1080 + for(var i=0;i<groups.length;i++){ 1081 + if( 1082 + Math.abs( 1083 + groups[i].top- 1084 + entry.rect.top 1085 + )<=ROW_TOLERANCE 1086 + ){ 1087 + group=groups[i]; 1088 + break; 1089 + } 1090 + } 1078 1078 1079 - function smallestThemeHeaders(){ 1080 - return Array.from( 1081 - root.querySelectorAll( 1082 - "div,span,p,strong,h3,h4,h5,h6" 1083 - ) 1084 - ).filter(function(el){ 1085 - if(!visible(el))return false; 1086 - if(!themeFor(el.textContent))return false; 1092 + if(!group){ 1093 + group={ 1094 + top:entry.rect.top, 1095 + entries:[] 1096 + }; 1097 + groups.push(group); 1098 + } 1087 1087 1088 - return !Array.from( 1089 - el.children||[] 1090 - ).some(function(child){ 1091 - return !!themeFor( 1092 - child.textContent 1093 - ); 1100 + group.entries.push(entry); 1094 1094 }); 1095 - }); 1102 + 1103 + return groups; 1096 1096 } 1097 1097 1098 - function findOverviewCard(header){ 1099 - var node=header.parentElement; 1100 - var candidates=[]; 1106 + function validRow(group){ 1107 + if(group.entries.length<2)return false; 1101 1101 1102 - while(node&&node!==root){ 1103 - var rect=node.getBoundingClientRect(); 1104 - var style=getComputedStyle(node); 1109 + var lefts= 1110 + group.entries 1111 + .map(function(e){return e.rect.left;}) 1112 + .sort(function(a,b){return a-b;}); 1105 1105 1106 - var border= 1107 - num(style.borderTopWidth)+ 1108 - num(style.borderRightWidth)+ 1109 - num(style.borderBottomWidth)+ 1110 - num(style.borderLeftWidth); 1114 + if( 1115 + lefts[lefts.length-1]- 1116 + lefts[0]< 1117 + 80 1118 + ){ 1119 + return false; 1120 + } 1111 1111 1112 - if( 1113 - rect.width>=220&& 1114 - rect.width<=800&& 1115 - rect.height>=120&& 1116 - border>=1 1117 - ){ 1118 - candidates.push(node); 1119 - } 1122 + var widths= 1123 + group.entries 1124 + .map(function(e){return e.rect.width;}) 1125 + .filter(function(w){return w>0;}); 1120 1120 1121 - node=node.parentElement; 1122 - } 1127 + if(widths.length<2)return false; 1123 1123 1124 - if(!candidates.length)return null; 1129 + var minW= 1130 + Math.min.apply(Math,widths); 1125 1125 1126 - candidates.sort(function(a,b){ 1127 - return ( 1128 - b.getBoundingClientRect().height- 1129 - a.getBoundingClientRect().height 1132 + var maxW= 1133 + Math.max.apply(Math,widths); 1134 + 1135 + return ( 1136 + maxW/ 1137 + Math.max(1,minW)<= 1138 + 1.9 1139 + ); 1140 + } 1141 + 1142 + /* ---------- Known ARSN first section bars ---------- */ 1143 + 1144 + function knownBar(el){ 1145 + var text= 1146 + normalizeText( 1147 + el.textContent 1130 1130 ); 1131 - }); 1132 1132 1133 - return candidates[0]; 1150 + return ( 1151 + text==="HIER STARTEN"|| 1152 + text==="ORGANISIEREN & DOKUMENTIEREN"|| 1153 + text==="ENTSCHEIDEN"|| 1154 + text==="START HERE"|| 1155 + text==="GET STARTED"|| 1156 + text==="ORGANISE & DOCUMENT"|| 1157 + text==="ORGANIZE & DOCUMENT"|| 1158 + text==="DECIDE" 1159 + ); 1134 1134 } 1135 1135 1136 - function rowCandidates(link,card){ 1137 - var result=[]; 1162 + function findKnownBar(card){ 1138 1138 var cardRect= 1139 1139 card.getBoundingClientRect(); 1140 1140 1141 - var node=link; 1166 + var rows= 1167 + Array.from( 1168 + card.querySelectorAll( 1169 + "div,p,span,strong,h3,h4,h5,h6" 1170 + ) 1171 + ) 1172 + .filter(function(el){ 1173 + if(!visible(el,20,6))return false; 1174 + if(!knownBar(el))return false; 1142 1142 1143 - while(node&&node!==card){ 1144 - if(visible(node)){ 1145 - var rect= 1146 - node.getBoundingClientRect(); 1176 + var r=el.getBoundingClientRect(); 1147 1147 1148 - if( 1149 - rect.height<=105&& 1150 - rect.width>= 1151 - cardRect.width*.50&& 1152 - rect.width<= 1153 - cardRect.width*1.03 1154 - ){ 1155 - result.push(node); 1156 - } 1157 - } 1178 + var rel= 1179 + r.top- 1180 + cardRect.top; 1158 1158 1159 - node=node.parentElement; 1160 - } 1161 - 1162 - return result; 1163 - } 1164 - 1165 - function chooseOuterRow( 1166 - candidates, 1167 - link 1168 - ){ 1169 - if(!candidates.length){ 1170 - return link; 1171 - } 1172 - 1173 - var bordered= 1174 - candidates.filter(function(el){ 1175 1175 return ( 1176 - num( 1177 - getComputedStyle(el) 1178 - .borderLeftWidth 1179 - )>=1 1183 + rel>=35&& 1184 + rel<= 1185 + cardRect.height*.75 1180 1180 ); 1187 + }) 1188 + .sort(function(a,b){ 1189 + return ( 1190 + a.getBoundingClientRect().top- 1191 + b.getBoundingClientRect().top 1192 + ); 1181 1181 }); 1182 1182 1183 - var pool= 1184 - bordered.length 1185 - ?bordered 1186 - :candidates; 1195 + return rows[0]||null; 1196 + } 1187 1187 1188 - pool.sort(function(a,b){ 1189 - var ar= 1190 - a.getBoundingClientRect(); 1198 + function alignKnownBars(cards){ 1199 + var rows= 1200 + cards.map(function(card){ 1201 + var bar= 1202 + findKnownBar(card); 1191 1191 1192 - var br= 1193 - b.getBoundingClientRect(); 1204 + if(!bar)return null; 1194 1194 1195 - return ( 1196 - ar.left-br.left|| 1197 - br.width-ar.width 1198 - ); 1199 - }); 1206 + var cr= 1207 + card.getBoundingClientRect(); 1200 1200 1201 - r eturnpool[0]||link;1202 - }1209 + var br= 1210 + bar.getBoundingClientRect(); 1203 1203 1204 - function applyOverviewPalette(){ 1205 - if(PAGE_KIND!=="overview"){ 1206 - return []; 1212 + return { 1213 + bar:bar, 1214 + relativeTop: 1215 + br.top- 1216 + cr.top 1217 + }; 1218 + }); 1219 + 1220 + if( 1221 + rows.some(function(row){ 1222 + return !row; 1223 + }) 1224 + ){ 1225 + return false; 1207 1207 } 1208 1208 1209 - var headers= 1210 - smallestThemeHeaders() 1211 - .map(function(el){ 1212 - return { 1213 - el:el, 1214 - theme: 1215 - themeFor( 1216 - el.textContent 1217 - ), 1218 - card: 1219 - findOverviewCard( 1220 - el 1221 - ) 1222 - }; 1228 + var target= 1229 + Math.max.apply( 1230 + Math, 1231 + rows.map(function(row){ 1232 + return row.relativeTop; 1223 1223 }) 1224 - .filter(function(row){ 1225 - return !!row.card; 1226 - }); 1234 + ); 1227 1227 1228 - var unique=[]; 1229 - var seenHeaders=new Set(); 1236 + rows.forEach(function(row){ 1237 + var delta= 1238 + target- 1239 + row.relativeTop; 1230 1230 1231 - headers.forEach(function(row){ 1232 - var key= 1233 - row.theme.name+ 1234 - "|"+ 1235 - Math.round( 1236 - row.card 1237 - .getBoundingClientRect() 1238 - .left 1239 - )+ 1240 - "|"+ 1241 - Math.round( 1242 - row.el 1243 - .getBoundingClientRect() 1244 - .top 1245 - ); 1241 + if(delta<=1)return; 1246 1246 1247 - if(!seenHeaders.has(key)){1248 - seenHeaders.add(key);1249 - unique.push(row);1250 - }1251 - });1243 + saveOriginal( 1244 + row.bar, 1245 + originalMarginTop, 1246 + "margin-top" 1247 + ); 1252 1252 1253 - unique.forEach(function(row){ 1254 - var headerRect= 1255 - row.el 1256 - .getBoundingClientRect(); 1249 + var current= 1250 + num( 1251 + getComputedStyle( 1252 + row.bar 1253 + ).marginTop 1254 + ); 1257 1257 1258 - row.el.style.setProperty( 1259 - "background", 1260 - row.theme.bg, 1261 - "important" 1256 + row.bar.style.setProperty( 1257 + "margin-top", 1258 + ( 1259 + current+ 1260 + delta 1261 + )+"px" 1262 1262 ); 1263 1263 1264 - row.el.style.setProperty( 1265 - "color", 1266 - row.theme.text, 1267 - "important" 1264 + row.bar.setAttribute( 1265 + "data-sn-first-section-aligned", 1266 + "7" 1268 1268 ); 1269 1269 1270 - row.el.style.setProperty( 1271 - "text-align", 1272 - "left", 1273 - "important" 1269 + sectionManaged.add( 1270 + row.bar 1274 1274 ); 1272 + }); 1275 1275 1276 - row.el.style.setProperty( 1277 - "word-spacing", 1278 - "normal", 1279 - "important" 1280 - ); 1274 + return true; 1275 + } 1281 1281 1282 - var later= 1283 - unique 1284 - .filter(function(other){ 1285 - return ( 1286 - other.card===row.card&& 1287 - other.el 1288 - .getBoundingClientRect() 1289 - .top> 1290 - headerRect.top+2 1291 - ); 1292 - }) 1293 - .sort(function(a,b){ 1294 - return ( 1295 - a.el 1296 - .getBoundingClientRect() 1297 - .top- 1298 - b.el 1299 - .getBoundingClientRect() 1300 - .top 1301 - ); 1302 - }); 1277 + /* ---------- Generic first content after heading ---------- */ 1303 1303 1304 - var stopTop= 1305 - later.length 1306 - ?later[0].el 1307 - .getBoundingClientRect() 1308 - .top 1309 - :Infinity; 1279 + function heading(card){ 1280 + var cr= 1281 + card.getBoundingClientRect(); 1310 1310 1283 + var rows= 1311 1311 Array.from( 1312 - row.card.querySelectorAll("a") 1313 - ).forEach(function(link){ 1314 - if(!visible(link))return; 1285 + card.querySelectorAll( 1286 + "h1,h2,h3,h4,h5,h6,.box-title,[role=heading]" 1287 + ) 1288 + ) 1289 + .filter(function(el){ 1290 + if(!visible(el,20,8))return false; 1315 1315 1316 - var rect= 1317 - link.getBoundingClientRect(); 1292 + var r=el.getBoundingClientRect(); 1318 1318 1319 - if( 1320 - rect.top<= 1321 - headerRect.bottom-2|| 1322 - rect.top>= 1323 - stopTop-2 1324 - ){ 1325 - return; 1326 - } 1294 + var rel= 1295 + r.top- 1296 + cr.top; 1327 1327 1328 - var candidates= 1329 - rowCandidates( 1330 - link, 1331 - row.card 1332 - ); 1333 - 1334 - var target= 1335 - chooseOuterRow( 1336 - candidates, 1337 - link 1338 - ); 1339 - 1340 - candidates.forEach(function(el){ 1341 - el.style.setProperty( 1342 - "border-left", 1343 - "0 solid transparent", 1344 - "important" 1345 - ); 1346 - }); 1347 - 1348 - target.style.setProperty( 1349 - "border-left", 1350 - "3px solid "+ 1351 - row.theme.accent, 1352 - "important" 1298 + return ( 1299 + rel>=0&& 1300 + rel<= 1301 + Math.min( 1302 + 160, 1303 + cr.height*.45 1304 + ) 1353 1353 ); 1354 - 1355 - target.style.setProperty(1356 - "box-sizing",1357 - "border-box",1358 - "important"1306 + }) 1307 + .sort(function(a,b){ 1308 + return ( 1309 + a.getBoundingClientRect().top- 1310 + b.getBoundingClientRect().top 1359 1359 ); 1360 1360 }); 1361 - }); 1362 1362 1363 - return unique;1314 + return rows[0]||null; 1364 1364 } 1365 1365 1366 - /* ======================================================= 1367 - OVERVIEW CARD HEIGHT + FIRST THEMATIC ROW 1368 - ======================================================= */ 1317 + function firstContent(card,h){ 1318 + if(!h)return null; 1369 1369 1370 - function alignOverviewCards(headers){ 1371 - if( 1372 - PAGE_KIND!=="overview"|| 1373 - window.innerWidth<=MOBILE_MAX 1374 - ){ 1375 - return; 1376 - } 1320 + var cr= 1321 + card.getBoundingClientRect(); 1377 1377 1378 - var cards=[];1379 - varseen=new Set();1323 + var hr= 1324 + h.getBoundingClientRect(); 1380 1380 1381 - headers.forEach(function(row){ 1382 - if(!seen.has(row.card)){ 1383 - seen.add(row.card); 1384 - cards.push(row.card); 1385 - } 1386 - }); 1326 + var rows= 1327 + Array.from( 1328 + card.querySelectorAll( 1329 + "p,div,ul,ol,dl,blockquote" 1330 + ) 1331 + ) 1332 + .filter(function(el){ 1333 + if( 1334 + el===h|| 1335 + h.contains(el)|| 1336 + el.contains(h) 1337 + ){ 1338 + return false; 1339 + } 1387 1387 1388 - if(cards.length<2){ 1389 - return; 1390 - } 1341 + if(!visible(el,30,8))return false; 1391 1391 1392 - // Group cards by actual top position. 1393 - var groups=[]; 1343 + var text= 1344 + String(el.textContent||"") 1345 + .replace(/\s+/g," ") 1346 + .trim(); 1394 1394 1395 - cards.forEach(function(card){ 1396 - var top= 1397 - card.getBoundingClientRect().top; 1348 + if(text.length<3)return false; 1398 1398 1399 - var group=null;1350 + var r=el.getBoundingClientRect(); 1400 1400 1401 - for(var i=0;i<groups.length;i++){ 1402 1402 if( 1403 - Math.abs( 1404 - groups[i].top-top 1405 - )<=ROW_TOLERANCE 1353 + r.top< 1354 + hr.bottom-1 1406 1406 ){ 1407 - group=groups[i]; 1408 - break; 1356 + return false; 1409 1409 } 1410 - } 1411 1411 1412 - if(!group){ 1413 - group={ 1414 - top:top, 1415 - cards:[] 1416 - }; 1417 - groups.push(group); 1418 - } 1359 + if( 1360 + r.top-cr.top> 1361 + Math.min( 1362 + 280, 1363 + cr.height*.65 1364 + ) 1365 + ){ 1366 + return false; 1367 + } 1419 1419 1420 - group.cards.push(card); 1421 - }); 1369 + if( 1370 + r.height> 1371 + cr.height*.58 1372 + ){ 1373 + return false; 1374 + } 1422 1422 1423 - groups.forEach(function(group){ 1424 - if(group.cards.length<2){ 1425 - return; 1426 - } 1376 + return true; 1377 + }) 1378 + .sort(function(a,b){ 1379 + var ar= 1380 + a.getBoundingClientRect(); 1427 1427 1428 - var firstHeaders= 1429 - group.cards.map(function(card){ 1430 - var candidates= 1431 - headers 1432 - .filter(function(row){ 1433 - return row.card===card; 1434 - }) 1435 - .sort(function(a,b){ 1436 - return ( 1437 - a.el 1438 - .getBoundingClientRect() 1439 - .top- 1440 - b.el 1441 - .getBoundingClientRect() 1442 - .top 1443 - ); 1444 - }); 1382 + var br= 1383 + b.getBoundingClientRect(); 1445 1445 1446 - return candidates.length 1447 - ?candidates[0] 1448 - :null; 1449 - }); 1385 + return ( 1386 + ar.top-br.top|| 1387 + ar.height-br.height 1388 + ); 1389 + }); 1450 1450 1451 - if( 1452 - !firstHeaders.some(function(row){ 1453 - return !row; 1454 - }) 1455 - ){ 1456 - var targetTop= 1457 - Math.max.apply( 1458 - Math, 1459 - firstHeaders.map(function(row){ 1460 - return ( 1461 - row.el 1462 - .getBoundingClientRect() 1463 - .top- 1464 - row.card 1465 - .getBoundingClientRect() 1466 - .top 1467 - ); 1468 - }) 1469 - ); 1391 + return rows[0]||null; 1392 + } 1470 1470 1471 - firstHeaders.forEach(function(row){ 1472 - var relativeTop= 1473 - row.el 1474 - .getBoundingClientRect() 1475 - .top- 1476 - row.card 1477 - .getBoundingClientRect() 1478 - .top; 1394 + function alignGeneric(cards){ 1395 + var rows= 1396 + cards.map(function(card){ 1397 + var h= 1398 + heading(card); 1479 1479 1480 - var delta= 1481 - targetTop-relativeTop; 1400 + var c= 1401 + firstContent( 1402 + card, 1403 + h 1404 + ); 1482 1482 1483 - if(delta>1){ 1484 - saveStyle( 1485 - row.el, 1486 - originalMargin, 1487 - "margin-top" 1488 - ); 1406 + if(!h||!c)return null; 1489 1489 1490 - var current= 1491 - num( 1492 - getComputedStyle( 1493 - row.el 1494 - ).marginTop 1495 - ); 1408 + var cr= 1409 + card.getBoundingClientRect(); 1496 1496 1497 - row.el.style.setProperty( 1498 - "margin-top", 1499 - ( 1500 - current+delta 1501 - )+"px" 1502 - ); 1411 + var rr= 1412 + c.getBoundingClientRect(); 1503 1503 1504 - row.el.setAttribute( 1505 - "data-sn-master-first-row", 1506 - "1" 1507 - ); 1414 + return { 1415 + content:c, 1416 + relativeTop: 1417 + rr.top-cr.top 1418 + }; 1419 + }); 1508 1508 1509 - managedMargin.add( 1510 - row.el 1511 - ); 1512 - } 1513 - }); 1514 - } 1421 + if( 1422 + rows.some(function(row){ 1423 + return !row; 1424 + }) 1425 + ){ 1426 + return false; 1427 + } 1515 1515 1516 - var maxHeight=0; 1429 + var target= 1430 + Math.max.apply( 1431 + Math, 1432 + rows.map(function(row){ 1433 + return row.relativeTop; 1434 + }) 1435 + ); 1517 1517 1518 - group.cards.forEach(function(card){ 1519 - maxHeight= 1520 - Math.max( 1521 - maxHeight, 1522 - card 1523 - .getBoundingClientRect() 1524 - .height 1525 - ); 1526 - }); 1437 + rows.forEach(function(row){ 1438 + var delta= 1439 + target- 1440 + row.relativeTop; 1527 1527 1528 - maxHeight= 1529 - Math.ceil(maxHeight); 1442 + if(delta<=1)return; 1530 1530 1531 - group.cards.forEach(function(card){ 1532 - saveStyle( 1533 - card, 1534 - originalHeight, 1535 - "min-height" 1536 - ); 1444 + saveOriginal( 1445 + row.content, 1446 + originalMarginTop, 1447 + "margin-top" 1448 + ); 1537 1537 1538 - card.style.setProperty( 1539 - "min-height", 1540 - maxHeight+"px" 1450 + var current= 1451 + num( 1452 + getComputedStyle( 1453 + row.content 1454 + ).marginTop 1541 1541 ); 1542 1542 1543 - card.setAttribute( 1544 - "data-sn-master-equal-height", 1545 - "1" 1546 - ); 1457 + row.content.style.setProperty( 1458 + "margin-top", 1459 + ( 1460 + current+ 1461 + delta 1462 + )+"px" 1463 + ); 1547 1547 1548 - managedHeight.add( 1549 - card 1550 - ); 1551 - }); 1465 + row.content.setAttribute( 1466 + "data-sn-first-content-aligned", 1467 + "7" 1468 + ); 1469 + 1470 + contentManaged.add( 1471 + row.content 1472 + ); 1552 1552 }); 1474 + 1475 + return true; 1553 1553 } 1554 1554 1555 - /* ======================================================= 1556 - DETAIL GRID EQUAL HEIGHT, DESKTOP ONLY 1557 - ======================================================= */ 1478 + function applyRow(group){ 1479 + if(!validRow(group))return false; 1558 1558 1559 - function equaliseDetailGrids(){ 1481 + var cards=[]; 1482 + var seen=new Set(); 1483 + 1484 + group.entries.forEach(function(entry){ 1485 + if(!seen.has(entry.target)){ 1486 + seen.add(entry.target); 1487 + cards.push(entry.target); 1488 + } 1489 + }); 1490 + 1491 + if(cards.length<2)return false; 1492 + 1560 1560 if( 1561 - PAGE_KIND!=="detail"|| 1562 - window.innerWidth<=MOBILE_MAX 1494 + !alignKnownBars(cards) 1563 1563 ){ 1564 - return;1496 + alignGeneric(cards); 1565 1565 } 1566 1566 1567 - var selectors=[ 1568 - ".arsn-grid", 1569 - ".arsn-grid-2", 1570 - ".arsn-grid-3", 1571 - ".dmp-grid", 1572 - ".ido-grid", 1573 - ".pp-grid" 1574 - ]; 1499 + var maxHeight=0; 1575 1575 1576 - selectors.forEach(function(selector){ 1577 - Array.from( 1578 - root.querySelectorAll(selector) 1579 - ).forEach(function(grid){ 1580 - var children= 1581 - Array.from( 1582 - grid.children||[] 1583 - ).filter(visible); 1501 + cards.forEach(function(card){ 1502 + maxHeight= 1503 + Math.max( 1504 + maxHeight, 1505 + card.getBoundingClientRect().height 1506 + ); 1507 + }); 1584 1584 1585 - if(children.length<2){ 1586 - return; 1587 - } 1509 + maxHeight= 1510 + Math.ceil( 1511 + maxHeight 1512 + ); 1588 1588 1589 - vargroups=[];1514 + if(maxHeight<MIN_H)return false; 1590 1590 1591 - children.forEach(function(child){ 1592 - var top= 1593 - child 1594 - .getBoundingClientRect() 1595 - .top; 1516 + cards.forEach(function(card){ 1517 + saveOriginal( 1518 + card, 1519 + originalMinHeight, 1520 + "min-height" 1521 + ); 1596 1596 1597 - var group=null; 1523 + card.style.setProperty( 1524 + "min-height", 1525 + maxHeight+"px" 1526 + ); 1598 1598 1599 - for(var i=0;i<groups.length;i++){ 1600 - if( 1601 - Math.abs( 1602 - groups[i].top-top 1603 - )<=ROW_TOLERANCE 1604 - ){ 1605 - group=groups[i]; 1606 - break; 1607 - } 1608 - } 1528 + card.setAttribute( 1529 + "data-sn-equal-height-managed", 1530 + "7" 1531 + ); 1609 1609 1610 - if(!group){ 1611 - group={ 1612 - top:top, 1613 - items:[] 1614 - }; 1615 - groups.push(group); 1616 - } 1533 + heightManaged.add(card); 1534 + }); 1617 1617 1618 - group.items.push(child);1619 - });1536 + return true; 1537 + } 1620 1620 1621 - groups.forEach(function(group){ 1622 - if(group.items.length<2){ 1623 - return; 1624 - } 1539 + function calculate(force){ 1540 + if(applying)return; 1625 1625 1626 - var maxHeight=0; 1542 + var width= 1543 + Math.round( 1544 + window.innerWidth 1545 + ); 1627 1627 1628 - group.items.forEach(function(item){ 1629 - maxHeight= 1630 - Math.max( 1631 - maxHeight, 1632 - item 1633 - .getBoundingClientRect() 1634 - .height 1635 - ); 1636 - }); 1547 + var meaningful= 1548 + lastWidth<0|| 1549 + Math.abs( 1550 + width- 1551 + lastWidth 1552 + )>= 1553 + MIN_WIDTH_CHANGE; 1637 1637 1638 - maxHeight= 1639 - Math.ceil(maxHeight); 1555 + if( 1556 + hasApplied&& 1557 + !force&& 1558 + !meaningful 1559 + ){ 1560 + return; 1561 + } 1640 1640 1641 - group.items.forEach(function(item){ 1642 - saveStyle( 1643 - item, 1644 - originalHeight, 1645 - "min-height" 1646 - ); 1563 + applying=true; 1647 1647 1648 - item.style.setProperty( 1649 - "min-height", 1650 - maxHeight+"px" 1651 - ); 1565 + try{ 1566 + harmoniseCustomCallouts(); 1652 1652 1653 - item.setAttribute(1654 - "data-sn-master-equal-height",1655 - "1"1656 - );1568 + if(width<=MOBILE_MAX){ 1569 + if(hasApplied){ 1570 + resetRuntime(); 1571 + } 1657 1657 1658 - managedHeight.add(item); 1659 - }); 1573 + hasApplied=false; 1574 + lastWidth=width; 1575 + return; 1576 + } 1577 + 1578 + if(hasApplied){ 1579 + resetRuntime(); 1580 + } 1581 + 1582 + var parents= 1583 + Array.from( 1584 + root.querySelectorAll("*") 1585 + ) 1586 + .filter(function(parent){ 1587 + return ( 1588 + visible( 1589 + parent, 1590 + MIN_W, 1591 + MIN_H 1592 + )&& 1593 + parent.children&& 1594 + parent.children.length>=2&& 1595 + parent.children.length<= 1596 + MAX_PARENT_CHILDREN 1597 + ); 1660 1660 }); 1661 - }); 1662 - }); 1663 - } 1664 1664 1665 - /* ======================================================= 1666 - RUN / RESPONSIVE SCHEDULING 1667 - ======================================================= */ 1600 + var touched= 1601 + new Set(); 1668 1668 1669 - function run(){1670 - if(running)return;1603 + parents.forEach(function(parent){ 1604 + var entries=[]; 1671 1671 1672 - running=true; 1606 + Array.from( 1607 + parent.children 1608 + ).forEach(function(child){ 1609 + if( 1610 + !visible( 1611 + child, 1612 + MIN_W, 1613 + MIN_H 1614 + ) 1615 + ){ 1616 + return; 1617 + } 1673 1673 1674 - try{ 1675 - resetRuntime(); 1676 - applyPlaceholderBadge(); 1677 - propagateDetailAccents(); 1619 + var target= 1620 + pickTarget(child); 1678 1678 1679 - var headers= 1680 - applyOverviewPalette(); 1622 + if(!target)return; 1681 1681 1682 - if( 1683 - window.innerWidth> 1684 - MOBILE_MAX 1685 - ){ 1686 - alignOverviewCards( 1687 - headers 1688 - ); 1624 + entries.push({ 1625 + target:target, 1626 + rect: 1627 + target.getBoundingClientRect() 1628 + }); 1629 + }); 1689 1689 1690 - equaliseDetailGrids(); 1691 - } 1631 + groupRows( 1632 + entries 1633 + ).forEach(function(group){ 1634 + if(!validRow(group))return; 1635 + 1636 + var targets= 1637 + group.entries.map(function(entry){ 1638 + return entry.target; 1639 + }); 1640 + 1641 + if( 1642 + !targets.some(function(el){ 1643 + return !touched.has(el); 1644 + }) 1645 + ){ 1646 + return; 1647 + } 1648 + 1649 + if(applyRow(group)){ 1650 + targets.forEach(function(el){ 1651 + touched.add(el); 1652 + }); 1653 + } 1654 + }); 1655 + }); 1656 + 1657 + lastWidth=width; 1658 + hasApplied=true; 1692 1692 }finally{ 1693 - running=false;1660 + applying=false; 1694 1694 } 1695 1695 } 1696 1696 1697 - function onResize(){1664 + function resize(){ 1698 1698 if(resizeTimer){ 1699 1699 clearTimeout( 1700 1700 resizeTimer ... ... @@ -1705,40 +1705,19 @@ 1705 1705 setTimeout( 1706 1706 function(){ 1707 1707 resizeTimer=0; 1708 - run();1675 + calculate(false); 1709 1709 }, 1710 1710 RESIZE_DEBOUNCE 1711 1711 ); 1712 1712 } 1713 1713 1714 - async function waitForReady(){ 1715 - if( 1716 - document.readyState!=="complete" 1717 - ){ 1718 - await new Promise(function(resolve){ 1719 - window.addEventListener( 1720 - "load", 1721 - resolve, 1722 - {once:true} 1723 - ); 1724 - }); 1725 - } 1726 - 1727 - if( 1728 - document.fonts&& 1729 - document.fonts.ready 1730 - ){ 1731 - try{ 1732 - await document.fonts.ready; 1733 - }catch(error){} 1734 - } 1735 - 1681 + function waitImages(){ 1736 1736 var images= 1737 1737 Array.from( 1738 1738 root.querySelectorAll("img") 1739 1739 ); 1740 1740 1741 - await Promise.all(1687 + return Promise.all( 1742 1742 images.map(function(img){ 1743 1743 if(img.complete){ 1744 1744 return Promise.resolve(); ... ... @@ -1763,20 +1763,46 @@ 1763 1763 }); 1764 1764 }) 1765 1765 ); 1712 + } 1766 1766 1767 - run(); 1714 + async function initial(){ 1715 + if( 1716 + document.readyState!== 1717 + "complete" 1718 + ){ 1719 + await new Promise(function(resolve){ 1720 + addEventListener( 1721 + "load", 1722 + resolve, 1723 + {once:true} 1724 + ); 1725 + }); 1726 + } 1727 + 1728 + if( 1729 + document.fonts&& 1730 + document.fonts.ready 1731 + ){ 1732 + try{ 1733 + await document.fonts.ready; 1734 + }catch(error){} 1735 + } 1736 + 1737 + await waitImages(); 1738 + 1739 + // Exactly one initial layout calculation. 1740 + calculate(true); 1768 1768 } 1769 1769 1770 - window.addEventListener(1743 + addEventListener( 1771 1771 "resize", 1772 - onResize,1745 + resize, 1773 1773 {passive:true} 1774 1774 ); 1775 1775 1776 - waitForReady();1749 + initial(); 1777 1777 })(); 1778 1778 </script> 1779 1779 1780 -<!-- SN_SERVICE_NAVIGATOR_MASTER_STYLE_END --> 1781 -{{/html}} 1782 - 1753 +<!-- SN_HORIZONTAL_BOX_HARMONIZER_END --> 1754 +{{/html}}\n