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