|  | @@ -36,13 +36,13 @@
 | 
	
		
			
				|  |  |  /* Make that console is defined */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  if (typeof console === "undefined") {
 | 
	
		
			
				|  |  | -    this.console = {
 | 
	
		
			
				|  |  | -	log: function() {},
 | 
	
		
			
				|  |  | -	warn: function() {},
 | 
	
		
			
				|  |  | -	info: function() {},
 | 
	
		
			
				|  |  | -	debug: function() {},
 | 
	
		
			
				|  |  | -	error: function() {}
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | +	this.console = {
 | 
	
		
			
				|  |  | +		log: function() {},
 | 
	
		
			
				|  |  | +		warn: function() {},
 | 
	
		
			
				|  |  | +		info: function() {},
 | 
	
		
			
				|  |  | +		debug: function() {},
 | 
	
		
			
				|  |  | +		error: function() {}
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -53,472 +53,472 @@ function SmalltalkBehavior(){};
 | 
	
		
			
				|  |  |  function SmalltalkClass(){};
 | 
	
		
			
				|  |  |  function SmalltalkPackage(){};
 | 
	
		
			
				|  |  |  function SmalltalkMetaclass(){
 | 
	
		
			
				|  |  | -    this.meta = true;
 | 
	
		
			
				|  |  | +	this.meta = true;
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  function SmalltalkMethod(){};
 | 
	
		
			
				|  |  |  function SmalltalkNil(){};
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  function Smalltalk(){
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    var st = this;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    /* This is the current call context object. While it is publicly available,
 | 
	
		
			
				|  |  | -       Use smalltalk.getThisContext() instead which will answer a safe copy of 
 | 
	
		
			
				|  |  | -       the current context */
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    st.thisContext = undefined;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    /* List of all reserved words in JavaScript. They may not be used as variables
 | 
	
		
			
				|  |  | -       in Smalltalk. */
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    st.reservedWords = ['break', 'case', 'catch', 'class', 'continue', 'debugger', 
 | 
	
		
			
				|  |  | -			'default', 'delete', 'do', 'else', 'finally', 'for', 'function', 
 | 
	
		
			
				|  |  | -			'if', 'in', 'instanceof', 'new', 'private', 'protected', 
 | 
	
		
			
				|  |  | -			'public', 'return', 'static', 'switch', 'this', 'throw',
 | 
	
		
			
				|  |  | -			'try', 'typeof', 'var', 'void', 'while', 'with', 'yield'];
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | -    /* We hold all Packages in a separate Object */
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    st.packages = {};
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    /* Smalltalk package creation. To add a Package, use smalltalk.addPackage() */
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    function pkg(spec) {
 | 
	
		
			
				|  |  | -	var that      = new SmalltalkPackage();
 | 
	
		
			
				|  |  | -	that.pkgName  = spec.pkgName;
 | 
	
		
			
				|  |  | -	that.properties = spec.properties || [];
 | 
	
		
			
				|  |  | -	return that;
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    /* Smalltalk class creation. A class is an instance of an automatically 
 | 
	
		
			
				|  |  | -       created metaclass object. Newly created classes (not their metaclass) 
 | 
	
		
			
				|  |  | -       should be added to the smalltalk object, see smalltalk.addClass().
 | 
	
		
			
				|  |  | -       Superclass linking is *not* handled here, see smalltalk.init()  */
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    function klass(spec) {
 | 
	
		
			
				|  |  | -	var spec = spec || {};
 | 
	
		
			
				|  |  | -	var that;
 | 
	
		
			
				|  |  | -	if(spec.meta) {
 | 
	
		
			
				|  |  | -	    that = new SmalltalkMetaclass();
 | 
	
		
			
				|  |  | -	} else {
 | 
	
		
			
				|  |  | -	    that = new (klass({meta: true})).fn;
 | 
	
		
			
				|  |  | -	    that.klass.instanceClass = that;
 | 
	
		
			
				|  |  | -	    that.className = spec.className;
 | 
	
		
			
				|  |  | -	    that.klass.className = that.className + ' class';
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	
 | 
	
		
			
				|  |  | -	that.fn = spec.fn || function(){};
 | 
	
		
			
				|  |  | -	that.superclass = spec.superclass;
 | 
	
		
			
				|  |  | -	that.iVarNames = spec.iVarNames || [];
 | 
	
		
			
				|  |  | -	if(that.superclass) {
 | 
	
		
			
				|  |  | -	    that.klass.superclass = that.superclass.klass;
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	that.pkg = spec.pkg;
 | 
	
		
			
				|  |  | -	that.fn.prototype.methods = {};
 | 
	
		
			
				|  |  | -	that.fn.prototype.inheritedMethods = {};
 | 
	
		
			
				|  |  | -	that.fn.prototype.klass = that;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	return that;
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    /* Smalltalk method object. To add a method to a class,
 | 
	
		
			
				|  |  | -       use smalltalk.addMethod() */
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    st.method = function(spec) {
 | 
	
		
			
				|  |  | -	var that = new SmalltalkMethod();
 | 
	
		
			
				|  |  | -	that.selector          = spec.selector;
 | 
	
		
			
				|  |  | -	that.jsSelector        = spec.jsSelector;
 | 
	
		
			
				|  |  | -	that.args              = spec.args || {};
 | 
	
		
			
				|  |  | -	that.category          = spec.category;
 | 
	
		
			
				|  |  | -	that.source            = spec.source;
 | 
	
		
			
				|  |  | -	that.messageSends      = spec.messageSends || [];
 | 
	
		
			
				|  |  | -	that.referencedClasses = spec.referencedClasses || [];
 | 
	
		
			
				|  |  | -	that.fn                = spec.fn;
 | 
	
		
			
				|  |  | -	return that
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    /* Initialize a class in its class hierarchy. Handle both class and
 | 
	
		
			
				|  |  | -       metaclasses. */
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    st.init = function(klass) {
 | 
	
		
			
				|  |  | -	var subclasses = st.subclasses(klass);
 | 
	
		
			
				|  |  | -	var methods;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	if(klass.superclass && klass.superclass !== nil) {
 | 
	
		
			
				|  |  | -	    methods = st.methods(klass.superclass);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	    //Methods linking
 | 
	
		
			
				|  |  | -	    for(var i in methods) {
 | 
	
		
			
				|  |  | -		if(!klass.fn.prototype.methods[i]) {
 | 
	
		
			
				|  |  | -		    klass.fn.prototype.inheritedMethods[i] = methods[i];
 | 
	
		
			
				|  |  | -		    klass.fn.prototype[methods[i].jsSelector] = methods[i].fn;
 | 
	
		
			
				|  |  | +	var st = this;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/* This is the current call context object. While it is publicly available,
 | 
	
		
			
				|  |  | +	   Use smalltalk.getThisContext() instead which will answer a safe copy of 
 | 
	
		
			
				|  |  | +	   the current context */
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	st.thisContext = undefined;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/* List of all reserved words in JavaScript. They may not be used as variables
 | 
	
		
			
				|  |  | +	   in Smalltalk. */
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	st.reservedWords = ['break', 'case', 'catch', 'char', 'class', 'continue', 'debugger', 
 | 
	
		
			
				|  |  | +		'default', 'delete', 'do', 'else', 'finally', 'for', 'function', 
 | 
	
		
			
				|  |  | +		'if', 'in', 'instanceof', 'new', 'private', 'protected', 
 | 
	
		
			
				|  |  | +		'public', 'return', 'static', 'switch', 'this', 'throw',
 | 
	
		
			
				|  |  | +		'try', 'typeof', 'var', 'void', 'while', 'with', 'yield'];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/* We hold all Packages in a separate Object */
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	st.packages = {};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/* Smalltalk package creation. To add a Package, use smalltalk.addPackage() */
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	function pkg(spec) {
 | 
	
		
			
				|  |  | +		var that      = new SmalltalkPackage();
 | 
	
		
			
				|  |  | +		that.pkgName  = spec.pkgName;
 | 
	
		
			
				|  |  | +		that.properties = spec.properties || {};
 | 
	
		
			
				|  |  | +		return that;
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/* Smalltalk class creation. A class is an instance of an automatically 
 | 
	
		
			
				|  |  | +	   created metaclass object. Newly created classes (not their metaclass) 
 | 
	
		
			
				|  |  | +	   should be added to the smalltalk object, see smalltalk.addClass().
 | 
	
		
			
				|  |  | +	   Superclass linking is *not* handled here, see smalltalk.init()  */
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	function klass(spec) {
 | 
	
		
			
				|  |  | +		var spec = spec || {};
 | 
	
		
			
				|  |  | +		var that;
 | 
	
		
			
				|  |  | +		if(spec.meta) {
 | 
	
		
			
				|  |  | +			that = new SmalltalkMetaclass();
 | 
	
		
			
				|  |  | +		} else {
 | 
	
		
			
				|  |  | +			that = new (klass({meta: true})).fn;
 | 
	
		
			
				|  |  | +			that.klass.instanceClass = that;
 | 
	
		
			
				|  |  | +			that.className = spec.className;
 | 
	
		
			
				|  |  | +			that.klass.className = that.className + ' class';
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  | -	    }
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	for(var i=0;i<subclasses.length;i++) {
 | 
	
		
			
				|  |  | -     	    st.init(subclasses[i]);
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	if(klass.klass && !klass.meta) {
 | 
	
		
			
				|  |  | -	    st.init(klass.klass);
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | +		that.fn = spec.fn || function(){};
 | 
	
		
			
				|  |  | +		that.superclass = spec.superclass;
 | 
	
		
			
				|  |  | +		that.iVarNames = spec.iVarNames || [];
 | 
	
		
			
				|  |  | +		if(that.superclass) {
 | 
	
		
			
				|  |  | +			that.klass.superclass = that.superclass.klass;
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		that.pkg = spec.pkg;
 | 
	
		
			
				|  |  | +		that.fn.prototype.methods = {};
 | 
	
		
			
				|  |  | +		that.fn.prototype.inheritedMethods = {};
 | 
	
		
			
				|  |  | +		that.fn.prototype.klass = that;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		return that;
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/* Smalltalk method object. To add a method to a class,
 | 
	
		
			
				|  |  | +	   use smalltalk.addMethod() */
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	st.method = function(spec) {
 | 
	
		
			
				|  |  | +		var that = new SmalltalkMethod();
 | 
	
		
			
				|  |  | +		that.selector          = spec.selector;
 | 
	
		
			
				|  |  | +		that.jsSelector        = spec.jsSelector;
 | 
	
		
			
				|  |  | +		that.args              = spec.args || {};
 | 
	
		
			
				|  |  | +		that.category          = spec.category;
 | 
	
		
			
				|  |  | +		that.source            = spec.source;
 | 
	
		
			
				|  |  | +		that.messageSends      = spec.messageSends || [];
 | 
	
		
			
				|  |  | +		that.referencedClasses = spec.referencedClasses || [];
 | 
	
		
			
				|  |  | +		that.fn                = spec.fn;
 | 
	
		
			
				|  |  | +		return that
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/* Initialize a class in its class hierarchy. Handle both class and
 | 
	
		
			
				|  |  | +	   metaclasses. */
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	st.init = function(klass) {
 | 
	
		
			
				|  |  | +		var subclasses = st.subclasses(klass);
 | 
	
		
			
				|  |  | +		var methods;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		if(klass.superclass && klass.superclass !== nil) {
 | 
	
		
			
				|  |  | +			methods = st.methods(klass.superclass);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +			//Methods linking
 | 
	
		
			
				|  |  | +			for(var i in methods) {
 | 
	
		
			
				|  |  | +				if(!klass.fn.prototype.methods[i]) {
 | 
	
		
			
				|  |  | +					klass.fn.prototype.inheritedMethods[i] = methods[i];
 | 
	
		
			
				|  |  | +					klass.fn.prototype[methods[i].jsSelector] = methods[i].fn;
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    /* Answer all registered Packages as Array */
 | 
	
		
			
				|  |  | +		for(var i=0;i<subclasses.length;i++) {
 | 
	
		
			
				|  |  | +			st.init(subclasses[i]);
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		if(klass.klass && !klass.meta) {
 | 
	
		
			
				|  |  | +			st.init(klass.klass);
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    st.packages.all = function() {
 | 
	
		
			
				|  |  | -	var packages = [];
 | 
	
		
			
				|  |  | -	for(var i in st.packages) {
 | 
	
		
			
				|  |  | -          if (!st.packages.hasOwnProperty(i) || typeof(st.packages[i]) === "function") continue;
 | 
	
		
			
				|  |  | -	    packages.push(st.packages[i]);
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	return packages
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | +	/* Answer all registered Packages as Array */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    /* Answer all registered Smalltalk classes */
 | 
	
		
			
				|  |  | +	st.packages.all = function() {
 | 
	
		
			
				|  |  | +		var packages = [];
 | 
	
		
			
				|  |  | +		for(var i in st.packages) {
 | 
	
		
			
				|  |  | +			if (!st.packages.hasOwnProperty(i) || typeof(st.packages[i]) === "function") continue;
 | 
	
		
			
				|  |  | +			packages.push(st.packages[i]);
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		return packages
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    st.classes = function() {
 | 
	
		
			
				|  |  | -	var classes = [];
 | 
	
		
			
				|  |  | -	for(var i in st) {
 | 
	
		
			
				|  |  | -	    if(i.search(/^[A-Z]/g) != -1) {
 | 
	
		
			
				|  |  | -		classes.push(st[i]);
 | 
	
		
			
				|  |  | -	    }
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	return classes
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | +	/* Answer all registered Smalltalk classes */
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	st.classes = function() {
 | 
	
		
			
				|  |  | +		var classes = [];
 | 
	
		
			
				|  |  | +		for(var i in st) {
 | 
	
		
			
				|  |  | +			if(i.search(/^[A-Z]/g) != -1) {
 | 
	
		
			
				|  |  | +				classes.push(st[i]);
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		return classes
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    /* Answer all methods (included inherited ones) of klass. */
 | 
	
		
			
				|  |  | +	/* Answer all methods (included inherited ones) of klass. */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    st.methods = function(klass) {
 | 
	
		
			
				|  |  | -	var methods = {};
 | 
	
		
			
				|  |  | -	for(var i in klass.fn.prototype.methods) {
 | 
	
		
			
				|  |  | -	    methods[i] = klass.fn.prototype.methods[i]
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	for(var i in klass.fn.prototype.inheritedMethods) {
 | 
	
		
			
				|  |  | -	    methods[i] = klass.fn.prototype.inheritedMethods[i]
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	return methods;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    /* Answer the direct subclasses of klass. */
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    st.subclasses = function(klass) {
 | 
	
		
			
				|  |  | -	var subclasses = [];
 | 
	
		
			
				|  |  | -	var classes = st.classes();
 | 
	
		
			
				|  |  | -	for(var i in classes) {
 | 
	
		
			
				|  |  | -	    if(classes[i].fn) {
 | 
	
		
			
				|  |  | -		//Metaclasses
 | 
	
		
			
				|  |  | -		if(classes[i].klass && classes[i].klass.superclass === klass) {
 | 
	
		
			
				|  |  | -		    subclasses.push(classes[i].klass);
 | 
	
		
			
				|  |  | +	st.methods = function(klass) {
 | 
	
		
			
				|  |  | +		var methods = {};
 | 
	
		
			
				|  |  | +		for(var i in klass.fn.prototype.methods) {
 | 
	
		
			
				|  |  | +			methods[i] = klass.fn.prototype.methods[i]
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  | -		//Classes
 | 
	
		
			
				|  |  | -		if(classes[i].superclass === klass) {
 | 
	
		
			
				|  |  | -		    subclasses.push(classes[i]);
 | 
	
		
			
				|  |  | +		for(var i in klass.fn.prototype.inheritedMethods) {
 | 
	
		
			
				|  |  | +			methods[i] = klass.fn.prototype.inheritedMethods[i]
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  | -	    }
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	return subclasses;
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    /* Create a new class wrapping a JavaScript constructor, and add it to the 
 | 
	
		
			
				|  |  | -       global smalltalk object. Package is lazily created if it does not exist with given name. */
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    st.mapClassName = function(className, pkgName, fn, superclass) {
 | 
	
		
			
				|  |  | -	var pkg = st.addPackage(pkgName, null);
 | 
	
		
			
				|  |  | -	st[className] = klass({
 | 
	
		
			
				|  |  | -	    className:  className, 
 | 
	
		
			
				|  |  | -	    superclass: superclass,
 | 
	
		
			
				|  |  | -	    pkg:        pkg, 
 | 
	
		
			
				|  |  | -	    fn:         fn
 | 
	
		
			
				|  |  | -	});
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    /* Add a package to the smalltalk.packages object, creating a new one if needed.
 | 
	
		
			
				|  |  | -       If pkgName is null or empty we return nil, which is an allowed package for a class.
 | 
	
		
			
				|  |  | -       If package already exists we still update the properties of it. */
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    st.addPackage = function(pkgName, properties) {
 | 
	
		
			
				|  |  | -	if(!pkgName) {return nil;}
 | 
	
		
			
				|  |  | -	if(!(st.packages[pkgName])) {
 | 
	
		
			
				|  |  | -	    st.packages[pkgName] = pkg({
 | 
	
		
			
				|  |  | -		pkgName: pkgName,
 | 
	
		
			
				|  |  | -		properties: properties
 | 
	
		
			
				|  |  | -	    });
 | 
	
		
			
				|  |  | -	} else {
 | 
	
		
			
				|  |  | -	    if(properties) {
 | 
	
		
			
				|  |  | -		st.packages[pkgName].properties = properties;
 | 
	
		
			
				|  |  | -	    }	
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	return st.packages[pkgName];
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    /* Add a class to the smalltalk object, creating a new one if needed.
 | 
	
		
			
				|  |  | -       Package is lazily created if it does not exist with given name.*/
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    st.addClass = function(className, superclass, iVarNames, pkgName) {
 | 
	
		
			
				|  |  | -	var pkg = st.addPackage(pkgName, null);
 | 
	
		
			
				|  |  | -	if(st[className]) {
 | 
	
		
			
				|  |  | -	    st[className].superclass = superclass;
 | 
	
		
			
				|  |  | -	    st[className].iVarNames = iVarNames;
 | 
	
		
			
				|  |  | -	    st[className].pkg = pkg || st[className].pkg;
 | 
	
		
			
				|  |  | -	} else {    
 | 
	
		
			
				|  |  | -	    st[className] = klass({
 | 
	
		
			
				|  |  | -		className: className, 
 | 
	
		
			
				|  |  | -		superclass: superclass,
 | 
	
		
			
				|  |  | -		pkg: pkg,
 | 
	
		
			
				|  |  | -		iVarNames: iVarNames
 | 
	
		
			
				|  |  | -	    });
 | 
	
		
			
				|  |  | +		return methods;
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    /* Add a method to a class */
 | 
	
		
			
				|  |  | +	/* Answer the direct subclasses of klass. */
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	st.subclasses = function(klass) {
 | 
	
		
			
				|  |  | +		var subclasses = [];
 | 
	
		
			
				|  |  | +		var classes = st.classes();
 | 
	
		
			
				|  |  | +		for(var i in classes) {
 | 
	
		
			
				|  |  | +			if(classes[i].fn) {
 | 
	
		
			
				|  |  | +				//Metaclasses
 | 
	
		
			
				|  |  | +				if(classes[i].klass && classes[i].klass.superclass === klass) {
 | 
	
		
			
				|  |  | +					subclasses.push(classes[i].klass);
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +				//Classes
 | 
	
		
			
				|  |  | +				if(classes[i].superclass === klass) {
 | 
	
		
			
				|  |  | +					subclasses.push(classes[i]);
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		return subclasses;
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/* Create a new class wrapping a JavaScript constructor, and add it to the 
 | 
	
		
			
				|  |  | +	   global smalltalk object. Package is lazily created if it does not exist with given name. */
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	st.mapClassName = function(className, pkgName, fn, superclass) {
 | 
	
		
			
				|  |  | +		var pkg = st.addPackage(pkgName);
 | 
	
		
			
				|  |  | +		st[className] = klass({
 | 
	
		
			
				|  |  | +			className:  className, 
 | 
	
		
			
				|  |  | +			superclass: superclass,
 | 
	
		
			
				|  |  | +			pkg:        pkg, 
 | 
	
		
			
				|  |  | +			fn:         fn
 | 
	
		
			
				|  |  | +		});
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/* Add a package to the smalltalk.packages object, creating a new one if needed.
 | 
	
		
			
				|  |  | +	   If pkgName is null or empty we return nil, which is an allowed package for a class.
 | 
	
		
			
				|  |  | +	   If package already exists we still update the properties of it. */
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	st.addPackage = function(pkgName, properties) {
 | 
	
		
			
				|  |  | +		if(!pkgName) {return nil;}
 | 
	
		
			
				|  |  | +		if(!(st.packages[pkgName])) {
 | 
	
		
			
				|  |  | +			st.packages[pkgName] = pkg({
 | 
	
		
			
				|  |  | +				pkgName: pkgName,
 | 
	
		
			
				|  |  | +				properties: properties
 | 
	
		
			
				|  |  | +			});
 | 
	
		
			
				|  |  | +		} else {
 | 
	
		
			
				|  |  | +			if(properties) {
 | 
	
		
			
				|  |  | +				st.packages[pkgName].properties = properties;
 | 
	
		
			
				|  |  | +			}	
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		return st.packages[pkgName];
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/* Add a class to the smalltalk object, creating a new one if needed.
 | 
	
		
			
				|  |  | +	   Package is lazily created if it does not exist with given name.*/
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	st.addClass = function(className, superclass, iVarNames, pkgName) {
 | 
	
		
			
				|  |  | +		var pkg = st.addPackage(pkgName);
 | 
	
		
			
				|  |  | +		if(st[className]) {
 | 
	
		
			
				|  |  | +			st[className].superclass = superclass;
 | 
	
		
			
				|  |  | +			st[className].iVarNames = iVarNames;
 | 
	
		
			
				|  |  | +			st[className].pkg = pkg || st[className].pkg;
 | 
	
		
			
				|  |  | +		} else {    
 | 
	
		
			
				|  |  | +			st[className] = klass({
 | 
	
		
			
				|  |  | +				className: className, 
 | 
	
		
			
				|  |  | +				superclass: superclass,
 | 
	
		
			
				|  |  | +				pkg: pkg,
 | 
	
		
			
				|  |  | +				iVarNames: iVarNames
 | 
	
		
			
				|  |  | +			});
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    st.addMethod = function(jsSelector, method, klass) {
 | 
	
		
			
				|  |  | -	klass.fn.prototype[jsSelector] = method.fn;
 | 
	
		
			
				|  |  | -	klass.fn.prototype.methods[method.selector] = method;
 | 
	
		
			
				|  |  | -	method.methodClass = klass;
 | 
	
		
			
				|  |  | -	method.jsSelector = jsSelector;
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | +	/* Add a method to a class */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    /* Handles Smalltalk message send. Automatically converts undefined to the nil object.
 | 
	
		
			
				|  |  | -       If the receiver does not understand the selector, call its #doesNotUnderstand: method */
 | 
	
		
			
				|  |  | +	st.addMethod = function(jsSelector, method, klass) {
 | 
	
		
			
				|  |  | +		klass.fn.prototype[jsSelector] = method.fn;
 | 
	
		
			
				|  |  | +		klass.fn.prototype.methods[method.selector] = method;
 | 
	
		
			
				|  |  | +		method.methodClass = klass;
 | 
	
		
			
				|  |  | +		method.jsSelector = jsSelector;
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    sendWithoutContext = function(receiver, selector, args, klass) {
 | 
	
		
			
				|  |  | -	if(receiver === undefined || receiver === null) {
 | 
	
		
			
				|  |  | -	    receiver = nil;
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	if(!klass && receiver.klass && receiver[selector]) {
 | 
	
		
			
				|  |  | -	    return receiver[selector].apply(receiver, args);
 | 
	
		
			
				|  |  | -	} else if(klass && klass.fn.prototype[selector]) {
 | 
	
		
			
				|  |  | -	    return klass.fn.prototype[selector].apply(receiver, args)
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	return messageNotUnderstood(receiver, selector, args);
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | +	/* Handles Smalltalk message send. Automatically converts undefined to the nil object.
 | 
	
		
			
				|  |  | +	   If the receiver does not understand the selector, call its #doesNotUnderstand: method */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +	sendWithoutContext = function(receiver, selector, args, klass) {
 | 
	
		
			
				|  |  | +		if(receiver === undefined || receiver === null) {
 | 
	
		
			
				|  |  | +			receiver = nil;
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		if(!klass && receiver.klass && receiver[selector]) {
 | 
	
		
			
				|  |  | +			return receiver[selector].apply(receiver, args);
 | 
	
		
			
				|  |  | +		} else if(klass && klass.fn.prototype[selector]) {
 | 
	
		
			
				|  |  | +			return klass.fn.prototype[selector].apply(receiver, args)
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		return messageNotUnderstood(receiver, selector, args);
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    /* Handles unhandled errors during message sends */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    sendWithContext = function(receiver, selector, args, klass) {
 | 
	
		
			
				|  |  | -	if(st.thisContext) {
 | 
	
		
			
				|  |  | -	     return withContextSend(receiver, selector, args, klass);
 | 
	
		
			
				|  |  | -	} else {
 | 
	
		
			
				|  |  | -	    try {return withContextSend(receiver, selector, args, klass)}
 | 
	
		
			
				|  |  | -	    catch(error) {
 | 
	
		
			
				|  |  | -		// Reset the context stack in any case
 | 
	
		
			
				|  |  | -		st.thisContext = undefined;
 | 
	
		
			
				|  |  | -		if(error.smalltalkError) {
 | 
	
		
			
				|  |  | -		    handleError(error);
 | 
	
		
			
				|  |  | +	/* Handles unhandled errors during message sends */
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	sendWithContext = function(receiver, selector, args, klass) {
 | 
	
		
			
				|  |  | +		if(st.thisContext) {
 | 
	
		
			
				|  |  | +			return withContextSend(receiver, selector, args, klass);
 | 
	
		
			
				|  |  |  		} else {
 | 
	
		
			
				|  |  | -		    throw(error);
 | 
	
		
			
				|  |  | +			try {return withContextSend(receiver, selector, args, klass)}
 | 
	
		
			
				|  |  | +			catch(error) {
 | 
	
		
			
				|  |  | +				// Reset the context stack in any case
 | 
	
		
			
				|  |  | +				st.thisContext = undefined;
 | 
	
		
			
				|  |  | +				if(error.smalltalkError) {
 | 
	
		
			
				|  |  | +					handleError(error);
 | 
	
		
			
				|  |  | +				} else {
 | 
	
		
			
				|  |  | +					throw(error);
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  | -	    }
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    /* Same as sendWithoutContext but creates a methodContext. */
 | 
	
		
			
				|  |  | +	/* Same as sendWithoutContext but creates a methodContext. */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    withContextSend = function(receiver, selector, args, klass) {
 | 
	
		
			
				|  |  | -	var call, context;
 | 
	
		
			
				|  |  | -	if(receiver === undefined || receiver === null) {
 | 
	
		
			
				|  |  | -	    receiver = nil;
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	if(!klass && receiver.klass && receiver[selector]) {
 | 
	
		
			
				|  |  | -	    context = pushContext(receiver, selector, args);
 | 
	
		
			
				|  |  | -	    call = receiver[selector].apply(receiver, args);
 | 
	
		
			
				|  |  | -	    popContext(context);
 | 
	
		
			
				|  |  | -	    return call;
 | 
	
		
			
				|  |  | -	} else if(klass && klass.fn.prototype[selector]) {
 | 
	
		
			
				|  |  | -	    context = pushContext(receiver, selector, args);
 | 
	
		
			
				|  |  | -	    call = klass.fn.prototype[selector].apply(receiver, args);
 | 
	
		
			
				|  |  | -	    popContext(context);
 | 
	
		
			
				|  |  | -	    return call;
 | 
	
		
			
				|  |  | +	withContextSend = function(receiver, selector, args, klass) {
 | 
	
		
			
				|  |  | +		var call, context;
 | 
	
		
			
				|  |  | +		if(receiver === undefined || receiver === null) {
 | 
	
		
			
				|  |  | +			receiver = nil;
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		if(!klass && receiver.klass && receiver[selector]) {
 | 
	
		
			
				|  |  | +			context = pushContext(receiver, selector, args);
 | 
	
		
			
				|  |  | +			call = receiver[selector].apply(receiver, args);
 | 
	
		
			
				|  |  | +			popContext(context);
 | 
	
		
			
				|  |  | +			return call;
 | 
	
		
			
				|  |  | +		} else if(klass && klass.fn.prototype[selector]) {
 | 
	
		
			
				|  |  | +			context = pushContext(receiver, selector, args);
 | 
	
		
			
				|  |  | +			call = klass.fn.prototype[selector].apply(receiver, args);
 | 
	
		
			
				|  |  | +			popContext(context);
 | 
	
		
			
				|  |  | +			return call;
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		return messageNotUnderstood(receiver, selector, args);
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/* Handles Smalltalk errors. Triggers the registered ErrorHandler 
 | 
	
		
			
				|  |  | +	   (See the Smalltalk class ErrorHandler and its subclasses */
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	function handleError(error) {
 | 
	
		
			
				|  |  | +		st.thisContext = undefined;
 | 
	
		
			
				|  |  | +		smalltalk.ErrorHandler._current()._handleError_(error);
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | -	return messageNotUnderstood(receiver, selector, args);
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    /* Handles Smalltalk errors. Triggers the registered ErrorHandler 
 | 
	
		
			
				|  |  | -       (See the Smalltalk class ErrorHandler and its subclasses */
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | -    function handleError(error) {
 | 
	
		
			
				|  |  | -	st.thisContext = undefined;
 | 
	
		
			
				|  |  | -	smalltalk.ErrorHandler._current()._handleError_(error);
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | +	/* Handles #dnu: *and* JavaScript method calls.
 | 
	
		
			
				|  |  | +	   if the receiver has no klass, we consider it a JS object (outside of the
 | 
	
		
			
				|  |  | +	   Amber system). Else assume that the receiver understands #doesNotUnderstand: */
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	function messageNotUnderstood(receiver, selector, args) {
 | 
	
		
			
				|  |  | +		/* Handles JS method calls. */
 | 
	
		
			
				|  |  | +		if(receiver.klass === undefined || receiver.allowJavaScriptCalls) {
 | 
	
		
			
				|  |  | +			return callJavaScriptMethod(receiver, selector, args);
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    /* Handles #dnu: *and* JavaScript method calls.
 | 
	
		
			
				|  |  | -       if the receiver has no klass, we consider it a JS object (outside of the
 | 
	
		
			
				|  |  | -       Amber system). Else assume that the receiver understands #doesNotUnderstand: */
 | 
	
		
			
				|  |  | +		/* Handles not understood messages. Also see the Amber counter-part 
 | 
	
		
			
				|  |  | +		   Object>>doesNotUnderstand: */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    function messageNotUnderstood(receiver, selector, args) {
 | 
	
		
			
				|  |  | -	/* Handles JS method calls. */
 | 
	
		
			
				|  |  | -	if(receiver.klass === undefined || receiver.allowJavaScriptCalls) {
 | 
	
		
			
				|  |  | -	    return callJavaScriptMethod(receiver, selector, args);
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | +		return receiver._doesNotUnderstand_(
 | 
	
		
			
				|  |  | +				st.Message._new()
 | 
	
		
			
				|  |  | +				._selector_(st.convertSelector(selector))
 | 
	
		
			
				|  |  | +				._arguments_(args)
 | 
	
		
			
				|  |  | +				);
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	/* Handles not understood messages. Also see the Amber counter-part 
 | 
	
		
			
				|  |  | -	   Object>>doesNotUnderstand: */
 | 
	
		
			
				|  |  | -	
 | 
	
		
			
				|  |  | -	return receiver._doesNotUnderstand_(
 | 
	
		
			
				|  |  | -	    st.Message._new()
 | 
	
		
			
				|  |  | -		._selector_(st.convertSelector(selector))
 | 
	
		
			
				|  |  | -		._arguments_(args)
 | 
	
		
			
				|  |  | -	);
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    function callJavaScriptMethod(receiver, selector, args) {
 | 
	
		
			
				|  |  |  	/* Call a method of a JS object, or answer a property if it exists.
 | 
	
		
			
				|  |  |  	   Else try wrapping a JSObjectProxy around the receiver.
 | 
	
		
			
				|  |  | - 
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  	   Converts keyword-based selectors by using the first
 | 
	
		
			
				|  |  |  	   keyword only, but keeping all message arguments.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	   Example:
 | 
	
		
			
				|  |  |  	   "self do: aBlock with: anObject" -> "self.do(aBlock, anObject)" */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	var jsSelector = selector._asJavaScriptSelector();
 | 
	
		
			
				|  |  | -	var jsProperty = receiver[jsSelector];
 | 
	
		
			
				|  |  | -	if(typeof jsProperty === "function") {
 | 
	
		
			
				|  |  | -	    return jsProperty.apply(receiver, args);
 | 
	
		
			
				|  |  | -	} else if(jsProperty !== undefined) {
 | 
	
		
			
				|  |  | -	    if(args[0]) {
 | 
	
		
			
				|  |  | -		receiver[jsSelector] = args[0];
 | 
	
		
			
				|  |  | -		return nil;
 | 
	
		
			
				|  |  | -	    } else {
 | 
	
		
			
				|  |  | -		return jsProperty
 | 
	
		
			
				|  |  | -	    }
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	
 | 
	
		
			
				|  |  | -	return st.send(st.JSObjectProxy._on_(receiver), selector, args);
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | +	function callJavaScriptMethod(receiver, selector, args) {
 | 
	
		
			
				|  |  | +		var jsSelector = selector._asJavaScriptSelector();
 | 
	
		
			
				|  |  | +		var jsProperty = receiver[jsSelector];
 | 
	
		
			
				|  |  | +		if(typeof jsProperty === "function") {
 | 
	
		
			
				|  |  | +			return jsProperty.apply(receiver, args);
 | 
	
		
			
				|  |  | +		} else if(jsProperty !== undefined) {
 | 
	
		
			
				|  |  | +			if(args[0]) {
 | 
	
		
			
				|  |  | +				receiver[jsSelector] = args[0];
 | 
	
		
			
				|  |  | +				return nil;
 | 
	
		
			
				|  |  | +			} else {
 | 
	
		
			
				|  |  | +				return jsProperty
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +		return st.send(st.JSObjectProxy._on_(receiver), selector, args);
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    /* Reuse old contexts stored in oldContexts */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    st.oldContexts = [];
 | 
	
		
			
				|  |  | +	/* Reuse old contexts stored in oldContexts */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	
 | 
	
		
			
				|  |  | -    /* Handle thisContext pseudo variable */
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | -    st.getThisContext = function() {
 | 
	
		
			
				|  |  | -	if(st.thisContext) {
 | 
	
		
			
				|  |  | -	    return st.thisContext.copy();
 | 
	
		
			
				|  |  | -	} else {
 | 
	
		
			
				|  |  | -	    return undefined;
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | +	st.oldContexts = [];
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    pushContext = function(receiver, selector, temps) {
 | 
	
		
			
				|  |  | -	if(st.thisContext) {
 | 
	
		
			
				|  |  | -	    return st.thisContext = st.thisContext.newContext(receiver, selector, temps);
 | 
	
		
			
				|  |  | -	} else {
 | 
	
		
			
				|  |  | -	    return st.thisContext = new SmalltalkMethodContext(receiver, selector, temps);
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    popContext = function(context) {
 | 
	
		
			
				|  |  | -	if(context) {
 | 
	
		
			
				|  |  | -	    context.removeYourself();
 | 
	
		
			
				|  |  | +	/* Handle thisContext pseudo variable */
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	st.getThisContext = function() {
 | 
	
		
			
				|  |  | +		if(st.thisContext) {
 | 
	
		
			
				|  |  | +			return st.thisContext.copy();
 | 
	
		
			
				|  |  | +		} else {
 | 
	
		
			
				|  |  | +			return undefined;
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    /* Convert a string to a valid smalltalk selector.
 | 
	
		
			
				|  |  | -       if you modify the following functions, also change String>>asSelector
 | 
	
		
			
				|  |  | -       accordingly */
 | 
	
		
			
				|  |  | +	pushContext = function(receiver, selector, temps) {
 | 
	
		
			
				|  |  | +		if(st.thisContext) {
 | 
	
		
			
				|  |  | +			return st.thisContext = st.thisContext.newContext(receiver, selector, temps);
 | 
	
		
			
				|  |  | +		} else {
 | 
	
		
			
				|  |  | +			return st.thisContext = new SmalltalkMethodContext(receiver, selector, temps);
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    st.convertSelector = function(selector) {
 | 
	
		
			
				|  |  | -	if(selector.match(/__/)) {
 | 
	
		
			
				|  |  | -	    return convertBinarySelector(selector);
 | 
	
		
			
				|  |  | -	} else {
 | 
	
		
			
				|  |  | -	    return convertKeywordSelector(selector);
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    function convertKeywordSelector(selector) {
 | 
	
		
			
				|  |  | -	return selector.replace(/^_/, '').replace(/_/g, ':');
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    function convertBinarySelector(selector) {
 | 
	
		
			
				|  |  | -	return selector
 | 
	
		
			
				|  |  | -	    .replace(/^_/, '')
 | 
	
		
			
				|  |  | -	    .replace(/_plus/, '+')
 | 
	
		
			
				|  |  | -	    .replace(/_minus/, '-')
 | 
	
		
			
				|  |  | -	    .replace(/_star/, '*')
 | 
	
		
			
				|  |  | -	    .replace(/_slash/, '/')
 | 
	
		
			
				|  |  | -	    .replace(/_gt/, '>')
 | 
	
		
			
				|  |  | -	    .replace(/_lt/, '<')
 | 
	
		
			
				|  |  | -	    .replace(/_eq/, '=')
 | 
	
		
			
				|  |  | -	    .replace(/_comma/, ',')
 | 
	
		
			
				|  |  | -	    .replace(/_at/, '@')
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    /* Converts a JavaScript object to valid Smalltalk Object */
 | 
	
		
			
				|  |  | -    st.readJSObject = function(js) {
 | 
	
		
			
				|  |  | -	var object = js;
 | 
	
		
			
				|  |  | -	var readObject = (js.constructor === Object);
 | 
	
		
			
				|  |  | -	var readArray = (js.constructor === Array);
 | 
	
		
			
				|  |  | -	
 | 
	
		
			
				|  |  | -	if(readObject) {
 | 
	
		
			
				|  |  | -	    object = smalltalk.Dictionary._new();
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	for(var i in js) {
 | 
	
		
			
				|  |  | -	    if(readObject) {
 | 
	
		
			
				|  |  | -		object._at_put_(i, st.readJSObject(js[i]));
 | 
	
		
			
				|  |  | -	    } 
 | 
	
		
			
				|  |  | -	    if(readArray) {
 | 
	
		
			
				|  |  | -		object[i] = st.readJSObject(js[i]);
 | 
	
		
			
				|  |  | -	    }
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	return object;
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | +	popContext = function(context) {
 | 
	
		
			
				|  |  | +		if(context) {
 | 
	
		
			
				|  |  | +			context.removeYourself();
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    /* Toggle deployment mode (no context will be handled during message send */
 | 
	
		
			
				|  |  | -    st.setDeploymentMode = function() {
 | 
	
		
			
				|  |  | -	st.send = sendWithoutContext;
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | +	/* Convert a string to a valid smalltalk selector.
 | 
	
		
			
				|  |  | +	   if you modify the following functions, also change String>>asSelector
 | 
	
		
			
				|  |  | +	   accordingly */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    st.setDevelopmentMode = function() {
 | 
	
		
			
				|  |  | -	st.send = sendWithContext;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | +	st.convertSelector = function(selector) {
 | 
	
		
			
				|  |  | +		if(selector.match(/__/)) {
 | 
	
		
			
				|  |  | +			return convertBinarySelector(selector);
 | 
	
		
			
				|  |  | +		} else {
 | 
	
		
			
				|  |  | +			return convertKeywordSelector(selector);
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	function convertKeywordSelector(selector) {
 | 
	
		
			
				|  |  | +		return selector.replace(/^_/, '').replace(/_/g, ':');
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	function convertBinarySelector(selector) {
 | 
	
		
			
				|  |  | +		return selector
 | 
	
		
			
				|  |  | +			.replace(/^_/, '')
 | 
	
		
			
				|  |  | +			.replace(/_plus/, '+')
 | 
	
		
			
				|  |  | +			.replace(/_minus/, '-')
 | 
	
		
			
				|  |  | +			.replace(/_star/, '*')
 | 
	
		
			
				|  |  | +			.replace(/_slash/, '/')
 | 
	
		
			
				|  |  | +			.replace(/_gt/, '>')
 | 
	
		
			
				|  |  | +			.replace(/_lt/, '<')
 | 
	
		
			
				|  |  | +			.replace(/_eq/, '=')
 | 
	
		
			
				|  |  | +			.replace(/_comma/, ',')
 | 
	
		
			
				|  |  | +			.replace(/_at/, '@')
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/* Converts a JavaScript object to valid Smalltalk Object */
 | 
	
		
			
				|  |  | +	st.readJSObject = function(js) {
 | 
	
		
			
				|  |  | +		var object = js;
 | 
	
		
			
				|  |  | +		var readObject = (js.constructor === Object);
 | 
	
		
			
				|  |  | +		var readArray = (js.constructor === Array);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		if(readObject) {
 | 
	
		
			
				|  |  | +			object = smalltalk.Dictionary._new();
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		for(var i in js) {
 | 
	
		
			
				|  |  | +			if(readObject) {
 | 
	
		
			
				|  |  | +				object._at_put_(i, st.readJSObject(js[i]));
 | 
	
		
			
				|  |  | +			} 
 | 
	
		
			
				|  |  | +			if(readArray) {
 | 
	
		
			
				|  |  | +				object[i] = st.readJSObject(js[i]);
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		return object;
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    /* Set development mode by default */
 | 
	
		
			
				|  |  | -    st.setDevelopmentMode();
 | 
	
		
			
				|  |  | +	/* Toggle deployment mode (no context will be handled during message send */
 | 
	
		
			
				|  |  | +	st.setDeploymentMode = function() {
 | 
	
		
			
				|  |  | +		st.send = sendWithoutContext;
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	st.setDevelopmentMode = function() {
 | 
	
		
			
				|  |  | +		st.send = sendWithContext;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/* Set development mode by default */
 | 
	
		
			
				|  |  | +	st.setDevelopmentMode();
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  function SmalltalkMethodContext(receiver, selector, temps, home) {
 | 
	
		
			
				|  |  | -    var that = this;
 | 
	
		
			
				|  |  | -    that.receiver = receiver;
 | 
	
		
			
				|  |  | -    that.selector = selector;
 | 
	
		
			
				|  |  | -    that.temps = temps || {};
 | 
	
		
			
				|  |  | -    that.homeContext = home;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    that.copy = function() {
 | 
	
		
			
				|  |  | -	var home = that.homeContext;
 | 
	
		
			
				|  |  | -	if(home) {home = home.copy()}
 | 
	
		
			
				|  |  | -	return new SmalltalkMethodContext(
 | 
	
		
			
				|  |  | -	    that.receiver, 
 | 
	
		
			
				|  |  | -	    that.selector, 
 | 
	
		
			
				|  |  | -	    that.temps, 
 | 
	
		
			
				|  |  | -	    home
 | 
	
		
			
				|  |  | -	);
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    that.newContext = function(receiver, selector, temps) {
 | 
	
		
			
				|  |  | -	var c = smalltalk.oldContexts.pop();
 | 
	
		
			
				|  |  | -	if(c) {
 | 
	
		
			
				|  |  | -	    c.homeContext = that;
 | 
	
		
			
				|  |  | -	    c.receiver = receiver;
 | 
	
		
			
				|  |  | -	    c.selector = selector;
 | 
	
		
			
				|  |  | -	    c.temps = temps || {};
 | 
	
		
			
				|  |  | -	} else {
 | 
	
		
			
				|  |  | -	    c = new SmalltalkMethodContext(receiver, selector, temps, that);
 | 
	
		
			
				|  |  | +	var that = this;
 | 
	
		
			
				|  |  | +	that.receiver = receiver;
 | 
	
		
			
				|  |  | +	that.selector = selector;
 | 
	
		
			
				|  |  | +	that.temps = temps || {};
 | 
	
		
			
				|  |  | +	that.homeContext = home;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	that.copy = function() {
 | 
	
		
			
				|  |  | +		var home = that.homeContext;
 | 
	
		
			
				|  |  | +		if(home) {home = home.copy()}
 | 
	
		
			
				|  |  | +		return new SmalltalkMethodContext(
 | 
	
		
			
				|  |  | +				that.receiver, 
 | 
	
		
			
				|  |  | +				that.selector, 
 | 
	
		
			
				|  |  | +				that.temps, 
 | 
	
		
			
				|  |  | +				home
 | 
	
		
			
				|  |  | +				);
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	that.newContext = function(receiver, selector, temps) {
 | 
	
		
			
				|  |  | +		var c = smalltalk.oldContexts.pop();
 | 
	
		
			
				|  |  | +		if(c) {
 | 
	
		
			
				|  |  | +			c.homeContext = that;
 | 
	
		
			
				|  |  | +			c.receiver = receiver;
 | 
	
		
			
				|  |  | +			c.selector = selector;
 | 
	
		
			
				|  |  | +			c.temps = temps || {};
 | 
	
		
			
				|  |  | +		} else {
 | 
	
		
			
				|  |  | +			c = new SmalltalkMethodContext(receiver, selector, temps, that);
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		return c;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	that.removeYourself = function() {
 | 
	
		
			
				|  |  | +		smalltalk.thisContext = that.homeContext;
 | 
	
		
			
				|  |  | +		that.homeContext = undefined;
 | 
	
		
			
				|  |  | +		smalltalk.oldContexts.push(that);
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | -	return c;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    that.removeYourself = function() {
 | 
	
		
			
				|  |  | -	smalltalk.thisContext = that.homeContext;
 | 
	
		
			
				|  |  | -	that.homeContext = undefined;
 | 
	
		
			
				|  |  | -	smalltalk.oldContexts.push(that);
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /* Global Smalltalk objects. */
 | 
	
	
		
			
				|  | @@ -527,7 +527,7 @@ var nil = new SmalltalkNil();
 | 
	
		
			
				|  |  |  var smalltalk = new Smalltalk();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  if(this.jQuery) {
 | 
	
		
			
				|  |  | -    this.jQuery.allowJavaScriptCalls = true;
 | 
	
		
			
				|  |  | +	this.jQuery.allowJavaScriptCalls = true;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /****************************************************************************************/
 |