PageSourceSearch

https://www.americamagazine.org/wp-content/plugins/americamagazine…/js/americamagazine-piano.js?ver=1.0.6

js americamagazine.org collected 2026-09-24 08:05:50 UTC 5,755 bytes, 204 lines download raw bytes

1/* global americaSettings tp sessionStorage localStorage */
2( function () {
3	// Set up objects
4	tp = window.tp || [];
5	if ( ! window.americaUtils ) {
6		window.americaUtils = {};
7	}
8	const americaUtils = window.americaUtils;
9
10	// Track where user is in Piano offer/checkout to coordinate UX
11	americaUtils.pianoOfferState = {};
12	[
13		'showOffer',
14		'startCheckout',
15		'checkoutStateChange',
16		'checkoutSelectTerm',
17	].forEach( ( event ) => {
18		tp.push( [
19			'addHandler',
20			event,
21			( params ) => {
22				americaUtils.pianoOfferState[ event ] = params;
23			},
24		] );
25	} );
26
27	// Helper to wrap tp's callApi function in a Promise
28	americaUtils.callPianoApi = function ( endpoint, args ) {
29		return new Promise( ( resolve, reject ) => {
30			tp.api.callApi( endpoint, args, ( response ) => {
31				// Piano API returns a code of 0 for a successful call
32				if ( response.code !== 0 ) {
33					reject( response );
34				} else {
35					resolve( response );
36				}
37			} );
38		} );
39	};
40
41	// Helper to show login screen (used by Coral)
42	americaUtils.showLogin = function ( e = null ) {
43		if ( e ) {
44			e.preventDefault();
45		}
46		tp.pianoId.show( { screen: 'login' } );
47	};
48
49	// Helper to check if the logged in user has subscriber access
50	// Also caches result in session storage
51	americaUtils.getSubscriberAccess = function () {
52		return new Promise( ( resolve, reject ) => {
53			// Can only get subscriber access for logged in users
54			if ( ! tp.pianoId.isUserValid() ) {
55				resolve( false );
56			}
57			// Check if we have a cached result
58			const sessionStorageCheck = JSON.parse(
59				sessionStorage.getItem( 'america-subscriber-access' )
60			);
61			if ( sessionStorageCheck ) {
62				// Answer from cached session storage check
63				resolve( sessionStorageCheck.access_id !== null );
64			} else {
65				// If no session storage item, then get it from the API
66				americaUtils
67					.callPianoApi( '/access/check', {
68						rid: americaSettings.piano.subscriber_rid,
69					} )
70					.then( ( response ) => {
71						sessionStorage.setItem(
72							'america-subscriber-access',
73							JSON.stringify( response.access )
74						);
75						resolve( response.access.access_id !== null );
76					} )
77					.catch( ( err ) => {
78						reject( err );
79					} );
80			}
81		} );
82	};
83
84	// Helper to clear America items in local and session storage
85	americaUtils.clearAmericaStorage = function () {
86		[ localStorage, sessionStorage ].forEach( ( storage ) => {
87			Object.keys( storage )
88				.filter( ( k ) => k.startsWith( 'america-' ) )
89				.forEach( ( k ) => storage.removeItem( k ) );
90		} );
91	};
92
93	// Helper to take an action on all elements matching a query selector
94	americaUtils.forEachElementBySelector = function ( selector, callback ) {
95		const elements = document.querySelectorAll( selector );
96		for ( const e of elements ) {
97			callback( e );
98		}
99	};
100
101	// Modify the UX to reflect account state
102	americaUtils.configureAccountUx = function () {
103		// Helper to close the mobile menu during login (it covers up the login screen)
104		americaUtils.forEachElementBySelector( '.wp_piano_id_button', ( e ) => {
105			e.addEventListener( 'click', () => {
106				if (
107					document.body.classList.contains( 'mobile-menu-opened' )
108				) {
109					// Slight delay to allow for login to render before closing menu
110					setTimeout( () => {
111						document
112							.querySelector(
113								'#mobile-sidebar-fallback .mobile-menu-toggle'
114							)
115							.click();
116					}, 300 );
117				}
118			} );
119		} );
120
121		if ( tp.pianoId.isUserValid() ) {
122			// Identify logged in status to the whole page
123			document.body.classList.add( 'piano-logged-in' );
124
125			// The stock Piano plugin hides the login button, so we only need to unhide UX for logged-in users
126			americaUtils.forEachElementBySelector(
127				'.wp_piano_id_logged_in',
128				( e ) => {
129					e.classList.remove( 'hide' );
130				}
131			);
132
133			// Wire the logout link to a Piano ID action
134			americaUtils.forEachElementBySelector(
135				'.wp_piano_id_logout',
136				( e ) => {
137					e.addEventListener( 'click', () => {
138						tp.pianoId.logout();
139					} );
140				}
141			);
142
143			// Adjust UX for subscribers
144			americaUtils.getSubscriberAccess().then( ( subscribed ) => {
145				if ( subscribed ) {
146					document.body.classList.add( 'piano-subscriber' );
147					// Tag the mobile CTA subscribe button with the class we use
148					americaUtils.forEachElementBySelector( '.mb-cta', ( e ) => {
149						e.classList.add( 'wp_piano_subscribe_button' );
150					} );
151					// Hide subscribe buttons
152					americaUtils.forEachElementBySelector(
153						'.wp_piano_subscribe_button',
154						( e ) => {
155							e.classList.add( 'hide' );
156						}
157					);
158				}
159			} );
160		}
161	};
162
163	// Enqueue handler to configure UX to run on init (for user who is already logged in)
164	tp.push( [
165		'init',
166		() => {
167			americaUtils.configureAccountUx();
168		},
169	] );
170
171	// Enqueue handler for user logging in while on this page
172	tp.push( [
173		'addHandler',
174		'loginSuccess',
175		( loginData ) => {
176			americaUtils.configureAccountUx();
177			// Handle logging in from a modal offer
178			if ( loginData.source === 'OFFER' ) {
179				americaUtils.getSubscriberAccess().then( ( subscribed ) => {
180					if ( subscribed ) {
181						tp.offer.close();
182						americaUtils.pianoOfferState = {};
183					} else {
184						// If the user is not a subscriber, we don't know whether or not they have access,
185						// so reload the entire page to let Piano Composer run from scratch
186						// TODO: evaluate pianoOfferState to determine whether or not to reload
187						// - what if the user logs in in the middle of checkout?
188						window.location.reload();
189					}
190				} );
191			}
192		},
193	] );
194
195	// Enqueue logout handler (clear data and return user to homepage)
196	tp.push( [
197		'addHandler',
198		'logout',
199		() => {
200			americaUtils.clearAmericaStorage();
201			window.location.href = '/';
202		},
203	] );
204} )();

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.