Fork v0.2 overview

3 views
Skip to first unread message

Peter Michaux

unread,
Jul 21, 2008, 2:50:52 AM7/21/08
to Fork JavaScript
Fork hasn't been updated since v0.1.1 of March 2007. That is because
I've been happily using it and haven't found any bugs in the parts I
do use. I have added bits and tweaked things recently. I've also
learned a lot more about feature testing and want to encorporate this
knowledge in the library. It is time for an update.

The goals for v0.2

* Shorter namespacing hierarchy.
* "FORK" is a durable object with only function-valued properties
which are all importable.
(http://yuiblog.com/blog/2008/05/24/durable-objects/)
* a library for use on pages right out there in the open on the unrestricted web
* For use with HTML. If it doesn't work with XHTML it is not a problem for me
* Feature test all Host objects at least for existence and for
functionality when known buggy implementation exist
* Feature test any Native objects introduced in or after any of IE4,
NN4, ECMAScript-262 3rd ed.
* Features of the Fork library are only defined if they will work in a
particular browser

The feature testing might be a little more than some people deem
necessary but that is the better side on which to err.

Fork is a reasonably small library and I'd like it to stay that way.
It normalizes browsers, works around bugs and fixes the most painful
browser APIs. It doesn't have any widgets. A widget library could be
built on top which is actually how I use Fork for real work.

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

The majority of the library requires feature detection. Detecting
native features is relatively easy because the ECMAScript spec defines
the values of "typeof obj.prop". Detecting host features is more
difficult as the values of typeof are implementation dependent and
implementations do vary. A set of three feature detection functions
suggested by David Mark on comp.lang.javascript will be provided. They
are described here

http://peter.michaux.ca/article/7146

FORK.isHostMethod(obj, prop)
FORK.isHostCollection(obj, prop)
FORK.isHostObject(obj, prop)

I think these three functions are quite settled. I would be possible
to get away with a looser set of functions but these three only open
the door far enough that studied implementations can get through. If a
new implementation appears that requires looser functions then these
functions can be relaxed to allow that new implementation through.

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

Some feature tests require the document, documentElement or any
element. An example is checking the style object is present on a
representative element and that a particular property of that style
element has typeof "string".

FORK.getDocument()
FORK.getDocumentElement(doc)
FORK.getAnElement(doc)

I'm not sure these three functions will survive exactly like this.
Richard Cornford described one issue today on comp.lang.javascript
where a library is used in a multiple window/frame situation. If two
windows involve different doctypes, then feature testing results in
one window may not apply to another. Fork is really for HTML 4.01
transitional and strict documents that may be in various windows, a
frameset or iframes. If feature tests pass in a transitional frame is
there any evidence the feature tests should be performed in a strict
frame and will have different results. I don't know of any need for
this level of paranoia.

I don't think much of XHTML and there are plenty of articles on the
web explaining why XHTML is not viable for the general web.

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

A CSS selector function with support for simple selectors like ".foo",
"#bar", "div", "div.foo#bar". That's it. The reason is that allowing
CSS selectors like ".foo > #bar[bip=bap]" make the implementation of
the finder function much larger and also makes the selectors brittle.
If the designer adds and extra div wrapper somewhere in the HTML, it
may brake the selector.

FORK.find(selector, root)

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

Some helpers to make dealing with the class attributes of elements easier.

FORK.hasClass(el, className) // el can be an array
FORK.addClass(el, className)
FORK.removeClass(el, className)

Currently "el" can be an array otherwise the calling code has quite a burden

var els = FORK.find('.foo');
for (var i=0, ilen=els.length; i<ilen; i++) {
var el = els[i];
FORK.addClass(el, bar);
}

or

var els = FORK.find('.foo');
arrayForEach(els, function(el) {FORK.addClass(el, bar);});

If "el" is an array, hasClass returns true if all "el" have the class.

The "el" parameter cannot be a string id or css selector because this
is not a burden for the calling code and keeps the class helpers
implementation cleaner.

FORK.addClass(FORK.find('.foo'), 'bar');

Setting opacity.

FORK.setOpacity(el, val)

Currently "el" cannot be an array. Should it be for symmetry with
FORK.addClass, etc. Or should they not be able to accept an array
argument?

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

The following function produces a new durable object with three
function-valued properties "addEventListener", "removeEventListener",
"fireEvent". These names are too long. I think they should probably be
just "on", "off", "fire" to parallel the DOM event library.

FORK.makeObservable()

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

Report the amount by which the page has been scrolled. Perhaps these
should take an argument indicating which window/frame to report?

FORK.getPageScrollX()
FORK.getPageScrollY()

I want to have all features of the Fork library defined only if they
will work in the particular browser. Feature testing for Scroll
reporting in some versions of IE when a doctype is not used, for
example, require the body to be present for the feature test. Can
these browsers and situations just go down the degradation path? I
would really like to put them down that path. The problem is really
more general and there could come a time when another part of Fork
cannot be tested until the document is ready. It may be possible to
avoid this problem now but have to deal with it in a future version.

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

The API for the event library in Fork v0.1 seems to have been
reasonable. I want to shorten the naming and reduce the namespace
depth.

FORK.on(el, type, handler, options)
FORK.off(el, type, handler, options)
FORK.purge(el, options)
FORK.stopPropagation(e)
FORK.preventDefault(e)
FORK.getTarget(e)
FORK.getRelatedTarget(e)
FORK.getEventPageX(e)
FORK.getEventPageY(e)

The reason for the names "on" and "off" is they are the most
frequently used functions that I use in Fork and short is handy.
Because I use them so frequently, I don't forget what the somewhat
cryptic names mean.

I don't plan on using the "options" argument to "FORK.on" or
"FORK.off" anymore and an optimization will be added so that the extra
wrapping needed to bind "this" or fix "arguments" won't be used if
"options" is not provided.

In v0.1 there is a hacky legacy workaround for a bug in versions of
Safari up to something like 2.0.2 where preventDefault didn't work if
an event listener was attached with addEventListener. Since these
versions of Safari are either very old (i.e. versions 1.x) or
automatically upgraded to versions where this bug was fixed, I want to
put these versions of Safari down the degradation path. There is no
feature test, that I know of for this bug, so the plan is to use
multiple object inference to determine that the browser is Safari and
old. I don't mind if slightly later versions of Safari are put down
the degradation path so long as at least the most recent version of
the 2.x series is not since it didn't have the bug. Supporting only
version 3.x seems too aggressive. Would anyone like to explore this
issue?

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

These are the FORK.Mutate functions in v0.1. The only addition below
is FORK.empty. I think the functionality is fine here but perhaps the
naming is not.

FORK.update(el, html, evalScripts)
FORK.replace(el, html, evalScripts)
FORK.insertBefore(el, html, evalScripts)
FORK.insertTop(el, html, evalScripts)
FORK.insertBottom(el, html, evalScripts)
FORK.insertAfter(el, html, evalScripts)
FORK.remove(el)
FORK.empty(el)

"el" is not able to be an array right now. Should it be allowed?

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

Douglas Crockford's json2.js slightly modified so it doesn't augment
"Date.prototype". This is namespaced inside the "FORK" object. Feature
detection wrapped around the library.

FORK.dumpJSON(value, replacer, space)
FORK.loadJSON(text, reviver)

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

The v0.1 XMLHttpRequest wrapper was used by calling "new FORK.Ajax".
That feels like it was a mistake. I want to have the following.

FORK.xhr(method, url, options)

Otherwise, I've enjoyed using this part of the library. I don't plan
on using the "this" or "arguments" options any more but they can stay
like they will in the event functions.

I've never used the abort or timeout features of the library. They can stay.

Would it be handy to have a "handlerError" function that runs if the
particular status handler throws an error? I was asked to wrap my
handlers in try-catch blocks at work by the server-side programmers.
The idea doesn't offend me but the implementation might.

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

I don't know what to do about the cookie API. The functionality is
right but I'd like not to require "new Cookie" as none of the other
parts of the library will

FORK.makeCookie

producing a durable object with "store" and "remove" function-valued
properties. I'm not sure yet.

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

Building HTML elements with document.createElement and then setting
attributes is a royal pain. There are many bugs where setting certain
properties doesn't work. Using innerHTML always seems to work. For a
full client-side app I have built in the past year, it seems the
following was very helpful and it used innerHTML.

FORK.build(tag, attrs, opts)

For example, my typical use was creating an element where I needed a
reference to that element.

var el = FORK.build('div', {className: 'foo'}, {innerHTML: "hello"});
FORK.on(el, 'click', fn);

I don't like this function particularly but it allowed me to get on with life.

This function is somewhat peripheral and I could see not including it.

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

The drag and drop stuff uses FORK.extend. I think the drag and drop
library is good, fast and very flexible. The API needs work. This part
of the library is more low-level than the rest of the library. Kind of
like Lego parts. You have to build something out of them.

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

I have started working on the code. I've been doing quite a bit of
coding without even trying to run it or see if it parses properly. I'm
enjoying just reading the code over and over again seeing if there are
conceptual errors.

The code is always available for browsing here

http://dev.forkjavascript.org/trac/browser/trunk/public/javascripts/fork

or Subversion checkout as described here

http://dev.forkjavascript.org/trac

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

Comments on any of the above are very welcome.

Peter

Peter Michaux

unread,
Jul 29, 2008, 7:06:30 PM7/29/08
to Fork JavaScript
On Jul 20, 11:50 pm, "Peter Michaux" <petermich...@gmail.com> wrote:

> I don't know what to do about the cookie API. The functionality is
> right but I'd like not to require "new Cookie" as none of the other
> parts of the library will
>
> FORK.makeCookie
>
> producing a durable object with "store" and "remove" function-valued
> properties. I'm not sure yet.


I don't like, and have never liked, multi-statement API's where the
caller has to know the correct order in which to do things. In Fork
v0.1 updating a cookie was

var c = new FORK.Cookie('foo');
c.a = 1;
c.store('/');


In Fork v0.2 it will be a one-liner

FORK.updateCookie('foo', {a:1}, {path:'/'});


The full API will be:

// returns a crumbs object, options = {document}
FORK.getCookie(name, options)

// options = {days, path, domain, secure, document}
FORK.setCookie(name, crumbs, options)

// options = {days, path, domain, secure, document}
FORK.updateCookie(name, crumbs, options)

// options = {days, path, domain, secure, document}
FORK.deleteCookie(name, options)

Peter
Reply all
Reply to author
Forward
0 new messages