/* ox.js */ Ox = { version: "0.1.2" }; (function() { var _ = { uid: 0 }; Ox.makeObject = function() { /* >>> Ox.makeObject("foo", "bar").foo bar >>> Ox.makeObject({foo: "bar"}).foo bar */ var obj = {}; if (arguments.length == 1) { obj = arguments[0]; } else { obj[arguments[0]] = arguments[1] } return obj; } Ox.uid = function() { /* returns a unique id */ return _.uid++; } })(); /* ox.ui.js */ (function() { var _ = { elements: [], jQueryFunctions: function() { var functions = [], $element = $("
"); delete $element.length; $.each($element, function(k, v) { if (typeof v == "function") { functions.push(k); } }); return functions.sort(); }() }; Ox.Widget = function(options, self) { // construct var self = self || {}, that = this; // init (function() { if (typeof options == "string") { options = { element: options }; } that.ox = Ox.version; that.id = Ox.uid(); that.$element = $("<" + (options.element || "div") + "/>") .data("ox", that.id); _.elements[that.id] = that; wrapjQuery(); })(); // private function wrapjQuery() { $.each(_.jQueryFunctions, function(i, v) { that[v] = function() { var args = arguments, length = args.length, id, ret; $.each(args, function(i, v) { // if an ox object was passed // then pass its $element instead // so we can do jqObj.jqFn(oxObj) if (v.ox) { args[i] = v.$element; } }); // why does this not work? // ret = that.$element[v].apply(this, arguments); if (length == 0) { ret = that.$element[v](); } else if (length == 1) { ret = that.$element[v](args[0]); } else if (length == 2) { ret = that.$element[v](args[0], args[1]); } else if (length == 3) { ret = that.$element[v](args[0], args[1], args[2]); } else if (length == 4) { ret = that.$element[v](args[0], args[1], args[2], args[3]); } // if the $element of an ox object was returned // then return the ox object instead // so we can do oxObj.jqFn().oxFn() return ret.jquery && oxui.elements[id = ret.data("ox")] ? oxui.elements[id] : ret; } }); } // shared self.onChange = function() { /* self.onChange(option, value) is called when an option changes to be implemented by widget */ }; // public that.defaults = function(defaults) { /* that.defaults({foo: x}) sets self.defaults */ self.defaults = defaults; return that; } that.options = function() { /* that.options() returns self.options that.options("foo") returns self.options.foo that.options("foo", x) sets self.options.foo, returns that that.options({foo: x, bar: y}) sets self.options.foo and self.options.bar, returns that */ var length = arguments.length, args, ret; if (length == 0) { // options() ret = self.options; } else if (length == 1 && typeof arguments[0] == "string") { // options(str) ret = self.options[arguments[0]] } else { // options (str, val) or options({str: val, ...}) // translate (str, val) to ({str: val}) args = Ox.makeObject.apply(that, arguments); // if options have not been set, extend defaults, // otherwise, extend options self.options = $.extend( self.options || self.defaults, args); $.each(args, function(k, v) { self.onChange(k, v); }); ret = that; } return ret; } // return return that; } /* Widget Design Pattern Ox.MyWidget = function(options, self) { // construct var self = self || {}, that = new Ox.Widget({...}, self) .defaults({...}) .options(options || {}); // init, wrapped in function so it can be collapsed (function() {...})(); // private, can be called from init function foo() {...} // private, shared self.onChange = function(option, value) {...} self.foo = function() {...} // public that.foo = function() {...} // return return that; } */ Ox.Foo = function(options, self) { var self = self || {}, that = new Ox.Widget({ element: "div" }, self) .defaults({ foo: "bar" }) .options(options || {}); (function() { self.time = Date.now(); })(); self.onChange = function(option, value) { if (option == "foo") { Ox.print("foo set to", value); } } that.getTime = function() { return self.time; } return that; } Ox.Bar = function(options, self) { var self = self || {}, that = Ox.Foo({ foo: "baz" }, self) .defaults({ bar: "xyz" }) .options(options || {}); (function() { self.time = 0; })(); that.bar = function() { Ox.print("Bar.bar()"); } return that; } })();