1"use strict"; 2 3/* 4 Recently Viewed Searches 5*/ 6 7// Read's the body tag for classes matching `site-foobar`. 8function getSiteNameFromBody() { 9 return document.querySelector("body").dataset.siteName; 10} 11 12function saveRecentlyViewedSearch(item) { 13 fetch('/rest/personalization/v1/saved-searches', { 14 method: "POST", 15 headers: { 16 'Content-Type': 'application/json' 17 }, 18 body: JSON.stringify({ 19 searchParameters: item.searchParameterMap, 20 title: item.title, 21 resultCount: parseInt(item.resultCount.replace(/,/g, '')), 22 siteName: item.siteName 23 }) 24 }).then(function (response) { 25 return response.text(); 26 }).then(function (data) { 27 location.reload(); 28 }).catch(function (error) { 29 console.error('Error: ', error); 30 }); 31} 32 33var qsa = function qsa(sel) { 34 return Array.from(document.querySelectorAll(sel)); 35}; 36function initializeRecentlyViewedSearches() { 37 var allrecentlyViewedSearches = qsa('.recentlyViewedSearches'); 38 var siteName = getSiteNameFromBody(); 39 // <span data-resulttotal="127" id="resultTotal" class="count">127</span> 40 var resultTotal = document.getElementById('resultTotal'); 41 var resultCount = ''; 42 if (resultTotal) { 43 resultCount = resultTotal.dataset.resulttotal; 44 } 45 // <ul> ... 46 var recentlyViewedSearches = document.querySelector('.recentlyViewedSearches'); 47 var resultLabel = ''; 48 var isSearching = false; 49 if (recentlyViewedSearches) { 50 resultLabel = recentlyViewedSearches.dataset.resultregionlabel; 51 isSearching = recentlyViewedSearches.dataset.issearching == 'true'; 52 } 53 54 // .recentlyViewedSearches > <li> <span class="criteria"> ... <a>save icon 55 var recentlyViewedSearchTemplate = document.querySelector('.recentlyViewedSearchTemplate'); 56 if (recentlyViewedSearchTemplate) { 57 recentlyViewedSearchTemplate = recentlyViewedSearchTemplate.cloneNode(true); 58 allrecentlyViewedSearches.forEach(function (el) { 59 var temel = el.querySelector('.recentlyViewedSearchTemplate'); 60 if (temel) { 61 el.removeChild(temel); 62 } 63 }); 64 } 65 66 var getTitleWithResult = function getTitleWithResult(title, resultCount) { 67 return title !== null && title.length > 25 ? title.substring(0, 22) + '... (' + resultCount + ' ' + resultLabel + ') ' : title + ' (' + resultCount + ' ' + resultLabel + ') '; 68 }; 69 70 var getTemplate = function getTemplate(title, href, searchParameterMap, resultCount) { 71 var templateElement = recentlyViewedSearchTemplate.cloneNode(true); 72 var button = templateElement.querySelector('[data-component="saveButton"]'); 73 button.dataset.searchparametermap = JSON.stringify(searchParameterMap); 74 button.setAttribute('href', href); 75 button.innerHTML = getTitleWithResult(title, resultCount); 76 return templateElement; 77 }; 78 79 // Deserialize sessionStorage 80 var searchesFromSessionStorage = sessionStorage.getItem('recentlyViewedSearches'); 81 if (!searchesFromSessionStorage) { 82 searchesFromSessionStorage = []; 83 } else { 84 searchesFromSessionStorage = JSON.parse(searchesFromSessionStorage); 85 } 86 87 // if template exist, retrieve info from it 88 if (recentlyViewedSearches && recentlyViewedSearchTemplate) { 89 90 // Serialize the data of the current template 91 var button = recentlyViewedSearchTemplate.querySelector('[data-component="saveButton"]'); 92 93 var templateData = { 94 searchParameterMap: JSON.parse(button.dataset.searchparametermap), 95 title: button.getAttribute('title'), 96 href: button.getAttribute('href'), 97 resultCount: resultCount, 98 siteName: siteName 99 }; 100 101 // if href is unique among stored searches, add to front 102 if (isSearching && searchesFromSessionStorage.filter(function (e) { 103 return button.getAttribute('href') === e.href; 104 }).length === 0) { 105 searchesFromSessionStorage.unshift(templateData); 106 } 107 } 108 109 // check if all fields exist. discard otherwise 110 var properties = ['title', 'href', 'searchParameterMap', 'resultCount', 'siteName']; 111 searchesFromSessionStorage = searchesFromSessionStorage.filter(function (item) { 112 var hasAllProperties = true; 113 var propertiesLength = properties.length; 114 for (var i = 0; i < propertiesLength && hasAllProperties; i++) { 115 hasAllProperties = item.hasOwnProperty(properties[i]); 116 } 117 return hasAllProperties; 118 }); 119 120 // Update the count strings on the page 121 var recentlyViewedSearchesCount = qsa('.count.recentlyViewedSearchesCount'); 122 var mySearchesButtonCount = document.querySelector('.mySearches .count'); 123 124 var totalCount = 0; 125 if (mySearchesButtonCount) { 126 totalCount = parseInt(mySearchesButtonCount.innerHTML.replace(/\D/g, '')); 127 } 128 totalCount += searchesFromSessionStorage.length; 129 130 if (recentlyViewedSearchesCount && mySearchesButtonCount) { 131 recentlyViewedSearchesCount.forEach(function (el) { 132 el.innerHTML = '(' + searchesFromSessionStorage.length + ')'; 133 }); 134 135 mySearchesButtonCount.innerHTML = '(' + totalCount + ')'; 136 } 137 138 // if recently viewed searches exist, deserialize array from session storage and add the entries 139 if (recentlyViewedSearches) { 140 recentlyViewedSearches.innerHTML = ''; 141 searchesFromSessionStorage.filter(function (item) { 142 return item.siteName === siteName; 143 }
143).forEach(function (item) { 144 var template = getTemplate(item.title, item.href, item.searchParameterMap, item.resultCount); 145 allrecentlyViewedSearches.forEach(function (el) { 146 el.appendChild(template); 147 }); 148 if (document.querySelector('body').classList.contains('loggedin')) { 149 template.querySelector('a.save').addEventListener('click', function (event) { 150 event.preventDefault(); 151 saveRecentlyViewedSearch(item); 152 }); 153 template.querySelector('a.save').addEventListener('keydown', function (event) { 154 if (event.keyCode == 13) { 155 event.preventDefault(); 156 saveRecentlyViewedSearch(item); 157 } 158 }); 159 } else { 160 template.querySelector('a.save').remove(); 161 } 162 }); 163 } 164 165 // Reserialize the array and store it in sessionStorage 166 sessionStorage.setItem('recentlyViewedSearches', JSON.stringify(searchesFromSessionStorage)); 167} 168 169// Return the first element of a list that starts with "start" 170var pickItem = function pickItem(elements, start) { 171 var result = Array.from(elements).filter(function (item) { 172 return item.startsWith(start); 173 }); 174 if (result.length > 0) { 175 return result[0]; 176 } else { 177 return null; 178 } 179}; 180 181// test 2 182var hasItem = function hasItem(elements, start) { 183 return pickItem(elements, start) !== null; 184}; 185 186function saveRecentlyViewedEntry(item) { 187 fetch('/rest/v1/savedContent', { 188 method: "POST", 189 headers: { 190 'Content-Type': 'application/json' 191 }, 192 body: JSON.stringify({ 193 uri: item.uri, 194 title: item.title, 195 siteName: item.siteName 196 }) 197 }).then(function (response) { 198 return response.text(); 199 }).then(function (data) { 200 location.reload(); 201 }).catch(function (error) { 202 console.error('Error: ', error); 203 }); 204} 205 206function initializeRecentlyViewedEntries() { 207 var body = document.querySelector('body'); 208 var siteName = getSiteNameFromBody(); 209 var allrecentlyViewedEntries = qsa('.recentlyViewedEntries'); 210 var isContentPage = hasItem(body.classList, 'page-content') || hasItem(body.classList, 'page-view') || hasItem(body.classList, 'nonConfigurableViewPage'); 211 212 var isNonConfigurable = hasItem(body.classList, 'nonConfigurableViewPage'); 213 214 var nonConfigurableTitle = body.dataset.myContentTitle; 215 216 var titleEl = document.querySelector('.component-content-title .title'); 217 var pageTitle = document.getElementById('pagetitle'); // alternative source in OUP sites 218 var recentlyViewedEntries = document.querySelector('.recentlyViewedEntries'); 219 var contentTitle = document.body.dataset.myContentTitle ? document.body.dataset.myContentTitle : titleEl ? titleEl.innerText : nonConfigurableTitle ? nonConfigurableTitle : pageTitle ? pageTitle.childElementCount === 0 ? pageTitle.innerText : pageTitle.firstChild.innerText : null; 220 221 if (pageTitle && (nonConfigurableTitle === undefined || nonConfigurableTitle === null)) { 222 if (pageTitle.childElementCount > 0 && pageTitle.firstChild.textContent !== undefined) { 223 contentTitle = pageTitle.firstChild.textContent; 224 } 225 } 226 227 if (contentTitle == null) { 228 var tempTitle = document.querySelector('#mainTitle'); 229 if (tempTitle) { 230 contentTitle = tempTitle.innerText; 231 } 232 } 233 234 var recentlyViewedEntriesCount = document.querySelector('.recentlyViewedEntriesCount'); 235 var myEntriesButtonCount = document.querySelector('#savedEntries .count'); 236 var allEntriesButtonCount = qsa('#savedEntries .count'); 237 var allrecentlyViewedEntriesCount = qsa('.recentlyViewedEntriesCount'); 238 239 var getTemplate = function getTemplate(title, href) { 240 var templateElement = recentlyViewedEntryTemplate.cloneNode(true); 241 var button = templateElement.querySelector('[data-component="saveButton"]'); 242 button.setAttribute('href', href); 243 button.innerHTML = title.length > 25 ? title.substr(0, 22) + "..." : title; 244 return templateElement; 245 }; 246 247 // Deserialize sessionStorage 248 var entriesFromSessionStorage = sessionStorage.getItem('recentlyViewedEntries'); 249 250 if (!entriesFromSessionStorage) { 251 entriesFromSessionStorage = []; 252 } else { 253 entriesFromSessionStorage = JSON.parse(entriesFromSessionStorage); 254 } 255 256 var recentlyViewedEntryTemplate = document.querySelector('.recentlyViewedEntryTemplate'); 257 if (recentlyViewedEntryTemplate) { 258 recentlyViewedEntryTemplate = recentlyViewedEntryTemplate.cloneNode(true);
259 allrecentlyViewedEntries.forEach(function (el) { 260 var temel = el.querySelector('.recentlyViewedEntryTemplate'); 261 if (temel) { 262 el.removeChild(temel); 263 } 264 }); 265 } 266 267 // if template exist, retrieve info from it 268 if (isContentPage && recentlyViewedEntries && recentlyViewedEntryTemplate) { 269 var button = recentlyViewedEntryTemplate.querySelector('[data-component="saveButton"]'); 270 271 var templateData = { 272 title: contentTitle, 273 link: button !== undefined && button !== null ? button.href : window.location.pathname, 274 uri: button !== undefined && button !== null ? button.dataset.uri : window.location.pathname !== null ? window.location.pathname.substring(window.location.pathname.indexOf("/view/") + 5) : window.location.pathname, 275 siteName: siteName 276 }; 277 278 if (isContentPage && entriesFromSessionStorage.filter(function (e) { 279 return button.dataset.uri === e.uri; 280 }).length === 0) { 281 entriesFromSessionStorage.unshift(templateData); 282 } 283 284 while (entriesFromSessionStorage.length > 10) { 285 entriesFromSessionStorage.pop(); 286 } 287 } 288 289 // check if all fields exist. discard otherwise 290 var properties = ['title', 'link', 'uri', 'siteName']; 291 entriesFromSessionStorage = entriesFromSessionStorage.filter(function (item) { 292 var hasAllProperties = true; 293 var propertiesLength = properties.length; 294 for (var i = 0; i < propertiesLength && hasAllProperties; i++) { 295 hasAllProperties = item.hasOwnProperty(properties[i]); 296 } 297 return hasAllProperties; 298 }); 299 300 if (isNonConfigurable && !recentlyViewedEntryTemplate && contentTitle !== undefined && contentTitle !== null && contentTitle.length > 0) { 301 var uriJs = window.location.pathname !== null ? window.location.pathname.substring(window.location.pathname.indexOf("/view/") + 5) : window.location.pathname; 302 303 var _templateData = { 304 title: contentTitle, 305 link: window.location.pathname, 306 uri: uriJs, 307 siteName: siteName 308 }; 309 310 if (isContentPage && entriesFromSessionStorage.filter(function (e) { 311 return uriJs === e.uri; 312 }).length === 0) { 313 entriesFromSessionStorage.unshift(_templateData); 314 } 315 316 while (entriesFromSessionStorage.length > 10) { 317 entriesFromSessionStorage.pop(); 318 } 319 } 320 321 if (recentlyViewedEntries) { 322 recentlyViewedEntries.innerHTML = ''; 323 var recentlyViewedEntriesForSite = 0; 324 entriesFromSessionStorage.filter(function (item) { 325 return item.siteName === getSiteNameFromBody(); 326 }).forEach(function (item) { 327 if (siteName !== null && item.siteName !== null && siteName.length > 0 && siteName.length == item.siteName.length && siteName.indexOf(item.siteName) === 0) { 328 var template = getTemplate(item.title, item.link); 329 allrecentlyViewedEntries.forEach(function (el) { 330 el.appendChild(template); 331 }); 332 //recentlyViewedEntries.appendChild(template); 333 if (document.querySelector('body').classList.contains('loggedin')) { 334 template.querySelector('a.save').addEventListener('click', function (event) { 335 event.preventDefault(); 336 saveRecentlyViewedEntry(item); 337 }); 338 template.querySelector('a.save').addEventListener('keydown', function (event) { 339 if (event.keyCode == 13) { 340 event.preventDefault(); 341 saveRecentlyViewedEntry(item); 342 } 343 }); 344 } else { 345 template.querySelector('a.save').remove(); 346 } 347 recentlyViewedEntriesForSite++; 348 } 349 }); 350 351 if (allrecentlyViewedEntriesCount.length > 1) { 352 allrecentlyViewedEntriesCount.forEach(function (el) { 353 el.innerHTML = '(' + recentlyViewedEntriesForSite + ')'; 354 }); 355 } else { 356 recentlyViewedEntriesCount.innerHTML = '(' + recentlyViewedEntriesForSite + ')'; 357 } 358 var totalCount = parseInt(myEntriesButtonCount.innerHTML.replace(/\D/g, '')); 359 totalCount += recentlyViewedEntriesForSite; 360 if (allEntriesButtonCount.length > 1) { 361 allEntriesButtonCount.forEach(function (el) { 362 if (el.classList.contains('recentlyViewedEntriesCount')) { 363 el.innerHTML = '(' + recentlyViewedEntriesForSite + ')'; 364 } else { 365 el.innerHTML = '(' + totalCount + ')'; 366 } 367 }); 368 } else { 369 myEntriesButtonCount.innerHTML = '(' + totalCount + ')'; 370 } 371 } 372 373 // Reserialize the array and store it in sessionStorage 374 sessionStorage.setItem('recentlyViewedEntries', JSON.stringify(entriesFromSessionStorage)); 375 376 // Scrolling fix 377 var chapterBody = document.querySelector(".container-chapterBody"); 378 if (chapterBody) { 379 var lastScroll = 0; 380 document.querySelector(".content-page").addEventListener('click', function (e) { 381 var anchor = e.target.closest('a'); 382 if (anchor !== null) { 383 if (anchor.hasChildNodes()) { 384 var path = anchor.hash; 385 path = path.split("#")[1]; 386 var el = document.getElementById(path); 387 if (el) { 388 var children = anchor.childNodes; 389 for (var i = 0; i < children.length; i++) { 390 //if(children[0].tagName === "SUP"){ 391 if (anchor.hash) { 392 e.preventDefault(); 393 var yOffset = document.querySelector(".c-Appbar").offsetHeight; 394 var y = el.getBoundingClientRect().top + window.pageYOffset; 395 //el.scrollIntoView(true); 396 if (y < lastScroll) { 397 y = el.getBoundingClientRect().top + window.pageYOffset - yOffset; 398 window.scrollTo({ top: y, behavior: 'smooth' }); 399 } else { 400 window.scrollTo({ top: y, behavior: 'smooth' }); 401 } 402 lastScroll = y; 403 } 404 } 405 } 406 } 407 } 408 }, false); 409 } 410} 411 412initializeRecentlyViewedSearches(); 413initializeRecentlyViewedEntries();
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.