Archaeology of Self

Every experience I have is a new lesson in life, a new addition to things that I’ve already learned. This process of learning happens whether I am aware of it or not. With every lesson, I also learn how to learn. That is, I continuously increase my capacity to learn.

Depending on the depth of my capacity to learn, the nature of the lesson shifts. When I was a child, my learning capacity was still nascent, and the lessons I learned were simple. Things were high-contrast: bad or good, sad or happy, dangerous or safe.

As I grew up, my capacity to learn deepened. I started seeing a more subtle and complex world and that this growing complexity is not the change in the world itself, but rather a change in how I make meaning of it. As my capacity to learn deepened, new dimensions of complexity opened up, with new opportunities to learn.

Thus far, the learning happened in the context of my previous learning. What I learned in the past shaped how I would learn in the future. The stark nature of the early childhood lessons created sharp edges in the foundation of my continuous construction of meaning.

I am now recognizing that these sharp edges limit the extent of my capacity to learn. They are these unseen forces that collapse my choices, blind me to alternatives, especially in challenging situations. David Burns called them “cognitive distortions”. James Hollis gave them a more dramatic name of “woundings”. Brené Brown talks of armor. All these are different takes on the same thing: the natural outcome of learning when my learning capacity is a work-in-progress itself.

Thus, the deepening of my capacity to learn now includes re-examining the lessons from the past. Through careful archaeology of Self, I am challenged to understand the nature of my assumptions and beliefs, the context of meaning-making in which I learned those lessons, and learning different lessons with my current understanding of the world.

Puzzle Me

Where do I end? Where does the “outside of me” begin? These questions seem simple at first and evoke answers involving epidermis, but I am discovering that my boundary has little to do with molecular structures. Rather, I perceive my boundary in the social context, in relation to others around me. Such boundaries tend to be rather ill-defined and ambiguous. As a result, I often experience the boundary crises: the mismatches in my understanding of where the boundary actually lies. To help me make sense of these crises, I have a fun metaphor.

In this metaphor, I am a puzzle. There are many pieces of feelings, needs, identities, fears and aspirations in me-as-puzzle. This puzzle is quite unusual in that it’s near-infinitely complex and–ever so slightly–constantly changing. No matter how much I work on assembling the puzzle, it always seems like I barely started. But this puzzle is how I define my Self, so am steadily compelled to keep working on it, consciously or not. Some pieces fit just right. Some I still haven’t figured out where they belong. Some look curiously out of place.

Other people are puzzles, too. They have their own bits and pieces that they are fitting together. It’s a lot of puzzles.

Sometimes, I get confused and decide that pieces of other people’s puzzles are mine. In such cases, my imagined design of a puzzle creates a boundary crisis of insufficiency. Because I view these foreign puzzle bits as requirements for completing my Self, I am doomed to suffer: these pieces will never be fully mine, and I will never feel sufficient. I will never feel like I am good enough or at peace with who I am.

My impostor syndrome is a good example here. It’s that underlying belief that my accomplishments define my worthiness. That is, I define my self-worth by how others value what I’d done. I crave that missing puzzle piece of others’ approval. I can’t fathom how my puzzle could be complete without it, and yet I can never own it.

The opposite also happens. I may decide that my puzzle pieces are necessary for completing other people’s puzzles. This creates the boundary crisis of overwhelment. Seeing bits of my Self as critical in others’ lives, I am also doomed to suffer: I will always feel overwhelmed trying to co-assemble multiple puzzles, rather than just focusing on mine.

For example, when I avoid giving a colleague unpleasant feedback because I am overcome with anxiety that they will take it poorly, I assuming responsibility for how they would receive that news. All of the workarounds and clever techniques that follow are me trying to complete their puzzle with my pieces.

Now, I have plenty of cases of both. I have been putting this puzzle together all my life, and doing so mostly unconsciously. I grabbed others’ pieces and tried jamming them in, and I took plenty of responsibility for others’ puzzles. My puzzle is a mess, with tons of opportunities for suffering.

To reduce this suffering, I systematically examine me-as-puzzle, remove foreign pieces, and take back the pieces that are mine. It sounds easy, but given the decades of lodged pieces in this massive, unique collage that is me, it is quite challenging. Remove a piece, and whole swaths of the puzzle suddenly become unmoored, world temporarily seizing to making sense. It’s a high-risk proposition. If I am not that puzzle that I was before, then who am I? Where do others end? Where do I begin?

The Illusion of Injured Identity

Throughout my live, I accumulate identities: a father, a husband, a software engineer, an occasional blogger. These identities are curious constructs, because they link me to other objects or concepts. Each turns two separate things–me and something else–into one, fusing us. Suppose I view myself as a hockey fan. Put differently, a “hockey fan” is one of my identities. Bizarrely, when someone says something disparaging about hockey fans, I have an emotional response. I feel irritated or defensive. What’s happening here?

What I am experiencing is truly a wondrous thing: the link to identity rings the power of the negative comment about hockey fans into me–bzzzt!–like an electrical current, and I feel something akin to physical pain. Sometimes this pain is mild (I am not that big of a hockey fan), and sometimes it’s not. The stronger the link–that is, the stronger I am fused with the object of my identity–the more intense the pain. Back in the Shadow DOM days, I quit Twitter because I simply couldn’t handle the excruciating hurt of comments that I would even remotely perceive as negative toward Web components. The identity link was so strong that in my mind, I was Web components.

In such cases, I am feeling the effect of injured identity. I am acting as the designated receiver of pain of an injury to an object. This injury is not real. Objects can’t feel pain. But through the magic of fused identity, I am here to take on that responsibility.

How did I end up fused with my identities? Best I can tell, it’s a habit that I developed to become a functioning member of society. As I was growing up, I was bombarded with calls to become a “responsible adult”, “good neighbor”, “trustworthy friend” or even a “rebellious, out-of-the-box thinker”. The societal system around me applied its unyielding pressure to adopt the identities that were necessary to be socially accepted. At school, at home, around friends, various identities were held out and incentivized. A “good student” gets goods grades. A “cool kid” gets respect from his buddies. A “weird kid” gets bullied.

At that age, I only knew of one way to adopt an identity: to assume it, to become it, to make it part of myself. So I became a whole web of identities. Some of them I considered desirable and some I desperately did not want.

Though this habit had helped me make sense of my life early on, as the mental demands of the modern life increased, I began to find the effects distracting and counter-productive. When I feel the pain of injured identity, I immediately move to protect myself. My sympathetic system mobilizes to cope with a physical threat. My heart rate goes up. My perspective narrows, zeroed in on the threat. My contrast knob goes to 11. No shades of gray here. I spin the stress response roulette: fight, flight, or freeze.

Since there’s no actual physical threat here, my response is usually directed at another person, whom I perceive to have injured me. Will I be my best self interacting with this person? Nope. Will I regret this interaction later or stew on it for hours/days/months? Yup. Will I have a nagging feeling that I wasted a ton of energy? Definitely. Maybe even have another stress response to feeling terrible about the waste and beat myself up? Oh, I have totally done that. Have I mentioned that I myself could be the target of my threat response?

I want to change this habit.

For me, the change begins with learning to detect an injured identity. After I cringe as someone comments about me not writing any code lately, I take time to reflect on what’s going on. I trace the pain back to the “software engineer” identity and examine my linkage with it. Just being able to observe this process rather than being driven by it has been immensely helpful for me. In doing so, I begin to gently separate myself from from the identity. I start seeing it as something that I have, rather than something that I am.

I am not defined by my identities. They are just tokens of the society’s currency, and though valuable, they–just like coins in my pocket–do not determine my worthiness. My self-worth comes from something deeper. Staying focused on this distinction, patiently struggling to see through the illusion of injured identity is how I gradually turn these random pangs of pain and automatic reactions into a deeper, more centered life.

My Own Clock

Most of my life I lived unaware of My Own Clock. I am not sure how, but I never seemed to see it. As a kid, I was somewhat bothered by the odd pulsing sense coming from some invisible thing deep inside. It was weird and I preferred not to dwell on it. Instead, I learned to listen to others’ Clocks. Early on, other people appeared big and important. Listening to the tick-tock of their Clocks was just the logical thing to do. I even got pretty good at carrying the beat of others’ Clocks, almost as if they were my own.

It wasn’t easy. Everybody’s Clock is different, with their own drifts and skips. Synchronizing all of those Clocks was work. At first, I was excited to learn and master it, because being in sync allowed me relate to other people and appreciate their being. But I kept noticing that occasionally, the rhythm of another’s Clock would resonate in magical ways. Something inside of me would match that rhythm–just briefly–and the world would become a bit brighter. Like rays of light, little by little, these blips of resonance revealed that carrying others’ Clocks wasn’t just work. It was toil.

Boy, those were tough times. I felt lost, realizing the misery of existence that is just fitting into others’ Clock beats. I felt betrayed, let down by the insight that all these Clocks, however well-adopted by me, can never be part of me. And yet, this insight is what nudged me to a wondrous discovery.

I am not exactly sure how, but one day, I saw a glimpse of it. While reflecting, I was startled to see My Own Clock. Not a precisely-executed replica of my Father’s Clock. Not a beautifully-crafted myriad-piece orchestra of The Society Clock. Rather, My Own Clock. Clicking its own rhythm. The rhythm that way back then, would briefly resonate with others’. A barely audible tick-tock. And yet, my own, unique rhythm.

That glimpse was a profound and energizing experience. Now I knew that it’s there. It is there. I still can’t always find it, and I still confuse it with the other clocks. It’s a struggle to unlearn the habit of falling into the rhythm of another’s Clock. But every day, I strain to look and listen. And every day, get a little bit closer to living by My Own Clock.

Going Forward Is Leaving Past Behind

Greetings, hypothetical Web app developer. So I wrote this thing. It’s for your eyes only. Your non-Web developer buddy will find my ramblings mostly trivial and nonsensical. But you… you are in for a trip. I think. Ready?

Prologue

It’s hard to part with the past. Things we’ve done, stuff we’ve learned, the experiences we’ve had — they aren’t just mental artifacts. They shape us, define us. Yet, they are also the scars we carry, the cold-sweat nightmares that keep us awake. And thus continues our struggle between embracing and shedding what has been.

In this way, a platform is somewhat like us. If it only embraces its past, it can’t ever evolve. If it only looks into the future, it’s no longer a platform. Striking the balance is a delicate game.

Progress

In order to survive, a platform has to move forward. A tranquil platform is a dead platform.

In particular, the Web platform had been caught napping. It awoke startled, facing the mobile beast that’s eating the world and went: Oh shit.

Turns out, our platform has gotten a bit plump. All those bells and whistles are now just flab in the way of scampering limbs. It’s time to get lean–or be lunch.

What’s worse, we aren’t even in the same league. While we’re still struggling to run without apoplexy, the other guy can fly and shoot lasers. We’re so screwed. Gotta get cranking on those lasers. And start losing weight.

Cost

Losing weight is hard work. Like with anything where we give up our habits, the way we steel ourselves and go through is by thinking of the cost of not changing.

For the platform, the obvious one is the code size, which is really a proxy for the cost of complexity — the engineering and maintenance complexity, to be precise. Making a modern browser is an incredibly large task and adding urgency further skews the triangle to higher costs.

Then there’s this paradoxically-sounding thing:

The less often a feature is used, the more it costs.

This is the opportunity cost. The more complicated the system, the more confused is the reasoning about the next steps. At the limit, you can’t step forward at all — there’s always an artifact from your past in the way, be it the fun extra nested event loop, the thing you thought was cool back then, or the the dead appendages you grew one day, just for the hell of it.

Here’s another way to put it (now with action figures!): You have a platform with features and users. Bob is a user of a feature. The cost of keeping this feature in the platform is evenly distributed among all users.

However, if Bob is the only user of the feature, something weird happens: all the users still pay the costs, but now they’re paying them to fund Bob’s habit.

As other users ask for new capabilities and polish, Bob’s feature slowly sinks to the bottom of priorities. A statistical wash, the code of the feature grows a beard and stops doing laundry. Bad smells and bugs creep in. With the rest of the code base moving on, the likelihood of a fire drill around this forgotten mess only goes up.

Time is finite and you spend non-zero time on every feature. There’s some feature work you’re not doing to keep this Bob-only feature.

At this point, all other users should be strongly motivated to make Bob stop using his feature. Bob’s dragging everyone down.

Budget

These are all pretty obvious thought experiments, I guess. Web platform engineers (aka browser builders) are a limited resource. For you, Web app developers, they are your home improvement budget.

Thus we arrive to the main point of this anecdote: how would you rather have this budget allocated?

The answer likely goes like this (pardon for possibly putting words in your mouth):

I want you bastards to let me build things that are not terrible on mobile. You are moving too slowly and that’s highly annoying. My boss is telling me to build a native app, and I SWEAR I will, if you don’t start moving your goofy ass NOW. You know what? I am leaving now. Hear these footsteps?

I’m holding my breath, hoping you’re just faking those footsteps. And if you are (whew!), it seems fair to assume that you want most of your budget spent on making browser leaner, meaner, and capable of flying while shooting lasers. Not maintaining the old stuff. Which means that we need to get serious about deprecation. And being serious means we need data.

Data

In Blink land, we have a fairly comprehensive usage measuring system. Despite some limitations, it provides a reasonable approximation of how widely a feature is used.

Just knowing how widely it is used isn’t enough. There’s definitely some extra dimensions here. Despite their equally low usage, there’s a difference between a newly-launched feature and a forgotten one. Similarly, something that’s rarely used could be so well-entrenched in some enterprise front-end somewhere that removing it will be met with tortured screams of anguish.

We also need to give you, web developers, clear indicators of our past mistakes. There are plenty of platform features that are frequently used, but we platform peeps can’t look at without a frown. It seemed like a good idea at the time. Then the reality happened. Communicating this frown is sometimes difficult, but necessary to look forward.

Action

Clearly, we have work to do. Arriving at a clear framework of deprecation principles is trial, error, and likely yet more tears. But we know we need it. We’re working on it.

As for you, my dear web developer… I need your help.

Use feature metrics in planning your new work and refactoring. If you see a feature that’s falling behind in statistics, think twice about using/keeping it. Talk to your friends and explain the danger of relying on old, rarely used things.

Don’t be a bob. Don’t let your friends be bobs. Being a bob sucks. Not the actual person named “Bob”, of course. Being that Bob is totally awesome.

What the Heck is Shadow DOM?

If you build Web sites, you probably use Javascript libraries. If so, you are probably grateful to the nameless heroes who make these libraries not suck.

One common problem these brave soldiers of the Web have to face is encapsulation. You know, one of them turtles on which the Object-Oriented Programming foundation sits, upon which stands most of the modern software engineering. How do you create that boundary between the code that you wrote and the code that will consume it?

With the exception of SVG (more on that later), today’s Web platform offers only one built-in mechanism to isolate one chunk of code from another — and it ain’t pretty. Yup, I am talking about iframes. For most encapsulation needs, frames are too heavy and restrictive.

What do you mean I must put each of my custom buttons in a separate iframe? What kind of insane are you?

So we need something better. Turns out, most browsers have been sneakily employing a powerful technique to hide their gory implementation details. This technique is called the shadow DOM.

My name is DOM, Shadow DOM

Shadow DOM refers to the ability of the browser to include a subtree of DOM elements into the rendering of a document, but not into the main document DOM tree. Consider a simple slider:

<input id="foo" type="range">
 

Pop this code into any WebKit-powered browser, and it’ll appear like so:

Typical Slider Control on WebKit

Simple enough. There’s a slider track and there’s a thumb, which you can slide along the track.

Wait, what? There’s a separate movable element inside of the input element? How come I can’t see it from Javascript?

var slider = document.getElementsById("foo");
console.log(slider.firstChild); // returns null
 

Is this some sort of magic?

No magic, my fair person of the Web. Just shadow DOM in action. You see, browser developers realized that coding the appearance and behavior of HTML elements completely by hand is a) hard and b) silly. So they sort of cheated.

They created a boundary between what you, the Web developer can reach and what’s considered implementation details, thus inaccessible to you. The browser however, can traipse across this boundary at will. With this boundary in place, they were able to build all HTML elements using the same good-old Web technologies, out of the divs and spans just like you would.

Some of these are simple, like the slider above. Some get pretty complex. Check out the video element. It’s got trigger buttons, timelines, a hover-appearing volume control, you name it:

WebKit Video Element With Controls

All of this is just HTML and CSS — hidden inside of a shadow DOM subtree.

To borrow a verse from that magnetic meme duo, “how does it work?” To build a better mental model, let’s pretend we have a way to poke at it with Javascript. Given this simple page:

<html>
<head>
<style> p { color: Green; } </style>
</head>
<body>
<p>My Future is so bright</p>
<div id="foo"></div>
<script>
    var foo = document.getElementById('foo');
    // WARNING: Pseudocode, not a real API.
    foo.shadow = document.createElement('p');
    foo.shadow.textContent = 'I gotta wear shades';
</script>
</body>
</html>
 

We get the DOM tree like this:

<p>My Future is so bright</p>
<div id="foo"></div>
 

But it is rendered as if it were this:

<p>My Future is so bright</p>
<div id="foo"> <!-- shadow subtree begins -->
    <p>I gotta wear shades</p>
</div> <!-- shadow subtree ends -->
 

Or visually like so:

Shadow DOM Example

Notice how the second part of the rendered sentence is not green? That’s because the p selector I have in my document can’t reach into the shadow DOM. How cool is that?! What would a framework developer give to have powers like this? The ability to write your widget and not worry about some random selector fiddling with your style seems … downright intoxicating.

Course of Events

To keep things natural, events fired in shadow DOM subtree can be listened to in the document. For instance, if you click on the mute button in the audio element, your event listeners on an enclosing div would hear the click:

<div onclick="alert('who dat?')">
    <audio controls src="test.wav"></audio>
</div>
 

However, if you ask to identify who fired the event, you’ll find out it was the audio element itself, not some button inside of it.

<div onclick="alert('fired by:' + event.target)">
    <audio controls src="test.wav"></audio>
</div>
 

Why? Because when crossing the shadow DOM boundary, the events are re-targeted to avoid exposing things inside of the shadow subtree. This way, you get to hear the events, fired from the shadow DOM, and the implementor gets to keep their details hidden from you.

Reaching into Shadows with CSS

One other trick up the sleeve is the ability to control how and whether CSS reaches into the shadow subtree. Suppose I want to customize the look of my slider. Instead of the standard OS-specific appearance, I want it be stylish, like so:

input[type=range].custom {
    -webkit-appearance: none;
    background-color: Red;
    width: 200px;
}
 

The result I get is:

Slider with a custom-styled track

Ok, that’s nice, but how do I style the thumb? We already determined the that our usual selectors don’t go into the shadow DOM tree. Turns out, there’s a handy pseudo attribute capability, which allows shadow DOM subtrees to associate an arbitrary pseudo-element identifier with an element in the subtree. For example, the thumb in the WebKit slider can be reached at:

input[type=range].custom::-webkit-slider-thumb {
    -webkit-appearance: none;
    background-color: Green;
    opacity: 0.5;
    width: 10px;
    height: 40px;
}
 

Which gives us:

Fully custom-styled slider

Ain’t it great? Think about it. You can style elements in the shadow DOM without actually being able to access them. And the builder of the shadow DOM subtree gets to decide which specific parts of their tree can be styled. Don’t you wish you had powers like this when building your UI widget toolkit?

Shadows with Holes, How’s that for a Mind-bender?

Speaking of awesome powers, what happens when you add a child to an element with a shadow DOM subtree? Let’s experiment:

// Create an element with a shadow DOM subtree.
var input = document.body.appendChild(document.createElement('input'));
// Add a child to it.
var test = input.appendChild(document.createElement('p'));
// .. with some text.
test.textContent = 'Team Edward';
 

Displaying as:

Input Element and Nothing Else

Whoa. Welcome to the twilight DOM — a chunk of document that’s accessible by traversal but not rendered on the page. Is it useful? Not very. But it’s there for you, if you need it. Teens seem to like it.

But what if we did have the ability to show element’s children as part of its shadow DOM subtree? Think of the shadow DOM as a template with a hole, through which the element’s children peek:

// WARNING: Pseudocode, not a real API.
var element = document.getElementById('element');
// Create a shadow subtree.
element.shadow = document.createElement('div');
element.shadow.innerHTML = '<h1>Think of the Children</h1>' +
    <div class="children">{{children-go-here}}</div>';
// Now add some children.
var test = element.appendChild(document.createElement('p'));
test.textContent = 'I see the light!';
 

As a result, if you traverse the DOM you will see this:

<div id="element">
    <p>I see the light</p>
</div>
 

But it will render like this:

<div id="element">
    <div> <!-- shadow tree begins -->
        <h1>Think of the Children</h1>
        <div class="children"> <!-- shadow tree hole begins -->
            <p>I see the light</p>
        </div> <!-- shadow tree hole ends -->
    </div> <!-- shadow tree ends --> 
</div>
 

As you add children to element, they act as normal children if you look at them from the DOM, but rendering-wise, they are teleported into a hole in the shadow DOM subtree.

This is the point where you admit that this is pretty cool and start asking:

When can I have it in my browser?

Homework Assignment

Did you think you’d read through all this preaching and get away without homework? As a Javascript library or framework developer, try to think of all the different great things having shadow DOM would allow you to do. Then think of specific use cases (actual/pseudo code a plus) of where shadow DOM could be applied. To help you get your thinking groove going, here is current list of use cases.

Finally. share your use cases on public-webapps mailing list. The discussion about adding these capabilities to the Web platform is under way and your help is needed.

If you aren’t a much a framework writer, you can still participate — by cheering for the shadow DOM and spreading the joy on your favorite social networking site. Because joy is what’s it’s all about.

PS. SVG and Shadow DOM

Almost forgot. Believe it or not, SVG has actually had shadow DOM since the beginning. The trouble is, its shadow DOM is very… shady. No, that’s not it. There’s another qualifier that also begins with “sh” and ends with a “y”. Yeah, that one. I could go on, but trust me on this. Or read the spec.

From HTML5 to Gibson’s Matrix?

I shouldn’t admit it, but — what the heck. I haven’t read the Sprawl Trilogy. Until this weekend. After falling prey to another round of the seasonal crud, and with the long Memorial Day weekend in sight, I dove in.

The books aged extremely well. It was too easy to ignore the awkward artifacts of the 80’s culture and go with the smooth and intricate flow. It felt just right. Not the mind-boggling, monolithic Stephenson’s universe that pounds you with all its kilo-page might. It was gentler and more focused on the characters, rather than the surrounding gadgetry and sound reasoning behind its existence.

Anywho. I walked away inspired. The Sprawl was a tantalizing illusion, my brain spinning in a vertigo of subconscious attempts to fill in the missing engineering details. But in riding this high, I also felt disappointment. It’s 2009, for crying outloud. Where are the AIs? I mean those that can reasonably fool a Turing test? Where are the consoles that connect you directly to the full sensory representation of the Internet? And hovercrafts?! I want my frickin hovercrafts!

How is it that we are still tinkering with a 10-year old hypertext format, asymptotically trying to make it work right on our respective rendering engines, bolting new steel plates on the old wooden boat as it creaks, sinking further under the weight of our add-ons? How come there’s a whole echelon of computer industry burning midnight oil congealing bits of CSS, HTML, and JS into the scary, scary nonsensical frankensteins that we call Web sites? And how come it is so hard to build and grow these sites — not to mention use them?

Where have we gone wrong? Perhaps it was the naive notion that HTML wasn’t just an accidental leader of the rising wave, that it was somehow special, because it was just like text and thus “easy of use?” I shudder even typing these three words. Or was it the idea that the Web is what it is and shouldn’t break it? Or maybe it was us, proclaiming that content is king and that the vehicle didn’t matter? We’ve become content with what we’ve got. Even new aspirations, however alien, look suspiciously like the same old stuff.

But yes, we are where we are. Otherwise, we wouldn’t be anywhere. Right? Riiight. We have this spec, called HTML5 and we’re trying to make it work. It’s better than what we have today, and it is a step forward. But on the big scheme of things — is this what we need? Small, painful incremental steps on the burning coals of the Web as we know it? Is this taking us somewhere? And if it is, are we there yet?

Are we there yet?