コード例 #1
0
        public async Task ReactBridge_InvokeCallback()
        {
            await JavaScriptHelpers.Run(async (executor, jsQueueThread) =>
            {
                using (var nativeThread = new ActionQueue(ex => { Assert.Fail(); }))
                {
                    var bridge = new ReactBridge(executor, new MockReactCallback(), nativeThread);
                    var token  = await jsQueueThread.RunAsync(() =>
                    {
                        bridge.InvokeCallback(1, new JArray());
                        return(executor.GetGlobalVariable("CallbackCalls"));
                    });

                    var expected = new JArray
                    {
                        new JArray
                        {
                            1,
                            new JArray(),
                        },
                    };

                    Assert.That(expected.ToString(Formatting.None), Is.EqualTo(token.ToString(Formatting.None)));
                }
            });
        }
コード例 #2
0
        public async Task ReactBridge_CallFunction()
        {
            await JavaScriptHelpers.Run(async (executor, jsQueueThread) =>
            {
                using (var nativeThread = CreateNativeModulesThread())
                {
                    var reactCallback = new MockReactCallback();
                    var bridge        = new ReactBridge(executor, new MockReactCallback(), nativeThread);
                    var token         = await jsQueueThread.CallOnQueue(() =>
                    {
                        bridge.CallFunction("module", "method", new JArray());
                        return(executor.GetGlobalVariable("FunctionCalls"));
                    });

                    var expected = new JArray
                    {
                        new JArray
                        {
                            "module",
                            "method",
                            new JArray(),
                        },
                    };

                    Assert.AreEqual(expected.ToString(Formatting.None), token.ToString(Formatting.None));
                }
            });
        }
コード例 #3
0
        public async Task ChakraJavaScriptExecutor_ArgumentChecks()
        {
            await JavaScriptHelpers.Run((executor, jsQueueThread) =>
            {
                AssertEx.Throws <ArgumentNullException>(
                    () => executor.Call(null, "foo", new JArray()),
                    ex => Assert.AreEqual("moduleName", ex.ParamName));

                AssertEx.Throws <ArgumentNullException>(
                    () => executor.Call("foo", null, new JArray()),
                    ex => Assert.AreEqual("methodName", ex.ParamName));

                AssertEx.Throws <ArgumentNullException>(
                    () => executor.Call("foo", "bar", null),
                    ex => Assert.AreEqual("arguments", ex.ParamName));

                AssertEx.Throws <ArgumentNullException>(
                    () => executor.RunScript(null),
                    ex => Assert.AreEqual("script", ex.ParamName));

                AssertEx.Throws <ArgumentNullException>(
                    () => executor.SetGlobalVariable(null, new JArray()),
                    ex => Assert.AreEqual("propertyName", ex.ParamName));

                AssertEx.Throws <ArgumentNullException>(
                    () => executor.SetGlobalVariable("foo", null),
                    ex => Assert.AreEqual("value", ex.ParamName));

                AssertEx.Throws <ArgumentNullException>(
                    () => executor.GetGlobalVariable(null),
                    ex => Assert.AreEqual("propertyName", ex.ParamName));
            });
        }
コード例 #4
0
        public async Task ReactBridge_InvokeCallback()
        {
            await JavaScriptHelpers.Run(async (executor, jsQueueThread) =>
            {
                using (var nativeThread = MessageQueueThread.Create(MessageQueueThreadSpec.Create("native", MessageQueueThreadKind.BackgroundAnyThread), ex => { Assert.Fail(); }))
                {
                    var reactCallback = new MockReactCallback();
                    var bridge        = new ReactBridge(executor, new MockReactCallback(), nativeThread);
                    var token         = await jsQueueThread.CallOnQueue(() =>
                    {
                        bridge.InvokeCallback(1, new JArray());
                        return(executor.GetGlobalVariable("CallbackCalls"));
                    });

                    var expected = new JArray
                    {
                        new JArray
                        {
                            1,
                            new JArray(),
                        },
                    };

                    Assert.AreEqual(expected.ToString(Formatting.None), token.ToString(Formatting.None));
                }
            });
        }
コード例 #5
0
        public async Task ReactBridge_Ctor_ArgumentChecks()
        {
            await JavaScriptHelpers.Run((executor, jsQueueThread) =>
            {
                using (var nativeThread = CreateNativeModulesThread())
                {
                    var reactCallback = new MockReactCallback();

                    Assert.That(
                        () => new ReactBridge(null, reactCallback, nativeThread),
                        Throws.ArgumentNullException.With.Property("ParamName").EqualTo("executor")
                        );

                    Assert.That(
                        () => new ReactBridge(executor, null, nativeThread),
                        Throws.ArgumentNullException.With.Property("ParamName").EqualTo("reactCallback")
                        );

                    Assert.That(
                        () => new ReactBridge(executor, reactCallback, null),
                        Throws.ArgumentNullException.With.Property("ParamName").EqualTo("nativeModulesQueueThread")
                        );
                }
            });
        }
コード例 #6
0
        /// <summary>
        /// Setup RequireJS to be used in layouts
        /// </summary>
        /// <param name="html">
        /// Html helper.
        /// </param>
        /// <param name="config">
        /// Configuration object for various options.
        /// </param>
        /// <returns>
        /// The <see cref="MvcHtmlString"/>.
        /// </returns>
        public static MvcHtmlString RenderRequireJsSetup(
            this HtmlHelper html,
            RequireRendererConfiguration config)
        {
            if (config == null)
            {
                throw new ArgumentNullException("config");
            }

            var entryPointPath = html.RequireJsEntryPoint(config.BaseUrl, config.EntryPointRoot);

            if (entryPointPath == null)
            {
                return(new MvcHtmlString(string.Empty));
            }

            if (config.ConfigurationFiles == null || !config.ConfigurationFiles.Any())
            {
                throw new Exception("No config files to load.");
            }

            var processedConfigs = config.ConfigurationFiles.Select(r =>
            {
                var resultingPath = html.ViewContext.HttpContext.MapPath(r);
                PathHelpers.VerifyFileExists(resultingPath);
                return(resultingPath);
            }).ToList();

            var resultingConfig = GetCachedOverridenConfig(processedConfigs, config, entryPointPath.ToString());

            var locale = config.LocaleSelector(html);

            var outputConfig = createOutputConfigFrom(resultingConfig, config, locale);

            var options = createOptionsFrom(html.ViewContext.HttpContext, config, locale);

            var configBuilder = new JavaScriptBuilder();

            configBuilder.AddStatement(JavaScriptHelpers.SerializeAsVariable(options, "requireConfig"));
            configBuilder.AddStatement(JavaScriptHelpers.SerializeAsVariable(outputConfig, "require"));

            var requireRootBuilder = new JavaScriptBuilder();

            requireRootBuilder.AddAttributesToStatement("src", config.RequireJsUrl);

            var requireEntryPointBuilder = new JavaScriptBuilder();

            requireEntryPointBuilder.AddStatement(
                JavaScriptHelpers.MethodCall(
                    "require",
                    (object)new[] { entryPointPath.ToString() }));

            return(new MvcHtmlString(
                       configBuilder.Render()
                       + Environment.NewLine
                       + requireRootBuilder.Render()
                       + Environment.NewLine
                       + requireEntryPointBuilder.Render()));
        }
コード例 #7
0
        public void Truthiness()
        {
            Assert.IsFalse(JavaScriptHelpers.IsTruthy(null), "Null is not truthy.");

            Assert.IsTrue(JavaScriptHelpers.IsTruthy(this), "Non-null object is truthy.");

            Assert.IsTrue(JavaScriptHelpers.IsTruthy(true), "Boolean value of true is truthy.");
            Assert.IsFalse(JavaScriptHelpers.IsTruthy(false), "Boolean value of false is not truthy.");

            Assert.IsTrue(JavaScriptHelpers.IsTruthy((sbyte)42), "Non-zero sbyte value is truthy");
            Assert.IsTrue(JavaScriptHelpers.IsTruthy((sbyte)-42), "Non-zero sbyte value is truthy");
            Assert.IsFalse(JavaScriptHelpers.IsTruthy((sbyte)0), "Zero sbyte value is not truthy");

            Assert.IsTrue(JavaScriptHelpers.IsTruthy((byte)42), "Non-zero byte value is truthy");
            Assert.IsFalse(JavaScriptHelpers.IsTruthy((byte)0), "Zero byte value is not truthy");

            Assert.IsTrue(JavaScriptHelpers.IsTruthy((char)0), "Char value is truthy.");

            Assert.IsTrue(JavaScriptHelpers.IsTruthy((short)42), "Non-zero short value is truthy");
            Assert.IsTrue(JavaScriptHelpers.IsTruthy((short)-42), "Non-zero short value is truthy");
            Assert.IsFalse(JavaScriptHelpers.IsTruthy((short)0), "Zero short value is not truthy");

            Assert.IsTrue(JavaScriptHelpers.IsTruthy((ushort)42), "Non-zero ushort value is truthy");
            Assert.IsFalse(JavaScriptHelpers.IsTruthy((ushort)0), "Zero ushort value is not truthy");

            Assert.IsTrue(JavaScriptHelpers.IsTruthy((int)42), "Non-zero int value is truthy");
            Assert.IsTrue(JavaScriptHelpers.IsTruthy((int)-42), "Non-zero int value is truthy");
            Assert.IsFalse(JavaScriptHelpers.IsTruthy((int)0), "Zero int value is not truthy");

            Assert.IsTrue(JavaScriptHelpers.IsTruthy((uint)42), "Non-zero uint value is truthy");
            Assert.IsFalse(JavaScriptHelpers.IsTruthy((uint)0), "Zero uint value is not truthy");

            Assert.IsTrue(JavaScriptHelpers.IsTruthy((long)42), "Non-zero long value is truthy");
            Assert.IsTrue(JavaScriptHelpers.IsTruthy((long)-42), "Non-zero long value is truthy");
            Assert.IsFalse(JavaScriptHelpers.IsTruthy((long)0), "Zero long value is not truthy");

            Assert.IsTrue(JavaScriptHelpers.IsTruthy((ulong)42), "Non-zero ulong value is truthy");
            Assert.IsFalse(JavaScriptHelpers.IsTruthy((ulong)0), "Zero ulong value is not truthy");

            Assert.IsTrue(JavaScriptHelpers.IsTruthy((float)42), "Non-zero float value is truthy");
            Assert.IsTrue(JavaScriptHelpers.IsTruthy((float)-42), "Non-zero float value is truthy");
            Assert.IsFalse(JavaScriptHelpers.IsTruthy((float)0), "Zero float value is not truthy");

            Assert.IsTrue(JavaScriptHelpers.IsTruthy((double)42), "Non-zero double value is truthy");
            Assert.IsTrue(JavaScriptHelpers.IsTruthy((double)-42), "Non-zero double value is truthy");
            Assert.IsFalse(JavaScriptHelpers.IsTruthy((double)0), "Zero double value is not truthy");

            Assert.IsTrue(JavaScriptHelpers.IsTruthy((decimal)42), "Non-zero decimal value is truthy");
            Assert.IsTrue(JavaScriptHelpers.IsTruthy((decimal) - 42), "Non-zero decimal value is truthy");
            Assert.IsFalse(JavaScriptHelpers.IsTruthy((decimal)0), "Zero decimal value is not truthy");

            Assert.IsTrue(JavaScriptHelpers.IsTruthy("42"), "Non-zero length string is truthy");
            Assert.IsFalse(JavaScriptHelpers.IsTruthy(""), "Zero length string is not truthy");

            Assert.IsTrue(JavaScriptHelpers.IsTruthy((bool?)true), "Nullable values' truthiness is based on the actual value if they do not have a value assigned.");
            Assert.IsFalse(JavaScriptHelpers.IsTruthy((bool?)false), "Nullable values' truthiness is based on the actual value if they do not have a value assigned.");
            Assert.IsFalse(JavaScriptHelpers.IsTruthy((char?)null), "Nullable values are not truthy if they do not have a value assigned.");
        }
コード例 #8
0
        /// <summary>
        /// Setup RequireJS to be used in layouts
        /// </summary>
        /// <param name="baseUrl">Scrips folder</param>
        /// <param name="requireUrl">requirejs.js url</param>
        /// <param name="configsList">RequireJS.config files path</param>
        public static MvcHtmlString RenderRequireJsSetup(this HtmlHelper html, string baseUrl, string requireUrl,
                                                         IList <string> configsList, IRequireJsLogger logger = null)
        {
            var entryPointPath = html.RequireJsEntryPoint();

            if (entryPointPath == null)
            {
                return(new MvcHtmlString(string.Empty));
            }

            if (!configsList.Any())
            {
                throw new Exception("No config files to load.");
            }
            var processedConfigs = configsList.Select(r =>
            {
                var resultingPath = html.ViewContext.HttpContext.MapPath(r);
                PathHelpers.VerifyFileExists(resultingPath);
                return(resultingPath);
            }).ToList();

            var loader          = new ConfigLoader(processedConfigs, logger);
            var resultingConfig = loader.Get();
            var outputConfig    = new JsonConfig
            {
                BaseUrl = baseUrl,
                Locale  = html.CurrentCulture(),
                Paths   = resultingConfig.Paths.PathList.ToDictionary(r => r.Key, r => r.Value),
                Shim    = resultingConfig.Shim.ShimEntries.ToDictionary(r => r.For, r => new JsonRequireDeps
                {
                    Dependencies = r.Dependencies.Select(x => x.Dependency).ToList(),
                    Exports      = r.Exports
                }),
                Map = resultingConfig.Map.MapElements.ToDictionary(r => r.For,
                                                                   r => r.Replacements.ToDictionary(x => x.OldKey, x => x.NewKey))
            };

            var options = new JsonRequireOptions
            {
                Locale         = html.CurrentCulture(),
                PageOptions    = html.ViewBag.PageOptions,
                WebsiteOptions = html.ViewBag.GlobalOptions
            };

            var configBuilder = new JavaScriptBuilder();

            configBuilder.AddStatement(JavaScriptHelpers.SerializeAsVariable(options, "requireConfig"));
            configBuilder.AddStatement(JavaScriptHelpers.SerializeAsVariable(outputConfig, "require"));

            var requireRootBuilder = new JavaScriptBuilder();

            requireRootBuilder.AddAttributesToStatement("data-main", entryPointPath.ToString());
            requireRootBuilder.AddAttributesToStatement("src", requireUrl);

            return(new MvcHtmlString(configBuilder.Render() + requireRootBuilder.Render()));
        }
コード例 #9
0
        // Implement ICanCreateJsonFields
        public virtual void AddJsonFields(IList <string> jsonFields, Dictionary <string, string> appenderNames,
                                          Func <string, string> virtualToAbsoluteFunc)
        {
            var stringValue = new StringValue();

            JavaScriptHelpers.AddJsonField(jsonFields, FieldLevel, level, new LevelValue());
            JavaScriptHelpers.AddJsonField(jsonFields, "ipRegex", ipRegex, stringValue);
            JavaScriptHelpers.AddJsonField(jsonFields, "userAgentRegex", userAgentRegex, stringValue);
            JavaScriptHelpers.AddJsonField(jsonFields, "disallow", disallow, stringValue);
        }
コード例 #10
0
ファイル: Appender.cs プロジェクト: dazinator/jsnlog
        // Implement ICanCreateJsonFields
        public override void AddJsonFields(IList <string> jsonFields, Dictionary <string, string> appenderNames, Func <string, string> virtualToAbsoluteFunc)
        {
            var levelValue = new LevelValue();

            JavaScriptHelpers.AddJsonField(jsonFields, FieldSendWithBufferLevel, sendWithBufferLevel, levelValue);
            JavaScriptHelpers.AddJsonField(jsonFields, FieldStoreInBufferLevel, storeInBufferLevel, levelValue);
            JavaScriptHelpers.AddJsonField(jsonFields, FieldBufferSize, bufferSize);
            JavaScriptHelpers.AddJsonField(jsonFields, FieldBatchSize, batchSize);

            base.AddJsonFields(jsonFields, appenderNames, virtualToAbsoluteFunc);
        }
コード例 #11
0
        public async Task ThrowsWithCorrectParameterNameWhenGivenNull()
        {
            await JavaScriptHelpers.Run((executor, jsQueueThread) =>
            {
                Assert.That(
                    () => executor.CallFunctionReturnFlushedQueue(null, "foo", new JArray()),
                    Throws.ArgumentNullException.With.Property("ParamName").EqualTo("moduleName")
                    );

                Assert.That(
                    () => executor.CallFunctionReturnFlushedQueue("foo", null, new JArray()),
                    Throws.ArgumentNullException.With.Property("ParamName").EqualTo("methodName")
                    );

                Assert.That(
                    () => executor.CallFunctionReturnFlushedQueue("foo", "bar", null),
                    Throws.ArgumentNullException.With.Property("ParamName").EqualTo("arguments")
                    );

                Assert.That(
                    () => executor.InvokeCallbackAndReturnFlushedQueue(0, null),
                    Throws.ArgumentNullException.With.Property("ParamName").EqualTo("arguments")
                    );

                Assert.That(
                    () => executor.RunScript(null, "foo"),
                    Throws.ArgumentNullException.With.Property("ParamName").EqualTo("sourcePath")
                    );

                Assert.That(
                    () => executor.RunScript("", null),
                    Throws.ArgumentNullException.With.Property("ParamName").EqualTo("sourceUrl")
                    );

                Assert.That(
                    () => executor.SetGlobalVariable(null, new JArray()),
                    Throws.ArgumentNullException.With.Property("ParamName").EqualTo("propertyName")
                    );

                Assert.That(
                    () => executor.SetGlobalVariable("foo", null),
                    Throws.ArgumentNullException.With.Property("ParamName").EqualTo("value")
                    );

                Assert.That(
                    () => executor.GetGlobalVariable(null),
                    Throws.ArgumentNullException.With.Property("ParamName").EqualTo("propertyName")
                    );
            });
        }
コード例 #12
0
 // Implement ICanCreateJsonFields
 public void AddJsonFields(IList <string> jsonFields, Dictionary <string, string> appenderNames, Func <string, string> virtualToAbsoluteFunc)
 {
     try
     {
         JavaScriptHelpers.AddJsonField(jsonFields, FieldEnabled, enabled);
         JavaScriptHelpers.AddJsonField(jsonFields, FieldMaxMessages, maxMessages);
         JavaScriptHelpers.AddJsonField(jsonFields, FieldDefaultAjaxUrl, defaultAjaxUrl, new UrlValue(virtualToAbsoluteFunc));
     }
     catch (Exception e)
     {
         string displayName = "jsnlog library";
         throw new ConfigurationException(displayName, e);
     }
 }
コード例 #13
0
        public void ParseConstant()
        {
            object result;

            JavaScriptHelpers.ParseConstant("'this'").Should().Be("this");
            JavaScriptHelpers.ParseConstant("5").Should().Be(5);
            JavaScriptHelpers.ParseConstant("0.25").Should().Be(0.25);
            JavaScriptHelpers.ParseConstant("true").Should().Be(true);
            JavaScriptHelpers.ParseConstant("false").Should().Be(false);

            JavaScriptHelpers.TryParseConstant("0.25", out result).Should().Be(true);
            JavaScriptHelpers.TryParseConstant("false", out result).Should().Be(true);
            JavaScriptHelpers.TryParseConstant("xi0", out result).Should().Be(false);
            JavaScriptHelpers.TryParseConstant("'unbalanced", out result).Should().Be(false);
        }
コード例 #14
0
        // Implement ICanCreateJsonFields
        public override void AddJsonFields(IList <string> jsonFields, Dictionary <string, string> appenderNames, Func <string, string> virtualToAbsoluteFunc)
        {
            JavaScriptHelpers.AddJsonField(jsonFields, FieldAppenders, appenders, new AppendersValue(appenderNames));

            if (onceOnlies != null)
            {
                // Note that regex on a onceOnly object can be null (that is, not given in the config).
                // This allows user to specify an empty list of onceOnlies, to override the onceOnlies of
                // the parent logger. See http://jsnlog.com/Documentation/WebConfig/JSNLog/Logger
                JavaScriptHelpers.AddJsonField(jsonFields, FieldOnceOnly,
                                               onceOnlies.Select(o => o.regex), new StringValue());
            }

            base.AddJsonFields(jsonFields, appenderNames, virtualToAbsoluteFunc);
        }
コード例 #15
0
        public async Task ReactBridge_Method_ArgumentChecks()
        {
            await JavaScriptHelpers.Run((executor, jsQueueThread) =>
            {
                using (var nativeThread = CreateNativeModulesThread())
                {
                    var reactCallback = new MockReactCallback();
                    var bridge        = new ReactBridge(executor, reactCallback, nativeThread);

                    AssertEx.Throws <ArgumentNullException>(
                        () => bridge.SetGlobalVariable(null, null),
                        ex => Assert.AreEqual("propertyName", ex.ParamName));
                }
            });
        }
コード例 #16
0
 public void Abort(System.IO.TextWriter writer, bool isHtmlBool)
 {
     // Bound attribute
     if (binding != null)
     {
         RenderAttribute(writer, attribute.Name, attribute.Binding.Expression);
     }
     // Simple attribute
     else if (!isHtmlBool)
     {
         RenderAttribute(writer, attribute.Name, attribute.Value);
     }
     else if (JavaScriptHelpers.IsTruthy(attribute.Value))
     {
         RenderAttribute(writer, attribute.Name, attribute.Name);
     }
 }
コード例 #17
0
        // Implement ICanCreateElement
        public void CreateElement(StringBuilder sb, Dictionary <string, string> appenderNames, int sequence,
                                  Func <string, string> virtualToAbsoluteFunc)
        {
            try
            {
                string jsVariableName = string.Format("{0}{1}", Constants.JsLoggerVariablePrefix, sequence);
                JavaScriptHelpers.GenerateLogger(jsVariableName, name, sb);

                JavaScriptHelpers.GenerateSetOptions(jsVariableName, this, appenderNames, virtualToAbsoluteFunc,
                                                     sb, null);
            }
            catch (Exception e)
            {
                string displayName = String.IsNullOrEmpty(name) ? "<nameless root logger>" : name;;
                throw new ConfigurationException(displayName, e);
            }
        }
コード例 #18
0
        public async Task ReactBridge_SyncCallback()
        {
            var jsFactories = new Func <IJavaScriptExecutor>[]
            {
                () => new ChakraJavaScriptExecutor(),
#if WINDOWS_UWP
                () => new NativeJavaScriptExecutor(),
#endif
            };

            foreach (var jsFactory in jsFactories)
            {
                await JavaScriptHelpers.Run(async (executor, jsQueueThread) =>
                {
                    using (var nativeThread = CreateNativeModulesThread())
                    {
                        var moduleId = 42;
                        var methodId = 7;
                        var called   = 0;
                        var callback = new MockReactCallback
                        {
                            InvokeSyncHandler = (mod, met, arg) =>
                            {
                                Assert.AreEqual(moduleId, mod);
                                Assert.AreEqual(methodId, met);
                                Assert.AreEqual(0, arg.Count);
                                ++called;
                                return(JValue.CreateNull());
                            },
                        };

                        var bridge = new ReactBridge(executor, callback, nativeThread);
                        await jsQueueThread.RunAsync(() =>
                        {
                            bridge.CallFunction("SyncModule", "test", new JArray {
                                42, 7, new JArray()
                            });
                        });

                        Assert.AreEqual(1, called);
                    }
                },
                                            jsFactory,
                                            @"Resources/sync.js");
            }
        }
コード例 #19
0
        protected bool TryRenderIf(AjaxPage page, IEnumerable <string> templateNames, System.IO.TextWriter writer, out AttributeBinding ifBinding, out bool canRender)
        {
            if (If == null)
            {
                ifBinding = null;
                canRender = true;
                return(true);
            }

            ifBinding = If.Evaluate(page);

            if (!ifBinding.IsValid)
            {
                canRender = false;
                return(false);
            }

            canRender = JavaScriptHelpers.IsTruthy(ifBinding.Value);
            return(true);
        }
コード例 #20
0
        protected void CreateAppender(StringBuilder sb, Dictionary <string, string> appenderNames, int sequence,
                                      Func <string, string> virtualToAbsoluteFunc, string jsCreateMethodName, string configurationObjectName)
        {
            try
            {
                ValidateAppender(configurationObjectName);

                string appenderVariableName = string.Format("{0}{1}", Constants.JsAppenderVariablePrefix, sequence);
                appenderNames[name] = appenderVariableName;

                JavaScriptHelpers.GenerateCreate(appenderVariableName, jsCreateMethodName, name, sb);

                JavaScriptHelpers.GenerateSetOptions(appenderVariableName, this, appenderNames, virtualToAbsoluteFunc,
                                                     sb, null);
            }
            catch (Exception e)
            {
                throw new ConfigurationException(name, e);
            }
        }
コード例 #21
0
        public async Task ReactBridge_Ctor_ArgumentChecks()
        {
            await JavaScriptHelpers.Run((executor, jsQueueThread) =>
            {
                using (var nativeThread = CreateNativeModulesThread())
                {
                    var reactCallback = new MockReactCallback();

                    AssertEx.Throws <ArgumentNullException>(
                        () => new ReactBridge(null, reactCallback, nativeThread),
                        ex => Assert.AreEqual("executor", ex.ParamName));

                    AssertEx.Throws <ArgumentNullException>(
                        () => new ReactBridge(executor, null, nativeThread),
                        ex => Assert.AreEqual("reactCallback", ex.ParamName));

                    AssertEx.Throws <ArgumentNullException>(
                        () => new ReactBridge(executor, reactCallback, null),
                        ex => Assert.AreEqual("nativeModulesQueueThread", ex.ParamName));
                }
            });
        }
コード例 #22
0
        // --------------------------------

        public void ProcessLogger(XmlElement xe, string parentName, Dictionary <string, string> appenderNames, Sequence sequence,
                                  IEnumerable <AttributeInfo> loggerAttributes, StringBuilder sb)
        {
            if (xe == null)
            {
                return;
            }

            var    appendersValue = new AppendersValue(appenderNames);
            string appenders      = XmlHelpers.OptionalAttribute(xe, "appenders", null, appendersValue.ValidValueRegex);
            string loggerName     = XmlHelpers.OptionalAttribute(xe, "name", "");

            JavaScriptHelpers.GenerateLogger(Constants.JsLoggerVariable, loggerName, sb);

            AttributeValueCollection attributeValues = new AttributeValueCollection();

            if (appenders != null)
            {
                attributeValues[Constants.JsLoggerAppendersOption] = new Value(appenders, appendersValue);
            }

            Utils.ProcessOptionAttributes(Constants.JsLoggerVariable, xe, loggerAttributes, attributeValues, sb);
        }
コード例 #23
0
        protected void ProcessAppender(XmlElement xe, string parentName, Dictionary <string, string> appenderNames, Sequence sequence,
                                       IEnumerable <AttributeInfo> appenderAttributes, string jsCreateMethodName, List <XmlHelpers.TagInfo> childTagInfos, StringBuilder sb)
        {
            if (xe == null)
            {
                return;
            }

            string appenderName = XmlHelpers.RequiredAttribute(xe, "name");

            string appenderVariableName = string.Format("{0}{1}", Constants.JsAppenderVariablePrefix, sequence.Next());

            appenderNames[appenderName] = appenderVariableName;

            JavaScriptHelpers.GenerateCreate(appenderVariableName, jsCreateMethodName, appenderName, sb);
            Utils.ProcessOptionAttributes(
                appenderVariableName, xe, appenderAttributes, null, sb, (attributeValues) => { Validate(appenderName, attributeValues); });

            XmlHelpers.ProcessNodeList(
                xe.ChildNodes,
                childTagInfos,
                appenderVariableName, appenderNames, sequence, sb);
        }
コード例 #24
0
        public void Render(AjaxPage page, System.IO.TextWriter writer, bool isHtmlBool, bool generateIds, bool isTextArea)
        {
            // Bound attribute
            if (binding != null)
            {
                // Valid binding
                if (binding.IsValid)
                {
                    // Render the binding value for sys attributes
                    if (attribute.Name.StartsWith("sys:"))
                    {
                        var attributeName = attribute.Name.Substring(4);

                        // Render two-way binding expressions
                        if (attribute.Binding.IsTwoWay)
                        {
                            RenderAttribute(writer, "data-sys-" + attributeName, attribute.Binding.Expression);
                        }

                        if (binding.Value != null)
                        {
                            if (attributeName != "if" && attributeName != "innerhtml" && attributeName != "innertext" && !(isTextArea && attributeName == "value") && !attribute.Name.StartsWith("sys:class-"))
                            {
                                if (isHtmlBool)
                                {
                                    if (JavaScriptHelpers.IsTruthy(binding.Value))
                                    {
                                        RenderAttribute(writer, attributeName, attributeName);
                                    }
                                }
                                else
                                {
                                    RenderAttribute(writer, attributeName, binding.Value.ToString());
                                }
                            }
                        }
                    }
                    else
                    {
                        RenderAttribute(writer, "data-" + attribute.Name.Replace(':', '-'), attribute.Binding.Expression);
                    }
                }

                // Invalid binding
                else
                {
                    RenderAttribute(writer, attribute.Name, attribute.Binding.Expression);
                }
            }
            else if (generateIds && (attribute.Name == "id" || attribute.Name == "sys:id"))
            {
                RenderAttribute(writer, "id", page.Context.GetInstanceId(attribute.Value));
            }
            // Simple attribute
            else if (attribute.Name.Contains(":") && attribute.Name != "sys:id")
            {
                RenderAttribute(writer, "data-" + attribute.Name.Replace(':', '-'), attribute.Value);
            }
            else if (isHtmlBool)
            {
                if (JavaScriptHelpers.IsTruthy(attribute.Value))
                {
                    RenderAttribute(writer, attribute.Name, attribute.Name);
                }
            }
            else
            {
                RenderAttribute(writer, attribute.Name, attribute.Value);
            }
        }
コード例 #25
0
ファイル: AjaxAppender.cs プロジェクト: thestonehead/jsnlog
        // Implement ICanCreateJsonFields
        public override void AddJsonFields(IList <string> jsonFields, Dictionary <string, string> appenderNames, Func <string, string> virtualToAbsoluteFunc)
        {
            JavaScriptHelpers.AddJsonField(jsonFields, FieldUrl, url, new UrlValue(virtualToAbsoluteFunc));

            base.AddJsonFields(jsonFields, appenderNames, virtualToAbsoluteFunc);
        }
コード例 #26
0
        protected void RenderStartTag(AjaxPage page, System.IO.TextWriter writer, Func <IEnumerable <AttributeBinding>, IEnumerable <AttributeBinding> > attributeTransform, bool abort, params AttributeBinding[] bindings)
        {
            // Immediately abort if no tag name
            if (Tag == null)
            {
                return;
            }

            // Open Tag
            writer.Write("<" + Tag);

            // Attributes
            string innerContent = null;
            var    attributes   = (Attributes ?? new List <Attribute>())
                                  .Select(attribute => attribute.Binding == null ? new AttributeBinding(attribute, null) : attribute.Binding.Evaluate(page));

            // Adding binding attributes if necessary
            if (bindings != null && bindings.Length > 0)
            {
                attributes = attributes.Concat(bindings.Where(b => b != null));
            }

            // Transform the attributes if necessary
            if (attributeTransform != null)
            {
                attributes = attributeTransform(attributes);
            }

            string classNames = null;
            bool   foundId    = false;
            bool   isTextArea = Tag.Equals("textarea", StringComparison.InvariantCultureIgnoreCase);

            var attrs = attributes.ToArray();

            // Write the attributes to the output stream
            foreach (var attribute in attrs)
            {
                // Ensure that multiple id attributes are not specified
                if (!page.Context.IsGlobal && (attribute.Name == "id" || attribute.Name == "sys:id"))
                {
                    if (foundId)
                    {
                        throw new ApplicationException("Found multiple id attributes: " + Markup);
                    }
                    foundId = true;
                }

                // Determine if the attribute represents bound element content
                if (attribute.IsBound)
                {
                    if (attribute.Name == "sys:innerhtml" || (isTextArea && attribute.Name == "sys:value"))
                    {
                        innerContent = (attribute.DisplayValue ?? "");
                    }
                    else if (attribute.Name == "sys:innertext")
                    {
                        innerContent = HttpUtility.HtmlEncode(attribute.DisplayValue ?? "");
                    }
                }

                bool isHtmlBoolean;
                var  attributeName = attribute.Name.StartsWith("sys:") ? attribute.Name.Substring(4) : attribute.Name;
                if (Tag.Equals("input", StringComparison.InvariantCultureIgnoreCase))
                {
                    var attr = attrs.SingleOrDefault(a => a.Name.Equals("type", StringComparison.InvariantCultureIgnoreCase) && a.IsValid && a.Value != null);
                    if (attr == null)
                    {
                        isHtmlBoolean = HtmlHelpers.IsBooleanAttribute(attributeName, Tag, null, true);
                    }
                    else
                    {
                        isHtmlBoolean = HtmlHelpers.IsBooleanAttribute(attributeName, Tag, attr.Value.ToString());
                    }
                }
                else
                {
                    isHtmlBoolean = HtmlHelpers.IsBooleanAttribute(attributeName, Tag);
                }

                if (abort)
                {
                    attribute.Abort(writer, isHtmlBoolean);
                }
                else
                {
                    if (attribute.Name == "class")
                    {
                        if (classNames == null)
                        {
                            classNames = (string)attribute.Value;
                        }
                        else
                        {
                            classNames += " " + (string)attribute.Value;
                        }
                    }
                    else
                    {
                        if (attribute.Name.StartsWith("sys:class-"))
                        {
                            // If binding evaluates as truthy, then render the store the class name
                            if (JavaScriptHelpers.IsTruthy(attribute.Value))
                            {
                                string sysClassValue = attribute.Name.Substring(10);
                                if (classNames == null)
                                {
                                    classNames = sysClassValue;
                                }
                                else
                                {
                                    classNames += (classNames.Length > 0 ? " " : "") + sysClassValue;
                                }
                            }
                        }
                        attribute.Render(page, writer, isHtmlBoolean, !page.Context.IsGlobal, isTextArea);
                    }
                }
            }

            // Write direct class and sys:class- attribute values together. Note: by checking
            // for null we may be avoiding writing a class attribute altogether whereas the
            // client framework would have produced an empty class attribute.
            if (classNames != null)
            {
                writer.Write(" class=\"");
                HttpUtility.HtmlAttributeEncode(classNames, writer);
                writer.Write("\"");
            }

            // Close Tag
            if (IsEmpty)
            {
                if (!string.IsNullOrEmpty(innerContent))
                {
                    writer.Write(">" + innerContent + "</" + Tag + ">");
                }
                else if (HtmlHelpers.IsSelfClosing(Tag))
                {
                    writer.Write(" />");
                }
                else
                {
                    writer.Write("></" + Tag + ">");
                }
            }
            else if (!string.IsNullOrEmpty(innerContent))
            {
                writer.Write(">" + innerContent);
            }
            else
            {
                writer.Write(">");
            }
        }
コード例 #27
0
        public async Task ReactBridge_FlushQueueImmediate()
        {
            var jsFactories = new Func <IJavaScriptExecutor>[]
            {
                () => new ChakraJavaScriptExecutor(),
#if WINDOWS_UWP
                () => new NativeJavaScriptExecutor(),
#endif
            };

            foreach (var jsFactory in jsFactories)
            {
                await JavaScriptHelpers.Run(async (executor, jsQueueThread) =>
                {
                    using (var nativeThread = CreateNativeModulesThread())
                    {
                        var moduleId       = 42;
                        var methodId       = 7;
                        var called         = 0;
                        var countdownEvent = new CountdownEvent(1);
                        var callback       = new MockReactCallback
                        {
                            InvokeHandler = (mod, met, arg) =>
                            {
                                Assert.AreEqual(moduleId, mod);
                                Assert.AreEqual(methodId, met);
                                Assert.AreEqual(1, arg.Count);
                                Assert.AreEqual("foo", arg[0].Value <string>());
                                ++called;
                            },
                            OnBatchCompleteHandler = () => countdownEvent.Signal(),
                        };

                        var bridge = new ReactBridge(executor, callback, nativeThread);
                        await jsQueueThread.RunAsync(() =>
                        {
                            bridge.CallFunction("FlushQueueImmediateModule", "test", new JArray {
                                10, new JArray {
                                    new JArray {
                                        42
                                    }, new JArray {
                                        7
                                    }, new JArray {
                                        new JArray {
                                            "foo"
                                        }
                                    }
                                }
                            });
                        });

                        // wait for `OnBatchComplete` in background
                        // so we don't block native module thread
                        await Task.Run(new Action(countdownEvent.Wait));

                        Assert.AreEqual(10, called);
                    }
                },
                                            jsFactory,
                                            @"Resources/immediate.js");
            }
        }
コード例 #28
0
        /// <summary>
        /// Setup RequireJS to be used in layouts
        /// </summary>
        /// <param name="html">
        /// Html helper.
        /// </param>
        /// <param name="config">
        /// Configuration object for various options.
        /// </param>
        /// <returns>
        /// The <see cref="MvcHtmlString"/>.
        /// </returns>
        public static MvcHtmlString RenderRequireJsSetup(
            this HtmlHelper html,
            RequireRendererConfiguration config)
        {
            if (config == null)
            {
                throw new ArgumentNullException("config");
            }

            var entryPointPath = html.RequireJsEntryPoint(config.BaseUrl, config.EntryPointRoot);

            if (entryPointPath == null)
            {
                return(new MvcHtmlString(string.Empty));
            }

            if (config.ConfigurationFiles == null || !config.ConfigurationFiles.Any())
            {
                throw new Exception("No config files to load.");
            }

            var processedConfigs = config.ConfigurationFiles.Select(r =>
            {
                var resultingPath = html.ViewContext.HttpContext.MapPath(r);
                PathHelpers.VerifyFileExists(resultingPath);
                return(resultingPath);
            }).ToList();

            var resultingConfig = GetCachedOverridenConfig(processedConfigs, config, entryPointPath.ToString());

            var locale = config.LocaleSelector(html);

            var outputConfig = new JsonRequireOutput
            {
                BaseUrl     = config.BaseUrl,
                Locale      = locale,
                UrlArgs     = config.UrlArgs,
                WaitSeconds = config.WaitSeconds,
                Paths       = resultingConfig.Paths.PathList.ToDictionary(r => r.Key, r => r.Value),
                Shim        = resultingConfig.Shim.ShimEntries.ToDictionary(
                    r => r.For,
                    r => new JsonRequireDeps
                {
                    Dependencies = r.Dependencies.Select(x => x.Dependency).ToList(),
                    Exports      = r.Exports
                }),
                Map = resultingConfig.Map.MapElements.ToDictionary(
                    r => r.For,
                    r => r.Replacements.ToDictionary(x => x.OldKey, x => x.NewKey))
            };

            config.ProcessConfig(outputConfig);

            var options = new JsonRequireOptions
            {
                Locale         = locale,
                PageOptions    = RequireJsOptions.GetPageOptions(html.ViewContext.HttpContext),
                WebsiteOptions = RequireJsOptions.GetGlobalOptions(html.ViewContext.HttpContext)
            };

            config.ProcessOptions(options);

            var configBuilder = new JavaScriptBuilder();

            configBuilder.AddStatement(JavaScriptHelpers.SerializeAsVariable(options, "requireConfig"));
            configBuilder.AddStatement(JavaScriptHelpers.SerializeAsVariable(outputConfig, "require"));

            var requireRootBuilder = new JavaScriptBuilder();

            requireRootBuilder.AddAttributesToStatement("src", config.RequireJsUrl);

            var requireEntryPointBuilder = new JavaScriptBuilder();

            requireEntryPointBuilder.AddStatement(
                JavaScriptHelpers.MethodCall(
                    "require",
                    (object)new[] { entryPointPath.ToString() }));

            return(new MvcHtmlString(
                       configBuilder.Render()
                       + Environment.NewLine
                       + requireRootBuilder.Render()
                       + Environment.NewLine
                       + requireEntryPointBuilder.Render()));
        }
コード例 #29
0
        internal override void Render(AjaxPage page, string[] templateNames, System.IO.TextWriter writer)
        {
            bool             canRender;
            AttributeBinding ifBinding;

            if (!TryRenderIf(page, templateNames, writer, out ifBinding, out canRender))
            {
                Abort(page, templateNames, writer);
                return;
            }

            if (!canRender)
            {
                return;
            }

            // Output the original template if toggle on was not specified
            if (On == null)
            {
                Abort(page, templateNames, writer);
                return;
            }

            // Get the data associated with the data view
            var onBinding = On.Evaluate(page);

            // Output the original template if no data for on was found
            if (!onBinding.IsValid)
            {
                Abort(page, templateNames, writer);
                return;
            }

            var onValue = onBinding.Value;

            var classValue   = "";
            var classBinding = (AttributeBinding)null;

            if (ClassName != null)
            {
                classBinding = ClassName.Evaluate(page);

                // Output the original template if no data for class was found
                if (!classBinding.IsValid)
                {
                    Abort(page, templateNames, writer);
                    return;
                }

                classValue = (string)classBinding.Value;
            }

            ToggleAction?actionValue;

            var actionBinding = (AttributeBinding)null;

            // Get the value of the toggle action (i.e.: show, hide, etc.)
            if (Action != null)
            {
                actionBinding = Action.Evaluate(page);

                // Output the original template if no data for action was found
                if (!actionBinding.IsValid)
                {
                    Abort(page, templateNames, writer);
                    return;
                }

                actionValue = (ToggleAction)Enum.Parse(typeof(ToggleAction), (string)actionBinding.Value, true);
            }
            else if (!string.IsNullOrEmpty(classValue))
            {
                actionValue = ToggleAction.AddClass;
            }
            else
            {
                actionValue = ToggleAction.Show;
            }

            var groupNameBinding = (AttributeBinding)null;

            if (GroupName != null)
            {
                groupNameBinding = GroupName.Evaluate(page);

                // Output the original template if no data for group name was found
                if (!groupNameBinding.IsValid)
                {
                    Abort(page, templateNames, writer);
                    return;
                }
            }

            var strictModeValue   = false;
            var strictModeBinding = (AttributeBinding)null;

            if (StrictMode != null)
            {
                strictModeBinding = StrictMode.Evaluate(page);

                // Output the original template if no data for strict mode was found
                if (!strictModeBinding.IsValid)
                {
                    Abort(page, templateNames, writer);
                    return;
                }

                if (strictModeBinding.Value is bool)
                {
                    strictModeValue = (bool)strictModeBinding.Value;
                }
                else
                {
                    strictModeValue = bool.Parse((string)strictModeBinding.Value);
                }
            }

            bool?equals;

            var whenBinding = (AttributeBinding)null;

            // Evaluate whether the on and when conditions are equal or
            // satisified, which determines whether the toggle is on or off
            if (When == null)
            {
                if (strictModeValue)
                {
                    // In strict mode the on value must be a boolean true
                    if (!(onValue is bool))
                    {
                        throw new ApplicationException(string.Format("With strict mode enabled, toggle:on should be a value of type Boolean, actual type \"{0}\".", onValue == null ? "null" : onValue.GetType().Name));
                    }

                    equals = (bool)onValue;
                }
                else if (onValue is System.Collections.IEnumerable)
                {
                    equals = false;

                    // Satisfied if there are any items
                    foreach (object o in (System.Collections.IEnumerable)onValue)
                    {
                        equals = true;
                        break;
                    }
                }
                else
                {
                    // Otherwise, check to see that the on value is "truthy"
                    equals = JavaScriptHelpers.IsTruthy(onValue);
                }
            }
            else
            {
                whenBinding = When.Evaluate(page);

                var whenValue = whenBinding.Value;

                if (whenValue == null)
                {
                    equals = (onValue == null);
                }
                else if (whenValue is FunctionInstance)
                {
                    object result;

                    try
                    {
                        result = Page.ScriptMarshaller.Unwrap(((FunctionInstance)whenValue).Call(null, Page.ScriptMarshaller.Wrap(onValue)));
                    }
                    catch
                    {
                        Abort(page, templateNames, writer);
                        return;
                    }

                    if (strictModeValue)
                    {
                        if (!(result is bool))
                        {
                            throw new ApplicationException(string.Format("With strict mode enabled, toggle:when function should return a value of type Boolean, found type \"{0}\".", result == null ? "null" : result.GetType().Name));
                        }
                        equals = (bool)result;
                    }
                    else
                    {
                        equals = JavaScriptHelpers.IsTruthy(result);
                    }
                }
                else
                {
                    equals = whenValue.Equals(onValue);
                }
            }

            // If no class value is defined then abort
            if ((actionValue == ToggleAction.AddClass || actionValue == ToggleAction.RemoveClass) && string.IsNullOrEmpty(classValue))
            {
                Abort(page, templateNames, writer);
                return;
            }

            bool render = actionValue == ToggleAction.Render || actionValue == ToggleAction.Dispose;

            AttributeBinding contentTemplateBinding;

            if (!TryContentTemplate(page, templateNames, writer, out contentTemplateBinding))
            {
                Abort(page, templateNames, writer);
                return;
            }

            var ownTemplateNames = contentTemplateBinding != null ?
                                   ((string)contentTemplateBinding.Value).Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) :
                                   new string[0];

            using (var context = render ? page.BeginContext(page.Context.DataItem, null) : null)
            {
                RenderStartTag(page, writer, attrs => MergeAttribute(MergeAttribute(MergeAttribute(attrs,
                                                                                                   "class", value =>
                {
                    if (actionValue == ToggleAction.AddClass || actionValue == ToggleAction.RemoveClass)
                    {
                        if ((actionValue == ToggleAction.AddClass && equals.Value) || (actionValue == ToggleAction.RemoveClass && !equals.Value))
                        {
                            value = AttributeHelper.EnsureClassName(value, classValue);
                        }
                        else
                        {
                            value = AttributeHelper.RemoveClassName(value, classValue);
                        }
                    }

                    // Add/remove the "toggle-on" and "toggle-off" classes based on state
                    value = AttributeHelper.EnsureClassName(value, equals.Value ? "toggle-on" : "toggle-off");
                    value = AttributeHelper.RemoveClassName(value, equals.Value ? "toggle-off" : "toggle-on");

                    return(value);
                }).ToArray(),
                                                                                    "style", value =>
                {
                    if (actionValue == ToggleAction.Show || actionValue == ToggleAction.Hide ||
                        actionValue == ToggleAction.Render || actionValue == ToggleAction.Dispose)
                    {
                        if (((actionValue == ToggleAction.Show || actionValue == ToggleAction.Render) && equals.Value) ||
                            ((actionValue == ToggleAction.Hide || actionValue == ToggleAction.Dispose) && !equals.Value))
                        {
                            if (AttributeHelper.GetCssStyle(value, "display") == "none")
                            {
                                value = AttributeHelper.RemoveCssStyle(value, "display");
                            }
                        }
                        else
                        {
                            value = AttributeHelper.EnsureCssStyle(value, "display", "none");
                        }
                    }

                    return(value);
                }).ToArray(),
                                                                     "disabled", value =>
                {
                    if (actionValue == ToggleAction.Enable || actionValue == ToggleAction.Disable)
                    {
                        if ((actionValue == ToggleAction.Enable && equals.Value) || (actionValue == ToggleAction.Disable && !equals.Value))
                        {
                            value = null;
                        }
                        else
                        {
                            value = "disabled";
                        }
                    }

                    return(value);
                }), ifBinding, onBinding, classBinding, actionBinding, groupNameBinding, strictModeBinding, whenBinding, contentTemplateBinding,
                               // If this is render/dispose, include the nested template index as a special attribute
                               render ? new AttributeBinding(new Attribute()
                {
                    Name = "data-sys-tmplidx", Value = NestedTemplateIndex.ToString()
                }, null) : null,
                               render ? new AttributeBinding(new Attribute()
                {
                    Name = "data-sys-tcindex", Value = context.Id
                }, null) : null);

                // Only render the inner blocks if the template would be rendered client-side
                if (!render || (actionValue == ToggleAction.Render && equals.Value) || (actionValue == ToggleAction.Dispose && !equals.Value))
                {
                    foreach (var block in Blocks)
                    {
                        block.Render(page, templateNames.Concat(ownTemplateNames).ToArray(), writer);
                    }
                }

                RenderEndTag(writer);
            }
        }