Prototype is a complete crock as well. Always has been. [...]
And it is full of browser sniffing, which the developers
must constantly twiddle with to make it "work" in a handful of
browsers in their default configurations.
Apparently, that's about to change:
http://ajaxian.com/archives/common-feature-tests
I must have missed Sixty Minutes.
Here is the script by "Kangax" that is featured in the article. It
has nothing to do with Prototype. In fact, at least part of it is
lifted directly from my library.
(function(){
var t = new Date();
function isHostMethod(o, m) {
var t = typeof(o[m]);
return t == 'function' || !!(t == 'object' && o[m]) || t ==
'unknown';
};
Now, where have I seen that before? Oh yeah, I wrote and published it
here a year ago (and it is now part of my library.)
var features = { };
var bugs = { };
features.IS_TRANSFORMATION_SUPPORTED =
(features.__IS_TRANSFORMATION_SUPPORTED = function(){
var el = document.createElement('div');
Oops. Where's the test for document.createElement?
var isSupported = ('WebkitTransform' in el.style) ||
('MozTransform' in el.style);
How very interesting. Using the - in - operator to smooth over
differences in older browsers is obviously not a good idea. He forgot
to copy isRealObjectProperty.
el = null;
return isSupported;
})();
features.IS_TAGNAME_UPPERCASED = (features.__IS_TAGNAME_UPPERCASED =
function(){
return /[A-Z]/.test(document.documentElement.tagName);
})();
What a perfectly ridiculous test. And it assumes
document.documentElement exists.
bugs.QUERY_SELECTOR_IGNORES_CAPITALIZED_VALUES =
(bugs.__QUERY_SELECTOR_IGNORES_CAPITALIZED_VALUES = function(){
var el = document.createElement('div'),
el2 = document.createElement('span'),
isBuggy = false;
el2.className = 'Test';
el.appendChild(el2);
isBuggy = ('querySelector' in el) ? (el.querySelector('.Test') !==
null) : null;
el = el2 = null;
return isBuggy;
})();
Same issues. And what possible use is this?
features.ARRAY_PROTOTYPE_SLICE_CAN_CONVERT_NODELIST_TO_ARRAY =
(features.__ARRAY_PROTOTYPE_SLICE_CAN_CONVERT_NODELIST_TO_ARRAY =
function(){
try {
return (Array.prototype.slice.call(document.forms, 0) instanceof
Array);
Kore bad assumptions.
} catch(e) { };
return false;
})();
A try-catch clause in a gateway? That's rich.
features.EVENT_HANDLERS_ARE_FIFO =
(features.__EVENT_HANDLERS_ARE_FIFO = function(){
function addEvent(element, name, handler) {
if (element.addEventListener) {
Why did he bother to steal isHostMethod?
element.addEventListener(name, handler, false);
}
else if (element.attachEvent) {
element.attachEvent("on" + name, handler);
}
}
function removeEvent(element, name, handler) {
if (element.removeEventListener) {
element.removeEventListener(name, handler, false);
}
else if (element.detachEvent) {
element.detachEvent("on" + name, handler);
}
}
function handler1() {
a.push(1);
}
function handler2() {
a.push(2);
}
var f = document.createElement('form'), a = [];
f.action = '';
addEvent(f, 'reset', handler1);
addEvent(f, 'reset', handler2);
f.reset();
removeEvent(f, 'reset', handler1);
removeEvent(f, 'reset', handler2);
f = null;
return (a[0] === 1);
})();
Another useless waste of time.
features.WINDOW_EVAL_EVALUATES_IN_GLOBAL_SCOPE =
(features.__WINDOW_EVAL_EVALUATES_IN_GLOBAL_SCOPE = function(){
var fnId = '__eval' + Number(new Date()),
passed = false;
window.eval('function ' + fnId + '(){}');
passed = (fnId in window);
if (passed) {
delete window[fnId];
}
return passed;
})();
More worthless than the last.
(function(){
features.IS_EVENT_METAKEY_PRESENT = false;
features.IS_DOM2_EVENT_INTERFACE_IMPLEMENTED = false;
features.IS_EVENT_SRCELEMENT_PRESENT = false;
var i = document.createElement('input'),
root = document.documentElement;
if (i) {
i.type = 'checkbox';
i.style.display = 'none';
i.onclick = function(e) {
e = e || window.event;
features.IS_EVENT_METAKEY_PRESENT = ('metaKey' in e);
features.IS_DOM2_EVENT_INTERFACE_IMPLEMENTED =
(('preventDefault' in e) && ('stopPropagation' in e));
features.IS_EVENT_SRCELEMENT_PRESENT = ('srcElement' in e);
};
root.appendChild(i);
i.click();
OMFG. People with no experience or ability fit right in with the
Prototype crowd. As mentioned, he is now part of the "core." It's
over. No amount of feature testing (even if competent) can save it.
[snip additional useless nonsense]
Here is a typical response from a library jockey (found at the bottom
of the page.)
"It seems to me that the popularity of the libraries themselves have
already guaranteed that browser sniffing will work.
..
Take Chrome. It worked pretty well right out of the gate because they
tested it against a myriad of web sites. Who is going to release a
browser that crashes on jQuery sites, for example?"
Chrome is misidentified by jQuery as Safari (that will catch up to
them.) And browser developers do not bend to browser sniffers (they
break them.)