Änderungen von Dokument Art & Research Services Navigator
Zuletzt geändert von Veronika Kocher am Freitag, 18 Sep. 2026 16:47
Von Version 11.3
bearbeitet von Veronika Kocher
am Freitag, 04 Sep. 2026 9:18
am Freitag, 04 Sep. 2026 9:18
Ä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
-
... ... @@ -3,6 +3,7 @@ 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 + 6 6 7 7 **Support Kunst und Forschung (SKF)** begleitet Projekt- und Fördervorhaben und arbeitet je nach Bedarf mit den passenden Services der Universität zusammen. 8 8 ... ... @@ -434,9 +434,9 @@ 434 434 ))) 435 435 ))) 436 436 437 -(% class="arsn-phase-cta-wrap" style="padding:0 16px 16px 16px;" %)438 +(% style="padding:0 16px 16px 16px;" %) 438 438 ((( 439 -[[Zu Vorbereiten>>https://xwiki.uni-ak.ac.at/bin/view/Service%20Navigator/Art%20%26%20Research%20Services%20Navigator/Enable/||class="btn btn-primary btn-block arsn-phase-cta"]]440 +[[Zu Vorbereiten>>https://xwiki.uni-ak.ac.at/bin/view/Service%20Navigator/Art%20%26%20Research%20Services%20Navigator/Enable/||class="btn btn-primary btn-block"]] 440 440 ))) 441 441 ))) 442 442 ))) ... ... @@ -500,9 +500,9 @@ 500 500 ))) 501 501 ))) 502 502 503 -(% class="arsn-phase-cta-wrap" style="padding:0 16px 16px 16px;" %)504 +(% style="padding:0 16px 16px 16px;" %) 504 504 ((( 505 -[[Zu Arbeiten & Verwalten>>https://xwiki.uni-ak.ac.at/bin/view/Service%20Navigator/Art%20%26%20Research%20Services%20Navigator/Work%20%26%20Manage/||class="btn btn-primary btn-block arsn-phase-cta"]]506 +[[Zu Arbeiten & Verwalten>>https://xwiki.uni-ak.ac.at/bin/view/Service%20Navigator/Art%20%26%20Research%20Services%20Navigator/Work%20%26%20Manage/||class="btn btn-primary btn-block"]] 506 506 ))) 507 507 ))) 508 508 ))) ... ... @@ -576,9 +576,9 @@ 576 576 ))) 577 577 ))) 578 578 579 -(% class="arsn-phase-cta-wrap" style="padding:0 16px 16px 16px;" %)580 +(% style="padding:0 16px 16px 16px;" %) 580 580 ((( 581 -[[Zu Publizieren & Teilen>>https://xwiki.uni-ak.ac.at/bin/view/Service%20Navigator/Art%20%26%20Research%20Services%20Navigator/Publish%20%26%20Share/||class="btn btn-primary btn-block arsn-phase-cta"]]582 +[[Zu Publizieren & Teilen>>https://xwiki.uni-ak.ac.at/bin/view/Service%20Navigator/Art%20%26%20Research%20Services%20Navigator/Publish%20%26%20Share/||class="btn btn-primary btn-block"]] 582 582 ))) 583 583 ))) 584 584 ))) ... ... @@ -634,13 +634,12 @@ 634 634 {{/info}} 635 635 ))) 636 636 637 -{{html clean="false"}} 638 -<!-- SN_SERVICE_NAVIGATOR_MASTER_STYLE_START --> 638 +\n\n 639 +\n\n{{html clean="false"}} 640 +<!-- SN_HORIZONTAL_BOX_HARMONIZER_START --> 639 639 640 -<style data-sn-service-navigator-master="1"> 641 -/* ========================================================= 642 - MASTER TYPOGRAPHY 643 - ========================================================= */ 642 +<style data-sn-horizontal-box-harmonizer="7"> 643 +/* ---------- Typography: never justify headings ---------- */ 644 644 #xwikicontent h1, 645 645 #xwikicontent h2, 646 646 #xwikicontent h3, ... ... @@ -662,105 +662,88 @@ 662 662 word-spacing:normal!important; 663 663 } 664 664 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{ 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"]{ 693 693 box-sizing:border-box!important; 694 - border-left:4px solid #21b6d7!important; 695 - 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; 696 696 text-align:left!important; 683 + text-justify:auto!important; 697 697 word-spacing:normal!important; 685 + box-shadow:none!important; 698 698 } 699 699 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, 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, 707 707 #xwikicontent .errormessage{ 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; 708 + --sn-callout-accent:#e94b13; 709 + background:#fff1ec!important; 713 713 } 714 714 715 -[data-sn-master-equal-height], 716 -[data-sn-master-first-row]{ 717 - box-sizing:border-box; 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 718 } 719 719 720 -/* ========================================================= 721 - FULL-WIDTH THREE-LINE NUMBER / TITLE / SUBTITLE BLOCKS 722 - ========================================================= */ 723 -#xwikicontent .arsn-area-label[data-sn-three-line="1"]{ 724 - display:grid!important; 725 - grid-template-columns:minmax(0,1fr)!important; 726 - grid-auto-rows:auto!important; 727 - width:100%!important; 728 - max-width:none!important; 729 - box-sizing:border-box!important; 730 - justify-items:start!important; 731 - align-items:start!important; 732 - gap:2px!important; 733 - text-align:left!important; 734 - text-align-last:left!important; 735 - text-justify:auto!important; 736 - word-spacing:normal!important; 737 - white-space:normal!important; 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; 738 738 } 739 -#xwikicontent .arsn-area-label[data-sn-three-line="1"] > .arsn-area-number, 740 -#xwikicontent .arsn-area-label[data-sn-three-line="1"] > .sn-area-label-title, 741 -#xwikicontent .arsn-area-label[data-sn-three-line="1"] > .arsn-area-action{ 742 - display:block!important; 743 - width:100%!important; 744 - margin:0!important; 745 - text-align:left!important; 746 - text-align-last:left!important; 747 - text-justify:auto!important; 748 - word-spacing:normal!important; 749 - white-space:normal!important; 727 + 728 +#xwikicontent [data-sn-equal-height-managed], 729 +#xwikicontent [data-sn-first-section-aligned], 730 +#xwikicontent [data-sn-first-content-aligned]{ 731 + box-sizing:border-box; 750 750 } 751 751 </style> 752 752 753 -<script data-sn- service-navigator-master="1">735 +<script data-sn-horizontal-box-harmonizer="7"> 754 754 (function(){ 755 755 "use strict"; 756 756 757 - var PAGE_KIND="overview"; 758 - var PLACEHOLDER=false; 759 - var PLACEHOLDER_LABEL="IN VORBEREITUNG"; 760 - 761 761 var MOBILE_MAX=767; 762 762 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; 763 763 var RESIZE_DEBOUNCE=220; 746 + var MIN_WIDTH_CHANGE=2; 764 764 765 765 var root= 766 766 document.getElementById("xwikicontent")|| ... ... @@ -770,114 +770,142 @@ 770 770 771 771 if(!root)return; 772 772 773 - var managedHeight=new Set(); 774 - var managedMargin=new Set(); 775 - var originalHeight=new WeakMap(); 776 - var originalMargin=new WeakMap(); 756 + var heightManaged=new Set(); 757 + var sectionManaged=new Set(); 758 + var contentManaged=new Set(); 777 777 760 + var originalMinHeight=new WeakMap(); 761 + var originalMarginTop=new WeakMap(); 762 + 778 778 var resizeTimer=0; 779 - var running=false; 764 + var lastWidth=-1; 765 + var hasApplied=false; 766 + var applying=false; 780 780 781 - var THEMES=[ 782 - { 783 - name:"BLUE", 784 - accent:"#21b6d7", 785 - bg:"#eaf7fb", 786 - text:"#315d68", 787 - labels:[ 788 - "HIER STARTEN", 789 - "ENTSCHEIDEN", 790 - "ÜBERPRÜFEN & ANPASSEN", 791 - "START HERE", 792 - "DECIDE", 793 - "REVIEW & ADAPT" 794 - ] 795 - }, 796 - { 797 - name:"RED", 798 - accent:"#e94b13", 799 - bg:"#fff1ec", 800 - text:"#8a4d36", 801 - labels:[ 802 - "PLANEN & ORGANISIEREN", 803 - "ORGANISIEREN & DOKUMENTIEREN", 804 - "PUBLIZIEREN & PRÄSENTIEREN", 805 - "PLAN & ORGANISE", 806 - "PLAN & ORGANIZE", 807 - "ORGANISE & DOCUMENT", 808 - "ORGANIZE & DOCUMENT", 809 - "PUBLISH & PRESENT" 810 - ] 811 - }, 812 - { 813 - name:"YELLOW", 814 - accent:"#f0aa00", 815 - bg:"#fff8e7", 816 - text:"#785b17", 817 - labels:[ 818 - "SCHÜTZEN & KLÄREN", 819 - "STANDARDISIEREN & IDENTIFIZIEREN", 820 - "ÖFFNEN, NACHNUTZEN & AUFFINDBAR MACHEN", 821 - "PROTECT & CLARIFY", 822 - "STANDARDISE & IDENTIFY", 823 - "STANDARDIZE & IDENTIFY", 824 - "OPEN, REUSE & MAKE FINDABLE" 825 - ] 826 - }, 827 - { 828 - name:"GREEN", 829 - accent:"#38b76a", 830 - bg:"#edf9f1", 831 - text:"#3f7451", 832 - labels:[ 833 - "INFRASTRUKTUR EINRICHTEN", 834 - "INFRASTRUKTUR & ZUSAMMENARBEIT EINRICHTEN", 835 - "SPEICHERN & ZUGRIFF STEUERN", 836 - "REPOSITORIUM, ERHALTEN & ÜBERGEBEN", 837 - "SET UP INFRASTRUCTURE", 838 - "SET UP INFRASTRUCTURE & COLLABORATION", 839 - "STORE & CONTROL ACCESS", 840 - "REPOSITORY, PRESERVE & HAND OVER" 841 - ] 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; 842 842 } 843 - ]; 844 844 845 - function num(value){ 846 - var n=parseFloat(value); 847 - 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 + ); 848 848 } 849 849 850 - function norm (value){851 - return String( value||"")794 + function normalizeText(text){ 795 + return String(text||"") 852 852 .replace(/\s+/g," ") 853 853 .trim() 854 854 .toUpperCase(); 855 855 } 856 856 857 - function visible(el){ 858 - 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 + } 859 859 860 - var style=getComputedStyle(el); 861 - var rect=el.getBoundingClientRect(); 810 + /* ---------- Custom coloured callouts ---------- */ 862 862 812 + function nativeCallout(el){ 813 + var c= 814 + typeof el.className==="string" 815 + ? el.className.toLowerCase() 816 + : ""; 817 + 863 863 return ( 864 - style.display!=="none"&& 865 - style.visibility!=="hidden"&& 866 - rect.width>20&& 867 - rect.height>4 819 + /(^|\s)(infomessage|warningmessage|successmessage|errormessage)(\s|$)/.test(c) 868 868 ); 869 869 } 870 870 871 - 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){ 872 872 if(map.has(el))return; 873 873 874 874 map.set(el,{ 875 - value:el.style.getPropertyValue(property), 876 - priority:el.style.getPropertyPriority(property) 880 + value: 881 + el.style.getPropertyValue( 882 + property 883 + ), 884 + priority: 885 + el.style.getPropertyPriority( 886 + property 887 + ) 877 877 }); 878 878 } 879 879 880 - function restore Style(el,map,property){891 + function restoreOriginal(el,map,property){ 881 881 var original=map.get(el); 882 882 883 883 if(original&&original.value){ ... ... @@ -887,1078 +887,770 @@ 887 887 original.priority||"" 888 888 ); 889 889 }else{ 890 - el.style.removeProperty(property); 901 + el.style.removeProperty( 902 + property 903 + ); 891 891 } 892 892 } 893 893 894 894 function resetRuntime(){ 895 - managedHeight.forEach(function(el){896 - restore Style(908 + heightManaged.forEach(function(el){ 909 + restoreOriginal( 897 897 el, 898 - originalHeight, 911 + originalMinHeight, 899 899 "min-height" 900 900 ); 914 + 901 901 el.removeAttribute( 902 - "data-sn- master-equal-height"916 + "data-sn-equal-height-managed" 903 903 ); 904 904 }); 905 905 906 - managedMargin.forEach(function(el){907 - restore Style(920 + sectionManaged.forEach(function(el){ 921 + restoreOriginal( 908 908 el, 909 - originalMargin, 923 + originalMarginTop, 910 910 "margin-top" 911 911 ); 926 + 912 912 el.removeAttribute( 913 - "data-sn- master-first-row"928 + "data-sn-first-section-aligned" 914 914 ); 915 915 }); 916 916 917 - managedHeight.clear(); 918 - managedMargin.clear(); 919 - } 932 + contentManaged.forEach(function(el){ 933 + restoreOriginal( 934 + el, 935 + originalMarginTop, 936 + "margin-top" 937 + ); 920 920 921 - function themeFor(text){ 922 - var value=norm(text); 939 + el.removeAttribute( 940 + "data-sn-first-content-aligned" 941 + ); 942 + }); 923 923 924 - for(var i=0;i<THEMES.length;i++){ 925 - for(var j=0;j<THEMES[i].labels.length;j++){ 926 - var label=THEMES[i].labels[j]; 927 - 928 - if( 929 - value===label|| 930 - value.indexOf(label+" ")===0|| 931 - value.indexOf(label+" -")===0|| 932 - value.indexOf(label+" ·")===0 933 - ){ 934 - return THEMES[i]; 935 - } 936 - } 937 - } 938 - 939 - return null; 944 + heightManaged.clear(); 945 + sectionManaged.clear(); 946 + contentManaged.clear(); 940 940 } 941 941 942 - /* ======================================================= 943 - BORDERLESS FILLED RED/ORANGE CTA BUTTONS 944 - ======================================================= */ 949 + /* ---------- Card detection ---------- */ 945 945 946 - function colourDistance(a,b){ 947 - return Math.sqrt( 948 - Math.pow(a[0]-b[0],2)+ 949 - Math.pow(a[1]-b[1],2)+ 950 - Math.pow(a[2]-b[2],2) 951 - ); 951 + function namedLikeBox(el){ 952 + var c= 953 + typeof el.className==="string" 954 + ? el.className 955 + : ""; 956 + 957 + return /(^|[\s_-])(box|card|tile|panel|role|check|service|source|call|area|detail|resource|topic|warn|info)([\s_-]|$)/i.test(c); 952 952 } 953 953 954 - function makeFilledRedOrangeCTAsBorderless(){ 955 - var RED_ORANGE=[233,75,19]; 960 + function boxLike(el){ 961 + if( 962 + !visible(el,MIN_W,MIN_H)|| 963 + excluded(el) 964 + ){ 965 + return false; 966 + } 956 956 957 - Array.from( 958 - root.querySelectorAll( 959 - 'a,button,[role="button"],input[type="submit"],input[type="button"]' 960 - ) 961 - ).forEach(function(el){ 962 - if(!visible(el))return; 968 + var s=getComputedStyle(el); 969 + var r=el.getBoundingClientRect(); 963 963 964 - var style=getComputedStyle(el); 965 - var rgb=parseRGB(style.backgroundColor); 971 + var border= 972 + num(s.borderTopWidth)+ 973 + num(s.borderRightWidth)+ 974 + num(s.borderBottomWidth)+ 975 + num(s.borderLeftWidth); 966 966 967 - if(!rgb)return; 977 + var radius=Math.max( 978 + num(s.borderTopLeftRadius), 979 + num(s.borderTopRightRadius), 980 + num(s.borderBottomLeftRadius), 981 + num(s.borderBottomRightRadius) 982 + ); 968 968 969 - if( 970 - colourDistance( 971 - rgb, 972 - RED_ORANGE 973 - )>55 974 - ){ 975 - return; 976 - } 984 + var bg= 985 + s.backgroundColor&& 986 + s.backgroundColor!=="rgba(0, 0, 0, 0)"&& 987 + s.backgroundColor!=="transparent"; 977 977 978 - var rect=el.getBoundingClientRect(); 989 + var shadow= 990 + s.boxShadow&& 991 + s.boxShadow!=="none"; 979 979 980 - if( 981 - rect.width<80|| 982 - rect.height<24 983 - ){ 984 - return; 985 - } 993 + return ( 994 + namedLikeBox(el)|| 995 + border>=1|| 996 + (bg&&radius>=3)|| 997 + (shadow&&r.width>=180) 998 + ); 999 + } 986 986 987 - el.style.setProperty( 988 - "border", 989 - "none", 990 - "important" 991 - ); 1001 + function pickTarget(child){ 1002 + if(!visible(child,MIN_W,MIN_H))return null; 992 992 993 - el.style.setProperty( 994 - "border-left", 995 - "none", 996 - "important" 997 - ); 1004 + if(boxLike(child))return child; 998 998 999 - el.style.setProperty( 1000 - "border-top", 1001 - "none", 1002 - "important" 1003 - ); 1006 + var cr=child.getBoundingClientRect(); 1007 + var q=[]; 1004 1004 1005 - el.style.setProperty( 1006 - "border-right", 1007 - "none", 1008 - "important" 1009 - ); 1010 - 1011 - el.style.setProperty( 1012 - "border-bottom", 1013 - "none", 1014 - "important" 1015 - ); 1016 - 1017 - el.style.setProperty( 1018 - "box-shadow", 1019 - "none", 1020 - "important" 1021 - ); 1009 + Array.from(child.children||[]).forEach(function(el){ 1010 + q.push({el:el,depth:1}); 1022 1022 }); 1023 - } 1024 1024 1025 - /* ======================================================= 1026 - FULL-WIDTH THREE-LINE AREA LABELS 1027 - ======================================================= */ 1013 + var best=null; 1014 + var bestScore=-Infinity; 1028 1028 1029 - function compactText(value){ 1030 - return String(value||"") 1031 - .replace(/\s+/g," ") 1032 - .trim(); 1033 - } 1016 + while(q.length){ 1017 + var item=q.shift(); 1018 + var el=item.el; 1034 1034 1035 - function makeThreeLineAreaLabels(){ 1036 - Array.from( 1037 - root.querySelectorAll( 1038 - ".arsn-area-label" 1039 - ) 1040 - ).forEach(function(label){ 1041 - if( 1042 - label.getAttribute( 1043 - "data-sn-three-line" 1044 - )==="1" 1045 - ){ 1046 - return; 1047 - } 1020 + if(!visible(el,MIN_W,MIN_H))continue; 1048 1048 1049 - var number= 1050 - label.querySelector( 1051 - ":scope > .arsn-area-number" 1052 - ); 1022 + var r=el.getBoundingClientRect(); 1053 1053 1054 - var action= 1055 - label.querySelector( 1056 - ":scope > .arsn-area-action" 1057 - ); 1058 - 1059 1059 if( 1060 - !number||1061 - !action1025 + r.width>=cr.width*.68&& 1026 + boxLike(el) 1062 1062 ){ 1063 - return; 1064 - } 1028 + var widthFit= 1029 + 1-Math.min( 1030 + 1, 1031 + Math.abs(cr.width-r.width)/ 1032 + Math.max(1,cr.width) 1033 + ); 1065 1065 1066 - var clone= 1067 - label.cloneNode(true); 1035 + var topFit= 1036 + 1-Math.min( 1037 + 1, 1038 + Math.abs(cr.top-r.top)/100 1039 + ); 1068 1068 1069 - var cloneNumber= 1070 - clone.querySelector( 1071 - ":scope > .arsn-area-number" 1072 - ); 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; 1073 1073 1074 - var cloneAction= 1075 - clone.querySelector( 1076 - ":scope > .arsn-area-action" 1077 - ); 1078 - 1079 - if(cloneNumber){ 1080 - cloneNumber.remove(); 1047 + if(score>bestScore){ 1048 + best=el; 1049 + bestScore=score; 1050 + } 1081 1081 } 1082 1082 1083 - if(cloneAction){ 1084 - cloneAction.remove(); 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 + }); 1085 1085 } 1061 + } 1086 1086 1087 - var titleText= 1088 - compactText( 1089 - clone.textContent 1090 - ); 1063 + return best; 1064 + } 1091 1091 1092 - if(!titleText){ 1093 - return; 1094 - } 1066 + function groupRows(entries){ 1067 + var groups=[]; 1095 1095 1096 - var numberNode= 1097 - number.cloneNode(true); 1098 - 1099 - var actionNode= 1100 - action.cloneNode(true); 1101 - 1102 - var titleNode= 1103 - document.createElement( 1104 - "span" 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 1105 1105 ); 1076 + }) 1077 + .forEach(function(entry){ 1078 + var group=null; 1106 1106 1107 - titleNode.className= 1108 - "sn-area-label-title"; 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 + } 1109 1109 1110 - titleNode.textContent= 1111 - titleText; 1092 + if(!group){ 1093 + group={ 1094 + top:entry.rect.top, 1095 + entries:[] 1096 + }; 1097 + groups.push(group); 1098 + } 1112 1112 1113 - while(label.firstChild){ 1114 - label.removeChild( 1115 - label.firstChild 1116 - ); 1117 - } 1100 + group.entries.push(entry); 1101 + }); 1118 1118 1119 - label.appendChild( 1120 - numberNode 1121 - ); 1122 - 1123 - label.appendChild( 1124 - titleNode 1125 - ); 1126 - 1127 - label.appendChild( 1128 - actionNode 1129 - ); 1130 - 1131 - label.setAttribute( 1132 - "data-sn-three-line", 1133 - "1" 1134 - ); 1135 - 1136 - var head= 1137 - label.closest( 1138 - ".arsn-area-head" 1139 - ); 1140 - 1141 - if(head){ 1142 - head.style.setProperty( 1143 - "width", 1144 - "100%", 1145 - "important" 1146 - ); 1147 - 1148 - head.style.setProperty( 1149 - "max-width", 1150 - "100%", 1151 - "important" 1152 - ); 1153 - 1154 - head.style.setProperty( 1155 - "box-sizing", 1156 - "border-box", 1157 - "important" 1158 - ); 1159 - } 1160 - }); 1103 + return groups; 1161 1161 } 1162 1162 1163 - /* ======================================================= 1164 - PLACEHOLDER BADGE 1165 - ======================================================= */ 1106 + function validRow(group){ 1107 + if(group.entries.length<2)return false; 1166 1166 1167 - function applyPlaceholderBadge(){ 1168 - if(!PLACEHOLDER)return; 1109 + var lefts= 1110 + group.entries 1111 + .map(function(e){return e.rect.left;}) 1112 + .sort(function(a,b){return a-b;}); 1169 1169 1170 1170 if( 1171 - document.querySelector(1172 - ".sn-coming-soon-badge"1173 - )1115 + lefts[lefts.length-1]- 1116 + lefts[0]< 1117 + 80 1174 1174 ){ 1175 - return; 1119 + return false; 1176 1176 } 1177 1177 1178 - var title= 1179 - document.querySelector( 1180 - "#document-title" 1181 - )|| 1182 - document.querySelector( 1183 - "h1" 1184 - ); 1122 + var widths= 1123 + group.entries 1124 + .map(function(e){return e.rect.width;}) 1125 + .filter(function(w){return w>0;}); 1185 1185 1186 - if( !title)return;1127 + if(widths.length<2)return false; 1187 1187 1188 - var badge= 1189 - document.createElement( 1190 - "span" 1191 - ); 1129 + var minW= 1130 + Math.min.apply(Math,widths); 1192 1192 1193 - badge.className=1194 - "sn-coming-soon-badge";1132 + var maxW= 1133 + Math.max.apply(Math,widths); 1195 1195 1196 - badge.textContent= 1197 - PLACEHOLDER_LABEL; 1198 - 1199 - badge.setAttribute( 1200 - "aria-label", 1201 - PLACEHOLDER_LABEL 1135 + return ( 1136 + maxW/ 1137 + Math.max(1,minW)<= 1138 + 1.9 1202 1202 ); 1203 - 1204 - title.appendChild( 1205 - badge 1206 - ); 1207 1207 } 1208 1208 1209 - /* ======================================================= 1210 - DETAIL PAGE OWN-ACCENT PROPAGATION 1211 - ======================================================= */ 1142 + /* ---------- Known ARSN first section bars ---------- */ 1212 1212 1213 - function parseRGB(value){ 1214 - var match=String(value||"").match( 1215 - /rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)/i 1216 - ); 1144 + function knownBar(el){ 1145 + var text= 1146 + normalizeText( 1147 + el.textContent 1148 + ); 1217 1217 1218 - if(!match)return null; 1219 - 1220 - return [ 1221 - Number(match[1]), 1222 - Number(match[2]), 1223 - Number(match[3]) 1224 - ]; 1225 - } 1226 - 1227 - function distance(a,b){ 1228 - return Math.sqrt( 1229 - Math.pow(a[0]-b[0],2)+ 1230 - Math.pow(a[1]-b[1],2)+ 1231 - Math.pow(a[2]-b[2],2) 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" 1232 1232 ); 1233 1233 } 1234 1234 1235 - function paletteMatch(cssColor){ 1236 - var rgb=parseRGB(cssColor); 1162 + function findKnownBar(card){ 1163 + var cardRect= 1164 + card.getBoundingClientRect(); 1237 1237 1238 - if(!rgb)return null; 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; 1239 1239 1240 - var palette=[ 1241 - {hex:"#21b6d7",rgb:[33,182,215]}, 1242 - {hex:"#e94b13",rgb:[233,75,19]}, 1243 - {hex:"#f0aa00",rgb:[240,170,0]}, 1244 - {hex:"#38b76a",rgb:[56,183,106]} 1245 - ]; 1176 + var r=el.getBoundingClientRect(); 1246 1246 1247 - var best=null; 1248 - var bestDistance=Infinity; 1178 + var rel= 1179 + r.top- 1180 + cardRect.top; 1249 1249 1250 - palette.forEach(function(item){ 1251 - var d=distance(rgb,item.rgb); 1182 + return ( 1183 + rel>=35&& 1184 + rel<= 1185 + cardRect.height*.75 1186 + ); 1187 + }) 1188 + .sort(function(a,b){ 1189 + return ( 1190 + a.getBoundingClientRect().top- 1191 + b.getBoundingClientRect().top 1192 + ); 1193 + }); 1252 1252 1253 - if(d<bestDistance){ 1254 - best=item; 1255 - bestDistance=d; 1256 - } 1257 - }); 1258 - 1259 - return bestDistance<=30 1260 - ?best 1261 - :null; 1195 + return rows[0]||null; 1262 1262 } 1263 1263 1264 - function propagateDetailAccents(){ 1265 - if(PAGE_KIND!=="detail")return; 1198 + function alignKnownBars(cards){ 1199 + var rows= 1200 + cards.map(function(card){ 1201 + var bar= 1202 + findKnownBar(card); 1266 1266 1267 - Array.from( 1268 - root.querySelectorAll( 1269 - ".arsn-call,.dmp-call,.ido-call,.pp-call,"+ 1270 - ".arsn-source,.dmp-source,.ido-source,.pp-source" 1271 - ) 1272 - ).forEach(function(el){ 1273 - if(!visible(el))return; 1204 + if(!bar)return null; 1274 1274 1275 - var style=getComputedStyle(el); 1206 + var cr= 1207 + card.getBoundingClientRect(); 1276 1276 1277 - if( 1278 - num(style.borderTopWidth)>=2 1279 - ){ 1280 - var match= 1281 - paletteMatch( 1282 - style.borderTopColor 1283 - ); 1209 + var br= 1210 + bar.getBoundingClientRect(); 1284 1284 1285 - if(match){ 1286 - el.style.setProperty( 1287 - "border-left", 1288 - "4px solid "+match.hex, 1289 - "important" 1290 - ); 1291 - } 1292 - } 1293 - }); 1212 + return { 1213 + bar:bar, 1214 + relativeTop: 1215 + br.top- 1216 + cr.top 1217 + }; 1218 + }); 1294 1294 1295 - // Warning families: explicit safety override. 1296 - Array.from( 1297 - root.querySelectorAll( 1298 - ".arsn-warn,.dmp-warn,.ido-warn,.pp-warn,"+ 1299 - ".warn,.warning,.warningmessage,.errormessage" 1300 - ) 1301 - ).forEach(function(el){ 1302 - if(!visible(el))return; 1220 + if( 1221 + rows.some(function(row){ 1222 + return !row; 1223 + }) 1224 + ){ 1225 + return false; 1226 + } 1303 1303 1304 - el.style.setProperty( 1305 - "border-left", 1306 - "4px solid #e94b13", 1307 - "important" 1228 + var target= 1229 + Math.max.apply( 1230 + Math, 1231 + rows.map(function(row){ 1232 + return row.relativeTop; 1233 + }) 1308 1308 ); 1309 - }); 1310 1310 1311 - // Info families: explicit orientation override. 1312 - Array.from( 1313 - root.querySelectorAll( 1314 - ".arsn-info,.dmp-info,.ido-info,.pp-info,.infomessage" 1315 - ) 1316 - ).forEach(function(el){ 1317 - if(!visible(el))return; 1236 + rows.forEach(function(row){ 1237 + var delta= 1238 + target- 1239 + row.relativeTop; 1318 1318 1319 - el.style.setProperty( 1320 - "border-left", 1321 - "4px solid #21b6d7", 1322 - "important" 1241 + if(delta<=1)return; 1242 + 1243 + saveOriginal( 1244 + row.bar, 1245 + originalMarginTop, 1246 + "margin-top" 1323 1323 ); 1324 - }); 1325 - } 1326 1326 1327 - /* ======================================================= 1328 - OVERVIEW SEMANTIC THEME PALETTE 1329 - ======================================================= */ 1330 - 1331 - function smallestThemeHeaders(){ 1332 - return Array.from( 1333 - root.querySelectorAll( 1334 - "div,span,p,strong,h3,h4,h5,h6" 1335 - ) 1336 - ).filter(function(el){ 1337 - if(!visible(el))return false; 1338 - if(!themeFor(el.textContent))return false; 1339 - 1340 - return !Array.from( 1341 - el.children||[] 1342 - ).some(function(child){ 1343 - return !!themeFor( 1344 - child.textContent 1249 + var current= 1250 + num( 1251 + getComputedStyle( 1252 + row.bar 1253 + ).marginTop 1345 1345 ); 1346 - }); 1347 - }); 1348 - } 1349 1349 1350 - function findOverviewCard(header){ 1351 - var node=header.parentElement; 1352 - var candidates=[]; 1256 + row.bar.style.setProperty( 1257 + "margin-top", 1258 + ( 1259 + current+ 1260 + delta 1261 + )+"px" 1262 + ); 1353 1353 1354 - while(node&&node!==root){ 1355 - var rect=node.getBoundingClientRect(); 1356 - var style=getComputedStyle(node); 1264 + row.bar.setAttribute( 1265 + "data-sn-first-section-aligned", 1266 + "7" 1267 + ); 1357 1357 1358 - var border= 1359 - num(style.borderTopWidth)+ 1360 - num(style.borderRightWidth)+ 1361 - num(style.borderBottomWidth)+ 1362 - num(style.borderLeftWidth); 1363 - 1364 - if( 1365 - rect.width>=220&& 1366 - rect.width<=800&& 1367 - rect.height>=120&& 1368 - border>=1 1369 - ){ 1370 - candidates.push(node); 1371 - } 1372 - 1373 - node=node.parentElement; 1374 - } 1375 - 1376 - if(!candidates.length)return null; 1377 - 1378 - candidates.sort(function(a,b){ 1379 - return ( 1380 - b.getBoundingClientRect().height- 1381 - a.getBoundingClientRect().height 1269 + sectionManaged.add( 1270 + row.bar 1382 1382 ); 1383 1383 }); 1384 1384 1385 - return candidates[0];1274 + return true; 1386 1386 } 1387 1387 1388 - function rowCandidates(link,card){ 1389 - var result=[]; 1390 - var cardRect= 1277 + /* ---------- Generic first content after heading ---------- */ 1278 + 1279 + function heading(card){ 1280 + var cr= 1391 1391 card.getBoundingClientRect(); 1392 1392 1393 - var node=link; 1283 + var rows= 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; 1394 1394 1395 - while(node&&node!==card){ 1396 - if(visible(node)){ 1397 - var rect= 1398 - node.getBoundingClientRect(); 1292 + var r=el.getBoundingClientRect(); 1399 1399 1400 - if( 1401 - rect.height<=105&& 1402 - rect.width>= 1403 - cardRect.width*.50&& 1404 - rect.width<= 1405 - cardRect.width*1.03 1406 - ){ 1407 - result.push(node); 1408 - } 1409 - } 1294 + var rel= 1295 + r.top- 1296 + cr.top; 1410 1410 1411 - node=node.parentElement; 1412 - } 1413 - 1414 - return result; 1415 - } 1416 - 1417 - function chooseOuterRow( 1418 - candidates, 1419 - link 1420 - ){ 1421 - if(!candidates.length){ 1422 - return link; 1423 - } 1424 - 1425 - var bordered= 1426 - candidates.filter(function(el){ 1427 1427 return ( 1428 - num( 1429 - getComputedStyle(el) 1430 - .borderLeftWidth 1431 - )>=1 1299 + rel>=0&& 1300 + rel<= 1301 + Math.min( 1302 + 160, 1303 + cr.height*.45 1304 + ) 1432 1432 ); 1306 + }) 1307 + .sort(function(a,b){ 1308 + return ( 1309 + a.getBoundingClientRect().top- 1310 + b.getBoundingClientRect().top 1311 + ); 1433 1433 }); 1434 1434 1435 - var pool= 1436 - bordered.length 1437 - ?bordered 1438 - :candidates; 1439 - 1440 - pool.sort(function(a,b){ 1441 - var ar= 1442 - a.getBoundingClientRect(); 1443 - 1444 - var br= 1445 - b.getBoundingClientRect(); 1446 - 1447 - return ( 1448 - ar.left-br.left|| 1449 - br.width-ar.width 1450 - ); 1451 - }); 1452 - 1453 - return pool[0]||link; 1314 + return rows[0]||null; 1454 1454 } 1455 1455 1456 - function applyOverviewPalette(){ 1457 - if(PAGE_KIND!=="overview"){ 1458 - return []; 1459 - } 1317 + function firstContent(card,h){ 1318 + if(!h)return null; 1460 1460 1461 - var headers= 1462 - smallestThemeHeaders() 1463 - .map(function(el){ 1464 - return { 1465 - el:el, 1466 - theme: 1467 - themeFor( 1468 - el.textContent 1469 - ), 1470 - card: 1471 - findOverviewCard( 1472 - el 1473 - ) 1474 - }; 1475 - }) 1476 - .filter(function(row){ 1477 - return !!row.card; 1478 - }); 1320 + var cr= 1321 + card.getBoundingClientRect(); 1479 1479 1480 - var unique=[];1481 - varseenHeaders=new Set();1323 + var hr= 1324 + h.getBoundingClientRect(); 1482 1482 1483 - headers.forEach(function(row){ 1484 - var key= 1485 - row.theme.name+ 1486 - "|"+ 1487 - Math.round( 1488 - row.card 1489 - .getBoundingClientRect() 1490 - .left 1491 - )+ 1492 - "|"+ 1493 - Math.round( 1494 - row.el 1495 - .getBoundingClientRect() 1496 - .top 1497 - ); 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 + } 1498 1498 1499 - if(!seenHeaders.has(key)){ 1500 - seenHeaders.add(key); 1501 - unique.push(row); 1502 - } 1503 - }); 1341 + if(!visible(el,30,8))return false; 1504 1504 1505 - unique.forEach(function(row){1506 - varheaderRect=1507 - row.el1508 - . getBoundingClientRect();1343 + var text= 1344 + String(el.textContent||"") 1345 + .replace(/\s+/g," ") 1346 + .trim(); 1509 1509 1510 - row.el.style.setProperty( 1511 - "background", 1512 - row.theme.bg, 1513 - "important" 1514 - ); 1348 + if(text.length<3)return false; 1515 1515 1516 - row.el.style.setProperty( 1517 - "color", 1518 - row.theme.text, 1519 - "important" 1520 - ); 1350 + var r=el.getBoundingClientRect(); 1521 1521 1522 - row.el.style.setProperty( 1523 - "text-align", 1524 - "left", 1525 - "important" 1526 - ); 1352 + if( 1353 + r.top< 1354 + hr.bottom-1 1355 + ){ 1356 + return false; 1357 + } 1527 1527 1528 - row.el.style.setProperty( 1529 - "word-spacing", 1530 - "normal", 1531 - "important" 1532 - ); 1533 - 1534 - var later= 1535 - unique 1536 - .filter(function(other){ 1537 - return ( 1538 - other.card===row.card&& 1539 - other.el 1540 - .getBoundingClientRect() 1541 - .top> 1542 - headerRect.top+2 1543 - ); 1544 - }) 1545 - .sort(function(a,b){ 1546 - return ( 1547 - a.el 1548 - .getBoundingClientRect() 1549 - .top- 1550 - b.el 1551 - .getBoundingClientRect() 1552 - .top 1553 - ); 1554 - }); 1555 - 1556 - var stopTop= 1557 - later.length 1558 - ?later[0].el 1559 - .getBoundingClientRect() 1560 - .top 1561 - :Infinity; 1562 - 1563 - Array.from( 1564 - row.card.querySelectorAll("a") 1565 - ).forEach(function(link){ 1566 1566 if( 1567 - link.classList && 1568 - link.classList.contains( 1569 - "arsn-phase-cta" 1360 + r.top-cr.top> 1361 + Math.min( 1362 + 280, 1363 + cr.height*.65 1570 1570 ) 1571 1571 ){ 1572 - return; 1366 + return false; 1573 1573 } 1574 1574 1575 - if(!visible(link))return; 1576 - 1577 - var rect= 1578 - link.getBoundingClientRect(); 1579 - 1580 1580 if( 1581 - rect.top<= 1582 - headerRect.bottom-2|| 1583 - rect.top>= 1584 - stopTop-2 1370 + r.height> 1371 + cr.height*.58 1585 1585 ){ 1586 - return; 1373 + return false; 1587 1587 } 1588 1588 1589 - varcandidates=1590 - rowCandidates(1591 - link,1592 - row.card1593 - ); 1376 + return true; 1377 + }) 1378 + .sort(function(a,b){ 1379 + var ar= 1380 + a.getBoundingClientRect(); 1594 1594 1595 - var target= 1596 - chooseOuterRow( 1597 - candidates, 1598 - link 1599 - ); 1382 + var br= 1383 + b.getBoundingClientRect(); 1600 1600 1601 - candidates.forEach(function(el){ 1602 - el.style.setProperty( 1603 - "border-left", 1604 - "0 solid transparent", 1605 - "important" 1606 - ); 1607 - }); 1608 - 1609 - target.style.setProperty( 1610 - "border-left", 1611 - "3px solid "+ 1612 - row.theme.accent, 1613 - "important" 1385 + return ( 1386 + ar.top-br.top|| 1387 + ar.height-br.height 1614 1614 ); 1615 - 1616 - target.style.setProperty( 1617 - "box-sizing", 1618 - "border-box", 1619 - "important" 1620 - ); 1621 1621 }); 1622 - }); 1623 1623 1624 - return unique;1391 + return rows[0]||null; 1625 1625 } 1626 1626 1627 - /* ======================================================= 1628 - OVERVIEW CARD HEIGHT + FIRST THEMATIC ROW 1629 - ======================================================= */ 1394 + function alignGeneric(cards){ 1395 + var rows= 1396 + cards.map(function(card){ 1397 + var h= 1398 + heading(card); 1630 1630 1631 - function alignOverviewCards(headers){ 1632 - if( 1633 - PAGE_KIND!=="overview"|| 1634 - window.innerWidth<=MOBILE_MAX 1635 - ){ 1636 - return; 1637 - } 1400 + var c= 1401 + firstContent( 1402 + card, 1403 + h 1404 + ); 1638 1638 1639 - var cards=[]; 1640 - var seen=new Set(); 1406 + if(!h||!c)return null; 1641 1641 1642 - headers.forEach(function(row){ 1643 - if(!seen.has(row.card)){ 1644 - seen.add(row.card); 1645 - cards.push(row.card); 1646 - } 1647 - }); 1408 + var cr= 1409 + card.getBoundingClientRect(); 1648 1648 1649 - if(cards.length<2){ 1650 - return; 1651 - } 1411 + var rr= 1412 + c.getBoundingClientRect(); 1652 1652 1653 - // Group cards by actual top position. 1654 - var groups=[]; 1414 + return { 1415 + content:c, 1416 + relativeTop: 1417 + rr.top-cr.top 1418 + }; 1419 + }); 1655 1655 1656 - cards.forEach(function(card){ 1657 - var top= 1658 - card.getBoundingClientRect().top; 1421 + if( 1422 + rows.some(function(row){ 1423 + return !row; 1424 + }) 1425 + ){ 1426 + return false; 1427 + } 1659 1659 1660 - var group=null; 1429 + var target= 1430 + Math.max.apply( 1431 + Math, 1432 + rows.map(function(row){ 1433 + return row.relativeTop; 1434 + }) 1435 + ); 1661 1661 1662 - for(var i=0;i<groups.length;i++){ 1663 - if( 1664 - Math.abs( 1665 - groups[i].top-top 1666 - )<=ROW_TOLERANCE 1667 - ){ 1668 - group=groups[i]; 1669 - break; 1670 - } 1671 - } 1437 + rows.forEach(function(row){ 1438 + var delta= 1439 + target- 1440 + row.relativeTop; 1672 1672 1673 - if(!group){ 1674 - group={ 1675 - top:top, 1676 - cards:[] 1677 - }; 1678 - groups.push(group); 1679 - } 1442 + if(delta<=1)return; 1680 1680 1681 - group.cards.push(card); 1682 - }); 1444 + saveOriginal( 1445 + row.content, 1446 + originalMarginTop, 1447 + "margin-top" 1448 + ); 1683 1683 1684 - groups.forEach(function(group){ 1685 - if(group.cards.length<2){ 1686 - return; 1687 - } 1450 + var current= 1451 + num( 1452 + getComputedStyle( 1453 + row.content 1454 + ).marginTop 1455 + ); 1688 1688 1689 - var firstHeaders= 1690 - group.cards.map(function(card){ 1691 - var candidates= 1692 - headers 1693 - .filter(function(row){ 1694 - return row.card===card; 1695 - }) 1696 - .sort(function(a,b){ 1697 - return ( 1698 - a.el 1699 - .getBoundingClientRect() 1700 - .top- 1701 - b.el 1702 - .getBoundingClientRect() 1703 - .top 1704 - ); 1705 - }); 1457 + row.content.style.setProperty( 1458 + "margin-top", 1459 + ( 1460 + current+ 1461 + delta 1462 + )+"px" 1463 + ); 1706 1706 1707 - returncandidates.length1708 - ?candidates[0]1709 - :null;1710 - });1465 + row.content.setAttribute( 1466 + "data-sn-first-content-aligned", 1467 + "7" 1468 + ); 1711 1711 1712 - if( 1713 - !firstHeaders.some(function(row){ 1714 - return !row; 1715 - }) 1716 - ){ 1717 - var targetTop= 1718 - Math.max.apply( 1719 - Math, 1720 - firstHeaders.map(function(row){ 1721 - return ( 1722 - row.el 1723 - .getBoundingClientRect() 1724 - .top- 1725 - row.card 1726 - .getBoundingClientRect() 1727 - .top 1728 - ); 1729 - }) 1730 - ); 1470 + contentManaged.add( 1471 + row.content 1472 + ); 1473 + }); 1731 1731 1732 - firstHeaders.forEach(function(row){ 1733 - var relativeTop= 1734 - row.el 1735 - .getBoundingClientRect() 1736 - .top- 1737 - row.card 1738 - .getBoundingClientRect() 1739 - .top; 1475 + return true; 1476 + } 1740 1740 1741 - var delta=1742 - targetTop-relativeTop;1478 + function applyRow(group){ 1479 + if(!validRow(group))return false; 1743 1743 1744 - if(delta>1){ 1745 - saveStyle( 1746 - row.el, 1747 - originalMargin, 1748 - "margin-top" 1749 - ); 1481 + var cards=[]; 1482 + var seen=new Set(); 1750 1750 1751 - varcurrent=1752 - num(1753 - getComputedStyle(1754 - row.el1755 - ).marginTop1756 - );1484 + group.entries.forEach(function(entry){ 1485 + if(!seen.has(entry.target)){ 1486 + seen.add(entry.target); 1487 + cards.push(entry.target); 1488 + } 1489 + }); 1757 1757 1758 - row.el.style.setProperty( 1759 - "margin-top", 1760 - ( 1761 - current+delta 1762 - )+"px" 1763 - ); 1491 + if(cards.length<2)return false; 1764 1764 1765 - row.el.setAttribute( 1766 - "data-sn-master-first-row", 1767 - "1" 1768 - ); 1493 + if( 1494 + !alignKnownBars(cards) 1495 + ){ 1496 + alignGeneric(cards); 1497 + } 1769 1769 1770 - managedMargin.add( 1771 - row.el 1772 - ); 1773 - } 1774 - }); 1775 - } 1499 + var maxHeight=0; 1776 1776 1777 - var maxHeight=0; 1501 + cards.forEach(function(card){ 1502 + maxHeight= 1503 + Math.max( 1504 + maxHeight, 1505 + card.getBoundingClientRect().height 1506 + ); 1507 + }); 1778 1778 1779 - group.cards.forEach(function(card){ 1780 - maxHeight= 1781 - Math.max( 1782 - maxHeight, 1783 - card 1784 - .getBoundingClientRect() 1785 - .height 1786 - ); 1787 - }); 1509 + maxHeight= 1510 + Math.ceil( 1511 + maxHeight 1512 + ); 1788 1788 1789 - maxHeight= 1790 - Math.ceil(maxHeight); 1514 + if(maxHeight<MIN_H)return false; 1791 1791 1792 - group.cards.forEach(function(card){1793 - saveStyle(1794 - card,1795 - originalHeight,1796 - "min-height"1797 - );1516 + cards.forEach(function(card){ 1517 + saveOriginal( 1518 + card, 1519 + originalMinHeight, 1520 + "min-height" 1521 + ); 1798 1798 1799 - card.style.setProperty(1800 - "min-height",1801 - maxHeight+"px"1802 - );1523 + card.style.setProperty( 1524 + "min-height", 1525 + maxHeight+"px" 1526 + ); 1803 1803 1804 - card.setAttribute(1805 - "data-sn-master-equal-height",1806 - "1"1807 - );1528 + card.setAttribute( 1529 + "data-sn-equal-height-managed", 1530 + "7" 1531 + ); 1808 1808 1809 - managedHeight.add( 1810 - card 1811 - ); 1812 - }); 1533 + heightManaged.add(card); 1813 1813 }); 1535 + 1536 + return true; 1814 1814 } 1815 1815 1816 - /* ======================================================= 1817 - DETAIL GRID EQUAL HEIGHT, DESKTOP ONLY 1818 - ======================================================= */ 1539 + function calculate(force){ 1540 + if(applying)return; 1819 1819 1820 - function equaliseDetailGrids(){ 1542 + var width= 1543 + Math.round( 1544 + window.innerWidth 1545 + ); 1546 + 1547 + var meaningful= 1548 + lastWidth<0|| 1549 + Math.abs( 1550 + width- 1551 + lastWidth 1552 + )>= 1553 + MIN_WIDTH_CHANGE; 1554 + 1821 1821 if( 1822 - PAGE_KIND!=="detail"|| 1823 - window.innerWidth<=MOBILE_MAX 1556 + hasApplied&& 1557 + !force&& 1558 + !meaningful 1824 1824 ){ 1825 1825 return; 1826 1826 } 1827 1827 1828 - var selectors=[ 1829 - ".arsn-grid", 1830 - ".arsn-grid-2", 1831 - ".arsn-grid-3", 1832 - ".dmp-grid", 1833 - ".ido-grid", 1834 - ".pp-grid" 1835 - ]; 1563 + applying=true; 1836 1836 1837 - selectors.forEach(function(selector){ 1838 - Array.from( 1839 - root.querySelectorAll(selector) 1840 - ).forEach(function(grid){ 1841 - var children= 1842 - Array.from( 1843 - grid.children||[] 1844 - ).filter(visible); 1565 + try{ 1566 + harmoniseCustomCallouts(); 1845 1845 1846 - if(children.length<2){ 1847 - return; 1568 + if(width<=MOBILE_MAX){ 1569 + if(hasApplied){ 1570 + resetRuntime(); 1848 1848 } 1849 1849 1850 - var groups=[]; 1573 + hasApplied=false; 1574 + lastWidth=width; 1575 + return; 1576 + } 1851 1851 1852 - children.forEach(function(child){ 1853 - var top= 1854 - child 1855 - .getBoundingClientRect() 1856 - .top; 1578 + if(hasApplied){ 1579 + resetRuntime(); 1580 + } 1857 1857 1858 - var group=null; 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 + }); 1859 1859 1860 - for(var i=0;i<groups.length;i++){ 1861 - if( 1862 - Math.abs( 1863 - groups[i].top-top 1864 - )<=ROW_TOLERANCE 1865 - ){ 1866 - group=groups[i]; 1867 - break; 1868 - } 1869 - } 1600 + var touched= 1601 + new Set(); 1870 1870 1871 - if(!group){ 1872 - group={ 1873 - top:top, 1874 - items:[] 1875 - }; 1876 - groups.push(group); 1877 - } 1603 + parents.forEach(function(parent){ 1604 + var entries=[]; 1878 1878 1879 - group.items.push(child); 1880 - }); 1881 - 1882 - groups.forEach(function(group){ 1883 - if(group.items.length<2){ 1606 + Array.from( 1607 + parent.children 1608 + ).forEach(function(child){ 1609 + if( 1610 + !visible( 1611 + child, 1612 + MIN_W, 1613 + MIN_H 1614 + ) 1615 + ){ 1884 1884 return; 1885 1885 } 1886 1886 1887 - var maxHeight=0; 1619 + var target= 1620 + pickTarget(child); 1888 1888 1889 - group.items.forEach(function(item){ 1890 - maxHeight= 1891 - Math.max( 1892 - maxHeight, 1893 - item 1894 - .getBoundingClientRect() 1895 - .height 1896 - ); 1622 + if(!target)return; 1623 + 1624 + entries.push({ 1625 + target:target, 1626 + rect: 1627 + target.getBoundingClientRect() 1897 1897 }); 1629 + }); 1898 1898 1899 - maxHeight= 1900 - Math.ceil(maxHeight); 1631 + groupRows( 1632 + entries 1633 + ).forEach(function(group){ 1634 + if(!validRow(group))return; 1901 1901 1902 - group.items.forEach(function(item){ 1903 - saveStyle( 1904 - item, 1905 - originalHeight, 1906 - "min-height" 1907 - ); 1636 + var targets= 1637 + group.entries.map(function(entry){ 1638 + return entry.target; 1639 + }); 1908 1908 1909 - item.style.setProperty( 1910 - "min-height", 1911 - maxHeight+"px" 1912 - ); 1641 + if( 1642 + !targets.some(function(el){ 1643 + return !touched.has(el); 1644 + }) 1645 + ){ 1646 + return; 1647 + } 1913 1913 1914 - item.setAttribute( 1915 - "data-sn-master-equal-height", 1916 - "1" 1917 - ); 1918 - 1919 - managedHeight.add(item); 1920 - }); 1649 + if(applyRow(group)){ 1650 + targets.forEach(function(el){ 1651 + touched.add(el); 1652 + }); 1653 + } 1921 1921 }); 1922 1922 }); 1923 - }); 1924 - } 1925 1925 1926 - /* ======================================================= 1927 - RUN / RESPONSIVE SCHEDULING 1928 - ======================================================= */ 1929 - 1930 - function run(){ 1931 - if(running)return; 1932 - 1933 - running=true; 1934 - 1935 - try{ 1936 - resetRuntime(); 1937 - applyPlaceholderBadge(); 1938 - propagateDetailAccents(); 1939 - 1940 - var headers= 1941 - applyOverviewPalette(); 1942 - 1943 - makeThreeLineAreaLabels(); 1944 - makeFilledRedOrangeCTAsBorderless(); 1945 - 1946 - if( 1947 - window.innerWidth> 1948 - MOBILE_MAX 1949 - ){ 1950 - alignOverviewCards( 1951 - headers 1952 - ); 1953 - 1954 - equaliseDetailGrids(); 1955 - } 1657 + lastWidth=width; 1658 + hasApplied=true; 1956 1956 }finally{ 1957 - running=false;1660 + applying=false; 1958 1958 } 1959 1959 } 1960 1960 1961 - function onResize(){1664 + function resize(){ 1962 1962 if(resizeTimer){ 1963 1963 clearTimeout( 1964 1964 resizeTimer ... ... @@ -1969,40 +1969,19 @@ 1969 1969 setTimeout( 1970 1970 function(){ 1971 1971 resizeTimer=0; 1972 - run();1675 + calculate(false); 1973 1973 }, 1974 1974 RESIZE_DEBOUNCE 1975 1975 ); 1976 1976 } 1977 1977 1978 - async function waitForReady(){ 1979 - if( 1980 - document.readyState!=="complete" 1981 - ){ 1982 - await new Promise(function(resolve){ 1983 - window.addEventListener( 1984 - "load", 1985 - resolve, 1986 - {once:true} 1987 - ); 1988 - }); 1989 - } 1990 - 1991 - if( 1992 - document.fonts&& 1993 - document.fonts.ready 1994 - ){ 1995 - try{ 1996 - await document.fonts.ready; 1997 - }catch(error){} 1998 - } 1999 - 1681 + function waitImages(){ 2000 2000 var images= 2001 2001 Array.from( 2002 2002 root.querySelectorAll("img") 2003 2003 ); 2004 2004 2005 - await Promise.all(1687 + return Promise.all( 2006 2006 images.map(function(img){ 2007 2007 if(img.complete){ 2008 2008 return Promise.resolve(); ... ... @@ -2027,89 +2027,46 @@ 2027 2027 }); 2028 2028 }) 2029 2029 ); 1712 + } 2030 2030 2031 - 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); 2032 2032 } 2033 2033 2034 - window.addEventListener(1743 + addEventListener( 2035 2035 "resize", 2036 - onResize,1745 + resize, 2037 2037 {passive:true} 2038 2038 ); 2039 2039 2040 - waitForReady();1749 + initial(); 2041 2041 })(); 2042 2042 </script> 2043 2043 2044 -<!-- SN_SERVICE_NAVIGATOR_MASTER_STYLE_END --> 2045 -{{/html}} 2046 - 2047 -{{html clean="false"}} 2048 -<!-- ARSN_PHASE_CTA_MOBILE_EDGE_FIX_V3_START --> 2049 -<style data-arsn-phase-cta-mobile-edge-fix="3"> 2050 -@media (max-width:767px){ 2051 - 2052 - /* Remove the white side gutters around the three phase CTAs. */ 2053 - #xwikicontent .arsn-phase-cta-wrap{ 2054 - box-sizing:border-box!important; 2055 - width:calc(100% + 2px)!important; 2056 - max-width:none!important; 2057 - margin:14px -1px -1px -1px!important; 2058 - padding:0!important; 2059 - border:0!important; 2060 - border-left:0!important; 2061 - box-shadow:none!important; 2062 - background:transparent!important; 2063 - } 2064 - 2065 - /* Full-width orange CTA; no extra border/shadow. */ 2066 - #xwikicontent a.arsn-phase-cta{ 2067 - display:flex!important; 2068 - align-items:center!important; 2069 - justify-content:center!important; 2070 - gap:8px!important; 2071 - 2072 - box-sizing:border-box!important; 2073 - width:100%!important; 2074 - max-width:none!important; 2075 - min-width:0!important; 2076 - 2077 - margin:0!important; 2078 - padding:12px 14px!important; 2079 - 2080 - border:0!important; 2081 - border-left:0!important; 2082 - border-right:0!important; 2083 - border-top:0!important; 2084 - border-bottom:0!important; 2085 - box-shadow:none!important; 2086 - 2087 - border-radius:8px!important; 2088 - 2089 - text-align:center!important; 2090 - text-align-last:center!important; 2091 - text-justify:auto!important; 2092 - word-spacing:normal!important; 2093 - white-space:normal!important; 2094 - } 2095 - 2096 - /* Keep an XWiki external-link icon on the same line/flex row. */ 2097 - #xwikicontent a.arsn-phase-cta::after{ 2098 - flex:0 0 auto!important; 2099 - margin-left:2px!important; 2100 - } 2101 - 2102 - #xwikicontent a.arsn-phase-cta > .fa, 2103 - #xwikicontent a.arsn-phase-cta > .icon, 2104 - #xwikicontent a.arsn-phase-cta > .external-link-icon, 2105 - #xwikicontent a.arsn-phase-cta > [class*="external"]{ 2106 - position:static!important; 2107 - display:inline-block!important; 2108 - flex:0 0 auto!important; 2109 - margin:0!important; 2110 - } 2111 -} 2112 -</style> 2113 -<!-- ARSN_PHASE_CTA_MOBILE_EDGE_FIX_V3_END --> 2114 -{{/html}} 2115 - 1753 +<!-- SN_HORIZONTAL_BOX_HARMONIZER_END --> 1754 +{{/html}}\n