public static void Register(IJsEngine engine) { if (engine == null) throw new NullReferenceException(); _scriptEngine = engine; }
/// <summary> /// Destroys object /// </summary> public void Dispose() { if (!_disposed) { _disposed = true; if (_jsEngine != null) { _jsEngine.Dispose(); _jsEngine = null; } } }
/// <summary> /// Collects garbage in the specified V8 engine. /// </summary> /// <param name="engine"></param> private static void V8CollectGarbage(IJsEngine engine) { // Since JavaScriptEngineSwitcher does not expose the inner JavaScript engine, we need // to use reflection to get to it. if (_innerEngineField == null) { _innerEngineField = engine.GetType().GetField("_jsEngine", BindingFlags.NonPublic | BindingFlags.Instance); } var innerJsEngine = _innerEngineField.GetValue(engine); // Use reflection to get the garbage collection method so we don't have a hard // dependency on ClearScript. Not ideal but this will do for now. if (_collectGarbageMethod == null) { _collectGarbageMethod = innerJsEngine.GetType().GetMethod("CollectGarbage"); } _collectGarbageMethod.Invoke(innerJsEngine, new object[] { true }); }
/// <summary> /// Disposes the object and frees resources for the Garbage Collector. /// </summary> /// <param name="disposing">If true, the object gets disposed.</param> private void Dispose(bool disposing) { if (this.isDisposed) { return; } if (disposing) { if (this.javascriptEngine != null) { this.javascriptEngine.Dispose(); this.javascriptEngine = null; } } // Call the appropriate methods to clean up // unmanaged resources here. // Note disposing is done. this.isDisposed = true; }
/// <summary> /// Tries to execute a code from embedded JavaScript resource with pre-compilation. /// </summary> /// <param name="engine">Engine to execute a code from embedded JavaScript resource with pre-compilation</param> /// <param name="cache">Cache used for storing the pre-compiled scripts</param> /// <param name="resourceName">The case-sensitive resource name</param> /// <param name="assembly">The assembly, which contains the embedded resource</param> /// <returns>true if can perform a script pre-compilation; otherwise, false.</returns> public static bool TryExecuteResourceWithPrecompilation(this IJsEngine engine, ICache cache, string resourceName, Assembly assembly) { EnsurePrecompilationAvailability(engine, cache); var cacheKey = string.Format(PRECOMPILED_JS_RESOURCE_CACHE_KEY, resourceName); var precompiledScript = cache.Get <IPrecompiledScript>(cacheKey); if (precompiledScript == null) { precompiledScript = engine.PrecompileResource(resourceName, assembly); cache.Set( cacheKey, precompiledScript, slidingExpiration: PRECOMPILED_JS_CACHE_ENTRY_SLIDING_EXPIRATION ); } engine.Execute(precompiledScript); return(true); }
/// <summary> /// Disposes the object and frees resources for the Garbage Collector. /// </summary> /// <param name="disposing">If true, the object gets disposed.</param> private void Dispose(bool disposing) { if (this.isDisposed) { return; } if (disposing) { if (this.javascriptEngine != null) { this.javascriptEngine.RemoveVariable(COUNTRY_STATISTICS_SERVICE_VARIABLE_NAME); this.javascriptEngine.Dispose(); this.javascriptEngine = null; } } // Call the appropriate methods to clean up // unmanaged resources here. // Note disposing is done. this.isDisposed = true; }
/// <summary> /// Constructs an instance of the Autoprefixer /// </summary> /// <param name="jsEngineFactory">JS engine factory</param> /// <param name="options">Processing options</param> public Autoprefixer(IJsEngineFactory jsEngineFactory, ProcessingOptions options) { if (jsEngineFactory == null) { throw new ArgumentNullException(nameof(jsEngineFactory)); } _options = options ?? _defaultOptions; _serializedOptions = SerializeProcessingOptions(_options); try { _jsEngine = jsEngineFactory.CreateEngine(); } catch (JsEngineLoadException e) { throw AutoprefixerErrorHelpers.WrapAutoprefixerLoadException(e); } catch (Exception e) { throw AutoprefixerErrorHelpers.WrapAutoprefixerLoadException(e, true); } }
/// <summary> /// Loads standard React and Babel scripts into the engine. /// </summary> protected virtual void InitialiseEngine(IJsEngine engine) { var thisAssembly = typeof(ReactEnvironment).Assembly; engine.ExecuteResource("React.Resources.shims.js", thisAssembly); if (_config.LoadReact) { engine.ExecuteResource("React.Resources.react-with-addons.js", thisAssembly); engine.Execute("React = global.React"); } if (_config.LoadBabel) { engine.ExecuteResource("React.node_modules.babel_core.browser.js", thisAssembly); } LoadUserScripts(engine); if (!_config.LoadReact) { // We expect to user to have loaded their own versino of React in the scripts that // were loaded above, let's ensure that's the case. EnsureReactLoaded(engine); } }
/// <summary> /// Constructs an instance of the Autoprefixer /// </summary> /// <param name="createJsEngineInstance">Delegate that creates an instance of JS engine</param> /// <param name="options">Processing options</param> public Autoprefixer(Func <IJsEngine> createJsEngineInstance, ProcessingOptions options) { if (createJsEngineInstance == null) { throw new ArgumentNullException(nameof(createJsEngineInstance)); } _options = options ?? _defaultOptions; _serializedOptions = SerializeProcessingOptions(_options); try { _jsEngine = createJsEngineInstance(); } catch (JsEngineLoadException e) { throw AutoprefixerErrorHelpers.WrapAutoprefixerLoadException(e); } catch (Exception e) { throw AutoprefixerErrorHelpers.WrapAutoprefixerLoadException(e, true); } }
/// <summary> /// Gets a factory for the most appropriate JavaScript engine for the current environment. /// The first functioning JavaScript engine with the lowest priority will be used. /// </summary> /// <returns>Function to create JavaScript engine</returns> private static Func <IJsEngine> GetFactory(IEnumerable <Registration> availableFactories) { var availableEngineFactories = availableFactories .OrderBy(x => x.Priority) .Select(x => x.Factory); foreach (var engineFactory in availableEngineFactories) { IJsEngine engine = null; try { engine = engineFactory(); // Perform a sanity test to ensure this engine is usable if (engine.Evaluate <int>("1 + 1") == 2) { // Success! Use this one. return(engineFactory); } } catch (Exception ex) { // This engine threw an exception, try the next one Trace.WriteLine(string.Format("Error initialising {0}: {1}", engineFactory, ex)); } finally { if (engine != null) { engine.Dispose(); } } } // Epic fail, none of the engines worked. Nothing we can do now. throw new ReactException("No usable JavaScript engine found :("); }
public void ShouldCreateNewEngineForNewThread() { var factory = CreateBasicFactory(); var engine1 = factory.GetEngineForCurrentThread(); IJsEngine engine2 = null; var thread = new Thread(() => { engine2 = factory.GetEngineForCurrentThread(); // Need to ensure engine is disposed in same thread as it was created in factory.DisposeEngineForCurrentThread(); }); thread.Start(); thread.Join(); var engine3 = factory.GetEngineForCurrentThread(); // Different threads should have different engines Assert.NotEqual(engine1, engine2); // Same thread should share same engine Assert.Equal(engine1, engine3); factory.DisposeEngineForCurrentThread(); }
/// <summary> /// Calls a JavaScript function using the specified engine. If <typeparamref name="T"/> is /// not a scalar type, the function is assumed to return a string of JSON that can be /// parsed as that type. /// </summary> /// <typeparam name="T">Type returned by function</typeparam> /// <param name="engine">Engine to execute function with</param> /// <param name="function">Name of the function to execute</param> /// <param name="args">Arguments to pass to function</param> /// <returns>Value returned by function</returns> public static T CallFunctionReturningJson <T>(this IJsEngine engine, string function, params object[] args) { if (ValidationHelpers.IsSupportedType(typeof(T))) { // Type is supported directly (ie. a scalar type like string/int/bool) // Just execute the function directly. return(engine.CallFunction <T>(function, args)); } // The type is not a scalar type. Assume the function will return its result as // JSON. var resultJson = engine.CallFunction <string>(function, args); try { return(JsonConvert.DeserializeObject <T>(resultJson)); } catch (JsonReaderException ex) { throw new ReactException(string.Format( "{0} did not return valid JSON: {1}.\n\n{2}", function, ex.Message, resultJson )); } }
public JsEvaluationViewModel Evaluate(JsEvaluationViewModel model) { IJsEngine engine = null; var result = new JsEvaluationResultViewModel(); try { engine = _engineSwitcher.CreateEngine(model.EngineName); result.Value = engine.Evaluate <string>(model.Expression); } catch (JsEngineLoadException e) { var error = GetJsEvaluationErrorFromException(e); result.Errors.Add(error); } catch (JsRuntimeException e) { var error = GetJsEvaluationErrorFromException(e); error.LineNumber = e.LineNumber; error.ColumnNumber = e.ColumnNumber; error.SourceFragment = e.SourceFragment; result.Errors.Add(error); } finally { if (engine != null) { engine.Dispose(); } } model.Result = result; return(model); }
private static JObject DecodeData(string data, string key, out int keyId) { keyId = 0; IJsEngineSwitcher engineSwitcher = JsEngineSwitcher.Current; engineSwitcher.EngineFactories.Add(new JurassicJsEngineFactory()); engineSwitcher.DefaultEngineName = JurassicJsEngine.EngineName; using (IJsEngine engine = JsEngineSwitcher.Current.CreateDefaultEngine()) { engine.Execute(DedeDataJsCode); var publickey = engine.CallFunction("getCtKey", key); string PostjsonStr = engine.CallFunction("decode", data, publickey).ToString(); JObject jo; if (PostjsonStr.StartsWith("{")) { jo = JsonStringToJsonObj(PostjsonStr); if (jo != null) { return(jo); } } keyId = 1; engine.Execute("var this_UrlKey1 = 'db0FaVXtwixFUGGQ1Iq9dN7yMrJ9DFHQ';var this_UrlKey2 = 'R8nD2B0DRcT0IoFrA5UqHeHLeFsbrOBvXIVhKmgcXXcDLDrQemyyQLdDpAom9N'"); publickey = engine.CallFunction("getCtKey", key); PostjsonStr = engine.CallFunction("decode", data, publickey).ToString(); if (PostjsonStr.StartsWith("{")) { jo = JsonStringToJsonObj(PostjsonStr); if (jo != null) { return(jo); } } return(null); } }
/// <summary> /// Tries to execute a code from JavaScript file with pre-compilation. /// </summary> /// <param name="engine">Engine to execute code from JavaScript file with pre-compilation</param> /// <param name="cache">Cache used for storing the pre-compiled scripts</param> /// <param name="fileSystem">File system wrapper</param> /// <param name="path">Path to the JavaScript file</param> /// <param name="scriptLoader">Delegate that loads a code from specified JavaScript file</param> /// <returns>true if can perform a script pre-compilation; otherwise, false.</returns> public static bool TryExecuteFileWithPrecompilation(this IJsEngine engine, ICache cache, IFileSystem fileSystem, string path, Func <string, string> scriptLoader = null) { var cacheKey = string.Format(PRECOMPILED_JS_FILE_CACHE_KEY, path); var precompiledScript = cache.Get <IPrecompiledScript>(cacheKey); if (precompiledScript == null) { var contents = scriptLoader != null?scriptLoader(path) : fileSystem.ReadAsString(path); precompiledScript = engine.Precompile(contents, path); var fullPath = fileSystem.MapPath(path); cache.Set( cacheKey, precompiledScript, slidingExpiration: PRECOMPILED_JS_CACHE_ENTRY_SLIDING_EXPIRATION, cacheDependencyFiles: new[] { fullPath } ); } engine.Execute(precompiledScript); return(true); }
/// <summary> /// Loads any user-provided scripts. Only scripts that don't need JSX transformation can /// run immediately here. JSX files are loaded in ReactEnvironment. /// </summary> /// <param name="engine">Engine to load scripts into</param> private void LoadUserScripts(IJsEngine engine) { foreach (var file in _config.ScriptsWithoutTransform) { try { if (_config.AllowJavaScriptPrecompilation && engine.TryExecuteFileWithPrecompilation(_cache, _fileSystem, file)) { // Do nothing. } else { engine.ExecuteFile(_fileSystem, file); } } catch (JsScriptException ex) { // We can't simply rethrow the exception here, as it's possible this is running // on a background thread (ie. as a response to a file changing). If we did // throw the exception here, it would terminate the entire process. Instead, // save the exception, and then just rethrow it later when getting the engine. _scriptLoadException = new ReactScriptLoadException(string.Format( "Error while loading \"{0}\": {1}\r\nLine: {2}\r\nColumn: {3}", file, ex.Message, ex.LineNumber, ex.ColumnNumber )); } catch (IOException ex) { _scriptLoadException = new ReactScriptLoadException(ex.Message); } } }
/// <summary> /// Constructs a instance of CSS cleaner /// </summary> /// <param name="createJsEngineInstance">Delegate that creates an instance of JS engine</param> /// <param name="options">Cleaning options</param> public CssCleaner(Func <IJsEngine> createJsEngineInstance, CleaningOptions options) { _jsEngine = createJsEngineInstance(); _options = options ?? new CleaningOptions(); _optionsString = ConvertCleaningOptionsToJson(_options).ToString(); }
/// <summary> /// Initializes a new instance of the <see cref="AutoPrefixerProcessor"/> class. /// </summary> /// <param name="javascriptEngineFactory"> /// The javascript engine factory. /// </param> public AutoPrefixerProcessor(Func<IJsEngine> javascriptEngineFactory) { this.javascriptEngine = javascriptEngineFactory(); }
/// <summary> /// Returns an engine to the pool so it can be reused /// </summary> /// <param name="engine">Engine to return</param> public virtual void ReturnEngineToPool(IJsEngine engine) { if (!_metadata.ContainsKey(engine)) { // This engine was from another pool. This could happen if a pool is recycled // and replaced with a different one (like what ReactJS.NET does when any // loaded files change). Let's just pretend we never saw it. engine.Dispose(); return; } _metadata[engine].InUse = false; var usageCount = _metadata[engine].UsageCount; if (_config.MaxUsagesPerEngine > 0 && usageCount >= _config.MaxUsagesPerEngine) { // Engine has been reused the maximum number of times, recycle it. DisposeEngine(engine); return; } if ( _config.GarbageCollectionInterval > 0 && usageCount % _config.GarbageCollectionInterval == 0 && engine.SupportsGarbageCollection() ) { engine.CollectGarbage(); } _availableEngines.Add(engine); }
/// <summary> /// Configures the JavaScript engine that should be used to perform the string generation. /// </summary> /// <param name="engine"></param> public void ConfigureEngine(IJsEngine engine) { Debug.Assert(null != engine); this.Engine = engine; }
/// <summary> /// Marks the specified engine as "in use" /// </summary> /// <param name="engine"></param> private IJsEngine TakeEngine(IJsEngine engine) { _metadata[engine].InUse = true; _metadata[engine].UsageCount++; return(engine); }
/// <inheritdoc /> public IEnumerable <IDocument> Execute(IReadOnlyList <IDocument> inputs, IExecutionContext context) { HtmlParser parser = new HtmlParser(); using (IJsEnginePool enginePool = context.GetJsEnginePool(x => { if (string.IsNullOrWhiteSpace(_highlightJsFile)) { x.ExecuteResource("highlight-all.js", typeof(Highlight)); } else { x.ExecuteFile(_highlightJsFile); } })) { return(inputs.AsParallel().Select(context, input => { // We materialize the list before exiting the using statement, so safe to access enginePool // ReSharper disable once AccessToDisposedClosure using (IJsEngine engine = enginePool.GetEngine()) { try { using (Stream stream = input.GetStream()) using (IHtmlDocument htmlDocument = parser.Parse(stream)) { foreach (AngleSharp.Dom.IElement element in htmlDocument.QuerySelectorAll(_codeQuerySelector)) { // Don't highlight anything that potentially is already highlighted if (element.ClassList.Contains("hljs")) { continue; } // Make sure to use TextContent, otherwise you'll get escaped html which highlight.js won't parse engine.SetVariableValue("input", element.TextContent); // Check if they specified a language in their code block string language = element.ClassList.FirstOrDefault(i => i.StartsWith("language")); try { if (language != null) { engine.SetVariableValue("language", language.Replace("language-", "")); engine.Execute("result = hljs.highlight(language, input)"); } else { language = "(auto)"; // set this to auto in case there is an exception below engine.Execute("result = hljs.highlightAuto(input)"); string detectedLanguage = engine.Evaluate <string>("result.language"); if (string.IsNullOrWhiteSpace(detectedLanguage) == false) { element.ClassList.Add("language-" + detectedLanguage); } } element.ClassList.Add("hljs"); string formatted = engine.Evaluate <string>("result.value"); element.InnerHtml = formatted; } catch (Exception innerEx) { if (innerEx.Message.Contains("Unknown language: ") && _warnOnMissingLanguage) { Trace.Warning("Exception while highlighting source code for {0} using language {1}: {2}", input.SourceString(), language, innerEx.Message); } else { Trace.Information("Exception while highlighting source code for {0} using language {1}: {2}", input.SourceString(), language, innerEx.Message); } } } string content = htmlDocument.ToHtml(); return context.GetDocument(input, content); } } catch (Exception ex) { Trace.Warning("Exception while highlighting source code for {0}: {1}", input.SourceString(), ex.Message); return input; } } }).ToList()); } }
/// <summary> /// Initializes a new instance of the <see cref="CoffeeScriptCompiler"/> class. /// </summary> /// <param name="javascriptEngineFactory"> /// The javascript engine factory. /// </param> public CoffeeScriptCompiler(Func<IJsEngine> javascriptEngineFactory) { this.javascriptEngine = javascriptEngineFactory(); }
/// <summary> /// Initializes a new instance of the <see cref="CoffeeScriptCompiler"/> class. /// </summary> /// <param name="javascriptEngineFactory"> /// The javascript engine factory. /// </param> public CoffeeScriptCompiler(Func <IJsEngine> javascriptEngineFactory) { this.javascriptEngine = javascriptEngineFactory(); }
public void RecycleEngine(IJsEngine engine) { throw new NotImplementedException(); }
/// <summary> /// Constructs a instance of CSS-cleaner /// </summary> /// <param name="createJsEngineInstance">Delegate that creates an instance of JavaScript engine</param> /// <param name="defaultOptions">Default cleaning options</param> public CssCleaner(Func<IJsEngine> createJsEngineInstance, CleaningOptions defaultOptions) { _jsEngine = createJsEngineInstance(); _defaultOptions = defaultOptions ?? new CleaningOptions(); _defaultOptionsString = ConvertCleaningOptionsToJson(_defaultOptions).ToString(); }
public MarkdownCompiler(IJsEngine jsEngine) { _jsEngine = jsEngine; }
/// <summary> /// Constructs a instance of CSS-autoprefixer /// </summary> /// <param name="createJsEngineInstance">Delegate that creates an instance of JavaScript engine</param> /// <param name="defaultOptions">Default autoprefixing options</param> public CssAutoprefixer(Func<IJsEngine> createJsEngineInstance, AutoprefixingOptions defaultOptions) { _jsEngine = createJsEngineInstance(); _defaultOptionsString = (defaultOptions != null) ? ConvertAutoprefixingOptionsToJson(defaultOptions).ToString() : "null"; }
/// <summary> /// Disposes the specified engine. /// </summary> /// <param name="engine">Engine to dispose</param> /// <param name="repopulateEngines"> /// If <c>true</c>, a new engine will be created to replace the disposed engine /// </param> public virtual void DisposeEngine(IJsEngine engine, bool repopulateEngines = true) { engine.Dispose(); _metadata.Remove(engine); Interlocked.Decrement(ref _engineCount); if (repopulateEngines) { // Ensure we still have at least the minimum number of engines. PopulateEngines(); } }
public JavaScriptEngine(IJsEngine engine) { _engine = engine; }
/// <summary> /// Performs a sanity check to ensure the specified engine type is usable. /// </summary> /// <param name="engine">Engine to test</param> /// <param name="allowMsie">Whether the MSIE engine can be used</param> /// <returns></returns> private static bool EngineIsUsable(IJsEngine engine, bool allowMsie) { // Perform a sanity test to ensure this engine is usable var isUsable = engine.Evaluate<int>("1 + 1") == 2; #if NETSTANDARD16 var isMsie = false; #else var isMsie = engine is MsieJsEngine; #endif return isUsable && (!isMsie || allowMsie); }
/// <summary> /// Constructs a instance of CSS-optimizer /// </summary> /// <param name="createJsEngineInstance">Delegate that creates an instance of JavaScript engine</param> public CssOptimizer(Func<IJsEngine> createJsEngineInstance) { _jsEngine = createJsEngineInstance(); }
public static void InitialiseJSRuntime(string jsPath, IJsEngine engine) { engine.ExecuteFile(jsPath); }
/// <summary> /// Constructs a instance of Hogan-compiler /// </summary> /// <param name="createJsEngineInstance">Delegate that creates an instance of JavaScript engine</param> /// <param name="defaultOptions">Default compilation options</param> public HoganCompiler(Func<IJsEngine> createJsEngineInstance, CompilationOptions defaultOptions) { _jsEngine = createJsEngineInstance(); _defaultOptions = defaultOptions ?? new CompilationOptions(); _defaultOptionsString = ConvertCompilationOptionsToJson(_defaultOptions).ToString(); }
/// <summary> /// Ensures that React has been correctly loaded into the specified engine. /// </summary> /// <param name="engine">Engine to check</param> private static void EnsureReactLoaded(IJsEngine engine) { var result = engine.CallFunction<bool>("ReactNET_initReact"); if (!result) { throw new ReactNotInitialisedException( "React has not been loaded correctly. Please expose your version of React as a global " + "variable named 'React', or enable the 'LoadReact' configuration option to " + "use the built-in version of React." ); } }
/// <summary> /// Performs a sanity check to ensure the specified engine type is usable. /// </summary> /// <param name="engine">Engine to test</param> /// <returns></returns> private static bool EngineIsUsable(IJsEngine engine) { // Perform a sanity test to ensure this engine is usable return(engine.Evaluate <int>("1 + 1") == 2); }
/// <summary> /// Performs a sanity check to ensure the specified engine type is usable. /// </summary> /// <param name="engine">Engine to test</param> /// <param name="allowMsie">Whether the MSIE engine can be used</param> /// <returns></returns> private static bool EngineIsUsable(IJsEngine engine, bool allowMsie) { // Perform a sanity test to ensure this engine is usable var isUsable = engine.Evaluate<int>("1 + 1") == 2; var isMsie = engine is MsieJsEngine; return isUsable && (!isMsie || allowMsie); }
public BabelJsCompiler(Func <IJsEngine> createJsEngineInstance, BabelJsCompilationOptions options) { _jsEngine = createJsEngineInstance(); _defaultOptions = options ?? new BabelJsCompilationOptions(); }
public TencentComicOperator(INetworkAdapter networkAdapter, IJsEngine jsEngine) { this.jsEngine = jsEngine; this.networkAdapter = networkAdapter; }
public void Initialize(IJsEngine engine) { engine.ExecuteFile(_env.MapPath("server.js")); }
/// <summary> /// Marks the specified engine as "in use" /// </summary> /// <param name="engine"></param> private IJsEngine TakeEngine(IJsEngine engine) { _metadata[engine].InUse = true; _metadata[engine].UsageCount++; return engine; }
/// <summary> /// Constructs a instance of JS packer /// </summary> /// <param name="createJsEngineInstance">Delegate that creates an instance of JS engine</param> /// <param name="options">Packing options</param> public JsPacker(Func <IJsEngine> createJsEngineInstance, PackingOptions options) { _jsEngine = createJsEngineInstance(); _options = options; }
/// <summary> /// Constructs a instance of TypeScript-compiler /// </summary> /// <param name="createJsEngineInstance">Delegate that creates an instance of JavaScript engine</param> /// <param name="defaultOptions">Default compilation options</param> public TypeScriptCompiler(Func<IJsEngine> createJsEngineInstance, CompilationOptions defaultOptions) { _jsEngine = createJsEngineInstance(); _defaultOptions = defaultOptions; _defaultOptionsString = (defaultOptions != null) ? ConvertCompilationOptionsToJson(defaultOptions).ToString() : "null"; Type type = GetType(); _commonTypesDefinitions = new Dictionary<string, string> { { DEFAULT_LIBRARY_FILE_NAME, Utils.GetResourceAsString(RESOURCES_NAMESPACE + "." + DEFAULT_LIBRARY_FILE_NAME, type) }, { DEFAULT_LIBRARY_ES6_FILE_NAME, Utils.GetResourceAsString(RESOURCES_NAMESPACE + "." + DEFAULT_LIBRARY_ES6_FILE_NAME, type) } }; }
/// <summary> /// Loads standard React and Babel scripts into the engine. /// </summary> protected virtual void InitialiseEngine(IJsEngine engine) { var thisAssembly = typeof(ReactEnvironment).Assembly; engine.ExecuteResource("React.Resources.shims.js", thisAssembly); if (_config.LoadReact) { engine.ExecuteResource("React.Resources.react-with-addons.js", thisAssembly); engine.Execute("React = global.React"); } LoadUserScripts(engine); if (!_config.LoadReact) { // We expect to user to have loaded their own versino of React in the scripts that // were loaded above, let's ensure that's the case. EnsureReactLoaded(engine); } }
/// <summary> /// Destroys object /// </summary> public void Dispose() { if (!_disposed) { _disposed = true; if (_jsEngine != null) { _jsEngine.Dispose(); _jsEngine = null; } if (_commonTypesDefinitions != null) { _commonTypesDefinitions.Clear(); _commonTypesDefinitions = null; } } }
/// <summary> /// Loads any user-provided scripts. Only scripts that don't need JSX transformation can /// run immediately here. JSX files are loaded in ReactEnvironment. /// </summary> /// <param name="engine">Engine to load scripts into</param> private void LoadUserScripts(IJsEngine engine) { foreach (var file in _config.ScriptsWithoutTransform) { try { var contents = _fileSystem.ReadAsString(file); engine.Execute(contents); } catch (JsRuntimeException ex) { throw new ReactScriptLoadException(string.Format( "Error while loading \"{0}\": {1}\r\nLine: {2}\r\nColumn: {3}", file, ex.Message, ex.LineNumber, ex.ColumnNumber )); } } }
/// <summary> /// Determines if this JavaScript engine supports the JSX transformer. /// </summary> /// <param name="jsEngine">JavaScript engine</param> /// <returns><c>true</c> if JSXTransformer is supported</returns> public static bool SupportsJsxTransformer(this IJsEngine jsEngine) { // Jint overflows the stack if you attempt to run the JSX Transformer :( return(!(jsEngine is JintJsEngine)); }
/// <summary> /// Returns an engine to the pool so it can be reused /// </summary> /// <param name="engine">Engine to return</param> public virtual void ReturnEngineToPool(IJsEngine engine) { // This could be called from ReactEnvironment.Dispose if that class is disposed after // this class. Let's just ignore this if it's disposed. if (!_disposed) { _pool.ReturnEngineToPool(engine); } }
public JisuComicOperator(IJsEngine v8, INetworkAdapter networkAdapter) : base(v8, networkAdapter) { }
/// <summary> /// Loads standard React and JSXTransformer scripts into the engine. /// </summary> protected virtual void InitialiseEngine(IJsEngine engine) { var thisAssembly = typeof(ReactEnvironment).Assembly; engine.ExecuteResource("React.Resources.shims.js", thisAssembly); if (_config.LoadReact) { engine.ExecuteResource("React.Resources.react-with-addons.js", thisAssembly); engine.Execute("React = global.React"); // TODO: Make this configurable, so we don't load Babel if it's not needed. engine.ExecuteResource("React.node_modules.babel_core.browser.js", thisAssembly); } LoadUserScripts(engine); if (!_config.LoadReact) { // We expect to user to have loaded their own versino of React in the scripts that // were loaded above, let's ensure that's the case. EnsureReactLoaded(engine); } }
/// <summary> /// Constructs a instance of CoffeeScript compiler /// </summary> /// <param name="createJsEngineInstance">Delegate that creates an instance of JS engine</param> /// <param name="options">Compilation options</param> public CoffeeScriptCompiler(Func <IJsEngine> createJsEngineInstance, CompilationOptions options) { _jsEngine = createJsEngineInstance(); _options = options ?? new CompilationOptions(); }
/// <summary> /// Executes a code from JavaScript file. /// </summary> /// <param name="engine">Engine to execute code from JavaScript file</param> /// <param name="fileSystem">File system wrapper</param> /// <param name="path">Path to the JavaScript file</param> public static void ExecuteFile(this IJsEngine engine, IFileSystem fileSystem, string path) { var contents = fileSystem.ReadAsString(path); engine.Execute(contents, path); }
/// <summary> /// Constructs a instance of JS uglifier /// </summary> /// <param name="createJsEngineInstance">Delegate that creates an instance of JS engine</param> /// <param name="options">Uglification options</param> public JsUglifier(Func <IJsEngine> createJsEngineInstance, UglificationOptions options) { _jsEngine = createJsEngineInstance(); _options = options ?? new UglificationOptions(); _optionsString = ConvertUglificationOptionsToJson(_options).ToString(); }
/// <summary> /// Constructs a instance of LESS-compiler /// </summary> /// <param name="createJsEngineInstance">Delegate that creates an instance of JavaScript engine</param> /// <param name="defaultOptions">Default compilation options</param> public LessCompiler(Func<IJsEngine> createJsEngineInstance, CompilationOptions defaultOptions) { _jsEngine = createJsEngineInstance(); _defaultOptions = defaultOptions ?? new CompilationOptions(); _defaultOptionsString = (defaultOptions != null) ? ConvertCompilationOptionsToJson(defaultOptions).ToString() : "null"; }
/// <summary> /// Loads standard React and Babel scripts into the engine. /// </summary> protected virtual void InitialiseEngine(IJsEngine engine) { #if NETSTANDARD16 var thisAssembly = typeof(ReactEnvironment).GetTypeInfo().Assembly; engine.ExecuteResource("React.Core.Resources.shims.js", thisAssembly); if (_config.LoadReact) { // TODO: Add option to choose whether to load dev vs prod version of React. engine.ExecuteResource("React.Core.Resources.react.generated.js", thisAssembly); } #else var thisAssembly = typeof(ReactEnvironment).Assembly; engine.ExecuteResource("React.Resources.shims.js", thisAssembly); if (_config.LoadReact) { // TODO: Add option to choose whether to load dev vs prod version of React. engine.ExecuteResource("React.Resources.react.generated.js", thisAssembly); } #endif LoadUserScripts(engine); if (!_config.LoadReact) { // We expect to user to have loaded their own version of React in the scripts that // were loaded above, let's ensure that's the case. EnsureReactLoaded(engine); } }
/// <summary> /// Gets a factory for the most appropriate JavaScript engine for the current environment. /// The first functioning JavaScript engine with the lowest priority will be used. /// </summary> /// <returns>Function to create JavaScript engine</returns> private static Func <IJsEngine> GetFactory(IJsEngineSwitcher jsEngineSwitcher, bool allowMsie) { EnsureJsEnginesRegistered(jsEngineSwitcher, allowMsie); string defaultEngineName = jsEngineSwitcher.DefaultEngineName; if (!string.IsNullOrWhiteSpace(defaultEngineName)) { var engineFactory = jsEngineSwitcher.EngineFactories.Get(defaultEngineName); if (engineFactory != null) { return(engineFactory.CreateEngine); } else { throw new ReactEngineNotFoundException( "Could not find a factory that creates an instance of the JavaScript " + "engine with name `" + defaultEngineName + "`."); } } foreach (var engineFactory in jsEngineSwitcher.EngineFactories) { IJsEngine engine = null; try { engine = engineFactory.CreateEngine(); if (EngineIsUsable(engine, allowMsie)) { // Success! Use this one. return(engineFactory.CreateEngine); } } catch (Exception ex) { // This engine threw an exception, try the next one Trace.WriteLine(string.Format("Error initialising {0}: {1}", engineFactory, ex)); } finally { if (engine != null) { engine.Dispose(); } } } // Epic fail, none of the engines worked. Nothing we can do now. // Throw an error relevant to the engine they should be able to use. #if NET45 if (JavaScriptEngineUtils.EnvironmentSupportsClearScript()) { JavaScriptEngineUtils.EnsureEngineFunctional <V8JsEngine, ClearScriptV8InitialisationException>( ex => new ClearScriptV8InitialisationException(ex) ); } #endif if (JavaScriptEngineUtils.EnvironmentSupportsVroomJs()) { JavaScriptEngineUtils.EnsureEngineFunctional <VroomJsEngine, VroomJsInitialisationException>( ex => new VroomJsInitialisationException(ex.Message) ); } throw new ReactEngineNotFoundException(); }
/// <summary> /// Loads any user-provided scripts. Only scripts that don't need JSX transformation can /// run immediately here. JSX files are loaded in ReactEnvironment. /// </summary> /// <param name="engine">Engine to load scripts into</param> private void LoadUserScripts(IJsEngine engine) { foreach (var file in _config.ScriptsWithoutTransform) { try { var contents = _fileSystem.ReadAsString(file); engine.Execute(contents); } catch (JsRuntimeException ex) { // We can't simply rethrow the exception here, as it's possible this is running // on a background thread (ie. as a response to a file changing). If we did // throw the exception here, it would terminate the entire process. Instead, // save the exception, and then just rethrow it later when getting the engine. _scriptLoadException = new ReactScriptLoadException(string.Format( "Error while loading \"{0}\": {1}\r\nLine: {2}\r\nColumn: {3}", file, ex.Message, ex.LineNumber, ex.ColumnNumber )); } } }
public virtual void TearDown() { if (_jsEngine != null) { _jsEngine.Dispose(); _jsEngine = null; } }
/// <summary> /// Ensures that React has been correctly loaded into the specified engine. /// </summary> /// <param name="engine">Engine to check</param> private static void EnsureReactLoaded(IJsEngine engine) { var result = engine.CallFunction<bool>("ReactNET_initReact"); if (!result) { throw new ReactNotInitialisedException( "React has not been loaded correctly. Please expose your version of React as global " + "variables named 'React', 'ReactDOM' and 'ReactDOMServer', or enable the " + "'LoadReact' configuration option to use the built-in version of React. See " + "http://reactjs.net/guides/byo-react.html for more information." ); } }