Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

MooTools: An Objective Look

231 views
Skip to first unread message

David Mark

unread,
Dec 21, 2008, 1:22:59 PM12/21/08
to
MooTools: An Objective Look

Seems this oddity is now creeping into public perception. So is it
any good at all?

As an aside, the "builder" is enhanced to the point of inaccessibility
and it is one of those pages that is falling off the edge of the left
side of the window (at least in FF3.) Not promising.

Excerpts:

- Some functionality inspired by [Prototype.js](http://
prototypejs.org) Copyright (c) 2005-2007 Sam Stephenson, [MIT License]
(http://opensource.org/licenses/mit-license.php)
*/

There's a big red flag right off the bat.

var Hash = new Native({
name: 'Hash',

initialize: function(object){
if ($type(object) == 'hash') object = $unlink(object.getClean());
for (var key in object) this[key] = object[key];
return this;
}

});

They are aping the initial effort of a Javascript programmer who
obviously hadn't yet learned Javascript. Note the incessant use of
"$" as well as the "initialize" method.

And why isn't that for-in loop filtered? This is supposed to be a
drop-in solution, yet it is clearly vulnerable to the machinations of
other scripts.

function $arguments(i){
return function(){
return arguments[i];
};
};

Useless syntactic sugar (and for what?)

function $chk(obj){
return !!(obj || obj === 0);
};

Try to guess what that's for. Then wonder how it came to be called
"$chk".

function $defined(obj){
return (obj != undefined);
};

Hard to botch a one-line function such as this, but I spot no less
than four mistakes, including the aforementioned use of "$".

function $lambda(value){
return (typeof value == 'function') ? value : function(){
return value;
};
};

So why would you pass a function to this in the first place?

function $splat(obj){
var type = $type(obj);
return (type) ? ((type != 'array' && type != 'arguments') ? [obj] :
obj) : [];
};

Splat indeed.

function $try(){
for (var i = 0, l = arguments.length; i < l; i++){
try {
return arguments[i]();
} catch(e){}
}
return null;
};

That lets out a lot of older browsers (syntax error) and it appears to
be part of the core.

function $type(obj){
if (obj == undefined) return false;
if (obj.$family) return (obj.$family.name == 'number' && !isFinite
(obj)) ? false : obj.$family.name;
if (obj.nodeName){
switch (obj.nodeType){
case 1: return 'element';
case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' :
'whitespace';
}
} else if (typeof obj.length == 'number'){
if (obj.callee) return 'arguments';
else if (obj.item) return 'collection';
}
return typeof obj;
};

I don't know what this is supposed to be, but I don't like it. And
something tells me the whole script hinges on it.

var Browser = $merge({

Engine: {name: 'unknown', version: 0},

Platform: {name: (window.orientation != undefined) ? 'ipod' :
(navigator.platform.match(/mac|win|linux/i) || ['other'])
[0].toLowerCase()},

Here we go.

Features: {xpath: !!(document.evaluate), air: !!(window.runtime),
query: !!(document.querySelector)},

This is stupid. Methods that rely on missing features should
themselves be missing from the API. No extraneous collection of flags
necessary.

Plugins: {},

Engines: {

Wonder how many the authors have heard of (and how many they know how
to detect?)

presto: function(){
return (!window.opera) ? false : ((arguments.callee.caller) ? 960 :
((document.getElementsByClassName) ? 950 : 925));

Jesus. The versions?!

},

There's none.

trident: function(){
return (!window.ActiveXObject) ? false : ((window.XMLHttpRequest) ?
5 : 4);
},

And none.

webkit: function(){
return (navigator.taintEnabled) ? false :
((Browser.Features.xpath) ? ((Browser.Features.query) ? 525 : 420) :
419);
},

Still none.

gecko: function(){
return (document.getBoxObjectFor == undefined) ? false :
((document.getElementsByClassName) ? 19 : 18);

The gBOF method is deprecated and will be removed in the next release
of FF. So this "detection" already has an expiration date.

}

And none. So, this was all a waste of time.

}

}, Browser || {});

Browser.Platform[Browser.Platform.name] = true;

For your sniffing convenience.

Browser.detect = function(){

for (var engine in this.Engines){
var version = this.Engines[engine]();
if (version){
this.Engine = {name: engine, version: version};
this.Engine[engine] = this.Engine[engine + version] = true;
break;
}
}

return {name: engine, version: version};

};

Browser.detect();

Well, at least they are honest about it. This doesn't even aspire to
be cross-browser (or maintainable.)

Browser.Features.xhr = !!(Browser.Request());

Another extraneous flag.

Browser.Plugins.Flash = (function(){
var version = ($try(function(){
return navigator.plugins['Shockwave Flash'].description;
}, function(){
return new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable
('$version');
}) || '0 r0').match(/\d+/g);
return {version: parseInt(version[0] || 0 + '.' + version[1] || 0),
build: parseInt(version[2] || 0)};
})();

That dog don't hunt. The first "try" doesn't need try-catch and the
second is just wrong. Granted, Adobe's own examples are abominable,
but they at least attempt to address the myriad issues involved with
sniffing Flash.

function $exec(text){
if (!text) return text;
if (window.execScript){
window.execScript(text);
} else {
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');

Why would anyone use setAttribute for this? Perhaps because dot
notation wouldn't work.

script[(Browser.Engine.webkit && Browser.Engine.version < 420) ?
'innerText' : 'text'] = text;

Now we see the incompetence inherent in the system. And how old is
this script? You can't buy that sort of ineptitude, so why not
download it for free?

document.head.appendChild(script);
document.head.removeChild(script);
}
return text;
};

var $uid = (Browser.Engine.trident) ? function(item){
return (item.uid || (item.uid = [Native.UID++]))[0];
} : function(item){
return item.uid || (item.uid = Native.UID++);
};

Similar nonsense.

var Window = new Native({

name: 'Window',

legacy: (Browser.Engine.trident) ? null: window.Window,

Isn't that something.

initialize: function(win){
$uid(win);
if (!win.Element){
win.Element = $empty;
if (Browser.Engine.webkit) win.document.createElement("iframe"); //
fixes safari 2

Oh I bet it does. And what of Safari 3? And WTF are they trying to
fix?

win.Element.prototype = (Browser.Engine.webkit) ? window
["[[DOMElement.prototype]]"] : {};

That does it.

}
win.document.window = win;

A document expando to boot. And that sure looks like a circular
reference to me.

return $extend(win, Window.Prototype);
},

I don't think it warrants any further study or consideration.

Peter Michaux

unread,
Dec 22, 2008, 1:04:08 PM12/22/08
to
On Dec 21, 10:22 am, David Mark <dmark.cins...@gmail.com> wrote:

> Hard to botch a one-line function such as this, but I spot no less
> than four mistakes, including the aforementioned use of "$".

ECMAScript 3.1 spec removes the line about dollar sign is only for
machine generated code. The dollar sign will just be another
identifier character. I think this is a good change to the spec as
they should only state what is allowed and disallowed by a compliant
implementation.

Peter

dhtml

unread,
Dec 23, 2008, 12:47:22 AM12/23/08
to
David Mark wrote:
> MooTools: An Objective Look
>
> Seems this oddity is now creeping into public perception. So is it
> any good at all?

* Modification of built-ins.
* Modification to host object (and assoc. prototype)
* Low level typechecking gone wrong ($type).
* Incorrect use of comparison operator everywhere (== where === is needed)

The name "MooTools" comes from "My OO Tools". It does not seem very OO.
The library creates a lot of low-level dependencies on built-ins and
host obj prototypes.


>
> And why isn't that for-in loop filtered? This is supposed to be a
> drop-in solution, yet it is clearly vulnerable to the machinations of
> other scripts.
>


There are a lot of beginner mistakes like that:
* Something named 'Hash' should be checking own-properties only.
* The use of == where === should be used is

>
> function $defined(obj){
> return (obj != undefined);
> };
>
> Hard to botch a one-line function such as this, but I spot no less
> than four mistakes, including the aforementioned use of "$".
>

1) the use of != where !== must be used
2) extra empty statement (the xtra ;).

The unneeded grouping is not a problem. I don't know if you're counting
that as a mistake.


> function $try(){
> for (var i = 0, l = arguments.length; i < l; i++){
> try {
> return arguments[i]();
> } catch(e){}
> }
> return null;
> };
>

I understand that the mootools library uses tabs, but you could have
used a simple find-replace for the formatting.

> That lets out a lot of older browsers (syntax error) and it appears to
> be part of the core.
>
> function $type(obj){
> if (obj == undefined) return false;

boolean.
- If obj is null or undefined, false is returned.

> if (obj.$family) return (obj.$family.name == 'number' && !isFinite
> (obj)) ? false : obj.$family.name;

boolean || string.
- if obj has a $family property, if not finite, return false,
otherwise, return "number".

> if (obj.nodeName){
> switch (obj.nodeType){
> case 1: return 'element';
> case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' :
> 'whitespace';
> }
> } else if (typeof obj.length == 'number'){
> if (obj.callee) return 'arguments';
> else if (obj.item) return 'collection';
> }
> return typeof obj;

string.

> };
>
> I don't know what this is supposed to be, but I don't like it.

Function $type is a low-level utility used for typechecking. The
function returns either a string or a boolean (I find this to be ironic).

There is a bug in the clause:-


switch (obj.nodeType){
case 1: return 'element';
case 3: return (/\S/).test(obj.nodeValue) ?
'textnode' : 'whitespace';

. Because obj.nodeType is 3, it will return either 'textnode' or
'whitespace'. They are consider '\u00a0', '\n', and other things to be
'textnode' not 'whitespace'. This is tricky, because it is unclear who
would be interested in '\n', and who would not want to care about that.
It places concern about what the callee might be doing with this value.
It is very non-OO.

The built-ins' prototypes, such as Array.prototype, are modified with a
$family property so that when $type is called, it can access that
property off the prototype chain of the object.

Being such a core part of a library named "My OO Tools", it indicates a
strong contradiction to the library's name.

> Now we see the incompetence inherent in the system. And how old is
> this script? You can't buy that sort of ineptitude, so why not
> download it for free?
>
> document.head.appendChild(script);
> document.head.removeChild(script);
> }
> return text;
> };
>

The head property was added to the document by this script. That side
effect isn't justified by the benefit obtained (less typing).


> Similar nonsense.
>
> var Window = new Native({
>
> name: 'Window',
>
> legacy: (Browser.Engine.trident) ? null: window.Window,
>
> Isn't that something.
>
> initialize: function(win){
> $uid(win);
> if (!win.Element){
> win.Element = $empty;
> if (Browser.Engine.webkit) win.document.createElement("iframe"); //
> fixes safari 2
>
> Oh I bet it does. And what of Safari 3? And WTF are they trying to
> fix?
>
> win.Element.prototype = (Browser.Engine.webkit) ? window
> ["[[DOMElement.prototype]]"] : {};
>
> That does it.
>

Modifying Host objects' prototype, and expecting the result to be that
the element will have, in the prototype chain, the property, but only
after browser sniffing. A lot of risky inferences. This approach is
totally unnecessary.


> }
> win.document.window = win;
>
> A document expando to boot. And that sure looks like a circular
> reference to me.
>
> return $extend(win, Window.Prototype);
> },
>
> I don't think it warrants any further study or consideration.

It is taken seriously. It was discussed at a recent 'JS Meetup' here in
SF, as is the cappucino framework, and its authors who frequently
present there (we can discuss this one next week).

It is somewhat useful to study this library because it is taken
seriously. If you reply to a job inquiry, and you get asked a silly
question like 'how is your mootools on a 1 to 10', you are ready with a
relaxed, objective, well-informed response (try not to laugh too much).

Garrett

--
comp.lang.javascript FAQ <URL: http://jibbering.com/faq/ >

David Mark

unread,
Dec 23, 2008, 5:33:59 AM12/23/08
to
On Dec 23, 12:47 am, dhtml <dhtmlkitc...@gmail.com> wrote:
> David Mark wrote:
> > MooTools: An Objective Look
>
> > Seems this oddity is now creeping into public perception.  So is it
> > any good at all?
>
> * Modification of built-ins.
> * Modification to host object (and assoc. prototype)
> * Low level typechecking gone wrong ($type).
> * Incorrect use of comparison operator everywhere (== where === is needed)
>
> The name "MooTools" comes from "My OO Tools". It does not seem very OO.
> The library creates a lot of low-level dependencies on built-ins and
> host obj prototypes.

Yes. Looked pretty inefficient and inflexible to me for this reason.
And of course, the host object prototype stuff is madness.

>
>
>
> > And why isn't that for-in loop filtered?  This is supposed to be a
> > drop-in solution, yet it is clearly vulnerable to the machinations of
> > other scripts.
>
> There are a lot of beginner mistakes like that:
>   * Something named 'Hash' should be checking own-properties only.
>   * The use of == where === should be used is
>
>
>
> > function $defined(obj){
> >    return (obj != undefined);
> > };
>
> > Hard to botch a one-line function such as this, but I spot no less
> > than four mistakes, including the aforementioned use of "$".
>
> 1) the use of != where !== must be used
> 2) extra empty statement (the xtra ;).

LOL. Thanks. Five mistakes (how did I miss that one!) Those two,
plus:

3. The "$"
4. The unneeded parentheses
5. Use of undefined identifier will break some older agents (typeof
should be used in such low-level code)

>
> The unneeded grouping is not a problem. I don't know if you're counting
> that as a mistake.

Yes. I was being picky on some of those.

>
> > function $try(){
> >    for (var i = 0, l = arguments.length; i < l; i++){
> >            try {
> >                    return arguments[i]();
> >            } catch(e){}
> >    }
> >    return null;
> > };
>
> I understand that the mootools library uses tabs, but you could have
> used a simple find-replace for the formatting.

Sorry about that.

>
> > That lets out a lot of older browsers (syntax error) and it appears to
> > be part of the core.
>
> > function $type(obj){
> >    if (obj == undefined) return false;
>
> boolean.
>   - If obj is null or undefined, false is returned.
>
> >    if (obj.$family) return (obj.$family.name == 'number' && !isFinite
> > (obj)) ? false : obj.$family.name;
>
> boolean || string.
>   - if obj has a $family property, if not finite, return false,
> otherwise, return "number".
>
> >    if (obj.nodeName){
> >            switch (obj.nodeType){
> >                    case 1: return 'element';
> >                    case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' :
> > 'whitespace';
> >            }
> >    } else if (typeof obj.length == 'number'){
> >            if (obj.callee) return 'arguments';
> >            else if (obj.item) return 'collection';
> >    }
> >    return typeof obj;
>
> string.
>
> > };
>
> > I don't know what this is supposed to be, but I don't like it.
>
> Function $type is a low-level utility used for typechecking. The
> function returns either a string or a boolean (I find this to be ironic).

Yes. Do you then call $type again to check the type of result?!

>
> There is a bug in the clause:-
>    switch (obj.nodeType){
>      case 1: return 'element';
>      case 3: return (/\S/).test(obj.nodeValue) ?
>      'textnode' :  'whitespace';
>
> . Because obj.nodeType is 3, it will return either 'textnode' or
> 'whitespace'. They are consider '\u00a0', '\n', and other things to be
> 'textnode' not 'whitespace'. This is tricky, because it is unclear who
> would be interested in '\n', and who would not want to care about that.
> It places concern about what the callee might be doing with this value.
> It is very non-OO.

I may not know OO, but I know what I like (and this ain't it.)

>
> The built-ins' prototypes, such as Array.prototype, are modified with a
> $family property so that when $type is called, it can access that
> property off the prototype chain of the object.
>
> Being such a core part of a library named "My OO Tools", it indicates a
> strong contradiction to the library's name.
>
> > Now we see the incompetence inherent in the system.  And how old is
> > this script?  You can't buy that sort of ineptitude, so why not
> > download it for free?
>
> >            document.head.appendChild(script);
> >            document.head.removeChild(script);
> >    }
> >    return text;
> > };
>
> The head property was added to the document by this script. That side

Unbelievable. I missed that one as I was focused on the browser
sniffing that preceded it.

> effect isn't justified by the benefit obtained (less typing).

And of course, if document.expando is false in IE...

>
>
>
> > Similar nonsense.
>
> > var Window = new Native({
>
> >    name: 'Window',
>
> >    legacy: (Browser.Engine.trident) ? null: window.Window,
>
> > Isn't that something.
>
> >    initialize: function(win){
> >            $uid(win);
> >            if (!win.Element){
> >                    win.Element = $empty;
> >                    if (Browser.Engine.webkit) win.document.createElement("iframe"); //
> > fixes safari 2
>
> > Oh I bet it does.  And what of Safari 3?  And WTF are they trying to
> > fix?
>
> >                    win.Element.prototype = (Browser.Engine.webkit) ? window
> > ["[[DOMElement.prototype]]"] : {};
>
> > That does it.
>
> Modifying Host objects' prototype, and expecting the result to be that
> the element will have, in the prototype chain, the property, but only
> after browser sniffing. A lot of risky inferences. This approach is
> totally unnecessary.

I think you are being too kind.

>
> >            }
> >            win.document.window = win;
>
> > A document expando to boot.  And that sure looks like a circular
> > reference to me.
>
> >            return $extend(win, Window.Prototype);
> >    },
>
> > I don't think it warrants any further study or consideration.
>
> It is taken seriously. It was discussed at a recent 'JS Meetup' here in

I know. The old "Prototype vs. jQuery" shriek-fest seems to have
"evolved" to include this thing. It seems the worse the script, the
more people blindly swear by it.

> SF, as is the cappucino framework, and its authors who frequently
> present there (we can discuss this one next week).

Never looked at that one.

>
> It is somewhat useful to study this library because it is taken
> seriously. If you reply to a job inquiry, and you get asked a silly
> question like 'how is your mootools on a 1 to 10', you are ready with a
> relaxed, objective, well-informed response (try not to laugh too much).

I agree in part, but seriously think that most HR types (or even IT
managers) would smile and award the applicant a 0 for that "skill."

Gregor Kofler

unread,
Dec 23, 2008, 8:55:39 AM12/23/08
to
dhtml meinte:

> It is somewhat useful to study this library because it is taken
> seriously. If you reply to a job inquiry, and you get asked a silly
> question like 'how is your mootools on a 1 to 10', you are ready with a
> relaxed, objective, well-informed response (try not to laugh too much).

Ah, I'm sure they'd like to hear you stating you were a MooTools
aficionado from version 0.0.1 on. But then: You probably don't want to
have that very job. (After getting close to a job of fixing IE memory
leaks in a Spry-prototype/scriptaculous-jQuery application, I definitely
know what to despise.)

Gregor

Matt Kruse

unread,
Dec 23, 2008, 12:01:15 PM12/23/08
to
On Dec 22, 12:04 pm, Peter Michaux <petermich...@gmail.com> wrote:
> ECMAScript 3.1 spec removes the line about dollar sign is only for
> machine generated code.

This is good news! One less thing to nit-pick and argue about here ;)

Matt Kruse

David Mark

unread,
Dec 23, 2008, 2:41:02 PM12/23/08
to

I bet that was something. Of course, it won't be something for very
long.

Maybe this would be a good visual aid for an interview:

http://farm4.static.flickr.com/3211/2347642183_91247aa0c8_o.jpg

David Mark

unread,
Dec 23, 2008, 4:12:01 PM12/23/08
to
On Dec 23, 12:47 am, dhtml <dhtmlkitc...@gmail.com> wrote:

[snip]

>
> It is taken seriously. It was discussed at a recent 'JS Meetup' here in
> SF, as is the cappucino framework, and its authors who frequently
> present there (we can discuss this one next week).

No time like the present. As for the download page, these framework
authors don't believe in left margins do they?

An excerpt from their flagship demo:

<script type="text/javascript" charset="utf-8">
//create a new timestamp to monitor launch time
_LAUNCH_TIME = new Date();

var path = document.location.href;

Not a good start. Using document.location (as opposed to
window.location) is the mark of a know-nothing.

path = path.substr(0, path.lastIndexOf('/') + 1);

document.write("<base href=\"" + path + "1224293852/" + "\"><!--[if IE]
><"+"/base><![endif]-->");

As is unnecessary concatenation.

</script>

<script src = "Frameworks/Objective-J/Objective-J.js" type = "text/
javascript"></script>

Nice markup.

Excerpt from "Objective J":

var NO = false,
YES = true,
nil = null,
Nil = null,
NULL = null,
ABS = Math.abs,
ASIN = Math.asin,
ACOS = Math.acos,
ATAN = Math.atan,
ATAN2 = Math.atan2,
SIN = Math.sin,
COS = Math.cos,
TAN = Math.tan,
EXP = Math.exp,
POW = Math.pow,
CEIL = Math.ceil,
FLOOR = Math.floor,
ROUND = Math.round,
MIN = Math.min,
MAX = Math.max,
RAND = Math.random,
SQRT = Math.sqrt,
E = Math.E,
LN2 = Math.LN2,
LN10 = Math.LN10,
LOG2E = Math.LOG2E,
LOG10E = Math.LOG10E,
PI = Math.PI,
PI2 = Math.PI * 2.0,
PI_2 = Math.PI / 2.0,
SQRT1_2 = Math.SQRT1_2,
SQRT2 = Math.SQRT2;

WTF?

var objj_continue_alerting = NO;

Yeah, I guess "false" is harder on the fingers.

with (new prototype_bug())
member = true;

Ugh.

if (window.ActiveXObject) {

Ineffectual feature detection.

if (window.XMLHttpRequest) {

Again.

objj_request_xmlhttp = function()
{
return new XMLHttpRequest();
}
} else if (window.ActiveXObject) {
var MSXML_XMLHTTP_OBJECTS = [ "Microsoft.XMLHTTP", "Msxml2.XMLHTTP",
"Msxml2.XMLHTTP.3.0", "Msxml2.XMLHTTP.6.0" ],

Second one isn't needed.

index = MSXML_XMLHTTP_OBJECTS.length;
while (index--)
{
try
{
new ActiveXObject(MSXML_XMLHTTP_OBJECTS[index]);
break;
}
catch (anException)
{
}
}
var MSXML_XMLHTTP = MSXML_XMLHTTP_OBJECTS[index];
delete index;
delete MSXML_XMLHTTP_OBJECTS;

I've seen enough.

[snip]

Matt Kruse

unread,
Dec 24, 2008, 8:32:34 AM12/24/08
to
On Dec 21, 12:22 pm, David Mark <dmark.cins...@gmail.com> wrote:
> MooTools: An Objective Look

I would be interested to see you look at jQuery again after the next
1.3 release (as will I, but I haven't done so yet). They are cleaning
out all browser sniffing, from what I can tell, and making an effort
to use better coding practices.

Of course, some of the design decisions will still be disagreed with
(overloading functions, use of $, supporting only a subset of known
browsers, etc). But is seems like they are trying to address some of
the coding concerns expressed here and by others.

The nice thing about a public library with a community and a group of
developers is that it can grow and improve and become more robust over
time. Hopefully.

Matt Kruse

David Mark

unread,
Dec 24, 2008, 12:11:43 PM12/24/08
to
On Dec 24, 8:32 am, Matt Kruse <m...@thekrusefamily.com> wrote:
> On Dec 21, 12:22 pm, David Mark <dmark.cins...@gmail.com> wrote:
>
> > MooTools: An Objective Look
>
> I would be interested to see you look at jQuery again after the next
> 1.3 release (as will I, but I haven't done so yet). They are cleaning

Let me know when it is released and I will.

> out all browser sniffing, from what I can tell, and making an effort

If they swap UA-parsing for poor object inferences like MooTools, it
won't really represent progress (okay, maybe a tiny bit.)

> to use better coding practices.

That would be nice, but you have to feel for the site and widget
authors who will have to re-test everything.

>
> Of course, some of the design decisions will still be disagreed with
> (overloading functions, use of $, supporting only a subset of known

I really couldn't care less about "$". That's just a symbol of
incompetence. It's the real problems that bother me.

> browsers, etc). But is seems like they are trying to address some of
> the coding concerns expressed here and by others.

I've heard that before. We'll see.

>
> The nice thing about a public library with a community and a group of
> developers is that it can grow and improve and become more robust over
> time. Hopefully.

Depends on the developers.

David Mark

unread,
Dec 24, 2008, 4:29:34 PM12/24/08
to
On Dec 24, 8:32 am, Matt Kruse <m...@thekrusefamily.com> wrote:
> On Dec 21, 12:22 pm, David Mark <dmark.cins...@gmail.com> wrote:
>
> > MooTools: An Objective Look
>
> I would be interested to see you look at jQuery again after the next
> 1.3 release (as will I, but I haven't done so yet). They are cleaning
> out all browser sniffing, from what I can tell, and making an effort
> to use better coding practices.
>

[snip]

I see the discussions. The sniffing is officially deprecated (along
with the box model detection which I pointed out as ludicrous a full
year ago), though still available for abuse (and the box model stuff
affects some of the core features.) I see a lot of clueless people
arguing for sniffing because of quirks they can't detect with feature
testing. The answer to that is obvious (don't encapsulate such things
in a browser scripting library.)

It is ironic that John Resig is finally trying to follow the road map
laid out a year back, which he dismissed as minor quibbling at the
time.

I was told of a similar effort by the Prototype crowd a few weeks
ago. As it turned out, something called "Kangax" had appropriated a
bit of my code and then veered off into pure fantasy. So the fact
that some of the jQuery developers have had a similar epiphany doesn't
mean much until they follow through with competently written feature
testing code.

Perhaps I will change the licensing requirements for My Library (and
finish the documentation of course.) It seems silly for most of the
world to hold their breath for a competent version of a script that
could have eliminated browser sniffing years ago. And, as mentioned,
there are lots of other problems with the jQuery design that can't be
addressed by patching.

And I still think that learning browser scripting is preferable to
using any prefab library or framework.

kangax

unread,
Dec 24, 2008, 6:28:13 PM12/24/08
to
David Mark wrote:

[snip]

> I was told of a similar effort by the Prototype crowd a few weeks
> ago. As it turned out, something called "Kangax" had appropriated a
> bit of my code and then veered off into pure fantasy. So the fact

I don't recall Micheaux' article (which `isHostMethod` was taken from
and which I linked to from the blog post) mentioning any specific
license or copyright. Granted, he does talk about you participating in
feature detection-related dicsussions, but there's no mention of any
kind of authorship that `isHostMethod` (and others) must retain. So what
exactly are you talking about?

Having said that, I do realize that my code must be full of stupid
mistakes, and would gladly listen to what you find delusional in my
"pure fantasy".

[snip]

--
kangax

David Mark

unread,
Dec 24, 2008, 7:08:01 PM12/24/08
to
On Dec 24, 6:28 pm, kangax <kan...@gmail.com> wrote:
> David Mark wrote:
>
> [snip]
>
> > I was told of a similar effort by the Prototype crowd a few weeks
> > ago.  As it turned out, something called "Kangax" had appropriated a
> > bit of my code and then veered off into pure fantasy.  So the fact
>
> I don't recall Micheaux' article (which `isHostMethod` was taken from
> and which I linked to from the blog post) mentioning any specific
> license or copyright. Granted, he does talk about you participating in
> feature detection-related dicsussions, but there's no mention of any

I'm pretty sure he mentions that isHostMethod is mine. And if you
trace the lineage, it is based on a method recommended by Thomas that
first appeared here several years ago.

> kind of authorship that `isHostMethod` (and others) must retain. So what
> exactly are you talking about?

I didn't imply an legal liability for using it. After all, it was
first published to this newsgroup. Ironically, your feature testing
code doesn't call it at all. Is it meant to be window dressing?

It is also ironic to see the product of discussions in this group
appearing in these library efforts. When exactly did the "real world"
change its collective tune? I see that the Dojo developers still live
in Fantasyland though (they reportedly laughed at Resig's "revelation"
about browser sniffing at a recent conference.)

>
> Having said that, I do realize that my code must be full of stupid
> mistakes, and would gladly listen to what you find delusional in my
> "pure fantasy".

Search the archive. I commented on it after it was mentioned as a
sign that Prototype was attempting to move away from browser
sniffing. And if you are going to use one of my methods, why not just
use my library? What possible use is there in propping up a falling
star like Prototype?

[snip]

kangax

unread,
Dec 24, 2008, 8:02:33 PM12/24/08
to
David Mark wrote:
> On Dec 24, 6:28 pm, kangax <kan...@gmail.com> wrote:
>> David Mark wrote:
>>
>> [snip]
>>
>>> I was told of a similar effort by the Prototype crowd a few weeks
>>> ago. As it turned out, something called "Kangax" had appropriated a
>>> bit of my code and then veered off into pure fantasy. So the fact
>> I don't recall Micheaux' article (which `isHostMethod` was taken from
>> and which I linked to from the blog post) mentioning any specific
>> license or copyright. Granted, he does talk about you participating in
>> feature detection-related dicsussions, but there's no mention of any
>
> I'm pretty sure he mentions that isHostMethod is mine. And if you
> trace the lineage, it is based on a method recommended by Thomas that
> first appeared here several years ago.

Yes, I've read through the archives after you brought this up the first
time. Perhaps I should have paid more attention to script's origins and
put a note in the source, but since I wasn't even using it (as you
obviously noticed) it didn't seem so important.

>
>> kind of authorship that `isHostMethod` (and others) must retain. So what
>> exactly are you talking about?
>
> I didn't imply an legal liability for using it. After all, it was
> first published to this newsgroup. Ironically, your feature testing
> code doesn't call it at all. Is it meant to be window dressing?

It was meant to replace plain boolean type conversion. While known to be
error-prone in certain cases, boolean type conversion seems more than
enough in such limited set of tests. Are there any known environments
where, say, `document.createElement` needs to be tested with `typeof`?

>
> It is also ironic to see the product of discussions in this group
> appearing in these library efforts. When exactly did the "real world"
> change its collective tune? I see that the Dojo developers still live
> in Fantasyland though (they reportedly laughed at Resig's "revelation"
> about browser sniffing at a recent conference.)

Yes, I was at that conference. I remember all four speakers (of
different libraries) talking about cases where browser sniffing can not
be avoided.

>
>> Having said that, I do realize that my code must be full of stupid
>> mistakes, and would gladly listen to what you find delusional in my
>> "pure fantasy".
>
> Search the archive. I commented on it after it was mentioned as a
> sign that Prototype was attempting to move away from browser

Ok. I'll read through it.

> sniffing. And if you are going to use one of my methods, why not just
> use my library? What possible use is there in propping up a falling

I am using Garrett's APE [1] in some of the projects. I find it a great
base to build upon (although I told him about clients in which it fails
- e.g. older Safari due to lack of `hasOwnProperty`). I need to find
some time to read through your library.

> star like Prototype?

I don't have executive decisions rights in Prototype.js development. Its
core understands some of the major flaws in library design (such as host
objects extension, sniffing and unnecessary low-level abstractions). It
would be much easier for us to make something decent out of it if not
for the the burden of backwards compatibility. Lack of time is another
show-stopper. Nevertheless, I think it's moving in the right direction.

>
> [snip]

[1] http://www.dhtmlkitchen.com/ape/

--
kangax

David Mark

unread,
Dec 24, 2008, 8:24:34 PM12/24/08
to
On Dec 24, 8:02 pm, kangax <kan...@gmail.com> wrote:
> David Mark wrote:
> > On Dec 24, 6:28 pm, kangax <kan...@gmail.com> wrote:
> >> David Mark wrote:
>
> >> [snip]
>
> >>> I was told of a similar effort by the Prototype crowd a few weeks
> >>> ago.  As it turned out, something called "Kangax" had appropriated a
> >>> bit of my code and then veered off into pure fantasy.  So the fact
> >> I don't recall Micheaux' article (which `isHostMethod` was taken from
> >> and which I linked to from the blog post) mentioning any specific
> >> license or copyright. Granted, he does talk about you participating in
> >> feature detection-related dicsussions, but there's no mention of any
>
> > I'm pretty sure he mentions that isHostMethod is mine.  And if you
> > trace the lineage, it is based on a method recommended by Thomas that
> > first appeared here several years ago.
>
> Yes, I've read through the archives after you brought this up the first
> time. Perhaps I should have paid more attention to script's origins and
> put a note in the source, but since I wasn't even using it (as you
> obviously noticed) it didn't seem so important.

No. I don't care if you put a note in there or not. I was simply
noting that you included one of my library's methods and then failed
to call it at all.

>
>
>
> >> kind of authorship that `isHostMethod` (and others) must retain. So what
> >> exactly are you talking about?
>
> > I didn't imply an legal liability for using it.  After all, it was
> > first published to this newsgroup.  Ironically, your feature testing
> > code doesn't call it at all.  Is it meant to be window dressing?
>
> It was meant to replace plain boolean type conversion. While known to be

Yes, I know (I wrote it.)

> error-prone in certain cases, boolean type conversion seems more than
> enough in such limited set of tests. Are there any known environments
> where, say, `document.createElement` needs to be tested with `typeof`?

Wouldn't matter if there weren't. But if you read about the origins
of this technique, you will find lots of cases where boolean type
conversion of host methods blows up (all are found in IE.)

>
>
>
> > It is also ironic to see the product of discussions in this group
> > appearing in these library efforts.  When exactly did the "real world"
> > change its collective tune?  I see that the Dojo developers still live
> > in Fantasyland though (they reportedly laughed at Resig's "revelation"
> > about browser sniffing at a recent conference.)
>
> Yes, I was at that conference. I remember all four speakers (of
> different libraries) talking about cases where browser sniffing can not
> be avoided.

And all can be considered ignorant for attempting to encapsulate such
cases in browser scripting libraries (assuming the cases really aren't
reconcilable with feature testing.) What I want to know is why anyone
would listen to them at this point (let alone pay money for the
privilege.) Seems more like a freak show than a conference.

>
>
>
> >> Having said that, I do realize that my code must be full of stupid
> >> mistakes, and would gladly listen to what you find delusional in my
> >> "pure fantasy".
>
> > Search the archive.  I commented on it after it was mentioned as a
> > sign that Prototype was attempting to move away from browser
>
> Ok. I'll read through it.

Post questions if you have any. And good luck convincing the
Prototype authors to give up their addiction to browser sniffing.

>
> > sniffing.  And if you are going to use one of my methods, why not just
> > use my library?  What possible use is there in propping up a falling
>
> I am using Garrett's APE [1] in some of the projects. I find it a great

I have to figure that is a much more solid choice than Prototripe. I
have no experience with his library, but I doubt it contains the sorts
of blunders found in the "big four."

> base to build upon (although I told him about clients in which it fails
> - e.g. older Safari due to lack of `hasOwnProperty`). I need to find
> some time to read through your library.
>
> > star like Prototype?
>
> I don't have executive decisions rights in Prototype.js development. Its
> core understands some of the major flaws in library design (such as host
> objects extension, sniffing and unnecessary low-level abstractions). It

Then why does it still use sniffing and unnecessary low-level
abstractions? It seems like *you* understand a bit about these
things, but the "core" is still focused on tired arguments against
feature testing.

> would be much easier for us to make something decent out of it if not
> for the the burden of backwards compatibility. Lack of time is another

I don't know what that means in relation to Prototype. It only claims
to support a few of the latest browsers and uses sniffing to create
the illusion that it does. There is nowhere to go but up from there.
Even John Resig seems to grasp that at this point.

> show-stopper. Nevertheless, I think it's moving in the right direction.

Wherever it is going, it is doing so at a snail's pace. Same for
jQuery, but at least they are trying to turn in the right direction.

[snip]

Kenny

unread,
Dec 25, 2008, 1:43:05 AM12/25/08
to
Matt Kruse wrote:
> On Dec 21, 12:22 pm, David Mark <dmark.cins...@gmail.com> wrote:
>
>>MooTools: An Objective Look
>
>
> I would be interested to see you look at jQuery again after the next
> 1.3 release (as will I, but I haven't done so yet). They are cleaning
> out all browser sniffing, from what I can tell, and making an effort
> to use better coding practices.
>
> Of course, some of the design decisions will still be disagreed with
> (overloading functions, use of $, supporting only a subset of known
> browsers, etc). But is seems like they are trying to address some of
> the coding concerns expressed here and by others.

The naysayers would naysay that anyone who made the mistake of
browser-sniffing in the first place is by definition subhuman so the
entire framework must be dumped in the garbage. But what do we do when
Subhuman admits he should not be doing browser sniffing and tries to
cure? Are they still subhuman?

I am just happy I have an application to work on so I do not have to
worry about the answer.

>
> The nice thing about a public library with a community and a group of
> developers is that it can grow and improve and become more robust over
> time. Hopefully.

Word. But (a quibble) there is not so much hope as there is a need to
(a) look at the core to see if it is salvageable and then (b) look at
the project to see if it is active. If all looks good, no hope is
needed: just add one's shoulder to the wheel. OK, I was not quibbling: I
hated YUI when I looked inside, which confirmed my experience from the
outside and the stream of tortured emails on the support list: YUI is a
library only its author can love and only because they wrote it.

kt

David Mark

unread,
Dec 25, 2008, 8:19:31 AM12/25/08
to
On Dec 25, 1:43 am, Kenny <kentil...@gmail.com> wrote:
> Matt Kruse wrote:
> > On Dec 21, 12:22 pm, David Mark <dmark.cins...@gmail.com> wrote:
>
> >>MooTools: An Objective Look
>
> > I would be interested to see you look at jQuery again after the next
> > 1.3 release (as will I, but I haven't done so yet). They are cleaning
> > out all browser sniffing, from what I can tell, and making an effort
> > to use better coding practices.
>
> > Of course, some of the design decisions will still be disagreed with
> > (overloading functions, use of $, supporting only a subset of known
> > browsers, etc). But is seems like they are trying to address some of
> > the coding concerns expressed here and by others.
>
> The naysayers would naysay that anyone who made the mistake of
> browser-sniffing in the first place is by definition subhuman so the

That is preposterous. Other than you now, who ever said such a
thing? However, it seems quite late in the game for the Web to
littered with scripts that stoop to such levels.

> entire framework must be dumped in the garbage. But what do we do when

The jQuery "framework" is just a bad script. And yes it should be
thrown out, regardless of whether it finally jettisons the sniffing
nonsense.

> Subhuman admits he should not be doing browser sniffing and tries to
> cure? Are they still subhuman?

If you are referring to Resig. I don't think history will be kind as
he fought the idea for over a year and then announced *his* revelation
about feature testing. The tagline I saw was "They said it couldn't
be done." Who is "they?" Among others, I told him it could and
should be done and he responded that such ideas had no place in his
framework for the "real world." He's clearly a bit dim and
disingenuous, but more or less human.

>
> I am just happy I have an application to work on so I do not have to
> worry about the answer.

You could have just skipped the question.

>
>
>
> > The nice thing about a public library with a community and a group of
> > developers is that it can grow and improve and become more robust over
> > time. Hopefully.
>
> Word. But (a quibble) there is not so much hope as there is a need to
> (a) look at the core to see if it is salvageable and then (b) look at

In the case of jQuery, it is not salvageable.

> the project to see if it is active. If all looks good, no hope is

Activity doesn't indicate much. How many widgets have been written
for the old jQuery version(s) in the last year? AIUI, many of them
use the browser flags exposed by jQuery. As the authors are now faced
with "deprecated" browser sniffing support, they are looking at
rewrites they are most likely incapable of doing (as evidenced by the
vocal resistance to this move.) And what about all of the Websites
that use these things? If they upgrade jQuery, will it break the
dependent widgets? Will newer versions of the widgets work with the
old jQuery? Is the average Web developer even conscious of these
issues?

What was the benefit of using jQuery again? To paraphrase one of the
Ajaxian editors in an article that dismissed any and all suggestions
of better frameworks: "these things have widgets." In other words,
that ship has sailed (never mind that it is sinking.)

> needed: just add one's shoulder to the wheel. OK, I was not quibbling: I
> hated YUI when I looked inside, which confirmed my experience from the

That is typical of your inability to judge code quality. I certainly
wouldn't recommend YUI (not even to Yahoo!), but it is definitely
better than that monstrosity you advocate.

> outside and the stream of tortured emails on the support list: YUI is a

Tortured emails don't indicate much either. There will always be
people who are incapable of understanding, don't read the manual, etc.

> library only its author can love and only because they wrote it.

Now there's a glimmer of insight. It's faint, but it's there.

Thomas 'PointedEars' Lahn

unread,
Dec 28, 2008, 2:09:26 PM12/28/08
to
David Mark wrote:

> dhtml wrote:
>> David Mark wrote:
>>> MooTools: An Objective Look
>>> Seems this oddity is now creeping into public perception. So is it
>>> any good at all?
>> * Modification of built-ins.

I don't know which built-ins you are referring to exactly here, but I don't
think there is anything *inherently* wrong with that. For a prominent
example, if Math.max() was detected not to support more than two arguments
in an implementation, and an application needed to determine the maximum out
of three or more values, I think it would be acceptable, if not prudent, to
try overwriting the built-in Math.max() with a method that is capable of
handling that (preferably storing the reference in another property, and
even reusing them in the replacement).

>> * Modification to host object (and assoc. prototype)
>> * Low level typechecking gone wrong ($type).
>> * Incorrect use of comparison operator everywhere (== where === is needed)
>>
>> The name "MooTools" comes from "My OO Tools". It does not seem very OO.
>> The library creates a lot of low-level dependencies on built-ins and
>> host obj prototypes.
>
> Yes. Looked pretty inefficient and inflexible to me for this reason.
> And of course, the host object prototype stuff is madness.

I don't think there is anything *inherently* wrong with using the prototype
object of host objects when it is provided either; after all, we have to
assume that modification of existing features or augmentation with new
features is the reason why it was made publicly available by the vendor in
the first place, and the augmentation of prototype objects can be much more
efficient than using a wrapper object that provides the new feature.

The problem (or as you put it, the madness) begins when one assumes that
because a prototype object is provided by one DOM API (e.g., the Gecko DOM)
it must also be provided by another, and if not already there to try making
it so. Because the former would be object inference, and the latter would
be host object augmentation; as discussed already, both must be considered
error-prone.


PointedEars

Thomas 'PointedEars' Lahn

unread,
Dec 28, 2008, 2:35:19 PM12/28/08
to
Peter Michaux wrote:

> David Mark wrote:
>> Hard to botch a one-line function such as this, but I spot no less
>> than four mistakes, including the aforementioned use of "$".
>
> ECMAScript 3.1 spec removes the line about dollar sign is only for
> machine generated code. The dollar sign will just be another
> identifier character. I think this is a good change to the spec as
> they should only state what is allowed and disallowed by a compliant
> implementation.

I think that is a shortsighted argumentation out of lack of sufficient
experience on your part. Technical specifications before have often, if not
always, stated not only what was allowed for achieving conformance and what
wasn't, but also have made recommendations as to what to consider
appropriate according to its author(s), and to what extent. See also
RFC2119 -- "Key words for use in RFCs to Indicate Requirement Levels"[1].

As for the `$', while the recommendation to use it only as prefix in
machine-generated code may be debatable, it stands to reason that given the
number of different libraries around that use the standalone `$' as an
identifier already, it would be unwise to follow that practice in new
(library) code that is supposed to be compatible. And, in fact, it could be
argued that using the `$' in new identifiers might lead to confusion when
reading and using such library code.

As for ECMAScript Edition 3.1 (and 4), it remains to be seen when it will be
finished, and when first implemented in a production environment. Insofar
your argument is not much more than of an academic nature at this point, and
you would be well-advised, if not required by the current prose of its text,
to refer to this Edition, like other Working Drafts out there, only as work
in progress, and therefore subject to change and being declared obsolete at
any time. "ECMA-262 Editions 3.1 and 4 are the next-generation versions of
ECMAScript *being developed* currently by the ECMA TC39 committee."[1]


PointedEars
___________
[1] <http://rfc-editor.org/rfc/rfc2119.txt>
[2] <http://www.ecmascript.org/docs.php>

dhtml

unread,
Dec 31, 2008, 12:35:30 AM12/31/08
to
Thomas 'PointedEars' Lahn wrote:
> David Mark wrote:
>> dhtml wrote:
>>> David Mark wrote:
>>>> MooTools: An Objective Look
>>>> Seems this oddity is now creeping into public perception. So is it
>>>> any good at all?
>>> * Modification of built-ins.
>
> I don't know which built-ins you are referring to exactly here,

Please see the Mootools documentation or source code.

Some of the modifications make sense, like adding the array-extras, if
they don't exist.

Other modifications don't really seem useful and might even conflict
with new releases of the language (Function.prototype.bind, for example).

>
> I don't think there is anything *inherently* wrong with using the prototype
> object of host objects when it is provided either; after all, we have to
> assume that modification of existing features or augmentation with new
> features is the reason why it was made publicly available by the vendor in

We don't have to assume anything.

It seems more likely (to me) that Mozilla exposed the XPConnect wrapped
prototypes so that developers could write quick patches.

> the first place, and the augmentation of prototype objects can be much more
> efficient than using a wrapper object that provides the new feature.

Example:

Element.prototype.customMeth = function(){ }

Do not do this. Augmenting host objects is error-prone. (you've said so
yourself, below).

It is less clear which methods are native and which are user add-ons. It
has the effect of creating a big ball of mud.

A decorator or a static method is much clearer. That way those
methods/constructors can be imported on the page they are used.

You have provided no evidence that modifying a host object prototype
would be more efficient than creating a static method and passing an
element to that method. I'm inclined to think that the lookup of that
method would be less efficient, as the method property name would have
to be found on the prototype chain of the object (if it is not shadowed).

> The problem (or as you put it, the madness) begins when one assumes that
> because a prototype object is provided by one DOM API (e.g., the Gecko DOM)
> it must also be provided by another, and if not already there to try making
> it so. Because the former would be object inference, and the latter would
> be host object augmentation; as discussed already, both must be considered
> error-prone.
>

Yes, modifying host objects' prototypes is error-prone.

Thomas 'PointedEars' Lahn

unread,
Dec 31, 2008, 7:24:49 PM12/31/08
to
dhtml wrote:
> Thomas 'PointedEars' Lahn wrote:
> > David Mark wrote:
> >> dhtml wrote:
> >>> David Mark wrote:
> >>>> MooTools: An Objective Look
> >>>> Seems this oddity is now creeping into public perception. So is
> > > > > it
> >>>> any good at all?
> >>> * Modification of built-ins.
> >
> > I don't know which built-ins you are referring to exactly here,
>
> Please see the Mootools documentation or source code.

Maybe later.



> Some of the modifications make sense, like adding the array-extras, if
>
> they don't exist.
>
> Other modifications don't really seem useful and might even conflict
> with new releases of the language (Function.prototype.bind, for
> example).

I was not arguing about the (doubtful) code quality of MooTools here but
about the -- I think -- inappropriate *general* criticism of some of the
design patterns it employs.



> > I don't think there is anything *inherently* wrong with using the
> > prototype
> > object of host objects when it is provided either; after all, we
> > have to
> > assume that modification of existing features or augmentation with
> > new
> > features is the reason why it was made publicly available by the
> > vendor in
>
> We don't have to assume anything.

That is also correct, but you miss the point.



> It seems more likely (to me) that Mozilla exposed the XPConnect
> wrapped
> prototypes so that developers could write quick patches.

Now that does not make sense to me at all. Patches to the C++ or Java
source code of Mozilla can be easily written without the Gecko DOM
exposing host object's prototypes through ECMAScript binding. Are you
sure you know what you are talking about?



> > the first place, and the augmentation of prototype objects can be
> > much more
> > efficient than using a wrapper object that provides the new feature.
>
> Example:
>
> Element.prototype.customMeth = function(){ }
>
> Do not do this.

Name a really good reason why not.

> Augmenting host objects is error-prone. (you've said so yourself,
> below).

That is NOT augmenting a host object.



> It is less clear which methods are native and which are user add-ons.

Really? I think the enumerable ones are user-defined and vice-versa
(CMIIW, I can't test right now).

> It
has the effect of creating a big ball of mud.

That is not an argument.



> A decorator or a static method is much clearer.

Maybe so, but it is also more expensive in memory.

> That way those
> methods/constructors can be imported on the page they are used.

With augmenting a host object's prototype, a property/feature becomes
available for all corresponding elements in a *document* without costly
iteration. I see no good reason why not to make use of such a useful DOM
feature if it is available. (In fact, I think it has the capacity to
become a DOM standard.)



> You have provided no evidence that modifying a host object prototype
> would be more efficient than creating a static method and passing an
> element to that method.

An element object reference, and the greater efficiency in this case
would seem to be self-evident.

> I'm inclined to think that the lookup of that
> method would be less efficient, as the method property name would have
>
> to be found on the prototype chain of the object (if it is not
> shadowed).

As always, the bargain is runtime efficiency vs. memory efficiency.



> > The problem (or as you put it, the madness) begins when one assumes
> > that
> > because a prototype object is provided by one DOM API (e.g., the
> > Gecko DOM)
> > it must also be provided by another, and if not already there to try
> > making
> > it so. Because the former would be object inference, and the latter
> > would
> > be host object augmentation; as discussed already, both must be
> > considered
> > error-prone.

>
> Yes, modifying host objects' prototypes is error-prone.

No, it isn't. Prototype objects are native objects.


PointedEars

dhtml

unread,
Jan 1, 2009, 2:49:00 PM1/1/09
to
Thomas 'PointedEars' Lahn wrote:
> dhtml wrote:
>> Thomas 'PointedEars' Lahn wrote:
>>> David Mark wrote:
>>>> dhtml wrote:
>>>>> David Mark wrote:
>>>>>> MooTools: An Objective Look


>

> I was not arguing about the (doubtful) code quality of MooTools here but
> about the -- I think -- inappropriate *general* criticism of some of the
> design patterns it employs.
>

What design patterns in Mootools were criticized?

>
>> It seems more likely (to me) that Mozilla exposed the XPConnect
>> wrapped
>> prototypes so that developers could write quick patches.
>
> Now that does not make sense to me at all. Patches to the C++ or Java
> source code of Mozilla can be easily written without the Gecko DOM
> exposing host object's prototypes through ECMAScript binding. Are you
> sure you know what you are talking about?
>

Take the pageX/Y properties. Problems in Firefox were that it did not
include scroll. An experimental monkey patch:-

MouseEvent.prototype.__defineGetter__('pageX', function() {
return this.clientX + window.pageXOffset;
});
MouseEvent.prototype.__defineGetter__('pageY', function() {
return this.clientY + window.pageYOffset;
});

If the monkey patch worked, it could be later incorporated into a real
patch.

I would not want to rely on this for a real webapp, though. It would
require a lot of feature testing and would probably be easier to design
around the problem.

>
>> It is less clear which methods are native and which are user add-ons.
>
> Really? I think the enumerable ones are user-defined and vice-versa
> (CMIIW, I can't test right now).
>

Many DOM properties have a |readonly| flag. This flag can map to
ECMAScript {ReadOnly} attribute. However, there is nothing that maps to
ECMAScript {DontEnum} attribute. This is not defined for any dom
objects, and so it is entirely dependent on the implementation.

The Host object might have a property with the same name hidden away
somewhere else on the object or its prototype chain. It might have a
getter defined on that object itself.

If('

>> It
> has the effect of creating a big ball of mud.
>
> That is not an argument.
>

The design issue...

I don't have costly iteration in my scripts and I never augment
Element.prototype. It is a solution to a problem that does not exist.

"Big ball of mud" is packaging of everything together.

Changes to part of a package affect the entire "package" (I'm using the
term "package" to describe software that is released as a unit).

Packages should be grouped according to usage patterns are smaller and
more clearly defined in terms of scope. This offers a few benefits:-

1) Unit testing small, narrowly defined portions of code is easier.
2) Packages grouped according to usage patterns are smaller. They
download faster and take up less space in the cache.

The package can be released as a set of functions in a file, or a set of
files that are intended to be used together.

Closures lend themselves nicely to packaging. Things that do not need to
be shared can be kept private to the scope.

A dependency on a package is a dependency on everything in that package.
The biggest issues I have with most library code I see (even in my own)
is that the packages are too generalized. There is generally too much
generality.

Recent uses use of dojo, jQuery and Mootools that I have looked at used
only a small portion of the library. Of that small portion, only part of
the code paths were executed. What the author was trying to accomplish
could have been achieved with much less code than those functions that
the library used and far less code than the entire library. The library
itself was not needed and that even as used for the purpose the author
used it for. It was not pulling its weight and was an inefficient
solution to the problem.

If the author had pared down the library (by snipping unused functions),
the library code would still be more than what was needed. A author who
is going to take to pains paring down one of these libraries to only the
functions he needs is probably skilled enough to be able to write his
own solution.

I see no good reason why not to make use of such a useful DOM
> feature if it is available. (In fact, I think it has the capacity to
> become a DOM standard.)
>

It is becoming a DOM standard (WEB IDL). They will have a lot of work in
for themselves if they plan on defining the prototype chain for objects,
and which attributes will be present {ReadOnly, DontDelete, DontEnum}.

I wonder how they will map a DOM readonly property. Is that supposed to
be {ReadOnly}? Many of these dom readonly properties are implemented as
getters. For example, ElementCSSInlineStyle is a getter. A getter
behaves differently than a ES {ReadOnly} property. Assigning to a ES
{ReadOnly} property fails silently Assignment to a property that has a
getter but no setter results in TypeError in Mozilla JavaScript. Example:-

document.body.style=1

>> You have provided no evidence that modifying a host object prototype
>> would be more efficient than creating a static method and passing an
>> element to that method.
>
> An element object reference, and the greater efficiency in this case
> would seem to be self-evident.
>
>> I'm inclined to think that the lookup of that
>> method would be less efficient, as the method property name would have
>>
>> to be found on the prototype chain of the object (if it is not
>> shadowed).
>
> As always, the bargain is runtime efficiency vs. memory efficiency.
>

Comparing:-

// 1.
Element.prototype.getX = function() { };
// 2.
function getX(el) { }

Where is the memory efficiency in #1?

Function getX (2) would not have to be resolved off the host object's
prototype chain. Element.prototype.getX would have to be resolved up the
prototype chain.

>>> The problem (or as you put it, the madness) begins when one assumes
>>> that
>>> because a prototype object is provided by one DOM API (e.g., the
>>> Gecko DOM)
>>> it must also be provided by another, and if not already there to try
>>> making
>>> it so. Because the former would be object inference, and the latter
>>> would
>>> be host object augmentation; as discussed already, both must be
>>> considered
>>> error-prone.
>
>> Yes, modifying host objects' prototypes is error-prone.
>
> No, it isn't. Prototype objects are native objects.
>

Given a host object Element, Element.prototype does not have to be a
native object. This next example creates a user-defined function X,
creates a new Image() (a host object), and assigns that new Image to
X.prototype. Constructing a new X will result in a [[Prototype]]
property - X.prototype - on the new object:-

function X() {}
X.prototype = new Image;
"x" in new X;

The example shows that a prototype object of a native ES object may be a
Host object. A prototype of a Host object could also be a Host object,
though it could also be null, undefined, Object.prototype...

Running the example, the |in| expression -- "x" in new X -- may or may
not be true, depending on implementation. The |x| property might be
implemented as a setter or it might be implemented as a property
somewhere. There is no standard for that and implementations vary. That
would be up to the implementation.

Consider a case of a hypothetical user-defined property |x| on
Element.prototype, Element.prototype.x. When resolving an identifier |x|
on an img object, img.x, the |x| property would be not be resolved on
Element.prototype. Instead, it would more likely be found in
HTMLImageElement.prototype, or on the object itself. The |x| property
might be implemented as a getter or it might be implemented as a property.

Node
|
Element {x:Function(user-def} EventTarget
| |
HTMLElement {style::ElementCSSInlineStyle}
|
HTMLImageElement { getter x::uint }
|
img

If HTMLImageElement has an |x| property, then Element.prototype.x would
be resolved to the |x| property on HTMLImageElement, not to the one you
added.

There is not any |x| property defined by current w3c HTML dom
specifications for HTMLImageElement. Implementations cannot be expected
to define no extra properties. In fact, they do often do define other
properties. Nor can they be expected to not shadow properties, nor can
they be expected to define the properties as readonly, dontdelete. I
think it would be a bad idea to assume that implementations always map
DOM readonly to ES {ReadOnly) (and not implement that property as a
getter).

A method that accepts an element should be able to safely access the
element's properties withouth resolving user-defined property on a Host
object's prototype.

Garrett

Thomas 'PointedEars' Lahn

unread,
Jan 2, 2009, 5:08:27 PM1/2/09
to
dhtml wrote:
> Thomas 'PointedEars' Lahn wrote:
>> dhtml wrote:
>>> Thomas 'PointedEars' Lahn wrote:
>>>> David Mark wrote:
>>>>> dhtml wrote:
>>>>>> David Mark wrote:
>>>>>>> MooTools: An Objective Look
>> I was not arguing about the (doubtful) code quality of MooTools here but
>> about the -- I think -- inappropriate *general* criticism of some of the
>> design patterns it employs.
>
> What design patterns in Mootools were criticized?

I am not here to reiterate this discussion for you.

>>> It seems more likely (to me) that Mozilla exposed the XPConnect
>>> wrapped
>>> prototypes so that developers could write quick patches.
>> Now that does not make sense to me at all. Patches to the C++ or Java
>> source code of Mozilla can be easily written without the Gecko DOM
>> exposing host object's prototypes through ECMAScript binding. Are you
>> sure you know what you are talking about?
>
> Take the pageX/Y properties. Problems in Firefox were that it did not
> include scroll. An experimental monkey patch:-
>
> MouseEvent.prototype.__defineGetter__('pageX', function() {
> return this.clientX + window.pageXOffset;
> });
> MouseEvent.prototype.__defineGetter__('pageY', function() {
> return this.clientY + window.pageYOffset;
> });
>
> If the monkey patch worked, it could be later incorporated into a real
> patch.

Nobody in their right mind would write or test *Gecko* patches like so.
You will have to come up with something more convincing.

>>> It is less clear which methods are native and which are user add-ons.
>> Really? I think the enumerable ones are user-defined and vice-versa
>> (CMIIW, I can't test right now).
>
> Many DOM properties have a |readonly| flag. This flag can map to
> ECMAScript {ReadOnly} attribute. However, there is nothing that maps to
> ECMAScript {DontEnum} attribute. This is not defined for any dom
> objects,

That might sound highly sophisticated to some, but is utter nonsense altogether.

The ECMAScript `ReadOnly' attribute of properties applies for native objects
only because only those objects MUST implement the internal [[Put]] method
as specified where [[CanPut]] is called and the ReadOnly property becomes
relevant in the first place. In fact, it can be readily observed that
assigning to a property which is "readonly" per the IDL or the
implementation, reverts back in some implementations to its previous value
instead of just not being modified, and that the assignment can result in a
runtime error, which is also not specified at all in ECMAScript. (We have
discussed this ad nauseam here.)

The ECMAScript `DontEnum' attribute of properties does not apply to
properties of host objects per Specification, however it can be readily
observed that some properties of host objects do not occur in a for..in
iteration. (We have discussed this ad nauseam here as well.)

> and so it is entirely dependent on the implementation.

We have a property of a host object here that is deliberately exposed by the
implementor, and it refers to a native object. It provides an efficient
means to add new default properties and new methods to a certain class of
related host objects. Not to use it and use another, less efficient
approach instead, is foolish.

> The Host object might have a property with the same name hidden away
> somewhere else on the object or its prototype chain. It might have a
> getter defined on that object itself.

It would not, else the object the property refers to would either be made
non-augmentable (which is possible with host objects only) or the property
would not be publicly exposed by the implementation at all.

> If('

Pardon?

>>> It
>> has the effect of creating a big ball of mud.
>>
>> That is not an argument.
>
> The design issue...

Pardon?

> I don't have costly iteration in my scripts and I never augment
> Element.prototype. It is a solution to a problem that does not exist.

To a problem that *you* do not have. At least one OP had this problem
already, and I can imagine situations where this feature comes in handy.

> "Big ball of mud" is packaging of everything together. ["snipped ball of
> mud" "explanation"]

Sounds like a big ball of mud altogether.

> I see no good reason why not to make use of such a useful DOM
>> feature if it is available. (In fact, I think it has the capacity to
>> become a DOM standard.)
>

> It is becoming a DOM standard (WEB IDL). [...]

URL?

>>> You have provided no evidence that modifying a host object prototype
>>> would be more efficient than creating a static method and passing an
>>> element to that method.
>> An element object reference, and the greater efficiency in this case
>> would seem to be self-evident.
>>
>>> I'm inclined to think that the lookup of that
>>> method would be less efficient, as the method property name would have
>>>
>>> to be found on the prototype chain of the object (if it is not
>>> shadowed).
>> As always, the bargain is runtime efficiency vs. memory efficiency.
>
> Comparing:-
>
> // 1.
> Element.prototype.getX = function() { };
> // 2.
> function getX(el) { }
>
> Where is the memory efficiency in #1?

If getX() is empty, none.

> Function getX (2) would not have to be resolved off the host object's
> prototype chain.

True, but if getX() was not empty, you would need to pass the element as an
argument, check the argument type, determine which class of element object
was being referred to with the passed value aso.

> Element.prototype.getX would have to be resolved up the prototype chain.

We have discussed the efficiency of the prototype chain already.
The prototype chain in this particular case could not be shorter:

Element instance --> Element.prototype --> Node.prototype
--> Object.prototype --> null

The expected loss in runtime efficiency by using it is thus negligible.
That said, this is a border case. One would seldom want to augment
Element.prototype.

>>>> The problem (or as you put it, the madness) begins when one assumes
>>>> that because a prototype object is provided by one DOM API (e.g., the
>>>> Gecko DOM) it must also be provided by another, and if not already
>>>> there to try making it so. Because the former would be object
>>>> inference, and the latter would be host object augmentation; as
>>>> discussed already, both must be considered error-prone.
>>>
>>> Yes, modifying host objects' prototypes is error-prone.
>> No, it isn't. Prototype objects are native objects.
>
> Given a host object Element, Element.prototype does not have to be a
> native object.

True, but it is a native object in the relevant implementations.

> Consider a case of a hypothetical user-defined property |x| on
> Element.prototype, Element.prototype.x. When resolving an identifier |x|
> on an img object, img.x, the |x| property would be not be resolved on
> Element.prototype. Instead, it would more likely be found in
> HTMLImageElement.prototype, or on the object itself. The |x| property
> might be implemented as a getter or it might be implemented as a property.
>
> Node
> |
> Element {x:Function(user-def} EventTarget
> | |
> HTMLElement {style::ElementCSSInlineStyle}
> |
> HTMLImageElement { getter x::uint }
> |
> img
>

> [...]

You are constantly ignoring the fact that e.g. HTMLImageElement.prototype
could be augmented as well, and the benefit that could bring. You must do
so because otherwise you would hurt the pointless argument which says that
using host object's prototypes is a bad idea per se.


PointedEars

dhtml

unread,
Jan 2, 2009, 10:07:00 PM1/2/09
to
Thomas 'PointedEars' Lahn wrote:
> dhtml wrote:
>> Thomas 'PointedEars' Lahn wrote:
>>> dhtml wrote:
>>>> Thomas 'PointedEars' Lahn wrote:
>>>>> David Mark wrote:
>>>>>> dhtml wrote:
>>>>>>> David Mark wrote:
>>>>>>>> MooTools: An Objective Look
>>> I was not arguing about the (doubtful) code quality of MooTools here but
>>> about the -- I think -- inappropriate *general* criticism of some of the
>>> design patterns it employs.
>> What design patterns in Mootools were criticized?
>
> I am not here to reiterate this discussion for you.
>

Discussion of design patterns did not occur, at least not on this
thread. (or you have a different interpretation of what was discussed,
or a different definition of 'design pattern').

It isn't clear what you mean by 'criticism of design patterns'. So I
asked, and, you wanted to play a silly game.

I'm done with having a discussion with you. It is neither entertaining
nor educational.

Andrew Poulos

unread,
Jan 3, 2009, 1:00:53 AM1/3/09
to
dhtml wrote:
> Thomas 'PointedEars' Lahn wrote:
>> dhtml wrote:
>>> Thomas 'PointedEars' Lahn wrote:
>>>> dhtml wrote:
>>>>> Thomas 'PointedEars' Lahn wrote:
>>>>>> David Mark wrote:
>>>>>>> dhtml wrote:
>>>>>>>> David Mark wrote:
>>>>>>>>> MooTools: An Objective Look
>>>> I was not arguing about the (doubtful) code quality of MooTools here
>>>> but sbout the -- I think -- inappropriate *general* criticism of
>>>> some of the design patterns it employs.
>>> What design patterns in Mootools were criticised?

>>
>> I am not here to reiterate this discussion for you.
>
> Discussion of design patterns did not occur, at least not on this
> thread. (or you have a different interpretation of what was discussed,
> or a different definition of 'design pattern').
>
> It isn't clear what you mean by 'criticism of design patterns'. So I
> asked, and, you wanted to play a silly game.
>
> I'm done with having a discussion with you. It is neither entertaining
> nor educational.

PointedEars replied with many other, in my opinion, valid points but you
have snipped them (chosen to ignore them). Why is that? I was hoping to
learn about more about MooTools.

Andrew Poulos

Thomas 'PointedEars' Lahn

unread,
Jan 3, 2009, 4:17:30 AM1/3/09
to
dhtml wrote:
> Thomas 'PointedEars' Lahn wrote:
>> dhtml wrote:
>>> Thomas 'PointedEars' Lahn wrote:
>>>> dhtml wrote:
>>>>> Thomas 'PointedEars' Lahn wrote:
>>>>>> David Mark wrote:
>>>>>>> dhtml wrote:
>>>>>>>> David Mark wrote:
>>>>>>>>> MooTools: An Objective Look
>>>> I was not arguing about the (doubtful) code quality of MooTools here but
>>>> about the -- I think -- inappropriate *general* criticism of some of the
>>>> design patterns it employs.
>>> What design patterns in Mootools were criticized?
>> I am not here to reiterate this discussion for you.
>
> Discussion of design patterns did not occur, at least not on this
> thread. (or you have a different interpretation of what was discussed,
> or a different definition of 'design pattern').
>
> It isn't clear what you mean by 'criticism of design patterns'. So I
> asked, and, you wanted to play a silly game.

Replacing built-in methods and augmentation of prototype objects of host
objects were the design patterns I have been commenting on in this thread,
the latter quite at length, as you could have noticed.

> I'm done with having a discussion with you. It is neither entertaining
> nor educational.

If one chooses to be completely ignorant about the points raised in favor of
using one of the aforementioned design patterns, that is the impression one
must get.


PointedEars

dhtml

unread,
Jan 3, 2009, 7:50:27 AM1/3/09
to
Thomas 'PointedEars' Lahn wrote:
> dhtml wrote:
>> Thomas 'PointedEars' Lahn wrote:
>>> dhtml wrote:
>>>> Thomas 'PointedEars' Lahn wrote:
>>>>> dhtml wrote:
>>>>>> Thomas 'PointedEars' Lahn wrote:
>>>>>>> David Mark wrote:
>>>>>>>> dhtml wrote:
>>>>>>>>> David Mark wrote:
>>>>>>>>>> MooTools: An Objective Look
>>>>> I was not arguing about the (doubtful) code quality of MooTools here but
>>>>> about the -- I think -- inappropriate *general* criticism of some of the
>>>>> design patterns it employs.
>>>> What design patterns in Mootools were criticized?
>>> I am not here to reiterate this discussion for you.
>> Discussion of design patterns did not occur, at least not on this
>> thread. (or you have a different interpretation of what was discussed,
>> or a different definition of 'design pattern').
>>
>> It isn't clear what you mean by 'criticism of design patterns'. So I
>> asked, and, you wanted to play a silly game.
>
> Replacing built-in methods and augmentation of prototype objects of host
> objects were the design patterns I have been commenting on in this thread,
> the latter quite at length, as you could have noticed.
>

I did notice that.

It sounds like you are naming of two new patterns:
'replacing built-in methods'
'augmentation of prototype objects of host objects'

Are those your design patterns?

Those are more like javascript programming techniques. There may be
not-yet-defined design patterns (possibly structural), but they have not
yet been identified.

A design pattern is a reusable solution to a problem in a context.

Thomas 'PointedEars' Lahn

unread,
Jan 3, 2009, 8:01:24 AM1/3/09
to

I beg your pardon -- "*it* *sounds* *like*"?

> Are those your design patterns?

Are you able to read?

> Those are more like javascript programming techniques. There may be
> not-yet-defined design patterns (possibly structural), but they have not
> yet been identified.
>
> A design pattern is a reusable solution to a problem in a context.

And these "programming techniques" are not such solutions? Think again.
The meaning of the term "design pattern" is not limited to those named by
the Group of Four.


PointedEars

Thomas 'PointedEars' Lahn

unread,
Jan 3, 2009, 8:05:43 AM1/3/09
to

I beg your pardon -- "*it* *sounds* *like*"?

> Are those your design patterns?

Are you able to read?

> Those are more like javascript programming techniques. There may be

> not-yet-defined design patterns (possibly structural), but they have not
> yet been identified.
>
> A design pattern is a reusable solution to a problem in a context.

And these "programming techniques" are not such solutions? Think again.
JFYI, the meaning of the term "design pattern" is not limited to those named
by the Gang of Four.


PointedEars

dhtml

unread,
Jan 4, 2009, 1:04:30 AM1/4/09
to

You're not making yourself clear enough. Are these the names of your
patterns:-

'replacing built-in methods'
'augmentation of prototype objects of host objects'

- or it something else?

I've never heard talk of those as patterns.

To me, I see this coding construct as an AOP cross cut alternative to a
Decorator (structural).

>> Are those your design patterns?
>
> Are you able to read?
>
>> Those are more like javascript programming techniques. There may be
>> not-yet-defined design patterns (possibly structural), but they have not
>> yet been identified.
>>
>> A design pattern is a reusable solution to a problem in a context.
>
> And these "programming techniques" are not such solutions? Think again.
> JFYI, the meaning of the term "design pattern" is not limited to those named

A common pattern has a name. This allows the pattern to communicated
with other developers.

What is the intent of the pattern (what problem is it supposed to solve?)

What is the motivation (scenario of a problem that can be solved by the
pattern)?

What is the applicability (context where this pattern can be used)?

For example, a partially filled-in template:-

Name:
Modify Base [Prototype] (Structural)

Intent:
The host object lacks a certain behavior that is needed.

Motivation/Scenario:
[...]

Structure:
SomeObjectPrototype -> newProperty
|
[...]
|
SomeObjectInstance

Applicability:
Use when desired to have that behavior on all objects of that type.

Collaboration:

Implementation:

Consequences:

Related Patterns:
Decorator

The "motivation/scenario" is crucial.

An OO Design Pattern should follow basic OO principles like programming
to an interface, not an implementation; encapsulating the parts that
vary; and favoring object composition over class inheritance.

Modifying the Foreign [Host] Object's Prototype is the exact opposite.
It relies on inheritance, does not use composition. It favors modifying
the implementation (not programming to an interface). The foreign object
doesn't do what is desired, so try to force it to. It does this at the
risk of the Host object allowing the modification and not shadowing the
property, in all environments, for all versions, and versions in the
future.

A pattern's usage is dictated by goals and constraints. So if this is a
pattern, we could look at the goals, usage, and constraints in Mootools.
From the homepage: "Mootools allows you to write powerful, flexible,
and cross-browser code". The pattern (if it is to called a pattern)
doesn't work in IE. It wouldn't seem to be a good choice for
"cross-browser code". So if the goal is to allow developers to write
"cross-browser code", and this is a pattern, then it seems
misappropriated for the goal.

The intent is nearly identical to a Decorator. This code technique (your
pattern) might be considered an AOP crosscut, but then the concern would
have to be identified. It would be hard to identify modular concerns
based on anything in the code or code comments. Let's take a look...

Mootools has a document.head. The document.head points to the head
element of the html document that the script is loaded in. Like other
elements, Mootools gives document.head the following methods (I kid you
not, these are the actual names): destroy, dispose, eliminate, erase,
grabBottom... -- sounds very heavy metal -- up until the "grabBottom"
method. Then there is toQueryString. Funny names, but what concern are
they related to? It doesn't seem very modular. It looks like a case of
"frameworkitis"[1].

Garrett

[1]http://www.artima.com/lejava/articles/reuse3.html

Thomas 'PointedEars' Lahn

unread,
Jan 4, 2009, 8:27:37 AM1/4/09
to
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

>>>> host objects were the design patterns I have been commenting on in this
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

>>>> thread, the latter quite at length, as you could have noticed.
>>> I did notice that.
>>>
>>> It sounds like you are naming of two new patterns: 'replacing built-in
>>> methods' 'augmentation of prototype objects of host objects'
>> I beg your pardon -- "*it* *sounds* *like*"?
>
> You're not making yourself clear enough. Are these the names of your
> patterns:- [...]

I have already said what I regarded as the design patterns I referred to.
That you are obviously unable to read is your problem alone.

> 'replacing built-in methods'
> 'augmentation of prototype objects of host objects'
>
> - or it something else?

No.

> I've never heard talk of those as patterns.

Your problem.

>>> Are those your design patterns?
>> Are you able to read?

Obviously not. Question retracted.

>>> Those are more like javascript programming techniques. There may be
>>> not-yet-defined design patterns (possibly structural), but they have not
>>> yet been identified.
>>>
>>> A design pattern is a reusable solution to a problem in a context.
>> And these "programming techniques" are not such solutions? Think again.
>> JFYI, the meaning of the term "design pattern" is not limited to those named
>
> A common pattern has a name. This allows the pattern to communicated
> with other developers.

I gave it a name.

> What is the intent of the pattern (what problem is it supposed to solve?)
>
> What is the motivation (scenario of a problem that can be solved by the
> pattern)?
>
> What is the applicability (context where this pattern can be used)?
>
> For example, a partially filled-in template:-

> [...]

See, you *almost* got it. In time, you might actually get it.


PointedEars

dhtml

unread,
Jan 4, 2009, 11:17:34 AM1/4/09
to

I am helping to argue the case that what you were describing might be
patterns. I gave a pattern template to fill in, described how to fill it
in, and filled in a few parts myself.

You have confirmed now that the two descriptions of javascript
techniques are the respective names for your patterns.

The template I provided remains to be filled out.

I suggest you start working on the template.

Garrett

dhtml

unread,
Jan 7, 2009, 11:40:55 PM1/7/09
to

Because when I ask:
| What design patterns in Mootools were criticized?

I get the reply:


| I am not here to reiterate this discussion for you.

PointedEars was the first to mention the term 'design patterns' in this
thread. I asked him to be specific; his reply does not answer, yet seems
to show what appears to be a superior attitude.

Another Ears quote:


| That might sound highly sophisticated to some, but
| is utter nonsense altogether.

Ears will say that something 'doesn't make sense' or is 'utter nonsense'
when he does not understand it himself. You'll never hear him say, for
example, "I'm not sure what you mean by that."

And if you back up to see what he responded to, I wrote:-

| Many DOM properties have a |readonly| flag. This flag can map to
| ECMAScript {ReadOnly} attribute. However, there is nothing that maps
| to ECMAScript {DontEnum} attribute. This is not defined for any dom

| objects.

We can see in a DOM spec, take DOM 2, for example, that the Node
interface, among others, has a |readonly| "nodeName" property[1].

http://www.w3.org/TR/DOM-Level-2-Core/idl-definitions.html#idl-dom.idl

In a nutshell:
1) an OMG IDL "readonly" property maps to a "get" style operation.
2) a get-style operation might vary between implementations
3) This would fail differently depending on the implementation.

Example:
A user-defined property is added to HTMLElement.prototype. That
user-defined property has the same name as a |readonly| property on the
Element interface. If and how it would fail is not defined. If the
implementation mapped DOM |readonly| to a JavaScriptTM getter, then an
error would result. However, an implementation that mapped DOM
|readonly| to ECMA {ReadOnly}, the result would be silent failure.

I'll try discussing again.

dhtml

unread,
Jan 8, 2009, 1:47:20 AM1/8/09
to
Thomas 'PointedEars' Lahn wrote:
> dhtml wrote:
>> Thomas 'PointedEars' Lahn wrote:
>>> dhtml wrote:
>>>> Thomas 'PointedEars' Lahn wrote:
>>>>> David Mark wrote:
>>>>>> dhtml wrote:
>>>>>>> David Mark wrote:
>>>>>>>> MooTools: An Objective Look

>>>> I'm inclined to think that the lookup of that

>>>> method would be less efficient, as the method property name would have
>>>>
>>>> to be found on the prototype chain of the object (if it is not
>>>> shadowed).
>>> As always, the bargain is runtime efficiency vs. memory efficiency.
>> Comparing:-
>>
>> // 1.
>> Element.prototype.getX = function() { };
>> // 2.
>> function getX(el) { }
>>
>> Where is the memory efficiency in #1?
>
> If getX() is empty, none.
>
>> Function getX (2) would not have to be resolved off the host object's
>> prototype chain.
>
> True, but if getX() was not empty, you would need to pass the element as an
> argument, check the argument type, determine which class of element object
> was being referred to with the passed value aso.
>

I'm not sure what you mean by 'class'.

The getX method would only have to concern itself with getting some sort
of x value of the object, as in:-

function getX(ob) {
if('x' in ob) {
return ob.x;
} else if('xx' in ob) {
return ob.xx;
}
}

It might be a consideration for the example to check |typeof ob ==
"undefined"|, and handle accordingly.

However, that is a contrived example.

Lets see _real_ example of how Mootools modifies Host object prototypes
(your "design pattern"). Here is Mootools' Event (Mootools calls Event a
"native", and replaces window.Event).

From Event.initialize:-

if (event.$extended) return event;
this.$extended = true;

That way, when handling of events is desired, the user (of this API),
can use:-

new Event(ev)

- and expect to get back an object with Mootools Event modifications.

This uses the same approach of PrototypeJS. If the element is not
"$extended", it will be augmented in "$extend()":-

function $extend(original, extended){
for (var key in (extended || {})) original[key] = extended[key];
return original;
};

The intent seems to be to provide a common interface to an object (not a
bad goal). To accomplish this Mootools passes an object that is designed
to modify the Host object to the Native constructor function.

An event could be:-
* a w3c dom Event
* a w3c dom Event w/a modified prototype
* an IE dom Event
* a modified IE dom Event

It does not appear to add clarity to the program. It may introduce
ambiguity of a library modified [IE] dom event.

Instead of trying to know what type of object it is, the alternative is
to take advantage of ducktyping.

For example:-

| function preventDefault(ev) {
| ev = ev || event;
| if(typeof ev.preventDefault == "function") {
| ev.preventDefault();
| } else if('returnValue' in ev) {
| ev.returnValue = false;
| }
| }

accomplishes the task of preventing the default action of an event. It
isn't necessary to know what interfaces are involved.

>> Element.prototype.getX would have to be resolved up the prototype chain.
>
> We have discussed the efficiency of the prototype chain already.
> The prototype chain in this particular case could not be shorter:
>
> Element instance --> Element.prototype --> Node.prototype
> --> Object.prototype --> null
>

How do you know that would be the prototype chain? Where is the
prototype chain for a Host DOM object defined? The resolution of a
|getX| method off an form element might be closer to:-

elementInstance --> HTMLFormElement.prototype --> HTMLElement.prototype
--> Element.prototype

However, the [[Get]] operation would probably involve a check to see if
the form has a control named "getX". Completely nonstandard, but
browsers do have to resolve things like |formElement.controlName|, as
many webpages still use that.

> The expected loss in runtime efficiency by using it is thus negligible.
> That said, this is a border case. One would seldom want to augment
> Element.prototype.
>

The use of Mootools' Event stop

To work in IE, there would be required call to

| new Event(ev).stop().

In a hypothetical "utopia" where all browsers supported your "design
pattern", the code could use:-

| ev.stop()

which would not be more efficient than

| preventDefault(ev)
| stopPropagation(ev)

.

>> Consider a case of a hypothetical user-defined property |x| on
>> Element.prototype, Element.prototype.x. When resolving an identifier |x|
>> on an img object, img.x, the |x| property would be not be resolved on
>> Element.prototype. Instead, it would more likely be found in
>> HTMLImageElement.prototype, or on the object itself. The |x| property
>> might be implemented as a getter or it might be implemented as a property.
>>
>> Node
>> |
>> Element {x:Function(user-def} EventTarget
>> | |
>> HTMLElement {style::ElementCSSInlineStyle}
>> |
>> HTMLImageElement { getter x::uint }
>> |
>> img
>>
>> [...]
>
> You are constantly ignoring the fact that e.g. HTMLImageElement.prototype
> could be augmented as well, and the benefit that could bring. You must do
> so because otherwise you would hurt the pointless argument which says that
> using host object's prototypes is a bad idea per se.
>

The point of the example is that the user-defined property would be
shadowed by something on HTMLImageElement interface.

If the desire were to modify the HTMLImageElementInterface by adding an
|x| property, that would fail in error:-

HTMLImageElement.prototype.x = 1;
TypeError: setting a property that has only a getter

Even if setting HTMLImageElement.prototype "worked", the strategy could
fail for other reasons:

1) could conflict with other objects in the prototype chain that the
Host environment introduced, that have the same name
2) Special lookups (special [[Get]]).
3) New interfaces/methods added for future implementations of the same
interface.

Other programmers seem to have similar sentiments. See LoD[1][2].

Garrett

[1]http://en.wikipedia.org/wiki/Law_of_Demeter
[2]http://c2.com/cgi/wiki?LawOfDemeter

Just for fun: http://perldesignpatterns.com/?ObjectOrgy

kangax

unread,
Jan 8, 2009, 8:42:10 AM1/8/09
to
dhtml wrote:

[...]

>>> Element.prototype.getX would have to be resolved up the prototype chain.
>>
>> We have discussed the efficiency of the prototype chain already.
>> The prototype chain in this particular case could not be shorter:
>>
>> Element instance --> Element.prototype --> Node.prototype
>> --> Object.prototype --> null
>>
>
> How do you know that would be the prototype chain? Where is the
> prototype chain for a Host DOM object defined? The resolution of a
> |getX| method off an form element might be closer to:-
>
> elementInstance --> HTMLFormElement.prototype --> HTMLElement.prototype
> --> Element.prototype

Yes, at least in browsers with `__proto__` support, checking this is
trivial. E.g., In FF3.0.5/Mac OS X 10.5 a prototype chain of an instance
of `HTMLFormElement` looks like:

elementInstance -> HTMLFormElement.prototype -> HTMLElement.prototype ->
Element.prototype -> Node.prototype -> Object.prototype

This is, of course, easy to check by executing the following expressions
(which are all `true`):

document.createElement('form').__proto__ === HTMLFormElement.prototype;
HTMLFormElement.prototype.__proto__ === HTMLElement.prototype;
HTMLElement.prototype.__proto__ === Element.prototype;
Element.prototype.__proto__ === Node.prototype;
Node.prototype.__proto__ === Object.prototype;

[...]

--
kangax

0 new messages