/// <summary> /// Build the JavaScript content and add it to the supplied /// <see cref="IFlowData"/> instance. /// </summary> /// <param name="data"> /// The <see cref="IFlowData"/> instance to populate with the /// resulting <see cref="JavaScriptBuilderElementData"/> /// </param> /// <param name="jsonObject"> /// The JSON data object to include in the JavaScript. /// </param> /// <param name="supportsPromises"> /// True to build JavaScript that uses promises. False to /// build JavaScript that does not use promises. /// </param> /// <param name="url"> /// The callback URL for the JavaScript to send a request to /// when it has new evidence values to supply. /// </param> /// <exception cref="ArgumentNullException"> /// Thrown if the supplied flow data is null. /// </exception> protected void BuildJavaScript(IFlowData data, string jsonObject, bool supportsPromises, Uri url) { if (data == null) { throw new ArgumentNullException(nameof(data)); } JavaScriptBuilderElementData elementData = (JavaScriptBuilderElementData) data.GetOrAdd( ElementDataKeyTyped, CreateElementData); // Try and get the requested object name from evidence. if (data.TryGetEvidence(Constants.EVIDENCE_OBJECT_NAME, out string objectName) == false || string.IsNullOrWhiteSpace(objectName)) { objectName = ObjName; } var ubdateEnabled = url != null && url.AbsoluteUri.Length > 0; JavaScriptResource javaScriptObj = new JavaScriptResource( objectName, jsonObject, supportsPromises, url, EnableCookies, ubdateEnabled); string content = _stubble.Render(_template, javaScriptObj.AsDictionary() /*, _renderSettings*/); string minifiedContent = content; if (_minify) { // Minimize the script. var ugly = Uglify.Js(content); if (ugly.HasErrors) { // If there were are errors then log them and // return the non-minified response. minifiedContent = content; if (_lastRequestWasError == false) { StringBuilder errorText = new StringBuilder(); errorText.AppendLine("Errors occurred when minifying JavaScript."); foreach (var error in ugly.Errors) { errorText.AppendLine($"{error.ErrorCode}: {error.Message}. " + $"Line(s) {error.StartLine}-{error.EndLine}. " + $"Column(s) {error.StartColumn}-{error.EndColumn}"); } errorText.AppendLine(content); Logger.LogError(errorText.ToString()); _lastRequestWasError = true; #pragma warning disable CS0618 // Type or member is obsolete // This usage should be replaced with the // CancellationToken implementation once it // is available. data.Stop = true; #pragma warning restore CS0618 // Type or member is obsolete } } else { minifiedContent = ugly.Code; } } elementData.JavaScript = minifiedContent; }
/// <summary> /// Build the JavaScript content and add it to the supplied /// <see cref="IFlowData"/> instance. /// </summary> /// <param name="data"> /// The <see cref="IFlowData"/> instance to populate with the /// resulting <see cref="JavaScriptBuilderElementData"/> /// </param> /// <param name="jsonObject"> /// The JSON data object to include in the JavaScript. /// </param> /// <param name="sessionId"> /// The session Id to use in the JavaScript response. /// </param> /// <param name="sequence"> /// The sequence value to use in the JavaScript response. /// </param> /// <param name="supportsPromises"> /// True to build JavaScript that uses promises. False to /// build JavaScript that does not use promises. /// </param> /// <param name="supportsFetch"> /// True to build JavaScript that makes use of the /// fetch API. Otherwise, the template will fall back to using /// XMLHttpRequest. /// </param> /// <param name="url"> /// The callback URL for the JavaScript to send a request to /// when it has new evidence values to supply. /// </param> /// <param name="parameters">The parameters to append to the URL</param> /// <exception cref="ArgumentNullException"> /// Thrown if the supplied flow data is null. /// </exception> protected void BuildJavaScript( IFlowData data, string jsonObject, string sessionId, int sequence, bool supportsPromises, bool supportsFetch, Uri url, string parameters) { if (data == null) { throw new ArgumentNullException(nameof(data)); } JavaScriptBuilderElementData elementData = (JavaScriptBuilderElementData) data.GetOrAdd( ElementDataKeyTyped, CreateElementData); string objectName = ObjName; // Try and get the requested object name from evidence. if (data.TryGetEvidence(Constants.EVIDENCE_OBJECT_NAME, out object objObjectName)) { objectName = objObjectName?.ToString() ?? ObjName; } var ubdateEnabled = url != null && url.AbsoluteUri.Length > 0; // This check won't be 100% fool-proof but it only needs to be // reasonably accurate and not take too long. var hasDelayedProperties = jsonObject != null && jsonObject.Contains("delayexecution"); JavaScriptResource javaScriptObj = new JavaScriptResource( objectName, jsonObject, sessionId, sequence, supportsPromises, supportsFetch, url, parameters, EnableCookies, ubdateEnabled, hasDelayedProperties); string content = _stubble.Render(_template, javaScriptObj.AsDictionary()); string minifiedContent = content; if (_minify) { // Minimize the script. var ugly = Uglify.Js(content); if (ugly.HasErrors) { // If there were are errors then log them and // return the non-minified response. minifiedContent = content; if (_lastRequestWasError == false) { StringBuilder errorText = new StringBuilder(); errorText.AppendLine("Errors occurred when minifying JavaScript."); foreach (var error in ugly.Errors) { errorText.AppendLine($"{error.ErrorCode}: {error.Message}. " + $"Line(s) {error.StartLine}-{error.EndLine}. " + $"Column(s) {error.StartColumn}-{error.EndColumn}"); } errorText.AppendLine(content); Logger.LogError(errorText.ToString()); _lastRequestWasError = true; #pragma warning disable CS0618 // Type or member is obsolete // This usage should be replaced with the // CancellationToken implementation once it // is available. data.Stop = true; #pragma warning restore CS0618 // Type or member is obsolete } } else { minifiedContent = ugly.Code; } } elementData.JavaScript = minifiedContent; }