diff --git a/packages/blaze/builtins.js b/packages/blaze/builtins.js index 055815dafb..16bffc43e8 100644 --- a/packages/blaze/builtins.js +++ b/packages/blaze/builtins.js @@ -26,18 +26,17 @@ Blaze.Unless = function (conditionFunc, contentFunc, elseFunc) { }); }; -Blaze.With = function (data, func) { - if (! (this instanceof Blaze.With)) - // called without new - return new Blaze.With(data, func); +Blaze.With = Blaze.Controller.extend({ + constructor: function (data, func) { + if (! (this instanceof Blaze.With)) + // called without new + return new Blaze.With(data, func); - Blaze.Controller.call(this); + Blaze.With.__super__.constructor.call(this); - this.dataVar = (data instanceof Blaze.Var) ? data : Blaze.Var(data); - this.func = func; -}; -Blaze.__extends(Blaze.With, Blaze.Controller); -_.extend(Blaze.With.prototype, { + this.dataVar = (data instanceof Blaze.Var) ? data : Blaze.Var(data); + this.func = func; + }, render: function () { var func = this.func; return func(); diff --git a/packages/blaze/component.js b/packages/blaze/component.js index c90265a26e..83724af73f 100644 --- a/packages/blaze/component.js +++ b/packages/blaze/component.js @@ -15,12 +15,11 @@ // while Controllers straddle the gap between Components and the // timeless RenderPoints which keep no instance state. -Blaze.Controller = function () { - this.parentController = Blaze.currentController; -}; -__extends(Blaze.Controller, Blaze.RenderPoint); - -_.extend(Blaze.Controller.prototype, { +Blaze.Controller = Blaze.RenderPoint.extend({ + constructor: function () { + Blaze.Controller.__super__.constructor.call(this); + this.parentController = Blaze.currentController; + }, evaluate: function () { var self = this; return Blaze.withCurrentController(self, function () { @@ -53,12 +52,7 @@ Blaze.withCurrentController = function (controller, func) { } }; -Blaze.Component = function () { - Blaze.Controller.call(this); -}; -__extends(Blaze.Component, Blaze.Controller); - -_.extend(Blaze.Component.prototype, { +Blaze.Component = Blaze.Controller.extend({ renderToDOM: function () { var self = this; if (self.domrange) diff --git a/packages/blaze/materialize.js b/packages/blaze/materialize.js index c113dffb08..c8a158e3f4 100644 --- a/packages/blaze/materialize.js +++ b/packages/blaze/materialize.js @@ -26,10 +26,7 @@ Blaze.ToTextVisitor = HTML.ToTextVisitor.extend({ } }); -var ToTextController = Blaze.ToTextController = function () { - Blaze.Controller.call(this); -}; -__extends(Blaze.ToTextController, Blaze.Controller); +Blaze.ToTextController = Blaze.Controller.extend(); Blaze.toText = function (content, textMode) { if (! Deps.active) { @@ -48,7 +45,7 @@ Blaze.toText = function (content, textMode) { var visitor = new Blaze.ToTextVisitor; visitor.textMode = textMode; - var controller = (Blaze.currentController || new ToTextController); + var controller = (Blaze.currentController || new Blaze.ToTextController); return Blaze.withCurrentController(controller, function () { return visitor.visit(content); }); @@ -68,10 +65,7 @@ Blaze.ToHTMLVisitor = HTML.ToHTMLVisitor.extend({ } }); -var ToHTMLController = Blaze.ToHTMLController = function () { - Blaze.Controller.call(this); -}; -__extends(Blaze.ToHTMLController, Blaze.Controller); +Blaze.ToHTMLController = Blaze.Controller.extend(); // This function is mainly for server-side rendering and is not in the normal // code path for client-side rendering. @@ -81,7 +75,7 @@ Blaze.toHTML = function (content) { return Blaze.toHTML(content); }); } - var controller = (Blaze.currentController || new ToHTMLController); + var controller = (Blaze.currentController || new Blaze.ToHTMLController); return Blaze.withCurrentController(controller, function () { return (new Blaze.ToHTMLVisitor).visit(content); }); diff --git a/packages/blaze/package.js b/packages/blaze/package.js index 5d2fdee69c..1f2394cbd1 100644 --- a/packages/blaze/package.js +++ b/packages/blaze/package.js @@ -9,6 +9,7 @@ Package.on_use(function (api) { api.use('deps'); api.use('underscore'); // only the subset in microscore.js api.use('htmljs'); + api.use('jsclass'); //api.use('observe-sequence'); api.add_files([ diff --git a/packages/blaze/render.js b/packages/blaze/render.js index 7af833f56a..1ef48dd8a2 100644 --- a/packages/blaze/render.js +++ b/packages/blaze/render.js @@ -4,16 +4,13 @@ var _onstopForRender = function () { this.computation.stop(); }; -var RenderController = Blaze.RenderController = function () { - Blaze.Controller.call(this); -}; -__extends(Blaze.RenderController, Blaze.Controller); +Blaze.RenderController = Blaze.Controller.extend(); Blaze.render = function (func) { var range = new Blaze.DOMRange; var controller = Blaze.currentController; if (! controller) - controller = new RenderController; + controller = new Blaze.RenderController; range.computation = Deps.autorun(function () { Blaze.withCurrentController(controller, function () { diff --git a/packages/blaze/renderpoint.js b/packages/blaze/renderpoint.js index 3957e0753c..0b53fa70be 100644 --- a/packages/blaze/renderpoint.js +++ b/packages/blaze/renderpoint.js @@ -1,8 +1,6 @@ // RenderPoints must support being evaluated and/or createDOMRanged multiple // times. They must not contain per-instance state. -Blaze.RenderPoint = function () {}; - -_.extend(Blaze.RenderPoint.prototype, { +Blaze.RenderPoint = JSClass.create({ render: function () { return null; }, @@ -22,16 +20,16 @@ _.extend(Blaze.RenderPoint.prototype, { } }); -Blaze.Isolate = function (func) { - if (! (this instanceof Blaze.Isolate)) - // called without new - return new Blaze.Isolate(func); +Blaze.Isolate = Blaze.RenderPoint.extend({ + constructor: function (func) { + if (! (this instanceof Blaze.Isolate)) + // called without new + return new Blaze.Isolate(func); - this.func = func; -}; -__extends(Blaze.Isolate, Blaze.RenderPoint); + Blaze.Isolate.__super__.constructor.call(this); -_.extend(Blaze.Isolate.prototype, { + this.func = func; + }, render: function () { var func = this.func; return func(); @@ -42,21 +40,21 @@ _.extend(Blaze.Isolate.prototype, { }); -Blaze.List = function (funcSequence) { - var self = this; +Blaze.List = Blaze.RenderPoint.extend({ + constructor: function (funcSequence) { + var self = this; - if (! (self instanceof Blaze.List)) - // called without `new` - return new Blaze.List(funcSequence); + if (! (self instanceof Blaze.List)) + // called without `new` + return new Blaze.List(funcSequence); - if (! (funcSequence instanceof Blaze.Sequence)) - throw new Error("Expected a Blaze.Sequence of functions in Blaze.List"); + if (! (funcSequence instanceof Blaze.Sequence)) + throw new Error("Expected a Blaze.Sequence of functions in Blaze.List"); - self.funcSeq = funcSequence; -}; -__extends(Blaze.List, Blaze.RenderPoint); + Blaze.List.__super__.constructor.call(this); -_.extend(Blaze.List.prototype, { + self.funcSeq = funcSequence; + }, render: function () { var funcSeq = this.funcSeq; this.funcSeq.depend(); diff --git a/packages/classes/classes.js b/packages/classes/classes.js deleted file mode 100644 index 95a8fdaf64..0000000000 --- a/packages/classes/classes.js +++ /dev/null @@ -1,52 +0,0 @@ -Classes = {}; - -// _assign is like _.extend or the upcoming Object.assign. -// Copy src's own, enumerable properties onto tgt and return -// tgt. -var _hasOwnProperty = Object.prototype.hasOwnProperty; -var _assign = function (tgt, src) { - for (var k in src) { - if (_hasOwnProperty.call(src, k)) - tgt[k] = src[k]; - } - return tgt; -}; - -Classes._extends = function(child, parent) { - _.extend(child, parent); - if (Object.create) { - child.prototype = Object.create(parent.prototype); - } else { - var ctor = function () {}; - ctor.prototype = parent.prototype; - child.prototype = new ctor(); - } - child.prototype.constructor = child; - child.__super__ = parent.prototype; - return child; -}; - -Classes._extend = function (props) { - var parent = this !== Classes ? this : null; - var constructor; - if (_hasOwnProperty(props, 'constructor')) { - constructor = props.constructor; - } else if (parent) { - constructor = function () { parent.apply(this, arguments); }; - } else { - constructor = function () {}; - } - - if (parent) - Classes._extends(constructor, parent); - - _assign(constructor.prototype, props); - - return constructor; -}; - -Classes.create = function (props, parentClass) { - var constructor = Classes._extend.call(parentClass || Classes, props); - constructor.extend = Classes._extend; - return constructor; -}; diff --git a/packages/jsclass/.gitignore b/packages/jsclass/.gitignore new file mode 100644 index 0000000000..677a6fc263 --- /dev/null +++ b/packages/jsclass/.gitignore @@ -0,0 +1 @@ +.build* diff --git a/packages/jsclass/jsclass.js b/packages/jsclass/jsclass.js new file mode 100644 index 0000000000..bb815101f9 --- /dev/null +++ b/packages/jsclass/jsclass.js @@ -0,0 +1,74 @@ +JSClass = {}; + +// _assign is like _.extend or the upcoming Object.assign. +// Copy src's own, enumerable properties onto tgt and return +// tgt. +var _hasOwnProperty = Object.prototype.hasOwnProperty; +var _assign = function (tgt, src) { + for (var k in src) { + if (_hasOwnProperty.call(src, k)) + tgt[k] = src[k]; + } + return tgt; +}; + +JSClass._extends = function(cls, supr) { + _assign(cls, supr); + if (Object.create) { + cls.prototype = Object.create(supr.prototype); + } else { + var ctor = function () {}; + ctor.prototype = supr.prototype; + cls.prototype = new ctor(); + } + cls.prototype.constructor = cls; + cls.__super__ = supr.prototype; + return cls; +}; + +JSClass._extend = function (props) { + var supr = this !== JSClass ? this : null; + var constructor; + if (props && _hasOwnProperty.call(props, 'constructor')) { + constructor = props.constructor; + } else if (supr) { + constructor = function () { supr.apply(this, arguments); }; + } else { + constructor = function () {}; + } + + if (supr) + JSClass._extends(constructor, supr); + + if (props) + _assign(constructor.prototype, props); + + return constructor; +}; + +/** + * JSClass.create([props], [superClass]) + * + * Defines a new class and returns it. + * + * * `props` - optional dictionary of properties (typically methods) + * to assign to the prototype. The `constructor` method is special + * and becomes the class constructor. + * + * * `superClass` - optional superclass + * + * If a superclass is provided but no constructor, a default constructor + * is supplied that calls the super constructor. + * + * All classes created in this way have a `.extend(props)` method that + * creates a superclass. + */ +JSClass.create = function (props, superClass) { + if (typeof props === 'function') { + superClass = props; + props = null; + } + var constructor = JSClass._extend.call(superClass || JSClass, props); + constructor.extend = JSClass._extend; + return constructor; +}; diff --git a/packages/classes/package.js b/packages/jsclass/package.js similarity index 100% rename from packages/classes/package.js rename to packages/jsclass/package.js diff --git a/packages/templating/global_template_object.js b/packages/templating/global_template_object.js index 3e22e9e383..13b956f43c 100644 --- a/packages/templating/global_template_object.js +++ b/packages/templating/global_template_object.js @@ -6,9 +6,9 @@ Template.__define__ = function (templateName, renderFunc) { if (Template.hasOwnProperty(templateName)) throw new Error("There are multiple templates named '" + templateName + "'. Each template needs a unique name."); - Template[templateName] = UI.Component.extend({ - kind: "Template_" + templateName, - render: renderFunc, - __helperHost: true + var templateClass = UI.Component2.extend({ + render: renderFunc }); + + Template[templateName] = templateClass.prototype; }; diff --git a/packages/ui/newblaze.js b/packages/ui/newblaze.js index 1bbe4eab25..ae9ce5549b 100644 --- a/packages/ui/newblaze.js +++ b/packages/ui/newblaze.js @@ -10,3 +10,5 @@ _.extend(UI.body2, { }); } }); + +UI.Component2 = Blaze.Component;