Reddit Multi Colum

Multi column layout for reddit redesign

Versión del día 23/8/2018. Echa un vistazo a la versión más reciente.

// ==UserScript==
// @name         Reddit Multi Colum
// @namespace    http://tampermonkey.net/
// @version      0.1.2
// @description  Multi column layout for reddit redesign
// @author       Can Altıparmak
// @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 = false;

    const OUTER = [
        '#SHORTCUT_FOCUSABLE_DIV > div > div:nth-child(2) > div > div > div > div:nth-child(2) > div:nth-child(3) > div:nth-child(1)',
        '#SHORTCUT_FOCUSABLE_DIV > div > div:nth-child(2) > div > div > div > div > div:nth-child(2) > div:nth-child(3) > div:nth-child(1)']
    const cardButton = () => document.querySelector('#layoutSwitch--card');

    const select = function() {
        let outer = null;
        for (let o of OUTER) {
            outer = document.querySelector(o);
            if (outer !== null) break;
        }
        let inner = outer !== null ? outer.firstChild.firstChild : null;
        return { outer, inner };
    }

    const makeLayout = function() {
        const c = cleanup;
        const { outer, inner } = select();
        if (inner === null) return;

        const cols = Math.floor(inner.offsetWidth / MIN_WIDTH);
        //if (cols === columns) return;

        if (c) {
            outer.style.width = '';
            inner.removeAttribute("style");
        } else {
            outer.style.width = "100%";
            inner.setAttribute("style", "display: flex; width: 100%; flex-flow: column wrap; position: relative;");
        }

        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++) {
            let post = posts[i];
            let col = i % columns;
            post.style.position = c ? "" : "absolute";
            post.style.width = c ? "" : `${WIDTH}%`;
            post.style.left = c ? "" : `${col*(WIDTH+1)}%`;
            post.style.top = c ? "" : `${heights[col]}px`;
            heights[col] += post.offsetHeight;
        }
        inner.style.height = c ? "" : `${Math.max(...heights)}px`;
    };

    const setLayout = function(changes, observer) {
        const button = cardButton();
        cleanup = button.getAttribute("aria-pressed") === "false";

        makeLayout();
    };

    const pageChange = new MutationObserver(makeLayout);
    const resize = new ResizeObserver(makeLayout);
    const layoutSwitch = new MutationObserver(setLayout);

    const watch = function(changes, observer) {
        const { inner } = select();
        if (inner === null) return;
        layoutSwitch.observe(cardButton(), {attributes: true});
        pageChange.observe(inner, {childList: true});
        resize.observe(inner, {childList: true});
    };

    const apply = new MutationObserver(watch);
    const page = document.querySelector('#SHORTCUT_FOCUSABLE_DIV > div > div:nth-child(2)');
    apply.observe(page, {childList: true, subtree: true});

    watch();
    setLayout();
})();