#6057 hyperkitty does not use a fixed-width font for e-mails
Closed: Upstream 6 years ago Opened 6 years ago by till.

I noticed that when a look at the orphaned packages reports the mails look very messy in hyperkitty:
https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org/thread/R6VRNIVSURTIOBJHYIDJD6ZHNJ5L7WX2/

This is because it is a ASCII art table and hyperkitty does not use a fixed-width font. Is there a way to get a link to these messages with a fixed-width font so people could properly read them? Would it be a possibility to always use a fixed-width font?


Would you be willing to file this upstream? I don't think there's any way to do this currently, but perhaps something could be implemented upstream...

https://gitlab.com/mailman/hyperkitty/issues

@abompard feel free to chime in if I am wrong here.

:school_satchel:

Metadata Update from @kevin:
- Issue tagged with: lists

6 years ago

This is rather trivial to alter with a greasemonkey script.

In general it's tough to tell when an email should be rendered with a fixed-width font; I never really came up with a good solution back when I used to write mailing list software. I've always considered it safe to render text/plain; format="flowed" bodies with a proportional font and use monospace otherwise. I would assume hyperkitty has access to that information but maybe the developers don't agree.

Here's the quickest of quick hacks:

// ==UserScript==
// @name        Hyperkitty monospace
// @namespace   tibbs@fedoraproject.org
// @description Makes Hyperkitty email bodies render in monospace
// @include     https://lists.fedoraproject.org/archives/
// @version     1
// @grant       none
// ==/UserScript==

$('.email-body').css({'font-family': 'monospace'})

Oops, make that:

// ==UserScript==
// @name        Hyperkitty monospace
// @namespace   tibbs@fedoraproject.org
// @description Makes Hyperkitty email bodies render in monospace
// @match       *://lists.fedoraproject.org/archives/list/* 
// @version     1
// @grant       none
// ==/UserScript==

$('.email-body').css({'font-family': 'monospace'})

It appears to work without having to use
// @require https://code.jquery.com/jquery-3.1.1.min.js
but I've never been entirely sure how safe that is.

Sorry to spam but only repo owners can edit comments....

Anyway, that one works but hyperkitty loads threads via XHR so.... this one will get all email bodies as they load.

// ==UserScript==
// @name        Hyperkitty monospace
// @namespace   tibbs@fedoraproject.org
// @description Makes Hyperkitty email bodies render in monospace
// @match       *://lists.fedoraproject.org/archives/list/* 
// @version     1
// @grant       none
// ==/UserScript==

/*--- waitForKeyElements(): 
    JLT - Grabbed from https://gist.github.com/BrockA/2625891

*/
function waitForKeyElements (
    selectorTxt,    /* Required: The jQuery selector string that
                        specifies the desired element(s).
                    */
    actionFunction, /* Required: The code to run when elements are
                        found. It is passed a jNode to the matched
                        element.
                    */
    bWaitOnce,      /* Optional: If false, will continue to scan for
                        new elements even after the first match is
                        found.
                    */
    iframeSelector  /* Optional: If set, identifies the iframe to
                        search.
                    */
) {
    var targetNodes, btargetsFound;

    if (typeof iframeSelector == "undefined")
        targetNodes     = $(selectorTxt);
    else
        targetNodes     = $(iframeSelector).contents ()
                                           .find (selectorTxt);

    if (targetNodes  &&  targetNodes.length > 0) {
        btargetsFound   = true;
        /*--- Found target node(s).  Go through each and act if they
            are new.
        */
        targetNodes.each ( function () {
            var jThis        = $(this);
            var alreadyFound = jThis.data ('alreadyFound')  ||  false;

            if (!alreadyFound) {
                //--- Call the payload function.
                var cancelFound     = actionFunction (jThis);
                if (cancelFound)
                    btargetsFound   = false;
                else
                    jThis.data ('alreadyFound', true);
            }
        } );
    }
    else {
        btargetsFound   = false;
    }

    //--- Get the timer-control variable for this selector.
    var controlObj      = waitForKeyElements.controlObj  ||  {};
    var controlKey      = selectorTxt.replace (/[^\w]/g, "_");
    var timeControl     = controlObj [controlKey];

    //--- Now set or clear the timer as appropriate.
    if (btargetsFound  &&  bWaitOnce  &&  timeControl) {
        //--- The only condition where we need to clear the timer.
        clearInterval (timeControl);
        delete controlObj [controlKey]
    }
    else {
        //--- Set a timer, if needed.
        if ( ! timeControl) {
            timeControl = setInterval ( function () {
                    waitForKeyElements (    selectorTxt,
                                            actionFunction,
                                            bWaitOnce,
                                            iframeSelector
                                        );
                },
                300
            );
            controlObj [controlKey] = timeControl;
        }
    }
    waitForKeyElements.controlObj   = controlObj;
}

function makeMonospace(n) {
    n.css({'font-family': 'monospace'})
}

waitForKeyElements("div.email-body", makeMonospace);

Sorry to spam but only repo owners can edit comments....

Anyway, that one works but hyperkitty loads threads via XHR so.... this one will get all email bodies as they load.

// ==UserScript==
// @name        Hyperkitty monospace
// @namespace   tibbs@fedoraproject.org
// @description Makes Hyperkitty email bodies render in monospace
// @match       *://lists.fedoraproject.org/archives/list/* 
// @version     1
// @grant       none
// ==/UserScript==

// Grabbed from https://gist.github.com/BrockA/2625891
function waitForKeyElements (selectorTxt, actionFunction, bWaitOnce, iframeSelector) {
    var targetNodes, btargetsFound;

    if (typeof iframeSelector == "undefined")
        targetNodes     = $(selectorTxt);
    else
        targetNodes     = $(iframeSelector).contents ()
                                           .find (selectorTxt);

    if (targetNodes  &&  targetNodes.length > 0) {
        btargetsFound   = true;
        targetNodes.each ( function () {
            var jThis        = $(this);
            var alreadyFound = jThis.data ('alreadyFound')  ||  false;

            if (!alreadyFound) {
                //--- Call the payload function.
                var cancelFound     = actionFunction (jThis);
                if (cancelFound)
                    btargetsFound   = false;
                else
                    jThis.data ('alreadyFound', true);
            }
        } );
    }
    else {
        btargetsFound   = false;
    }
    //--- Get the timer-control variable for this selector.
    var controlObj      = waitForKeyElements.controlObj  ||  {};
    var controlKey      = selectorTxt.replace (/[^\w]/g, "_");
    var timeControl     = controlObj [controlKey];

    //--- Now set or clear the timer as appropriate.
    if (btargetsFound  &&  bWaitOnce  &&  timeControl) {
        //--- The only condition where we need to clear the timer.
        clearInterval (timeControl);
        delete controlObj [controlKey]
    }
    else {
        //--- Set a timer, if needed.
        if ( ! timeControl) {
            timeControl = setInterval ( function () {
                    waitForKeyElements (    selectorTxt,
                                            actionFunction,
                                            bWaitOnce,
                                            iframeSelector
                                        );
                },
                300
            );
            controlObj [controlKey] = timeControl;
        }
    }
    waitForKeyElements.controlObj   = controlObj;
}

function makeMonospace(n) {
    n.css({'font-family': 'monospace'})
}

waitForKeyElements("div.email-body", makeMonospace);

Thank you for the greasemonkey script. The problem with it is that I would like to be able to give other people a link to an e-mail where they can properly look at them. For this they would need to use greasemonkey :-/

I filed this upstream here:
https://gitlab.com/mailman/hyperkitty/issues/133

I had made a PR for fixed-font to hyperkitty, probably that should fix the issue. :v:

Awesome. Thanks for that!

:eight_pointed_black_star:

And I just merged @sayanchowdhury 's PR. It will be deployed next time I update the stack in production.

And I just merged @sayanchowdhury 's PR. It will be deployed next time I update the stack in production.

Login to comment on this ticket.

Metadata