private static Func<object, object> GetFunc(string funcName, ObjectInstance exports) { var func = exports.Get(funcName); if (func.IsUndefined() || func.IsNull()) { return null; } if (func.Is<ICallable>()) { return s => { var model = JintProcessorHelper.ConvertStrongTypeToJsValue(s); return func.Invoke(model).ToObject(); }; } else { throw new InvalidPreprocessorException($"Invalid '{funcName}' variable definition. '{funcName} MUST be a function"); } }
private JsValue Str(string key, ObjectInstance holder) { var value = holder.Get(key); if (value.IsObject()) { var toJson = value.AsObject().Get("toJSON"); if (toJson.IsObject()) { var callableToJson = toJson.AsObject() as ICallable; if (callableToJson != null) { value = callableToJson.Call(value, Arguments.From(key)); } } } if (_replacerFunction != Undefined.Instance) { var replacerFunctionCallable = (ICallable)_replacerFunction.AsObject(); value = replacerFunctionCallable.Call(holder, Arguments.From(key, value)); } if (value.IsObject()) { var valueObj = value.AsObject(); switch (valueObj.Class) { case "Number": value = TypeConverter.ToNumber(value); break; case "String": value = TypeConverter.ToString(value); break; case "Boolean": value = TypeConverter.ToPrimitive(value); break; case "Array": value = SerializeArray(value.As<ArrayInstance>()); return value; case "Object": value = SerializeObject(value.AsObject()); return value; } } if (value == Null.Instance) { return "null"; } if (value.IsBoolean() && value.AsBoolean()) { return "true"; } if (value.IsBoolean() && !value.AsBoolean()) { return "false"; } if (value.IsString()) { return Quote(value.AsString()); } if (value.IsNumber()) { if (GlobalObject.IsFinite(Undefined.Instance, Arguments.From(value)).AsBoolean()) { return TypeConverter.ToString(value); } return "null"; } var isCallable = value.IsObject() && value.AsObject() is ICallable; if (value.IsObject() && isCallable == false) { if (value.AsObject().Class == "Array") { return SerializeArray(value.As<ArrayInstance>()); } return SerializeObject(value.AsObject()); } return JsValue.Undefined; }
/// <summary> /// Loads this plugin /// </summary> public override void Load() { // Load the plugin LoadSource(); if (JavaScriptEngine.GetValue(Name).TryCast<ObjectInstance>() == null) throw new Exception("Plugin is missing main object"); Class = JavaScriptEngine.GetValue(Name).AsObject(); if (!Class.HasProperty("Name")) Class.FastAddProperty("Name", Name, true, false, true); else Class.Put("Name", Name, true); // Read plugin attributes if (!Class.HasProperty("Title") || string.IsNullOrEmpty(Class.Get("Title").AsString())) throw new Exception("Plugin is missing title"); if (!Class.HasProperty("Author") || string.IsNullOrEmpty(Class.Get("Author").AsString())) throw new Exception("Plugin is missing author"); if (!Class.HasProperty("Version") || Class.Get("Version").ToObject() == null) throw new Exception("Plugin is missing version"); Title = Class.Get("Title").AsString(); Author = Class.Get("Author").AsString(); Version = (VersionNumber) Class.Get("Version").ToObject(); if (Class.HasProperty("Description")) Description = Class.Get("Description").AsString(); if (Class.HasProperty("ResourceId")) ResourceId = (int)Class.Get("ResourceId").AsNumber(); HasConfig = Class.HasProperty("HasConfig") && Class.Get("HasConfig").AsBoolean(); // Set attributes Class.FastAddProperty("Plugin", JsValue.FromObject(JavaScriptEngine, this), true, false, true); Globals = new Dictionary<string, ICallable>(); foreach (var property in Class.GetOwnProperties()) { var callable = property.Value.Value?.TryCast<ICallable>(); if (callable != null) Globals.Add(property.Key, callable); } foreach (var property in Class.Prototype.GetOwnProperties()) { var callable = property.Value.Value?.TryCast<ICallable>(); if (callable != null) Globals.Add(property.Key, callable); } if (!HasConfig) HasConfig = Globals.ContainsKey("LoadDefaultConfig"); // Bind any base methods (we do it here because we don't want them to be hooked) BindBaseMethods(); }