PageSourceSearch

https://bootcampdigital.com/wp-content/plugins/affiliate-wp/assets…iatewp-frontend-notifications.js?ver=2.36.4

js bootcampdigital.com collected 2026-10-02 04:26:31 UTC 5,148 bytes, 194 lines download raw bytes

1/**
2 * Frontend Notifications
3 *
4 * @since  2.23.0
5 * @author Andrew Munro <[email protected]>
6 */
7
8/* globals HTMLElement, affiliateWPFENotifications, customElements */
9
10/**
11 * Represents a custom notification element for AffiliateWP.
12 *
13 * @since 2.23.0
14 *
15 * This class extends HTMLElement to create a custom web component for displaying notifications.
16 * It includes functionality to dynamically set the theme based on admin settings,
17 * handle animations, and manage the display of notifications based on certain conditions.
18 */
19class AffiliateWPNotification extends HTMLElement {
20
21	/**
22	 * Constructor
23	 *
24	 * @since 2.23.0
25	 *
26	 * Constructs the AffiliateWPNotification element, initializing its shadow DOM
27	 * and cloning the template content into it.
28	 */
29	constructor() {
30
31		super();
32
33		this.attachShadow( { mode: 'open' } );
34
35		const template = document.getElementById( 'affwp-notification' );
36
37		if ( ! template ) {
38
39			window.console.error( 'Template not found' );
40			return;
41		}
42
43		this.shadowRoot.appendChild( template.content.cloneNode( true ) );
44
45		// Find and store references to dynamic parts of the template.
46		this.notificationDiv = this.shadowRoot.querySelector( '#notification' );
47	}
48
49	/**
50	 * Lifecycle hook called when the element is added to the document's DOM.
51	 *
52	 * @since 2.23.0
53	 *
54	 * It sets the theme based on admin settings, initializes CSS styling,
55	 * and sets up animations and event listeners for the notification element.
56	 */
57	connectedCallback() {
58
59		// Set the data-mode attribute based on the admin setting.
60		const notificationDiv      = this.shadowRoot.querySelector( '#notification' );
61		const adminDarkModeSetting = affiliateWPFENotifications.darkMode;
62
63		let useDarkMode = false;
64
65		if ( adminDarkModeSetting === 'dark' ) {
66			useDarkMode = true;
67		} else if ( adminDarkModeSetting === 'auto' ) {
68			useDarkMode = window.matchMedia( '(prefers-color-scheme: dark)' ).matches;
69		}
70
71		if ( notificationDiv ) {
72
73			if ( useDarkMode ) {
74				notificationDiv.setAttribute( 'data-mode', 'dark' );
75			} else {
76				notificationDiv.removeAttribute( 'data-mode' );
77			}
78		}
79
80		// Create a link element for the CSS.
81		const cssLink = document.createElement( 'link' );
82
83		cssLink.setAttribute( 'rel', 'stylesheet' );
84		cssLink.setAttribute( 'type', 'text/css' );
85
86		if ( affiliateWPFENotifications && affiliateWPFENotifications.cssUrl ) {
87			cssLink.setAttribute( 'href', affiliateWPFENotifications.cssUrl );
88		}
89
90		this.shadowRoot.appendChild( cssLink );
91
92		// Animation on mount.
93		const notification = this.shadowRoot.getElementById( 'notification' );
94
95		if ( notification ) {
96			notification.style.animation = 'slideIn 0.3s forwards';
97		}
98
99		// Event listener for close button
100		const closeButton = this.shadowRoot.querySelector( '#close-notification' );
101
102		if ( closeButton ) {
103
104			closeButton.addEventListener( 'click', () => {
105
106				notification.style.animation = 'slideOut 0.3s forwards';
107
108				setTimeout( () => this.remove(), 300 ); // Remove after animation.
109			} );
110		}
111	}
112}
113
114( function() {
115
116	customElements.define( 'affiliatewp-notification', AffiliateWPNotification );
117
118	/**
119	 * Extracts the affiliate identifier from the current URL.
120	 *
121	 * @since 2.23.0
122	 *
123	 * Attempts to retrieve the affiliate ID using the query parameter first; if not found,
124	 * falls back to parsing the URL's path segments.
125	 *
126	 * @return {string|null} The affiliate identifier if found, otherwise null.
127	 */
128	function getAffiliate() {
129
130		const urlParams = new URLSearchParams( window.location.search );
131		let affiliate = urlParams.get( affiliateWPFENotifications.referralVar );
132
133		if ( ! affiliate ) {
134
135			// For pretty permalink structure.
136			const pathArray = window.location.pathname.split( '/' );
137			const refIndex = pathArray.indexOf( affiliateWPFENotifications.referralVar );
138
139			if ( refIndex > -1 && pathArray.length > refIndex + 1 ) {
140				affiliate = pathArray[ refIndex + 1 ];
141			}
142		}
143
144		return affiliate;
145	}
146
147	/**
148	 * Creates and appends a custom notification element to the body of the document.
149	 *
150	 * @since 2.23.0
151	 *
152	 * This function is typically called in response to a specific event, such as a successful
153	 * application of an affiliate coupon.
154	 */
155	function showCustomNotification() {
156		document.body.appendChild( document.createElement( 'affiliatewp-notification' ) );
157	}
158
159	/**
160	 * Event listener for the DOMContentLoaded event.
161	 *
162	 * @since 2.23.0
163	 *
164	 * Fetches and applies an affiliate coupon if an affiliate identifier is present in the URL.
165	 * Upon successful application, displays a custom notification.
166	 */
167	document.addEventListener( 'DOMContentLoaded', () => {
168
169		const affiliate = getAffiliate();
170
171		if ( affiliate ) {
172
173			const params = new URLSearchParams( {
174				action: 'apply_affiliate_coupon',
175				affiliate
176			} );
177
178			fetch( `${affiliateWPFENotifications.ajaxUrl}?${params.toString()}`, {
179				method: 'POST',
180				credentials: 'same-origin'
181			} )
182
183			.then( response => response.json() )
184
185			.then( data => {
186				if ( data.couponApplied ) {
187					showCustomNotification();
188				}
189			} )
190
191			.catch( error => window.console.error( 'Error:', error ) );
192		}
193	} );
194} () );

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.