PageSourceSearch

https://theaircurrent.com/wp-content/plugins/tac-save-for-later/js/airflow.js?ver=1790277620

js theaircurrent.com collected 2026-09-24 19:20:49 UTC 4,783 bytes, 158 lines download raw bytes

1var airflowSaved = [];
2const airflowDebounce = (callback, wait) => {
3  let timeoutId = null;
4  return (...args) => {
5    window.clearTimeout(timeoutId);
6    timeoutId = window.setTimeout(() => {
7      callback.apply(null, args);
8    }, wait);
9  };
10}
11
12const handleNewAirflowEntries = airflowDebounce((ev) =>{
13	var tbody = document.getElementById('search-results');
14	addBookmarkToggle(tbody);
15}, 100 )
16
17function addBookmarkToggle(tbody) {
18	var rows = tbody.children;
19	for( var i = 0; i < rows.length; i++ ) {
20		var row = rows[i];
21		var isSaved = false;
22		var uuid = row.getAttribute('data-uuid');
23		if( uuid && airflowSaved.indexOf(uuid) > -1 ) {
24			isSaved = true;
25		}
26		var bookmark = row.querySelector('.tac-bookmark');
27		if( !bookmark ) {
28			var title = row.querySelector('.news-title');
29			if( title ) {
30				var bookmarkWrap = document.createElement('span');
31				bookmarkWrap.classList.add('tac-feed-bookmark-wrap');
32				var bookmarkBox = document.createElement('i');
33				bookmarkBox.classList.add('tac-bookmark');
34				if( isSaved ) {
35					bookmarkBox.classList.add('bookmarked');
36				}
37				bookmarkBox.setAttribute('data-tooltip','Save for later')
38				bookmarkBox.classList.add('fa');
39				bookmarkBox.classList.add('fa-bookmark');
40				bookmarkWrap.append(bookmarkBox);
41				var bookmarkMessage = document.createElement('div');
42				bookmarkMessage.classList.add('tac-feed-bookmark-message');
43				bookmarkMessage.textContent = 'Saved!';
44				bookmarkWrap.append(bookmarkMessage);
45				title.prepend(bookmarkWrap);
46			}
47		}
48	}
49}
50
51function airflowBookmarks() {
52	var table = document.querySelector('#airflow-container table');
53	if( table ) {
54		var tbody = document.getElementById('search-results');
55		console.log('airflow ready');
56		const config = { attributes: false, childList: true, subtree: false };
57		const callback = function (mutationsList, observer) {
58		  // Use traditional 'for loops' for IE 11
59		  for (const mutation of mutationsList) {
60		    if (mutation.type === "childList") {
61		      handleNewAirflowEntries(tbody);
62		    }
63		  }
64		};
65
66		// Create an observer instance linked to the callback function
67		const observer = new MutationObserver(callback);
68
69		// Start observing the target node for configured mutations
70		observer.observe(tbody, config);
71		addBookmarkToggle(tbody);
72	} else {
73		window.setTimeout( airflowBookmarks, 1000 );
74	}
75}
76
77function bookmarkAirflowAjax( method = 'GET', url = '/init', payload = {}, fn ) {
78  // Create the XMLHttpRequest object.
79  const xhr = new XMLHttpRequest();
80  // Initialize the request
81  xhr.open( method, '/wp-json/tac-save-for-later/v1'+ url );
82  // Send the request
83  if( method != 'GET' ) {
84    var data = JSON.stringify(payload);
85    xhr.send(data);
86  } else {
87    xhr.send();
88  }
89  // Fired once the request completes successfully 
90  xhr.onload = function(e) {
91      // Check if the request was a success
92      if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
93        // Get and convert the responseText into JSON
94        var response = JSON.parse(xhr.responseText);
95        fn(response);
96      }
97  }
98}
99
100function updateAirflowBookmark( el ) {
101	console.log('updating bookmark - airflow')
102	var url = '/'
103  if( el.classList.contains('bookmarked') ) {
104    url += 'remove_airflow/';
105    el.classList.remove('bookmarked');
106  } else {
107    url += 'add_airflow/';
108    el.nextSibling.classList.add('show');
109		window.setTimeout(function(){
110			el.nextSibling.classList.remove('show');
111		},1300);
112    el.classList.add('bookmarked');
113  }
114  url += el.closest('tr').getAttribute('data-uuid');
115  bookmarkAirflowAjax('GET', url, {}, function(response){
116    console.log('updated')
117    console.log(response)
118    /* In case of failure we revert/update */
119    if( response.saved ) {
120      el.classList.add('bookmarked');
121    } else {
122      el.classList.remove('bookmarked');
123    }
124  });
125}
126
127function setupAirflowBookmarks() {
128	bookmarkAirflowAjax('GET','/init_airflow', {}, function(response){
129		console.log(response);
130		if( response.show ) {
131			window.setTimeout( airflowBookmarks, 1000 );
132		}
133		if( response.saved ) {
134			airflowSaved = response.saved;
135		}
136		document.body.addEventListener("click", function (e) {
137	    if (e.target && (e.target.classList.contains("tac-bookmark") 
138	      ||(e.target.parentElement && e.target.parentElement.classList.contains("tac-bookmark")) ) ) {
139	      if( e.target.classList.contains("tac-bookmark") ) {
140	        updateAirflowBookmark( e.target );
141	      } else {
142	        updateAirflowBookmark( e.target.parentElement );
143	      }
144	      e.preventDefault();
145	      e.stopPropagation();
146	      return false;
147	    }
148	  });
149	})
150}
151
152document.addEventListener("DOMContentLoaded", () => {
153	/* Airflow */
154	if(document.body.classList.contains('page-id-16115')) {
155		setupAirflowBookmarks();
156	}
157});
158

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.