Skip to content

Instantly share code, notes, and snippets.

@vbuaraujo
Last active September 27, 2024 11:26
Show Gist options
  • Select an option

  • Save vbuaraujo/bddb3b93a0b2b7e28e1b to your computer and use it in GitHub Desktop.

Select an option

Save vbuaraujo/bddb3b93a0b2b7e28e1b to your computer and use it in GitHub Desktop.

Revisions

  1. vbuaraujo revised this gist May 2, 2016. 1 changed file with 17 additions and 59 deletions.
    76 changes: 17 additions & 59 deletions unfix-all-the-toolbars.user.js
    Original file line number Diff line number Diff line change
    @@ -13,19 +13,11 @@ Based on https://stackoverflow.com/questions/13696100/greasemonkey-script-to-mak
    2015-02-17: Original version.
    2016-05-01: Added the styleWidth threshold heuristic.
    2016-05-02: The fight goes on. Keep track of dynamic changes to "fixed".
    The big problem here is we want to avoid unfixing *all* "position: fixed"
    elements, because some of them are fake popup windows which become quite
    unusable if you change them to "position: static". So we need some heuristic
    to distinguish "legitimate" fixed elements from gratuitous ones like navbars.
    Still some problems with weird cases where "bottom" is negative
    (e.g., https://slack-files.com/T03JT4FC2-F151AAF7A-13fe6f98da?nojsmode=1).
    I don't know how to handle this.
    This is really kind of an uphill battle, but there we go.
    */

    function numPixels(str) {
    @@ -37,63 +29,29 @@ function numPixels(str) {
    }
    }

    function pageAttributes() {
    function unfixAll() {
    var bodyStyle = window.getComputedStyle(document.body);
    if (bodyStyle === null) {
    console.log("bodyStyle is null :(");
    throw new Exception("bodyStyle is null :()");
    }
    var pageWidth = numPixels(bodyStyle.width);
    var pageHeight = numPixels(bodyStyle.height);
    var toolbarWidthThreshold = 0.6 * pageWidth;
    var pageHeight= numPixels(bodyStyle.height);
    var toolbarWidthThreshold = 0.8 * pageWidth;

    return ({
    bodyStyle: bodyStyle,
    pageWidth: pageWidth,
    pageHeight: pageHeight,
    toolbarWidthThreshold: toolbarWidthThreshold
    });
    }

    function unfixAll() {
    var attrs = pageAttributes();

    Array.forEach(
    /* Assorted selection of likely fixed elements, to avoid querying all elements */
    document.querySelectorAll("h1, h2, ul, ol, li, div, nav, header, footer, table, tbody, th, tr, td"),
    document.querySelectorAll("h1, h2, ul, ol, li, div, nav, header, footer"),
    function (el) {
    unfixElement(el, attrs);
    // Observe further changes.
    var observer = new MutationObserver(function (mutations) {
    mutations.forEach(function (mutation) {
    if (mutation.attributeName == "style") {
    console.log("Change in style: " + mutation.target);
    unfixElement(mutation.target, attrs);
    }
    })
    });
    observer.observe(el, { attributes: true });
    }
    );
    }

    function unfixElement(el, attrs) {
    var style = window.getComputedStyle(el);
    if (style.position === "fixed") {
    /* Avoid unfixing JavaScript popus like Twitter's "confirm retweet" window */
    if (style.display === "none" || style.visibility === "hidden") return;
    if (numPixels(style.width) < attrs.toolbarWidthThreshold) return;
    var style = window.getComputedStyle(el);
    if (style.position === "fixed") {
    /* Avoid unfixing JavaScript popus like Twitter's "confirm retweet" window */
    if (style.display === "none" || style.visibility === "hidden") return;
    if (numPixels(style.width) < toolbarWidthThreshold) return;

    // Try to select the best replacement for 'fixed'. Still breaks lots of things, though.
    if (numPixels(style.bottom) === 0 && numPixels(style.top) > 0) {
    //console.log("STATIC: " + el.id + " " + style.bottom + " " + style.top);
    el.style.position = "static"; // Use static for footers.
    }
    else {
    //console.log("ABSOLUTE: " + el.id + " " + style.bottom + " " + style.top);
    el.style.position = "absolute";
    }
    }
    // Try to select the best replacement for 'fixed'. Still breaks lots of things, though.
    if (numPixels(style.bottom) === 0 && numPixels(style.top) > 0)
    el.style.position = "static"; // Use static for footers.
    else
    el.style.position = "absolute";
    }
    });
    }

    window.addEventListener("load", unfixAll);
  2. vbuaraujo revised this gist May 2, 2016. 1 changed file with 59 additions and 17 deletions.
    76 changes: 59 additions & 17 deletions unfix-all-the-toolbars.user.js
    Original file line number Diff line number Diff line change
    @@ -13,11 +13,19 @@ Based on https://stackoverflow.com/questions/13696100/greasemonkey-script-to-mak
    2015-02-17: Original version.
    2016-05-01: Added the styleWidth threshold heuristic.
    2016-05-02: The fight goes on. Keep track of dynamic changes to "fixed".
    The big problem here is we want to avoid unfixing *all* "position: fixed"
    elements, because some of them are fake popup windows which become quite
    unusable if you change them to "position: static". So we need some heuristic
    to distinguish "legitimate" fixed elements from gratuitous ones like navbars.
    Still some problems with weird cases where "bottom" is negative
    (e.g., https://slack-files.com/T03JT4FC2-F151AAF7A-13fe6f98da?nojsmode=1).
    I don't know how to handle this.
    This is really kind of an uphill battle, but there we go.
    */

    function numPixels(str) {
    @@ -29,29 +37,63 @@ function numPixels(str) {
    }
    }

    function unfixAll() {
    function pageAttributes() {
    var bodyStyle = window.getComputedStyle(document.body);
    if (bodyStyle === null) {
    console.log("bodyStyle is null :(");
    throw new Exception("bodyStyle is null :()");
    }
    var pageWidth = numPixels(bodyStyle.width);
    var pageHeight= numPixels(bodyStyle.height);
    var toolbarWidthThreshold = 0.8 * pageWidth;
    var pageHeight = numPixels(bodyStyle.height);
    var toolbarWidthThreshold = 0.6 * pageWidth;

    return ({
    bodyStyle: bodyStyle,
    pageWidth: pageWidth,
    pageHeight: pageHeight,
    toolbarWidthThreshold: toolbarWidthThreshold
    });
    }

    function unfixAll() {
    var attrs = pageAttributes();

    Array.forEach(
    /* Assorted selection of likely fixed elements, to avoid querying all elements */
    document.querySelectorAll("h1, h2, ul, ol, li, div, nav, header, footer"),
    document.querySelectorAll("h1, h2, ul, ol, li, div, nav, header, footer, table, tbody, th, tr, td"),
    function (el) {
    var style = window.getComputedStyle(el);
    if (style.position === "fixed") {
    /* Avoid unfixing JavaScript popus like Twitter's "confirm retweet" window */
    if (style.display === "none" || style.visibility === "hidden") return;
    if (numPixels(style.width) < toolbarWidthThreshold) return;

    // Try to select the best replacement for 'fixed'. Still breaks lots of things, though.
    if (numPixels(style.bottom) === 0 && numPixels(style.top) > 0)
    el.style.position = "static"; // Use static for footers.
    else
    el.style.position = "absolute";
    }
    });
    unfixElement(el, attrs);
    // Observe further changes.
    var observer = new MutationObserver(function (mutations) {
    mutations.forEach(function (mutation) {
    if (mutation.attributeName == "style") {
    console.log("Change in style: " + mutation.target);
    unfixElement(mutation.target, attrs);
    }
    })
    });
    observer.observe(el, { attributes: true });
    }
    );
    }

    function unfixElement(el, attrs) {
    var style = window.getComputedStyle(el);
    if (style.position === "fixed") {
    /* Avoid unfixing JavaScript popus like Twitter's "confirm retweet" window */
    if (style.display === "none" || style.visibility === "hidden") return;
    if (numPixels(style.width) < attrs.toolbarWidthThreshold) return;

    // Try to select the best replacement for 'fixed'. Still breaks lots of things, though.
    if (numPixels(style.bottom) === 0 && numPixels(style.top) > 0) {
    //console.log("STATIC: " + el.id + " " + style.bottom + " " + style.top);
    el.style.position = "static"; // Use static for footers.
    }
    else {
    //console.log("ABSOLUTE: " + el.id + " " + style.bottom + " " + style.top);
    el.style.position = "absolute";
    }
    }
    }

    window.addEventListener("load", unfixAll);
  3. vbuaraujo revised this gist May 1, 2016. 1 changed file with 6 additions and 4 deletions.
    10 changes: 6 additions & 4 deletions unfix-all-the-toolbars.user.js
    Original file line number Diff line number Diff line change
    @@ -30,8 +30,10 @@ function numPixels(str) {
    }

    function unfixAll() {
    var pageWidth = numPixels(window.getComputedStyle(document.body).width);
    var toolbarThreshold = 0.8 * pageWidth;
    var bodyStyle = window.getComputedStyle(document.body);
    var pageWidth = numPixels(bodyStyle.width);
    var pageHeight= numPixels(bodyStyle.height);
    var toolbarWidthThreshold = 0.8 * pageWidth;

    Array.forEach(
    /* Assorted selection of likely fixed elements, to avoid querying all elements */
    @@ -41,10 +43,10 @@ function unfixAll() {
    if (style.position === "fixed") {
    /* Avoid unfixing JavaScript popus like Twitter's "confirm retweet" window */
    if (style.display === "none" || style.visibility === "hidden") return;
    if (numPixels(style.width) < toolbarThreshold) return;
    if (numPixels(style.width) < toolbarWidthThreshold) return;

    // Try to select the best replacement for 'fixed'. Still breaks lots of things, though.
    if (numPixels(style.bottom) === 0)
    if (numPixels(style.bottom) === 0 && numPixels(style.top) > 0)
    el.style.position = "static"; // Use static for footers.
    else
    el.style.position = "absolute";
  4. vbuaraujo revised this gist May 1, 2016. No changes.
  5. vbuaraujo revised this gist May 1, 2016. 1 changed file with 10 additions and 11 deletions.
    21 changes: 10 additions & 11 deletions unfix-all-the-toolbars.user.js
    Original file line number Diff line number Diff line change
    @@ -20,18 +20,17 @@ unusable if you change them to "position: static". So we need some heuristic
    to distinguish "legitimate" fixed elements from gratuitous ones like navbars.
    */

    function styleWidth(style) {
    var width = style.width;
    if (width.endsWith("px"))
    return Number(width.slice(0, -2));
    function numPixels(str) {
    if (str.endsWith("px"))
    return Number(str.slice(0, -2));
    else {
    console.log("unfix-all-the-toolbars: Computed width is not in pixels! " + width);
    return null;
    }
    }

    function unfixAll() {
    var pageWidth = styleWidth(window.getComputedStyle(document.body));
    var pageWidth = numPixels(window.getComputedStyle(document.body).width);
    var toolbarThreshold = 0.8 * pageWidth;

    Array.forEach(
    @@ -42,13 +41,13 @@ function unfixAll() {
    if (style.position === "fixed") {
    /* Avoid unfixing JavaScript popus like Twitter's "confirm retweet" window */
    if (style.display === "none" || style.visibility === "hidden") return;
    if (styleWidth(style) < toolbarThreshold) return;
    if (numPixels(style.width) < toolbarThreshold) return;

    el.style.position = "absolute";
    /* I tried using "absolute" in the past, but this breaks WordPress's footer.
    Using "static" breaks it too, but at least it doesn't get in the way. */
    /* 2016-05-01: 'position: static' breaks Twitter status/conversation pages.
    Oh well. Back to using absolute, for now. */
    // Try to select the best replacement for 'fixed'. Still breaks lots of things, though.
    if (numPixels(style.bottom) === 0)
    el.style.position = "static"; // Use static for footers.
    else
    el.style.position = "absolute";
    }
    });
    }
  6. vbuaraujo revised this gist May 1, 2016. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion unfix-all-the-toolbars.user.js
    Original file line number Diff line number Diff line change
    @@ -44,9 +44,11 @@ function unfixAll() {
    if (style.display === "none" || style.visibility === "hidden") return;
    if (styleWidth(style) < toolbarThreshold) return;

    el.style.position = "static";
    el.style.position = "absolute";
    /* I tried using "absolute" in the past, but this breaks WordPress's footer.
    Using "static" breaks it too, but at least it doesn't get in the way. */
    /* 2016-05-01: 'position: static' breaks Twitter status/conversation pages.
    Oh well. Back to using absolute, for now. */
    }
    });
    }
  7. vbuaraujo revised this gist May 1, 2016. 1 changed file with 31 additions and 6 deletions.
    37 changes: 31 additions & 6 deletions unfix-all-the-toolbars.user.js
    Original file line number Diff line number Diff line change
    @@ -8,22 +8,47 @@
    // ==/UserScript==


    // Based on https://stackoverflow.com/questions/13696100/greasemonkey-script-to-make-fixed-positioned-elements-static
    /*
    Based on https://stackoverflow.com/questions/13696100/greasemonkey-script-to-make-fixed-positioned-elements-static
    2015-02-17: Original version.
    2016-05-01: Added the styleWidth threshold heuristic.
    The big problem here is we want to avoid unfixing *all* "position: fixed"
    elements, because some of them are fake popup windows which become quite
    unusable if you change them to "position: static". So we need some heuristic
    to distinguish "legitimate" fixed elements from gratuitous ones like navbars.
    */

    function styleWidth(style) {
    var width = style.width;
    if (width.endsWith("px"))
    return Number(width.slice(0, -2));
    else {
    console.log("unfix-all-the-toolbars: Computed width is not in pixels! " + width);
    return null;
    }
    }

    function unfixAll() {
    var pageWidth = styleWidth(window.getComputedStyle(document.body));
    var toolbarThreshold = 0.8 * pageWidth;

    Array.forEach(
    /* Assorted selection of likely fixed elements, to avoid querying all elements */
    document.querySelectorAll("h1, h2, ul, ol, li, div, nav, header, footer"),
    function (el) {
    var style = window.getComputedStyle(el);
    if (style.position === "fixed" &&
    !(style.display === "none" || style.visibility === "hidden"))
    /* Avoid unfixing JavaScript popups like Twitter's "confirm retweet" window */
    {
    if (style.position === "fixed") {
    /* Avoid unfixing JavaScript popus like Twitter's "confirm retweet" window */
    if (style.display === "none" || style.visibility === "hidden") return;
    if (styleWidth(style) < toolbarThreshold) return;

    el.style.position = "static";
    /* I tried using "absolute" in the past, but this breaks WordPress's footer.
    Using "static" breaks it too, but at least it doesn't get in the way. */
    }
    });
    }

    window.addEventListener("load", unfixAll);
    window.addEventListener("load", unfixAll);
  8. vbuaraujo revised this gist Feb 17, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion unfix-all-the-toolbars.user.js
    Original file line number Diff line number Diff line change
    @@ -17,7 +17,7 @@ function unfixAll() {
    var style = window.getComputedStyle(el);
    if (style.position === "fixed" &&
    !(style.display === "none" || style.visibility === "hidden"))
    /* Avoid unfixing JavaScript popus like Twitter's "confirm retweet" window */
    /* Avoid unfixing JavaScript popups like Twitter's "confirm retweet" window */
    {
    el.style.position = "static";
    /* I tried using "absolute" in the past, but this breaks WordPress's footer.
  9. vbuaraujo created this gist Feb 17, 2015.
    29 changes: 29 additions & 0 deletions unfix-all-the-toolbars.user.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,29 @@
    // ==UserScript==
    // @name unfix-all-the-toolbars
    // @description Removes "position: fixed" style from elements, unfixing "toolbars" and the such.
    // @namespace http://inf.ufrgs.br/~vbuaraujo/
    // @include *
    // @version 1
    // @grant none
    // ==/UserScript==


    // Based on https://stackoverflow.com/questions/13696100/greasemonkey-script-to-make-fixed-positioned-elements-static

    function unfixAll() {
    Array.forEach(
    document.querySelectorAll("h1, h2, ul, ol, li, div, nav, header, footer"),
    function (el) {
    var style = window.getComputedStyle(el);
    if (style.position === "fixed" &&
    !(style.display === "none" || style.visibility === "hidden"))
    /* Avoid unfixing JavaScript popus like Twitter's "confirm retweet" window */
    {
    el.style.position = "static";
    /* I tried using "absolute" in the past, but this breaks WordPress's footer.
    Using "static" breaks it too, but at least it doesn't get in the way. */
    }
    });
    }

    window.addEventListener("load", unfixAll);