NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name WorldCat Fast-Add-to-List // @version 0.1 // @author Michael Kazin // @namespace https://openuserjs.org/users/mkazin // @description Adds names of existing Lists on title elements for fast adding (skip the extra dialog) // @license BSD-3-Clause // @match https://www.worldcat.org/search?* // @icon https://www.google.com/s2/favicons?sz=64&domain=worldcat.org // @grant none // @run-at document-idle // ==/UserScript== // TODO: add support for institutional investors (currently being hardcoded to False) const LISTS_REQUEST_URL="https://www.worldcat.org/api/lists?limit=100&offset=1&orderBy=name-asc&listName=&isInstitutionalUser=false" const ADD_BUTTON_CONTAINER_CLASS = ".MuiButton-startIcon.MuiButton-iconSizeMedium" const ITEM_TITLE_CLASS = 'div h2 a' const ITEM_CONTAINER_CLASS = '.MuiGrid-item' const SEARCH_CHECK_INTERVAL = 2500 let lists = new Map() let listsContainer // Builds lists map of List Name to List ID function queryLists() { fetch(LISTS_REQUEST_URL) .then((response) => response.json()) .then((data) => { lists = new Map(data.listsData.entries.map( (entry) => [entry.id, entry.listName])) }) } function buildExistingListsContainers() { Array.from(document.querySelectorAll(ADD_BUTTON_CONTAINER_CLASS)).forEach(container => { const itemId = container.closest(ITEM_CONTAINER_CLASS).querySelector(ITEM_TITLE_CLASS).href.split('/').at(-1) let listContainer = document.createElement("div") let containerLabel = document.createElement("span") containerLabel.innerText = "Quick Add to List: " listContainer.append(containerLabel) lists.forEach( (listName, listId) => { let listLink = document.createElement("span") listLink.innerText = listName listLink.style.color = 'blue' listLink.onclick = () => { const post_url = `https://www.worldcat.org/api/lists/${listId}?listId=${listId}&itemId=${itemId}&isInstitutionalUser=false` fetch(post_url, { method: 'POST' }).then((response) => console.log(response)) } listContainer.append(listLink) }) container.closest(".MuiBox-root").append(listContainer) }) } var search_interval function startSearchInterval() { search_interval = setInterval(checkSearchCompletion, SEARCH_CHECK_INTERVAL) } function checkSearchCompletion() { if (document.querySelectorAll(ITEM_TITLE_CLASS).length > 0) { clearInterval(search_interval) onSearchCompletion() } } function onSearchCompletion() { buildExistingListsContainers() } (function() { 'use strict'; startSearchInterval() queryLists() })();