Browse Source

added check for native js objects to __instanceof, Std.is should work with native objects where typof returns "object" now
added function for getting js [[Class]]
added function for resolving native classes
added handling of native objects to getClass
added null-check to Type.getClassName to avoid error when a native class is used
added resolving of native classes to Type.resolveClass

mockey 11 years ago
parent
commit
580fd45c0a
2 changed files with 32 additions and 7 deletions
  1. 29 6
      std/js/Boot.hx
  2. 3 1
      std/js/_std/Type.hx

+ 29 - 6
std/js/Boot.hx

@@ -70,8 +70,13 @@ class Boot {
 	static inline function getClass(o:Dynamic) : Dynamic {
 		if (Std.is(o, Array))
 			return Array;
-		else
-			return untyped __define_feature__("js.Boot.getClass", o.__class__);
+		else {
+			var name = __nativeClassName(o);
+			if (name == "Object" || name == "Function")
+				return untyped __define_feature__("js.Boot.getClass", o.__class__);
+			else
+				return __resolveNativeClass(name);
+		}
 	}
 
 	@:ifFeature("may_print_enum")
@@ -180,11 +185,10 @@ class Boot {
 			return true;
 		default:
 			if( o != null ) {
-				// Check if o is an instance of a Haxe class
-				if( (untyped __js__("typeof"))(cl) == "function" ) {
-					if( untyped __js__("o instanceof cl") ) {
+				// Check if o is an instance of a Haxe class or a native JS object
+				if( (untyped __js__("typeof"))(cl) == "function" || __isNativeObj(cl) ) {
+					if( untyped __js__("o instanceof cl") )
 						return true;
-					}
 					if( __interfLoop(getClass(o),cl) )
 						return true;
 				}
@@ -202,5 +206,24 @@ class Boot {
 		if (__instanceof(o, t)) return o;
 		else throw "Cannot cast " +Std.string(o) + " to " +Std.string(t);
 	}
+	
+	// get native JS [[Class]]
+	static function __nativeClassName(o:Dynamic):String {
+		return untyped __js__("{}.toString").call(o).slice(8, -1);
+	}
+	
+	// check for usable native JS object
+	static function __isNativeObj(o:Dynamic):Bool {
+		var name = __nativeClassName(o);
+		// exclude general Object and Function
+		// and also Math and JSON, because instanceof cannot be called on them
+		return name != "Object" && name != "Function" && name != "Math" && name != "JSON";
+	}
+	
+	// resolve native JS class (with window or global):
+	static function __resolveNativeClass(name:String) untyped {
+		var g = __js__("typeof")(window) != "undefined" ? window : global;
+		return g[name];
+	}
 
 }

+ 3 - 1
std/js/_std/Type.hx

@@ -52,6 +52,8 @@ enum ValueType {
 
 	public static function getClassName( c : Class<Dynamic> ) : String {
 		var a : Array<String> = untyped c.__name__;
+		if (a == null)
+			return null;
 		return a.join(".");
 	}
 
@@ -64,7 +66,7 @@ enum ValueType {
 		var cl : Class<Dynamic> = $hxClasses[name];
 		// ensure that this is a class
 		if( cl == null || !js.Boot.isClass(cl) )
-			return null;
+			return js.Boot.__resolveNativeClass(name);
 		return cl;
 	}