// Register with framemanager that loading is complete. This needs to be the final script in the buffer. private void FinishOnLoadScript(StringBuilder scriptBlock) { // Don't do the script block if the content is not LRM. if (Session.CurrentActivityResourceType != ResourceType.Lrm) { return; } // Add the form to post. Need to do it here because we have just allowed the application to set the form // name. scriptBlock.Append("frameMgr.SetPostableForm(document.forms[0]);\r\n"); // Register that the frame loading is complete. This is required so as to notify the frameset of activity id, and // other UI status. scriptBlock.AppendFormat("frameMgr.RegisterFrameLoad({0});\r\n ", JScriptString.QuoteString("frameContent", false)); if (m_isPostedPage) { // Set PostIsComplete. THIS MUST BE THE LAST VALUE SET! scriptBlock.AppendLine("frameMgr.PostIsComplete();"); } }
public void UpdateRenderContext(RenderContext context, StringBuilder scriptBlock, LearningSession session) { // Set values other than OutputStream and RelativePath context.EmbeddedUIResourcePath = new Uri(SlkEmbeddedUIPath, "Images/"); SetMimeTypeMapping(context.MimeTypeMapping); SetIisCompatibilityModeExtensions(context.IisCompatibilityModeExtensions); // If this is not the primary resource, nothing else matters. if (scriptBlock == null) { return; } LearnerAssignmentProperties la = GetLearnerAssignment(); switch (AssignmentView) { case AssignmentView.Execute: { context.ShowCorrectAnswers = false; context.ShowReviewerInformation = false; } break; case AssignmentView.StudentReview: { context.ShowCorrectAnswers = la.Assignment.ShowAnswersToLearners; context.ShowReviewerInformation = false; } break; case AssignmentView.InstructorReview: { context.ShowCorrectAnswers = true; context.ShowReviewerInformation = true; } break; case AssignmentView.Grading: { context.ShowCorrectAnswers = true; context.ShowReviewerInformation = true; } break; } // Update hidden controls and script to include assignment information if there is script // information to be written. Only write script in LRM content. if ((scriptBlock != null) && (session.CurrentActivityResourceType == ResourceType.Lrm)) { WriteSlkMgrInit(scriptBlock); scriptBlock.AppendLine("slkMgr = Slk_GetSlkManager();"); context.FormHiddenControls.Add(HiddenFieldNames.LearnerAssignmentId, FramesetUtil.GetStringInvariant(la.LearnerAssignmentId.GetKey())); scriptBlock.AppendFormat("slkMgr.LearnerAssignmentId = document.getElementById({0}).value;\r\n", JScriptString.QuoteString(HiddenFieldNames.LearnerAssignmentId, false)); context.FormHiddenControls.Add(HiddenFieldNames.LearnerAssignmentStatus, SlkUtilities.GetLearnerAssignmentState(la.Status)); scriptBlock.AppendFormat("slkMgr.Status = document.getElementById({0}).value;\r\n", JScriptString.QuoteString(HiddenFieldNames.LearnerAssignmentStatus, false)); // Set the change in final points. This can only happen in grading. if (AssignmentView == AssignmentView.Grading) { string finalPointsValue = "null"; float? finalPoints = la.FinalPoints; if (finalPoints != null) { // FinalPoints is invariant culture finalPointsValue = Convert.ToString(finalPoints.Value, CultureInfo.InvariantCulture.NumberFormat); } scriptBlock.AppendFormat("slkMgr.FinalPoints = {0};\r\n", finalPointsValue); } // Send information about total points (ie, computed points on the client). if (session != null) { if (session.TotalPoints != null) { // TotalPoints is passed in current culture, as a string JScriptString totalPointsValue = JScriptString.QuoteString(Convert.ToString(session.TotalPoints, CultureInfo.CurrentCulture.NumberFormat), false); scriptBlock.AppendFormat("slkMgr.ComputedPoints = {0};\r\n", totalPointsValue); } else { scriptBlock.Append("slkMgr.ComputedPoints = \"\";\r\n"); } if (session.SuccessStatus != SuccessStatus.Unknown) { scriptBlock.AppendFormat("slkMgr.PassFail = {0};\r\n", JScriptString.QuoteString(((session.SuccessStatus == SuccessStatus.Passed) ? "passed" : "failed"), false)); } } } }
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] // exceptions caught, added to event log protected void Page_Load(object sender, EventArgs e) { try { SlkUtilities.RetryOnDeadlock(delegate() { //Initialize data that may need to be reset on retry Response.Clear(); ClearError(); m_sessionEnded = false; m_hiddenHelper = new HiddenHelper(Request, Response, SlkEmbeddedUIPath); m_hiddenHelper.ProcessPageLoad(SlkStore.PackageStore, GetSessionTitle, TryGetSessionView, TryGetAttemptId, AppendContentFrameDetails, RegisterError, GetErrorInfo, ProcessSessionEnd, ProcessViewRequest, GetMessage, IsPostBack); // Send assignment information to client. If the session has ended, then force a reload of the current // assignment properties. Otherwise, the cached value will have required info so no need to re-query database. LearnerAssignmentProperties la = GetLearnerAssignment(SessionEnded); // Add assignment information to the hidden controls HiddenControlInfo hiddenCtrlInfo = new HiddenControlInfo(); hiddenCtrlInfo.Id = new PlainTextString(HiddenFieldNames.LearnerAssignmentId); hiddenCtrlInfo.Value = new PlainTextString(FramesetUtil.GetStringInvariant(la.LearnerAssignmentId.GetKey())); hiddenCtrlInfo.FrameManagerInitializationScript = new JScriptString(ResHelper.Format("slkMgr.LearnerAssignmentId = document.getElementById({0}).value;", JScriptString.QuoteString(HiddenFieldNames.LearnerAssignmentId, false))); m_hiddenHelper.HiddenControls.Add(hiddenCtrlInfo); // Learner assignment status ('not started', 'in progress', etc) hiddenCtrlInfo = new HiddenControlInfo(); hiddenCtrlInfo.Id = new PlainTextString(HiddenFieldNames.LearnerAssignmentStatus); hiddenCtrlInfo.Value = new PlainTextString(SlkUtilities.GetLearnerAssignmentState(la.Status)); hiddenCtrlInfo.FrameManagerInitializationScript = new JScriptString(ResHelper.Format("slkMgr.Status = document.getElementById({0}).value;", JScriptString.QuoteString(HiddenFieldNames.LearnerAssignmentStatus, false))); m_hiddenHelper.HiddenControls.Add(hiddenCtrlInfo); hiddenCtrlInfo = new HiddenControlInfo(); if (la.FinalPoints != null) { // finalPoints is passed in invariant culture, as a float hiddenCtrlInfo.FrameManagerInitializationScript = new JScriptString(ResHelper.Format("slkMgr.FinalPoints = {0};", Convert.ToString(la.FinalPoints, CultureInfo.InvariantCulture.NumberFormat))); } else { hiddenCtrlInfo.FrameManagerInitializationScript = new JScriptString("slkMgr.FinalPoints = null;"); } m_hiddenHelper.HiddenControls.Add(hiddenCtrlInfo); // Send information about total points (ie, computed points on the client). This is called 'graded score' in // grading page. LearningSession session = m_hiddenHelper.Session; if (session != null) { hiddenCtrlInfo = new HiddenControlInfo(); if (session.TotalPoints != null) { // TotalPoints is passed in current culture, as a string JScriptString totalPointsValue = JScriptString.QuoteString(Convert.ToString(session.TotalPoints, CultureInfo.CurrentCulture.NumberFormat), false); hiddenCtrlInfo.FrameManagerInitializationScript = new JScriptString(ResHelper.Format("slkMgr.ComputedPoints = {0};", totalPointsValue)); } else { hiddenCtrlInfo.FrameManagerInitializationScript = new JScriptString("slkMgr.ComputedPoints = \"\";"); } m_hiddenHelper.HiddenControls.Add(hiddenCtrlInfo); if (session.SuccessStatus != SuccessStatus.Unknown) { hiddenCtrlInfo = new HiddenControlInfo(); hiddenCtrlInfo.FrameManagerInitializationScript = new JScriptString(ResHelper.Format("slkMgr.PassFail = {0};\r\n", JScriptString.QuoteString(((session.SuccessStatus == SuccessStatus.Passed) ? "passed" : "failed"), false))); m_hiddenHelper.HiddenControls.Add(hiddenCtrlInfo); } } }); } catch (Exception ex) { ClearError(); // Unexpected exceptions are not shown to user SlkStore.LogError(FramesetResources.FRM_UnknownExceptionMsg, ex.ToString()); RegisterError(ResHelper.GetMessage(FramesetResources.FRM_UnknownExceptionTitle), ResHelper.GetMessage(SlkFrameset.FRM_UnexpectedExceptionMsg), false); } }
SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods")] // parameter is validated public void ProcessSessionEnd(LearningSession session, ref string messageTitle, ref string message) { FramesetUtil.ValidateNonNullParameter("session", session); // If we have already been here, then there is nothing more to do. if (SessionEnded) { return; } LearnerAssignmentProperties la = GetLearnerAssignment(); // Session ending results in message shown to the user. if (session.View == SessionView.Execute) { StoredLearningSession slsSession = session as StoredLearningSession; if (slsSession != null) { // The rollup and/or sequencing process may have changed the state of the attempt. If so, there are some cases // that cannot continue so show an error message. switch (slsSession.AttemptStatus) { case AttemptStatus.Abandoned: messageTitle = SlkFrameset.HID_SessionAbandonedTitle; message = SlkFrameset.HID_ExecuteViewAbandonedSessionMsg; SessionEnded = true; break; case AttemptStatus.Completed: messageTitle = SlkFrameset.HID_SessionCompletedTitle; message = SlkFrameset.HID_ExecuteViewCompletedSessionMsg; SessionEnded = true; break; case AttemptStatus.Suspended: messageTitle = SlkFrameset.HID_SessionSuspendedTitle; message = SlkFrameset.HID_ExecuteViewSuspendedSessionMsg; // Do not set SessionEnded -- the session being suspended does not warrant ending the learner assignment break; } } if (SessionEnded) { // Call FinishLearnerAssignment since the attempt has already been completed. SlkStore.FinishLearnerAssignment(LearnerAssignmentGuidId); } } else if (session.View == SessionView.RandomAccess) { messageTitle = SlkFrameset.HID_GradingFinishedTitle; message = SlkFrameset.HID_GradingFinishedMessage; StringBuilder sb = new StringBuilder(1000); sb.Append(message); sb.Append("<br><script>"); // Write the assignment status to slkFrameMgr WriteSlkMgrInit(sb); sb.AppendLine("slkMgr = Slk_GetSlkManager();"); sb.AppendFormat("slkMgr.LearnerAssignmentId = {0};\r\n", JScriptString.QuoteString(FramesetUtil.GetStringInvariant(la.LearnerAssignmentId.GetKey()), false)); sb.AppendFormat("slkMgr.Status = {0};\r\n", JScriptString.QuoteString(SlkUtilities.GetLearnerAssignmentState(la.Status), false)); if (AssignmentView == AssignmentView.Grading) { string finalPointsValue = "null"; float? finalPoints = la.FinalPoints; if (finalPoints != null) { finalPointsValue = Convert.ToString(finalPoints.Value, CultureInfo.InvariantCulture.NumberFormat); } sb.AppendFormat("slkMgr.FinalPoints = {0};\r\n", finalPointsValue); } // Send information about total points (ie, computed points on the client). if (session != null) { if (session.TotalPoints != null) { sb.AppendFormat("slkMgr.ComputedPoints = {0};\r\n", JScriptString.QuoteString(Convert.ToString(session.TotalPoints, CultureInfo.CurrentCulture.NumberFormat), false)); } else { sb.AppendFormat("slkMgr.ComputedPoints = \"\";\r\n"); } if (session.SuccessStatus != SuccessStatus.Unknown) { sb.AppendFormat("slkMgr.PassFail = {0};\r\n", JScriptString.QuoteString(((session.SuccessStatus == SuccessStatus.Passed) ? "passed" : "failed"), false)); } } } }
/// <summary> /// Initialize information for the hidden controls and script. This sets up the information to create hidden fields in the form /// and to update the framesetMgr on page load. /// </summary> private void InitHiddenControlInfo(RenderContext context, StringBuilder onLoadScript) { // Should only do this if this is LRM content. Other content does not allow writing to the page. if (Session.CurrentActivityResourceType != ResourceType.Lrm) { return; } IDictionary <string, string> controls = context.FormHiddenControls; // Write the script to define frameMgr in script. WriteFindFrameMgr(onLoadScript); // If the session is attempt-based, then write attempt information if (Session != null) { controls.Add(HiddenFieldNames.AttemptId, FramesetUtil.GetStringInvariant(Session.AttemptId.GetKey())); onLoadScript.AppendFormat("frameMgr.SetAttemptId(document.getElementById({0}).value);\r\n", JScriptString.QuoteString(HiddenFieldNames.AttemptId, false)); } // If the session has ended (that is, is suspended, completed or abandoned), then we're // done. Just return. if (SessionIsEnded) { return; } // Write view to display. controls.Add(HiddenFieldNames.View, FramesetUtil.GetString(Session.View)); onLoadScript.AppendFormat("frameMgr.SetView(document.getElementById({0}).value);\r\n", JScriptString.QuoteString(HiddenFieldNames.View, false)); // Write frame to post. controls.Add(HiddenFieldNames.PostFrame, "frameContent"); onLoadScript.AppendFormat("frameMgr.SetPostFrame(document.getElementById({0}).value);\r\n", JScriptString.QuoteString(HiddenFieldNames.PostFrame, false)); // Set contentFrameUrl to be null. This prevents the content frame from being re-loaded. onLoadScript.Append("frameMgr.SetContentFrameUrl(null);\r\n"); // If a new activity has been identified, then instruct frameMgr to reinitialize the RTE. // BE CAREFUL to do this before setting any other data related to the rte! if (ActivityHasChanged) { string initNewActivity = "false"; if (Session.HasCurrentActivity) { initNewActivity = (CurrentActivityRequiresRte ? "true" : "false"); } onLoadScript.AppendFormat("frameMgr.InitNewActivity( {0} );\r\n", initNewActivity); } // Write the current activity Id. Write -1 if there isn't one. controls.Add(HiddenFieldNames.ActivityId, (Session.HasCurrentActivity ? FramesetUtil.GetStringInvariant(Session.CurrentActivityId) : "-1")); onLoadScript.AppendFormat("frameMgr.SetActivityId(document.getElementById({0}).value);\r\n", JScriptString.QuoteString(HiddenFieldNames.ActivityId, false)); // Write the navigation control state. Format of the control state is a series of T (to show) or F (to hide) // values, separated by semi-colons. The order of controls is: // showNext, showPrevious, showAbandon, showExit, showSave StringBuilder sb = new StringBuilder(10); sb.Append((Session.ShowNext) ? "T" : "F"); sb.Append(";"); sb.Append((Session.ShowPrevious) ? "T" : "F"); sb.Append(";"); sb.Append((Session.ShowAbandon) ? "T" : "F"); sb.Append(";"); sb.Append((Session.ShowExit) ? "T" : "F"); sb.Append(";"); sb.Append((Session.ShowSave) ? "T" : "F"); sb.Append(";"); onLoadScript.AppendFormat("frameMgr.SetNavVisibility( {0}, {1}, {2}, {3}, {4});\r\n", (Session.ShowNext ? "true" : "false"), (Session.ShowPrevious ? "true" : "false"), (Session.ShowAbandon ? "true" : "false"), (Session.ShowExit ? "true" : "false"), (Session.ShowSave ? "true" : "false")); controls.Add(HiddenFieldNames.ShowUI, sb.ToString()); context.Script = onLoadScript.ToString(); }
/// <summary>Write initialization code for frameset manager. </summary> /// <remarks> /// This method is called in three possible cases: /// 1. An error condition occurred /// 2. The submit page is being displayed. Note that in this case, since the submit page is registered as displaying an /// error condition, HasError will be true. /// 3. The current activity has changed and we display this page mainly so that the 'please wait' information can be /// displayed and the client can issue a GET request to load the new activity. /// </remarks> public void WriteFrameMgrInit() { // Write frame to post. When displaying an error (which is the case, since we are here) the hidden frame is posted next Response.Write("frameMgr.SetPostFrame('frameHidden');\r\n"); Response.Write("frameMgr.SetPostableForm(window.top.frames[MAIN_FRAME].document.getElementById(HIDDEN_FRAME).contentWindow.document.forms[0]);\r\n"); if (HasError || SubmitPageDisplayed) { // Set the content frame URL to be null. This means the content frame will not be re-loaded by the frameMgr. Response.Write("frameMgr.SetContentFrameUrl(null); \r\n"); } // If there is no session, we can't do anything else if (Session == null) { return; } if ((ActivityHasChanged) && (!SubmitPageDisplayed)) { // Reload the content frame with the new activity. Response.Write(String.Format(CultureInfo.CurrentCulture, "frameMgr.SetContentFrameUrl(\"{0}\"); \r\n", GetContentFrameUrl())); // The new activity may be scorm content, so reinitialize the rte, if needed Response.Write(ResHelper.Format("frameMgr.InitNewActivity( {0} );\r\n", (CurrentActivityRequiresRte ? "true" : "false"))); } Response.Write(ResHelper.Format("frameMgr.SetAttemptId('{0}');\r\n", FramesetUtil.GetStringInvariant(Session.AttemptId.GetKey()))); // Write view to display. Response.Write(String.Format(CultureInfo.CurrentCulture, "frameMgr.SetView('{0}');\r\n", FramesetUtil.GetString(Session.View))); // Write the current activity Id. Write -1 if there isn't one. string activityId; if (SubmitPageDisplayed) { activityId = SubmitId; } else { activityId = (Session.HasCurrentActivity ? FramesetUtil.GetStringInvariant(Session.CurrentActivityId) : "-1"); } Response.Write(String.Format(CultureInfo.InvariantCulture, "frameMgr.SetActivityId({0});\r\n", JScriptString.QuoteString(activityId, true))); // Write nav visibility, in case it's changed since the hidden frame was rendered if (SubmitPageDisplayed) { // If the submit page is being displayed, don't show UI elements Response.Write(String.Format(CultureInfo.CurrentCulture, "frameMgr.SetNavVisibility( {0}, {1}, {2}, {3}, {4});", ("false"), // showNext ("false"), // showPrevious ("false"), // showAbandon ("false"), // showExit (Session.ShowSave ? "true" : "false"))); // If the submit page is now being displayed, make sure the frameset isn't waiting for another commit Response.Write("frameMgr.WaitForContentCompleted(0);\r\n"); } else { Response.Write(String.Format(CultureInfo.CurrentCulture, "frameMgr.SetNavVisibility( {0}, {1}, {2}, {3}, {4});\r\n", (Session.ShowNext ? "true" : "false"), (Session.ShowPrevious ? "true" : "false"), (Session.ShowAbandon ? "true" : "false"), (Session.ShowExit ? "true" : "false"), (Session.ShowSave ? "true" : "false"))); } // Register that the frame loading is complete. This is required so as to notify the frameset of activity id, and // other UI status. Response.Write(String.Format(CultureInfo.InvariantCulture, "frameMgr.RegisterFrameLoad({0});\r\n ", JScriptString.QuoteString("frameContent", false))); if (m_isPostedPage) { // Set PostIsComplete. THIS MUST BE THE LAST VALUE SET! Response.Write("frameMgr.PostIsComplete();"); } }