/* Copyright (c) 2004-2006, The Dojo Foundation All Rights Reserved. Licensed under the Academic Free License version 2.1 or above OR the modified BSD license. For more information on Dojo licensing, see: http://dojotoolkit.org/community/licensing.shtml */ dojo.provide("dojo.lang.declare"); dojo.require("dojo.lang.common"); dojo.require("dojo.lang.extras"); /* * Creates a constructor: inherit and extend * * - inherits from "superclass(es)" * * "superclass" argument may be a Function, or an array of * Functions. * * If "superclass" is an array, the first element is used * as the prototypical ancestor and any following Functions * become mixin ancestors. * * All "superclass(es)" must be Functions (not mere Objects). * * Using mixin ancestors provides a type of multiple * inheritance. Mixin ancestors prototypical * properties are copied to the subclass, and any * inializater/constructor is invoked. * * - "props" are copied to the constructor prototype * * - name of the class ("className" argument) is stored in * "declaredClass" property * * - An initializer function can be specified in the "init" * argument, or by including a function called "initializer" * in "props". * * - Superclass methods (inherited methods) can be invoked using "inherited" method: * * this.inherited([, ]); * * - inherited will continue up the prototype chain until it finds an implementation of method * - nested calls to inherited are supported (i.e. inherited method "A" can succesfully call inherited("A"), and so on) * * Aliased as "dojo.declare" * * Usage: * * dojo.declare("my.classes.bar", my.classes.foo, { * initializer: function() { * this.myComplicatedObject = new ReallyComplicatedObject(); * }, * someValue: 2, * aMethod: function() { doStuff(); } * }); * */ dojo.lang.declare = function(className /*string*/, superclass /*function || array*/, init /*function*/, props /*object*/){ // FIXME: parameter juggling for backward compat ... deprecate and remove after 0.3.* // new sig: (className (string)[, superclass (function || array)[, init (function)][, props (object)]]) // old sig: (className (string)[, superclass (function || array), props (object), init (function)]) if ((dojo.lang.isFunction(props))||((!props)&&(!dojo.lang.isFunction(init)))){ var temp = props; props = init; init = temp; } var mixins = [ ]; if (dojo.lang.isArray(superclass)) { mixins = superclass; superclass = mixins.shift(); } if(!init){ init = dojo.evalObjPath(className, false); if ((init)&&(!dojo.lang.isFunction(init))){ init = null }; } var ctor = dojo.lang.declare._makeConstructor(); var scp = (superclass ? superclass.prototype : null); if(scp){ scp.prototyping = true; ctor.prototype = new superclass(); scp.prototyping = false; } ctor.superclass = scp; ctor.mixins = mixins; for(var i=0,l=mixins.length; i