Categories
hyperweb

It Came…From the Internet! MutationObserver

[Fade in Louis Armstrong singing On the Sunny Side of the Street.]

Grab your lab coat // Put on your hazmat, baby
Leave your worries on the doorstep
Life can be so sweet
On the sunny side of the street
[…]

Okay, MutationObserver isn’t really that scary. It’s part of the DOM4 specification as a replacement for Mutation Events. MDN: DOM: MutationObserver documents it.

What are Mutation Events? A DOM3 specification to allow you to watch the DOM change using the well worn events API. You know, the old

node.addEventListener('click', onNodeClick, false);

style events.

But Mutation Events made things slow. A lot of sites mutate or change the DOM quite often, and depending where you attach the listener and how frequent the changes come, it added up to a lot of event traffic. MutationObserver replaces this.

A MutationObserver doesn’t receive a callback for every change. Instead it receives periodic callbacks for a group of changes. That group may contain a single change, depending on the stability the DOM tree (if only a few changes occur at large intervals, they may be announced separately). Think of it like an announced log instead of alerts.

MutationObserver takes a bit more setup than just tagging an event listener on a node. But that setup makes it cleaner and more useful.

var observer = new MutationObserver(function (mutations) {
    mutations.forEach(function (mutation) {
        console.log(mutation.type);
    });
});

That’s a simple MutationObserver. You provide a function that receives an Array of MutationRecord objects. But that just creates the observer, you have to activate it.

var config = { childList: true, attributes: false, characterData: false, subtree: true };

So first you need an object (technically a MutationObserverInit object) specifying what types of mutations you care about (you can also specify some extra options about which data to include in the MutationRecord objects you get back). You really just worry about making this give you what you want and not give you anything else. If you want to know about node added or removed from the DOM tree, you don’t need attributes or characterData, for example.

Once you have your configuration ready, you also need a root node to observe. You can observe document, the true root, but you should attempt to observe the minimal subtree you will need.

Say the page shows a chess game, and you want to add some automatic comments or classes (for styling) to the move log. You only need to observe the part of the tree that contains the log. The page logo, the board itself, the chat, and anything else don’t matter.

var moveLog = document.querySelector('#moveLog');

We can finally turn the MutationObserver on:

observer.observe(moveLog, config);

Now when new changes happen under moveLog, the function we specified when creating the observer will be called back. But we can go a bit further. Let’s say you have two separate subtrees to observe. You could either find their lowest common ancestor and observe that whole subtree, or you can do the smart thing and simply register the observer with the second subtree:

observer.observe(oneNode, config);
observer.observe(twoNode, config);

Note that was, “register the observer with” the node, not the other way around. Although you call on the observer, this tells it to add itself to the list of observers associated with the node in question.

You can also shut the whole thing down:

observer.disconnect();

This kills all the registrations, so unfortunately you cannot easily modify the actively observed subtrees.

Also note:

observer.observe(myTarget, config1);
observer.observe(myTarget, config2);

This replaces the options for observing myTarget.

Anyway, that’s a brief overview of the not-so-scary, highly useful MutationObserver. It’s particularly nice for user scripts that want to cope with dynamic web pages. Instead of being stuck with some modification only for the nodes that were there when the page loaded, you can now easily observe changes and carry your modifications over as new nodes appear.

Categories
society

Learning to Compute

Some well-known person in the software community wrote about why, I don’t know, mere mortals?, shouldn’t learn to write software.

To be honest I didn’t read it. Any time someone says that I shouldn’t do something for any non-scientific or non-moral reason, I add another check to the column for “this maybe should be done.”

I skimmed several of the thoughtful rebuttals on other blogs, and think their general consensus is valuable, which is basically, “yes, you should learn to write software, because it’s awesome.”

Anyway, this isn’t about whether you should or shouldn’t, can or can’t, will or won’t. This is about doing the actual bit that’s being discussed abstractly.

Let’s assume for the sake of argument that you are using Firefox and viewing this site in the browser. Let’s assume it’s on a non-mobile Operating System with a keyboard and other fancy stuff like a screen.

Let’s assume you were to press the key combination Ctrl+Shift+K (Hey! Wait a damn minute there. Don’t press stuff without finding out what it does!) or go to the Firefox menu, to Web Developer and then to Web Console (which is what the key command before does).

You should now see some slick little bit of chrome fall out of the sky above the website.

You should see that it has a text input area at the bottom. Click there. Type something like, alert("Boo!"); and press Enter. Stop! Why are you typing stuff in before you know what it does?

Okay, to be fair, I type stuff in without knowing exactly what it will do, and aside from some wizards, most people who write software do this. But we know almost exactly, and we’ve got experience: think of it like cooking. A master chef can imagine how a recipe will taste just by reading it. Experience works like that, though even the experienced can be mistaken.

So before you type something, you should stop and think about what it might do, and what you want it to do. alert, that might make lights flash and buzzers sound. But it has those parentheses around the quoted bit.

Maybe it creates some kind of alert using that quoted part.

Go ahead and try it.

Right! A happy little alert box pops up with the text Boo!.

So why does that work? Think of it like cooking, again. The baker doesn’t just reach into the oven and pull out a pie. Each piece had to be made, including the pie tin (which was beyond the scope of the baker’s activity). In this case, think of the alert() bit as the pie tin. The makers of the browser gave you the pie tin and said, “fill it with what you need to fill it.”

If you think about it, the parentheses almost look like a pie tin. Are you hungry yet?

So let’s do something a bit simpler this time. Just type 1 + 1 and press Enter. Right, good thought, we have to ask what it might do. Well, if I wrote it down on paper and handed it to you, what would you probably say? Yes, you would say, “two.” That’s what the console will say back to you:

[13:25:34.419] 1 + 1
[13:25:34.423] 2

That bit there is taken directly from the console. If you select lines in it and then copy them, it puts the fancy timestamps in front. Those help you understand the behavior of more complex programs by letting you know what times the output corresponded to, how long things took (by seeing the difference in the times), etc.

Okay, one more thing to try for today. Start typing document, but just the d at first. Notice it gives you a handy drop-down of possible matches. You can use the up and down cursor keys to go through that list, or click on one with the mouse. If you keep typing, once it has a plausible match it will ghost-in the rest of the word for you. Once that happens, you can press the Tab button to complete the word.

Once you have document, put a . after it, and then type getElementById. You may have noticed that there were other getElement* bits, and some other things too. I hope you noticed, that’s the main skill to work on as a programmer: seeing all the details and wondering why.

Later on, if you want to keep learning about programming, you might go back to the web console (Ctrl+Shift+K) and just start typing things (don’t press Enter, just type say, c and see what pops up in the list). Ask yourself what they might do, and then use a search engine to ask the web what they actually do.

Okay, back on track: document.getElementById(???) What do we need to replace the ??? with? You’ll see the so-called “CamelCase” names in software a bit, so get used to mentally putting spaces in: get Element By Id. Right, if we hand it the Id, it will hand us the Element.

Let’s use one I know: site-title. That’s the id for the HTML element containing the blog title up top. So let’s do something with that.

We can do this two different ways. One way is to store the element we get back, and then speak about that, the other way is to do it directly.

The first way is to give the Element a name. To do this we can type var titleElement = document.getElementById('site-title'); and press Enter. We type var first, because we want it to be a regular variable. This has to do with scoping rules, which I won’t discuss here, but you will learn about if you keep growing your skill.

Once we have it as a variable named titleElement (you could name it something else if you prefer), we can use the name to reference that Element.

Now we can type titleElement.style.backgroundColor = "black"; and press Enter. The style part means that you want to access the Element‘s style properties. The style.backgroundColor means you want to access the background color of the Element. And we’re setting it to the named color black.

Scroll up to the top and look at the result. The background around the blog title is now black!

It doesn’t look right, of course. The background was more of a white, so let’s try changing it back.

Press the up arrow, and it will show you the last thing you typed. You can navigate the input history in the console using the up and down keys.

Change black to white and press enter again. Oops, it’s not quite white, either. What do we type to get it back the way it was?!

Let’s set it back the way it was, but let’s do it the other way I mentioned before: type document.getElementById('site-title').style.backgroundColor = "inherit"; and press Enter. Here we aren’t bothering to store the Element in a variable. We’re using it directly from the return of getElementById(). And we’re setting the color to inherit, which means “whatever the parent value is.”

The rules for Cascading Style Sheets are something you can learn about later, but you can think of it like cooking again. By default, a BLT sandwich has bacon, lettuce, and tomato. If someone wants a special one, then maybe its bltSandwich.style.bread = "pita", but normally it’s just whole-wheat. inherit just means, “whatever it would be for the environment it’s in.” (It means inherit the value from the parent, because elements in HTML are in a tree structure).

The main thing is that the color is back to normal!

That’s enough for now. You can close the console by clicking the x in the corner of it, or by pressing Ctrl+Shift+K again. If you make a live change while learning (live changes are those that you make to a webpage directly, such as by the Web Console), and you don’t know how to undo it, simply reloading the page should get you back to the default state.

Categories
hyperweb

Prototyping a Search Form

jsfiddle.net: a prototype of a searchform

Decided to make a little prototype today, to get a feel how this kind of form might work.

Description: The form has “bookends” with the left representing the previous searches and the right representing future searches. That’s previous/future as in a kind of timeline.

Hovering over the bookend will show the chronologically-closest value alongside the current, and clicking will both go to that value and show the next in that direction. If there is more than one value in a direction, it shows a little dropdown, and you can jump to any point in the history from there.

It’s not the cleanest code, but it’s a prototype, and it does a decent job of letting me get a feel for if this kind of control is worth using.

It’s likely that other controls are more useful for most cases, but maybe this is useful for some. Particularly, it might be more useful if the whole history showed at once, and you could use arrow keys to move back/forth.

Anyway, I did this in JSFiddle, mainly because it’s easy enough to share and people can try it right there.

Just hover/click on the little ends on either side of the main form in the result area (bottom right pane).

edit: I embedded it here:

Categories
analogies

Analogies for Tech: The Web as Houses

One of the historical patterns we see is where a specific field or part of life moves from being expert to common.  That’s been true with reading over time, for example.  It’s been true with automobiles in some countries.  There was a time when only women had babies….okay, you got me there.

But over time there’s an expectation in the computer industry that average people will learn technology to a greater degree, even if not to the same depth as a computer scientist or computer engineer.

I am examining potential analogies for explaining technology of various sorts to laypersons in the hopes they will grasp the relationships of the world they use every day.  I’ve already given part of the explanation of why, but here’s the other part:

Until you see the cracks in the walls with the sunlight slicing the darkness, and until you see the bubbles rising to the edge of the universe and ask what if it isn’t the edge at all, you have very little reason to jump out of the water or break into the day.

With that I hope to, from time to time, examine potential analogies for bits of technology.

The Web

The metaphor for the web is moving to a house you are building. In this, HTML is a set of special boxes.  You have some like title that are meant for very particular contents. You don’t put your china in a box with your hammers.

You have other boxes like html itself, which are there to hold everything you put in them. You put your china in one box, and your hammers in another, but both of those boxes can fit in a third, bigger box. That bigger box is actually the truck, in this case, but you might have palettes that hold many smaller boxes, as with something like div.

Then you have CSS, which are tags you attach to the boxes to tell the movers where they go. “This is a very dark brown room.” Or, “all of the windows should be blue, but after you have looked through one, it is purple.”

If you’ve seen that last bit, it’s the style applied to links using the default styles of most web browsers.

That’s right. There are default styles that come with the browser. They are there so that if you don’t specify, there’s a good base to work from.

Now, additional styles let you override those defaults, but there are also some amount of styling implied in the way you pack your boxes.

If you put some text in one box, then it will end up together in the house unless the styles applied are very explicit.

You also have peculiar boxes like script, which tell the builders that they contains fixtures or robots that will respond to visitors to the house in some way. They might be faucets that will, when turned on, create or delete whole rooms. They might be spy cameras to watch the visitors and tell the owners of the house what they did in the house.

Extending the metaphor out, the creator of the document packs everything up in their boxes with their blueprints and send them up to a server. Then you visit the server and it spits out the boxes with the blueprints, which your builder, the browser, assembles.

Some of the documents aren’t made in that way. Increasingly, the houses of the web are made in factories called applications. Think about some service like Google Search. They have thousands of computers working to find the content all over the internet, and when you search those computers shove that content into the right boxes with the blueprints and styles and deliver them to you.

Anyway, I guess that’s enough about the web for today. Did this analogy make it clear how the web works?

Categories
Firefox

Welcome to… Firefox 6?!

There’s a new Firefox development process (PMO: Mozilla Firefox Development Process (draft)).  Firefox 4 will come out next week, but Mozilla is looking forward to several more releases this year.  A lot of people are whining about browser version number hyperinflation, but that’s not what this is about.  It’s about a better browser.

The reasons for the change are several:

Web Growth

The web is growing as fast as ever.  New technologies are rolling out, and the landscape keeps changing.  This calls for more active browser development than before.  It’s not just about enhancing the workflow you’re used to, but about making the browser fit with the changes to your browsing habits as the web changes.

Better UX

More releases means more refinement in existing browser design and in new design.  As GNOME and Ubuntu prepare to release reimagined desktops, one of the big results is going to be the fallout from the shock of major changes.  Users adjust better to gradual changes in their software, as it moderates the learning curve and increases their ability to have moments of discovery.

Improved Consistency

One of the major issues with long release cycles is that some features just aren’t ready in time, but the organization is so invested that it wants to hold the release for them.  Other features aren’t ready, but they just gather dust for a year or two.  Faster releases means more features, because there’s less pressure to get that one big feature that isn’t ready.

Happy Developers

One of the best arguments for faster releases is that community contributors are happier.  The patch they just landed can actually see daylight in a reasonable timeframe.  That means they get more reinforcement from contributing and will do so more often.

Less Work

And the final reason to push for tighter loops is that it’s less work per loop.  It’s the difference between driving under an overpass and through a tunnel.  When you enter a tunnel it feels like time has stopped.  You’re just seeing the same thing over and over.  There’s no feedback.  It can even cause a feeling of despair and remorse for having ever entered the damn thing.  Will it ever end?  This tunnel… it’s eating my soul.  When you have a shorter tunnel, you can see daylight before you’re even halfway in.  It feels good.

I’m very glad to see this change in Mozilla.  It has every sign of making their browser much better, and the whole web will benefit.