in Clients/CrossBrowser/Xamarin.CrossBrowser.Mac/WrappedObject.cs [155:212]
static WrappedObject Inflate<T> (JSValue value) where T : WrappedObject
{
if (value == null || value.IsNull || value.IsUndefined)
return null;
if (typeof(T) == typeof(WrappedObject))
return new WrappedObject (value);
if (typeof(T) == typeof(Range))
return new Range (value);
else if (typeof(T) == typeof(Selection))
return new Selection (value);
var valueStr = value.ToString ().ToLowerInvariant ();
Type wrappedType;
if (!typeMap.TryGetValue (valueStr, out wrappedType)) {
if (valueStr == null ||
!valueStr.StartsWith ("[object ", StringComparison.Ordinal) ||
!valueStr.EndsWith ("]", StringComparison.Ordinal)) {
// element.toString doesn't return [object HTMLWhateverElement] for some element types,
// so if an object passes these tests, it's probably an HTML element anyway...
// for whatever reason this always returns [object Window], which should be a sure
// way to get the real type of an object (and works in the inspector console):
// value.Context.EvaluateScript ("Object.prototype.toString").Call (value)
// sigh.
if (value.HasProperty ("nodeType") && value.HasProperty ("nodeName")) {
switch (value.GetProperty ("nodeType").ToInt32 ()) {
case 1: // ELEMENT_NODE
return value.HasProperty ("isContentEditable")
? Inflate<T> (value, typeof(HtmlElement))
: Inflate<T> (value, typeof(Element));
}
}
return new WrappedObject (value);
}
var typeName = valueStr.Substring (8, valueStr.Length - 9);
wrappedType = typeof(WrappedObject).Assembly.GetType (
typeof(WrappedObject).Namespace + "." + typeName,
false, true);
if (wrappedType == null) {
if (typeName.EndsWith ("element", StringComparison.Ordinal))
wrappedType = typeName.StartsWith ("html", StringComparison.Ordinal)
? typeof(HtmlElement)
: typeof(Element);
else if (typeName.EndsWith ("event", StringComparison.Ordinal))
wrappedType = typeof(Event);
}
if (wrappedType == null)
return new WrappedObject (value);
typeMap.Add (valueStr, wrappedType);
}
return Inflate<T> (value, wrappedType);
}