`); let searchUrl = `/search/`; history.forEach((elem) => { prevsearch.find('#prevsearch-options').append(`
${elem}`); }); } $('#search-pretype-options').empty(); $('#search-pretype-options').append(prevsearch); let prevbooks = $(false); [ {title:"Recently Opened Textbooks", books:previous_books}, {title:"Recommended Textbooks", books:recommended_books} ].forEach((book_segment) => { if (Array.isArray(book_segment.books) && book_segment.books.length>0 && nsegments<2) { nsegments+=1; prevbooks = $(`
`); let searchUrl = "/books/xxx/"; book_segment.books.forEach((elem) => { prevbooks.find('#prevbooks-options'+nsegments.toString()).append(`
${elem.title} ${ordinal(elem.edition)} ${elem.author}`); }); } $('#search-pretype-options').append(prevbooks); }); } function anon_pretype() { let prebooks = null; try { prebooks = JSON.parse(localStorage.getItem('PRETYPE_BOOKS_ANON')); }catch(e) {} if ('previous_books' in prebooks && 'recommended_books' in prebooks) { previous_books = prebooks.previous_books; recommended_books = prebooks.recommended_books; if (typeof PREVBOOKS !== 'undefined' && Array.isArray(PREVBOOKS)) { new_prevbooks = PREVBOOKS; previous_books.forEach(elem => { for (let i = 0; i < new_prevbooks.length; i++) { if (elem.id == new_prevbooks[i].id) { return; } } new_prevbooks.push(elem); }); new_prevbooks = new_prevbooks.slice(0,3); previous_books = new_prevbooks; } if (typeof RECBOOKS !== 'undefined' && Array.isArray(RECBOOKS)) { new_recbooks = RECBOOKS; for (let j = 0; j < new_recbooks.length; j++) { new_recbooks[j].viewed_at = new Date(); } let insert = true; for (let i=0; i < recommended_books.length; i++){ for (let j = 0; j < new_recbooks.length; j++) { if (recommended_books[i].id == new_recbooks[j].id) { insert = false; } } if (insert){ new_recbooks.push(recommended_books[i]); } } new_recbooks.sort((a,b)=>{ adate = new Date(2000, 0, 1); bdate = new Date(2000, 0, 1); if ('viewed_at' in a) {adate = new Date(a.viewed_at);} if ('viewed_at' in b) {bdate = new Date(b.viewed_at);} // 100000000: instead of just erasing the suggestions from previous week, // we just move them to the back of the queue acurweek = ((new Date()).getDate()-adate.getDate()>7)?0:100000000; bcurweek = ((new Date()).getDate()-bdate.getDate()>7)?0:100000000; aviews = 0; bviews = 0; if ('views' in a) {aviews = acurweek+a.views;} if ('views' in b) {bviews = bcurweek+b.views;} return bviews - aviews; }); new_recbooks = new_recbooks.slice(0,3); recommended_books = new_recbooks; } localStorage.setItem('PRETYPE_BOOKS_ANON', JSON.stringify({ previous_books: previous_books, recommended_books: recommended_books })); build_popup(); } } var whiletyping_search_object = null; var whiletyping_search = { books: [], curriculum: [], topics: [] } var single_whiletyping_ajax_promise = null; var whiletyping_database_initial_burst = 0; //number of consecutive calls, after 3 we start the 1 per 5 min calls function get_whiletyping_database() { //gets the database from the server. // 1. by validating against a local database value we confirm that the framework is working and // reduce the ammount of continuous calls produced by errors to 1 per 5 minutes. return localforage.getItem('whiletyping_last_attempt').then(function(value) { if ( value==null || (new Date()) - (new Date(value)) > 1000*60*5 || (whiletyping_database_initial_burst < 3) ) { localforage.setItem('whiletyping_last_attempt', (new Date()).getTime()); // 2. Make an ajax call to the server and get the search database. let databaseUrl = `/search/whiletype_database/`; let resp = single_whiletyping_ajax_promise; if (resp === null) { whiletyping_database_initial_burst = whiletyping_database_initial_burst + 1; single_whiletyping_ajax_promise = resp = new Promise((resolve, reject) => { $.ajax({ url: databaseUrl, type: 'POST', data:{csrfmiddlewaretoken: "gxUiIML4XRhuBPTsomF3Xa7EwXdYFPpUEE4VXtu2Swc8Vk6t9s9aDvN04G5nfBZI"}, success: function (data) { // 3. verify that the elements of the database exist and are arrays if ( ('books' in data) && ('curriculum' in data) && ('topics' in data) && Array.isArray(data.books) && Array.isArray(data.curriculum) && Array.isArray(data.topics)) { localforage.setItem('whiletyping_last_success', (new Date()).getTime()); localforage.setItem('whiletyping_database', data); resolve(data); } }, error: function (error) { console.log(error); resolve(null); }, complete: function (data) { single_whiletyping_ajax_promise = null; } }) }); } return resp; } return Promise.resolve(null); }).catch(function(err) { console.log(err); return Promise.resolve(null); }); } function get_whiletyping_search_object() { // gets the fuse objects that will be in charge of the search if (whiletyping_search_object){ return Promise.resolve(whiletyping_search_object); } database_promise = localforage.getItem('whiletyping_database').then(function(database) { return localforage.getItem('whiletyping_last_success').then(function(last_success) { if (database==null || (new Date()) - (new Date(last_success)) > 1000*60*60*24*30 || (new Date('2023-04-25T00:00:00')) - (new Date(last_success)) > 0) { // New database update return get_whiletyping_database().then(function(new_database) { if (new_database) { database = new_database; } return database; }); } else { return Promise.resolve(database); } }); }); return database_promise.then(function(database) { if (database) { const options = { isCaseSensitive: false, includeScore: true, shouldSort: true, // includeMatches: false, // findAllMatches: false, // minMatchCharLength: 1, // location: 0, threshold: 0.2, // distance: 100, // useExtendedSearch: false, ignoreLocation: true, // ignoreFieldNorm: false, // fieldNormWeight: 1, keys: [ "title" ] }; let curriculum_index={}; let topics_index={}; database.curriculum.forEach(c => curriculum_index[c.id]=c); database.topics.forEach(t => topics_index[t.id]=t); for (j=0; j
I'm an expert in web development and programming, particularly in JavaScript and related technologies. My expertise is grounded in years of hands-on experience building and maintaining web applications, as well as staying up-to-date with the latest developments in the field. I have a deep understanding of various JavaScript frameworks and libraries, including jQuery, React, Angular, and Vue.js, and I've leveraged these tools to create dynamic and responsive user interfaces.
Additionally, I have a strong grasp of server-side technologies such as Node.js and Express.js, allowing me to develop full-stack applications seamlessly. My proficiency extends to database management systems like MongoDB, MySQL, and PostgreSQL, enabling me to design robust backend systems that efficiently handle data storage and retrieval.
Furthermore, I'm well-versed in web security best practices, ensuring that the applications I develop are protected against common vulnerabilities such as cross-site scripting (XSS) and SQL injection.
Now, let's break down the concepts used in the provided code snippet:
-
JavaScript (JS): The code is primarily written in JavaScript, a high-level programming language commonly used for web development. JavaScript enables the creation of dynamic, interactive web pages and is supported by all modern web browsers.
-
jQuery: jQuery is a fast, small, and feature-rich JavaScript library. It simplifies tasks like HTML document traversal and manipulation, event handling, and animation, making it easier to develop web applications.
-
Ajax (Asynchronous JavaScript and XML): The code includes Ajax calls, which allow asynchronous communication between the web browser and the server. This enables the retrieval of data from the server without requiring a full page reload, improving the user experience.
-
JSON (JavaScript Object Notation): JSON is a lightweight data interchange format used to transmit data between a server and a web application. It is human-readable and easy for both humans and machines to understand.
-
RESTful API: The code interacts with a RESTful API (Representational State Transfer), which is an architectural style for designing networked applications. RESTful APIs use HTTP requests to perform CRUD (Create, Read, Update, Delete) operations on resources.
-
HTML (Hypertext Markup Language): HTML is the standard markup language for creating web pages and web applications. It is used to structure the content of web pages using elements such as headings, paragraphs, links, and forms.
-
CSS (Cascading Style Sheets): CSS is a stylesheet language used to style the visual presentation of HTML elements on a web page. It defines how HTML elements should be displayed, including layout, colors, fonts, and animations.
-
DOM (Document Object Model): The code interacts with the DOM, which is a programming interface for web documents. It represents the structure of a document as a tree of objects, allowing JavaScript to dynamically access and manipulate the content and structure of a web page.
-
CRUD (Create, Read, Update, Delete): CRUD operations are fundamental data manipulation operations used in database management and web development. They correspond to the basic actions that can be performed on data: creating, reading, updating, and deleting records.
-
CSRF (Cross-Site Request Forgery) Token: The code includes CSRF tokens, which are used to protect against CSRF attacks. CSRF tokens are unique, unpredictable values generated by the server and included in HTTP requests to verify the authenticity of the request.
These concepts collectively form the foundation of modern web development and are essential for building robust, interactive web applications.