## “Modern” web design antipatterns

I am so fucking sick of modern web design where standard HTML form elements are reimplemented using <div> and Javascript.

For example: my mortgage provider just unleashed a new web design on the world. Functionally it’s identical to the old website, but it looks slightly shinier. It’s also completely non-functional for me.

When I try to log in, it gives me my wish-it-were-two-factor “secret question.” I enter my answer. I press Enter, and nothing happens. So I click the submit button – which is, as it turns out, a <div> with attached JavaScript. That JavaScript changes the <div> text to “please wait…” and then it sends off an asynchronous API request. When it gets the response from the server, it then changes the location URL in my browser.

Congratulations on reimplementing <form> the long way around!

Oh, and this process took way longer than it needed to, and I thought maybe it wasn’t working at all. So I opened up their contact form – which, as it turns out, only replaced the page content with that because of course everything’s a “single page application” now. I started filling it out, and when the first form submission finally came back, oops, suddenly I’m logged in! (Meaning I’ve now lost the contact form I was already halfway done filling out.)

So I opened up the contact form again in another tab, and found that I couldn’t tab into the requisite “state” drop down box (because of course I need to give my city and state to provide website feedback, for some reason). So I clicked on it, and tried typing “wa” – and nothing worked. It didn’t jump down to “Washington.” It didn’t even jump to “Washington” then back to “Alaska.” Oh, and of course cursor keys didn’t work either – I had to use my mouse to scroll and click and this hurts my wrist and is slow and error-prone. (Oh and I should add that there was no scroll bar on the selection box either, the expectation was that I’d know to use my scroll wheel and be able to! This is not something you can rely on!)

Because it turns out that the dropdown box, rather than being a <select>, was a fucking <div> with JavaScript to set the value. And doesn’t have any keyboard access. For bonus points, they invented some HTML tags like <dropdown> to contain it. Why?! Standards exist for a reason! What happens in some future HTML verson where the <dropdown> tag becomes a thing? Except it wouldn’t because fucking <select> already exists and has since HTML fucking 1 point 0.

Because, of course, they reimplemented <form> and <select> the long way around.

Why the fuck do people make their lives harder like this? Peering into the page source, everything was obviously built using Angular, which is just… bad. Really bad. I see so many Angular sites that do this. And there’s absolutely no reason for most Angular sites to be based on Angular.

It’s so maddening. You have to do more to get less functionality, that would already be handled by the browser in a cross-platform, humane, accessible manner!

So I sent them this message on their contact form:

Hi, your new website doesn’t function correctly in a number of web browsers, including Safari on macOS. After receiving the challenge question it simply hangs for several minutes. Also, your contact form no longer follows accessibility guidelines and doesn’t support keyboard entry for people with e.g. mobility impairments, and I suspect it won’t work correctly with many screen readers either.

Please don’t reimplement basic browser functionality; for example, there’s no reason for the <div class="dropdown"> with added JavaScript when browsers already have <select> widgets which work perfectly fine.

I bet they get back to me with something like “We apologize, but we only support the Chrome browser. Please download it at google.com/chrome” or something. Because we learned nothing after the whole debacle that was MSIE 6, apparently.

Anyway. Fuck modern web design. Make your shit out of plain old HTML. Seriously. Please. You can build asynchronous, self-updating sites using standard JavaScript and basic DOM methods without a lot of work, and that’s only in the case that you need to – and you probably don’t.

Not everything needs to be a fucking single-page “app,” for fuck’s sake. It buys you nothing except for a bad user experience when things don’t go perfectly.

## Sleep diagnosis

So, after many years of being aware of a problem with my sleep, I finally saw a sleep specialist. It was good to learn that whatever is going on can be figured out and treated.

What’s really frustrating is what led to me taking this long, and how much I’ve been shamed for having this disorder and how I’m yet still being shamed for having not taken care of it sooner.

## Computers were a mistake

What’s harder than setting up a new computer?

Re-setting up an account on the same computer.

## Plans for 2019

So, it’s a new year, huh.

Might as well share some brief outlines of what I hope to accomplish this year.

## Mobile Blogging with Publ and CodeAnywhere

Right now I’m sitting bored in a waiting room, so I decided to give CodeAnywhere a shot as a means of editing entries directly on my site, since that’s a use case I’ve mentioned as a possibility for the future.

Here are some of my observations as I run across them while writing this entry.

## Some more site template update thinguses

I’ve updated the Publ-templates-beesbuzz.biz repository, and also made it a lot easier for me to keep it up-to-date.

I also made it easier for me to put in webmention likes and stuff for things. And since this site is configured with fed.brid.gy support, maybe I can reply to Mastodon comments, like this one, which I have also marked as a “like” in this entry.

Anyway, boost it if you want to.

Update: fed.brid.gy continues to not actually behave in a way corresponding with how I expected. Oh well.

## More Authl thoughts

So, thinking about things more, the “profile URL” scheme doesn’t make sense for pure OAuth endpoints like Twitter, Facebook, etc. I’m thinking the API should provide two discovery mechanisms: one for profile-type (OpenID, IndieAuth/RelMeAuth, Mastodon), and one for SSO-type (OAuth).

## More fun with Webmentions

I ended up writing a little embed widget to embed webmention responses/reactions into my blog posts. It all happens client-side, but so do Disqus comments so I figure that’s okay.

It only works with webmention.io as the webmention endpoint (although it could be modified to work with any endpoint that speaks the same query API), and I suspect Aaron might end up being a skosh annoyed with how I actually implemented it, but whatever. :)

Anyway, if you find any bugs with it or want to make improvements, for now you can submit an issue against the Publ website repository or you can just, like, comment here or something. Update, 7/9/2019 I have moved this into its own GitHub repository.

## Authl: Yet another project I don’t have time for

So, I’ve started yet another web programming project, a generic authentication wrapper library for Python. Because I need something like this for Publ and just want to do it once.

## Medical terminology for trans healthcare

I am finally enrolled in Kaiser Permanente’s transgender healthcare program. (Why I didn’t get enrolled when I first signed up for it is a mystery, but whatever.) Today I finally received my insurance form for submitting reimbursement claims for my hair removal.

It gave me a diagnostic code of F649 with an explanation of “Uncomfortable with one’s gender.”

This is… not great phrasing.

## Reprogramming my sleep cycle

So because I’m starting the new job next week I figured it was time to get myself back on a compatible sleep schedule. In the past I’ve always done this by taking a dose of melatonin before bed to ease myself into going to bed early, and then try to continue to go to bed at a regular time every night. That usually works for about three days.

What I’m doing this time is attacking it from the other end: I have set my smart bed and Apple Watch to both wake me up at 8:00 every morning, both only on weekdays. The smart bed’s alarm comes through my phone (which charges on my nightstand) and happens during a shallow sleep phase during the half hour or so before the actual alarm time. This usually wakes me up effectively.

The Apple Watch charger, however, lives on the bookshelf across the room, and the Nightstand Mode alarm turns out to be the right combination of pleasant enough to not be jarring and annoying enough to get me up to turn it off.

## So what is Subl, anyway?

So I’ve been talking about distributed social stuff a lot lately, especially Publ (my publishing engine, which runs this site, in case you are new here), and also ecosystem stuff for things like private entries and other things that have been pinging around in my head for a while.

A thing I keep on mentioning is Subl, but generally only talking about it tangentially without actually going into detail with what it even is. So, I guess I should talk about that at some point.

## The authenticated Atom musings continue

Now that I’ve had a chance to think about this more than what was afforded by a quick response fired off between songs at a karaoke bar, I feel like expanding more on the details that I’d only implied (and probably badly) from the previous post. So, here’s how I think things could look.

## Some more on authenticated Atom

Oh hey, I got my first actual reply in WebMention form, from the wonderful Aaron Parecki, who responded to today’s design doc with some pretty good points:

I think my main concern, which you sort of hinted at, is that the feed will essentially leak info about how many followers someone has, as well as this potentially including a lot of data as someone’s followers grow to the hundreds.

Yeah, those are very good concerns and I’m definitely worried about all of those things. My expectation is that friends-only entries would be only going to a small, fairly select group and certainly not to all followers, but I admit I only had my specific use cases in mind when I wrote it.

Have you seen the work going on around making IndieAuth work in a server-to-server environment without user interaction? The idea with that is to let a feed reader fetch a private feed on behalf of a user. indieweb.org/AutoAuth

I actually hadn’t but I’m not surprised that’s being worked on. I actually do really like that idea in general combined with the authenticated feeds approach since it satisfies a pretty good set of positives:

• Auth exchange is trivial for the user
• It needs specific support by the feed reader, meaning that can also be an opportunity to add private-entry metadata that is to be abided by (reblog control etc)
• It doesn’t leak any data at all as far as I can tell

Offhand I do see two three negatives though:

• No subscription sharing (which is admittedly a very minor concern)
• I don’t see how that would work with WebSub immediately (which is a more major issue)
• EDIT: No static publishing either

I could see a way of supporting WebSub by having private entries cause a “check your auth feed” notification to all subscribers, which does leak the fact there’s private activity (and would cause extraneous notifications) but I don’t think it would actually leak any useful data that way (aside from someone being able to gather analytics on someone else’s private entry count). And come to think of it, that could work for the normal auth feed case.

This is definitely what I’ll keep my eye on going forward since I like its mix of characteristics and it means I can already move forward on how I’d implement it in Publ without having to wait for the spec to get formalized. (In the interim I’d probably go with the same old hybrid form I did with the placeholder entries though.)

Also I do have a slight issue with the current implementations of IndieAuth, or at least with the brokers I’ve seen: they require people to set up a profile page, rather than letting people directly use their auth identity (e.g. their GitHub or Twitter). It’s not a huge issue but it does present a barrier for people who aren’t already tech savvy and immersed in this world — but I hope that’s something that can change over time. (I also suspect it’s simply an oversight in the brokers I’ve looked at.)

Anyway. The multicast crypto approach was inspired by DVDCSS/AACS/SiriusXM/Dish/etc. which all work in that way at an absolutely gigantic scale, but their delivery infrastructure and rewuirements make it much more sensible for their respective situations. This probably doesn’t map so well to blogging, and it definitely doesn’t map well to microblogging. I was pleased mostly to have come up with a key exchange protocol for a seemingly least-bad crypto solution, but it seems like the crypto part has too many downsides.

Anyway, thanks for the feedback! I think I see a much better path forward.

(Also I thought I should mention I composed this entry on my iPhone over an ssh connection using vi. Inhave really got to get a better editor working. CodeAnywhere couldn’t connect to my server for some reason though. Oh well.)

## Federated access control with Atom and WebSub

I’ve been ranting about ActivityPub vs. RSS/Atom a lot lately, and I think I’ve proven to myself (and maybe a few others) that for fully-public content feeds, Atom (combined with WebSub and WebMention) is superior to ActivityPub; it’s simpler to implement, works with many more hosting environments and configurations, it generally scales better (and handles scaling failures better), and it’s modular and allows for much eaiser migrations between hosting setups and so on.

But one thing ActivityPub supports which Atom does not is the notion of private content. The way it does support this is a bit hamfisted (in that ActivityPub publishers choose to only push content to endpoints which have a trusted user, and endpoints only forward that content over to the trusted users, albeit in a not-very-trustable way). It doesn’t inherently support the ability to backfill older content (or make it otherwise browseable) to someone who is granted friends-only access after-the-fact, though, and it has many scaling and security implications in how this works (since it requires push to be reliable and requires the recipient’s storage of said push notifications to also be reliable).

I’ve put a lot of thought into how to add friends-only stuff to Atom on and off over the years; my previous blog (which used Movable Type for publishing and phpBB for comments) actually had an ad-hoc implementation which worked sort of okay; people could authenticate with my site’s forum, and people in a trusted friend group would see private content. On the public feed, if their reader were logged into the forum (via cookie sharing etc.) it would see the private content in the feed, otherwise it would see placeholders saying “THis is a friends-only entry, please visit the site to read it.” It worked okay but it was never great.

Anyway, I think I have finally come up with an auth approach that works with Atom and offers a… well, least-bad solution all around, which scales better and more reliably than ActivityPub while working with WebSub and existing/legacy feed readers.

## Some WebSub-Atom observations

As part of testing my WebSub changes for FoF, I decided to switch to a WebSub hub for myself that provides some subscriber analytics and so on. One neat thing about how WebSub works is that the “hub” layer is completely modular and it really doesn’t matter at all which one you use, and if the one you use has problems you can switch to another one just by changing the URL in your feed and all subscribers will eventually seamlessly migrate (at their next normal polling interval); if anyone even notices a problem it will just be that they don’t receive a push update during that polling interval. (Which, let’s be honest, is incredibly unlikely for most RSS feeds.)

Anyway, because of these new analytics, as well as information I gathered from my new WebSub-supporting reader, I now know a bit more about the state of WebSub.

## Implementing WebSub

So, I keep on talking about how Atom is a better idea overall than ActivityPub (due to scaling, fragility or lack thereof, and a bunch of other reasons), and how WebSub adds the much-requested push notification stuff to it, because apparently push is the only thing a lot of engineers talk about.

While this site has supported WebSub for a while, I kept on putting off actually implementing a client because I wanted to make that part of Subl.

Well, today I decided, screw it, I’m adding WebSub support to FeedOnFeeds. It seems to be code-complete, but I have yet to actually verify that it’s working. So this is a test entry to hopefully verify that.

EDIT: It works!!! Now to merge it into master and issue a PR…

## New job!

Two years ago when I decided to go indie I had a few motivations behind it. Part of it was that I needed to work on my own thing for a while, but most of it was just that I needed to get the heck out of the tech industry; everything in that industry is so toxic and based around everyone being “passionate” about doing everything for a company with an incredibly asymmetric relationship. I was working myself to death (often literally) and putting myself deeper into intractible chronic pain, which never felt like it was enough and employers kept on demanding more and more, while being less interested in my own physical and mental health.

So I went indie, because I had a bunch of projects I wanted to work on, such as Publ and my games. And I thought I’d be able to make a little niche for myself making music for other peoples' games as well.

Well, it turns out that I’m my own worst boss. When I’m working on my own projects I get just as passionate, obsessed, and self-injurious as ever, and I also managed to burn myself out on all that. And when it came to working for others, well, I had a hard time finding people I wanted to work with who would be able to give me anything approaching a steady income. I was also feeling impostor syndrome like crazy, like what right do I have to be trying to do this when I (feel like I) can’t even get everything done?
{"extraction_info": {"found_math": true, "script_math_tex": 0, "script_math_asciimath": 0, "math_annotations": 0, "math_alttext": 0, "mathml": 0, "mathjax_tag": 0, "mathjax_inline_tex": 0, "mathjax_display_tex": 0, "mathjax_asciimath": 1, "img_math": 0, "codecogs_latex": 0, "wp_latex": 0, "mimetex.cgi": 0, "/images/math/codecogs": 0, "mathtex.cgi": 0, "katex": 0, "math-container": 0, "wp-katex-eq": 0, "align": 0, "equation": 0, "x-ck12": 0, "texerror": 0, "math_score": 0.15277723968029022, "perplexity": 2138.265962479866}, "config": {"markdown_headings": true, "markdown_code": true, "boilerplate_config": {"ratio_threshold": 0.18, "absolute_threshold": 10, "end_threshold": 15, "enable": true}, "remove_buttons": true, "remove_image_figures": true, "remove_link_clusters": true, "table_config": {"min_rows": 2, "min_cols": 3, "format": "plain"}, "remove_chinese": true, "remove_edit_buttons": true, "extract_latex": true}, "warc_path": "s3://commoncrawl/crawl-data/CC-MAIN-2019-35/segments/1566027322170.99/warc/CC-MAIN-20190825021120-20190825043120-00217.warc.gz"}