diff --git a/.gitignore b/.gitignore index 92bfcba..72d4b6b 100644 --- a/.gitignore +++ b/.gitignore @@ -134,4 +134,7 @@ dist .yarn/unplugged .yarn/build-state.yml .yarn/install-state.gz -.pnp.* \ No newline at end of file +.pnp.* + +# VSCode preferences +.vscode/ \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index c25dfef..0000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "wp-build", - "group": { - "kind": "build", - "isDefault": true - }, - "problemMatcher": [], - "label": "npm: wp-build", - "detail": "webpack" - }, - { - "type": "npm", - "script": "install", - "group": "none", - "problemMatcher": [], - "label": "npm: install", - "detail": "install dependencies from package" - } - ] -} \ No newline at end of file diff --git a/css/redditChanges.css b/css/redditChanges.css index 67e5792..754dee1 100644 --- a/css/redditChanges.css +++ b/css/redditChanges.css @@ -22,7 +22,7 @@ max-width: unset !important; } .midcol { - margin: 0; + margin: 0 !important; } .sitetable.linklisting > .thing:not(.comment) { display: flex; diff --git a/css/subreddit_sidebar.css b/css/subredditSidebar.css similarity index 87% rename from css/subreddit_sidebar.css rename to css/subredditSidebar.css index 33994d6..4070fbd 100644 --- a/css/subreddit_sidebar.css +++ b/css/subredditSidebar.css @@ -16,7 +16,7 @@ padding-right: 10px; } -#sidebar-toggle { +#custom-sidebar-close { position: sticky; display: none; flex-direction: column; @@ -25,10 +25,10 @@ text-align: center; background-color: rgba(0, 0, 0, 0.5); } -#sidebar-toggle::before { +#custom-sidebar-close::before { font-size: 1.5em; } -#custom-sidebar.active #sidebar-toggle { +#custom-sidebar.active #custom-sidebar-close { display: flex; } #custom-sidebar.active { @@ -38,7 +38,7 @@ display: block; width: 80%; } -#custom-sidebar.active #sidebar-toggle { +#custom-sidebar.active #custom-sidebar-close { flex-grow: 1; } #custom-sidebar.showingup .side { diff --git a/css/userSidebar.css b/css/userSidebar.css index 466e8fb..f62d2ff 100644 --- a/css/userSidebar.css +++ b/css/userSidebar.css @@ -12,6 +12,7 @@ #user-sidebar .side { display: none; overflow-y: scroll; + background-color: var(--md-sys-color-surface); margin-left: 0px; margin-right: 0px; } @@ -31,9 +32,6 @@ display: block; width: 80%; } -#user-sidebar-open:before { - content: "menu"; -} #user-sidebar-open { width: 40px; height: 40px; diff --git a/dev/my_style_loader/index.js b/dev/my_style_loader/index.js new file mode 100644 index 0000000..4f4b605 --- /dev/null +++ b/dev/my_style_loader/index.js @@ -0,0 +1,16 @@ +path = require("path"); + +module.exports = { + pitch: function (request) { + const insertStylePath = this.utils.contextify( + this.context, path.resolve(__dirname, "./insertStyle.js")); + const cssPath = this.utils.contextify(this.context, `!!${request}`); + + const outputJs = ` + import insertStyle from ${JSON.stringify(insertStylePath)}; + import content from ${JSON.stringify(cssPath)}; + insertStyle(content.toString()); + `; + return outputJs; + }, +}; diff --git a/dev/my_style_loader/insertStyle.js b/dev/my_style_loader/insertStyle.js new file mode 100644 index 0000000..b41659b --- /dev/null +++ b/dev/my_style_loader/insertStyle.js @@ -0,0 +1,17 @@ +export default function insertStyle(style) { + var element = document.createElement("style"); + element.innerText = style; + if (document.head) { + document.head.appendChild(element); + return; + } + var observer = new MutationObserver(function () { + if (document.head) { + observer.disconnect(); + document.head.appendChild(element); + } + }); + observer.observe(document.documentElement, { + childList: true, + }); +} diff --git a/js/cs.js b/js/cs.js index 095059a..ebac246 100644 --- a/js/cs.js +++ b/js/cs.js @@ -1,7 +1,2 @@ import "./setPublicPath.js"; -import "./general.js"; -import "./header.js"; -import "./sidebars.js"; -import "./posts"; -import "./preferences.js"; -console.log("Content script loaded."); +import "./user.js"; diff --git a/js/general.js b/js/general.js deleted file mode 100644 index 250b90a..0000000 --- a/js/general.js +++ /dev/null @@ -1,30 +0,0 @@ -import "~/css/hideAds.css"; -import "~/css/redditChanges.css"; -import "~/css/customUi.css"; -import "~/css/resFullscreenGallery.css"; -import "~/css/material/theme.css"; -import "~/css/res-compat.css"; -import "~/css/comments.css"; -import "material-symbols/outlined.css"; - -function neuterSubredditCss() { - try { - document - .querySelector("link[title=applied_subreddit_stylesheet]") - .remove(); - } catch (e) { - console.log("failed to remove subreddit stylesheet"); - } -} - -function materialize() { - document.body.classList.add("background", "on-background-text"); -} - -neuterSubredditCss(); -materialize(); -// over18 -if (!document.cookie.includes("over18=1")) { - console.log("over18 not set, setting"); - document.cookie = "over18=1"; -} diff --git a/js/header.js b/js/header.js index 613e2f4..2422835 100644 --- a/js/header.js +++ b/js/header.js @@ -1,58 +1,16 @@ import "~/css/header.css"; import modal from "./modal"; -function makeSortSelector() { - // remove old selectors if exist - document - .querySelectorAll("#sortsel") - .forEach((el) => el.parentElement.removeChild(el)); - const options = {}; - const header = document.querySelector("#ol-header"); +import querySelectorAsync from "./utility/querySelectorAsync"; - for (const tab of document.querySelectorAll(".tabmenu li")) { - if ( - tab.innerText === "" || - tab.innerText.includes("show images") || - !tab.innerText.trim().length - ) { - continue; - } - console.log(tab.innerText); - let itemtext = tab.innerText[0].toUpperCase() + tab.innerText.slice(1); - options[itemtext] = tab.children[0].href; - if (tab.classList.contains("selected")) { - header.querySelector(".sort-mode").innerText = tab.innerText; - } - } - if (options.length <= 1) { - return; - } - const optionmenu = document.createElement("ul"); - for (const [option_text, option_link] of Object.entries(options)) { - const optel = document.createElement("li"); - const optel_link = document.createElement("a"); - optel_link.classList.add("sortmodeselector"); - optel_link.href = option_link; - optel_link.innerText = option_text; - optel.appendChild(optel_link); - optionmenu.appendChild(optel); - } - const btn = document.createElement("button"); - btn.id = "sortsel"; - btn.classList.add("material-symbols-outlined"); - btn.innerText = "sort"; - header.querySelector(".aux-buttons").appendChild(btn); - btn.onclick = () => { - modal("Sort mode", optionmenu, () => {}); - }; -} -function setupOldLanderHeader() { +async function createHeader() { const oldheader = document.getElementById("ol-header"); if (oldheader != null) { oldheader.remove(); } const header = document.createElement("div"); header.id = "ol-header"; - document.body.insertBefore(header, document.getElementById("header")); + const body = await querySelectorAsync("body"); + body.insertBefore(header, await querySelectorAsync("#header")); header.innerHTML = `

@@ -63,11 +21,8 @@ function setupOldLanderHeader() { pageName === null ? "Homepage" : pageName.innerText; let prevScrollPos = window.scrollY; - - window.addEventListener("scroll", function () { - // current scroll position + function onScroll() { const currentScrollPos = window.scrollY; - if (prevScrollPos > currentScrollPos) { // user has scrolled up let playAnim = true; @@ -92,12 +47,59 @@ function setupOldLanderHeader() { header.classList.remove("stick"); }); } - // update previous scroll position prevScrollPos = currentScrollPos; - }); + } + window.addEventListener("scroll", onScroll); + + return header; +} + +function makeSortSelector(header) { + // remove old selectors if exist + document + .querySelectorAll("#sortsel") + .forEach((el) => el.parentElement.removeChild(el)); + + const options = {}; + for (const tab of document.querySelectorAll(".tabmenu li")) { + if ( + tab.innerText === "" || + tab.innerText.includes("show images") || + !tab.innerText.trim().length + ) { + continue; + } + let itemtext = tab.innerText[0].toUpperCase() + tab.innerText.slice(1); + options[itemtext] = tab.children[0].href; + if (tab.classList.contains("selected")) { + header.querySelector(".sort-mode").innerText = tab.innerText; + } + } + if (Object.keys(options).length <= 1) { + return; + } + const optionmenu = document.createElement("ul"); + for (const [option_text, option_link] of Object.entries(options)) { + const optel = document.createElement("li"); + const optel_link = document.createElement("a"); + optel_link.classList.add("sortmodeselector"); + optel_link.href = option_link; + optel_link.innerText = option_text; + optel.appendChild(optel_link); + optionmenu.appendChild(optel); + } + const btn = document.createElement("button"); + btn.id = "sortsel"; + btn.classList.add("material-symbols-outlined"); + btn.innerText = "sort"; + header.querySelector(".aux-buttons").appendChild(btn); + btn.onclick = () => { + modal("Sort mode", optionmenu, () => {}); + }; } -function addSubSidebarButton() { + +function addSubSidebarButton(header) { const btn = document.createElement("button"); btn.innerText = "info"; btn.classList.add("material-symbols-outlined"); @@ -105,8 +107,25 @@ function addSubSidebarButton() { const evt = new Event("toggleSub"); document.dispatchEvent(evt); }; - document.querySelector("#ol-header .aux-buttons").appendChild(btn); + header.querySelector(".aux-buttons").appendChild(btn); +} +function addUserSidebarButton(header){ + const btn = document.createElement("button"); + btn.innerText = "menu"; + btn.classList.add("material-symbols-outlined"); + btn.id = "user-sidebar-open"; + btn.onclick = () => { + const evt = new Event("toggleUser"); + document.dispatchEvent(evt); + }; + header.prepend(btn); } -setupOldLanderHeader(); -makeSortSelector(); -addSubSidebarButton(); + +async function setupOldLanderHeader() { + const header = await createHeader(); + makeSortSelector(header); + addSubSidebarButton(header); + addUserSidebarButton(header); +} + +setupOldLanderHeader(); \ No newline at end of file diff --git a/js/modal.js b/js/modal.js index decb1c0..b8c9b5c 100644 --- a/js/modal.js +++ b/js/modal.js @@ -1,9 +1,11 @@ import "~/css/modal.css"; + export default function createModal(title, contents, callback) { const oldmodal = document.getElementById("modal"); if (oldmodal !== null) { oldmodal.remove(); } + const modal = document.createElement("div"); modal.id = "modal"; modal.innerHTML = ` @@ -28,16 +30,18 @@ export default function createModal(title, contents, callback) { duration: 250, } ); - anim.addEventListener("finish", () => { + const onFinish = () => { console.log(anim.playState); - modal.removeEventListener("animationend"); + modal.removeEventListener("animationend", onFinish); modal.classList.add("hide"); - }); + }; + anim.addEventListener("finish", onFinish); }) ); modal.querySelector(".olmodal-buttons button.ok").onclick = callback; document.body.appendChild(modal); } + window.testModal = () => { const modalContents = document.createElement("div"); modalContents.innerHTML = diff --git a/js/posts/index.js b/js/posts/index.js index 5ff7302..2d3a070 100644 --- a/js/posts/index.js +++ b/js/posts/index.js @@ -2,63 +2,62 @@ import setupNativeShare from "./nativeSharing.js"; import setupToggles from "./postToggles.js"; import expando from "./expando.js"; import "~/css/postIcons.css"; +import { waitForAllElements } from "../utility/waitForElement.js"; -export default function setupPosts() { - for (const post of document.querySelectorAll( - ".sitetable.linklisting > .thing:not(.riok)" - )) { - try { - setupNativeShare(post); - } catch (e) { - console.error("Failed to setup native share", e); - } - try { - setupToggles(post); - } catch (e) { - console.error("Failed to setup toggles", e); - } - // trim comments to only first word (comment count) - const comments = post.querySelector(".comments"); - if (comments !== null) { - comments.innerText = comments.innerText.split(" ")[0]; - if (comments.innerText.includes("comment")) { - comments.innerText = "0"; - } +function setupPost(post) { + try { + setupNativeShare(post); + } catch (e) { + console.error("Failed to setup native share", e); + } + try { + setupToggles(post); + } catch (e) { + console.error("Failed to setup toggles", e); + } + // trim comments to only first word (comment count) + const comments = post.querySelector(".comments"); + if (comments !== null) { + comments.innerText = comments.innerText.split(" ")[0]; + if (comments.innerText.includes("comment")) { + comments.innerText = "0"; } - const expando_btn = post.querySelector(".expando-button"); - if (expando_btn !== null) { - if ( - expando_btn.getAttribute("title") === "Expando is not yet ready" - ) { - const attrObserver = new MutationObserver((mutations) => { - mutations.forEach((mu) => { - if ( - mu.type !== "attributes" && - mu.attributeName !== "class" - ) - return; - console.log("class was modified!"); - expando(post); - attrObserver.disconnect(); - }); + } + const expando_btn = post.querySelector(".expando-button"); + if (expando_btn !== null) { + if (expando_btn.getAttribute("title") === "Expando is not yet ready") { + const attrObserver = new MutationObserver((mutations) => { + mutations.forEach((mu) => { + if ( + mu.type !== "attributes" && + mu.attributeName !== "class" + ) + return; + console.log("class was modified!"); + expando(post); + attrObserver.disconnect(); }); - console.log( - "Expando is not ready yet, setting up mutation observer for", - expando_btn - ); - attrObserver.observe(expando_btn, { attributes: true }); - } else { - expando(post); - } + }); + console.log( + "Expando is not ready yet, setting up mutation observer for", + expando_btn + ); + attrObserver.observe(expando_btn, { attributes: true }); + } else { + expando(post); } + } - // remove thumbnail no-image indicator. Could be done with CSS, but FF doesn't support :has. - const thumbnail = post.querySelector(".thumbnail"); - if (thumbnail !== null && thumbnail.children.length === 0) { - thumbnail.remove(); - } - post.classList.add("riok"); + // remove thumbnail no-image indicator. Could be done with CSS, but FF doesn't support :has. + const thumbnail = post.querySelector(".thumbnail"); + if (thumbnail !== null && thumbnail.children.length === 0) { + thumbnail.remove(); } + post.classList.add("riok"); +} + +export default function setupPosts() { + waitForAllElements(".sitetable.linklisting > .thing:not(.riok)", setupPost); } + setupPosts(); -window.addEventListener("neverEndingLoad", setupPosts); diff --git a/js/preferences.js b/js/preferences.js index cae4a8c..191d2b6 100644 --- a/js/preferences.js +++ b/js/preferences.js @@ -1,12 +1,11 @@ -export function formatPrefTable() { - const table = document.querySelector("table.preftable"); - if (!table) { - return; - } +import querySelectorAsync from "./utility/querySelectorAsync"; + +export async function formatPrefTable() { + const table = await querySelectorAsync("table.preftable"); + const tableParent = table.parentNode; const prefDiv = document.createElement("div"); - tableParent.appendChild(prefDiv); - tableParent.removeChild(table); + tableParent.replaceChild(prefDiv, table); const tbody = table.firstChild; for (const row of tbody.childNodes) { const newRow = document.createElement("div"); @@ -22,4 +21,4 @@ export function formatPrefTable() { } } -formatPrefTable(); \ No newline at end of file +formatPrefTable(); diff --git a/js/sidebar/buildSidebar.js b/js/sidebar/buildSidebar.js new file mode 100644 index 0000000..6861c9b --- /dev/null +++ b/js/sidebar/buildSidebar.js @@ -0,0 +1,41 @@ +export default function buildSidebar( + innerSidebar, + sidebarId, + closeToggleId, + isOnLeft +) { + document.querySelectorAll(`#${sidebarId}`).forEach((el) => el.remove()); + + const sidebar = document.createElement("div"); + sidebar.id = sidebarId; + + innerSidebar.addEventListener("animationend", () => { + if (sidebar.classList.contains("abouttodie")) { + sidebar.classList.remove("active"); + } + sidebar.classList.remove("showingup", "abouttodie"); + }); + + function activeToggle() { + if (sidebar.classList.contains("active")) { + sidebar.classList.add("abouttodie"); + } else { + sidebar.classList.add("active", "showingup"); + } + } + const closeToggle = document.createElement("div"); + closeToggle.id = closeToggleId; + closeToggle.onclick = (e) => { + e.preventDefault(); + e.stopPropagation(); + activeToggle(); + }; + + if (isOnLeft) { + sidebar.append(innerSidebar, closeToggle); + } else { + sidebar.append(closeToggle, innerSidebar); + } + + return [activeToggle, sidebar]; +} diff --git a/js/sidebar/index.js b/js/sidebar/index.js new file mode 100644 index 0000000..b2370e3 --- /dev/null +++ b/js/sidebar/index.js @@ -0,0 +1,54 @@ +import "swiped-events"; +import buildSubredditSidebar from "./subredditSidebar.js"; +import buildUserSidebar from "./userSidebar.js"; + +const eventListeners = { + toggleUser: [], + toggleSub: [], + "swiped-right": [], + "swiped-left": [], +}; +let toggleSub, toggleUser, subSide, userSide; + +function setEventListener(type, listener) { + for (const currentListener of eventListeners[type]) { + document.removeEventListener(type, currentListener); + } + document.addEventListener(type, listener); + eventListeners[type] = [listener]; +} + +async function setupSubredditSidebar() { + [toggleSub, subSide] = await buildSubredditSidebar(); + setSidebarEvents(); +} +async function setupUserSidebar() { + [toggleUser, userSide] = await buildUserSidebar(); + setSidebarEvents(); +} + +function setSidebarEvents() { + if (toggleSub) { + setEventListener("toggleSub", toggleSub); + } + if (toggleUser) { + setEventListener("toggleUser", toggleUser); + } + setEventListener("swiped-right", function () { + if (subSide && subSide.classList.contains("active")) { + toggleSub(); + } else if (userSide && !userSide.classList.contains("active")) { + toggleUser(); + } + }); + setEventListener("swiped-left", function () { + if (userSide && userSide.classList.contains("active")) { + toggleUser(); + } else if (subSide && !subSide.classList.contains("active")) { + toggleSub(); + } + }); +} + +setupSubredditSidebar(); +setupUserSidebar(); diff --git a/js/sidebar/subredditSidebar.js b/js/sidebar/subredditSidebar.js new file mode 100644 index 0000000..abaa1ba --- /dev/null +++ b/js/sidebar/subredditSidebar.js @@ -0,0 +1,19 @@ +import "~/css/subredditSidebar.css"; +import querySelectorAsync from "../utility/querySelectorAsync"; +import buildSidebar from "./buildSidebar"; + +export default async function buildSubredditSidebar() { + const body = await querySelectorAsync("body"); + const actualSidebar = await querySelectorAsync("body > .side"); + actualSidebar.remove(); + + const [activeToggle, sidebar] = buildSidebar( + actualSidebar, + "custom-sidebar", + "custom-sidebar-close", + false + ); + + body.appendChild(sidebar); + return [activeToggle, sidebar]; +} diff --git a/js/user_sidebar.js b/js/sidebar/userSidebar.js similarity index 59% rename from js/user_sidebar.js rename to js/sidebar/userSidebar.js index a8d637b..ba042c7 100644 --- a/js/user_sidebar.js +++ b/js/sidebar/userSidebar.js @@ -1,5 +1,7 @@ import "~/css/userSidebar.css"; import localforage from "localforage"; +import querySelectorAsync from "../utility/querySelectorAsync"; +import buildSidebar from "./buildSidebar"; function createSidebarItem(text, link, icon, isActive) { const item = document.createElement("a"); @@ -27,22 +29,24 @@ function createSidebarItem(text, link, icon, isActive) { } return item; } -function createSidebarSep(text) { + +function createSidebarSubheading(text) { const item = document.createElement("p"); item.innerText = text; item.classList.add("sidebar-headline"); return item; } -function setupMultireddits(actualSidebar) { + +async function setupMultireddits(container) { + await querySelectorAsync(".multis"); const multis = document.querySelectorAll( '.multis > li > a:not([href="/r/multihub/"])' ); - console.log(multis); if (multis.length > 0) { - actualSidebar.appendChild(document.createElement("hr")); - actualSidebar.appendChild(createSidebarSep("Multireddits")); + container.appendChild(document.createElement("hr")); + container.appendChild(createSidebarSubheading("Multireddits")); for (const multi of multis) { - actualSidebar.appendChild( + container.appendChild( createSidebarItem( multi.innerText, multi.href, @@ -53,16 +57,11 @@ function setupMultireddits(actualSidebar) { } } } -async function setupSubreddits(actualSidebar) { + +async function setupSubreddits(container) { const age = parseInt(await localforage.getItem("subredditcache_age")); const now = Math.floor(Date.now() / 1000); const cached = JSON.parse(await localforage.getItem("subredditcache_act")); - console.log( - "cache test:", - age + 60 * 60 < now, - isNaN(age), - cached === null - ); let subs = []; if (age + 60 * 60 < now || isNaN(age) || cached === null) { console.log("Updating subreddit cache"); @@ -97,16 +96,16 @@ async function setupSubreddits(actualSidebar) { subs = cached; console.log("Subreddit cache is up to date, created at", age, subs); } - actualSidebar.appendChild(document.createElement("hr")); - actualSidebar.appendChild(createSidebarSep("Subreddits")); - actualSidebar.appendChild( + container.appendChild(document.createElement("hr")); + container.appendChild(createSidebarSubheading("Subreddits")); + container.appendChild( createSidebarItem("Random", "/r/random", "shuffle", false) ); - actualSidebar.appendChild( + container.appendChild( createSidebarItem("Random NSFW", "/r/randnsfw", "18_up_rating", false) ); for (const subreddit of subs) { - actualSidebar.appendChild( + container.appendChild( createSidebarItem( subreddit.data.display_name, subreddit.data.url, @@ -116,8 +115,12 @@ async function setupSubreddits(actualSidebar) { ); } } -function moveHeaderItems(actualSidebar) { - const rheader = document.getElementById("header-bottom-right"); + +async function buildHeaderItems(container) { + const rheader = await querySelectorAsync("#header-bottom-right"); + + container.appendChild(document.createElement("hr")); + const userlink = rheader.querySelector(".user a"); if (userlink.innerText.includes("Log in")) { const loginitem = createSidebarItem( @@ -127,14 +130,13 @@ function moveHeaderItems(actualSidebar) { false ); loginitem.addEventListener("click", () => { - const rheader = document.getElementById("header-bottom-right"); - const userlink = rheader.querySelector(".user a"); userlink.click(); }); - actualSidebar.appendChild(loginitem); + container.appendChild(loginitem); return; } - actualSidebar.appendChild( + + container.appendChild( createSidebarItem( userlink.text, userlink.href, @@ -142,12 +144,9 @@ function moveHeaderItems(actualSidebar) { location.href === userlink.href ) ); - const mail = document.getElementById("mail"); - let mailicon = "mark_email_unread"; - if (mail.classList.contains("nohavemail")) { - mailicon = "mail"; - } - actualSidebar.appendChild( + const mail = rheader.querySelector("#mail"); + let mailicon = mail.classList.contains("nohavemail") ? "mail" : "mark_email_unread"; + container.appendChild( createSidebarItem( "Messages", mail.href, @@ -156,7 +155,7 @@ function moveHeaderItems(actualSidebar) { ) ); const prefslink = "https://old.reddit.com/prefs/"; - actualSidebar.appendChild( + container.appendChild( createSidebarItem( "Preferences", prefslink, @@ -165,7 +164,7 @@ function moveHeaderItems(actualSidebar) { ) ); if (document.body.classList.contains("res")) { - actualSidebar.appendChild( + container.appendChild( createSidebarItem( "RES settings console", location.href + "#res:settings", @@ -181,65 +180,41 @@ function moveHeaderItems(actualSidebar) { false ); logoutItem.onclick = () => { - document.querySelector("form.logout a").click(); + rheader.querySelector("form.logout a").click(); }; - actualSidebar.appendChild(logoutItem); + container.appendChild(logoutItem); } -export default function setupSidebar() { - document.body.classList.remove("with-listing-chooser"); - const sidebar = document.createElement("div"); - const old_sidebar = document.getElementById("user_sidebar"); - if (old_sidebar !== null) { - old_sidebar.remove(); - } - document.body.appendChild(sidebar); - sidebar.id = "user-sidebar"; - function activeToggle(e) { - console.log("AT"); - if (e !== undefined) { - e.preventDefault(); - e.stopPropagation(); - } - if (sidebar.classList.contains("active")) { - sidebar.classList.add("abouttodie"); - } else { - sidebar.classList.add("active", "showingup"); - } - } - const actualSidebar = document.createElement("div"); - actualSidebar.innerHTML = ``; - sidebar.appendChild(actualSidebar); - actualSidebar.classList.add("side", "surface"); - actualSidebar.addEventListener("animationend", () => { - console.log("Animation ended", sidebar.classList); - if (sidebar.classList.contains("abouttodie")) { - sidebar.classList.remove("active"); - } - sidebar.classList.remove("showingup", "abouttodie"); - }); - const sb_open = document.createElement("button"); - sb_open.classList.add("material-symbols-outlined"); - const sb_open_old = document.getElementById("user-sidebar-open"); - if (sb_open_old !== null) { - sb_open_old.remove(); - } - sb_open.id = "user-sidebar-open"; - sb_open.onclick = activeToggle; - document.getElementById("ol-header").prepend(sb_open); - const sb_close = document.createElement("div"); - sb_close.id = "user-sidebar-close"; - sb_close.onclick = activeToggle; - sidebar.appendChild(sb_close); +export default async function buildUserSidebar() { + const body = await querySelectorAsync("body"); + body.classList.remove("with-listing-chooser"); + + const innerSidebar = document.createElement("div"); + const [activeToggle, sidebar] = buildSidebar( + innerSidebar, + "user-sidebar", + "user-sidebar-close", + true + ); - actualSidebar.appendChild( + innerSidebar.innerHTML = ``; + innerSidebar.classList.add("side"); + innerSidebar.appendChild( createSidebarItem("Homepage", "/", "home", location.pathname == "/") ); - actualSidebar.appendChild(document.createElement("hr")); - moveHeaderItems(actualSidebar); + const headerItems = document.createElement("div"); + innerSidebar.appendChild(headerItems); + const multireddits = document.createElement("div"); + innerSidebar.appendChild(multireddits); + const subreddits = document.createElement("div"); + innerSidebar.appendChild(subreddits); + + // do not await, let the items load in in their own time + buildHeaderItems(headerItems); + setupMultireddits(multireddits); + setupSubreddits(subreddits); - setupMultireddits(actualSidebar); - setupSubreddits(actualSidebar); + body.appendChild(sidebar); return [activeToggle, sidebar]; } diff --git a/js/sidebars.js b/js/sidebars.js deleted file mode 100644 index dbb9f69..0000000 --- a/js/sidebars.js +++ /dev/null @@ -1,31 +0,0 @@ -import setupSubredditSidebar from "./subreddit_sidebar.js"; -import setupUserSidebar from "./user_sidebar.js"; -function setupSidebars() { - const [toggleSub, subSide] = setupSubredditSidebar(); - const [toggleUser, userSide] = setupUserSidebar(); - document.addEventListener("toggleUser", toggleUser); - if (toggleSub) { - document.addEventListener("toggleSub", toggleSub); - } - document.addEventListener("swiped-right", function (e) { - // sidebar.classList.remove("active"); - if (subSide && subSide.classList.contains("active")) { - toggleSub(); - return; - } - if (!userSide.classList.contains("active")) { - toggleUser(); - } - }); - document.addEventListener("swiped-left", function (e) { - // sidebar.classList.add("active"); - if (userSide.classList.contains("active")) { - toggleUser(); - return; - } - if (subSide && !subSide.classList.contains("active")) { - toggleSub(); - } - }); -} -setupSidebars(); diff --git a/js/styling.js b/js/styling.js new file mode 100644 index 0000000..813b204 --- /dev/null +++ b/js/styling.js @@ -0,0 +1,32 @@ +import "~/css/hideAds.css"; +import "~/css/redditChanges.css"; +import "~/css/customUi.css"; +import "~/css/resFullscreenGallery.css"; +import "~/css/material/theme.css"; +import "~/css/res-compat.css"; +import "~/css/comments.css"; +import "material-symbols/outlined.css"; + +import querySelectorAsync from "./utility/querySelectorAsync"; + +async function removeSubredditStyling() { + const element = await querySelectorAsync( + "link[title=applied_subreddit_stylesheet]" + ); + element.remove(); + console.log("Subreddit stylesheet removed"); +} + +async function addBodyStyling() { + const body = await querySelectorAsync("body"); + body.classList.add("background", "on-background-text"); +} + +removeSubredditStyling(); +addBodyStyling(); + +// over18 +if (!document.cookie.includes("over18=1")) { + console.log("over18 not set, setting"); + document.cookie = "over18=1"; +} diff --git a/js/subreddit_sidebar.js b/js/subreddit_sidebar.js deleted file mode 100644 index 6487a61..0000000 --- a/js/subreddit_sidebar.js +++ /dev/null @@ -1,36 +0,0 @@ -import "swiped-events"; -import "~/css/subreddit_sidebar.css"; -export default function setupSidebar() { - const sidebar = document.createElement("div"); - const sidebarToggle = document.createElement("div"); - const actualSidebar = document.querySelector(".side"); - if (!actualSidebar) { - return [null, null]; - } - sidebarToggle.id = "sidebar-toggle"; - sidebar.id = "custom-sidebar"; - sidebar.appendChild(sidebarToggle); - sidebar.appendChild(actualSidebar); - document.querySelectorAll("#custom-sidebar").forEach((el) => el.remove()); - document.body.appendChild(sidebar); - function activeToggle() { - if (sidebar.classList.contains("active")) { - sidebar.classList.add("abouttodie"); - } else { - sidebar.classList.add("active", "showingup"); - } - } - sidebarToggle.onclick = (e) => { - e.preventDefault(); - // sidebar.classList.toggle("active"); - activeToggle(); - }; - actualSidebar.addEventListener("animationend", () => { - console.log("Animation ended", sidebar.classList); - if (sidebar.classList.contains("abouttodie")) { - sidebar.classList.remove("active"); - } - sidebar.classList.remove("showingup", "abouttodie"); - }); - return [activeToggle, sidebar]; -} diff --git a/js/user.js b/js/user.js index 3da5fdc..f97f41a 100644 --- a/js/user.js +++ b/js/user.js @@ -1,7 +1,7 @@ import "./viewport.js"; -import "./general.js"; +import "./styling.js"; import "./header.js"; -import "./sidebars.js"; +import "./sidebar"; import "./posts"; import "./preferences.js"; diff --git a/js/utility/querySelectorAsync.js b/js/utility/querySelectorAsync.js new file mode 100644 index 0000000..6490b64 --- /dev/null +++ b/js/utility/querySelectorAsync.js @@ -0,0 +1,7 @@ +import { waitForElement } from "./waitForElement"; + +export default function querySelectorAsync(selector) { + return new Promise((resolve, _reject) => { + waitForElement(selector, resolve); + }); +} diff --git a/js/utility/waitForElement.js b/js/utility/waitForElement.js new file mode 100644 index 0000000..d67737e --- /dev/null +++ b/js/utility/waitForElement.js @@ -0,0 +1,58 @@ +export function waitForElement(selector, callback) { + // see if element exists already + const element = document.querySelector(selector); + if (element) { + callback(element); + return; + } + // otherwise set up an observer + var observer = new MutationObserver(function (mutations) { + for (const mutation of mutations) { + for (const node of mutation.addedNodes) { + if (node.nodeType === Node.ELEMENT_NODE) { + // new nodes have been added, check them + const element = document.querySelector(selector); + if (element) { + observer.disconnect(); + callback(element); + } + return; + } + } + } + }); + observer.observe(document.documentElement, { + childList: true, + subtree: true, + }); +} + +export function waitForAllElements(selector, callback) { + // perform callback on already existing elements + for (const element of document.querySelectorAll(selector)) { + callback(element); + } + // then set up an observer + var observer = new MutationObserver(function (mutations) { + const foundElements = new Set(); + for (const mutation of mutations) { + for (const node of mutation.addedNodes) { + if (node.nodeType === Node.ELEMENT_NODE) { + if (node.matches(selector)) { + foundElements.add(node); + } + for (const element of node.querySelectorAll(selector)) { + foundElements.add(element); + } + } + } + } + for (const element of foundElements) { + callback(element); + } + }); + observer.observe(document.documentElement, { + childList: true, + subtree: true, + }); +} diff --git a/js/viewport.js b/js/viewport.js index cd9b755..661bee2 100644 --- a/js/viewport.js +++ b/js/viewport.js @@ -1,25 +1,11 @@ -function setViewport() { - const viewportCfg = document.createElement("meta"); - viewportCfg.setAttribute("name", "viewport"); - viewportCfg.setAttribute( +import querySelectorAsync from "./utility/querySelectorAsync"; + +async function setViewport() { + const viewportElement = await querySelectorAsync('head > meta[name="viewport"]'); + viewportElement.setAttribute( "content", "width=device-width,initial-scale=1.0, maximum-scale=1.0, user-scalable=no" ); - document.head.appendChild(viewportCfg); } -// https://stackoverflow.com/questions/26324624/wait-for-document-body-existence -(function () { - "use strict"; - var observer = new MutationObserver(function () { - if (document.head) { - // It exists now - setViewport(); - observer.disconnect(); - } - }); - observer.observe(document.documentElement, { childList: true }); -})(); -document.addEventListener("DOMContentLoaded", function onDOMContentLoaded() { - setViewport(); -}); +setViewport(); diff --git a/webpack.config.js b/webpack.config.js index c0c1eb3..f6300b6 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -26,14 +26,10 @@ const manifest = { "https://raw.githubusercontent.com/OctoNezd/oldlander/chrome-ota/updates.xml", web_accessible_resources: ["riok_assets/*"], content_scripts: [ - { - matches: ["*://old.reddit.com/*"], - js: ["./viewport.js"], - run_at: "document_start", - }, { matches: ["*://old.reddit.com/*"], js: ["./cs.js", "./vendors.js"], + run_at: "document_start", }, ], browser_specific_settings: { @@ -78,13 +74,12 @@ module.exports = (env, argv) => { }, entry: { cs: "./js/cs.js", - viewport: "./js/viewport.js", }, output: { filename: "[name].js", path: __dirname + "/dist", clean: true, - publicPath: "extension://aaaa", + publicPath: "extension://placeholder_not_real_path", }, plugins: [ new CopyPlugin({ @@ -96,7 +91,7 @@ module.exports = (env, argv) => { rules: [ { test: /\.css$/i, - use: ["style-loader", "css-loader"], + use: ["my-style-loader", "css-loader"], }, { test: /\.(woff(2)?|ttf|eot)$/, @@ -107,6 +102,14 @@ module.exports = (env, argv) => { }, ], }, + resolveLoader: { + alias: { + "my-style-loader": path.resolve( + __dirname, + "./dev/my_style_loader/index.js" + ), + }, + }, resolve: { alias: { "~": path.resolve(__dirname, "."),