1const BACKGROUND_POSITIONS = new Map([ 2 ['center', 'center'], 3 ['top left', 'left top'], 4 ['left top', 'left top'], 5 ['top center', 'center top'], 6 ['center top', 'center top'], 7 ['top right', 'right top'], 8 ['right top', 'right top'], 9 ['left center', 'left center'], 10 ['center left', 'left center'], 11 ['right center', 'right center'], 12 ['center right', 'right center'], 13 ['bottom left', 'left bottom'], 14 ['left bottom', 'left bottom'], 15 ['bottom center', 'center bottom'], 16 ['center bottom', 'center bottom'], 17 ['bottom right', 'right bottom'], 18 ['right bottom', 'right bottom'], 19]); 20 21const MIRROR_POSITIONS = new Map([ 22 ['left top', 'right bottom'], 23 ['center top', 'center bottom'], 24 ['right top', 'left bottom'], 25 ['left center', 'right center'], 26 ['right center', 'left center'], 27 ['left bottom', 'right top'], 28 ['center bottom', 'center top'], 29 ['right bottom', 'left top'], 30]); 31 32const FULL_WIDTH_POSITIONS = new Set(['center', 'center top', 'center bottom']); 33 34// Side-anchored positions fill the section height so the image remains visible 35// on narrow mobile viewports regardless of its natural width. 36const SIDE_CENTER_POSITIONS = new Set(['left center', 'right center']); 37 38export function toBoolean(value) { 39 return value === true || value === 'true'; 40} 41
42export function normalizeBackgroundPosition(position) { 43 const value = `${position || 'center'}`.toLowerCase(); 44 return BACKGROUND_POSITIONS.get(value) || 'center'; 45} 46 47export function getBackgroundSize(position, tileFill = false) { 48 const normalizedPosition = normalizeBackgroundPosition(position); 49 if (tileFill) return 'auto'; 50 if (FULL_WIDTH_POSITIONS.has(normalizedPosition)) return 'cover'; 51 // Side-center positions (left center / right center): fill the section height 52 // so the decoration remains visible on narrow mobile viewports. 53 if (SIDE_CENTER_POSITIONS.has(normalizedPosition)) return 'auto 100%'; 54 return 'auto'; 55} 56 57export function getMirrorBackgroundPosition(position) { 58 return MIRROR_POSITIONS.get(normalizeBackgroundPosition(position)) || 'center'; 59} 60 61export function applyBackgroundImageStyles(target, { 62 image, 63 position = 'center', 64 tileFill = false, 65}) { 66 if (!target || !image) return; 67 68 const normalizedPosition = normalizeBackgroundPosition(position); 69 target.style.backgroundImage = `url("${image}")`; 70 target.style.backgroundPosition = normalizedPosition; 71 target.style.backgroundRepeat = tileFill ? 'repeat' : 'no-repeat'; 72 target.style.backgroundSize = getBackgroundSize(normalizedPosition, tileFill); 73} 74 75export function createMirroredBackgroundLayer(className, image, position, tileFill = false) {
76 const normalizedPosition = normalizeBackgroundPosition(position); 77 if (!image || normalizedPosition === 'center') return null; 78 79 const mirror = document.createElement('div'); 80 mirror.className = className; 81 mirror.setAttribute('aria-hidden', 'true'); 82 mirror.style.position = 'absolute'; 83 mirror.style.inset = '0'; 84 mirror.style.pointerEvents = 'none'; 85 mirror.style.transform = 'rotate(180deg)'; 86 mirror.style.transformOrigin = 'center'; 87 applyBackgroundImageStyles(mirror, { 88 image, 89 // Keep the same anchor and rotate the layer 180deg so the visual result 90 // lands on the opposite edge. 91 position: normalizedPosition, 92 tileFill, 93 }); 94 return mirror; 95}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.