<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Deniz Akşimşek</title>
    <description>The latest articles on DEV Community by Deniz Akşimşek (@dz4k).</description>
    <link>https://dev.to/dz4k</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F210155%2F7f87b9fd-89cc-4093-9682-402ddaa0fe26.jpeg</url>
      <title>DEV Community: Deniz Akşimşek</title>
      <link>https://dev.to/dz4k</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dz4k"/>
    <language>en</language>
    <item>
      <title>You don't need a modal window</title>
      <dc:creator>Deniz Akşimşek</dc:creator>
      <pubDate>Sun, 11 Jun 2023 23:23:05 +0000</pubDate>
      <link>https://dev.to/dz4k/you-dont-need-a-modal-window-47el</link>
      <guid>https://dev.to/dz4k/you-dont-need-a-modal-window-47el</guid>
      <description>&lt;p&gt;After a conversation in the &lt;a href="https://htmx.org/discord"&gt;htmx Discord&lt;/a&gt;, and realizing .dev domains aren't as expensive as I remember, I decided to make a microsite:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://YouDontNeedAModalWindow.dev"&gt;YouDontNeedAModalWindow.dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I tried to talk about the flaws and dangers of modal windows and how I think they're overused, while also acknowledging the cases where they are the right solution.&lt;/p&gt;

&lt;p&gt;What do you think?&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Intentionally Unscalable</title>
      <dc:creator>Deniz Akşimşek</dc:creator>
      <pubDate>Sun, 06 Feb 2022 11:52:45 +0000</pubDate>
      <link>https://dev.to/dz4k/intentionally-unscalable-1kbo</link>
      <guid>https://dev.to/dz4k/intentionally-unscalable-1kbo</guid>
      <description>&lt;p&gt;_hyperscript is intentionally unscalable. We make decisions that would be obviously inadvisable to anyone looking to make scalable software, and dismiss features like reactivity that seem to have proven themselves in this regard. To understand why, I examine and critique the concept of “scalable”.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scalability refers to the ability of a system to handle more work given more resources.&lt;/strong&gt; This definition matches both formal definitions and common use in application development circles. Given this definition, we can see that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scalability is unidirectional — it only refers to scaling up, never scaling down. In fact, I never hear “scaling down” discussed at all. Declaring it out-of-scope to ascribe this to a wider culture of growth, I’ll just speculate that perhaps scaling down is assumed to be trivial, or not necessary as a system that handles a large amount of work can necessarily handle a small amount, adequately, without modification.&lt;/li&gt;
&lt;li&gt;When people talk about the scalability of a tool, they are usually employing metonymy&lt;sup&gt;&lt;a href="https://denizaksimsek.com/2022/intentionally-unscalable/#fn1" id="fnref1"&gt;[1]&lt;/a&gt;&lt;/sup&gt;. They are discussing the impact of the tool on other systems’ scalability (will _hyperscript hinder us as we get more users/our app gets more complex?) and not the scalability of the tool itself (can we get hyperscript to run N lines of code in T time with better hardware?)&lt;/li&gt;
&lt;li&gt;System, work, resources — a software development team consists of multiple systems using multiple kinds of resources to do multiple kinds of work. Which system is being discussed is usually clear through context, but we should be aware when “scalable” is used without such context.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;System&lt;/th&gt;
&lt;th&gt;More Work&lt;/th&gt;
&lt;th&gt;Resources&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Software&lt;/td&gt;
&lt;td&gt;Serve more users.&lt;/td&gt;
&lt;td&gt;Computers.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Team&lt;/td&gt;
&lt;td&gt;Add complexity to the software and maintain it.&lt;/td&gt;
&lt;td&gt;Time, money.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;The two main systems in a software organization.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is scalability desired?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;“As our app gets more complex, X will prevent us from growing and maintaining it”.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;“As we get more users, the app we built with X will need rewriting”.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Write to rewrite
&lt;/h2&gt;

&lt;p&gt;Expect that you might need to rewrite your code, and be considerate of your future self who is doing that. _hyperscript helps you do this in two ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Readability over writability.&lt;/strong&gt; The fact that _hyperscript code examples look like plain English is just as much an achievement of the author as it is _hyperscript’s. We do not do anything smart like Natural Language Processing; _hyperscript uses common and normal parsing techniques. C++, Perl, perhaps even Ruby have more complex grammars than _hyperscript. We give you tools like the &lt;code&gt;prop of object&lt;/code&gt; and &lt;code&gt;object's prop&lt;/code&gt; syntax. and the&lt;code&gt;it&lt;/code&gt; variable that might seem magical but is actually little more than the accumulator register in an 8-bit processor. It is up to you the programmer to use these tools to create readable code. The burden you take upon your shoulders can include (but will not be limited to):&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Locality of behavior.&lt;/strong&gt; Ever looked through a GitHub repo, not been able to find the code you were looking for, eventually clone the repo locally and start “Jump to Definition”-ing and “Peek References”-ing your way towards your target, only to find out it’s a wrapper for yet another function? If it is a Java project, I usually give up before reaching any source code files at all. Htmx “Carson” Org has written about &lt;a href="https://htmx.org/essays/locality-of-behaviour"&gt;Locality of Behavior&lt;/a&gt;previously, so I’ll direct you there.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I recall what I now know to be an urban legend about the great architect Mimar Sinan. Supposedly, when the keystones of some arches in a mosque he built were yielding to old age, an engineer working on the restorations found a note in a bottle signed by Koca Mimar Sinan Ağa himself. It was a step-by-step guide on how to replace the keystone without disruption to the rest of the structure, complete with drawings.&lt;/p&gt;

&lt;p&gt;Putting aside the implication that our modern architects don’t know how stone arches are built, and that Great Sinan Agha The Architect expected such architects to restore his works, this fictional Mimar Sinan clearly doesn’t know anything about scalability. If he did, he would predict when the Sultan would die and make the mosque last exactly that long.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When asked what their language is good for, many designers would say “everything” which really means “nothing”.&lt;/p&gt;


&lt;p&gt;– Robert Nystrom, &lt;cite&gt;&lt;a href="http://journal.stuffwithstuff.com/2010/07/23/what-i-learned-at-the-emerging-languages-camp/"&gt;What I Learned at the Emerging Languages Camp&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;

&lt;/blockquote&gt;

&lt;p&gt;Nystrom said this in the context of choosing a niche for your language, but I believe it applies just as well to choosing a scale.&lt;/p&gt;




&lt;ol&gt;
&lt;li id="fn1"&gt;
&lt;p&gt;I was excited when looking up this word on &lt;a href="https://tureng.com/"&gt;Tureng&lt;/a&gt;, but “metonymy”
doesn’t really have the barebones simplicity of the Turkish “ad aktarması”
or the weight of the Arabic loan “mecaz-ı mürsel”. &lt;a href="https://denizaksimsek.com/2022/intentionally-unscalable/#fnref1"&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn2"&gt;
&lt;p&gt;The way that the “we’ll need rewriting” argument assumes growth, but
rejects relying on it reminds me of paying people in shares. If you can’t trust
it enough to just pay me the money you’ll definitely make
back, why should I? &lt;a href="https://denizaksimsek.com/2022/intentionally-unscalable/#fnref2"&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn3"&gt;
&lt;p&gt;originally said this much more pithily: “if you are certain you’ll
grow to 1 billion users, and you need an app that can handle that, why build it
now on a startup budget when you’re going to have the budget of a 1B-user app
soon” &lt;a href="https://denizaksimsek.com/2022/intentionally-unscalable/#fnref3"&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn4"&gt;
&lt;p&gt;I’m aware that some people do programming purely as a job. I sometimes
envy the indifference I imagine they have towards our petty squabbles. &lt;a href="https://denizaksimsek.com/2022/intentionally-unscalable/#fnref4"&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>Sprinkle Sharing</title>
      <dc:creator>Deniz Akşimşek</dc:creator>
      <pubDate>Thu, 02 Sep 2021 16:41:00 +0000</pubDate>
      <link>https://dev.to/dz4k/sprinkle-sharing-27ci</link>
      <guid>https://dev.to/dz4k/sprinkle-sharing-27ci</guid>
      <description>&lt;p&gt;&lt;em&gt;This post is directly from my notes, with no edits.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When people talk about code sharing between server and client, the usual suspects are Node.js and sharing model classes. However, there’s often good reason to duplicate these.&lt;/p&gt;

&lt;p&gt;A far more interesting type of code sharing to me is eliminating this duplication:&lt;/p&gt;

&lt;p&gt;When you are writing a server-driven web app with “sprinkles” of JS, you want to have interactive components, but also deliver usable HTML to non-JS-enabled &lt;sup&gt;&lt;a href="https://denizaksimsek.com/2021/sprinkle-sharing/#fn1" id="fnref1"&gt;[1]&lt;/a&gt;&lt;/sup&gt; clients. This means you are essentially writing a component with the first render and subsequent updates are written in different languages – HTML then JS. How to make this nicer? (Existing answers follow)&lt;/p&gt;

&lt;h2&gt;
  
  
  Alpine and similar
&lt;/h2&gt;

&lt;p&gt;Write both in one language: “HTML with JS inline in special attributes”.&lt;/p&gt;

&lt;h2&gt;
  
  
  React and similar
&lt;/h2&gt;

&lt;p&gt;Write both in one language: “JS optionally with JSX”. Hard to set up sprinkle style, but wasn’t this how it was originally created to be used?&lt;/p&gt;




&lt;ol&gt;
&lt;li id="fn1"&gt;
&lt;p&gt;“Non-JS-enabled” includes not only browsers where the user turned off JS, but also times when the JS didn’t load, or errored due to use of unsupported modern features. &lt;a href="https://denizaksimsek.com/2021/sprinkle-sharing/#fnref1"&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>Event Delegation in _hyperscript</title>
      <dc:creator>Deniz Akşimşek</dc:creator>
      <pubDate>Thu, 20 May 2021 09:43:49 +0000</pubDate>
      <link>https://dev.to/dz4k/event-delegation-in-hyperscript-4fl5</link>
      <guid>https://dev.to/dz4k/event-delegation-in-hyperscript-4fl5</guid>
      <description>&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;on click
  tell the closest &amp;lt;li/&amp;gt; to the target
    remove yourself
    -- do more stuff...
    -- "you" refers to the clicked list item
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I’ve seen some people use a pattern like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jinja"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
  &lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nv"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;items&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;_=&lt;/span&gt;&lt;span class="s"&gt;"on click remove me"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;endfor&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is convenient to write if you have a server-side templating system, but has a few issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The code needs to be parsed N times where N is the number of items.&lt;/li&gt;
&lt;li&gt;The resulting HTML is bloated.&lt;/li&gt;
&lt;li&gt;If you add more items client-side, you need to repeat the code there.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The pattern for resolving this is called event delegation. Here’s how you might do it in JavaScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;closest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;li&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;
  &lt;span class="nx"&gt;li&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We add a single event listener to the enclosing list, which finds the item that was clicked and manipulates it.&lt;/p&gt;

&lt;p&gt;In _hyperscript, the &lt;code&gt;tell&lt;/code&gt; command allows us to manipulate an element other than &lt;code&gt;me&lt;/code&gt; conveniently, by changing the implicit target from &lt;code&gt;me&lt;/code&gt; to &lt;code&gt;ypu&lt;/code&gt;, which refers to the element being “told”.&lt;/p&gt;

</description>
      <category>hyperscript</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Hypelet: make bookmarklets with _hyperscript</title>
      <dc:creator>Deniz Akşimşek</dc:creator>
      <pubDate>Sat, 01 May 2021 12:06:37 +0000</pubDate>
      <link>https://dev.to/dz4k/hypelet-make-bookmarklets-with-hyperscript-cja</link>
      <guid>https://dev.to/dz4k/hypelet-make-bookmarklets-with-hyperscript-cja</guid>
      <description>&lt;p&gt;I made a tool to make bookmarklets in &lt;a href="////hyperscript.org"&gt;_hyperscript&lt;/a&gt;. You just write some code in the box and drag the bookmarklet into your bookmarks toolbar. Hypelet injects glue code to load hyperscript dynamically and run your code. You can get a permalink to share your bookmarklet.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Here’s Hypelet: &lt;a href="https://hypelet.dz4k.com/"&gt;Hypelet&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Here’s the code for a bookmarklet to get the RSS feed of a page: &lt;a href="https://hypelet.dz4k.com/#%7B%22hs%22%3A%22get%20the%20href%20of%20the%20first%20%3C%5Brel%3Dfeed%5D%2C%20%5Btype%5E%3D%5C%22application%2Frss%2Bxml%5C%22%5D%2F%3E%5Cncall%20alert(it)%22%2C%22name%22%3A%22get%20rss%20feed%22%7D"&gt;Get RSS – Hypelet&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>hyperscript</category>
      <category>bookmarklet</category>
      <category>tools</category>
    </item>
    <item>
      <title>The Implementation of HDB, the _hyperscript debugger</title>
      <dc:creator>Deniz Akşimşek</dc:creator>
      <pubDate>Thu, 18 Mar 2021 07:44:13 +0000</pubDate>
      <link>https://dev.to/dz4k/the-implementation-of-hdb-the-hyperscript-debugger-5hf4</link>
      <guid>https://dev.to/dz4k/the-implementation-of-hdb-the-hyperscript-debugger-5hf4</guid>
      <description>&lt;p&gt;The 0.0.6 release of the &lt;a href="https://hyperscript.org"&gt;_hyperscript&lt;/a&gt; hypertext UI scripting language introduces HDB, an interactive debugging environment. In this article I discuss how the hyper-flexible hyperscript runtime allowed me to implement the first release of HDB with ease. If you'd like to see what HDB is like, I have a a demo on &lt;a href="https://denizaksimsek.com/2021/the-implementation-of-hdb/"&gt;my website&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;HDB lives in a &lt;a href="https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js"&gt;single JavaScript file&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Turning the keys
&lt;/h3&gt;

&lt;p&gt;In the hyperscript runtime (which is a tree walking interpreter), each command has an &lt;code&gt;execute()&lt;/code&gt; method which either returns the next command to be executed, or a &lt;code&gt;Promise&lt;/code&gt; thereof. The execute method for the breakpoint command creates an HDB environment and assigns it to the global scope (usually &lt;code&gt;window&lt;/code&gt;):&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L20"&gt;hdb.js ln. 20&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;hdb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;HDB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hdb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;hdb&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;HDB&lt;/code&gt; object keeps hold of the current command and context as we step through. (The context is the object holding the local variables for the hyperscript code, and some other things the runtime keeps track of). We call its &lt;code&gt;break()&lt;/code&gt; method:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L35"&gt;hdb.js ln. 35&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;HDB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;%c=== HDB///_hyperscript/debugger ===&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;headingStyle&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ui&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;continue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// Context switch&lt;/span&gt;
                &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;attr&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;delete&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;delete&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hdb&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findNext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;once&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are a few things to unpack here. We call &lt;code&gt;self.ui()&lt;/code&gt; to start the UI, which we'll get to later. Remember how a command can return the next method to execute as a promise? The break method resolves after the &lt;a href="https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L10"&gt;internal event bus&lt;/a&gt; receives a &lt;code&gt;"continue"&lt;/code&gt; event, whether by the user pressing "Continue" or simply reaching the end of the debugged code. &lt;/p&gt;

&lt;p&gt;The "context switch" is the dirtiest part of it all. Because we can step out of functions, we might finish debugging session with a different context than before. In this case, we just wipe the old context and copy the current context variables over. Honestly, I thought I'd have to do a lot more of this kind of thing.&lt;/p&gt;

&lt;p&gt;Speaking of stepping out of functions...&lt;/p&gt;

&lt;h3&gt;
  
  
  Stepping Over and Out
&lt;/h3&gt;

&lt;p&gt;Firstly, if self.cmd is null, then the previous command was the last one, so we just stop the debug process:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L58"&gt;hdb.js ln. 58&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;HDB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stepOver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;continueExec&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If not, then we do a little dance to execute the current command and get the next one: &lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L61"&gt;hdb.js ln. 61&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;breakpointCommand&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt;
    &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findNext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;unifiedEval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We perform a useless check that I forgot to take out (&lt;code&gt;self.cmd &amp;amp;&amp;amp;&lt;/code&gt;). Then, we special-case the &lt;code&gt;breakpoint&lt;/code&gt; command itself and don't execute it (nested debug sessions don't end well...), instead finding the subsequent command ourselves with the &lt;code&gt;runtime.findNext()&lt;/code&gt; in hyperscript core. Otherwise, we can execute the current command.&lt;/p&gt;

&lt;p&gt;Once we have our command result, we can step onto it:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L61"&gt;hdb.js ln. 64&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;implicitReturn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stepOut&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nb"&gt;Function&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dispatchEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;step&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;logCommand&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;halt_flag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dispatchEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;continue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dispatchEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;step&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;logCommand&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we returned from a function, we step out of it (discussed below). Otherwise, if the command returned a Promise, we await the next command, set &lt;code&gt;cmd&lt;/code&gt; to it, notify the event bus and log it with some fancy styles. If the result was synchronous and is a &lt;a href="https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/core.js#L1221"&gt;HALT&lt;/a&gt;; we stop debugging (as I write this, I'm realizing I should've called &lt;a href="https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L54"&gt;&lt;code&gt;continueExec()&lt;/code&gt;&lt;/a&gt; here). Finally, we commit the kind of code duplication hyperscript is meant to help you avoid, to handle a synchronous result.&lt;/p&gt;

&lt;p&gt;To step out, we first get our hands on the context from which we were called:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L80"&gt;hdb.js ln. 80&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;HDB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stepOut&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;caller&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;continueExec&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;callingCmd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;callingCommand&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;oldMe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;me&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;caller&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Turns out _hyperscript function calls already keep hold of the caller context (&lt;code&gt;callingCommand&lt;/code&gt; was added by me though). After we change context, we do something a little odd:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L92"&gt;hdb.js ln. 92&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findNext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callingCmd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findNext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why do we call &lt;code&gt;findNext&lt;/code&gt; twice? Consider the following hyperscript code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;transition 'color' to darkgray
set name to getName()
log the name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can't execute the command to set &lt;code&gt;name&lt;/code&gt; until we have the name, so when &lt;code&gt;getName()&lt;/code&gt; is called, the current command is still set to the &lt;code&gt;transition&lt;/code&gt;. We call &lt;code&gt;findNext&lt;/code&gt; once to find the &lt;code&gt;set&lt;/code&gt;, and again to find the &lt;code&gt;log&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Finally, we're done stepping out:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L95"&gt;hdb.js ln. 95&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dispatchEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;step&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  HDB UI
&lt;/h3&gt;

&lt;p&gt;What did I use to make the UI for the hyperscript debugger? Hyperscript, of course!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L107"&gt;hdb.js ln. 107&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"hdb"&lt;/span&gt; &lt;span class="na"&gt;_=&lt;/span&gt;&lt;span class="s"&gt;"
    on load or step from hdb.bus send update to me
    on continue from hdb.bus remove #hyperscript-hdb-ui-wrapper-"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are a lot of elements listening to &lt;code&gt;load or step from hdb.bus&lt;/code&gt;, so I consolidated them under &lt;code&gt;update from .hdb&lt;/code&gt;. &lt;code&gt;#hyperscript-hdb-ui-wrapper-&lt;/code&gt; is the element whose Shadow DOM this UI lives in --- using shadow DOM to isolate the styling of the panel cost me later on, as you'll see.&lt;/p&gt;




&lt;p&gt;We define some functions.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L112"&gt;hdb.js ln. 112&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;def highlightDebugCode
    set start to hdb.cmd.startToken.start
    set end to hdb.cmd.endToken.end
    set src to hdb.cmd.programSource
    set beforeCmd to escapeHTML(src.substring(0, start))
    set cmd to escapeHTML(src.substring(start, end))
    set afterCmd to escapeHTML(src.substring(end))
    return beforeCmd+"&lt;span class="nt"&gt;&amp;lt;u&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;'current'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;"+cmd+"&lt;span class="nt"&gt;&amp;lt;/u&amp;gt;&lt;/span&gt;"+afterCmd
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, I wasn't aware that we had &lt;a href="https://hyperscript.org/expressions/string/"&gt;template literals&lt;/a&gt; in hyperscript at this point, so that's for the next release. The &lt;code&gt;escapeHTML&lt;/code&gt; helper might disappoint some:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L122"&gt;hdb.js ln. 122&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;def escapeHTML(unsafe)
    js(unsafe) return unsafe
        .replace(/&lt;span class="err"&gt;&amp;amp;&lt;/span&gt;/g, "&lt;span class="ni"&gt;&amp;amp;amp;&lt;/span&gt;")
        .replace(/&lt;span class="nt"&gt;&amp;lt;/g&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt; &lt;span class="err"&gt;"&amp;amp;lt;")&lt;/span&gt;
        &lt;span class="err"&gt;.replace(/&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;/g, "&lt;span class="ni"&gt;&amp;amp;gt;&lt;/span&gt;")
        .replace(/\\x22/g, "&lt;span class="ni"&gt;&amp;amp;quot;&lt;/span&gt;")
        .replace(/\\x27/g, "&lt;span class="ni"&gt;&amp;amp;#039;&lt;/span&gt;") end
    return it
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unfortunately, hyperscript's regex syntax isn't decided yet. &lt;/p&gt;




&lt;p&gt;And we have the most broken part of HDB, the prettyPrint function. If you know how to do this better, feel free to send a PR.&lt;/p&gt;

&lt;p&gt;Having defined our functions we have a simple toolbar and then the &lt;strong&gt;eval panel&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L158"&gt;hdb.js ln. 158&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"eval-form"&lt;/span&gt;  &lt;span class="na"&gt;_=&lt;/span&gt;&lt;span class="s"&gt;"
    on submit call event.preventDefault()
    get the first &amp;lt;input/&amp;gt; in me
    then call _hyperscript(its.value, hdb.ctx)
    then call prettyPrint(it)
    then put it into the &amp;lt;output/&amp;gt; in me"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"eval-expr"&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"e.g. target.innerText"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Go&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;output&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"eval-output"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;em&amp;gt;&lt;/span&gt;The value will show up here&lt;span class="nt"&gt;&amp;lt;/em&amp;gt;&amp;lt;/output&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why do I use weird selectors like &lt;code&gt;&amp;lt;input/&amp;gt; in me&lt;/code&gt; when these elements have good IDs? Because &lt;code&gt;#eval-expr&lt;/code&gt; in hyperscript uses &lt;code&gt;document.querySelector&lt;/code&gt;, which doesn't reach Shadow DOM. &lt;/p&gt;




&lt;p&gt;A panel to show the code being debugged:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L170"&gt;hdb.js ln. 170&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;h3&lt;/span&gt; &lt;span class="na"&gt;_=&lt;/span&gt;&lt;span class="s"&gt;"on update from hdbUI
        put 'Debugging &amp;lt;code&amp;gt;'+hdb.cmd.parent.displayName+'&amp;lt;/code&amp;gt;' into me"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"code-container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;pre&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"code"&lt;/span&gt; &lt;span class="na"&gt;_=&lt;/span&gt;&lt;span class="s"&gt;"on update from hdbUI
                            if hdb.cmd.programSource
                                put highlightDebugCode() into my.innerHTML
                                scrollIntoView({ block: 'nearest' }) the
                                first .current in me"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/pre&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Finally, a context panel that shows the local variables.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L186"&gt;hdb.js ln. 106&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dl&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"context"&lt;/span&gt; &lt;span class="na"&gt;_=&lt;/span&gt;&lt;span class="s"&gt;"
    on update from hdbUI
    set my.innerHTML to ''
    repeat for var in Object.keys(hdb.ctx) if var != 'meta'
        get '&amp;lt;dt&amp;gt;'+var+'&amp;lt;dd&amp;gt;'+prettyPrint(hdb.ctx[var])
        put it at end of me
    end end
    on click
        get closest &amp;lt;dt/&amp;gt; to target
        log hdb.ctx[its.innerText]"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/dl&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That loop could definitely be cleaner. You can see the hidden feature where you can click a variable name to log it to the console (useful if you don't want to rely on my super-buggy pretty printer).&lt;/p&gt;

&lt;p&gt;Some CSS later, we're done with the UI! To avoid CSS interference from the host page, we create a wrapper and put our UI in its shadow DOM:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L350"&gt;hdb.js ln. 350&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;HDB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ui&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;shadow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;attachShadow&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;open&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;all: initial&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hyperscript-hdb-ui-wrapper-&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;shadow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ui&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hdbUI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;shadow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.hdb&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;_hyperscript&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;processNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hdbUI&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The End
&lt;/h2&gt;

&lt;p&gt;In just 360 lines, we have a basic debugger. This speaks volumes to the flexibility of the hyperscript runtime, and I hope HDB serves as an example of what's possible with the hyperscript extension API. Like the rest of hyperscript, it's in early stages of development --- feedback and contributors are always welcome!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>hyperscript</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Iota (from Golang) in JavaScript</title>
      <dc:creator>Deniz Akşimşek</dc:creator>
      <pubDate>Sun, 10 Jan 2021 14:57:00 +0000</pubDate>
      <link>https://dev.to/dz4k/iota-from-golang-in-javascript-b5i</link>
      <guid>https://dev.to/dz4k/iota-from-golang-in-javascript-b5i</guid>
      <description>&lt;p&gt;(Skip to code)&lt;/p&gt;

&lt;h2&gt;
  
  
  Enums in Javascript
&lt;/h2&gt;

&lt;p&gt;Currently, the ways we create enums include&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;String literals (see &lt;code&gt;addEventListener&lt;/code&gt;), which can be typed with TypeScript, but look a bit ugly&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Direction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;north&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;east&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;south&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;west&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;TypeScript enums&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;Direction&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;north&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;east&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;south&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;west&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Integer constants, IMO your best option if you’re not using TypeScript&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Directions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;north&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;east&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;south&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;west&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Enums in Go &lt;sup&gt;[1]&lt;/sup&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Go&lt;/em&gt; doesn’t have enums, but an unusual keyword &lt;code&gt;iota&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Direction&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;North&lt;/span&gt; &lt;span class="n"&gt;Direction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;iota&lt;/span&gt;
    &lt;span class="n"&gt;East&lt;/span&gt;
    &lt;span class="n"&gt;South&lt;/span&gt;
    &lt;span class="n"&gt;West&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There’s something subtle going on here. The iota relies on a few Go features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When multiple const declarations are grouped together, the right hand side is implicitly repeated&lt;/li&gt;
&lt;li&gt;Iota is incremented every time it is evaluated, and reset with each const&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My JavaScript shorthand is nowhere near as magical… but it does make use of proxies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;iota&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Proxy&lt;/span&gt;&lt;span class="p"&gt;({},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prop&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;north&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;east&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;south&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;west&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;iota&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;north&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, is this function any good?&lt;/p&gt;

&lt;p&gt;For one, it lacks some of Go’s &lt;code&gt;iota&lt;/code&gt; capabilities — you can’t create bitmasks with this the way you would in Go with &lt;code&gt;1 &amp;lt;&amp;lt; iota&lt;/code&gt;. We could augment it a bit by accepting a callback:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;iota&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Proxy&lt;/span&gt;&lt;span class="p"&gt;({},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prop&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// flag bits&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;hasPermissionFlag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;userModeFlag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useLegacyProtocolFlag&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;iota&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hasPermission&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;hasPermissionFlag&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I don’t think bitmasks are very common at all in JavaScript code, though.&lt;/p&gt;

&lt;p&gt;A more significant setback is that you can’t get a list of all the enum values — nothing we can’t fix:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;iota&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;firstProp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Proxy&lt;/span&gt;&lt;span class="p"&gt;({},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;firstProp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;firstProp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// Enum descriptor&lt;/span&gt;
                    &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prop&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Direction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;north&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;east&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;south&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;west&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;iota&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Direction&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is open for extension — we could add more methods on the enum description such as converting the integer value of a Direction to its name, or validating a Direction that we parsed from a config file.&lt;/p&gt;

&lt;p&gt;I might have a metaprogramming addiction.&lt;/p&gt;




&lt;ol&gt;
&lt;li id="fn1"&gt;
&lt;p&gt;Initially I wasn’t going to bring Go into this at all. However, it turns out &lt;code&gt;enum&lt;/code&gt; is a reserved word in JS, so I went with &lt;code&gt;iota&lt;/code&gt; for the name of the function, and felt the need to explain it. ↩︎&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>javascript</category>
      <category>metaprogramming</category>
    </item>
    <item>
      <title>Eleventy + Markdown + CoffeeScript = ❤</title>
      <dc:creator>Deniz Akşimşek</dc:creator>
      <pubDate>Fri, 16 Oct 2020 14:12:00 +0000</pubDate>
      <link>https://dev.to/dz4k/eleventy-markdown-coffeescript-p5a</link>
      <guid>https://dev.to/dz4k/eleventy-markdown-coffeescript-p5a</guid>
      <description>&lt;p&gt;I’ve started using CoffeeScript instead of YAML for frontmatter, and it works like a dream. &lt;a href="https://dev.toendorsed"&gt;Endorsed by Zach Leatherman&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Markdown with Frontmatter
&lt;/h2&gt;

&lt;p&gt;As far as I know, Jekyll is the origin of using a YAML block at the top of a Markdown file for metadata. It’s not hard to imagine why this became popular — associating prose with data is a common use case, and though they have their issues, both Markdown and YAML look pretty&lt;sup&gt;[1]&lt;/sup&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Eleventy Frontmatter
&lt;/h2&gt;

&lt;p&gt;Eleventy uses frontmatter blocks (delimited by &lt;code&gt;---&lt;/code&gt;) for all kinds of files. Markdown posts, HTML partials and Nunjucks/EJS/Liquid/… templates can all have them. The data in the frontmatter can then be used in templates. In the following, &lt;code&gt;title&lt;/code&gt; is not a reserved name:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--------
title: 'A Blog Post'
--------

# {title}

Lorem ipsum dolor sit amet...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We could have used &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;heading&lt;/code&gt; or &lt;code&gt;kdsad983erj33&lt;/code&gt;.&lt;/p&gt;




&lt;p&gt;Eleventy’s &lt;a href="https://www.11ty.dev/docs/data-computed/"&gt;“Computed Data”&lt;/a&gt; feature relies on functions in the frontmatter. As YAML doesn’t have functions, you are expected to use JS (well, you can use template strings I guess…):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--------js
{
  title: "My page title",
  eleventyComputed: {
    currentDate: () =&amp;gt;
      new Date().toLocaleString() 
  }
}
--------
&amp;lt;!doctype html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;!-- … --&amp;gt;
&amp;lt;body&amp;gt;
  &amp;lt;h1&amp;gt;{{title}}&amp;lt;/h1&amp;gt;
  &amp;lt;p&amp;gt;Published on {{currentDate}}&amp;lt;/p&amp;gt;
  &amp;lt;!-- … --&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Computed data is cool. Among other things, it allows me to move logic away from my templates and express it in an actual programming language. However JS frontmatter is not very pretty, and I don’t want to convert my whole frontmatter just for one function.&lt;/p&gt;

&lt;p&gt;If only there was a language that had the expressive power of JS, and the visually clean data notation of YAML…&lt;/p&gt;

&lt;h2&gt;
  
  
  CoffeeScript All The Time!
&lt;/h2&gt;

&lt;p&gt;CoffeeScript is actually mentioned in the GitHub repo for &lt;code&gt;gray-matter&lt;/code&gt;, the library Eleventy uese to parse frontmatter. Compared to YAML, it’s not much more verbose:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tr&gt;
&lt;td&gt;
&lt;pre&gt;&lt;code class="language-md"&gt;
--------
title: Street sign in İstanbul
date: 2020-10-10T19:27:39+03:00
tags:
- place
- design
uPhoto: /assets/photos/IMG20201007085906-02.jpeg
türkçe: /2020/istanbul-sokak-tabelasi/
--------

&amp;lt;!-- YAML --&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/td&gt;
&lt;td&gt;&lt;pre&gt;&lt;code class="language-md"&gt;
--------
title: 'Street sign in İstanbul'
date: '2020-10-10T19:27:39+03:00'
tags: ['place', 'design']
uPhoto: '/assets/photos/IMG20201007085906-02.jpeg'
türkçe: '/2020/istanbul-sokak-tabelasi/'
--------

&amp;lt;!-- CoffeeScript --&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The CoffeeScript code above is actually fully YAML-compatible! This keeps my templates portable. And with computed data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--------
layout: 'layout'
eleventyComputed:
  syndicationLinks: (data) -&amp;gt;
    DEV: data.devToSyndication[data.page.url]
--------

&amp;lt;article class="h-entry"&amp;gt;
&amp;lt;!-- ... --&amp;gt;
{%for silo, link in syndicationLinks%}
  &amp;lt;a class="u-syndication" href="{{link}}"&amp;gt;{{silo}}&amp;lt;/a&amp;gt;
  {%if not loop.last%} | {%endif%}
{%endfor%}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I think that computed frontmatter gives a nice balance of logic-less&lt;sup&gt;[2]&lt;/sup&gt; and logic-full templates.&lt;/p&gt;




&lt;ol&gt;
&lt;li id="fn1"&gt;
&lt;p&gt;“It looks pretty” is often what people really mean when they call something “human-readable”. ↩︎&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn2"&gt;
&lt;p&gt;Logicless templates: For people who will never need to make an HTML monthly calendar! ↩︎&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>eleventy</category>
      <category>markdown</category>
      <category>coffeescript</category>
      <category>jamstack</category>
    </item>
    <item>
      <title>Add Syndication Links On Your Personal Site Using Dev.to API</title>
      <dc:creator>Deniz Akşimşek</dc:creator>
      <pubDate>Thu, 17 Sep 2020 18:10:00 +0000</pubDate>
      <link>https://dev.to/dz4k/add-syndication-links-on-your-personal-site-using-dev-to-api-395</link>
      <guid>https://dev.to/dz4k/add-syndication-links-on-your-personal-site-using-dev-to-api-395</guid>
      <description>&lt;p&gt;I recently started using the &lt;a href="https://dev.to/settings/publishing-from-rss"&gt;RSS publishing&lt;/a&gt; option to syndicate posts from my personal site to DEV. This allows people to post comments under my posts, many of which might contain useful info. To allow my millions of readers (!) to easily discover and participate in these discussions, I’ve added links to the dev.to copies under my posts.&lt;/p&gt;

&lt;p&gt;(Skip to code)&lt;/p&gt;

&lt;p&gt;I could, of course, add these links manually whenever I post, but being armed with such a powerful static site generator as Eleventy, I couldn’t possibly &lt;em&gt;not&lt;/em&gt; automate it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The API and the Data File
&lt;/h2&gt;

&lt;p&gt;Eleventy users will be aware of how easy it is to gather all kinds of data from various APIs and put it in your site, all statically without client-side code. Our task here is exceptionally simple: Pick out the &lt;code&gt;url&lt;/code&gt; and &lt;code&gt;canonical_url&lt;/code&gt; properties for each article, and create a mapping from the latter to the former.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node-fetch&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://dev.to/api/articles?username=dza&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;articles&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;articles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;canonical_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;canonical_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromEntries&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you are copy-and-pasting this code, make sure to replace &lt;code&gt;dza&lt;/code&gt; with your own dev.to username.&lt;/p&gt;

&lt;p&gt;This will give us an object like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"https://www.denizaksimsek.com/2020/css-additional-box-shadow/"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"https://dev.to/dza/css-adding-additional-box-shadows-2lob"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let’s try using it in our templates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight liquid"&gt;&lt;code&gt;&lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="kr"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;devToSyndication&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;]%}&lt;/span&gt;
&amp;lt;section class="syndication-links"&amp;gt;
This article is syndicated to &amp;lt;a class="u-syndication"
    href="&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;devToSyndication&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;]}}&lt;/span&gt;"&amp;gt;DEV&amp;lt;/a&amp;gt;, where you can comment on it.
&amp;lt;/section&amp;gt;
&lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="kr"&gt;endif&lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Small problem: the &lt;code&gt;page.url&lt;/code&gt; property Eleventy provides us is a relative URL, whereas the URLs we got from DEV are absolute.&lt;/p&gt;

&lt;p&gt;Sounds like a job for the &lt;code&gt;URL&lt;/code&gt; class!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;makeRelativeUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;urlObj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// you might want to append url.search and url.hash too&lt;/span&gt;
    &lt;span class="c1"&gt;// but it's unlikely, and a small amount of tech debt is&lt;/span&gt;
    &lt;span class="c1"&gt;// good for the soul&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;urlObj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;canonical_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;makeRelativeUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;canonical_url&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you should see links on any post that is syndicated to DEV.&lt;/p&gt;

&lt;h2&gt;
  
  
  Appendix: The Final Data File
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node-fetch&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;makeRelativeUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;urlObj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// you might want to append url.search and url.hash too&lt;/span&gt;
    &lt;span class="c1"&gt;// but it's unlikely, and a small amount of tech debt is&lt;/span&gt;
    &lt;span class="c1"&gt;// good for the soul&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;urlObj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://dev.to/api/articles?username=dza&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;articles&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;articles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;canonical_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;makeRelativeUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;canonical_url&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromEntries&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>website</category>
      <category>eleventy</category>
      <category>rss</category>
    </item>
    <item>
      <title>Tip: Instantly Edit Your Eleventy Site on Github</title>
      <dc:creator>Deniz Akşimşek</dc:creator>
      <pubDate>Thu, 17 Sep 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/dz4k/tip-instantly-edit-your-eleventy-site-on-github-5cme</link>
      <guid>https://dev.to/dz4k/tip-instantly-edit-your-eleventy-site-on-github-5cme</guid>
      <description>&lt;p&gt;You’re looking at the blog post you made yesterday, when suddenly a typo catches your eye. What is the fastest way to fix it? (Skip to code).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This tip assumes you use GitHub. It could likely be adapted easily for other Git providers.&lt;/p&gt;

&lt;p&gt;Add the following to your base layout (note the &lt;code&gt;{{ }}&lt;/code&gt; and replace &lt;code&gt;&amp;lt;username&amp;gt;/&amp;lt;repo&amp;gt;&lt;/code&gt; with the repo for the site):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script&amp;gt;
addEventListener('keyup', e =&amp;gt; {
  if (e.shiftKey === true) {
    switch (e.keyCode) {
    case 69: // E
      window.location = 'https://github.com/&amp;lt;username&amp;gt;/&amp;lt;repo&amp;gt;/edit/master/{{page.inputPath}}'
      break 
    }
  } 
})
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you press Shift+E, the GitHub editor will open to the current page! The switch statement is there because I used to have a few more hotkeys.&lt;/p&gt;

</description>
      <category>eleventy</category>
      <category>website</category>
      <category>tips</category>
      <category>javascript</category>
    </item>
    <item>
      <title>CSS — Adding Additional Box Shadows</title>
      <dc:creator>Deniz Akşimşek</dc:creator>
      <pubDate>Wed, 02 Sep 2020 09:54:44 +0000</pubDate>
      <link>https://dev.to/dz4k/css-adding-additional-box-shadows-2lob</link>
      <guid>https://dev.to/dz4k/css-adding-additional-box-shadows-2lob</guid>
      <description>&lt;p&gt;When you want to add a box shadow to an element, but don’t want to override any it might already have. (Jump to code)&lt;/p&gt;

&lt;h2&gt;
  
  
  Less-than-amazing solutions
&lt;/h2&gt;

&lt;p&gt;We could copy the &lt;code&gt;box-shadow&lt;/code&gt; property from the element in question, paste it and append our additional shadow at the end. Of course, this requires us to know the box-shadow on the target element, which might not always be possible (say, making a reusable &lt;code&gt;.highlight-glow&lt;/code&gt; class).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.tostackoverflow-says"&gt;StackOverflow says to put the shadow on an absolutely-positioned pseudo-element&lt;/a&gt;. This leaves us with a similar problem to the one we started with — the element in question might already have styles on the &lt;code&gt;::before&lt;/code&gt; or &lt;code&gt;::after&lt;/code&gt; that conflicts with ours.&lt;/p&gt;

&lt;h2&gt;
  
  
  My solution
&lt;/h2&gt;

&lt;p&gt;Use CSS variables to apply box shadows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.shadowy-figure { --box-shadow: .5em .5em 1em #333; box-shadow: var(--box-shadow);}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Later on, you can tack things on at the end of this variable, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.highlight { box-shadow: var(--box-shadow), 0 0 .1em #fff inset;}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One drawback is that we cannot use this technique in several classes and apply them to one element. We can solve this problem when &lt;a href="https://dev.toparent-var"&gt;&lt;code&gt;parent-var()&lt;/code&gt;&lt;/a&gt; is a thing in CSS — if it already is by the time you read this post, do let me know!&lt;/p&gt;

</description>
      <category>css</category>
      <category>workaround</category>
    </item>
    <item>
      <title>Eleventy — Dynamically Inlining Google Fonts</title>
      <dc:creator>Deniz Akşimşek</dc:creator>
      <pubDate>Fri, 24 Jul 2020 11:33:00 +0000</pubDate>
      <link>https://dev.to/dz4k/eleventy-dynamically-inlining-google-fonts-2geg</link>
      <guid>https://dev.to/dz4k/eleventy-dynamically-inlining-google-fonts-2geg</guid>
      <description>&lt;p&gt;When you add Google Fonts to your website by copying the link from the &lt;a href="https://www.rarrw.com/blog/2020/11ty-inline-google-fonts/fonts.google.com"&gt;fonts.google.com&lt;/a&gt; website, you create a request chain. That is, after loading the HTML of your page, the browser then needs to request a bit of CSS from Google, and only then can it start loading the fonts themselves.&lt;/p&gt;

&lt;p&gt;A simple solution to this is to copy the CSS returned by Google and paste it into a &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; element in your page. However, I like to change fonts quite frequently, and I’d like to automate this process. This is easy with Eleventy.&lt;/p&gt;

&lt;h2&gt;
  
  
  A JavaScript data file
&lt;/h2&gt;

&lt;p&gt;We simply fetch the CSS at build time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// _data/googleFontsStylesheet.js
const fetch = require('node-fetch')
const url = 'the URL in the Google Fonts stylesheet link href'
module.exports = fetch(url).then(res =&amp;gt; res.text())
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And include it in our base layout.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;style type="text/css"&amp;gt;{{googleFontsStylesheet|safe}}&amp;lt;/style&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enjoy your improved Lighthouse scores!&lt;/p&gt;

</description>
      <category>eleventy</category>
      <category>performance</category>
      <category>css</category>
      <category>fonts</category>
    </item>
  </channel>
</rss>
