protected sealed override void FinishAjaxRequest() { // ajax request OSJSONResponse resp = CreateJSONResponse(); if (!AjaxRedirectLocation.IsEmpty()) { // ajax redirect... WriteAJAXClientRedirectResponse(Request, Response, AjaxRedirectLocation); return; } if (_partialViewStateBuckets.Count > 0) { // include in JSON response the updated viewstate buckets that is // at this moment stored in _partialViewStateBuckets foreach (string bucketName in _partialViewStateBuckets.Keys) { resp.AddToHidden(bucketName, _partialViewStateBuckets[bucketName].ToString()); } } // send the end request signal resp.AddToJs("OsEndRequest()"); WriteJavascriptResponse(FormatJSONResponseString(resp), /*flush*/ false); return; }
public string GetEndPageJavaScript() { string ret = ""; // send all the queued javascript, if any string onloadVSUpdate = OnloadVSUpdate; if (onloadVSUpdate.Length > 0) { ret += "<script type=\"text/javascript\">outsystems.internal.$._waitForViewstate = true;" + "outsystems.internal.$(document).ready(function() {outsystems.internal.$('input[name=__OSVSTATE]').val('" + onloadVSUpdate + "');" + "outsystems.internal.$._waitForViewstate = false;});</script>\n"; } if (_javascriptQueueResponse.Js.Count > 0) { if (IsFirstAjaxResponse) { ret += JavascriptBeginTag + GetJsonUpdateScript() + JavascriptEndTag; } OSJSONResponse resp = new OSJSONResponse(); resp.AddToJs("outsystems.internal.$(document).ready(function() {" + FormatJSONResponseString(_javascriptQueueResponse) + "});"); ret += JavascriptBeginTag + FormatJSONResponseString(resp) + JavascriptEndTag; } return(ret); }
public virtual void AddQueuedJavascript(string script) { if (IsAjaxRequest && !_isRefreshingWidget) { //immediate js OSJSONResponse resp = CreateJSONResponse(); resp.AddToJs(script); WriteJavascriptResponse(FormatJSONResponseString(resp), /*flush*/ true); } else { //queue javascript _javascriptQueueResponse.AddToJs(script); } }
private static void WriteJavascriptResponse(HttpRequest request, HttpResponse response, string script, bool flush) { try { bool isIE = (request.Browser.Browser == "IE"); response.ContentType = "text/html"; // #90781 // Internet explorer requires the first ajax response to be of at least 256 bytes, otherwise it will // only be executed when the receive buffer fills up in subsequent responses or when the request ends. // After that, subsequent responses can be of any size that they are executed promptly if (IsFirstAjaxResponse && isIE) { // This padding string ensures that 256 bytes are sent, even when compression is enabled // Using deflate compression stream, it outputs 256 bytes // Using gzip compression stream, it outputs 266 bytes // Using no compression, it outputs 334 bytes string firstPadding = "<!-- OSPADDING VURGXTTJYZMCVZAFKKOPWKYUBXQDXDADFBRUSOSCDMISJYMZIROBPVAHBEFPZLMQVJXTEGNVRMLKCGGCLQQBLYJFAFTOEYYOARSAWSRCEVURGXTTJYZMCVZAFKKOPWKYUBXQDXDADFBRUSOSCDMISJYMZIROBPVAHBEFPZLMQVJXTEGNVRMLKCGGCLQQBLYJFAFTOEYYOARSAWSRCEVURGXTTJYZMCVZAFKKOPWKYUBXQDXDADFBRUSOSCDMISJYMZIROBPVAHBEFPZLMQVJXTEGNVRMLKCGGCLQQBLYJFAFTOEYYOARSAWSRCE -->"; response.Write(firstPadding); } if (IsFirstAjaxResponse) { // Make sure the JSONUpdate function is defined in the current window response.Write(JavascriptBeginTag + GetJsonUpdateScript() + JavascriptEndTag); try { //Add requestInfo necessary data for beacon in performanceprobe.js OSJSONResponse resp = new OSJSONResponse(); RequestTracer perfTracer = AppInfo.GetAppInfo().OsContext.RequestTracer; resp.AddToJs("OsSetRequestInfo('{0}','{1}','{2}')".F(perfTracer.RequestKey, perfTracer.EntryActionName, perfTracer.EntryActionKey)); response.Write(JavascriptBeginTag + FormatJSONResponseString(resp) + JavascriptEndTag); } catch (Exception e) { ErrorLog.LogApplicationError(e, null, "WebWidgets"); } IsFirstAjaxResponse = false; } // This padding ensures that, if we are using a compression filter, that the output // is completely flushed to the underlying stream. // It is needed because the compression may flush every but the last few bytes. // Usually in a compressed flush the last one or two bytes will be missing. string padding = "<!-- OSPADDING -->"; // write the respose and its end tag response.Write(JavascriptBeginTag + script + JavascriptEndTag); if (RuntimePlatformUtils.IsJava() || flush) { response.Flush(); } response.Write(padding); if (RuntimePlatformUtils.IsJava() || flush) { //the padding goes on a separate chunk to make sure the actual content //get's flushed to the client response.Flush(); } } catch { // Ignore errors writting the response (eg: client closed tab) } }
public void AjaxRefresh(Control c, int rowIndex, string animationName, string listOperation, bool isTableRecord, object dataItem, StoreViewStateDelegate storeViewStateDelegate, string clientIdOverride) { // don't do nothing if not in a partial request or if the control is not accessible (e.g.: refreshing widgets inside table records from outside) if (!IsAjaxRequest || c == null) { return; } // mark that we are refreshing a widget, so that possible queued javascripts happening in the databind are queued // to be sent immediately after the control json (for web block preparations or user defined functions execution) _isRefreshingWidget = true; try { LocalState stackBackup = null; #if JAVA HashSet <IAbstractTopLevelComponentWithMandatory> previousVisibleComponentsWithValidation = null, newVisibleComponentsWithValidation = null; #endif if (c is OSUserControl) { OSUserControl blk = (OSUserControl)c; stackBackup = ((IWebScreen)blk.Page).PushStack(); } else { stackBackup = ((IWebScreen)c.Page).PushStack(); } if (listOperation == "") { #if JAVA previousVisibleComponentsWithValidation = GetVisibleComponentsWithValidation(c); #endif // databind the control c.DataBind(); #if JAVA newVisibleComponentsWithValidation = GetVisibleComponentsWithValidation(c); #endif } else { // some list operation if (!isTableRecord) { // list records require the prerender phase before list append, insert and remove operations, since prerender creates the current child controls hierarchy MethodInfo preRenderRecursiveInternal = typeof(Page).GetMethod("PreRenderRecursiveInternal", BindingFlags.NonPublic | BindingFlags.Instance); preRenderRecursiveInternal.Invoke(c, null); } IListRefresh listWidget = (IListRefresh)c; // execute the list refresh databind to restore LineCount and StartIndex runtime properties in the table / list record listWidget.DoListRefreshDataBind(); // execute the operation in the list switch (listOperation) { case "Append": listWidget.AppendItem(dataItem); break; case "Insert": listWidget.InsertItem(rowIndex, dataItem); break; case "Remove": listWidget.RemoveItem(rowIndex); break; case "Refresh": listWidget.RefreshItem(rowIndex); break; default: System.Diagnostics.Debug.Assert(false, "unknown list operation: " + listOperation); break; } } // call store viewstate in the calling page / block storeViewStateDelegate(); if (stackBackup != null) { Debugger.Pop(stackBackup, true); } // save partial viewstate and get modified buckets Hashtable modifiedBuckets = PartialSaveAllState(); OSJSONResponse resp = CreateJSONResponse(); // build JSON response with the control rendering and modified buckets foreach (string bucketName in modifiedBuckets.Keys) { resp.AddToHidden(bucketName, modifiedBuckets[bucketName].ToString()); } string html = ""; if (listOperation == "") { // regular ajax refresh // render control and add it to outers resp.AddToOuter(c.ClientID, RenderControl(c)); #if JAVA ProcessComponentsWithValidationTurnedInvisible(previousVisibleComponentsWithValidation, newVisibleComponentsWithValidation); #endif } else { // implicit ajax refresh via ListAppend, ListInsert or ListRemove if (listOperation == "Append") { html = RenderAjaxListOperationRow(c); } else if (listOperation == "Insert") { #if JAVA html = RenderAjaxListOperationRow(c, rowIndex); #else html = RenderAjaxListOperationRow(c); #endif } else if (listOperation == "Remove") { // need to render the empty message? if (((IListRefresh)c).IsEmpty) { html = RenderAjaxListOperationRow(c, true); } } else if (listOperation == "Refresh") { // row refresh operation html = RenderAjaxListOperationRow(c, rowIndex); } string oddLineStyle = ""; string evenLineStyle = ""; bool useBullets = false; if (c is OSDataGrid) { // get table record information to be sent to the client js OSDataGrid dg = (OSDataGrid)c; oddLineStyle = dg.OddLineStyle ?? oddLineStyle; evenLineStyle = dg.EvenLineStyle ?? evenLineStyle; } else { // get list record information to be sent to the client js Iterator it = (Iterator)c; useBullets = it.UseBullets; } resp.AddToList(clientIdOverride ?? c.ClientID, html, listOperation, rowIndex, isTableRecord, oddLineStyle, evenLineStyle, useBullets); } // Add call to animation registration if (animationName != null && animationName != "None") { if (listOperation == "Remove" && animationName == "Highlight") { animationName = "ListRemoveHighlight"; } resp.AddToJs("OsRegisterEffect" + animationName.Replace(" ", "") + "();"); } // write and flush the response WriteJavascriptResponse(FormatJSONResponseString(resp), /*flush*/ true); // send all the queued javascript gathered in this refresh if (_javascriptQueueResponse.Js.Count > 0) { resp = CreateJSONResponse(); resp.AddToJs("outsystems.internal.$(document).ready(function() {" + FormatJSONResponseString(_javascriptQueueResponse) + "});"); // clear it for next executions _javascriptQueueResponse.ClearJs(); // write the response WriteJavascriptResponse(FormatJSONResponseString(resp), /*flush*/ true); } // cleanup JavaScript includes so the next refresh will not re-include it BlocksJavaScript.CleanupAlreadyIncludedBlocksWithJavaScript(); } finally { // we're no longer refreshing a widget _isRefreshingWidget = false; } }