Changes for page Copyright, Rights & Licences
Last modified by Veronika Kocher on Friday, 18 Sep 2026 16:47
From version 5.11
edited by Veronika Kocher
on Thursday, 03 Sep 2026 13:04
on Thursday, 03 Sep 2026 13:04
Change comment:
There is no comment for this version
To version 5.10
edited by Veronika Kocher
on Thursday, 03 Sep 2026 10:09
on Thursday, 03 Sep 2026 10:09
Change comment:
There is no comment for this version
Summary
-
Page properties (1 modified, 0 added, 0 removed)
Details
- Page properties
-
- Content
-
... ... @@ -44,7 +44,7 @@ 44 44 45 45 == Who is responsible? == 46 46 47 - 47 +{{html}}<!-- ARSN_TOPIC_ROUTING_V1 -->{{/html}} 48 48 {{info title="Service routing"}} 49 49 **Primary specialist service(s):** Legal Department for binding legal questions and contracts; Publications and/or University Library for publication and licensing practice where relevant. 50 50 ... ... @@ -68,13 +68,12 @@ 68 68 <!-- ARSN_SEARCH_TERMS_END --> 69 69 {{/html}} 70 70 71 -{{html clean="false"}} 72 -<!-- SN_SERVICE_NAVIGATOR_MASTER_STYLE_START --> 71 +\n\n 72 +\n\n{{html clean="false"}} 73 +<!-- SN_HORIZONTAL_BOX_HARMONIZER_START --> 73 73 74 -<style data-sn-service-navigator-master="1"> 75 -/* ========================================================= 76 - MASTER TYPOGRAPHY 77 - ========================================================= */ 75 +<style data-sn-horizontal-box-harmonizer="7"> 76 +/* ---------- Typography: never justify headings ---------- */ 78 78 #xwikicontent h1, 79 79 #xwikicontent h2, 80 80 #xwikicontent h3, ... ... @@ -96,73 +96,88 @@ 96 96 word-spacing:normal!important; 97 97 } 98 98 99 -/* ========================================================= 100 - COMING SOON / IN VORBEREITUNG 101 - ========================================================= */ 102 -.sn-coming-soon-badge{ 103 - display:inline-block; 104 - vertical-align:middle; 105 - margin-left:10px; 106 - padding:4px 8px; 107 - border-radius:14px; 108 - border:1px solid #efd9cc; 109 - background:#fff4ee; 110 - color:#8a4d36; 111 - font-size:11px; 112 - font-weight:700; 113 - letter-spacing:.055em; 114 - line-height:1.2; 115 - white-space:nowrap; 116 -} 117 - 118 -/* ========================================================= 119 - NATIVE / DETAIL CALLOUT GEOMETRY 120 - Preserve existing backgrounds. 121 - ========================================================= */ 122 -#xwikicontent .arsn-info, 123 -#xwikicontent .dmp-info, 124 -#xwikicontent .ido-info, 125 -#xwikicontent .pp-info, 126 -#xwikicontent .infomessage{ 98 +/* ---------- Native XWiki semantic callouts ---------- */ 99 +#xwikicontent .box.infomessage, 100 +#xwikicontent .infomessage, 101 +#xwikicontent .box.warningmessage, 102 +#xwikicontent .warningmessage, 103 +#xwikicontent .box.successmessage, 104 +#xwikicontent .successmessage, 105 +#xwikicontent .box.errormessage, 106 +#xwikicontent .errormessage, 107 +#xwikicontent [data-sn-callout-harmonized="1"]{ 127 127 box-sizing:border-box!important; 128 - border-left:4px solid #21b6d7!important; 129 - border-radius:8px; 109 + border-radius:8px!important; 110 + border-top:1px solid rgba(0,0,0,.08)!important; 111 + border-right:1px solid rgba(0,0,0,.08)!important; 112 + border-bottom:1px solid rgba(0,0,0,.08)!important; 113 + border-left:4px solid var(--sn-callout-accent,#21b6d7)!important; 114 + padding:14px 16px!important; 130 130 text-align:left!important; 116 + text-justify:auto!important; 131 131 word-spacing:normal!important; 118 + box-shadow:none!important; 132 132 } 133 133 134 -#xwikicontent .arsn-warn, 135 -#xwikicontent .dmp-warn, 136 -#xwikicontent .ido-warn, 137 -#xwikicontent .pp-warn, 138 -#xwikicontent .warn, 139 -#xwikicontent .warning, 140 -#xwikicontent .warningmessage, 121 +#xwikicontent .box.infomessage, 122 +#xwikicontent .infomessage{ 123 + --sn-callout-accent:#21b6d7; 124 + background:#eaf7fb!important; 125 +} 126 + 127 +#xwikicontent .box.warningmessage, 128 +#xwikicontent .warningmessage{ 129 + --sn-callout-accent:#f0aa00; 130 + background:#fff8e7!important; 131 +} 132 + 133 +#xwikicontent .box.successmessage, 134 +#xwikicontent .successmessage{ 135 + --sn-callout-accent:#38b76a; 136 + background:#edf9f1!important; 137 +} 138 + 139 +#xwikicontent .box.errormessage, 141 141 #xwikicontent .errormessage{ 142 - box-sizing:border-box!important; 143 - border-left:4px solid #e94b13!important; 144 - border-radius:8px; 145 - text-align:left!important; 146 - word-spacing:normal!important; 141 + --sn-callout-accent:#e94b13; 142 + background:#fff1ec!important; 147 147 } 148 148 149 -[data-sn-master-equal-height], 150 -[data-sn-master-first-row]{ 145 +#xwikicontent [data-sn-callout-harmonized="1"] > :first-child, 146 +#xwikicontent .infomessage > :first-child, 147 +#xwikicontent .warningmessage > :first-child, 148 +#xwikicontent .successmessage > :first-child, 149 +#xwikicontent .errormessage > :first-child{ 150 + margin-top:0!important; 151 +} 152 + 153 +#xwikicontent [data-sn-callout-harmonized="1"] > :last-child, 154 +#xwikicontent .infomessage > :last-child, 155 +#xwikicontent .warningmessage > :last-child, 156 +#xwikicontent .successmessage > :last-child, 157 +#xwikicontent .errormessage > :last-child{ 158 + margin-bottom:0!important; 159 +} 160 + 161 +#xwikicontent [data-sn-equal-height-managed], 162 +#xwikicontent [data-sn-first-section-aligned], 163 +#xwikicontent [data-sn-first-content-aligned]{ 151 151 box-sizing:border-box; 152 152 } 153 153 </style> 154 154 155 -<script data-sn- service-navigator-master="1">168 +<script data-sn-horizontal-box-harmonizer="7"> 156 156 (function(){ 157 157 "use strict"; 158 158 159 - var PAGE_KIND="detail"; 160 - var PLACEHOLDER=true; 161 - var PLACEHOLDER_LABEL="COMING SOON"; 162 - 163 163 var MOBILE_MAX=767; 164 164 var ROW_TOLERANCE=6; 174 + var MIN_W=150; 175 + var MIN_H=36; 176 + var MAX_PARENT_CHILDREN=18; 177 + var SEARCH_DEPTH=5; 165 165 var RESIZE_DEBOUNCE=220; 179 + var MIN_WIDTH_CHANGE=2; 166 166 167 167 var root= 168 168 document.getElementById("xwikicontent")|| ... ... @@ -172,114 +172,142 @@ 172 172 173 173 if(!root)return; 174 174 175 - var managedHeight=new Set(); 176 - var managedMargin=new Set(); 177 - var originalHeight=new WeakMap(); 178 - var originalMargin=new WeakMap(); 189 + var heightManaged=new Set(); 190 + var sectionManaged=new Set(); 191 + var contentManaged=new Set(); 179 179 193 + var originalMinHeight=new WeakMap(); 194 + var originalMarginTop=new WeakMap(); 195 + 180 180 var resizeTimer=0; 181 - var running=false; 197 + var lastWidth=-1; 198 + var hasApplied=false; 199 + var applying=false; 182 182 183 - var THEMES=[ 184 - { 185 - name:"BLUE", 186 - accent:"#21b6d7", 187 - bg:"#eaf7fb", 188 - text:"#315d68", 189 - labels:[ 190 - "HIER STARTEN", 191 - "ENTSCHEIDEN", 192 - "ÜBERPRÜFEN & ANPASSEN", 193 - "START HERE", 194 - "DECIDE", 195 - "REVIEW & ADAPT" 196 - ] 197 - }, 198 - { 199 - name:"RED", 200 - accent:"#e94b13", 201 - bg:"#fff1ec", 202 - text:"#8a4d36", 203 - labels:[ 204 - "PLANEN & ORGANISIEREN", 205 - "ORGANISIEREN & DOKUMENTIEREN", 206 - "PUBLIZIEREN & PRÄSENTIEREN", 207 - "PLAN & ORGANISE", 208 - "PLAN & ORGANIZE", 209 - "ORGANISE & DOCUMENT", 210 - "ORGANIZE & DOCUMENT", 211 - "PUBLISH & PRESENT" 212 - ] 213 - }, 214 - { 215 - name:"YELLOW", 216 - accent:"#f0aa00", 217 - bg:"#fff8e7", 218 - text:"#785b17", 219 - labels:[ 220 - "SCHÜTZEN & KLÄREN", 221 - "STANDARDISIEREN & IDENTIFIZIEREN", 222 - "ÖFFNEN, NACHNUTZEN & AUFFINDBAR MACHEN", 223 - "PROTECT & CLARIFY", 224 - "STANDARDISE & IDENTIFY", 225 - "STANDARDIZE & IDENTIFY", 226 - "OPEN, REUSE & MAKE FINDABLE" 227 - ] 228 - }, 229 - { 230 - name:"GREEN", 231 - accent:"#38b76a", 232 - bg:"#edf9f1", 233 - text:"#3f7451", 234 - labels:[ 235 - "INFRASTRUKTUR EINRICHTEN", 236 - "INFRASTRUKTUR & ZUSAMMENARBEIT EINRICHTEN", 237 - "SPEICHERN & ZUGRIFF STEUERN", 238 - "REPOSITORIUM, ERHALTEN & ÜBERGEBEN", 239 - "SET UP INFRASTRUCTURE", 240 - "SET UP INFRASTRUCTURE & COLLABORATION", 241 - "STORE & CONTROL ACCESS", 242 - "REPOSITORY, PRESERVE & HAND OVER" 243 - ] 201 + function num(v){ 202 + var n=parseFloat(v); 203 + return Number.isFinite(n)?n:0; 204 + } 205 + 206 + function visible(el,minW,minH){ 207 + if(!el||el.nodeType!==1)return false; 208 + 209 + var s=getComputedStyle(el); 210 + 211 + if( 212 + s.display==="none"|| 213 + s.visibility==="hidden"|| 214 + Number(s.opacity)===0 215 + ){ 216 + return false; 244 244 } 245 - ]; 246 246 247 - function num(value){ 248 - var n=parseFloat(value); 249 - return Number.isFinite(n)?n:0; 219 + var r=el.getBoundingClientRect(); 220 + 221 + return ( 222 + r.width>=(minW||1)&& 223 + r.height>=(minH||1) 224 + ); 250 250 } 251 251 252 - function norm (value){253 - return String( value||"")227 + function normalizeText(text){ 228 + return String(text||"") 254 254 .replace(/\s+/g," ") 255 255 .trim() 256 256 .toUpperCase(); 257 257 } 258 258 259 - function visible(el){ 260 - if(!el||el.nodeType!==1)return false; 234 + function excluded(el){ 235 + return ( 236 + !el.matches|| 237 + el.matches( 238 + "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]" 239 + ) 240 + ); 241 + } 261 261 262 - var style=getComputedStyle(el); 263 - var rect=el.getBoundingClientRect(); 243 + /* ---------- Custom coloured callouts ---------- */ 264 264 245 + function nativeCallout(el){ 246 + var c= 247 + typeof el.className==="string" 248 + ? el.className.toLowerCase() 249 + : ""; 250 + 265 265 return ( 266 - style.display!=="none"&& 267 - style.visibility!=="hidden"&& 268 - rect.width>20&& 269 - rect.height>4 252 + /(^|\s)(infomessage|warningmessage|successmessage|errormessage)(\s|$)/.test(c) 270 270 ); 271 271 } 272 272 273 - function saveStyle(el,map,property){ 256 + function customCallout(el){ 257 + if(!visible(el,220,42)||excluded(el))return false; 258 + 259 + var r=el.getBoundingClientRect(); 260 + 261 + if(r.height>520)return false; 262 + 263 + var s=getComputedStyle(el); 264 + 265 + var bg= 266 + s.backgroundColor&& 267 + s.backgroundColor!=="rgba(0, 0, 0, 0)"&& 268 + s.backgroundColor!=="transparent"&& 269 + s.backgroundColor!=="rgb(255, 255, 255)"; 270 + 271 + var left= 272 + num(s.borderLeftWidth); 273 + 274 + return ( 275 + bg&& 276 + left>=2 277 + ); 278 + } 279 + 280 + function harmoniseCustomCallouts(){ 281 + Array.from( 282 + root.querySelectorAll( 283 + "div,aside,section" 284 + ) 285 + ).forEach(function(el){ 286 + if(nativeCallout(el))return; 287 + if(!customCallout(el))return; 288 + 289 + var s=getComputedStyle(el); 290 + 291 + el.setAttribute( 292 + "data-sn-callout-harmonized", 293 + "1" 294 + ); 295 + 296 + if( 297 + s.borderLeftColor 298 + ){ 299 + el.style.setProperty( 300 + "--sn-callout-accent", 301 + s.borderLeftColor 302 + ); 303 + } 304 + }); 305 + } 306 + 307 + /* ---------- Restore only values V7 itself changed ---------- */ 308 + 309 + function saveOriginal(el,map,property){ 274 274 if(map.has(el))return; 275 275 276 276 map.set(el,{ 277 - value:el.style.getPropertyValue(property), 278 - priority:el.style.getPropertyPriority(property) 313 + value: 314 + el.style.getPropertyValue( 315 + property 316 + ), 317 + priority: 318 + el.style.getPropertyPriority( 319 + property 320 + ) 279 279 }); 280 280 } 281 281 282 - function restore Style(el,map,property){324 + function restoreOriginal(el,map,property){ 283 283 var original=map.get(el); 284 284 285 285 if(original&&original.value){ ... ... @@ -289,845 +289,770 @@ 289 289 original.priority||"" 290 290 ); 291 291 }else{ 292 - el.style.removeProperty(property); 334 + el.style.removeProperty( 335 + property 336 + ); 293 293 } 294 294 } 295 295 296 296 function resetRuntime(){ 297 - managedHeight.forEach(function(el){298 - restore Style(341 + heightManaged.forEach(function(el){ 342 + restoreOriginal( 299 299 el, 300 - originalHeight, 344 + originalMinHeight, 301 301 "min-height" 302 302 ); 347 + 303 303 el.removeAttribute( 304 - "data-sn- master-equal-height"349 + "data-sn-equal-height-managed" 305 305 ); 306 306 }); 307 307 308 - managedMargin.forEach(function(el){309 - restore Style(353 + sectionManaged.forEach(function(el){ 354 + restoreOriginal( 310 310 el, 311 - originalMargin, 356 + originalMarginTop, 312 312 "margin-top" 313 313 ); 359 + 314 314 el.removeAttribute( 315 - "data-sn- master-first-row"361 + "data-sn-first-section-aligned" 316 316 ); 317 317 }); 318 318 319 - managedHeight.clear(); 320 - managedMargin.clear(); 321 - } 365 + contentManaged.forEach(function(el){ 366 + restoreOriginal( 367 + el, 368 + originalMarginTop, 369 + "margin-top" 370 + ); 322 322 323 - function themeFor(text){ 324 - var value=norm(text); 372 + el.removeAttribute( 373 + "data-sn-first-content-aligned" 374 + ); 375 + }); 325 325 326 - for(var i=0;i<THEMES.length;i++){ 327 - for(var j=0;j<THEMES[i].labels.length;j++){ 328 - var label=THEMES[i].labels[j]; 329 - 330 - if( 331 - value===label|| 332 - value.indexOf(label+" ")===0|| 333 - value.indexOf(label+" -")===0|| 334 - value.indexOf(label+" ·")===0 335 - ){ 336 - return THEMES[i]; 337 - } 338 - } 339 - } 340 - 341 - return null; 377 + heightManaged.clear(); 378 + sectionManaged.clear(); 379 + contentManaged.clear(); 342 342 } 343 343 344 - /* ======================================================= 345 - PLACEHOLDER BADGE 346 - ======================================================= */ 382 + /* ---------- Card detection ---------- */ 347 347 348 - function applyPlaceholderBadge(){ 349 - if(!PLACEHOLDER)return; 384 + function namedLikeBox(el){ 385 + var c= 386 + typeof el.className==="string" 387 + ? el.className 388 + : ""; 350 350 390 + return /(^|[\s_-])(box|card|tile|panel|role|check|service|source|call|area|detail|resource|topic|warn|info)([\s_-]|$)/i.test(c); 391 + } 392 + 393 + function boxLike(el){ 351 351 if( 352 - document.querySelector( 353 - ".sn-coming-soon-badge" 354 - ) 395 + !visible(el,MIN_W,MIN_H)|| 396 + excluded(el) 355 355 ){ 356 - return; 398 + return false; 357 357 } 358 358 359 - var title= 360 - document.querySelector( 361 - "#document-title" 362 - )|| 363 - document.querySelector( 364 - "h1" 365 - ); 401 + var s=getComputedStyle(el); 402 + var r=el.getBoundingClientRect(); 366 366 367 - if(!title)return; 404 + var border= 405 + num(s.borderTopWidth)+ 406 + num(s.borderRightWidth)+ 407 + num(s.borderBottomWidth)+ 408 + num(s.borderLeftWidth); 368 368 369 - var badge= 370 - document.createElement( 371 - "span" 372 - ); 373 - 374 - badge.className= 375 - "sn-coming-soon-badge"; 376 - 377 - badge.textContent= 378 - PLACEHOLDER_LABEL; 379 - 380 - badge.setAttribute( 381 - "aria-label", 382 - PLACEHOLDER_LABEL 410 + var radius=Math.max( 411 + num(s.borderTopLeftRadius), 412 + num(s.borderTopRightRadius), 413 + num(s.borderBottomLeftRadius), 414 + num(s.borderBottomRightRadius) 383 383 ); 384 384 385 - title.appendChild(386 - ba dge387 - ) ;388 - }417 + var bg= 418 + s.backgroundColor&& 419 + s.backgroundColor!=="rgba(0, 0, 0, 0)"&& 420 + s.backgroundColor!=="transparent"; 389 389 390 - /*=======================================================391 - DETAILPAGE OWN-ACCENT PROPAGATION392 - == ===================================================== */422 + var shadow= 423 + s.boxShadow&& 424 + s.boxShadow!=="none"; 393 393 394 - function parseRGB(value){ 395 - var match=String(value||"").match( 396 - /rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)/i 426 + return ( 427 + namedLikeBox(el)|| 428 + border>=1|| 429 + (bg&&radius>=3)|| 430 + (shadow&&r.width>=180) 397 397 ); 398 - 399 - if(!match)return null; 400 - 401 - return [ 402 - Number(match[1]), 403 - Number(match[2]), 404 - Number(match[3]) 405 - ]; 406 406 } 407 407 408 - function distance(a,b){ 409 - return Math.sqrt( 410 - Math.pow(a[0]-b[0],2)+ 411 - Math.pow(a[1]-b[1],2)+ 412 - Math.pow(a[2]-b[2],2) 413 - ); 414 - } 434 + function pickTarget(child){ 435 + if(!visible(child,MIN_W,MIN_H))return null; 415 415 416 - function paletteMatch(cssColor){ 417 - var rgb=parseRGB(cssColor); 437 + if(boxLike(child))return child; 418 418 419 - if(!rgb)return null; 439 + var cr=child.getBoundingClientRect(); 440 + var q=[]; 420 420 421 - var palette=[ 422 - {hex:"#21b6d7",rgb:[33,182,215]}, 423 - {hex:"#e94b13",rgb:[233,75,19]}, 424 - {hex:"#f0aa00",rgb:[240,170,0]}, 425 - {hex:"#38b76a",rgb:[56,183,106]} 426 - ]; 442 + Array.from(child.children||[]).forEach(function(el){ 443 + q.push({el:el,depth:1}); 444 + }); 427 427 428 428 var best=null; 429 - var best Distance=Infinity;447 + var bestScore=-Infinity; 430 430 431 - palette.forEach(function(item){ 432 - var d=distance(rgb,item.rgb); 449 + while(q.length){ 450 + var item=q.shift(); 451 + var el=item.el; 433 433 434 - if(d<bestDistance){ 435 - best=item; 436 - bestDistance=d; 437 - } 438 - }); 453 + if(!visible(el,MIN_W,MIN_H))continue; 439 439 440 - return bestDistance<=30 441 - ?best 442 - :null; 443 - } 455 + var r=el.getBoundingClientRect(); 444 444 445 - function propagateDetailAccents(){ 446 - if(PAGE_KIND!=="detail")return; 447 - 448 - Array.from( 449 - root.querySelectorAll( 450 - ".arsn-call,.dmp-call,.ido-call,.pp-call,"+ 451 - ".arsn-source,.dmp-source,.ido-source,.pp-source" 452 - ) 453 - ).forEach(function(el){ 454 - if(!visible(el))return; 455 - 456 - var style=getComputedStyle(el); 457 - 458 458 if( 459 - num(style.borderTopWidth)>=2 458 + r.width>=cr.width*.68&& 459 + boxLike(el) 460 460 ){ 461 - var match= 462 - paletteMatch( 463 - style.borderTopColor 461 + var widthFit= 462 + 1-Math.min( 463 + 1, 464 + Math.abs(cr.width-r.width)/ 465 + Math.max(1,cr.width) 464 464 ); 465 465 466 - if(match){ 467 - el.style.setProperty( 468 - "border-left", 469 - "4px solid "+match.hex, 470 - "important" 468 + var topFit= 469 + 1-Math.min( 470 + 1, 471 + Math.abs(cr.top-r.top)/100 471 471 ); 473 + 474 + var score= 475 + widthFit*6+ 476 + topFit*3+ 477 + Math.min(r.height,900)/450+ 478 + Math.min(r.width*r.height,900000)/900000; 479 + 480 + if(score>bestScore){ 481 + best=el; 482 + bestScore=score; 472 472 } 473 473 } 474 - }); 475 475 476 - // Warning families: explicit safety override. 477 - Array.from( 478 - root.querySelectorAll( 479 - ".arsn-warn,.dmp-warn,.ido-warn,.pp-warn,"+ 480 - ".warn,.warning,.warningmessage,.errormessage" 481 - ) 482 - ).forEach(function(el){ 483 - if(!visible(el))return; 486 + if(item.depth<SEARCH_DEPTH){ 487 + Array.from(el.children||[]).forEach(function(next){ 488 + q.push({ 489 + el:next, 490 + depth:item.depth+1 491 + }); 492 + }); 493 + } 494 + } 484 484 485 - el.style.setProperty( 486 - "border-left", 487 - "4px solid #e94b13", 488 - "important" 489 - ); 490 - }); 496 + return best; 497 + } 491 491 492 - // Info families: explicit orientation override. 493 - Array.from( 494 - root.querySelectorAll( 495 - ".arsn-info,.dmp-info,.ido-info,.pp-info,.infomessage" 496 - ) 497 - ).forEach(function(el){ 498 - if(!visible(el))return; 499 + function groupRows(entries){ 500 + var groups=[]; 499 499 500 - el.style.setProperty( 501 - "border-left", 502 - "4px solid #21b6d7", 503 - "important" 504 - ); 505 - }); 506 - } 502 + entries 503 + .slice() 504 + .sort(function(a,b){ 505 + return ( 506 + a.rect.top-b.rect.top|| 507 + a.rect.left-b.rect.left 508 + ); 509 + }) 510 + .forEach(function(entry){ 511 + var group=null; 507 507 508 - /* ======================================================= 509 - OVERVIEW SEMANTIC THEME PALETTE 510 - ======================================================= */ 513 + for(var i=0;i<groups.length;i++){ 514 + if( 515 + Math.abs( 516 + groups[i].top- 517 + entry.rect.top 518 + )<=ROW_TOLERANCE 519 + ){ 520 + group=groups[i]; 521 + break; 522 + } 523 + } 511 511 512 - function smallestThemeHeaders(){ 513 - return Array.from( 514 - root.querySelectorAll( 515 - "div,span,p,strong,h3,h4,h5,h6" 516 - ) 517 - ).filter(function(el){ 518 - if(!visible(el))return false; 519 - if(!themeFor(el.textContent))return false; 525 + if(!group){ 526 + group={ 527 + top:entry.rect.top, 528 + entries:[] 529 + }; 530 + groups.push(group); 531 + } 520 520 521 - return !Array.from( 522 - el.children||[] 523 - ).some(function(child){ 524 - return !!themeFor( 525 - child.textContent 526 - ); 533 + group.entries.push(entry); 527 527 }); 528 - }); 535 + 536 + return groups; 529 529 } 530 530 531 - function findOverviewCard(header){ 532 - var node=header.parentElement; 533 - var candidates=[]; 539 + function validRow(group){ 540 + if(group.entries.length<2)return false; 534 534 535 - while(node&&node!==root){ 536 - var rect=node.getBoundingClientRect(); 537 - var style=getComputedStyle(node); 542 + var lefts= 543 + group.entries 544 + .map(function(e){return e.rect.left;}) 545 + .sort(function(a,b){return a-b;}); 538 538 539 - var border= 540 - num(style.borderTopWidth)+ 541 - num(style.borderRightWidth)+ 542 - num(style.borderBottomWidth)+ 543 - num(style.borderLeftWidth); 547 + if( 548 + lefts[lefts.length-1]- 549 + lefts[0]< 550 + 80 551 + ){ 552 + return false; 553 + } 544 544 545 - if( 546 - rect.width>=220&& 547 - rect.width<=800&& 548 - rect.height>=120&& 549 - border>=1 550 - ){ 551 - candidates.push(node); 552 - } 555 + var widths= 556 + group.entries 557 + .map(function(e){return e.rect.width;}) 558 + .filter(function(w){return w>0;}); 553 553 554 - node=node.parentElement; 555 - } 560 + if(widths.length<2)return false; 556 556 557 - if(!candidates.length)return null; 562 + var minW= 563 + Math.min.apply(Math,widths); 558 558 559 - candidates.sort(function(a,b){ 560 - return ( 561 - b.getBoundingClientRect().height- 562 - a.getBoundingClientRect().height 565 + var maxW= 566 + Math.max.apply(Math,widths); 567 + 568 + return ( 569 + maxW/ 570 + Math.max(1,minW)<= 571 + 1.9 572 + ); 573 + } 574 + 575 + /* ---------- Known ARSN first section bars ---------- */ 576 + 577 + function knownBar(el){ 578 + var text= 579 + normalizeText( 580 + el.textContent 563 563 ); 564 - }); 565 565 566 - return candidates[0]; 583 + return ( 584 + text==="HIER STARTEN"|| 585 + text==="ORGANISIEREN & DOKUMENTIEREN"|| 586 + text==="ENTSCHEIDEN"|| 587 + text==="START HERE"|| 588 + text==="GET STARTED"|| 589 + text==="ORGANISE & DOCUMENT"|| 590 + text==="ORGANIZE & DOCUMENT"|| 591 + text==="DECIDE" 592 + ); 567 567 } 568 568 569 - function rowCandidates(link,card){ 570 - var result=[]; 595 + function findKnownBar(card){ 571 571 var cardRect= 572 572 card.getBoundingClientRect(); 573 573 574 - var node=link; 599 + var rows= 600 + Array.from( 601 + card.querySelectorAll( 602 + "div,p,span,strong,h3,h4,h5,h6" 603 + ) 604 + ) 605 + .filter(function(el){ 606 + if(!visible(el,20,6))return false; 607 + if(!knownBar(el))return false; 575 575 576 - while(node&&node!==card){ 577 - if(visible(node)){ 578 - var rect= 579 - node.getBoundingClientRect(); 609 + var r=el.getBoundingClientRect(); 580 580 581 - if( 582 - rect.height<=105&& 583 - rect.width>= 584 - cardRect.width*.50&& 585 - rect.width<= 586 - cardRect.width*1.03 587 - ){ 588 - result.push(node); 589 - } 590 - } 611 + var rel= 612 + r.top- 613 + cardRect.top; 591 591 592 - node=node.parentElement; 593 - } 594 - 595 - return result; 596 - } 597 - 598 - function chooseOuterRow( 599 - candidates, 600 - link 601 - ){ 602 - if(!candidates.length){ 603 - return link; 604 - } 605 - 606 - var bordered= 607 - candidates.filter(function(el){ 608 608 return ( 609 - num( 610 - getComputedStyle(el) 611 - .borderLeftWidth 612 - )>=1 616 + rel>=35&& 617 + rel<= 618 + cardRect.height*.75 613 613 ); 620 + }) 621 + .sort(function(a,b){ 622 + return ( 623 + a.getBoundingClientRect().top- 624 + b.getBoundingClientRect().top 625 + ); 614 614 }); 615 615 616 - var pool= 617 - bordered.length 618 - ?bordered 619 - :candidates; 628 + return rows[0]||null; 629 + } 620 620 621 - pool.sort(function(a,b){ 622 - var ar= 623 - a.getBoundingClientRect(); 631 + function alignKnownBars(cards){ 632 + var rows= 633 + cards.map(function(card){ 634 + var bar= 635 + findKnownBar(card); 624 624 625 - var br= 626 - b.getBoundingClientRect(); 637 + if(!bar)return null; 627 627 628 - return ( 629 - ar.left-br.left|| 630 - br.width-ar.width 631 - ); 632 - }); 639 + var cr= 640 + card.getBoundingClientRect(); 633 633 634 - r eturnpool[0]||link;635 - }642 + var br= 643 + bar.getBoundingClientRect(); 636 636 637 - function applyOverviewPalette(){ 638 - if(PAGE_KIND!=="overview"){ 639 - return []; 645 + return { 646 + bar:bar, 647 + relativeTop: 648 + br.top- 649 + cr.top 650 + }; 651 + }); 652 + 653 + if( 654 + rows.some(function(row){ 655 + return !row; 656 + }) 657 + ){ 658 + return false; 640 640 } 641 641 642 - var headers= 643 - smallestThemeHeaders() 644 - .map(function(el){ 645 - return { 646 - el:el, 647 - theme: 648 - themeFor( 649 - el.textContent 650 - ), 651 - card: 652 - findOverviewCard( 653 - el 654 - ) 655 - }; 661 + var target= 662 + Math.max.apply( 663 + Math, 664 + rows.map(function(row){ 665 + return row.relativeTop; 656 656 }) 657 - .filter(function(row){ 658 - return !!row.card; 659 - }); 667 + ); 660 660 661 - var unique=[]; 662 - var seenHeaders=new Set(); 669 + rows.forEach(function(row){ 670 + var delta= 671 + target- 672 + row.relativeTop; 663 663 664 - headers.forEach(function(row){ 665 - var key= 666 - row.theme.name+ 667 - "|"+ 668 - Math.round( 669 - row.card 670 - .getBoundingClientRect() 671 - .left 672 - )+ 673 - "|"+ 674 - Math.round( 675 - row.el 676 - .getBoundingClientRect() 677 - .top 678 - ); 674 + if(delta<=1)return; 679 679 680 - if(!seenHeaders.has(key)){681 - seenHeaders.add(key);682 - unique.push(row);683 - }684 - });676 + saveOriginal( 677 + row.bar, 678 + originalMarginTop, 679 + "margin-top" 680 + ); 685 685 686 - unique.forEach(function(row){ 687 - var headerRect= 688 - row.el 689 - .getBoundingClientRect(); 682 + var current= 683 + num( 684 + getComputedStyle( 685 + row.bar 686 + ).marginTop 687 + ); 690 690 691 - row.el.style.setProperty( 692 - "background", 693 - row.theme.bg, 694 - "important" 689 + row.bar.style.setProperty( 690 + "margin-top", 691 + ( 692 + current+ 693 + delta 694 + )+"px" 695 695 ); 696 696 697 - row.el.style.setProperty( 698 - "color", 699 - row.theme.text, 700 - "important" 697 + row.bar.setAttribute( 698 + "data-sn-first-section-aligned", 699 + "7" 701 701 ); 702 702 703 - row.el.style.setProperty( 704 - "text-align", 705 - "left", 706 - "important" 702 + sectionManaged.add( 703 + row.bar 707 707 ); 705 + }); 708 708 709 - row.el.style.setProperty( 710 - "word-spacing", 711 - "normal", 712 - "important" 713 - ); 707 + return true; 708 + } 714 714 715 - var later= 716 - unique 717 - .filter(function(other){ 718 - return ( 719 - other.card===row.card&& 720 - other.el 721 - .getBoundingClientRect() 722 - .top> 723 - headerRect.top+2 724 - ); 725 - }) 726 - .sort(function(a,b){ 727 - return ( 728 - a.el 729 - .getBoundingClientRect() 730 - .top- 731 - b.el 732 - .getBoundingClientRect() 733 - .top 734 - ); 735 - }); 710 + /* ---------- Generic first content after heading ---------- */ 736 736 737 - var stopTop= 738 - later.length 739 - ?later[0].el 740 - .getBoundingClientRect() 741 - .top 742 - :Infinity; 712 + function heading(card){ 713 + var cr= 714 + card.getBoundingClientRect(); 743 743 716 + var rows= 744 744 Array.from( 745 - row.card.querySelectorAll("a") 746 - ).forEach(function(link){ 747 - if(!visible(link))return; 718 + card.querySelectorAll( 719 + "h1,h2,h3,h4,h5,h6,.box-title,[role=heading]" 720 + ) 721 + ) 722 + .filter(function(el){ 723 + if(!visible(el,20,8))return false; 748 748 749 - var rect= 750 - link.getBoundingClientRect(); 725 + var r=el.getBoundingClientRect(); 751 751 752 - if( 753 - rect.top<= 754 - headerRect.bottom-2|| 755 - rect.top>= 756 - stopTop-2 757 - ){ 758 - return; 759 - } 727 + var rel= 728 + r.top- 729 + cr.top; 760 760 761 - var candidates= 762 - rowCandidates( 763 - link, 764 - row.card 765 - ); 766 - 767 - var target= 768 - chooseOuterRow( 769 - candidates, 770 - link 771 - ); 772 - 773 - candidates.forEach(function(el){ 774 - el.style.setProperty( 775 - "border-left", 776 - "0 solid transparent", 777 - "important" 778 - ); 779 - }); 780 - 781 - target.style.setProperty( 782 - "border-left", 783 - "3px solid "+ 784 - row.theme.accent, 785 - "important" 731 + return ( 732 + rel>=0&& 733 + rel<= 734 + Math.min( 735 + 160, 736 + cr.height*.45 737 + ) 786 786 ); 787 - 788 - target.style.setProperty(789 - "box-sizing",790 - "border-box",791 - "important"739 + }) 740 + .sort(function(a,b){ 741 + return ( 742 + a.getBoundingClientRect().top- 743 + b.getBoundingClientRect().top 792 792 ); 793 793 }); 794 - }); 795 795 796 - return unique;747 + return rows[0]||null; 797 797 } 798 798 799 - /* ======================================================= 800 - OVERVIEW CARD HEIGHT + FIRST THEMATIC ROW 801 - ======================================================= */ 750 + function firstContent(card,h){ 751 + if(!h)return null; 802 802 803 - function alignOverviewCards(headers){ 804 - if( 805 - PAGE_KIND!=="overview"|| 806 - window.innerWidth<=MOBILE_MAX 807 - ){ 808 - return; 809 - } 753 + var cr= 754 + card.getBoundingClientRect(); 810 810 811 - var cards=[];812 - varseen=new Set();756 + var hr= 757 + h.getBoundingClientRect(); 813 813 814 - headers.forEach(function(row){ 815 - if(!seen.has(row.card)){ 816 - seen.add(row.card); 817 - cards.push(row.card); 818 - } 819 - }); 759 + var rows= 760 + Array.from( 761 + card.querySelectorAll( 762 + "p,div,ul,ol,dl,blockquote" 763 + ) 764 + ) 765 + .filter(function(el){ 766 + if( 767 + el===h|| 768 + h.contains(el)|| 769 + el.contains(h) 770 + ){ 771 + return false; 772 + } 820 820 821 - if(cards.length<2){ 822 - return; 823 - } 774 + if(!visible(el,30,8))return false; 824 824 825 - // Group cards by actual top position. 826 - var groups=[]; 776 + var text= 777 + String(el.textContent||"") 778 + .replace(/\s+/g," ") 779 + .trim(); 827 827 828 - cards.forEach(function(card){ 829 - var top= 830 - card.getBoundingClientRect().top; 781 + if(text.length<3)return false; 831 831 832 - var group=null;783 + var r=el.getBoundingClientRect(); 833 833 834 - for(var i=0;i<groups.length;i++){ 835 835 if( 836 - Math.abs( 837 - groups[i].top-top 838 - )<=ROW_TOLERANCE 786 + r.top< 787 + hr.bottom-1 839 839 ){ 840 - group=groups[i]; 841 - break; 789 + return false; 842 842 } 843 - } 844 844 845 - if(!group){ 846 - group={ 847 - top:top, 848 - cards:[] 849 - }; 850 - groups.push(group); 851 - } 792 + if( 793 + r.top-cr.top> 794 + Math.min( 795 + 280, 796 + cr.height*.65 797 + ) 798 + ){ 799 + return false; 800 + } 852 852 853 - group.cards.push(card); 854 - }); 802 + if( 803 + r.height> 804 + cr.height*.58 805 + ){ 806 + return false; 807 + } 855 855 856 - groups.forEach(function(group){ 857 - if(group.cards.length<2){ 858 - return; 859 - } 809 + return true; 810 + }) 811 + .sort(function(a,b){ 812 + var ar= 813 + a.getBoundingClientRect(); 860 860 861 - var firstHeaders= 862 - group.cards.map(function(card){ 863 - var candidates= 864 - headers 865 - .filter(function(row){ 866 - return row.card===card; 867 - }) 868 - .sort(function(a,b){ 869 - return ( 870 - a.el 871 - .getBoundingClientRect() 872 - .top- 873 - b.el 874 - .getBoundingClientRect() 875 - .top 876 - ); 877 - }); 815 + var br= 816 + b.getBoundingClientRect(); 878 878 879 - return candidates.length 880 - ?candidates[0] 881 - :null; 882 - }); 818 + return ( 819 + ar.top-br.top|| 820 + ar.height-br.height 821 + ); 822 + }); 883 883 884 - if( 885 - !firstHeaders.some(function(row){ 886 - return !row; 887 - }) 888 - ){ 889 - var targetTop= 890 - Math.max.apply( 891 - Math, 892 - firstHeaders.map(function(row){ 893 - return ( 894 - row.el 895 - .getBoundingClientRect() 896 - .top- 897 - row.card 898 - .getBoundingClientRect() 899 - .top 900 - ); 901 - }) 902 - ); 824 + return rows[0]||null; 825 + } 903 903 904 - firstHeaders.forEach(function(row){ 905 - var relativeTop= 906 - row.el 907 - .getBoundingClientRect() 908 - .top- 909 - row.card 910 - .getBoundingClientRect() 911 - .top; 827 + function alignGeneric(cards){ 828 + var rows= 829 + cards.map(function(card){ 830 + var h= 831 + heading(card); 912 912 913 - var delta= 914 - targetTop-relativeTop; 833 + var c= 834 + firstContent( 835 + card, 836 + h 837 + ); 915 915 916 - if(delta>1){ 917 - saveStyle( 918 - row.el, 919 - originalMargin, 920 - "margin-top" 921 - ); 839 + if(!h||!c)return null; 922 922 923 - var current= 924 - num( 925 - getComputedStyle( 926 - row.el 927 - ).marginTop 928 - ); 841 + var cr= 842 + card.getBoundingClientRect(); 929 929 930 - row.el.style.setProperty( 931 - "margin-top", 932 - ( 933 - current+delta 934 - )+"px" 935 - ); 844 + var rr= 845 + c.getBoundingClientRect(); 936 936 937 - row.el.setAttribute( 938 - "data-sn-master-first-row", 939 - "1" 940 - ); 847 + return { 848 + content:c, 849 + relativeTop: 850 + rr.top-cr.top 851 + }; 852 + }); 941 941 942 - managedMargin.add( 943 - row.el 944 - ); 945 - } 946 - }); 947 - } 854 + if( 855 + rows.some(function(row){ 856 + return !row; 857 + }) 858 + ){ 859 + return false; 860 + } 948 948 949 - var maxHeight=0; 862 + var target= 863 + Math.max.apply( 864 + Math, 865 + rows.map(function(row){ 866 + return row.relativeTop; 867 + }) 868 + ); 950 950 951 - group.cards.forEach(function(card){ 952 - maxHeight= 953 - Math.max( 954 - maxHeight, 955 - card 956 - .getBoundingClientRect() 957 - .height 958 - ); 959 - }); 870 + rows.forEach(function(row){ 871 + var delta= 872 + target- 873 + row.relativeTop; 960 960 961 - maxHeight= 962 - Math.ceil(maxHeight); 875 + if(delta<=1)return; 963 963 964 - group.cards.forEach(function(card){ 965 - saveStyle( 966 - card, 967 - originalHeight, 968 - "min-height" 969 - ); 877 + saveOriginal( 878 + row.content, 879 + originalMarginTop, 880 + "margin-top" 881 + ); 970 970 971 - card.style.setProperty( 972 - "min-height", 973 - maxHeight+"px" 883 + var current= 884 + num( 885 + getComputedStyle( 886 + row.content 887 + ).marginTop 974 974 ); 975 975 976 - card.setAttribute( 977 - "data-sn-master-equal-height", 978 - "1" 979 - ); 890 + row.content.style.setProperty( 891 + "margin-top", 892 + ( 893 + current+ 894 + delta 895 + )+"px" 896 + ); 980 980 981 - managedHeight.add( 982 - card 983 - ); 984 - }); 898 + row.content.setAttribute( 899 + "data-sn-first-content-aligned", 900 + "7" 901 + ); 902 + 903 + contentManaged.add( 904 + row.content 905 + ); 985 985 }); 907 + 908 + return true; 986 986 } 987 987 988 - /* ======================================================= 989 - DETAIL GRID EQUAL HEIGHT, DESKTOP ONLY 990 - ======================================================= */ 911 + function applyRow(group){ 912 + if(!validRow(group))return false; 991 991 992 - function equaliseDetailGrids(){ 914 + var cards=[]; 915 + var seen=new Set(); 916 + 917 + group.entries.forEach(function(entry){ 918 + if(!seen.has(entry.target)){ 919 + seen.add(entry.target); 920 + cards.push(entry.target); 921 + } 922 + }); 923 + 924 + if(cards.length<2)return false; 925 + 993 993 if( 994 - PAGE_KIND!=="detail"|| 995 - window.innerWidth<=MOBILE_MAX 927 + !alignKnownBars(cards) 996 996 ){ 997 - return;929 + alignGeneric(cards); 998 998 } 999 999 1000 - var selectors=[ 1001 - ".arsn-grid", 1002 - ".arsn-grid-2", 1003 - ".arsn-grid-3", 1004 - ".dmp-grid", 1005 - ".ido-grid", 1006 - ".pp-grid" 1007 - ]; 932 + var maxHeight=0; 1008 1008 1009 - selectors.forEach(function(selector){ 1010 - Array.from( 1011 - root.querySelectorAll(selector) 1012 - ).forEach(function(grid){ 1013 - var children= 1014 - Array.from( 1015 - grid.children||[] 1016 - ).filter(visible); 934 + cards.forEach(function(card){ 935 + maxHeight= 936 + Math.max( 937 + maxHeight, 938 + card.getBoundingClientRect().height 939 + ); 940 + }); 1017 1017 1018 - if(children.length<2){ 1019 - return; 1020 - } 942 + maxHeight= 943 + Math.ceil( 944 + maxHeight 945 + ); 1021 1021 1022 - vargroups=[];947 + if(maxHeight<MIN_H)return false; 1023 1023 1024 - children.forEach(function(child){ 1025 - var top= 1026 - child 1027 - .getBoundingClientRect() 1028 - .top; 949 + cards.forEach(function(card){ 950 + saveOriginal( 951 + card, 952 + originalMinHeight, 953 + "min-height" 954 + ); 1029 1029 1030 - var group=null; 956 + card.style.setProperty( 957 + "min-height", 958 + maxHeight+"px" 959 + ); 1031 1031 1032 - for(var i=0;i<groups.length;i++){ 1033 - if( 1034 - Math.abs( 1035 - groups[i].top-top 1036 - )<=ROW_TOLERANCE 1037 - ){ 1038 - group=groups[i]; 1039 - break; 1040 - } 1041 - } 961 + card.setAttribute( 962 + "data-sn-equal-height-managed", 963 + "7" 964 + ); 1042 1042 1043 - if(!group){ 1044 - group={ 1045 - top:top, 1046 - items:[] 1047 - }; 1048 - groups.push(group); 1049 - } 966 + heightManaged.add(card); 967 + }); 1050 1050 1051 - group.items.push(child);1052 - });969 + return true; 970 + } 1053 1053 1054 - groups.forEach(function(group){ 1055 - if(group.items.length<2){ 1056 - return; 1057 - } 972 + function calculate(force){ 973 + if(applying)return; 1058 1058 1059 - var maxHeight=0; 975 + var width= 976 + Math.round( 977 + window.innerWidth 978 + ); 1060 1060 1061 - group.items.forEach(function(item){ 1062 - maxHeight= 1063 - Math.max( 1064 - maxHeight, 1065 - item 1066 - .getBoundingClientRect() 1067 - .height 1068 - ); 1069 - }); 980 + var meaningful= 981 + lastWidth<0|| 982 + Math.abs( 983 + width- 984 + lastWidth 985 + )>= 986 + MIN_WIDTH_CHANGE; 1070 1070 1071 - maxHeight= 1072 - Math.ceil(maxHeight); 988 + if( 989 + hasApplied&& 990 + !force&& 991 + !meaningful 992 + ){ 993 + return; 994 + } 1073 1073 1074 - group.items.forEach(function(item){ 1075 - saveStyle( 1076 - item, 1077 - originalHeight, 1078 - "min-height" 1079 - ); 996 + applying=true; 1080 1080 1081 - item.style.setProperty( 1082 - "min-height", 1083 - maxHeight+"px" 1084 - ); 998 + try{ 999 + harmoniseCustomCallouts(); 1085 1085 1086 - item.setAttribute(1087 - "data-sn-master-equal-height",1088 - "1"1089 - );1001 + if(width<=MOBILE_MAX){ 1002 + if(hasApplied){ 1003 + resetRuntime(); 1004 + } 1090 1090 1091 - managedHeight.add(item); 1092 - }); 1006 + hasApplied=false; 1007 + lastWidth=width; 1008 + return; 1009 + } 1010 + 1011 + if(hasApplied){ 1012 + resetRuntime(); 1013 + } 1014 + 1015 + var parents= 1016 + Array.from( 1017 + root.querySelectorAll("*") 1018 + ) 1019 + .filter(function(parent){ 1020 + return ( 1021 + visible( 1022 + parent, 1023 + MIN_W, 1024 + MIN_H 1025 + )&& 1026 + parent.children&& 1027 + parent.children.length>=2&& 1028 + parent.children.length<= 1029 + MAX_PARENT_CHILDREN 1030 + ); 1093 1093 }); 1094 - }); 1095 - }); 1096 - } 1097 1097 1098 - /* ======================================================= 1099 - RUN / RESPONSIVE SCHEDULING 1100 - ======================================================= */ 1033 + var touched= 1034 + new Set(); 1101 1101 1102 - function run(){1103 - if(running)return;1036 + parents.forEach(function(parent){ 1037 + var entries=[]; 1104 1104 1105 - running=true; 1039 + Array.from( 1040 + parent.children 1041 + ).forEach(function(child){ 1042 + if( 1043 + !visible( 1044 + child, 1045 + MIN_W, 1046 + MIN_H 1047 + ) 1048 + ){ 1049 + return; 1050 + } 1106 1106 1107 - try{ 1108 - resetRuntime(); 1109 - applyPlaceholderBadge(); 1110 - propagateDetailAccents(); 1052 + var target= 1053 + pickTarget(child); 1111 1111 1112 - var headers= 1113 - applyOverviewPalette(); 1055 + if(!target)return; 1114 1114 1115 - if( 1116 - window.innerWidth> 1117 - MOBILE_MAX 1118 - ){ 1119 - alignOverviewCards( 1120 - headers 1121 - ); 1057 + entries.push({ 1058 + target:target, 1059 + rect: 1060 + target.getBoundingClientRect() 1061 + }); 1062 + }); 1122 1122 1123 - equaliseDetailGrids(); 1124 - } 1064 + groupRows( 1065 + entries 1066 + ).forEach(function(group){ 1067 + if(!validRow(group))return; 1068 + 1069 + var targets= 1070 + group.entries.map(function(entry){ 1071 + return entry.target; 1072 + }); 1073 + 1074 + if( 1075 + !targets.some(function(el){ 1076 + return !touched.has(el); 1077 + }) 1078 + ){ 1079 + return; 1080 + } 1081 + 1082 + if(applyRow(group)){ 1083 + targets.forEach(function(el){ 1084 + touched.add(el); 1085 + }); 1086 + } 1087 + }); 1088 + }); 1089 + 1090 + lastWidth=width; 1091 + hasApplied=true; 1125 1125 }finally{ 1126 - running=false;1093 + applying=false; 1127 1127 } 1128 1128 } 1129 1129 1130 - function onResize(){1097 + function resize(){ 1131 1131 if(resizeTimer){ 1132 1132 clearTimeout( 1133 1133 resizeTimer ... ... @@ -1138,40 +1138,19 @@ 1138 1138 setTimeout( 1139 1139 function(){ 1140 1140 resizeTimer=0; 1141 - run();1108 + calculate(false); 1142 1142 }, 1143 1143 RESIZE_DEBOUNCE 1144 1144 ); 1145 1145 } 1146 1146 1147 - async function waitForReady(){ 1148 - if( 1149 - document.readyState!=="complete" 1150 - ){ 1151 - await new Promise(function(resolve){ 1152 - window.addEventListener( 1153 - "load", 1154 - resolve, 1155 - {once:true} 1156 - ); 1157 - }); 1158 - } 1159 - 1160 - if( 1161 - document.fonts&& 1162 - document.fonts.ready 1163 - ){ 1164 - try{ 1165 - await document.fonts.ready; 1166 - }catch(error){} 1167 - } 1168 - 1114 + function waitImages(){ 1169 1169 var images= 1170 1170 Array.from( 1171 1171 root.querySelectorAll("img") 1172 1172 ); 1173 1173 1174 - await Promise.all(1120 + return Promise.all( 1175 1175 images.map(function(img){ 1176 1176 if(img.complete){ 1177 1177 return Promise.resolve(); ... ... @@ -1196,20 +1196,46 @@ 1196 1196 }); 1197 1197 }) 1198 1198 ); 1145 + } 1199 1199 1200 - run(); 1147 + async function initial(){ 1148 + if( 1149 + document.readyState!== 1150 + "complete" 1151 + ){ 1152 + await new Promise(function(resolve){ 1153 + addEventListener( 1154 + "load", 1155 + resolve, 1156 + {once:true} 1157 + ); 1158 + }); 1159 + } 1160 + 1161 + if( 1162 + document.fonts&& 1163 + document.fonts.ready 1164 + ){ 1165 + try{ 1166 + await document.fonts.ready; 1167 + }catch(error){} 1168 + } 1169 + 1170 + await waitImages(); 1171 + 1172 + // Exactly one initial layout calculation. 1173 + calculate(true); 1201 1201 } 1202 1202 1203 - window.addEventListener(1176 + addEventListener( 1204 1204 "resize", 1205 - onResize,1178 + resize, 1206 1206 {passive:true} 1207 1207 ); 1208 1208 1209 - waitForReady();1182 + initial(); 1210 1210 })(); 1211 1211 </script> 1212 1212 1213 -<!-- SN_SERVICE_NAVIGATOR_MASTER_STYLE_END --> 1214 -{{/html}} 1215 - 1186 +<!-- SN_HORIZONTAL_BOX_HARMONIZER_END --> 1187 +{{/html}}\n