From: Garrett Smith on
David Mark wrote:
> Jorge wrote:
>> On Feb 27, 11:52 pm, Garrett Smith <dhtmlkitc...(a)gmail.com> wrote:
>>> (...)
>>> I hold copyright to my counterproposal, which has been published on this
>>> NG. (...)
>> Jeez, what a douchebag.
>>
>
> LOL. Internet tough-guy, huh? Not to mention freeloader. Perhaps you
> think intellectual property is an antiquated notion? I know that other
> have-nots share that view and it is obvious why that is the case. You
> just can't have everything handed to you for free, Internet or no Internet.
>
> Get better Jorge!
I would have shared the idea with the w3c, but they don't want it. On
the topic of "Touch and Gesture Events" Kari Hitola posted some wrong
information. He made statements that were false or incorrect. The
statements that were /provably/ false I provided one test case and a
link (to correct information). For other statements, IIRC, I questioned
him, but then got a notice that my "posting privilege had been suspended
for two weeks." All of my posts have been blocked since then. I have
tried to post even this month, IIRC. I can post to neither
public-script-coord, nor www-dom, nor public-webapps. I can still post
to www-style. I can't figure the rationale for picking those three
lists, so I can only assume it was blind anger and stupidity and they
overlooked www-style.

I stand by what I wrote and do not apologize for it. To the best of my
ability, I will continue question what I believe to be a misguided API
design.

The reason for Kari Hitola's posting, AISI, was to justify Nokia's copy
of Apple's API, post hoc.

If the w3c wants to block out my ideas from their lists, that's their
loss. I believe my idea is good and simple.

Those same W3C individuals might like the idea if they wrote it
themselves. They may do just that, but the idea is so simple that they
will probably expand on it and make it larger and more complicated.
--
Garrett
comp.lang.javascript FAQ: http://jibbering.com/faq/
From: Peter Michaux on
On Feb 27, 11:28 pm, David Mark <dmark.cins...(a)gmail.com> wrote:

> Dojo just installed a moderator on their new jQuery-powered forum,

What?!

Peter
From: David Mark on
Peter Michaux wrote:
> On Feb 27, 11:28 pm, David Mark <dmark.cins...(a)gmail.com> wrote:
>
>> Dojo just installed a moderator on their new jQuery-powered forum,
>
> What?!
>
That's not a misprint. The documentation pages have jQuery 1.2x as
well. Yeah, I know. Their Web developers just like gettin' stuff done,
even when it is obviously destroying whatever shred of credibility they
have left. I can't explain it. I'm tired of thinking about as it gives
me headaches. :(
From: Scott Sauyet on
David Mark wrote:
> Scott Sauyet wrote:
>> For instance, this is certainly fine for me:
?>
>>     API.roundCorners(myDiv);
>>
>> And this is overkill:
>>
>>     if (API.roundCorners) {
>>         API.roundCorners(myDiv);
>>     }
>
> No, you do _not_ do it that way.  You do a one-time check at the start
> for required methods.

Do you centralize all code that might need rounded corners, then? If
so, how do you deal with dynamic changes to the DOM? Or do you store
a variable with the result of API,roundCorners? If it's that, how
much savings do you really get?


>> And while there are times I might appreciate this flexibility:
>>
>>     if (API.myCoolFade) {
>>         API.myCoolFade(myDiv);
>>     } else {
>>         myDiv.style.display = 'none';
>>     }
>
>> It's also pretty nice to be able to do this:
>>
>>     API.myCoolFade(myDiv)
>
> Not at all nice when it blows up or fails silently.  ;)

Of course, but my whole post was about ways to make a static API
available that doesn't blow up or fail silently even in the absence of
features we would like.


>> and know that the library is internally checking API.canSetOpacity and
>> whatever other flags it needs, then defaulting to its own
>> "style.display = 'none'" branch if the effects are not available.
>
> Too much bloat and inefficiency in the internal code.

Unless I actually can note performance issues, I'm much more concerned
with clean APIs that are as easy to use as possible than I am about
bloat in the library code.

But if performance is a concern, this can be done efficiently. It can
still be an up-front check:

API.myCoolFade = (API.opacitySupported)
? function(elt) {
// cool opacity animation here.
}
: function(elt) {
if (elt) elt.style.display = 'none';
}


>> I know that such a technique is less flexible.  For instance, I
>> couldn't choose to do this:
>> <snip>
>> but I'm often willing to sacrifice such flexibility for the simplicity
>> of the static API.
>
> But a static API can't abstract a an unknown environment in any sort of
> efficient and flexible manner.

I certainly agree that a dynamic API can be more flexible; that's
practically tautological. I'm not sure I agree about the efficiency
question. To me the main question is whether the behavior of the
static API can degrade in a reasonable manner in environment that
don't support its full functionality.


>> One technique I've used on several occasions in my own mini-library
>> code is to add "supported" properties to API functions, which return
>> values "complete", "degrade", "empty", or false, depending upon
>> whether the function is completely supported, degrades acceptably,
>> returns empty objects or arrays, or is totally unsupported, with code
>> something like this:
>
> Okay, but I don't see why you would need more than a boolean (e.g. works
> or not).

I've done that.too. It works fine. The trouble is then if there is a
simpler supported version of the functionality with fewer bells and
whistles that I can fall back on. It's nice to have the super-cool
fade fall back on a simple hide in the absence of the necessary
environmental features. Then I simply don't have to think about it
usually.


>>     API.myCoolFade = API._support((function() {
>>         if (API.opacitySupported) return "complete";
>>         return "degrade";
>>     )(), function(elt) {
>>         if (API.opacitySupported) {
>>             // cool opacity animation here.
>>         } else {
>>             if (elt) elt.style.display = 'none';
>>         }
>>     });
>
> See what I mean about bloat?  Imagine an API with thousands of methods
> doing something like this for each one.  It wouldn't be feasible on the Web.

Well an API with thousands of methods would scare me much more than
this code. Even jQuery's large API has fewer than 250 methods in it.


>> It has worked for me, but I haven't had to use it much, because it's
>> never been for large public APIs.  It was exactly this sort of pseudo-
>> fade that motivated it, though, and it worked well enough there.  For
>> API methods that returned arrays of nodes, usually there is complete
>> support across browsers, but when there isn't, the "supported"
>> property tells me that the function will at least return me an array I
>> could continue to process, even if it's empty, which often simplified
>> further coding.
>
> Yes, for a small Intranet app, you could certainly get by with the above
> (depending on its performance requirements of course).

Why don't you think this would scale to the multiple environments of
the Internet?


>> In any case, I've never tried to code in the dynamic API style for
>> library code.  Are there good examples of libraries that do it?  I
>> understand My Library does; are there other publicly available
>> examples?
>
> Not that I know of.  :)

So it looks like you have some selling to do! :-)

-- Scott
From: David Mark on
Scott Sauyet wrote:
> David Mark wrote:
>> Scott Sauyet wrote:
>>> For instance, this is certainly fine for me:
> ?>
>>> API.roundCorners(myDiv);
>>>
>>> And this is overkill:
>>>
>>> if (API.roundCorners) {
>>> API.roundCorners(myDiv);
>>> }
>> No, you do _not_ do it that way. You do a one-time check at the start
>> for required methods.
>
> Do you centralize all code that might need rounded corners, then?

I don't think this is a good example feature as it is hard to imagine
code that hinges on rounded-corners. But yes, depending on the
complexity of the applications, you may need to break it up into
sections and use a different gateway for each section.

> If
> so, how do you deal with dynamic changes to the DOM? Or do you store
> a variable with the result of API,roundCorners? If it's that, how
> much savings do you really get?

I don't follow. The gateways prevent entry to sections that would rely
on that feature.

>
>
>>> And while there are times I might appreciate this flexibility:
>>>
>>> if (API.myCoolFade) {
>>> API.myCoolFade(myDiv);
>>> } else {
>>> myDiv.style.display = 'none';
>>> }
>>> It's also pretty nice to be able to do this:
>>>
>>> API.myCoolFade(myDiv)
>> Not at all nice when it blows up or fails silently. ;)
>
> Of course, but my whole post was about ways to make a static API
> available that doesn't blow up or fail silently even in the absence of
> features we would like.

Well, you can't really abstract a random environment with a static API
unless you are willing to allow some functions to fail silently (which
can work in some cases).

>
>
>>> and know that the library is internally checking API.canSetOpacity and
>>> whatever other flags it needs, then defaulting to its own
>>> "style.display = 'none'" branch if the effects are not available.
>> Too much bloat and inefficiency in the internal code.
>
> Unless I actually can note performance issues, I'm much more concerned
> with clean APIs that are as easy to use as possible than I am about
> bloat in the library code.

You can't get much cleaner than the method I describe. If the feature
is there, it is expected to work (and vice-versa), so all you have to do
is write an appropriate gateway (or gateways) for your app. As for the
API itself, the described technique lends itself well to one-off method
function creation, which leads to a clean and efficient set of methods.

>
> But if performance is a concern, this can be done efficiently. It can
> still be an up-front check:
>
> API.myCoolFade = (API.opacitySupported)
> ? function(elt) {
> // cool opacity animation here.
> }
> : function(elt) {
> if (elt) elt.style.display = 'none';
> }

But now you have an extraneous flag for each dynamically created
function. Why not just use the functions themselves as the flags? Then
there is nothing to get out of sync.

>
>
>>> I know that such a technique is less flexible. For instance, I
>>> couldn't choose to do this:
>>> <snip>
>>> but I'm often willing to sacrifice such flexibility for the simplicity
>>> of the static API.
>> But a static API can't abstract a an unknown environment in any sort of
>> efficient and flexible manner.
>
> I certainly agree that a dynamic API can be more flexible; that's
> practically tautological. I'm not sure I agree about the efficiency
> question. To me the main question is whether the behavior of the
> static API can degrade in a reasonable manner in environment that
> don't support its full functionality.

It is more efficient because neither the app nor the API functions have
to continually check for features or waste time calling code that falls
through silently.

>
>
>>> One technique I've used on several occasions in my own mini-library
>>> code is to add "supported" properties to API functions, which return
>>> values "complete", "degrade", "empty", or false, depending upon
>>> whether the function is completely supported, degrades acceptably,
>>> returns empty objects or arrays, or is totally unsupported, with code
>>> something like this:
>> Okay, but I don't see why you would need more than a boolean (e.g. works
>> or not).
>
> I've done that.too. It works fine. The trouble is then if there is a
> simpler supported version of the functionality with fewer bells and
> whistles that I can fall back on. It's nice to have the super-cool
> fade fall back on a simple hide in the absence of the necessary
> environmental features. Then I simply don't have to think about it
> usually.

Sure, do that at the application level. If the fade effect is there,
define a hide/show function that uses it. Otherwise use the stock
hide/show function.

if (API.effects && API.effects.fade) {
myCoolShowFunction = function() { ... };
} else {
myCoolShowFunction = API.showElement;
}

Note that this is a generic example. It is not specific (but is
similar) to My Library, which actually does something like this
internally. As a matter of fact, as it sits, My Library's show/hide
functionality is less than ideal as it actually does ignore effects
options on hide/show when effects are impossible. But when only
_specific_ effects are unavailable (e.g. fade), it is up to the
applications to avoid passing those effects functions in the options.
That's something I need to rearrange down the road. For now the
incongruity is simply documented. There actually is a flag on the
affected methods indicating whether the hide/show operation will be
immediate or progressive (the latter indicating that a callback can be
used). Affected methods include setElementHtml, changeImage, as well as
showElement and a few others that can optionally use effects and/or a
callback.

The effects stuff is a bad example though as effects in general will
virtually always be possible (all they need is CSS support and
setInterval). The fade effect may be unavailable in some ancient and/or
limited browsers, but that would be rare compared to something like XHR.
And it is hard to imagine an application that would actually _need_
effects at all, so other than checking for specific effects like fade,
it is fine for most applications to remain oblivious to their presence
or absence.

Of course, when using the OO interface, it is as simple as:-

var E;

if (E && E.prototype.fadeIn) {
// OO application that _must_ be able to fade in elements
}

>
>
>>> API.myCoolFade = API._support((function() {
>>> if (API.opacitySupported) return "complete";
>>> return "degrade";
>>> )(), function(elt) {
>>> if (API.opacitySupported) {
>>> // cool opacity animation here.
>>> } else {
>>> if (elt) elt.style.display = 'none';
>>> }
>>> });
>> See what I mean about bloat? Imagine an API with thousands of methods
>> doing something like this for each one. It wouldn't be feasible on the Web.
>
> Well an API with thousands of methods would scare me much more than
> this code. Even jQuery's large API has fewer than 250 methods in it.

Large is relative. jQuery isn't much more than a haphazard query engine
with a few basic (and broken) DOM wrappers thrown in. Where they are
starting to bloat is the ill-advised "Live" feature, which attempts to
bottle event delegation (again it is about marketing rather than
providing a sound API). Also, they combine getters and setters, which
reduces the number of methods, but makes application code virtually
unreadable (you must count the number of arguments passed to
differentiate between get and set operations).

>
>
>>> It has worked for me, but I haven't had to use it much, because it's
>>> never been for large public APIs. It was exactly this sort of pseudo-
>>> fade that motivated it, though, and it worked well enough there. For
>>> API methods that returned arrays of nodes, usually there is complete
>>> support across browsers, but when there isn't, the "supported"
>>> property tells me that the function will at least return me an array I
>>> could continue to process, even if it's empty, which often simplified
>>> further coding.
>> Yes, for a small Intranet app, you could certainly get by with the above
>> (depending on its performance requirements of course).
>
> Why don't you think this would scale to the multiple environments of
> the Internet?

In short, too many flag checks in the application code. Virtually
everything would require such checks as nothing is assured on the
Internet. It's much simpler (and more efficient) to detect methods of
the API up front and be done with it.

>
>
>>> In any case, I've never tried to code in the dynamic API style for
>>> library code. Are there good examples of libraries that do it? I
>>> understand My Library does; are there other publicly available
>>> examples?
>> Not that I know of. :)
>
> So it looks like you have some selling to do! :-)
>

You mean as far as examples of people using My Library. There are
several people building applications with it that I know of (and likely
many more that I don't know of), but it is only a couple of months in.
I think that if I continue to improve the documentation and wrap up the
last of the CSS3 selectors that everyone seems to expect these days, it
will sell itself. If something like jQuery can become wildly popular,
despite outrageous shortcomings and inefficiencies, I think it is only a
matter of time for mine to do the same.

I'm not much for selling though. As I've said repeatedly, the best bet
is to avoid general-purpose libraries altogether. But I suppose if you
are already sold on the strategy, mine has a lot of positives that
aren't found in any of the others (starting with the dynamic API and
ending with the support that I provide). Also, there is the fact that
none of the others can do much of anything without browser sniffing (in
one form or another). All but jQuery (which uses bad object inferences
and bogus feature testing) are still fixated on the UA string, which is
clearly a fatal flaw (and has been for a decade). They don't see it as
fatal as to them it is sane to swap out a huge script every time a new
browser comes out (and to ignore all that came before). But the
end-users won't buy (or even understand) that when their favorite sites
break (they'll just get new favorites).