Really cool technology with video.
Author: Steve
Average direction in SQL
Given a column of polar directions in degrees, this is a single SQL expression to compute their average, for use in a GROUP BY query. Some functions may be MySQL-specific.
IF(DEGREES(ATAN2(
-AVG(SIN(RADIANS(direction_deg)))
,-AVG(COS(RADIANS(direction_deg))))
) < 180
,DEGREES(ATAN2(
-AVG(SIN(RADIANS(direction_deg)))
,-AVG(COS(RADIANS(direction_deg))))
) + 180
,DEGREES(ATAN2(
-AVG(SIN(RADIANS(direction_deg)))
,-AVG(COS(RADIANS(direction_deg))))
) - 180
)
Thought someone might like to run across this.
Actionscript pains
I have an Actionscript 3 book lined up to tackle at some point, but generally my interaction with Actionscript is having to modify someone else’s SWF, most commonly old code from the 1.0 days. When I open one of these source files it sometimes takes time to even figure out where the code is. When I do find it, it’s not obvious when this code executes and in what scope. The object model of a Flash movie may not be much more complex than the browser DOM, but they’re quite different. I think part of my problem is that the structure of a movie (and the IDE navigation) is still foreign to me. The programmer in me wants to dig in with a spec in hand, and that often works with the projects I have to work on, but it would probably benefit me greatly to spend some time doing the boring beginner Flash tutorials.
Thoughts on a Javascript “validator”
(X)HTML and CSS have their own validators, but we need one for Javascript as well. JSLint could be part of it, but what I’m imagining would flag the use of “native” objects/interfaces not defined by W3C or ECMA standards. E.g., document.layers
or window.ActiveXObject
.
The hard part in doing this is finding a full Javascript interpreter with W3C DOM interfaces, but without the proprietary features that browsers have to support to remain usable on the web. A couple ways come to mind:
1. Rhino
John Resig has just implemented “window” for the Javascript interpreter Rhino, which, supposedly, is already based strictly on the ECMAscript standards. The short term goal of his script was to give Rhino enough of a browser interface to pass jQuery’s test suite, but the code could be branched to implement all current W3C DOM recommendations (and none of the proprietary interfaces). A Java app would set up Rhino, run John’s script, then run your script and simply report any errors.
2. A stricter browser
Most modern browsers are pretty malleable as far as letting user code clobber native functions/objects; in fact it’s a real problem. But this is convenient if you want to, say, overwrite all the proprietary features with your own code! With a whitelist in hand, you could use for-in loops to sniff out non-standard functions/properties and either delete or overwrite them with functions of your choice.
The advantage of the browser solution is that you could still provide the non-standard features (so the script would continue to run) while logging them. Using closures you could, in theory, “wrap” each non-standard function so that each of its calls would also call your logging function before returning the expected value. A crude example:
// may fail spectacularly
var _parseInt = window.parseInt;
window.parseInt = function (str) {
alert('parseInt was called.');
return _parseInt(str);
};
parseInt('2');
In practice, you’ll be at the mercy of the browser to allow native functions to be stored in variables like this. Sometimes it works, sometimes not. As for properties, you may be able to similarly log their usage with Javascript’s relatively new getters and setters.
So any idea where to get such a whitelist?
Hacking a 3rd party script for bookmarklet fun
A few weeks ago I created a simple bookmarklet that loads del.icio.us’s PlayTagger script into the current page. This post covers how some problems with this script were worked through.
Too late
The first challenge was that PlayTagger was designed to initialize itself (let’s call this method “init
“) on window.onload: If a user fired the bookmarklet after window.onload (99% of the time), playtagger.js would load but init
would’ve missed its chance to be called. This means I had to call init
manually, but since script elements load asynchronously, I had to wait until init
actually existed in the global scope to call it. This was fairly easily accomplished by attaching my code to the new script element’s “load” event (and using some proprietary “readyState” junk for IE).
Too early
If the page takes a long time to load, it’s possible the user will fire the bookmarklet before window.onload. One of two things will occur:
If it’s fired before the DOM is even “ready”, the bookmarklet throws an error when it tries to append the script element. I could use one of the standard “DOMready” routines to run the bookmarklet code a little later, but this case is rare enough to be not worth the effort to support; by the time the user can see there are mp3s on the page, the DOM is usually ready.
Assuming the DOM is ready, playtagger.js gets loaded via a new script element, the bookmarklet fires init
, but then, thanks to playtagger’s built-in event attachment, init
is called a second time on window.onload, producing a second “play” button per mp3 link. Harmless, but not good enough.
Preventing the 2nd init call
It would be nice if you could sniff whether or not window.onload has fired, but this doesn’t seem to be possible. Maybe via IE junk. Any ideas for a standards based way to tell?
My only hope seemed to be to somehow disable init
after manually calling it. The first try was to just redefine init
to a null function after calling it:
init();
init = function () {};
I figured out that redefining init
would not help here due to the way it’s attached to window.onload:
// simplified
var addLoadEvent = function(f) {
var old = window.onload;
window.onload = function() {
if (old) { old(); }
f();
};
};
addLoadEvent(init);
What’s important to notice here is that init
is passed to addLoadEvent as f
and window.onload is redefined as a new function, capturing f
in the closure. So now f
holds init
‘s original code (because functions are first-class in Javascript), and f
, not the global init
, is what is really executed at window.onload. As f
is private (hidden by the closure), I can’t overwrite it.
Disabling init from the inside by “breaking” Javascript
The second thing I tried was to break init
‘s code from the inside. The first thing init
does is loop over the NodeList returned by document.getElementsByTagName('a')
, so if I could get that function to return an empty array, that would kill init
‘s functionality. Because Javascript is brilliantly flexible I can do just that:
// cache for safe keeping
document.gebtn_ = document.getElementsByTagName;
// "break" the native function
document.getElementsByTagName = function(tag) {
if (tag != 'a') return document.gebtn_(a);
// called with 'a' (probably from init)
// "repair" this function for future use
document.getElementsByTagName = document.gebtn_;
// return init-busting empty array
return [];
};
Simplest solution
While the code above works pretty well, I thought of a simpler, more elegant solution: just rewrite window.onload to what it was before playtagger.js was loaded.
And with that here is the final unpacked bookmarklet code:
javascript:(function () {
if (window.Delicious && (Delicious.Mp3 || window.Mp3))
return;
var d = document
,s = d.createElement('script')
,wo = window.onload
,go = function () {
Delicious.Mp3.go();
window.onload = wo || null;
}
;
s.src = 'http://images.del.icio.us/static/js/playtagger.js';
if (null === s.onreadystatechange)
s.onreadystatechange = function () {
if (s.readyState == 'complete')
go();
};
else
s.onload = go;
d.body.appendChild(s);
})();
Kill these DOM0 shortcuts
A problem a decade in the making
You can refer to a form’s elements in your code by using the element’s name (from the NAME attribute)
— an ancient Javascript spec.
This means myForm.myElement
is a shortcut for myForm.elements['myElement']
. I’m sure this was seen as handy and harmless at the time, but the problem is that references to form elements, simply by using valid name attributes, can overwrite important DOM properties and methods on the form element. Make a text input with name=”submit” and you overwrite the form’s native submit method; no more form submission!
Workaround
Effectively, you have to avoid using name
s that already exist as properties or methods of the form DOM element, from modern specs back to the stone age. To get an idea of how many there are, I created an empty form element with no attributes, fired up the Javascript shell bookmarklet and used its handy props
function:
Methods: addEventListener, addRepetitionBlock, addRepetitionBlockByIndex, appendChild, attachEvent, blur, checkValidity, cloneNode, contains, detachEvent, dispatchEvent, dispatchFormChange, dispatchFormInput, focus, getAttribute, getAttributeNS, getAttributeNode, getAttributeNodeNS, getElementsByTagName, getElementsByTagNameNS, getFeature, hasAttribute, hasAttributeNS, hasAttributes, hasChildNodes, insertAdjacentElement, insertAdjacentHTML, insertAdjacentText, insertBefore, isDefaultNamespace, isSupported, item, lookupNamespaceURI, lookupPrefix, moveRepetitionBlock, namedItem, normalize, removeAttribute, removeAttributeNS, removeAttributeNode, removeChild, removeEventListener, removeNode, removeRepetitionBlock, replaceChild, reset, resetFromData, scrollIntoView, selectNodes, selectSingleNode, setAttribute, setAttributeNS, setAttributeNode, setAttributeNodeNS, submit, toString
Fields: accept, acceptCharset, action, all, attributes, childNodes, children, className, clientHeight, clientLeft, clientTop, clientWidth, contentEditable, currentStyle, data, dir, document, elements, encoding, enctype, firstChild, id, innerHTML, innerText, isContentEditable, lang, lastChild, length, localName, method, name, namespaceURI, nextSibling, nodeName, nodeType, nodeValue, offsetHeight, offsetLeft, offsetParent, offsetTop, offsetWidth, onblur, onclick, ondblclick, onfocus, onkeydown, onkeypress, onkeyup, onload, onmousedown, onmousemove, onmouseout, onmouseover, onmouseup, onunload, outerHTML, outerText, ownerDocument, parentElement, parentNode, prefix, previousSibling, repeatMax, repeatMin, repeatStart, repetitionBlocks, repetitionIndex, repetitionTemplate, repetitionType, replace, scrollHeight, scrollLeft, scrollTop, scrollWidth, sourceIndex, style, tagName, target, templateElements, text, textContent, title, unselectable
These are just in Opera; to be really safe you need to add in any extras from all the other modern browsers.
But there’s more
This problem also exists on the document
object: Give your form name="getElementById"
, then try using document.getElementById()
. Even worse, IE/win registers all element id
s onto the global (window
) object.
The real solution
The W3C/WhatWG needs to step up and formally denounce these shortcuts in the HTML DOM specs, and, IMO, also generate warnings in the HTML validator where input names match those in W3C DOM specs, at the very least. Since there’s a sea of legacy code out there using these shortcuts, browser makers desperately need a defined way to handle these collisions.
SketchUp action
Over the weekend I finally gave SketchUp a try and got pretty wrapped up in it. I was up till 3 Tuesday night putting the finishing touches on my first contribution to 3D Warehouse. Of course it’s a skate spot.
A great feature is that you can recreate a scene in 3D using a 2D image, but the problem is that your error goes up quickly as you try to guess angles and distances outside of the origin axis lines. You end up with a model that looks OK at the angle of the photo, but is more noticeably messed up when you shift the view. Most photos of the Hubba ledge aren’t at good angles to accurately map the perspective in SketchUp, so I had to tediously piece together the geometry based on several photos and a some guesswork.
So, when can I skate this?
Favorites of the php|tek 2007 slides
I didn’t go, of course (next year hopefully), but I can live vicariously through slides!
Ilia Alshanetsky had my favorites:
- Securing PHP Applications (.pdf) – Comprehensive with good examples. If you read Chris Shiflett, there won’t be a lot new covered, but still a good read.
- PHP & Performance (.pdf) – Again, covering all the bases with some real eye-openers. The kind of stuff Python devs find contemptful allows you to squeeze massive performance out of PHP. I like both schools of thought: elegance when possible, brute optimization when it heats up.
- Security Pitfalls (.pdf)
Also Jeff Moore’s presentation on the Dependency Injection (.pdf) pattern.
Derick Rethans (of eZ Components) has quite a few great presentations archived (though several are duplicates), including the best overview I’ve seen of PHP 5.2’s new native Date and DateTimeZone classes (.pdf) (and why date handling can be such a mess without them).
Running PHP on .NET???
Phalanger is a .NET compiler for PHP5. Yes, PHP code compiled into CLR running on .NET (or Mono), with access to .NET classes as PHP objects (!), and apparently running almost twice as fast as on the PHP CGI. And they’ve implemented enough native PHP functions identically enough to run fairly extensive apps (MediaWiki, WordPress, phpBB3) out-of-the-box. There are a couple PDFs in the docs that describe in intimate detail the intracacies of wrapping .NET objects so they behave as PHP objects do and vice-versa; the team knows the PHP5 object model inside and out and they’ve extended the syntax to allow importing namespaced .NET code.
The benchmarks look impressive (almost double the performance on phpBB), but certainly using a opcode cache or running on Apache or lighttpd would level the performance a bit. Then again, why would you use Phalanger just to run all native PHP apps? I guess if you’ve done a lot of PHP development and been itching to try out .NET, this is something to look into.
Google TechTalk: OLPC
Another brilliant Google TechTalk, this one on the massive tech challenges of the One Laptop Per Child project.
The revolutionary hardware design was hard enough, but the software goals are incredibly ambitious, particularly in the areas of security and long-term user data persistence within a very small space. Right now the permanent data store is 1Gb of flash RAM, and that stores the OS and apps as well. Every user file will have built-in versioning and they still have to figure out how to intelligently remove old documents and versions that are no longer needed. They want simple, near automated, and encrypted backups to school servers. Security with no passwords, no signed code, the OS runs with the assuption that any running app could be “evil”…as massive deployments of uniform systems these machines could become targets for worms and for use in DDoS attacks.
Another great talk I saw recently was a dissection of the XBOX’s security system and its compromise. The presenter does a particularly great job of entertainingly diagramming and describing the machine-level ideas behind the attacks without assuming much knowledge in the area.