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