Wednesday, 12 February 2014
My new personal challenge was to get jQuery working correctly in a sandboxed environment this proved to be really tricky. The first problem I encountered was my fake DOM environment wasn’t returning the correct value for nodeType on the document element, this made jQuery assume another state and breaking selectors. I ensured the DOM environment was correctly returning the node type & node name. Next my environment wasn’t returning Array.prototype.push and slice correctly, the functions I created was incorrectly returning false. I changed my object whitelist function to return the prototypes correctly.
I then got a strange error, push.apply is not writable I traced this down in the jQuery code and it seems I was making properties non-writable when rewriting arrays, in addition the length property wasn’t being written since it was referenced as length$ because it was sandboxed. The fix was to shadow the length property by creating a getter/setter on the rewritten object literals so calls to length$ where also update length of the object literal. Basically sizzle calls a push on a object and because it didn’t have a length property it wouldn’t work but now it’s shadowed it works fine.
You can see a small demo of sandboxed jQuery here.