My JavaScript book is out! Don't miss the opportunity to upgrade your beginner or average dev skills.
Showing posts with label DOM. Show all posts
Showing posts with label DOM. Show all posts

Tuesday, June 19, 2012

Dealing With Future Pointers

I have talked about this already in both JSConfEU and QCon - London and I have also blogged a couple of times about this problem that many developers keep ignoring ...

The Unexpected Input


In JSConfEU I have showed with my slides this picture:
iPad and magic mouse
which is simply the reason most of the so called mobile websites won't work as expected.
Why that? Because "ontouchend" in window, the most pointless feature detection ever, will produce a positive result and if you decide which event should be attached to the document or any DOM node relying this check, the moment the device that exposes touch events BUT has a trackpad, mouse, or any other alternative pointer device connected, it will fail, it won't work, it will look broken!

A Hybrid Solution

We could make the assumption that if the user is using fingers, the user will keep using fingers ... while if the user chooses the alternative pointer, there shouldn't be a case where fingers are again on the screen.
For this kind of situation/assumption, a lazy pointer detection is the only one we can rely.

// useless/unoptimized code - used to explain and nothing else
function initPointerEvents(e) {
// decide what should be used later on
switch (e.type) {
case "touchstart": return useTouches();
// other possible cases
default: return useMouse();
}
document.removeEventListener("touchstart", initPointerEvents, true);
document.removeEventListener("mousedown", initPointerEvents, true);
document.removeEventListener("mousemove", initPointerEvents, true);
document.removeEventListener("mousewheel", initPointerEvents, true);
}
// note the usage of true, so that we can be sure these detections are performed
// before any other listener attached with "false" ( bubbling phase )
document.addEventListener("touchstart", initPointerEvents, true);
document.addEventListener("mousedown", initPointerEvents, true);
document.addEventListener("mousemove", initPointerEvents, true);
document.addEventListener("mousewheel", initPointerEvents, true);

With above example it becomes really easy to understand what's the user choice: either touch, or keyboard.
No matter what kind of device we are dealing with, the very first event will tell us what kind/group of events we should use.

Well ... Still Not Friendly

What if the user combines touches and trackpad?
Microsoft Surface Tablet
The Microsoft Surface proposal looks great to me, but at the same time it might fail in most common mobile oriented websites.
First of all, MS has introduced kinda proprietary events to deal with pointers but I wonder how these events will behave once the user decide to switch between trackpad and screen.
I imagine that the mouse cursor will appear and disappear accordingly, at least that is what could make sense to me, so that the page could actually implement both :hover styles and still be based on touch events but the simple fact is that all this is a mess for web pages.
Here an example of how things could go wrong, assuming the classic trackpad in older laptop won't mean that msPointerEnabled is true ( being that screen not touchable )

// the MS suggested feature detection
if (window.navigator.msPointerEnabled) {
// fails when the user uses the trackpad instead of the screen
} else {
// fails when the user uses the screen instead of the trackpad
}

So, unless Windows 8 does not prefer MS events regardless the hardware, the inline feature detection will fail in this case as well.

We Need A Better Interface

This call is mainly for W3C, everything we have right now does not scale with more complex, modern, hybrid, devices.
This is also not only about mouses, trackpads, and screens, this is related to virtual keyboards too, the most annoying thing could appear and without notification/control in a webpage screen.
What we could do is to create yet another library able to deal in a totally abstract way with all these cases and in real time.
But how big this overhead would be? Think how many times we attach events to single nodes, rather than into the document only, and think how many checks we need to do in order to normalize properly and cross platform user actions.
The ideal library should be able to switch runtime and handle combination of any sort of pointer ... maybe you scroll a page with fingers, then you draw on canvas with a USB pen ... then you type on the screen, then suddenly you press enter in the keyboard ... and so on ...
Asus Transformer Prime


One Problem At The Time

There is no library out there able to truly behave as expected and switch runtime all these possibilities ... so I might decide to write one but the architecture should be both simple and able to scale.
I am not a huge fun of too abstract architectures for the simple reason that these rarely have good performances but this is a problem that later we deal with, more problems we'll have.
If you have any library I am not aware of that is that smart, please let me know and I'll update the post linking to this library.

Monday, January 16, 2012

On EventEmitter In node.js

Today I had a whole node.js session and I have spent a bit of time looking at current EventEmitter implementation.
I have twitted already that it sucks as it is, and while it's really trivial to implement the same for any browser, I believe many mistakes have been made about the API. Here the list:
  1. on() is a shortcut for addListener but there is no off() as removeListener's shortcut (inconsistent)
  2. add/removeListener is not DOM friendly, we cannot reuse an EventEmitter in the browser without double checking if those methods exist
  3. removeAllListeners() accepts no arguments and cleans up the whole emitter but there is no way to retrieve all listeners via listeners() passing no arguments (again, inconsistent)
  4. there's no possibility to use handleEvent property, as already defined in the EventListener, once again objects are not reusable between client and server
  5. no duplicated checks for both addListener and removeListener, this is totally inconsistent against DOM EventTarget plus I found it kinda hilarious since there is also a max number of listeners allowed defined via setMaxListeners method ... if we add same listener twice, it's fired twice ... a non-sense for those coming from the web. We also need to removeListener twice or more 'cause we have no idea if same listeners has been added by mistake twice so ... it's just screwed up, removing a specific listener may be not enough and there is no easy way to check if the listener has been removed or not
  6. there is no interface to define events plus the single argument is not a DOM Event like, not even an object with data property and at least a type that points to the event name ... once again, not possible to reuse anything on DOM world


Why All Of This Is Bad

node.js is bringing a lot of non JavaScripters and non browser friendly JS developers into its community and this is the good part. What is absolutely bad is that if node.js won't be minimally aligned with the rest of the code in the browsers out there our life as "one language everywhere" will become harder than ever.
I have personally created wru which runs in all browsers and many server side JS environments but what I would like to avoid is to write twice any sort of test because of weirdly implemented APIs.
If it's about shortcutting, as example, on() and off() are more than welcome but why on earth the long version should be addListener rather than addEventListener?
Why events passed as objects since ever in client JS should be passed as string with optional extra data as second argument?
Where are defaults control over events fired across more listeners?
Why on earth handleEvent is not supported and a listener can be only a function which most likely will require a bind to something else?
Why is it possible to erase all listeners without even knowing "who set them where" but it's not possible to retrieve all of them so that at least we could act accordingly with the event name following some rule rather than "just remove them all" ?

I hope somebody will agree with me, considering flakey points I have already described and changing or improving ASAP this EventEmitter API ... it would be sooooooo coooool to be aligned in both worlds for at least the most used pattern/procedure ever in JS world, don't you say? Thanks for your attention.

Tuesday, January 10, 2012

Introducing ObjectHandler

since the discussion about a better Function#bind will probably never end, and since a must have dependency would be the ES6 WeakMap which is in any existent shim leak prone due lack of control via ES5+, I have proposed another way to solve the problem.

ObjectHandler IDL Like


/**
* interface ObjectHandler implements EventListener {
* void handleEvent(in Event evt);
* void remitEvent(in Event evt);
* attribute Object events;
* };
*
* @link http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventListener
*/
var ObjectHandler = {
handleEvent: function handleEvent(e) {
var
events = this.events,
type = e.type
;
if (events.hasOwnProperty(type)) {
events[type].call(this, e);
}
},
// it could be called removeEvent too, as you wish
remitEvent: function cancelEvent(e) {
e.currentTarget.removeEventListener(
e.type, this, e.eventPhase === e.CAPTURING_PHASE
);
}
};

Above object is an Abstract implementation. In JavaScript we can borrow methods so whatever "class" would like to implement above behavior should extend the object or borrow those two methods and specify an events property.

Examples

Let's say we have a UI Class which aim is to react to certain events ... let's call it button:

function UIButton(parentNode) {
// add the node
this.el = parentNode.appendChild(
parentNode.ownerDocument.createElement("button")
);
// add quickly events to the node
for (var key in this.events) {
// add the listener ...
// NOTE: nothing to bind, no duplicated entries either
this.el.addEventListener(key, this, false);
}
}

// extends the class
Object.defineProperties(
UIButton.prototype,
{
// implements ObjectHandler
handleEvent: {value: ObjectHandler.handleEvent},
remitEvent: {value: ObjectHandler.remitEvent},
events: {value: {
// only once thanks to remitEvent
click: function (evt) {
alert("only once");
this.remitEvent(evt);
},
// some decoration on actions
mousedown: function (evt) {
this.el.style.border = "1px solid black";
},
mouseup: function (evt) {
this.el.style.border = null;
},
// recicle mouseup behavior
mouseout: function (evt) {
this.events.mouseup.call(this, evt);
}
}}
}
);

// example on window load
this.onload = function () {
new UIButton(document.body);
};

Got it? Events property is simply an object shared through the prototype with properties name that are exactly the equivalent of DOM events name ... easy!

Pros

  • memory safe, nothing to bind, trap as bound, and stuff like this ... all instances will share same logic and bind is not even needed, aka: problem solved
  • events are defined in a single place, easy to find, maintain, extend
  • events are recycled, as it was as example for mouseout, though the instance
  • most UI frameworks need the instance rather than the DOM node, to behave accordingly
  • ObjectHandler can be used same way for "ObjectTarget", those listeners/able JS implementations, in order to uniform an event driven approach
  • no risk to bind twice, no risk to remove the wrong callback, bound or not, it's the instance that makes the deal, not inline functions so it's less error prone
  • performances in therms of both memory footprint and operation per each instance ... once again, no need to bind all methods to the instance itself ... what is in events is basically bound automatically through a single entry point, defined in ObjectHandler, for every single use case


Cons

... no idea, I cannot find any and I just like this solution over the Function#bind improvements since it's both cross platform, whenever addEventListener is present, but it can be recycled for any other no DOM use case as long as the event will have a currentTarget property that points to the current instance ( I will write an example/proposal soon ... OK? )

As Summary

The main problem with proposal is adoptions and I would like to know UI Framework users feedbacks. Ideally this way to handle events could become a de facto standard dropping the redundant and massive usage of Function#bind for cases where the focus should be for the instance and not for the callback.

Thursday, October 20, 2011

Playing With DOM And ES5

A quick fun post about "how would you solve this real world problem".

The Problem

Given a generic array of strings, create an unordered list of items where each item contains the text of the relative array index without creating a singe leak or reference during the whole procedure.
As plus, make each item in the list clickable so that an alert with current text content occur once clicked.

The assumption is that we are in a standard W3C environment with ES5+ support.

The Reason

I think is one of the most common tasks in Ajax world. We receive an array with some info, we want to display this info to the user and we want to react once the user interact with the list.
If we manage to avoid references we are safer about leaks. If we manage to optimize the procedure, we are also safe about memory consumption over a simplified DOM logic ...
How would you solve this ? Give it a try, then come back for my solution.



The Solution

Here mine:

document.body.appendChild(
/* input */["a","b","c"].map(
function (s, i) {
this.appendChild(
document.createElement("li")
).textContent = s;
return this;
},
document.createElement("ul")
)[0]
).addEventListener(
"click",
function (e) {
if (e.target.nodeName === "LI") {
alert(e.target.textContent);
}
},
false
);

Did you solve it the same way ? :)

Sunday, October 25, 2009

Android DOM "Finger" Events


This is the Android based device I am talking about and the installed software is version 1.6, apparently with multi-touch support for more recent devices so mine is not the case.

Disclaimer

The reason I am writing this post is my attempt to reproduce the Android OS interface via browser, hilariously possible with every browser except the original one: the WebKit in Android.
Why would I do that? The mouse has been around for ages, thanks Xerox, but later these years we've seen so many touch screen based devices without common mouse pattern. Since I think both Android, iPhone, and others, have done an excellent work with the way we use the device UI I thought: Why not! It could be a great time to start analysis and piece of libraries to replicate in a cross browser way some device independent event. Well, as I've already said, and as you'll see next, right now it is not possible!

Mouse Events .. ahem, Finger Events

Every mouse related event we know does not make much sense with a touchscreen, at least the tested one. Think about it: a finger points something (aka: mousedown) move somewhere (aka: mousemove) remove the finger itself (aka: mouseup). This is not what truly happens.

Mouse Events Order

  • mouseout, optionally fired when point if before we pointed another element
  • mouseover, optionally fired if the pointed event is different (or no elements have been pointed before)
  • mousemove, always before mousedown, sometimes fired twice if the internal cursor is in position 0,0 - this event is not performed while we move the finger!
  • mousedown
  • mouseup
  • click, which is so far the only event that makes sense
  • DOMActivated, a common WebKit "bug"


Mousemove Events ... Whatever ...

Fired events are device dependent, my device fires these events just in order but whatever we change in the DOM wont be called/rendered until we release. Mousemove is fired once, maximum twice, but never during movement.
In few words the only "mouse event" that makes sense is click, not performed if we scroll.

Forget The Drag And Drop!

Even if the most interesting part of the Android interface is the drag and drop, via WebKit mobile we cannot even try to emulate it just because the only event fired while we move the pointer is scroll.

Scroll ... Whatever ...

This event could be considered just a notify and nothing else. If we do whatever action while we scroll a page nothing will happen until we release the pointed element. Accordingly we cannot use the element to synchronize somehow the rendered page since again, nothing will happen during the scroll. The phone browser is basically frozen during the entire lifecycle of a gesture, or a pointer (via finger) operation.

(window || document) // it does not matter
.addEventListener(
"scroll",
(function(i){
return function scroll(e){
// it's a waste of time
// to perform whatever
// action here
// let's speed up things
// adding delay
if(i)
clearTimeout(i);
i = setTimeout(function(){
i = 0;
onScroll();

}, /* about */ 250);
};
})(0)
)
;

Above snippet represents a delayed onScroll event which aim is to be performed faster without slowing down the page while we are scrolling.
I know this could sound a nonsense but operation will be performed in any cases but never rendered so why should we let our phone compute stuff will never be showed?
Also a scroll could be not perfect, since the mouse wheel won't be there and a pointer has 10 pixels of tolerance so just wait the end of the action, and only at that point perform something.

Resize

Both window or document, no difference in this case, will always perform a resize event. This is the last reliable event we have so far in a G1 device.

Drop Down Menu Not Worth It

Common JavaScript drop down menu usually activated via mouseover and removed on mouseout won't work as expected in common touchscreens while if we implement a "clever" click manager Desktop users will be a bit disoriented 'cause we failed implementing these menus everywhere just because these are strictly device pointer dependent, so not re-adaptable/usable at all.
Moreover, a finger is not a mouse and it's more complicated to click the right menu/link at first shot. We need to rethink a little bit the UI if our aim is to make a website usable, without having 2 versions to maintain, with both desktop and mobile or touchscreen.

As Summary

We have basically 3 events, and few others, such onload, DOMContentLoaded, focus and key related for inputs, but these a part other events won't necessarily act as expected.
We need to bear in mind that mousemove or mouseover/out are quite meaningless since there is no mouse and no sensor able to monitor the finger activity when close to the screen. iPhone implemented a touch event but still, touch does not allow drag and drop so if we would like to emulate the Mobile OS interface via the Mobile Browser, we simply cannot: what a joke, but that's how it is.

Thursday, October 15, 2009

DOM Node Proxy

This is just a quick post from home sweet home.
A common DOM related problem is to create an association between a node and a generic object. The most dirty, memory leaks prone, and obtrusive way to perform this task is this one:

document.body.obj = {
prop:"value",
otherProp:function(){}
};

Above snippet is a bad practice for different reasons.
  1. obtrusive, it's assuming that no other libraries will use "obj" property name to perform an analogue task
  2. dirty, if we associate a primitive value Internet Explorer will expose it in the node string representation
  3. memory leaks, if the object points something "live", another node, or a HTMLCollection, the generic node will never be collected by the garbage


Alternatives

Specially to avoid last problem, the memory consumption, it's a good practice to store an index, rather than an object. To make things less obtrusive and get rid of conflicts, we usually create a "unique id".

// the array with all objects
var stack = [];

// the unobtrusive property name
var expando = "prefix" + new Date().getTime();

// the obejct to relate
var o = {};

stack.push(o);

// the relation via index (last object)
document.body[expando] = stack.length - 1;

As I have already linked and explained, this technique is still dirty because Internet Explorer will show the unique id via outerHTML or generic node representation.

Strategies

jQuery, and many others, create an association for each manipulated dom node. This could consume RAM without a reason since there could be a lot of nodes with an associated object that will never be used.
Next version of jQuery, right now in alpha stage, understood this point changing the object association logic. I have not read how yet, but I would like to write something I've been used for a while, a sort of proxy object created for DOM nodes and object relations.

DOM Node Proxy

var proxy = (function(){
// another (C) WebReflection silly idea
var expando = "@".concat(+new Date, Math.random()),
stack = []
;
return function proxy(){
return stack[this[expando]] || stack[
this[expando] = new Number(stack.push({}) - 1)
];
};
})();

Above snippet uses almost all strategies I know to avoid obtrusive property, dirty layout, and direct object assignment (index strategy).
To better understand what exactly is above function I have commented each part of it:

var proxy = (function(){

// another (C) WebReflection silly idea

// one function to associate as proxy
// Being assignment a direct one
// standard browsers won't modify
// attributes while being proxy
// an object (not primitive value)
// IE won't expose it in node string
// representation (e.g. outerHTML)
function proxy(){

// a proxy call costs only once:
// the first time it's called
// Other calls will return the object
// This is to avoid objects association
// even if these are not necessary
return stack[this[expando]] || stack[

// the index is the last one in the
// private stack Array. To avoid
// leaks we don't associate directly
// an object but simply an integer.
// If we directly associate
// a primitive value, IE will expose
// is in the dom string representation
// (e.g. outerHTML)
// To avoid this we can just assign
// a Number instance, rather than
// a primitive "number"
this[expando] = new Number(

// push returns the new length
// we need last inserted object
// index to relate the object
stack.push({}) - 1
)
];
};

var
// private unique expando with
// an invalid char as prefix
// in order to make attr name
// easy to recognize in a possible
// IE attributes loop
expando = "@".concat(
+new Date,
Math.random()
),

// list of associated object
stack = []
;

// ready to go!
return proxy;

})();

Is it clear enough? This is a simple usage example (please reado NOTEs):

onload = function(){

// associate a proxy
// NOTE: this is still obtrusive
// the property name should be a unique id
// or it should have library prefix
// otherwise we could have conflicts
document.body.proxy = proxy;
// aka: node[expando] = proxy;

// retrieve the proxy object
var p = document.body.proxy();

// test proxy: true
alert(p === document.body.proxy());

// test clean body string representation
alert(document.documentElement.innerHTML);

// find proxy created property
for(var k in document.body){
if(k.charAt(0) === "@")
alert([k, document.body[k]])
;
}
};


As Summary

This is more a proof of concept but I hope showed code will help us to replicate the behavior. The main missed part is the internal stack management: how can I clean the stack index when I don't need the node anymore? All we need is an extra in-proxy-scope function or a specific associated instance rather than a raw object.
In ew words there are no best strategies for this second problem, it just depends what we need.
From a logical point of view, if we give indirect access to that stack, exposing its length or via functions able to modify it, stack safety could be compromised. What I could suggest is something like:
var proxy = (function(){
// (C) WebReflection - Mit Style License
function proxy(){
return stack[this[expando]] || stack[
this[expando] = new Number(stack.push(new $proxy) - 1)
];
};
function $proxy(){
this._index = stack.length;
};
$proxy.prototype.destroy = function destroy(){
delete stack[this._index];
};
var expando = "@".concat(+new Date, Math.random()),
stack = []
;
return proxy;
})();
where the stack is manipulated indirectly while nothing is publicly exposed.

Monday, August 17, 2009

Konami Code as DOM Event

If You do not know what is the Konami Code you are too young, or not geek at all.
In both cases, it does not matter, nobody is perfect, but what we should know is that some truly affectionate developer though to put this code to enable secret user powers, even if the the software is, as example, extremely recent.

So why not? Why can't we all have our secret mode in the most popular platform as the World Wide Web is?

Konami Code Event



var onkonamicode = function(el, fn){
// The Super Code Event by WebReflection - Mit Style
function onkonamicode(e){
konamicode.push((e || event).keyCode || e.charCode);
if(
konamicode.length === 10 &&
konamicode.join(".") === "38.38.40.40.37.39.37.39.66.65"
){
if(el.removeEventListener)
el.removeEventListener("keydown", onkonamicode, false);
else
el.detachEvent("onkeydown", onkonamicode);
fn(e);
};
clearTimeout(i);
i = setTimeout(clear, 1000);
};
function clear(){
konamicode = [];
};
var konamicode = [], i = 0;
if(el.addEventListener)
el.addEventListener("keydown", onkonamicode, false);
else
el.attachEvent("onkeydown", onkonamicode);
};


How To Activate Konami Code


It is that simple:

onkonamicode(document, function(e){
alert("access guaranteed");
});

Now try to perform the magic sequence and that's it, you have extra power!

Wednesday, July 29, 2009

PyramiDOM - Spectrum DOM Analyzer

Update PyramiDOM source code and a new bookmark available


During a post into jQuery developer list, I wrote a sort of non-sense reply talking about the DOM as a three dimensional space to analyze and " ... bla bla bla ... " (that was not so interesting, just probably "futuristic" ...)

But why not, why can't we escape from ordinary convention to analyze a document creating a sort of DOM spectrum as is for Audio, Video channels, and other medias?

As quick start test, I have created an alpha version of PyramiDOM, a script hopefully short enough to be clicked, saved, or dragged as a bookmark and able to put a spectrum inside whatever page we are surfing.

The generated spectrum will contain every single nodeType 1 present in the document and will show via tooltip info about that node (nodeName, id if present, className if present). Moreover, it highlights somehow that node temporary changing the background (yellow one). The most wicked effect was in jQuery website itself, since it is dark, and since it is linear enough (you scroll and the spectrum is almost there where you scroll).

On the other hand, the most interesting spectrum was in Gmail, where you can spot a proper pyramid of nested divs. Each nodeName will have the same color, but for practical reasons each time this color will be different (random).

If anybody will like this idea I will post and comment the source code ;-)

Wednesday, April 08, 2009

WebReflection PureDom baseline for TaskSpeed

I just had a quick and nice chat with Peter E Higgins and I am proud to announce that my PureDom test has been integrated into TaskSpeed test suite.

Why PureDom

We all know how many benefits libraries give us on daily basis about Web 2.0 supersonic development, but as both libraries author and users, we should pay attention.
Web Developers: sometime we delegate to our cool library some simple task which could be easily implemented manually. If performances are a problem we should use libraries only when and if necessary. There are a lot of best practices for each library and all we need to do is to read these practices to be sure our way to code is of course elegant, but not silly.

// this is silly
$("#items li.selected").each(function(){
$(this).css("color", "red");
$(this).css("background", "blue");
$(this).width($(this).parent().width());
});

// ... while this makes sense
$("#items li.selected").each(function(){

// cache the magic object
var $this = $(this);

// use full lib features, avoid redundant code
$this.css({color:"red", background:"blue"});

$this.width($this.parent().width());
});


Libraries Authors: our main purpose is to define a standard within the library logic and behavior to obtain best "results in zero efforts". Sometimes we could think about light layers between our super cool high level method and pure DOM in order to preserve performances for basic tasks. We all know the most problematic and slow browser, version whatever, is still Internet Explorer, and obviously more we overload the library for this browser, worse the latter one will perform. I hope the PureDom baseline will help all of us to compare results, specially for simple tasks where even the code size is not that different between the chosen lib and the manual DOM execution.


Tricky Monkey, but this is NOT "Python vs ASM"

I know some PureDom task could be interpreted as a "cheat" but honestly, what I have done, was simply follow instructions to create the result. That is my meaning of manual task implementation, and that is why libraries will have hard time against first column. It does not matter if libraries are slower than pure DOM, and it is quite obvious they will be slower, but more these libraries will be close to DOM results more advantages we will have using that library rather than the other one (more competition as well and we like it!)

Have fun with Web development and JavaScript! ;)

Monday, February 09, 2009

JavaScript, Bear in Mind DOM Methods

We all like the jQuery code style where the instance is returned almost everywhere, but we often forget about DOM methods that do the same and ages before whatever library. I rarely spot some "returned instance" trick in daily posts or even famous libraries.
Here a couple of example:

// daily way ...
var div = document.createElement("div");
document.body.appendChild(div);

// easy way
var div = document.body.appendChild(document.createElement("div"));


// boring way
var div = document.createElement("div");
div.appendChild(document.createTextNode("test"));
document.body.appendChild(div);

// funny way
var div = document.body.appendChild(
document.createElement("div")
).appendChild(
document.createTextNode("test")
).parentNode
;

... on and on, there are several methods used on daily basis that do not consider returned values. So, why don't we like to use them?

var el = document.createElement("div"),
div = document.createElement("div");
alert([
el === document.documentElement.appendChild(el), // el in the DOM
el === el.parentNode.removeChild(el), // el removed
div === document.documentElement.appendChild(div), // div in the DOM
div === div.parentNode.replaceChild(el, div), // div removed, el in the DOM
div === el.parentNode.insertBefore(div, el) // both in the DOM, div returned
].join("\n"));

As summary, try to find a leak possibility with this:

with((document.body || document.documentElement)
.appendChild(
document.createElement("div")
)
.appendChild(
document.createTextNode("not")
)) parentNode
.insertBefore(
document.createTextNode("Why "),
parentNode.firstChild
)
.parentNode
.appendChild(
document.createTextNode(" ?")
)
;

Not even a single variable declared, three elements inserted in a specific node of the DOM and in a different order :D