const getBookmarks = async (csrfToken) => { const bookmarksResponse = await fetch("https://codepen.io/graphql", { signal: AbortSignal.timeout(5000), credentials: "include", headers: { Accept: "application/graphql-response+json,application/json;q=0.9", "content-type": "application/json", "x-csrf-token": csrfToken, "x-requested-with": "XMLHttpRequest", "Sec-Fetch-Dest": "empty", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Site": "same-origin", }, body: '[{"operationName":"ItemsBookmarked","variables":{},"extensions":{"clientLibrary":{"name":"@apollo/client","version":"4.0.9"}},"query":"query ItemsBookmarked { itemsBookmarked { id }}"}]', method: "POST", mode: "cors", }); const bookmarksResponseJSON = await bookmarksResponse.json(); const bookmarks = bookmarksResponseJSON.data.itemsBookmarked .map((bookmark) => bookmark.id) .reverse(); return bookmarks; }; const createCollection = async (csrfToken, collectionName) => { const collectionResponse = await fetch("https://codepen.io/graphql", { credentials: "include", headers: { Accept: "application/graphql-response+json,application/json;q=0.9", "content-type": "application/json", "x-csrf-token": csrfToken, "x-requested-with": "XMLHttpRequest", "Sec-Fetch-Dest": "empty", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Site": "same-origin", }, body: '[{"operationName":"CollectionCreate","variables":{"input":{"description":"","isPrivate":false,"title":"' + collectionName + '","collectionType":"Item"}},"extensions":{"clientLibrary":{"name":"@apollo/client","version":"4.0.9"}},"query":"mutation CollectionCreate($input: CollectionCreateInput!) {\\n collectionCreate(input: $input) {\\n collection {\\n id\\n ...CollectionListFields\\n __typename\\n }\\n item {\\n id\\n ... on Pen {\\n cpid\\n __typename\\n }\\n __typename\\n token\\n }\\n __typename\\n }\\n}\\n\\nfragment CollectionListFields on Collection {\\n id\\n}"}]', method: "POST", mode: "cors", }); const collectionResponseJSON = await collectionResponse.json(); const collectionId = collectionResponseJSON.data.collectionCreate.collection.id; return collectionId; }; const addPenToCollection = (csrfToken, penId, collectionId) => fetch("https://codepen.io/graphql", { credentials: "include", headers: { Accept: "application/graphql-response+json,application/json;q=0.9", "content-type": "application/json", "x-csrf-token": csrfToken, "x-requested-with": "XMLHttpRequest", "Sec-Fetch-Dest": "empty", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Site": "same-origin", }, body: '[{"operationName":"CollectionItemCreate","variables":{"input":{"collectionId":"' + collectionId + '","itemId":"' + penId + '","itemType":"Pen","itemToken":null}},"extensions":{"clientLibrary":{"name":"@apollo/client","version":"4.0.9"}},"query":"mutation CollectionItemCreate($input: CollectionItemCreateInput!) {\\n collectionItemCreate(input: $input) {\\n collection {\\n collectionType\\n counts {\\n items\\n __typename\\n }\\n id\\n title\\n url\\n updatedAt\\n __typename\\n }\\n __typename\\n }\\n}"}]', method: "POST", mode: "cors", }); const importBookmarksToCollection = async ( csrfToken, bookmarks, collectionId, ) => { for (const [i, penId] of bookmarks.entries()) { sendMessage("Importing bookmark " + (i + 1) + "/" + bookmarks.length + "…"); await addPenToCollection(csrfToken, penId, collectionId); } }; const openCollection = (id) => { sendMessage("Opening the collection…"); window.location = "https://codepen.io/collection/" + id; sendMessage("Have a nice day :)"); document.getElementById("cpb2c").remove(); }; const sendMessage = async (content) => { browser.runtime.sendMessage({ action: "updatePopup", content, }); document.getElementById("cpb2c").textContent = content; }; browser.runtime.onMessage.addListener(async (message, sender, sendResponse) => { if (message.action !== "importCodePenBookmarks") { return; } const div = document.createElement("div"); div.id = "cpb2c"; div.style.position = "fixed"; div.style.top = 0; div.style.left = 0; div.style.right = 0; div.style.bottom = 0; div.style.display = "flex"; div.style.justifyContent = "center"; div.style.alignItems = "center"; div.style.backgroundColor = "rgba(0, 0, 0, 0.75)"; div.style.zIndex = 777; div.textContent = "Importing bookmarks…"; document.querySelector("body").append(div); const csrfTokenElement = document.querySelector("meta[name='csrf-token']"); const csrfToken = csrfTokenElement.getAttribute("content"); const bookmarks = await getBookmarks(csrfToken); const collectionName = "Bookmarks"; const collectionId = await createCollection(csrfToken, collectionName); await importBookmarksToCollection(csrfToken, bookmarks, collectionId); openCollection(collectionId); });