скачать руководство по ремонту тнвд руководство по эксплуатации вагонов renault clio руководство по эксплуатации Samsung E250 руководство системного администратора unix скачать скачать actionscript подробное руководство daewoo nexia руководство по эксплуатации Logixx 8 руководство пользователя lenovo 812 руководство хонда аккорд 4 samsung i8000 руководство пользователя volkswagen sharan руководство руководство пользователя nokia c6 мультимедийное руководство ваз 2107 руководство nissan avenir руководство по выживанию на пустошах Whistler volkswagen passat b3 руководство руководство по эксплуатации томагавк 9010 руководство по проектированию плитных фундаментов руководства по ремонту и инструкции Bosch qcad руководство пользователя chevrolet lacetti руководство A6 Fifa 11 suzuki vitara руководство скачать centurion xp руководство по установке 10 Thomas руководство по эксплуатации peugeot boxer Lg Tcc 5620 национальное руководство книги Toshiba 32av703r руководство по эксплуатации киа соренто руководство для женатого мужчины руководство по ремонту умз руководство гувд по саратовской области 2 методы руководства коллективом руководство по учету магия практическое руководство руководство по эксплуатации уаз 315148 руководство по эксплуатации рено кангу ниссан лаурель руководство по эксплуатации фестиваль педагогических идей классное руководство руководство по ремонту соренто скачать Nokia 71 руководство россии руководство по установке linux Korg Pa 500 Pioneer Pm 994 122 ивеко дейли руководство по эксплуатации руководство по ремонту citroen c2 14001 руководство по эксплуатации lexus gs300 руководство уфмс россии Jabra Jx10 Series 2 руководство по эксплуатации дэу сенс Samsung Wep350 mitsubishi outlander xl руководство 9020 особенности руководства samsung gt s5230w руководство 4 caldina руководство 323 ford fiesta руководство руководство по эксплуатации honda prelude руководство по ремонту автомобилей газ шевроле лачетти руководство по ремонту руководство по эксплуатации нива 21214 104 руководство по ремонту ваз 21074i а6 руководство скачать 281 руководство по ремонту priora hover руководство по ремонту руководство по ремонту рено магнум Htc Hd2 T8585 I5700 Htc Desire 8181 tusl2 c руководство руководство nissan x trail Panasonic Rr Us470 власть и руководство руководство банка Lg Gx300 руководство пользователя фотошоп cs5 практическое руководство системного администратора кенин руководство по эксплуатации ваз 2171 Hp M1132 руководство пользователя pocketbook iq 701 Samsung 8300 skype руководство пользователя руководство по эксплуатации pandora nokia 5230 руководство пользователя скачать маз руководство скачать 6 1100 стили руководства руководство x trail qashqai руководство 111 Pioneer Deh 4200sd руководство по эксплуатации авео tusl2 c руководство Boush 50 национальное руководство руководство bmw 7 e38 Pantera Slk 100 Sc руководство организации предприятия Nokia Tv Phone ситроен берлинго руководство ваз 21099 руководство по эксплуатации Canon 5d Nikon S220 руководство по эксплуатации bmw e38 руководство по эксплуатации бензогенератора руководство по производству полетов 5 itunes руководство пользователя руководство по эксплуатации автомобиля ланос Apc Smart Ups 1000 руководство по эксплуатации passat Motorola Janome L394 adobe premiere pro 2.0 руководство скачать клиническая фармакология национальное руководство Nokia 7610 Supernova автомобильные кузова руководство по ремонту руководство по эксплуатации кондиционера lg педагогическое руководство играми детей Whistler 555 руководство по терапии Lg руководство по эксплуатации шерхан 5 руководство по ремонту rover Nokia 6110 форд орион руководство по эксплуатации руководство по эксплуатации автомобиля volvo Sf 30 руководство по ремонту форд скачать руководство по эксплуатации audi a6 Dir 320 шевроле лачетти руководство по ремонту Mercedes S500 руководство по ремонту т 170 руководство пользователя sgh i900 pic микроконтроллеры полное руководство руководство администратора 8.2 307 sony sound forge руководство opengl руководство по программированию 4 руководство по качеству курсовая руководство ваз 21093 Canon L295 руководство пользователя toyota corolla 6700 bmw 525 руководство по ремонту мерседес 123 руководство по ремонту vw passat b5 руководство Skoda Fabia газ 3102 руководство по ремонту руководство пользователя ваз 2115 энтеробактерии руководство для врачей руководство по решению задач по статистике факторы определяющие стиль руководства 117 руководство по ремонту сузуки руководство по управлению рисками руководство volkswagen jetta руководство по ремонту мтз 82.1 руководство по ремонту ваз 21120 Lg ipad исчерпывающее руководство макфедрис п руководство по ремонту хундай старекс руководство по эксплуатации лифан fiat ducato руководство руководство по эксплуатации ниссан алмера руководство по ремонту ланцер Samsung Duos Canon Mp250 vw caddy руководство по эксплуатации руководство сбербанка россии Dsc W100 Cs4 adobe premiere руководство mitsubishi grandis руководство скачать руководство по эксплуатации honda prelude национальное руководство по наркологии 1с предприятие 8.1 руководство руководство по ремонту hyundai i30 руководство по интенсивной терапии скачать руководство по ремонту зил руководство тойота спринтер руководство visual studio 2010 linux полное руководство скачать скачать руководство газ 3307 найти руководство по эксплуатации Q7 Nokia 1680c 2 iphone 3gs 16gb руководство 2113 fallout new vegas прохождение руководство скачать классическое руководство Kenwood Grundfos Upa 15 90 25 руководство по эксплуатации pandora фольксваген в6 руководство по эксплуатации Starline 9 патриот руководство по ремонту скачать руководство по качеству организации Asus Wl 520g Beko Dfs 1500 руководство по ремонту ивеко Cenmax V7 Adobe Premier Elenberg Ms 5420 руководство пользователя sony vegas pro навител навигатор 3 руководство пользователя Sony Dsc T70 сервисное руководство Hp Officejet Pro 8500 руководство по эксплуатации ipad руководство по ремонту hyundai terracan Wlf 20170 Ce Bosch 126 руководство по эксплуатации hyundai руководство по эксплуатации fiat doblo 25 руководство по эксплуатации toyota harrier Xacti Sanyo руководство ваз 2107 07i скачать руководство по эксплуатации шевроле тахо руководство по эксплуатации canon Utorrent Iphone J8 директивная модель руководства Zanussi Zwo 2106 W скачать руководство по ремонту ман руководство пользователя r keeper Mail Ru Mitsubishi Galant руководство по эксплуатации мерседес w210 руководство по диагностике руководство по эксплуатации нива 2121 honda руководство по ремонту скачать Samsung 606 Gn1 2 руководство по эксплуатации онлайн Scher Khan Iv Gt S5230 Lightroom 3 руководство к духовной жизни Wd Elements Canon 400 asus n53j руководство пользователя руководство по 406 двигателю daewoo leganza руководство по эксплуатации 1с предприятие 8.1 руководство пользователя руководство по adobe illustrator cs5 Nokia 6300 октавия руководство по ремонту Yamaha руководство пользователя mandriva linux руководство по ремонту газовой плиты 100 Iphone 3gs H16 3300 руководство по эксплуатации mitsubishi rvr Cr V руководство по ремонту урал скачать руководство по эксплуатации rav 4 руководство по эксплуатации ups 25 классификация и характеристика стилей руководства руководство по среднему ремонту руководство по эксплуатации фольксваген джетта Ariston Als948tx руководство по ремонту крайслер скачать руководство по ремонту газ руководство по ремонту ваз 21093 руководство по эксплуатации сигнализации tomahawk Yosan Stealth 5 Sharp представитель руководства по качеству Hp 135 пример руководства по эксплуатации Cheat Engine 5.4 руководство по эксплуатации rav4 скачать 5 10 руководство по ремонту т 150 Nissan руководство по ремонту honda civic руководство по ремонту умз 6 руководство по ремонту volkswagen lt руководство windows mobile 6.5 руководство mac Casio 3768 руководство по ремонту славута microsoft office руководство пользователя Candy Holiday 104 D руководство по ремонту pajero руководство по эксплуатации panasonic Samsung Gt B7722 руководство по эксплуатации renault kangoo хундай соната руководство руководство по эксплуатации vw b3 nikon coolpix l110 руководство выплаты за классное руководство Hp опель астра j руководство классное руководство в 6 классе руководство по эксплуатации станка скачать peugeot 806 руководство стили лидерства и руководства руководство nokia e51 3 tohatsu руководство по эксплуатации руководство по медицине Panasonic Kx Mb2000 электронное руководство по эксплуатации самогипноз руководство по изменению себя Htc Touch Diamond2 hyundai coupe руководство по ремонту руководство по эксплуатации нива скачать 72 Kx Tg1401ru daewoo nubira руководство по эксплуатации audi a3 руководство Jabra Bluetooth руководство по эксплуатации уаз 390995 руководство по эксплуатации bmw e38 руководство vista ardeo Tomahawk D700 руководство по эксплуатации автомагнитолы kia sportage руководство samsung c3050 руководство пользователя 1 0 230 corolla руководство старлайн руководство по эксплуатации

A life in the day

1/4/2011

No Classes in Javascript

Filed under: — Scott Sauyet @ 9:39 pm

A colleague has published a series of posts (parts 1, 2, 3, 4, and 5) detailing the evolution of a Javascript class. We discussed this at our recent JS Club meeting. I had several concerns there; some I was able to raise and discuss, others I was not. Here I have the leisure to explain my objections more completely. But before I dive into it, I want to point out that while Paul and I disagree on a fair bit, I have a great deal of respect for him. He’s one of the people I most enjoy working with.

My first problem is the very notion of calling something a “class” when discussing Javascript. Javascript is a class-free language. The closest things Javascript has to the object-oriented notion of classes are constructor functions. But they are really not that close. Trying to impose OO thinking on what more closely resembles a functional language seems to start out in the wrong direction. But this may be simply a matter of terminology. We certainly want the ability to dynamically create multiple objects with similar interfaces and to encapsulate their data. If that’s all that’s meant by “classes”, then perhaps we are not too far apart.

The interface that he is creating can perhaps best be described by a few unit tests. Here are my own (QUnit) unit tests showing a partial set of the capabilities of Paul’s “Guy” constructor:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
test("Simple, index-based storage", function() {
    var bob = new Guy("Bob");
    bob.keep({socks: 2});
    equals(bob.show("0"), "{\"socks\":2}", "Expected Bob's socks to be in slot 1");
    bob.keep({looseChange: 6});
    equals(bob.show("1"), "{\"looseChange\":6}", "Expected Bob's loose change to be in slot 2");
    ok(bob.have("socks"), "Bob should still have his socks");
    ok(bob.have("looseChange"), "Bob should still have his loose change");
});
 
test("Named storage location", function() {
    var fred = new Guy("Fred");
    fred.keep({creditCards: 4}, "wallet");
    equals(fred.show("wallet"), "{\"creditCards\":4}", "Expected Fred's credit cards to be in his wallet");
    fred.keep({cash: 50}, "wallet");
    equals(fred.show("wallet"), "{\"creditCards\":4}", "Nothing else can go in Fred's wallet");
    ok(fred.have("creditCards"), "Bob should still have his credit cards");
});

A live version of these tests is at:

http://scott.sauyet.com/Javascript/Test/Guy/2011-01-04a/

Essentially, a Guy has a name and three public functions. He can store various objects, either in indexed locations or in specifically named ones. He can show JSON representations of the objects he’s stored when supplied their name. And he can report whether or not he’s stored something for a given name. These are represented by the functions keep, show, and have. This is a bit oversimplified, but it’s enough for these discussions. The unit tests above are by no means a complete test suite for the constructor function, but they do show much of the expected usage of Guys.

Here is Paul’s final implementation:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
var Person = function (name, basics) {
    this.name = name;
    this.stuff = basics || {};
    this.index = -1;
};
 
Person.prototype.find = function (where, keep) {
    var label = where.split("."),
    box = this.stuff;
    while (label.length > 1) {
        if (typeof box[label[0]] === "undefined") {
            if (keep) {
                box[label[0]] = {};
            } else {
                return;
            }
        } else {
            box = box[label.shift()];
        }
    }
    return [box, label[0]];
};
 
Person.prototype.keep = function (what, where) {
    var found, box, label;
    if (where) {
        found = this.find(where, true);
    } else {
        found = [this.stuff, this.index += 1];
    }
    box = found[0],
    label = found[1];
    if (typeof box[label] === "undefined") {
        box[label] = what;
    }
};
 
var Guy = function (name, basics) {
    var person = new Person(name, basics);
    this.have = function (what) {
        if (typeof person.find(what) !== "undefined") {
            return true;
        } else {
            return false;
        }
    };
    this.show = function (what) {
        var found, box, label;
        if (typeof what === "undefined") {
            found = [person, "stuff"];
        } else {
            found = person.find(what);
        }
        box = found[0];
        label = found[1];
        if (typeof box[label] === "object") {
            return JSON.stringify(box[label]);
        } else {
            return box[label];
        }
    };
    this.please = function (action) {
        var request = Array.prototype.slice.apply(arguments);
        request.shift();
        if (typeof action === "function") {
            action.apply(person, request);
        } else {
            if (person[action]) {
                person[action].apply(person, request);
            }
        }
    };
};
 
Guy.prototype.keep = function (what, where) {
    this.please("keep", what, where);
};

In this implementation, a Guy is created with a hidden reference to a Person. His own-properties, such as have and show, as well as his helper function, please, have access to this Person, but his prototype functions cannot directly access this Person; they need to elevate their privileges by calling please.

The first concern, and the one I raised in our discussion, but couldn’t fully articulate, was my objection to the expanded API this implementation entails. The unit tests above suggest a fairly simple API: There needs to be a constructor function which accepts a name. (The name is not actually used anywhere, but it’s easy enough to imagine there would be a use for it soon.) And the objects created from this constructor should have as properties the functions keep, show, and have. That’s all that’s really required. But this implementation exposes the Guy constructor, the prototype for that Constructor containing a keep function, the Person constructor, and its prototype containing find and keep. The objects created from the Guy constructor have the expected keep, show, and have properties, but they also have a please property exposed. If all those additional API capabilities were meant to be public, I would have no objection. But they are implementation details, which to my mind should be kept private.

A lesser concern has to do with the additional parameter which can be passed into the constructor. This was to allow us to start each Guy off with a certain set of stuff; it’s not tested in the code above. The problem is that, for all the concern about encapsulation in the discussions about the five steps, the implementation uses that object directly if supplied to store its stuff. So code that kept a reference to the object passed to this constructor would have a handle on what’s supposed to be entirely private stuff. This would be a major concern except that if this were actually in a larger system, there would probably some utility clone function which could be readily employed to fix this problem. This one can be chalked up to it being demo code.

The next objection is more substantial, but it might be the hardest to overcome if there is a need for a Guy’s configuration to remain safely encapsulated: Every Guy created has its own copy of the hide, show, and please functions. This could be quite memory-intensive if there are a lot of Guys in the system. Moreover, it seems very contrary to the overall direction of trying to make Javascript a little closer to classical OO languages. I’ll discuss my alternative implementation below. In it I don’t solve this issue; I don’t know of a solution to this. But I do reduce the custom functions to very thin wrappers around otherwise shared functions. Certainly it reduces the problem. This should demonstrate what I mean:

1
2
3
4
5
6
    var bob = new Guy("Bob");
    var fred = new Guy("Fred");
    console.log(fred.keep === bob.keep);     // true
    console.log(fred.show === bob.show);     // false
    console.log(fred.have === bob.have);     // false
    console.log(fred.please === bob.please); // false

But my biggest concern is that even though a major goal in the discussion was to encapsulate private data in a way that made it safe from prying eyes, this implementation does not manage to do so. Paul said that, “To make sure you don’t trick [a Guy] into giving away his stuff, please will return undefined.” But I can still get at it quite easily:

1
2
3
4
5
6
    var george = new Guy("George");
    george.keep({creditCards: ["Visa", "Amex"]}, "wallet");
    george.please(function() {pickpocket = this.stuff;});
    console.log(pickpocket); // {"wallet":{"creditCards":["Visa","Amex"]}}
    pickpocket.wallet.creditCards = [];
    console.log(george.show("wallet")); // {"creditCards":[]}

The pickpocket was able to get at George’s stuff, and not just a JSON-stringified copy, but a reference to the original. We could similarly get the entire Person, by simply storing this in the variable. This is rather disheartening for George, and demonstrates a real problem — possibly even an intractable one — with trying to hold data out of view in the closure of a constructor but still allowing access to it from prototype methods. Although it’s nice that we had to say “please” to get this data, it seems wrong to make that the only level of protection.


I created an alternate implementation. It solves the first and last issues completely. The public API is just what we would like, and the private data remains private. I didn’t try to solve the non-cloned constructor parameter issue; that’s simple enough to do, and the same sort of code would solve it for both implementations. For the remaining issue, I reduced the memory requirements for each Guy, but individual objects still have their own implementations of the public functions. Those are simple wrappers around common functions, so the cost is lower, but it does not solve this problem entirely. I’d love to see a technique that manages to do this and still keep the small API and properly encapsulate its data.

This solution is less object-oriented than Paul’s. I choose a more functional approach. As best I could, I kept his functions intact. The test page is here:

http://scott.sauyet.com/Javascript/Test/Guy/2011-01-04c/

The code looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
var Guy = (function() {
    var 
    find = function (where, keep) {
        var label = where.split("."),
        box = this.stuff;
        while (label.length > 1) {
            if (typeof box[label[0]] === "undefined") {
                if (keep) {
                    box[label[0]] = {};
                } else {
                    return;
                }
            } else {
                box = box[label.shift()];
            }
        }
        return [box, label[0]];
    },
    have = function (what) {
        if (typeof find.call(this, what) !== "undefined") {
            return true;
        } else {
            return false;
        }
    },
 
    keep = function (what, where) {
        var found, box, label;
        if (where) {
            found = find.call(this, where, true);
        } else {
            found = [this.stuff, this.index += 1];
        }
        box = found[0],
        label = found[1];
        if (typeof box[label] === "undefined") {
            box[label] = what;
        }
    },
    show = function (what) {
        var found, box, label, result;
        if (typeof what === "undefined") {
            result = this.stuff;
        } else {
            found = find.call(this, what);
            box = found[0];
            label = found[1];
            result = box[label];
        }
        if (typeof result === "object") {
            return JSON.stringify(result);
        } else {
            return result;
        }
    },
    Guy = function(name, basics) {
        if (!(this instanceof Guy)) {
            return new Guy(name, basics);
        }
        var cfg = {stuff: basics || {}, index: -1};
        this.keep = function(what, where) {keep.call(cfg, what, where);};
        this.have = function(what) {return have.call(cfg, what);};
        this.show = function(what) {return show.call(cfg, what);};
    };
    return Guy;
}());

I don’t have very much to say about this implementation. It’s a few lines shorter than the original. The techniques are nothing new. The actual constructor function is wrapped in a closure along with the basic functions to be used. The objects created have thin wrappers calling these functions, supplying the configuration information.

I should note that one of Paul’s concerns was being able to break apart his implementation into pieces that could be maintained separately. This technique would make that more difficult. This does not worry me, because I believe that such constructor functions should be cohesive pieces that are relatively short and easy for a single person to maintain. But if that’s a bigger issue for the reader than the ones above, then s/he is encouraged to look for other approaches.

In any case, I hope this sheds some light on the different concerns that developers might have on to how to build constructor functions in Javascript. A central issue is that we should be using the strengths of the language rather than trying to make it look like some other type of language. Javascript’s flexible semi-functional nature can be very powerful. Trying to graft on a substantial OO gloss can serve to hide the beauty and the power of Javascript.
msi a6205 драйвера руководство по эксплуатации audi tt
gigabyte ga 8pe800 драйвера скачать руководство 3110
драйвер hp 3500c нива шевроле скачать руководство руководство по эксплуатации спринтер
драйвер epson stylus 7300 полное руководство citroen c3 руководство по эксплуатации
canon 810 драйвер скачать руководство по ремонту logan
mustek 2400cs plus драйвер руководство по эксплуатации samsung 5230
speedlink strike2 драйвера man tga руководство скачать
драйвер для принтера canon lbp2900b полное руководство по хиромантии вебстер методы руководства предприятием
драйвер nvidia 9500gt руководство по ремонту зил 5301 candy руководство по эксплуатации
загрузить драйверы nvidia vw sharan руководство презентации по классному руководству
драйвера для ноутбуков samsung r508 руководство по ремонту татра 815 руководство пользователя microsoft word
asus x42jv драйвера
драйвер sis agp руководство по эксплуатации scenic руководство по эксплуатации автомобиля мерседес
xerox phaser 3250 драйвер руководство по ремонту форд ка nissan note руководство скачать
драйвера asus k51ae айфон 4g руководство пользователя
scx 4200 драйвер скачать vista
intel atom драйвер
драйвера intel 875 руководство пользователя фотошоп cs5 руководство по эксплуатации audi q5
ati radeon xpress 1270 драйвер общее руководство таможенным делом
samsung 4216f драйвер руководство по эксплуатации авео стили руководства и организационное поведение
ati radeon xpress 1150 драйвер руководство по ремонту subaru legacy
драйвера для ноутбуков samsung r440
nvidia драйвер скачать windows 7
скачать драйвер принтер xerox 3119 джон коггзолл php5 полное руководство руководство организации предприятия
samsung r519 драйвера xp suzuki vitara руководство по ремонту руководство исо мэк 25
драйвер ati radeon 2600 скачать руководство филиалом
nforce 570 драйвер
драйвера для ноутбуков asus f80l руководство пк
acer 5741zg драйвера mercedes w203 руководство скачать
pixma ip4200 скачать драйвер руководство по эксплуатации nissan liberty руководство по таро
драйвера на звук asus p4p800 руководство пользователя первая помощь 1.0 corolla руководство по эксплуатации
драйвер gf 9500 руководство starline b6
драйвера для ноутбуков lenovo e43 руководство по пользованию windows 7 руководство по эксплуатации мазда трибьют
age star драйвер руководство по ремонту b3
скачать драйвера для asus k40ad руководство бмв х3 руководство по эксплуатации 2111
acer travelmate 5623wsmi драйвера ситуативные модели руководства
драйвер hp designjet 500 plus
samsung ml1750 драйвер toyota corolla руководство руководство по ремонту rav 4
bluetooth драйвер для ноутбука dell руководство по эксплуатации lancer 9 руководство матиз
драйвер принтера samsung ml1615 nissan x trail руководство скачать руководство маз 4370
драйвер для жесткого диска transcend
sound blaster audigy se драйвер pc share manager samsung руководство руководство пользователя windows xp скачать
realtek rtl8168b скачать драйвер секс реальное иллюстрированное руководство скачать руководство по эксплуатации w221
драйверы roverbook navigator
драйвера для samsung gt s7070
hd аудио драйвер
ga 60x драйвера руководство по эксплуатации приус honda partner руководство
canon canoscan 4400f драйвер
драйвер 7300gt agp руководство по ремонту соната
scanjet g3010 драйвер
winfast n15235 драйвер скачать методы руководства реферат
скачать драйвера на звук directsound руководство по ремонту мтз скачать руководство по ремонту hyundai verna
драйвера для ноутбуков asus a6r руководство по эксплуатации мтз 80 руководство хонда цивик
asus pro5ij драйвера руководство по ремонту автомобиля ниссан
драйвера для ноутбука acer 5920g
драйвер для видеокарты dell руководство по эксплуатации принтера canon восстание под руководством булавина
скачать драйвер asus p5kpl c
драйвера ga 8i915p
canon lpb 800 драйвер
optiarc 7170 драйвер руководство по ремонту rover скания руководство
realtek alc883 скачать драйвер xp руководство canon 400d
pinnacle pctv stereo драйвер
драйвера hp pavilion dv 5 руководство пользователя samsung i9000 тарифное руководство 4 книга 3
драйвера для ноутбуков compaq cq60 руководство по эксплуатации w221 остров кенгуру руководство по запузачиванию
sony ericsson s302 драйвер руководство форд фьюжн
драйвер radeon x1600 windows 7 руководство по эксплуатации jeep
драйвер для флешки transcend xp аштанга йога полное пошаговое руководство руководство по эксплуатации автомобиля toyota
oklick 725l драйвера
драйвера ati 5850 война под руководством богдана хмельницкого chrysler pacifica руководство по эксплуатации
драйвер для видеокарты geforce 4 руководство по ремонту кайрон
драйвер epson cx 3200
драйвера для dvd rom lg руководство по эксплуатации subaru outback
драйвера samsung n127 coreldraw 12 руководство
acer aspire one zg5 драйвера руководство по эксплуатации шкода
asus vk193d драйвер руководство windows
realtek semiconductor corp драйвер руководство по эксплуатации порше кайен руководство по ремонту ваз 21065
универсальный драйвер hp скачать классное руководство в начальных классах
canon pixma ip 1700 драйвера
dell latitude d620 драйвера руководство по эксплуатации фотоаппарата руководство по ремонту мтз 82
toshiba satellite a300 15e драйвера нива 2131 скачать руководство
драйвера для acer 5710 руководство по ремонту тойота харриер руководство по эксплуатации сигнализации шерхан
dell inspiron 1525 драйвера 7
biostar nf520 a2 te драйвера руководство по эксплуатации снегохода буран руководство по эксплуатации nokia c7
audio драйвера для windows 7
hp 3570c драйвер
драйвер logitech m505 explay руководство по эксплуатации
драйвера canon mp 190 руководство по ремонту sonata
новый драйвер для ati
скачать bda драйвер beholder киа маджентис руководство
msi s310 драйвера
драйвера для ноутбука samsung r430
скачать драйвера logitech dual action
realtek audio драйвер windows 7 руководство ваз 2107 скачать
сетевые драйвера для ноутбуков toshiba видео руководство по настройке wifi
блютуз orient скачать драйвера булюбаш руководство по гештальт терапии
3com 3c940 драйвер vw bora руководства playstation 3 руководство пользователя
драйвера samsung
проблемы с realtek драйверами
asus f3jp драйвера скачать руководство по ремонту spark скачать руководство по ремонту вольво
palit n61s драйвера джокер смена руководства

3/31/2007

Overlabel with JQuery

Filed under: — Scott Sauyet @ 2:24 pm

I’ve been playing with JQuery lately, and when I found a need to use the wonderful little accessible compact form script by Mike Brittain, I thought I’d try to duplicate it with JQuery’s simpler syntax. This is my first attempt at anything close to a JQuery plugin. It works for me, as you can see on the test page.

Here’s the code I wrote (Update: There is an updated version in the comments.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
jQuery.fn.overlabel = function() {
    this.each(function(index) {
        var label = $(this); var field;
        var id = this.htmlFor || label.attr('for');
        if (id && (field = document.getElementById(id))) {
            var control = $(field);
            label.addClass("overlabel-apply");
            if (field.value !== '') {
                label.css("text-indent", "-1000px");
            }
            control.focus(function () {label.css("text-indent", "-1000px");}).blur(function () {
                if (this.value === '') {
                    label.css("text-indent", "0px");
                }
            });
            label.click(function() {
                var label = $(this); var field;
                var id = this.htmlFor || label.attr('for');
                if (id && (field = document.getElementById(id))) {
                    field.focus();
                }
            });
        }
    });
};

And it would be called like this:

1
2
3
$(document).ready(function() {
    $("label.overlabel").overlabel();
});

I’m wondering whether there are some simplifications to this that a more experienced JQuery user could explain, though. I feel as though it’s still too wordy, and that it spends too much time switching between the DOM elements and the JQuery ones.

In any case, if you are interested in this (public domain) plugin, you can grab a zip here, or just go straight to the Javascript source.

3/15/2005

Stylesheets Plugin

Filed under: — site admin @ 12:52 pm

I’ve created my first WordPress plugin. It allows you to add your own stylesheets independent of the chosen theme. You can download it at http://scott.sauyet.com/php/wp-plugins/stylesheets/. Install is the standard, unzip, drop it in the plugins directory, and activate. It adds a panel to the managment page.

The genesis of this plugin was a little itch I had to scratch: I’ve been playing with themes for my blog. Someday I’ll get around to writing my own, but for now I’m working with many of the beautiful options available online. The trouble is that I kept having to patch the stylesheets with a little extra CSS that I was using on my site. I have some health issues that I’m tracking with markup that looks like this:

    I’m at <strong class="good reading">78</strong>, which is in the
    target range of below <strong class="target reading">100</strong>.

which in this blog looks like:

I’m at 78, which is in the target range of below 100.

and of course sometimes there’s a "class='bad reading'" too. :-( To go along with this, I’d been adding a tiny bit of CSS to the stylesheet for each theme I tested. This is tedious and error-prone, and seems to be against the spirit of WordPress.

So when I started to understand the plugin architecture, I created a tiny plugin that added the necessary CSS to the head of the document. Then I switched to an extenal call to the stylesheet. After that, I arranged for the call to the stylesheet to call through the plugin itself. At this point I realized that these techniques could be useful to others. So I’ve generalized it quite a bit, and tried to reasonably bulletproof it.

I think it’s straightforward to use, and self-documenting. It allows you to create as many separate stylesheets as you like, each one including as much CSS as you choose, linked or imported (maybe later I’ll add the option to include the CSS directly in the head), and associated with whatever collection of media you wish. You can also choose to hide any of these stylesheets.

I’m pretty happy with the results, but so far I am the only user. I would love to hear feedback from WordPress users.
(more…)

1/6/2005

Arguing for an upgrade

Filed under: — site admin @ 12:41 pm

My team has a big architectural meeting coming up soon; it will be time to discuss what’s working, what’s not, what our system wants to be when it grows up. It’s a three-day, offsite meeting. We’re flying in team members from Houston and Indianapolis. It’s a big deal. And I’m trying to prepare.

I want to write a document describing some of the benefits of many of the modern software development tools and techniques. But I’m stumped at where to begin. The problem is that there’s far too much to say.

Our current system is an ASP/VB/SQL Server web application. It works only with IE6. Our ASP pages are mixes of presentation, business logic, and data access. Parts of the navigation relies on Javascript. Some of the HTML is generated inside VB DLLs. There are client-specific functions mixed in with generic stuff. There is a very flat directory structure, with no way to distinguish the functionality of various modules.

There are no automated tests, nor any scripts for manual testing. Building the system is a matter of grabbing the code from several different source-code control databases (and all the code that developers have forgotten to check in), moving it to the production machine, then manually trying out anything you’ve been working on, finding the DLLs you forgot you needed to register, trying it again, calling everyone who worked on the system, adding to the database the tables someone forgot to tell you you needed, lathering, rinsing, and repeating until no one notices any further errors.

And of course there is absolutely no documentation.

The initial system was built by a very talented programmer who was quite new to all the technologies used. She did a great job getting things working, but the system has grown in all directions, and there has been little coordination of the efforts.

What I want to propose is a multi-tiered application architecture, using modern development technologies and techniques. My choice would be Java with Hibernate and Spring, although I don’t have much experience with either framework. But I would certainly be willing to live with .NET or a Python framework. I could even see doing all or some of it in PHP. I would be willing to consider full-fledged J2EE, although that scares me a bit.

Out output should be standards-compliant XHTML and CSS. Javascript should be optional, used only to enhance a working page(1).

Everything should be test-driven. No code should be checked in without passing unit tests, and no code should be written without having tests for it to pass. The builds should be automated. There should be automated functional tests.

In short, we should be building a modern, modular, scalable, testable, automated system.

The trouble is in having so much to say that I can’t seem to even begin actually writing my document. I’ve been working around the edges, mostly analysis of the various options for technology. But I need to work on the main part, and I need to do so soon.

Anyone ever seen good sites describing in management’s terms the advantages to modern techniques?


(1) There is one inescapable exception to this. We have a Javascript WYSIWYG editor. We are told we need to maintain a WYSIWYG editor without relying on any plug-in. Nonetheless, everything else should still work with Javascript turned off.

Powered by WordPress