Prototype 1.6--Somebody Stop These People

Discussion in 'Javascript' started by David Mark, Dec 24, 2009.

  1. David Mark

    David Mark Guest

    /* Prototype JavaScript framework, version 1.6.1
    * (c) 2005-2009 Sam Stephenson
    *
    * Prototype is freely distributable under the terms of an MIT-style
    license.
    * For details, see the Prototype web site: http://www.prototypejs.org/
    *

    *--------------------------------------------------------------------------
    */

    var Prototype = {
    Version: '1.6.1',

    Browser: (function(){
    var ua = navigator.userAgent;
    var isOpera = Object.prototype.toString.call(window.opera) ==
    '[object Opera]';


    Not a bad test for Opera, but who needs to test for Opera in 2010? :)


    return {
    IE: !!window.attachEvent && !isOpera,


    Sure, anything not Opera with attachEvent is bound to be IE. :)


    Opera: isOpera,
    WebKit: ua.indexOf('AppleWebKit/') > -1,
    Gecko: ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML')
    === -1,
    MobileSafari: /Apple.*Mobile.*Safari/.test(ua)


    They can't even do browser sniffing "right". ;)


    }
    })(),

    BrowserFeatures: {
    XPath: !!document.evaluate,
    SelectorsAPI: !!document.querySelector,
    ElementExtensions: (function() {
    var constructor = window.Element || window.HTMLElement;
    return !!(constructor && constructor.prototype);
    })(),


    Haven't these guys figured out that "extending" Elements is a bad
    idea? They must develop in a vacuum.


    SpecificElementExtensions: (function() {
    if (typeof window.HTMLDivElement !== 'undefined')
    return true;

    var div = document.createElement('div');
    var form = document.createElement('form');
    var isSupported = false;

    if (div['__proto__'] && (div['__proto__'] !== form
    ['__proto__'])) {
    isSupported = true;
    }

    div = form = null;

    return isSupported;
    })()
    },


    Sheesh.


    ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
    JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,

    emptyFunction: function() { },
    K: function(x) { return x }
    };

    if (Prototype.Browser.MobileSafari)
    Prototype.BrowserFeatures.SpecificElementExtensions = false;


    Browser sniffing to "enable" bizarre hacks is about as poor as
    strategies come (see also MooTools).


    var Abstract = { };


    var Try = {
    these: function() {
    var returnValue;

    for (var i = 0, length = arguments.length; i < length; i++) {
    var lambda = arguments;
    try {
    returnValue = lambda();
    break;
    } catch (e) { }
    }

    return returnValue;
    }
    };

    /* Based on Alex Arnell's inheritance implementation. */


    Do not accept inheritance implementations from this man. ;)


    var Class = (function() {
    function subclass() {};
    function create() {
    var parent = null, properties = $A(arguments);
    if (Object.isFunction(properties[0]))


    isFunction?!


    parent = properties.shift();

    function klass() {
    this.initialize.apply(this, arguments);
    }


    Bullshit.


    Object.extend(klass, Class.Methods);
    klass.superclass = parent;
    klass.subclasses = [];

    if (parent) {
    subclass.prototype = parent.prototype;
    klass.prototype = new subclass;
    parent.subclasses.push(klass);
    }

    for (var i = 0; i < properties.length; i++)
    klass.addMethods(properties);

    if (!klass.prototype.initialize)
    klass.prototype.initialize = Prototype.emptyFunction;

    klass.prototype.constructor = klass;
    return klass;
    }

    function addMethods(source) {
    var ancestor = this.superclass && this.superclass.prototype;
    var properties = Object.keys(source);

    if (!Object.keys({ toString: true }).length) {
    if (source.toString != Object.prototype.toString)
    properties.push("toString");
    if (source.valueOf != Object.prototype.valueOf)
    properties.push("valueOf");


    That's hardly a complete list.


    }

    for (var i = 0, length = properties.length; i < length; i++) {
    var property = properties, value = source[property];
    if (ancestor && Object.isFunction(value) &&
    value.argumentNames().first() == "$super") {
    var method = value;
    value = (function(m) {
    return function() { return ancestor[m].apply(this,
    arguments); };
    })(property).wrap(method);

    value.valueOf = method.valueOf.bind(method);
    value.toString = method.toString.bind(method);
    }
    this.prototype[property] = value;
    }

    return this;
    }

    return {
    create: create,
    Methods: {
    addMethods: addMethods
    }
    };
    })();
    (function() {

    var _toString = Object.prototype.toString;


    Why the funny underscore?


    function extend(destination, source) {
    for (var property in source)
    destination[property] = source[property];
    return destination;
    }

    function inspect(object) {
    try {
    if (isUndefined(object)) return 'undefined';


    isUndefined?!


    if (object === null) return 'null';
    return object.inspect ? object.inspect() : String(object);
    } catch (e) {
    if (e instanceof RangeError) return '...';


    Oh brother. This is their own code they are calling. :)


    throw e;
    }
    }

    [...]

    function keys(object) {
    var results = [];
    for (var property in object)

    No filter after all of these years?

    results.push(property);
    return results;
    }

    function values(object) {
    var results = [];
    for (var property in object)
    results.push(object[property]);
    return results;
    }

    function clone(object) {
    return extend({ }, object);
    }

    function isElement(object) {
    return !!(object && object.nodeType == 1);
    }

    function isArray(object) {
    return _toString.call(object) == "[object Array]";
    }


    Of course. :(


    function isHash(object) {
    return object instanceof Hash;
    }


    Again.


    function isFunction(object) {
    return typeof object === "function";
    }

    Waste.


    function isString(object) {
    return _toString.call(object) == "[object String]";
    }


    Stupid.


    function isNumber(object) {
    return _toString.call(object) == "[object Number]";
    }


    Ditto.


    function isUndefined(object) {
    return typeof object === "undefined";
    }


    Saw that coming. ;)


    [...]


    function bindAsEventListener(context) {
    var __method = this, args = slice.call(arguments, 1);
    return function(event) {
    var a = update([event || window.event], args);

    That lets frames out. :(

    return __method.apply(context, a);
    }
    }


    [...]

    function evalScripts() {
    return this.extractScripts().map(function(script) { return eval
    (script) });
    }


    Don't use eval for this. How many times has this come up over the
    years?


    function escapeHTML() {
    return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/
    g,'&gt;');
    }

    function unescapeHTML() {
    return this.stripTags().replace(/&lt;/g,'<').replace(/&gt;/
    g,'>').replace(/&amp;/g,'&');
    }


    It's about time they fixed that one. :)


    function toQueryParams(separator) {
    var match = this.strip().match(/([^?#]*)(#.*)?$/);
    if (!match) return { };

    return match[1].split(separator || '&').inject({ }, function(hash,
    pair) {
    if ((pair = pair.split('='))[0]) {
    var key = decodeURIComponent(pair.shift());
    var value = pair.length > 1 ? pair.join('=') : pair[0];
    if (value != undefined) value = decodeURIComponent(value);

    if (key in hash) {
    if (!Object.isArray(hash[key])) hash[key] = [hash[key]];

    There it is (isArray). All incompetent JS designers think alike (plow
    right into language-imposed roadblocks and let the "edge cases" fall
    where they may).

    hash[key].push(value);
    }
    else hash[key] = value;
    }
    return hash;
    });
    }

    [...]

    function evalJSON(sanitize) {
    var json = this.unfilterJSON();
    try {
    if (!sanitize || json.isJSON()) return eval('(' + json + ')');

    Hello? Function constructor? It's like they deliberately try to do
    everything wrong.


    } catch (e) { }
    throw new SyntaxError('Badly formed JSON string: ' + this.inspect
    ());


    Clueless use of try-catch. Who knows what threw the exception?


    }

    [...]

    function concat() {
    var array = slice.call(this, 0), item;
    for (var i = 0, length = arguments.length; i < length; i++) {
    item = arguments;
    if (Object.isArray(item) && !('callee' in item)) {


    Somebody stop these guys. :(


    for (var j = 0, arrayLength = item.length; j < arrayLength; j+
    +)
    array.push(item[j]);
    } else {
    array.push(item);
    }
    }
    return array;
    }

    Object.extend(arrayProto, Enumerable);


    Still extending native objects?


    if (!arrayProto._reverse)
    arrayProto._reverse = arrayProto.reverse;


    That's helpful. :)


    [...]


    function abs() {
    return Math.abs(this);
    }

    function round() {
    return Math.round(this);
    }

    function ceil() {
    return Math.ceil(this);
    }

    function floor() {
    return Math.floor(this);
    }


    Wastes.


    [...]


    var Ajax = {
    getTransport: function() {
    return Try.these(
    function() {return new XMLHttpRequest()},
    function() {return new ActiveXObject('Msxml2.XMLHTTP')},
    function() {return new ActiveXObject('Microsoft.XMLHTTP')}
    ) || false;
    },

    activeRequestCount: 0
    };


    Well, at least they _tried_. :)


    [...]


    function $(element) {


    Here we go.


    if (arguments.length > 1) {
    for (var i = 0, elements = [], length = arguments.length; i <
    length; i++)
    elements.push($(arguments));
    return elements;
    }
    if (Object.isString(element))
    element = document.getElementById(element);
    return Element.extend(element);


    So it is one "$" wrapper for both single and multiple elements. That
    sounds familiar. :)


    }

    if (Prototype.BrowserFeatures.XPath) {
    document._getElementsByXPath = function(expression, parentElement) {
    var results = [];
    var query = document.evaluate(expression, $(parentElement) ||
    document,
    null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
    for (var i = 0, length = query.snapshotLength; i < length; i++)
    results.push(Element.extend(query.snapshotItem(i)));
    return results;
    };
    }

    How do I know their "slow lane" is going to be wildly incompatible
    with XPath? Just a hunch.


    /
    *--------------------------------------------------------------------------
    */

    if (!window.Node) var Node = { };


    OMFG. How about:-

    var Node;
    if (!Node) { Node = {}; }

    I suppose that would make too much sense and leaves out the cool
    window reference. ;)


    if (!Node.ELEMENT_NODE) {
    Object.extend(Node, {
    ELEMENT_NODE: 1,
    ATTRIBUTE_NODE: 2,
    TEXT_NODE: 3,
    CDATA_SECTION_NODE: 4,
    ENTITY_REFERENCE_NODE: 5,
    ENTITY_NODE: 6,
    PROCESSING_INSTRUCTION_NODE: 7,
    COMMENT_NODE: 8,
    DOCUMENT_NODE: 9,
    DOCUMENT_TYPE_NODE: 10,
    DOCUMENT_FRAGMENT_NODE: 11,
    NOTATION_NODE: 12
    });
    }


    (function(global) {

    var SETATTRIBUTE_IGNORES_NAME = (function(){

    Poorly chosen name (betrays a misunderstanding of the problem).

    var elForm = document.createElement("form");
    var elInput = document.createElement("input");
    var root = document.documentElement;
    elInput.setAttribute("name", "test");


    No need to use that method here. It's virtually never needed in an
    HTML DOM (the only type of DOM available to this script).


    elForm.appendChild(elInput);
    root.appendChild(elForm);


    For Christ's sake. There must be a book on this stuff somewhere (e.g.
    Browser Scripting for the Terminally Clueless). :)

    Anyway, wait until the DOM is _ready_ and append the form to the
    _body_.


    var isBuggy = elForm.elements
    ? (typeof elForm.elements.test == "undefined")
    : null;


    That's an odd test. When would elForm.elements be falsy?


    root.removeChild(elForm);
    elForm = elInput = null;
    return isBuggy;
    })();


    And they (and Resig) got that pattern from me. Why do they have to
    foul it up so badly?

    var element = global.Element;
    global.Element = function(tagName, attributes) {
    attributes = attributes || { };
    tagName = tagName.toLowerCase();
    var cache = Element.cache;
    if (SETATTRIBUTE_IGNORES_NAME && attributes.name) {
    tagName = '<' + tagName + ' name="' + attributes.name + '">';


    I knew it. :) There's no reason to do that. It's another classic
    incantation passed down from one clueless developer to the next.


    delete attributes.name;
    return Element.writeAttribute(document.createElement(tagName),
    attributes);


    I can guess what _that_ method is going to look like (and everything
    is hinges on it). :)


    }
    if (!cache[tagName]) cache[tagName] = Element.extend
    (document.createElement(tagName));
    return Element.writeAttribute(cache[tagName].cloneNode(false),
    attributes);
    };
    Object.extend(global.Element, element || { });
    if (element) global.Element.prototype = element.prototype;
    })(this);

    Element.cache = { };
    Element.idCounter = 1;

    Element.Methods = {
    visible: function(element) {
    return $(element).style.display != 'none';
    },


    That's worthless.


    [...]


    update: (function(){

    var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){
    var el = document.createElement("select"),
    isBuggy = true;
    el.innerHTML = "<option value=\"test\">test</option>";
    if (el.options && el.options[0]) {
    isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION";
    }
    el = null;
    return isBuggy;
    })();


    That's lifted (and mangled) straight from My Library.


    [...]

    var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () {
    var s = document.createElement("script"),
    isBuggy = false;
    try {
    s.appendChild(document.createTextNode(""));
    isBuggy = !s.firstChild ||
    s.firstChild && s.firstChild.nodeType !== 3;
    } catch (e) {
    isBuggy = true;
    }
    s = null;
    return isBuggy;
    })();


    That looks like one of the three feature tests for script injection (.
    333 copying average).


    [...]


    But I guess they didn't read the attribute-related code.


    readAttribute: function(element, name) {
    element = $(element);


    Why?


    if (Prototype.Browser.IE) {


    Here we go. :)


    var t = Element._attributeTranslations.read;


    More on those later...


    if (t.values[name]) return t.values[name](element, name);
    if (t.names[name]) name = t.names[name];
    if (name.include(':')) {

    Whatever.

    return (!element.attributes || !element.attributes[name]) ?
    null :
    element.attributes[name].value;
    }
    }
    return element.getAttribute(name);
    },

    writeAttribute: function(element, name, value) {
    element = $(element);
    var attributes = { }, t = Element._attributeTranslations.write;

    if (typeof name == 'object') attributes = name;
    else attributes[name] = Object.isUndefined(value) ? true : value;


    What?! No wonder this stuff has an inch or dust on it. :)


    for (var attr in attributes) {
    name = t.names[attr] || attr;
    value = attributes[attr];
    if (t.values[attr]) name = t.values[attr](element, value);
    if (value === false || value === null)
    element.removeAttribute(name);

    LOL. This method works completely differently in IE8 than in previous
    versions. So much for browser sniffing. :)


    else if (value === true)
    element.setAttribute(name, name);
    else element.setAttribute(name, value);

    As does this one. This is a catastrophe for those who must support
    IE. And this is at the _basement_ level. ;)


    }
    return element;
    },

    getHeight: function(element) {
    return Element.getDimensions(element).height;
    },

    getWidth: function(element) {
    return Element.getDimensions(element).width;
    },

    classNames: function(element) {
    return new Element.ClassNames(element);
    },

    hasClassName: function(element, className) {
    if (!(element = $(element))) return;

    :)

    var elementClassName = element.className;
    return (elementClassName.length > 0 && (elementClassName ==
    className ||
    new RegExp("(^|\\s)" + className + "(\\s|$)").test
    (elementClassName)));
    },

    addClassName: function(element, className) {
    if (!(element = $(element))) return;

    :)

    if (!Element.hasClassName(element, className))
    element.className += (element.className ? ' ' : '') + className;
    return element;
    },

    removeClassName: function(element, className) {
    if (!(element = $(element))) return;

    :)

    element.className = element.className.replace(
    new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip();
    return element;
    },

    [...]

    scrollTo: function(element) {
    element = $(element);

    Any wonder this stuff moves at a snail's pace (the code, not the
    similarly challenged development effort).

    var pos = Element.cumulativeOffset(element);
    window.scrollTo(pos[0], pos[1]);

    No feature testing at all. :(

    return element;
    },

    getStyle: function(element, style) {
    element = $(element);
    style = style == 'float' ? 'cssFloat' : style.camelize();


    Are we in a browser sniffing fork? I've lost track.


    var value = element.style[style];
    if (!value || value == 'auto') {
    var css = document.defaultView.getComputedStyle(element, null);
    value = css ? css[style] : null;
    }
    if (style == 'opacity') return value ? parseFloat(value) : 1.0;

    Not 1, but 1.0. :) And why are they converting this to a number here
    anyway? That's a very goofy design. And what about the older
    proprietary opacity styles?

    return value == 'auto' ? null : value;
    },

    getOpacity: function(element) {
    return $(element).getStyle('opacity');
    },

    setStyle: function(element, styles) {
    element = $(element);
    var elementStyle = element.style, match;
    if (Object.isString(styles)) {
    element.style.cssText += ';' + styles;
    return styles.include('opacity') ?
    element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)
    [1]) : element;


    WTF?! Nothing else comes to mind.


    }
    for (var property in styles)
    if (property == 'opacity') element.setOpacity(styles[property]);
    else
    elementStyle[(property == 'float' || property == 'cssFloat') ?
    (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' :
    'styleFloat') :
    property] = styles[property];


    But that doesn't match the float handling above. (?)


    return element;
    },

    setOpacity: function(element, value) {
    element = $(element);


    Why?!


    element.style.opacity = (value == 1 || value === '') ? '' :
    (value < 0.00001) ? 0 : value;
    return element;

    Oh, how "cool" is that?


    },

    getDimensions: function(element) {
    element = $(element);
    var display = Element.getStyle(element, 'display');
    if (display != 'none' && display != null) // Safari bug

    That's _not_ a bug.

    return {width: element.offsetWidth, height:
    element.offsetHeight};

    var els = element.style;
    var originalVisibility = els.visibility;
    var originalPosition = els.position;
    var originalDisplay = els.display;
    els.visibility = 'hidden';
    if (originalPosition != 'fixed') // Switching fixed to absolute
    causes issues in Safari
    els.position = 'absolute';
    els.display = 'block';


    This is really sad (and completely unecessary). That sums up the
    whole project. :)


    var originalWidth = element.clientWidth;
    var originalHeight = element.clientHeight;
    els.display = originalDisplay;
    els.position = originalPosition;
    els.visibility = originalVisibility;
    return {width: originalWidth, height: originalHeight};
    },

    [...]

    if (Prototype.Browser.Opera) {

    Here we go again...

    Element.Methods.getStyle = Element.Methods.getStyle.wrap(
    function(proceed, element, style) {
    switch (style) {
    case 'left': case 'top': case 'right': case 'bottom':
    if (proceed(element, 'position') === 'static') return null;
    case 'height': case 'width':
    if (!Element.visible(element)) return null;

    var dim = parseInt(proceed(element, style), 10);

    if (dim !== element['offset' + style.capitalize()])
    return dim + 'px';

    var properties;
    if (style === 'height') {
    properties = ['border-top-width', 'padding-top',
    'padding-bottom', 'border-bottom-width'];
    }
    else {
    properties = ['border-left-width', 'padding-left',
    'padding-right', 'border-right-width'];
    }
    return properties.inject(dim, function(memo, property) {
    var val = proceed(element, property);
    return val === null ? memo : memo - parseInt(val, 10);
    }) + 'px';
    default: return proceed(element, style);
    }
    }
    );

    Element.Methods.readAttribute = Element.Methods.readAttribute.wrap(
    function(proceed, element, attribute) {
    if (attribute === 'title') return element.title;
    return proceed(element, attribute);
    }
    );
    }

    else if (Prototype.Browser.IE) {
    Element.Methods.getOffsetParent =
    Element.Methods.getOffsetParent.wrap(
    function(proceed, element) {
    element = $(element);
    try { element.offsetParent }
    catch(e) { return $(document.body) }
    var position = element.getStyle('position');
    if (position !== 'static') return proceed(element);
    element.setStyle({ position: 'relative' });
    var value = proceed(element);
    element.setStyle({ position: position });
    return value;
    }
    );

    $w('positionedOffset viewportOffset').each(function(method) {
    Element.Methods[method] = Element.Methods[method].wrap(
    function(proceed, element) {
    element = $(element);
    try { element.offsetParent }
    catch(e) { return Element._returnOffset(0,0) }
    var position = element.getStyle('position');
    if (position !== 'static') return proceed(element);
    var offsetParent = element.getOffsetParent();
    if (offsetParent && offsetParent.getStyle('position') ===
    'fixed')
    offsetParent.setStyle({ zoom: 1 });
    element.setStyle({ position: 'relative' });
    var value = proceed(element);
    element.setStyle({ position: position });
    return value;
    }
    );
    });

    Element.Methods.cumulativeOffset =
    Element.Methods.cumulativeOffset.wrap(
    function(proceed, element) {
    try { element.offsetParent }
    catch(e) { return Element._returnOffset(0,0) }
    return proceed(element);
    }
    );

    Element.Methods.getStyle = function(element, style) {


    Deja vu all over again.


    [...]

    Element._attributeTranslations = (function(){

    var classProp = 'className';
    var forProp = 'for';

    var el = document.createElement('div');

    el.setAttribute(classProp, 'x');

    if (el.className !== 'x') {
    el.setAttribute('class', 'x');
    if (el.className === 'x') {
    classProp = 'class';
    }
    }
    el = null;


    Where have I seen _that_ test before? Did they learn anything?


    el = document.createElement('label');
    el.setAttribute(forProp, 'x');
    if (el.htmlFor !== 'x') {
    el.setAttribute('htmlFor', 'x');
    if (el.htmlFor === 'x') {
    forProp = 'htmlFor';
    }
    }

    Nope. Not a clue. It's all based on observations made by people who
    don't understand what they are looking at.

    el = null;

    return {
    read: {
    names: {
    'class': classProp,
    'className': classProp,
    'for': forProp,
    'htmlFor': forProp
    },

    "className" and "htmlFor" are _not_ attribute names.


    values: {
    _getAttr: function(element, attribute) {
    return element.getAttribute(attribute);
    },
    _getAttr2: function(element, attribute) {
    return element.getAttribute(attribute, 2);
    },
    _getAttrNode: function(element, attribute) {
    var node = element.getAttributeNode(attribute);
    return node ? node.value : "";
    },
    _getEv: (function(){

    var el = document.createElement('div');
    el.onclick = Prototype.emptyFunction;
    var value = el.getAttribute('onclick');

    var f;

    if (String(value).indexOf('{') > -1) {
    f = function(element, attribute) {
    attribute = element.getAttribute(attribute);
    if (!attribute) return null;
    attribute = attribute.toString();
    attribute = attribute.split('{')[1];
    attribute = attribute.split('}')[0];
    return attribute.strip();
    };
    }
    else if (value === '') {
    f = function(element, attribute) {
    attribute = element.getAttribute(attribute);
    if (!attribute) return null;
    return attribute.strip();
    };
    }
    el = null;
    return f;
    })(),
    _flag: function(element, attribute) {
    return $(element).hasAttribute(attribute) ? attribute :
    null;
    },


    Their hasAttribute wrapper is BS too.


    style: function(element) {
    return element.style.cssText.toLowerCase();
    },
    title: function(element) {
    return element.title;
    }
    }
    }
    }
    })();

    Element._attributeTranslations.write = {
    names: Object.extend({
    cellpadding: 'cellPadding',
    cellspacing: 'cellSpacing'
    }, Element._attributeTranslations.read.names),
    values: {
    checked: function(element, value) {
    element.checked = !!value;
    },

    style: function(element, value) {
    element.style.cssText = value ? value : '';
    }
    }
    };


    It's the world according to Prototype. :)


    Element._attributeTranslations.has = {};

    $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' +
    'encType maxLength readOnly longDesc frameBorder').each(function
    (attr) {
    Element._attributeTranslations.write.names[attr.toLowerCase()] =
    attr;
    Element._attributeTranslations.has[attr.toLowerCase()] = attr;
    });


    As they see it, of course.


    (function(v) {
    Object.extend(v, {
    href: v._getAttr2,
    src: v._getAttr2,
    type: v._getAttr,
    action: v._getAttrNode,
    disabled: v._flag,
    checked: v._flag,
    readonly: v._flag,
    multiple: v._flag,
    onload: v._getEv,
    onunload: v._getEv,
    onclick: v._getEv,
    ondblclick: v._getEv,
    onmousedown: v._getEv,
    onmouseup: v._getEv,
    onmouseover: v._getEv,
    onmousemove: v._getEv,
    onmouseout: v._getEv,
    onfocus: v._getEv,
    onblur: v._getEv,
    onkeypress: v._getEv,
    onkeydown: v._getEv,
    onkeyup: v._getEv,
    onsubmit: v._getEv,
    onreset: v._getEv,
    onselect: v._getEv,
    onchange: v._getEv
    });
    })(Element._attributeTranslations.read.values);


    Can you spot the pattern for events?


    [...]

    else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test
    (navigator.userAgent)) {
    Element.Methods.setOpacity = function(element, value) {
    element = $(element);
    element.style.opacity = (value == 1) ? 0.999999 :
    (value === '') ? '' : (value < 0.00001) ? 0 : value;
    return element;
    };
    }

    else if (Prototype.Browser.WebKit) {
    Element.Methods.setOpacity = function(element, value) {
    element = $(element);
    element.style.opacity = (value == 1 || value === '') ? '' :
    (value < 0.00001) ? 0 : value;

    if (value == 1)
    if(element.tagName.toUpperCase() == 'IMG' && element.width) {
    element.width++; element.width--;
    } else try {
    var n = document.createTextNode(' ');
    element.appendChild(n);
    element.removeChild(n);
    } catch (e) { }

    return element;
    };


    More magic spells. And who do they think is going to maintain all of
    this crap?


    [...]

    function findDOMClass(tagName) {
    var klass;
    var trans = {
    "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P":
    "Paragraph",
    "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL":
    "DList",
    "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3":
    "Heading",
    "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",
    "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image",
    "CAPTION":
    "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol",
    "THEAD":
    "TableSection", "TFOOT": "TableSection", "TBODY":
    "TableSection", "TR":
    "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":
    "FrameSet", "IFRAME": "IFrame"
    };
    if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';
    if (window[klass]) return window[klass];
    klass = 'HTML' + tagName + 'Element';
    if (window[klass]) return window[klass];
    klass = 'HTML' + tagName.capitalize() + 'Element';
    if (window[klass]) return window[klass];

    var element = document.createElement(tagName);
    var proto = element['__proto__'] || element.constructor.prototype;
    element = null;
    return proto;
    }


    Wothless waste of space (and they sure can't spare any).

    [...]

    document.viewport = {

    getDimensions: function() {
    return { width: this.getWidth(), height: this.getHeight() };
    },

    getScrollOffsets: function() {
    return Element._returnOffset(
    window.pageXOffset || document.documentElement.scrollLeft ||
    document.body.scrollLeft,
    window.pageYOffset || document.documentElement.scrollTop ||
    document.body.scrollTop);
    }


    LOL. It's the same BS over and over (see Closure, Qooxdoo, etc.) Why
    do people waste their lives writing and maintaining such follies?


    };

    (function(viewport) {
    var B = Prototype.Browser, doc = document, element, property = {};

    function getRootElement() {
    if (B.WebKit && !doc.evaluate)
    return document;


    OMG. That's a sniff for Safari 2, which features document.clientWidth/
    Height.

    http://www.cinsoft.net/viewport.asp



    if (B.Opera && window.parseFloat(window.opera.version()) < 9.5)
    return document.body;


    Sniff for older Operas. They don't read the trades I guess.


    return document.documentElement;
    }

    [...]

    /* Portions of the Selector class are derived from Jack Slocum's
    DomQuery,
    * part of YUI-Ext version 0.40, distributed under the terms of an MIT-
    style
    * license. Please see http://www.yui-ext.com/ for more information.
    */


    How does it help for these projects to copy off each other?


    var Selector = Class.create({
    initialize: function(expression) {
    this.expression = expression.strip();

    if (this.shouldUseSelectorsAPI()) {
    this.mode = 'selectorsAPI';
    } else if (this.shouldUseXPath()) {
    this.mode = 'xpath';
    this.compileXPathMatcher();
    } else {
    this.mode = "normal";
    this.compileMatcher();
    }

    },

    shouldUseXPath: (function() {

    var IS_DESCENDANT_SELECTOR_BUGGY = (function(){
    var isBuggy = false;
    if (document.evaluate && window.XPathResult) {
    var el = document.createElement('div');
    el.innerHTML = '<ul><li></li></ul><div><ul><li></li></ul></
    div>';

    var xpath = ".//*[local-name()='ul' or local-name()='UL']" +
    "//*[local-name()='li' or local-name()='LI']";

    var result = document.evaluate(xpath, el, null,
    XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);

    isBuggy = (result.snapshotLength !== 2);
    el = null;
    }
    return isBuggy;
    })();

    return function() {
    if (!Prototype.BrowserFeatures.XPath) return false;

    var e = this.expression;

    if (Prototype.Browser.WebKit &&
    (e.include("-of-type") || e.include(":empty")))
    return false;


    Just look at this shit.


    if ((/(\[[\w-]*?:|:checked)/).test(e))
    return false;

    if (IS_DESCENDANT_SELECTOR_BUGGY) return false;

    return true;
    }

    })(),

    [...]


    attrPresence: function(nodes, root, attr, combinator) {
    if (!nodes) nodes = root.getElementsByTagName("*");
    if (nodes && combinator) nodes = this[combinator](nodes);
    var results = [];
    for (var i = 0, node; node = nodes; i++)
    if (Element.hasAttribute(node, attr)) results.push(node);
    return results;
    },

    attr: function(nodes, root, attr, value, operator, combinator) {
    if (!nodes) nodes = root.getElementsByTagName("*");
    if (nodes && combinator) nodes = this[combinator](nodes);
    var handler = Selector.operators[operator], results = [];
    for (var i = 0, node; node = nodes; i++) {
    var nodeValue = Element.readAttribute(node, attr);

    There it is. Game, set and match (no pun intended). This BS is
    incompatible with the other two (!) forks. Cross-browser consistency
    is out of the question. You just can't have such breakdowns in the
    boiler room.

    And there's still a mile of code to go... But I think this one is
    done anyway.

    I'll be posting some demonstrations of the various library (and
    "framework") query follies shortly (they are _all_ screwed up). At
    the very least, it's hilarious seeing all of the various versions of
    these things sputter and regress over the years (with no right answers
    or even understanding in sight). At best, it should scare people
    straight.

    These developers are _incompetent_. There's no other word for it.
    They are wasting their time, but they don't need to waste yours. You
    can't tell these people they are wrong, because they are super-genius
    JS developers (at least that's what everyone tells them). Read their
    forums and mailing lists and the clouds part (they can scarcely hide
    their confusion and overconfidence). Moderation is a _huge_ red flag
    as it indicates an attempt to shield the developers from criticism and
    preserve a "scholarly" air (hasn't worked very well).

    Cross-browser scripting is _not_ impossible (except for the
    incompetent, which goes without saying). It never was, but it is
    hardly even a challenge these days (for those who seek to support only
    modern desktop browsers). Think about that before you choose the
    "simplicity" of one of these query-based pieces of junk.

    Anyone who tells you different is ignorant or selling something.
    David Mark, Dec 24, 2009
    #1
    1. Advertising

  2. David Mark

    David Mark Guest

    On Dec 24, 3:42 pm, David Mark <> wrote:

    [...]

    > Somebody stop these guys.  :(


    Doesn't look like they need any help there. A recent suggestion in
    their (virtually empty) support group:-

    "How 'bout something like
    var paramsA = Form.serializeElements( $("frm").getInputs('checkbox',
    "typeA"),true);
    var paramsB = Form.serializeElements( $("frm").getInputs('checkbox',
    "typeB"),true);
    var paramsC = Form.serializeElements( $("frm").getInputs('checkbox',
    "typeC"),true);"

    How 'bout finding another hobby? Pass it along...

    " var params = paramsA + '&' + paramsB + '&' + paramsC;

    Yeah... I know it's not as sexy as defining the array and running
    through an 'each' loop but I bet it would work :)"

    I bet it would be a disaster as the OP was looking for performance
    tips. ;)

    "(With string concatenation, you could, of course, do it all in a
    single variable)"

    Oh, of course. :) This may be the worst JS-related "answer" I've
    ever seen (and that's against some pretty fierce competition).

    The communities usually mirror the proficiency of the code they
    worship and this one is no exception.
    David Mark, Dec 24, 2009
    #2
    1. Advertising

  3. David Mark

    David Mark Guest

    David Mark, Dec 25, 2009
    #3
  4. David Mark wrote:
    > /* Prototype JavaScript framework, version 1.6.1
    > * (c) 2005-2009 Sam Stephenson
    > *
    > * Prototype is freely distributable under the terms of an MIT-style
    > license.
    > * For details, see the Prototype web site: http://www.prototypejs.org/
    > *
    >
    > *--------------------------------------------------------------------------
    > */
    >
    > var Prototype = {
    > Version: '1.6.1',
    >
    > Browser: (function(){
    > var ua = navigator.userAgent;
    > var isOpera = Object.prototype.toString.call(window.opera) ==
    > '[object Opera]';
    >
    >
    > Not a bad test for Opera, but who needs to test for Opera in 2010? :)
    >


    PrototypeJS is legacy code. Refactoring PrototypeJS, removing those
    would be a problem. Other low-level code or even code in third party
    libraries should not be using that.

    I would add an @deprecated comment above that.
    --
    Garrett
    comp.lang.javascript FAQ: http://jibbering.com/faq/
    Garrett Smith, Dec 25, 2009
    #4
  5. David Mark wrote:

    > David Mark wrote:
    >> The communities usually mirror the proficiency of the code they
    >> worship and this one is no exception.

    >
    > https://prototype.lighthouseapp.com/projects/8886/tickets/529-element-
    > constructor-doesnt-add-classname-in-ie8
    >
    > :)


    "The `className' property wasn't object-oriented enough, we needed to work
    around setAttribute() quirks instead." :->


    PointedEars
    --
    Danny Goodman's books are out of date and teach practices that are
    positively harmful for cross-browser scripting.
    -- Richard Cornford, cljs, <cife6q$253$1$> (2004)
    Thomas 'PointedEars' Lahn, Dec 25, 2009
    #5
  6. David Mark

    David Mark Guest

    On Dec 25, 12:06 am, Garrett Smith <> wrote:
    > David Mark wrote:
    > > /*  Prototype JavaScript framework, version 1.6.1
    > >  *  (c) 2005-2009 Sam Stephenson
    > >  *
    > >  *  Prototype is freely distributable under the terms of an MIT-style
    > > license.
    > >  *  For details, see the Prototype web site:http://www.prototypejs.org/
    > >  *

    >
    > > *--------------------------------------------------------------------------
    > > */

    >
    > > var Prototype = {
    > >   Version: '1.6.1',

    >
    > >   Browser: (function(){
    > >     var ua = navigator.userAgent;
    > >     var isOpera = Object.prototype.toString.call(window.opera) ==
    > > '[object Opera]';

    >
    > > Not a bad test for Opera, but who needs to test for Opera in 2010?  :)

    >
    > PrototypeJS is legacy code. Refactoring PrototypeJS, removing those
    > would be a problem.  Other low-level code or even code in third party
    > libraries should not be using that.
    >
    > I would add an @deprecated comment above that.


    Did you read the code I posted? The _entire_ thing is based on those
    flags. It's not a matter of deprecation at this point (first they
    have to rewrite their own code).
    David Mark, Dec 25, 2009
    #6
  7. David Mark

    David Mark Guest

    On Dec 25, 8:06 am, Thomas 'PointedEars' Lahn <>
    wrote:
    > David Mark wrote:
    > > David Mark wrote:
    > >> The communities usually mirror the proficiency of the code they
    > >> worship and this one is no exception.

    >
    > >https://prototype.lighthouseapp.com/projects/8886/tickets/529-element-
    > > constructor-doesnt-add-classname-in-ie8

    >
    > > :)

    >
    > "The `className' property wasn't object-oriented enough, we needed to work
    > around setAttribute() quirks instead." :->
    >


    Yeah, after all of these years, they are not fighting browser quirks
    at all. They are fighting their own misconceptions and foolish
    designs. ;)

    I think it is clear how this situation came about. Various neophytes
    (likely ex-Java programmers) tried to break into browser scripting
    around 2005-6 when the major browsers were still fairly quirky. They
    created designs that were inappropriate for JS and spent the next few
    years trying to pound their square pegs into round holes (and bitching
    about IE).

    Not one of these projects ever figured out IE6/7 (ostensibly the main
    reason for their existence). Now they want to drop "support" for
    those (and never mind that IE8 can act much like IE6/7 at the touch of
    a button). Of course, if they drop support for those, they are left
    with a half dozen QSA-enabled browsers (all with real documentation)
    that don't need 50-100K of monkey code to provide a consistent
    interface (or to do queries).

    So, they are all on their way out and will ultimately be remembered as
    dismal failures. ;)
    David Mark, Dec 25, 2009
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Whitecrest
    Replies:
    1
    Views:
    393
    longroad
    Jul 2, 2004
  2. Developwebsites

    who lets these people on the net?...

    Developwebsites, Aug 31, 2004, in forum: HTML
    Replies:
    27
    Views:
    860
    kchayka
    Sep 1, 2004
  3. Steve Holden
    Replies:
    7
    Views:
    466
    Christos TZOTZIOY Georgiou
    Mar 30, 2005
  4. Noble
    Replies:
    18
    Views:
    452
  5. Replies:
    1
    Views:
    707
    Roger Lindsjö
    Jun 11, 2008
Loading...

Share This Page