Skip to content

Instantly share code, notes, and snippets.

@c6p
Last active April 29, 2024 23:58
Show Gist options
  • Save c6p/463892bb243f611f2a3cfa4268c6435e to your computer and use it in GitHub Desktop.
Save c6p/463892bb243f611f2a3cfa4268c6435e to your computer and use it in GitHub Desktop.
Reddit Multi Column
// ==UserScript==
// @name Reddit Multi Column
// @namespace https://gist.github.com/c6p/463892bb243f611f2a3cfa4268c6435e
// @version 0.1.15
// @description Multi column layout for reddit redesign
// @author Can Altıparmak
// @homepageURL https://gist.github.com/c6p/463892bb243f611f2a3cfa4268c6435e
// @match https://www.reddit.com/*
// @grant none
// ==/UserScript==
/* jshint esversion: 6 */
(function() {
'use strict';
const MIN_WIDTH = 400;
const COLUMNS = 4;
let columns = COLUMNS;
let cleanup = null;
// https://codepen.io/jpkempf/pen/MbePGB
function debounce(fn, wait) {
var timeout;
return function() {
var context = this;
var args = arguments;
clearTimeout(timeout);
timeout = setTimeout(function() {
fn.apply(context, args);
}, wait);
};
}
const OUTER = '#SHORTCUT_FOCUSABLE_DIV > div > div > div > div > div:nth-child(2) > div:last-child'
const cardButton = () => document.querySelector('#layoutSwitch--card') // old
|| document.querySelector('#LayoutSwitch--picker > span:nth-child(2)') // new
const indexOfSmallest = function (a) {
let lowest = 0;
for (let i = 1; i<a.length; i++) {
if (a[i] < a[lowest]) lowest = i;
}
return lowest;
};
const select = function() {
let outer = document.querySelector(OUTER)
let inner = outer !== null ? outer.firstChild.firstChild : null
if (window.location.pathname === '/original/') // fix for OC
{
inner = outer.firstChild.firstChild.lastChild.previousSibling
}
else
{
while (inner.childElementCount <= 5) {
inner = inner.nextSibling
}
}
return { outer, inner };
}
const makeLayout = function(changes=[]) {
// TODO if changes not empty, update only changed
const { outer, inner } = select();
if (inner === null) return;
const c = cleanup;
if (c) {
outer.style = 'max-width: 100%'
outer.firstChild.removeAttribute("style");
inner.removeAttribute("style");
} else {
outer.style = 'width: 100%; max-width: 100%';
outer.firstChild.style = 'width: 100%; max-width: 100%';
inner.setAttribute("style", "width: 100%; position: relative;");
}
const cols = Math.floor(inner.offsetWidth / MIN_WIDTH);
//if (changes.length === 0 && cols === columns) return;
columns = cols;
const WIDTH = Math.floor((100-columns)/columns);
let posts = inner.children;
let heights = Array(columns).fill(0);
for (let i=0; i<posts.length; i++) {
const post = posts[i];
const col = indexOfSmallest(heights);
let s = post.style
s.position = c ? "" : "absolute";
s.width = c ? "" : `${WIDTH}%`;
s.left = c ? "" : `${col*(WIDTH+1)}%`;
s.top = c ? "" : `${heights[col]}px`;
s.zIndex = "10";
heights[col] += post.offsetHeight;
}
inner.style.height = c ? "" : `${Math.max(...heights)}px`;
};
const setLayout = function(changes, observer) {
const button = cardButton();
const c = button.nodeName === "BUTTON"
? button.getAttribute("aria-pressed") === "false" // old
: button.textContent !== "card" // new
console.warn(c)
if (c !== cleanup) {
cleanup = c;
window.requestAnimationFrame(makeLayout);
}
};
const pageChange = new MutationObserver(makeLayout);
window.addEventListener('resize', () => makeLayout());
const layoutSwitch = new MutationObserver(setLayout);
const watch = function(changes, observer) {
const { inner } = select();
if (inner === null) return;
pageChange.observe(inner, {childList: true});
layoutSwitch.observe(cardButton(), {attributes: true, subtree: true, characterData: true});
};
const apply = new MutationObserver(watch);
const page = document.querySelector('#SHORTCUT_FOCUSABLE_DIV');
apply.observe(page, {childList: true, subtree: true});
//watch();
setLayout();
window.requestAnimationFrame(makeLayout);
})();
@dmax511
Copy link

dmax511 commented Mar 16, 2022

ok thanks for looking into it

@Krokette
Copy link

it doesn't seem to work anymore. Is there a fix for it ?

@drhouse
Copy link

drhouse commented Apr 29, 2024

it doesn't seem to work anymore. Is there a fix for it ?

I started using this userscript Reddit 2023 Ui Revert to forward www.reddit.com to new.reddit.com, then add:
// @match https://new.reddit.com/*
to the top of Reddit Multi Column script and it will work again

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment