diff src/site.js @ 0:8f4df159f06b

start public repo
author Franklin Schmidt <fschmidt@gmail.com>
date Fri, 11 Jul 2025 20:57:49 -0600
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/site.js	Fri Jul 11 20:57:49 2025 -0600
@@ -0,0 +1,250 @@
+'use strict';
+
+function ajax(url,postData,context) {
+	let request = new XMLHttpRequest();
+	let method = postData ? 'POST' : 'GET';
+	request.open( method, url );
+	if( postData )
+		request.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' );
+	request.onload = function() {
+		if( request.status !== 200 ) {
+			let err = 'ajax failed: ' + request.status;
+			if( request.responseText ) {
+				err += '\n' + request.responseText.trim();
+				document.write('<pre>'+request.responseText+'</pre>');
+			}
+			err += '\nurl = ' + url;
+			err += '\npage = ' + window.location;
+			ajax( '/error_log.js', 'err='+encodeURIComponent(err) );
+			return;
+		}
+		try {
+			eval( request.responseText );
+		} catch(e) {
+			console.log( request.responseText );
+			window.err = '\najax-url = ' + url;
+			throw e;
+		}
+	};
+	request.send(postData);
+}
+
+window.onerror = function(msg, url, line, col, error) {
+	if( !url )
+		return;
+	let err = msg;
+	err += '\nurl = ' + url;
+	if( url != window.location )
+		err += '\npage = ' + window.location;
+	err += '\nline = '+line;
+	if( col )
+		err += '\ncolumn = ' + col;
+	if( error ) {
+		if( error.stack )
+			err += '\nstack = ' + error.stack;
+		if( error.cause )
+			err += '\ncause= ' + error.cause;
+		if( error.fileName )
+			err += '\nfileName= ' + error.fileName;
+	}
+	if( window.err ) {
+		err += window.err;
+		window.err = null;
+	}
+	ajax( '/error_log.js', 'err='+encodeURIComponent(err) );
+};
+
+window.onunhandledrejection = function(event) {
+	//console.log(event);
+	let reason = event.reason;
+	let err = reason && reason.message || reason || JSON.stringify(event);
+	if( reason && reason.stack )
+		err += '\nstack = ' + reason.stack;
+	ajax( '/error_log.js', 'err='+encodeURIComponent(err) );
+};
+
+let isProduction = location.hostname==='linkmy.style';
+
+let cookies;
+function setCookies() {
+	cookies = {};
+	if( document.cookie !== '' ) {
+		let a = document.cookie.split('; ');
+		for( let i=0; i<a.length; i++ ) {
+			let s = a[i];
+			let j = s.indexOf('=');
+			if( j !== -1 ) {
+				let name = s.substring(0,j);
+				let value = s.substring(j+1);
+				cookies[name] = decodeURIComponent(value);
+			}
+		}
+	}
+}
+setCookies();
+
+document.cookie = 'testcookie=x; Max-Age=1;';
+document.cookie = '';
+let hasCookies = document.cookie.includes('testcookie');
+
+// Mixpanel
+const MIXPANEL_CUSTOM_LIB_URL = "https://mp.linkmy.style/lib.min.js";
+
+(function (f, b) { if (!b.__SV) { var e, g, i, h; window.mixpanel = b; b._i = []; b.init = function (e, f, c) { function g(a, d) { var b = d.split("."); 2 == b.length && ((a = a[b[0]]), (d = b[1])); a[d] = function () { a.push([d].concat(Array.prototype.slice.call(arguments, 0))); }; } var a = b; "undefined" !== typeof c ? (a = b[c] = []) : (c = "mixpanel"); a.people = a.people || []; a.toString = function (a) { var d = "mixpanel"; "mixpanel" !== c && (d += "." + c); a || (d += " (stub)"); return d; }; a.people.toString = function () { return a.toString(1) + ".people (stub)"; }; i = "disable time_event track track_pageview track_links track_forms track_with_groups add_group set_group remove_group register register_once alias unregister identify name_tag set_config reset opt_in_tracking opt_out_tracking has_opted_in_tracking has_opted_out_tracking clear_opt_in_out_tracking start_batch_senders people.set people.set_once people.unset people.increment people.append people.union people.track_charge people.clear_charges people.delete_user people.remove".split( " "); for (h = 0; h < i.length; h++) g(a, i[h]); var j = "set set_once union unset remove delete".split(" "); a.get_group = function () { function b(c) { d[c] = function () { call2_args = arguments; call2 = [c].concat(Array.prototype.slice.call(call2_args, 0)); a.push([e, call2]); }; } for ( var d = {}, e = ["get_group"].concat( Array.prototype.slice.call(arguments, 0)), c = 0; c < j.length; c++) b(j[c]); return d; }; b._i.push([e, f, c]); }; b.__SV = 1.2; e = f.createElement("script"); e.type = "text/javascript"; e.async = !0; e.src = "undefined" !== typeof MIXPANEL_CUSTOM_LIB_URL ? MIXPANEL_CUSTOM_LIB_URL : "file:" === f.location.protocol && "//cdn.mxpnl.com/libs/mixpanel-2-latest.min.js".match(/^\/\//) ? "https://cdn.mxpnl.com/libs/mixpanel-2-latest.min.js" : "//cdn.mxpnl.com/libs/mixpanel-2-latest.min.js"; g = f.getElementsByTagName("script")[0]; g.parentNode.insertBefore(e, g); } })(document, window.mixpanel || []);
+
+let mpConfig = {
+	debug: !isProduction,
+	persistence: 'localStorage',
+	api_host: 'https://mp.linkmy.style',
+};
+let mixpanelProps = {};
+{
+	if( isProduction ) {
+		mixpanel.init('404d4c479de9c3070252e692375e82ca',mpConfig,'ours');
+	} else {  // test
+		mixpanel.init('bd2099a22e4118350a46b5b360d8c4da',mpConfig,'ours');
+	}
+	if( !hasCookies || location.pathname.match(/^\/private\//) ) {
+		mixpanel.ours.disable();
+	} else {
+		let props = mixpanelProps;
+		if( navigator.userAgent.includes('Instagram') ) {
+			props.App = 'Instagram';
+		} else if( navigator.userAgent.includes('BytedanceWebview') ) {
+			props.App = 'TikTok';
+		}
+		props.LoggedIn = !!cookies.user;
+		if( typeof(URLSearchParams) === 'function' ) {
+			let searchParams = new URLSearchParams(location.search);
+			if( Symbol.iterator in searchParams ) {
+				for (let p of searchParams) {
+					props[p[0]] = p[1];
+				}
+			}
+		}
+		props.Path = window.Path || location.pathname;
+		if( !window.Owner ) {
+			mixpanel.ours.track( 'Page View', props );
+		} else {
+			props.Owner = window.Owner;
+			props.Page = window.Page;
+			if( isProduction ) {
+				mixpanel.init('2bb632e9309b175ef67b7df382a43aee',mpConfig,'rpt');
+			} else {  // test
+				mixpanel.init('4acad1a74dfe7dba21e30da2642b9f78',mpConfig,'rpt');
+			}
+			if( Math.random() > 0.01 )
+				mixpanel.rpt.disable();
+			mixpanel.rpt.track( 'Page View', props );
+			window.addEventListener( 'load', function() {
+				let links = document.querySelectorAll('a[link]');
+				for( let i=0; i<links.length; i++ ) {
+					let link = links[i];
+					link.addEventListener( 'click', function(event) {
+						props.Link = event.target.textContent;
+						mixpanel.rpt.track( 'Click', props, {send_immediately:true} );
+					} );
+				}
+			} );
+			if( window.OwnerMpId ) {
+				mixpanel.init(window.OwnerMpId,mpConfig,'owner');
+				let props = { Page: window.Page };
+				mixpanel.owner.track( 'Page View', props );
+				window.addEventListener( 'load', function() {
+					let links = document.querySelectorAll('a[link]');
+					for( let i=0; i<links.length; i++ ) {
+						let link = links[i];
+						link.addEventListener( 'click', function(event) {
+							props.Link = event.target.textContent;
+							mixpanel.owner.track( 'Click', props, {send_immediately:true} );
+						} );
+					}
+				} );
+			}
+		}
+	}
+}
+
+
+// Facebook
+let fbId = isProduction ? '667025338202310' : '1504114567086568';
+let fbOptions = {};
+if( window.UserEmail )
+	fbOptions.em = window.UserEmail.trim().toLowerCase();
+if( cookies.user )
+	fbOptions.external_id = cookies.user;
+//console.log(fbOptions);
+
+!function(f,b,e,v,n,t,s)
+{if(f.fbq)return;n=f.fbq=function(){n.callMethod?
+n.callMethod.apply(n,arguments):n.queue.push(arguments)};
+if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
+n.queue=[];t=b.createElement(e);t.async=!0;
+t.src=v;s=b.getElementsByTagName(e)[0];
+s.parentNode.insertBefore(t,s)}(window, document,'script',
+'https://connect.facebook.net/en_US/fbevents.js');
+fbq('init', fbId, fbOptions);
+
+let fbEvents = null;
+
+function fbSendEvents() {
+	//console.log(fbEvents);
+	let eventID = Math.random().toString();
+	let options = {eventID:eventID};
+	let url = `/facebook.js?event_id=${eventID}`;
+	for( let event of fbEvents ) {
+		let name = event.name;
+		let props = event.properties;
+		fbq( event.action, name, props, options );
+		url += `&event_name=${name}`;
+		if( props )
+			url += `&${name}=${encodeURIComponent(JSON.stringify(props))}`;
+	}
+	ajax(url);
+	fbEvents = null;
+}
+
+function fbTrack(action,name,properties) {
+	if( !fbEvents ) {
+		fbEvents = [];
+		setTimeout(fbSendEvents);
+	}
+	fbEvents.push({
+		action: action,
+		name: name,
+		properties: properties,
+	});
+}
+
+
+function mainSelectHashtag(hashtag) {
+	let style = document.querySelector('style[hashtag]');
+	if( hashtags[hashtag] ) {
+		style.innerHTML = `
+			div[pics] > span {
+				display: none;
+			}
+			div[pics] > span.${hashtag} {
+				display: block;
+			}
+`					;
+		history.replaceState(null,null, `#${hashtag}` );
+	} else {
+		style.innerHTML = '';
+		history.replaceState(null,null, location.pathname + location.search );
+	}
+}
+
+function mainInit() {
+	let hash = location.hash;
+	if( hash ) {
+		hash = hash.slice(1);  // remove '#'
+		if( hashtags[hash] ) {
+			let select = document.querySelector('[hashtags] select');
+			select.value = hash;
+			mainSelectHashtag(hash);
+		} else {
+			history.replaceState(null,null, location.pathname + location.search );
+		}
+	}
+}