Skip to content

Commit 120a3e2

Browse files
committed
Added background image positioning support
1 parent c931aef commit 120a3e2

6 files changed

Lines changed: 506 additions & 5 deletions

File tree

packages/scripts/dist/page-background.d.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,39 @@
11
export declare class PageBackground {
22
private pageBackground;
3+
private mutationObserver;
34
constructor();
5+
/**
6+
* Processes attribution positioning for background images by moving positioning classes
7+
* and data attributes from images to their parent column containers.
8+
*
9+
* This function handles two attribution patterns:
10+
* 1. Class-based: <img class="attribution-bottomright" src="...">
11+
* 2. Data attribute-based: <img data-background-position="bottomright" src="...">
12+
*
13+
* Examples:
14+
*
15+
* Class-based attribution:
16+
* <img class="attribution-bottomright" src="background.jpg">
17+
* → Moves "attribution-bottomright" class to parent .en__component--column
18+
*
19+
* Data attribute-based attribution:
20+
* <img data-background-position="top" src="background.jpg">
21+
* → Converts to "attribution-top" class and moves to parent .en__component--column
22+
*
23+
* Supported positioning values:
24+
* - center
25+
* - top, topcenter (these result in the same positioning)
26+
* - right, rightcenter (these result in the same positioning)
27+
* - bottom, bottomcenter (these result in the same positioning)
28+
* - left, leftcenter (these result in the same positioning)
29+
* - topright
30+
* - bottomright
31+
* - bottomleft
32+
* - topleft
33+
*/
34+
private processAttributionPositioning;
35+
private setupMutationObserver;
36+
reprocessAttributionPositioning(): void;
437
private setDataAttributes;
538
private hasVideoBackground;
639
private hasImageBackground;

packages/scripts/dist/page-background.js

Lines changed: 146 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import { ENGrid } from "./engrid";
22
export class PageBackground {
33
constructor() {
4+
var _a;
45
// @TODO: Change page-backgroundImage to page-background
56
this.pageBackground = document.querySelector(".page-backgroundImage");
7+
this.mutationObserver = null;
68
// Finds any <img> added to the "backgroundImage" ENGRid section and sets it as the "--engrid__page-backgroundImage_url" CSS Custom Property
9+
const pageBackgroundImg = (_a = this.pageBackground) === null || _a === void 0 ? void 0 : _a.querySelector("img");
710
if (this.pageBackground) {
8-
const pageBackgroundImg = this.pageBackground.querySelector("img");
911
let pageBackgroundImgDataSrc = pageBackgroundImg === null || pageBackgroundImg === void 0 ? void 0 : pageBackgroundImg.getAttribute("data-src");
1012
let pageBackgroundImgSrc = pageBackgroundImg === null || pageBackgroundImg === void 0 ? void 0 : pageBackgroundImg.src;
1113
if (this.pageBackground && pageBackgroundImgDataSrc) {
@@ -34,6 +36,149 @@ export class PageBackground {
3436
console.log("A background image set in the page was not found, any default image set in the theme on --engrid__page-backgroundImage_url will be used");
3537
}
3638
this.setDataAttributes();
39+
// Move attribution classes and data attributes from background image to parent column
40+
this.processAttributionPositioning();
41+
// Set up mutation observer to watch for DOM changes
42+
this.setupMutationObserver();
43+
}
44+
/**
45+
* Processes attribution positioning for background images by moving positioning classes
46+
* and data attributes from images to their parent column containers.
47+
*
48+
* This function handles two attribution patterns:
49+
* 1. Class-based: <img class="attribution-bottomright" src="...">
50+
* 2. Data attribute-based: <img data-background-position="bottomright" src="...">
51+
*
52+
* Examples:
53+
*
54+
* Class-based attribution:
55+
* <img class="attribution-bottomright" src="background.jpg">
56+
* → Moves "attribution-bottomright" class to parent .en__component--column
57+
*
58+
* Data attribute-based attribution:
59+
* <img data-background-position="top" src="background.jpg">
60+
* → Converts to "attribution-top" class and moves to parent .en__component--column
61+
*
62+
* Supported positioning values:
63+
* - center
64+
* - top, topcenter (these result in the same positioning)
65+
* - right, rightcenter (these result in the same positioning)
66+
* - bottom, bottomcenter (these result in the same positioning)
67+
* - left, leftcenter (these result in the same positioning)
68+
* - topright
69+
* - bottomright
70+
* - bottomleft
71+
* - topleft
72+
*/
73+
processAttributionPositioning() {
74+
if (this.pageBackground) {
75+
if (ENGrid.debug)
76+
console.log("Processing attribution positioning for background section:", this.pageBackground);
77+
// Define all supported attribution positioning classes
78+
const allowedClasses = [
79+
"attribution-center",
80+
"attribution-bottom",
81+
"attribution-bottomcenter",
82+
"attribution-bottomright",
83+
"attribution-bottomleft",
84+
"attribution-top",
85+
"attribution-topcenter",
86+
"attribution-topright",
87+
"attribution-topleft",
88+
"attribution-left",
89+
"attribution-leftcenter",
90+
"attribution-right",
91+
"attribution-rightcenter",
92+
];
93+
// Find all images in the background section (after any DOM transformations)
94+
const images = this.pageBackground.querySelectorAll("img");
95+
if (ENGrid.debug)
96+
console.log("Found images in background section:", images.length);
97+
images.forEach((img) => {
98+
// Pattern 1: Check for class-based attribution positioning
99+
// Example: <img class="attribution-bottomright" src="...">
100+
const matchedClass = allowedClasses.find((cls) => img.classList.contains(cls));
101+
// Pattern 2: Check for data attribute-based attribution positioning
102+
// Example: <img data-background-position="bottomright" src="...">
103+
const dataPosition = img.getAttribute("data-background-position");
104+
if (matchedClass) {
105+
// Handle class-based attribution positioning
106+
if (ENGrid.debug)
107+
console.log("Found attribution class on image:", matchedClass, img);
108+
const parentDiv = img.closest(".en__component--column");
109+
if (parentDiv) {
110+
// Move the class from image to parent column
111+
img.classList.remove(matchedClass);
112+
parentDiv.classList.add(matchedClass);
113+
if (ENGrid.debug)
114+
console.log("Moved attribution class from image to parent column:", matchedClass, parentDiv);
115+
}
116+
else {
117+
if (ENGrid.debug)
118+
console.log("No parent .en__component--column found for image:", img);
119+
}
120+
}
121+
else if (dataPosition) {
122+
// Handle data attribute-based attribution positioning
123+
// Convert data attribute value to attribution class format
124+
const attributionClass = `attribution-${dataPosition}`;
125+
if (ENGrid.debug)
126+
console.log("Found data-background-position on image:", dataPosition, "->", attributionClass, img);
127+
const parentDiv = img.closest(".en__component--column");
128+
if (parentDiv) {
129+
// Remove data attribute from image and add class to parent column
130+
img.removeAttribute("data-background-position");
131+
parentDiv.classList.add(attributionClass);
132+
if (ENGrid.debug)
133+
console.log("Moved data-background-position from image to parent column as class:", attributionClass, parentDiv);
134+
}
135+
else {
136+
if (ENGrid.debug)
137+
console.log("No parent .en__component--column found for image:", img);
138+
}
139+
}
140+
});
141+
}
142+
else {
143+
if (ENGrid.debug)
144+
console.log("No background section found for attribution positioning processing");
145+
}
146+
}
147+
setupMutationObserver() {
148+
if (this.pageBackground && window.MutationObserver) {
149+
this.mutationObserver = new MutationObserver((mutations) => {
150+
let shouldReprocess = false;
151+
mutations.forEach((mutation) => {
152+
// Check if nodes were added or attributes changed
153+
if (mutation.type === "childList" || mutation.type === "attributes") {
154+
shouldReprocess = true;
155+
}
156+
});
157+
if (shouldReprocess) {
158+
if (ENGrid.debug)
159+
console.log("DOM changes detected in background section, reprocessing attribution classes");
160+
// Use a small delay to ensure all changes are complete
161+
setTimeout(() => {
162+
this.processAttributionPositioning();
163+
}, 100);
164+
}
165+
});
166+
// Start observing the background section
167+
this.mutationObserver.observe(this.pageBackground, {
168+
childList: true,
169+
subtree: true,
170+
attributes: true,
171+
attributeFilter: ["class"],
172+
});
173+
if (ENGrid.debug)
174+
console.log("MutationObserver set up for background section");
175+
}
176+
}
177+
// Public method to manually trigger reprocessing
178+
reprocessAttributionPositioning() {
179+
if (ENGrid.debug)
180+
console.log("Manually reprocessing attribution positioning");
181+
this.processAttributionPositioning();
37182
}
38183
setDataAttributes() {
39184
if (this.hasVideoBackground())

0 commit comments

Comments
 (0)