Starting to Build a JavaScript Library

D

dhtml

Frustrated with every other Javascript framework, I have decided to
write something better.

I want a Javascript library that doesn't get in the way, is easily
extensible. Just some basic framework to build on for widgets.

The BAD things of other libraries:
* Weird "OOP"ish schemes
* oversimplified interface that does more things behind the scenes
* Kitchen Sink - too much bloat in the main library file; non-
cohesive.
* buggy, with superficial examples that they call "tests"
* non-modular design
* core library features are poor, inconsistent across browsers, and
buggy

And, to quote Brendan Eich:
Too many of the JS/DHTML toolkits have the "you must use our APIs for
everything, including how you manipulate strings" disease.

I know what I don't want.

Goals:
* Minimal Framework, mainly used for AOP and OOP functionality
* unit tested
* AOP Event System
* Namespacing
* Modularity, Cohesion, Packaging based on REP
* No browser detection

TBD:
* import() - dynamic script insertion? Dependency resolution?
* Building files to modules is easier to test, but feels weird

RIA development using javascript, I need widgets (Data Table, Rich
Editor). Widgets need: DOM adapter functions (style, position,
className), Event-based ajax (or "deferred" Async's), Form
serialization, Drag 'n Drop, Animation.
I
JavaScript lacks "import" and "extend" which are useful for widgets. I
use AOP cross cuts even more. I have not seen 1 library that gets
these things right. It is very important to get this part right.

The base component is APE.js ->
http://dhtmlkitchen.com/ape/src/APE.js

It is too early to be releasing the code, but I want to get some
feedback sooner rather than later. One pair of eyes on the code isn't
enough.

APE, by itself does nothing. I have some tests for what it does,
http://dhtmlkitchen.com/ape/test/tests/APE-test.html
 
T

timothytoe

Frustrated with every other Javascript framework, I have decided to
write something better.

I want a Javascript library that doesn't get in the way, is easily
extensible. Just some basic framework to build on for widgets.

The BAD things of other libraries:
* Weird "OOP"ish schemes
* oversimplified interface that does more things behind the scenes
* Kitchen Sink - too much bloat in the main library file; non-
cohesive.
* buggy, with superficial examples that they call "tests"
* non-modular design
* core library features are poor, inconsistent across browsers, and
buggy

And, to quote Brendan Eich:
Too many of the JS/DHTML toolkits have the "you must use our APIs for
everything, including how you manipulate strings" disease.

I know what I don't want.

Goals:
* Minimal Framework, mainly used for AOP and OOP functionality
* unit tested
* AOP Event System
* Namespacing
* Modularity, Cohesion, Packaging based on REP
* No browser detection

TBD:
* import() - dynamic script insertion? Dependency resolution?
* Building files to modules is easier to test, but feels weird

RIA development using javascript, I need widgets (Data Table, Rich
Editor). Widgets need: DOM adapter functions (style, position,
className), Event-based ajax (or "deferred" Async's), Form
serialization, Drag 'n Drop, Animation.
I
JavaScript lacks "import" and "extend" which are useful for widgets. I
use AOP cross cuts even more. I have not seen 1 library that gets
these things right. It is very important to get this part right.

The base component is APE.js ->http://dhtmlkitchen.com/ape/src/APE.js

It is too early to be releasing the code, but I want to get some
feedback sooner rather than later. One pair of eyes on the code isn't
enough.

APE, by itself does nothing. I have some tests for what it does,http://dhtmlkitchen.com/ape/test/tests/APE-test.html

It may be possible to improve the performance of your "extend" by
using Cornford's method in this thread:

http://groups.google.com/group/comp...5e864536?lnk=gst&q=crockford#38e8a2d75e864536
 
P

Peter Michaux

Frustrated with every other Javascript framework, I have decided to
write something better.

I want a Javascript library that doesn't get in the way, is easily
extensible. Just some basic framework to build on for widgets.

You may like to look at some of this code

* import() - dynamic script insertion? Dependency resolution?

I don't think that level of complexity in production is a good idea.
Work harder in development and have better performance in production.
* Building files to modules is easier to test, but feels weird

Why? Most programming environments require a build step.

I don't think the monolith style library is a good idea.

------------

You need a very clear idea of which browsers you are targeting or is
your code for the general web? Then you need a plan for feature
detection. David Mark has been going through his system with the group
for a few months now. I've summarized it as an article just yesterday

<URL: http://peter.michaux.ca/article/7146>

Peter
 
P

Peter Michaux


I don't think you need the namespace function. One namespace level *at
most* is sufficient. If you can't manage your namespace collisions in
a few thousand lines of code you have a big problem that needs to be
addressed. Emacs-lisp is all in one jumbo namespace and that is at
least many tens of thousands of lines that has survived decades.

Your extend function looks like something I thought was a good idea.
If you do keep it, your library shouldn't be dependent on it. In fact
your library should depend on itself as little as possible.

Peter
 
P

Peter Michaux

Frustrated with every other Javascript framework, I have decided to
write something better.

I want a Javascript library that doesn't get in the way, is easily
extensible. Just some basic framework to build on for widgets.

The BAD things of other libraries:
* Weird "OOP"ish schemes
* oversimplified interface that does more things behind the scenes
* Kitchen Sink - too much bloat in the main library file; non-
cohesive.
* buggy, with superficial examples that they call "tests"
* non-modular design
* core library features are poor, inconsistent across browsers, and
buggy

And, to quote Brendan Eich:
Too many of the JS/DHTML toolkits have the "you must use our APIs for
everything, including how you manipulate strings" disease.

I know what I don't want.

Goals:
* Minimal Framework, mainly used for AOP and OOP functionality
* unit tested
* AOP Event System
* Namespacing
* Modularity, Cohesion, Packaging based on REP
* No browser detection

TBD:
* import() - dynamic script insertion? Dependency resolution?
* Building files to modules is easier to test, but feels weird

RIA development using javascript, I need widgets (Data Table, Rich
Editor). Widgets need: DOM adapter functions (style, position,
className), Event-based ajax (or "deferred" Async's), Form
serialization, Drag 'n Drop, Animation.
I
JavaScript lacks "import" and "extend" which are useful for widgets. I
use AOP cross cuts even more. I have not seen 1 library that gets
these things right. It is very important to get this part right.

The base component is APE.js ->http://dhtmlkitchen.com/ape/src/APE.js


String.prototype.normalize =


Really bad. This is a major problem with Prototype and has burned them
when a browser implements the very same function. If you are keen on
namespacing then you definitely shouldn't be playing with common
objects.

"Don't modify objects you don't own."

Do this...

function normalizeString(string) {}



Peter
 
D

dhtml

String.prototype.normalize =

Really bad. This is a major problem with Prototype and has burned them
when a browser implements the very same function. If you are keen on
namespacing then you definitely shouldn't be playing with common
objects.

"Don't modify objects you don't own."

Do this...

function normalizeString(string) {}
I've put a conditional check before each:

if(!String.prototype.trim)
String.prototype.trim = function(){...}

What is the disadvantage?
 
J

Joost Diepenmaat

dhtml said:
I've put a conditional check before each:

if(!String.prototype.trim)
String.prototype.trim = function(){...}

What is the disadvantage?

The disadvantage is that *if* some browser implements
String.prototype.trim in some way that has different semantics it could
break the script.

Chances of that happening are probably higher than chances of a browser
implementing APE.trim() for instance.

Personally though, I would (and do) take that risk for *some*
functionality simply because it allows for a straight forward way to do
polymorphism (which may imply you shouldn't use it for functions that
have no real polymorphic uses).
 
D

dhtml

String.prototype.normalize =

Really bad. This is a major problem with Prototype and has burned them
when a browser implements the very same function. If you are keen on
namespacing then you definitely shouldn't be playing with common
objects.

"Don't modify objects you don't own."

Do this...

function normalizeString(string) {}

Peter

couldn't find a disadvantage.

I did some analysis and I was only using trim()/normalize() with my
className functions. I reduced this to one function, normalize, as
that's all I needed. So I have one fewer function call, I also have
normalize in the enclosing scope (closure), so it might be faster to
access (doesn't have to look up the prototype chain.

I wrote a test for my className functions:
http://dhtmlkitchen.com/ape/test/tests/dom/classname-f-test.html

The fully expanded, commented version of APE.js is down to 2.9k.

I'm happy with the change.

Garrett
 
D

David Mark

couldn't find a disadvantage.

I did some analysis and I was only using trim()/normalize() with my
className functions. I reduced this to one function, normalize, as
that's all I needed. So I have one fewer function call, I also have
normalize in the enclosing scope (closure), so it might be faster to
access (doesn't have to look up the prototype chain.

I wrote a test for my className functions:http://dhtmlkitchen.com/ape/test/tests/dom/classname-f-test.html

The fully expanded, commented version of APE.js is down to 2.9k.

I'm happy with the change.

Something is very wrong with the style of that test page. I can't see
the leftmost edge (which makes it impossible to read the results of
the test) and there is a horizontal scrollbar in IE7.
 
L

Lasse Reichstein Nielsen

dhtml said:
Frustrated with every other Javascript framework, I have decided to
write something better.

I want a Javascript library that doesn't get in the way, is easily
extensible. Just some basic framework to build on for widgets.

Sounds like the goal of jQuery too. I would at least listen -
critically- to the author of that, to see what experience can
be reused.

I must say he sounds more reasonable in this talk than in Richard
Cornford's signatures.

/L
 
D

dhtml

Sounds like the goal of jQuery too. I would at least listen -
critically- to the author of that, to see what experience can
be reused.
I watched that before. I disagree with most of what he says, I think
it deserves at least one, if not two threads to go over. It's mostly
higher-level API design stuff. Though I do agree with some of it. It
gave me contrast to say: That's what I DON'T want to do.

API design deserves a thread to discuss all the namespacing, modifying
built-ins, one file vs build system.

Going back to my code sample. timothytoe suggested I reuse the
function. Since I'm working with an Object literal, I am considering
to make a function property. I don't like this property, but I can
reuse it in two functions.

fun : function(){},

Each call to newApply used create a function, then call extend, which
created another function. It's inefficient.

/**
* @param {Function} fun constructor to be invoked.
* @param {Array} args arguments to pass to the constructor.
*/
newApply : function(fun, args) {
var f = APE.fun;
f.prototype = fun.prototype;// Copy prototype.
f.prototype.constructor = f;

var i = new f;
fun.apply(i, args); // Apply the original constructor.
return i;
},


What do you think?

I could instead wrap the whole thing in a closure, just for the sake
of reusing fun.


Garrett
 
L

Lasse Reichstein Nielsen

dhtml said:
/**
* @param {Function} fun constructor to be invoked.
* @param {Array} args arguments to pass to the constructor.
*/
newApply : function(fun, args) {
var f = APE.fun;

I wouldn't care about reuse here, unless performance is a problem
and the problem can be tracked to the creation of empty functions
here.
Readability-wise, I have to know here that APE.fun is an empty
function where it doesn't matter that I clobber its prototype.
f.prototype = fun.prototype;// Copy prototype.
f.prototype.constructor = f;

Why change the constructor property?

I would expect the effect of
newApply(fun,[arg1,arg2])
to be equivalent to
new fun(arg1, arg2)
and the latter inherits a prototype with .constructor == fun,
not APE.fun.
var i = new f;

For readability, I would capitalize "f", and use a different variable
name than "i" (suggests a loop index), e.g., "o" or "newObject".
fun.apply(i, args); // Apply the original constructor.
return i;
},


What do you think?

Neat idea!

/L
 
D

dhtml

Why change the constructor property?

I would expect the effect of
newApply(fun,[arg1,arg2])
to be equivalent to
new fun(arg1, arg2)
and the latter inherits a prototype with .constructor == fun,
not APE.fun.
You're right.
For readability, I would capitalize "f", and use a different variable
name than "i" (suggests a loop index), e.g., "o" or "newObject".
You're right about the constructor prop. I'll change f to F. As for |
i|, well, I'll think about a better variable name. I was thinking
"instance", but just called it |i| for brevity.


Now I need a test to make sure the constructor property is set
correctly.
Neat idea!
Cool! Thanks for the bug rept.
 
P

Peter Michaux

[snip]
Now I need a test to make sure the constructor property is set
correctly.

I don't ever use the constructor property and I doubt many folks do.
It isn't worth the trouble to keep it "correct".

Then again, I never overwrite the initial prototype property of a
function anymore so I'm not screwing up the constructor property in
the first place.

Peter
 
R

RobG

[snip]
Now I need a test to make sure the constructor property is set
correctly.

I don't ever use the constructor property and I doubt many folks do.
It isn't worth the trouble to keep it "correct".

Then again, I never overwrite the initial prototype property of a
function anymore so I'm not screwing up the constructor property in
the first place.

Are you persisting with FORK? Or have you decided that the "code
worth recommending project" (cwrp) will form the basis of a (new?)
modular FORK?

Perhaps dhtml can use the cwrp as the basis for a modular library else
it seem the effort is already forked (gosh, my puns are nearly as bad
as Linus T's).
 
P

Peter Michaux

Now I need a test to make sure the constructor property is set
correctly.
I don't ever use the constructor property and I doubt many folks do.
It isn't worth the trouble to keep it "correct".
Then again, I never overwrite the initial prototype property of a
function anymore so I'm not screwing up the constructor property in
the first place.

Are you persisting with FORK? Or have you decided that the "code
worth recommending project" (cwrp) will form the basis of a (new?)
modular FORK?

Perhaps dhtml can use the cwrp as the basis for a modular library else
it seem the effort is already forked (gosh, my puns are nearly as bad
as Linus T's).

I don't quite know what will happen yet. David seems to be working on
a library and I have enjoyed all of the discussion that the code worth
recommending project prompted. I'm currently using the Fork code in
work and it has been working fine for me without any changes for a
year.

Peter
 
D

David Mark

[snip]
Now I need a test to make sure the constructor property is set
correctly.
I don't ever use the constructor property and I doubt many folks do.
It isn't worth the trouble to keep it "correct".
Then again, I never overwrite the initial prototype property of a
function anymore so I'm not screwing up the constructor property in
the first place.
Are you persisting with FORK?  Or have you decided that the "code
worth recommending project" (cwrp) will form the basis of a (new?)
modular FORK?
Perhaps dhtml can use the cwrp as the basis for a modular library else
it seem the effort is already forked (gosh, my puns are nearly as bad
as Linus T's).

I don't quite know what will happen yet. David seems to be working on

Things are as they seem in this case. Did you check out the Alpha I
posted a month back? The Beta should go live this weekend and I will
invite everybody to try it out (criticism and suggestions will be more
than welcome.)
a library and I have enjoyed all of the discussion that the code worth
recommending project prompted. I'm currently using the Fork code in
work and it has been working fine for me without any changes for a
year.

I recently surveyed FORK (Fork?) and it looked quite good. Though I
imagine there are things you would change after all of the various CWR-
related discussions.
 
P

Peter Michaux

[snip]
Now I need a test to make sure the constructor property is set
correctly.
I don't ever use the constructor property and I doubt many folks do.
It isn't worth the trouble to keep it "correct".
Then again, I never overwrite the initial prototype property of a
function anymore so I'm not screwing up the constructor property in
the first place.
Are you persisting with FORK? Or have you decided that the "code
worth recommending project" (cwrp) will form the basis of a (new?)
modular FORK?
Perhaps dhtml can use the cwrp as the basis for a modular library else
it seem the effort is already forked (gosh, my puns are nearly as bad
as Linus T's).
I don't quite know what will happen yet. David seems to be working on

Things are as they seem in this case. Did you check out the Alpha I
posted a month back?

I have been reading the code which has been a big help. The builder is
a great feature.
The Beta should go live this weekend and I will
invite everybody to try it out (criticism and suggestions will be more
than welcome.)

How do you feel about promoting your library? With Fork, I found out
almost instantly that I didn't want to promote it aggressively. Folks
that run the YUI, jQuery, Dojo, Prototype libraries go to a lot of
conferences and have birthday parties, etc. Some of the libraries have
people designated as evangelists, I believe. I don't have a problem
with any of that and it is why the libraries are popular.
Theoretically popular means more people reading the code and reporting
bugs. Those projects do have bug fix releases and so that part is
working.
I recently surveyed FORK (Fork?) and it looked quite good. Though I
imagine there are things you would change after all of the various CWR-
related discussions.

Indeed there are. It is working fine for me because I only use it on a
site behind login with tech-savvy users. No complaints.

I like the API in general but would drop the namespacing to just one
level. I don't know why I can't mentally just go to global functions
like FORK_addistener. What is wrong with that anyway?

-----

By the way, I think I'll be posting the tabbed pane article tonight. I
just need to have it tested remotely on some very old Safari versions.
Thanks for all the help. I'm interested to see if people will read it
and comment.

Peter
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top