NokiMo
Touhou-Project.com
Touhou-Project.com

patreon


A Good Format (Part 2)

Hey all, hope you’ve been well and have enjoyed using THP the last few days. I’m going to continue my story from last time around and talk about the process of making the formatting buttons in the post box.

The previously I had mentioned that I had decided to make my own fonts. I’ll refer you to the previous post for the rationale and advantages and focus on the process itself. Now, I had never attempted such a thing before. I didn’t know where to start. But I knew it was possible and couldn’t be too difficult because custom fonts were commonplace, even ones that were just symbols instead of letters.

Research revealed that the Unicode Consortium thought things through in its quest to map all human language and symbols and reserved a large space in the spec to private use. That is to say, fonts can define characters in that range themselves. Fonts can be loaded up on web browsers but, crucially, I didn’t want to make it load by default and possibly override how things are displayed on most of the page. CSS has an in-built rule that allows a font to be defined, called up, and loaded on demand. This can be set to specific elements and classes, thereby automatically replacing otherwise unreadable characters with those mapped in the font.

An initial dry run with some font I found on the web showed that it worked just fine and soon I was looking for tools that allowed me to create my own custom font. I found what I was looking for in Glyphr. As I am mostly bereft of visual design talent, I wasn’t about to draw things myself. At best, I’d tweak existing designs. So I hunted down various vector images in SVG form that were public domain or permissibly licensed. Using a lot of trial and error—including figuring out the appropriate size definitions for each glyph—I eventually managed to map a half dozen symbols down into a custom font.

I should also mention that I also learned of the Web Open Font Format and made sure that my new font was converted to it, making a file that was merely 2ish KiB. Highly acceptable. And the icons I chose, though not perfect, get the point across for the most part I feel. If I get feedback that they’re unclear, I can always change them as well.

Since I was already making my own font, I used to opportunity to clean up a couple of old elements in THP’s design. Things like the sticky or locked icons that are used for threads were old low-res gifs and were unceremoniously removed. In their place you get crisp little unicode that is easily scalable and whose color and other properties can also be changed. As you might imagine, this programming detour did take some time as I had to test how things looked in my local webserver and make sure that there were no bugs.

As an aside, I also changed how already-formatted text was handled on the website and in the databse. That is to say all that bold or italic text got simplified and now depends more on our standard style sheet instead of inline trickery. It may sound like a little thing but it still shaved off a couple of MiB off the post table size.

Okay, so at this point, and after several days of work and research, The prototype was ready to be trialed. The HTML code for the buttons was added into the post box template and the global stylesheet updated to contain references to the new font. A few other tweaks were also done for the locked thread logic and other things and I added the Javascript code into the boards. I had to change a few things in the JS to account for the actual element names and whatever as my initial prototype had placeholders.

As expected, it worked. For the most part. I quickly ran into bugs and errors. Like, if the floating post box was enabled, it would not correctly insert elements there. This was due to how the textarea is recreated by the script and so I had to add additional logic that selected the correct element even if it wasn’t in its default place.

Then, came the quick reply box. It’s a separate but highly-related entity. I could have just created a different set of buttons for it and inserted it at the bottom of every page (where the hidden quick reply ‘lives’ until it’s needed). But that would be a waste of many small KiBs that’d add up. As the formatting tools required Javascript, anyhow, I decided to make the buttons get cloned when/if the quick reply box is called up for the first time. Somewhat simple to do—especially now that I had JQuery available in the environment because we use it for other things.

I ran into some issues. Mainly that the events listeners (ie: on click this triggers x event) were not being copied over even though they were supposed to be. I had to adjust some properties in the basic HTML templates anyhow so that the “correct” textarea would be selected by each anyhow. So I made a few additional changes that help me detect and grab the right thing. I refactored that scripting code some more, making some of it into an additional function that was called not only on load but when the quick reply element was shown for the first time. In essence, the event listeners now attached themselves as needed at different points.

All this and we were still not done! I had to stop and check for crossplatform and browser issues and make sure that nothing else was broken. Once all of that was sorted, still had to integrate a couple of other older features with some of the new code. Like, for example, the character counter that keeps track of inputs now needed to contend with tags that could be inserted without a key press and instead by event. Once more I turned to the spec and found out that some of my groundwork, namely giving the textarea focus whenever a tag was added, could work to my advantage. Optimization is important as well, as you don’t want scripts to take up too much memory or power to get things done but, in the end, it only took a little bit more effort to get those things playing nice with the new system.

The post preview feature was also enabled by default. I had planned to eventually do so anyways but the addition of the formatting tools was a good excuse. This led to a quick check to see whether anything was broken with the post area’s new overall appearance and also some partial reworking of the preview feature. Specifically, on the timeouts in place so that people can’t spam it. It’s not particularly resource-intensive but, if there are no controls, a malicious actor could possibly write a script to hammer it. As a lot of the newer prevention is server-side, the older things on the side of the client were made less annoying. In practical terms, that means that the existing alert that pops up to warn the user that they must wait a moment checks only for very small (I believe around 5 seconds) intervals while the server check looks at the overall amount of requests in a longer time period.

Finally, in line with giving users choices, the post preview enabling setting was removed and a new one added to hide the formatting tools away if so desired.

With all of that done, I could call work on the formatting tools complete. Other changes, besides the ones described in these two posts, also made the roll out. And there’s more work I did in parallel that’s not quite oven-ready. Both the other features and the future work will be covered in future posts, so look forward to that.

I can’t accurately put a number on the amount of hours spent on all of this but it took at least two full days of work to sort everything out. While I’m thankful for the amount of money in excess of the basic running costs for THP, I’d be remiss not to put things into perspective: if I were to “pay myself” $5/hr for coding work, I could only budget in about eight hours of work a month with the Patreon proceeds. It goes without saying that third party would ask for far more. The work I do on the site is therefore mostly a labor of love and I regularly put in work and effort during my limited free time to get things done.

There’s just no getting around the amount of manhours needed for each stage of development. Research, planning, implementation, modification, testingand bugfixing all take time to do properly. A clear plan helps, but cannot foresee every issue. Other systems and their behavior need to be accounted for since it’s very rare to work on wholly isolated systems.

I hope you enjoyed reading this limited account of a specific feature and all the work that went behind it. I’ll see about writing up the other things that I did (and am doing) whenever I have more free time. Until then, take it easy!


Related Creators