Notes on codes, projects and everything

Proof of Concept: YQuery

After the last post, I found that it may be fun to write a wrapper for YUI in order to make it behave like jQuery. Therefore, the code below is clearly mainly for self-amusement and is not intended to be used in production projects. However, through coding this, I found that although the difference in design, but YUI is obviously capable to do what jQuery offers (if not more). I will not continue working on this so whoever interested may just copy and paste the code to further developing it.

/**
 * Proof of concept : jQuery-like syntax in YUI
 */
(function() {

var yui_builder = (function(Selector, Element, DOM, Event) {
    return function(_selector) {
        var Result = function() {};

        var init = function(_selector) {
            var result = [];

            if(typeof _selector == 'object') {
                result = [ new Element(_selector) ];
            } else {
                result = query_elements.call(this, _selector);
            }

            return result;
        };

        var delegate = function(_scope, _function) {
            return function() {
                return _function.apply(_scope, arguments);
            };
        };

        var query_elements = function(_selector) {
            var result = new Result;
            var elements = wrap_elements(Selector.query(_selector));

            for(var i in elements) {
                result[i] = elements[i];
            }

            return result;
        };

        var unwrap_elements = function(_elements) {
            var result = [];

            for(var i in _elements) {
                result[i] = _elements[i].get('element');
            }

            return result;
        };

        var wrap_elements = function(_elements) {
            var result = [];

            for(var i in _elements) {
                result[i] = new Element(_elements[i]);
            }

            return result;
        };

        return (function(_elements) {
            _this = new Result;

            _this.addClass = function(_class) {
                for(var i in _elements) {
                    _elements[i].addClass(_class);
                }

                return this;
            };

            _this.append = function(_content) {
                if(typeof _content == 'string') {
                    for(var i in _elements) {
                        _elements[i].set(
                            'innerHTML',
                            _elements[i].get('innerHTML') + _content
                        );
                    }
                } else if(typeof _content == 'object') {
                    _elements[0].appendChild(_content);
                }

                return this;
            };

            _this.appendTo = function(_selector) {
                var _parent = yui_builder(_selector);

                for(var i in _elements) {
                    _elements[i].appendTo(_parent.get(0));
                }

                return this;
            }

            _this.attr = function() {
                var result = this;

                if(arguments.length == 1 && typeof arguments[0] == 'string') {
                    result = _elements[0].get(arguments[0]);

                    if(!result) {
                        result = undefined;
                    }
                } else if(arguments.length == 1 && typeof arguments[0] == 'object') {
                    for(var i in _elements) {
                        for(var attribute in arguments[0]) {
                            _elements[i].set(attribute, arguments[0][attribute]);
                        }
                    }
                } else if(typeof arguments[1] == 'function') {
                    for(var i in _elements) {
                        _elements[i].set(arguments[0], arguments[1].call(_elements[i].get('element'), i));
                    }
                } else {
                    for(var i in _elements) {
                        _elements[i].set(arguments[0], arguments[1]);
                    }
                }

                return result;
            };

            _this.each = function(_callback) {
                for(var i in _elements) {
                    _callback.call(_elements[i].get('element'), i, _elements[i].get('element'));
                }

                return this;
            };

            _this.eq = function(_index) {
                return yui_builder(_elements[_index]);
            };

            _this.get = function() {
                var result = [];

                if(arguments.length == 0) {
                    result = unwrap_elements.call(this, _elements);
                } else {
                    result = _elements[arguments[0]].get('element');
                }

                return result;
            };

            _this.hasClass = function(_class) {
                var result = false;

                for(var i in _elements) {
                    if(_elements[i].hasClass(_class)) {
                        result = true;
                        break;
                    }
                }

                return result;
            };

            _this.html = function() {
                var result = this;

                if(arguments.length == 0) {
                    result = _elements[0].get('innerHTML');
                } else {
                    _elements[0].set('innerHTML', arguments[0]);
                }

                return result;
            }

            _this.index = function(_subject) {
                var result = -1;

                for(var i in _elements) {
                    if(_elements[i].get('element') === _subject) {
                        result = i;
                    }
                }

                return result;
            };

            _this.removeClass = function(_class) {
                for(var i in _elements) {
                    _elements[i].removeClass(_class);
                }

                return this;
            }

            _this.size = function() {
                return _elements.length;
            };

            _this.toggleClass = function() {
                if(arguments.length == 0) {
                    for(var i in _elements) {
                        if(_elements[i].hasClass) {
                            _elements[i].removeClass(arguments[0]);
                        } else {
                            _elements[i].addClass(arguments[0]);
                        }
                    }
                } else {
                    for(var i in _elements) {
                        if(arguments[1]) {
                            _elements[i].addClass(arguments[0]);
                        } else {
                            _elements[i].removeClass(arguments[0]);
                        }
                    }
                }

                return this;
            };

            _this.val = function() {
                var result = this;

                if(arguments.length == 0) {
                    result = this.attr('value');
                } else {
                    for(var i in _elements) {
                        this.attr('value', arguments[0]);
                    }
                }

                return result;
            };

            (function() {
                for(var i in _elements) {
                    _this[i] = _elements[i];
                }
            }).call(_this)

            return _this;
        }).call(this, init.apply(this, arguments));
    }
})(YAHOO.util.Selector, YAHOO.util.Element, YAHOO.util.Dom, YAHOO.util.Event);

})();

Most of the implemented functions are similar to what jQuery offers, therefore to use the yui_builder:


(function($) {
    // everyone loves $ function
    $(document.createElement('a'));
        .attr('href', 'test')
        .html('test')
        .appendTo(document.body);
})(yui_builder);

leave your comment

name is required

email is required

have a blog?

This blog uses scripts to assist and automate comment moderation, and the author of this blog post does not hold responsibility in the content of posted comments. Please note that activities such as flaming, ungrounded accusations as well as spamming will not be entertained.

Click to change color scheme