javascript(21/0)
Offer local user comment interaction
I’m wondering if it would be nice for users to take comments on my pages? Or for myself even? Here’s a self-contained example of a simple page that lets the user highlight a bit of text, make a short comment, and append it to the page. I’m not interested in wiring this up to a service or anything, but it’s pretty cool just to have this kind of local interaction with the content.…
Web development is both imperative and declarative
Jeremy Keith explores Imperative/Declarative web development and how team culture defines the paradigm a project chooses more than the language itself in this Youtube Video. It’s insightful and short: only 22 minutes. Jeremy defines imperative programming in terms of control. Imperative programs stipulate each step (instantiate this array, iterate over this collection, put items that meet this criteria into the instantiated array). Side-effects are minimized, but the code must also describe everything that must be accomplished.…
Prefer Light DOM to Shadow DOM
While there are legitimate uses for Shadow DOM, light DOM ought to be preferred until it is absolutely necessary to place your component’s element tree outside the main document. One common use-case which does not require shadow DOM is a custom element that does something special with events. Light DOM Use-Case Let’s say you have a custom element called <chaos-filter>. It has a form with a <select> dropdown and a filter <button> which applies the selected option to a list of children.…
Inject web component dependencies
If you’re transitioning from a framework like Angular to native web components it feel natural to inject services into your components. When you discover it’s not possible via the constructor, you may give up and use a framework after all. Or you might engineer your own dependency injection decorators. But there’s another lightweight option. Let me show you. ℹ️ These instructions are perfect for small, private use-cases. If you're building dozens of services with interlocking dependencies, there's no decent option besides a framework.…
Test web components with playwright
So you’ve created a native web component or two. How do you test them in popular browsers? Packages There are a few tools to install. First, test-runner to find and execute our tests. It comes with the Mocha test framework by default, and we won’t change it. Might as well install chai too for test assertions and expectations. Second, the browser runner Playwright plugin. Playwright integrates headless browser testing into the mix, allowing us to run our code inside a browser context for every one of the major browser binaries (chromium, firefox, webkit).…
Build web components for forms
Forms are an obvious web component, but there are a few gotchas. Stephen solves a common problem when writing my own web components: How to communicate with a form tag. I’m curious to try his approach for myself. I recently took a different approach: don’t use the shadow DOM at all. Then the browser has no trouble connecting the input tags with the form. See my chaos-filter, which is used on this page.…
Recurse tree nodes
Reasons to build recursive functions happen infrequently enough that I often forget how to do it. Here’s an example I wrote recently to retrieve a flat array of nodes in a tree which meet a certain requirement. Essentially it’s a recursive filter. It’s been made generic so that any object which implements the Node interface can use it. export interface Node { public parent?: Node; public children?: Node[]; } export function getNodesBy<T>(propFunc: (Node) => boolean, tree: Node[]): T[] { const getNodes = (items: Node[]) => { const matches = items.…
Embed web components into static HTML
I’ve successfully published hundreds of articles using only a static site generator. Sometimes though, I itch to create reactive elements like I build at work with Angular. What is a developer to do? My needs are tiny, so here is a tiny way to get started. ℹ️ My intended goal is to supply a small number of custom web components for most pages on my website that I can inject via Hugo shortcodes.…
Get published today feed
This JavaScript snippet reads multiple RSS/XML feeds on my site and adds a list of the items published on this day to the bottom of my page. I may use this in future to add a “Published On This Day” feed to my site, kind of like how OneDrive will pop up a picture from last year. const parser = new DOMParser(); const today = new Date(); const lastYear = new Date(today.…
Hide nodes by sum of attribute
My tags list has 195 tags with a single entry. One of the primary purposes for tags is to compare writing with the same tag to discover similarities, so these entries achieve little. A simple button to the tags list with the following JavaScript will hide all tags with a plant and stone sum of less than two. document.querySelectorAll("div.terms-page__terms>div").forEach((el) => { var txt = el.childNodes[0].childNodes[1].innerText; var txtSum = txt.slice(1,-1).split('/').reduce((p,c) => Number(p) + Number(c)); if (txtSum < 2) { el.…
Javascript build tooling is a mess
It’s refreshing to read Julia’s article about esbuild. I’ve found the JavaScript build tooling to be an obtuse, obscure mess ever since I first began to use it years ago. When that’s all a person knows, like many front-end developers I’ve met, then it’s taken for granted that this is a necessary evil. But when you’ve used clean, simple back-end CLI’s like dotnet or scaffolded your project’s pipeline with a Makefile, the wreckage that is JavaScript bundling and transpiling feels gross.…
Distinguish series and one time observables
Observables are extremely helpful; however, the observable.subscribe() pattern hides whether the call is expected to return once or multiple times. It’s important to distinguish when there will be a single update and when there will be a series. Series observables usually belong in the onInit() method and drive component behavior when they receive dispatches. One-time observables are merely getting data. The methods to interact with each are different. For example, one-time uses Ramda’s forkJoin to resolve all observables, but combineLatest when updates are expected.…
Verify your RSS feed
If you have an RSS feed, you can use this snippet as a starting place to review the output. I’m printing the titles of each RSS item to the console, but go as deep as necessary to ensure the right information ends up in your feed. fetch('https://my-url-here.com') .then(res => res.text()) .then(text => { const domParser = new DOMParser(); const doc = domParser.parseFromString(text, 'text/html'); var feedURL = doc.querySelector('link[type="application/rss+xml"]'); return fetch(feedURL.href); }) .…
Save unfinished notes in local storage
When I publish content to my site I sometimes get nervous that the work I’ve written into the publish form will be lost. Jan-Lukas has written a straightforward Javascript snippet to store my work locally so it will not be lost. Thanks! Simply cache form fields in localStorage
Display backlink preview on hover
The combination of microformat2 h-entry and backlinks is potent. Each note page that’s marked up with a e-content microformat2 property can be retrieved via fetch() and displayed as a preview elsewhere on the site. No database required; the website is the API. With these two snippets you can implement dynamic backlink functionality on pretty much any webpage. With a little standardization (mostly complete by the microformat2 standard), one could support backlinks across websites.…
Add snippets to your text input
If you have a textarea where you enter content on a regular basis and want to implement snippets to help with certain constructs, this JavaScript example might be just your style. I may use it in my publishing service so I can easily enter Hugo shortcodes I’ve developed for my site. document.querySelector('textarea.content').addEventListener('keyup', (event) => { var txt = event.target.value; if (txt.length < 7) { return; } var lastWord = txt.split(' ')?…
Custom container queries with resize observer
Until CSS container queries are baked into every browser, ResizeObserver fills the gap. Here’s an example of an observer that switches the CSS Flex from row to column based on the container’s width. This is used on my Plants and Stones pages. ℹ️ I use a Store object to share observable state across my application. This vastly simplifies communication between components; in this case, with my filter component. When my filter results change, I want to re-calculate the possible list width.…
One subscription per resource
Here’s my subscription progression for the qrm-category-container root component. Let me know if this is headed in the right direction. Stage One - Current Code The root container creates a subscription in onInit() that fires whenever fedId or QRM periodId changes, like so: combineLatest([this.sessionQuery.federalReserveId$, this.sessionQuery.qualitativePeriodId$]) .subscribe(([fedId, qualitativePeriodId]) => { this.qualitativePeriodId = qualitativePeriodId; this.refreshViewModel(fedId, qualitativePeriodId, this.viewCustomerData, this.categoryId); }); That’s not too bad, right? Consider what happens in refreshViewModel()… refreshViewModel(federalReserveId: number, periodId: number, viewCustomerData: boolean, categoryId): void { this.…
Smart components observe state over input
In component design there are two buckets, smart and dumb components. Smart components are keepers of data models and reactive to changes. Dumb components render explicit data models to views. Dumb components benefit from the explicit interface created by a clear set of inputs. Smart components, however, can get into a lot of trouble if they depend on mutable inputs for their data models. While it seems easy to add an onChanges() function to child smart components to re-render based on changes to their inputs, this dependency can have unexpected consequences.…
Read webpage as API
One of the Indieweb mindsets is to treat HTML content as its own API. HTML-only content is eminently sharable Content that sits in a database is sharable, but not eminently so. Databases are queried via an API that’s usually not publicly available and documented. While the user may comfortably use the API to render content to their site, my interface is the site itself rather than the underlying API. Lazy-load data via JavaScript and, well, it’s not eminently sharable.…
Embedded youtube videos attach google ads
I know that I shouldn’t be surprised at this point, but adding Matthew’s video to my ship’s log also inadvertently added a Google Ad tracker to my website (pun intended). It’s in Matthew’s best interest that I leave the video on my site, but maybe there’s a way I can embed it that doesn’t send my visitor’s information to Google?