Index: lams_central/conf/language/lams/ApplicationResources.properties
===================================================================
diff -u -rdcb7977d20f0d29b809b2139a6814bc113c4485c -r0e442ec998f242b5d7874b92488fb86fa881bf5e
--- lams_central/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision dcb7977d20f0d29b809b2139a6814bc113c4485c)
+++ lams_central/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision 0e442ec998f242b5d7874b92488fb86fa881bf5e)
@@ -511,6 +511,7 @@
authoring.fla.transition.place.prompt =Click on an activity
authoring.fla.paste.error =Sorry, you can not paste this type of activity
authoring.fla.preview.error =Error while initialising lesson for preview
+authoring.fla.cross.branching.error =Cross-branching transitions are not allowed
authoring.fla.ok.button =OK
authoring.fla.cancel.button =Cancel
authoring.fla.clear.all.button =Clear all
Index: lams_central/web/authoring/authoring.jsp
===================================================================
diff -u -rdcb7977d20f0d29b809b2139a6814bc113c4485c -r0e442ec998f242b5d7874b92488fb86fa881bf5e
--- lams_central/web/authoring/authoring.jsp (.../authoring.jsp) (revision dcb7977d20f0d29b809b2139a6814bc113c4485c)
+++ lams_central/web/authoring/authoring.jsp (.../authoring.jsp) (revision 0e442ec998f242b5d7874b92488fb86fa881bf5e)
@@ -102,7 +102,7 @@
RUN_SEQUENCES_FOLDER : '',
ARRANGE_CONFIRM : '',
CLEAR_CANVAS_CONFIRM : '',
- BRANCHING_START_PLACE_PROMPT : '',
+ BRANCHING_START_PLACE_PROMPT : '',
BRANCHING_END_PLACE_PROMPT : '',
ANNOTATION_REGION_PLACE_PROMPT : '',
ANNOTATION_LABEL_PLACE_PROMPT : '',
@@ -111,6 +111,7 @@
TRANSITION_PLACE_PROMPT : '',
PASTE_ERROR : '',
PREVIEW_ERROR : '',
+ CROSS_BRANCHING_ERROR : '',
// PropertyLib
OK_BUTTON : '',
Index: lams_central/web/includes/javascript/authoring/authoringActivity.js
===================================================================
diff -u -r1367c68bda1ff51ded26c5220a9a059fa67235f5 -r0e442ec998f242b5d7874b92488fb86fa881bf5e
--- lams_central/web/includes/javascript/authoring/authoringActivity.js (.../authoringActivity.js) (revision 1367c68bda1ff51ded26c5220a9a059fa67235f5)
+++ lams_central/web/includes/javascript/authoring/authoringActivity.js (.../authoringActivity.js) (revision 0e442ec998f242b5d7874b92488fb86fa881bf5e)
@@ -817,6 +817,15 @@
* Draws a transition between two activities.
*/
addTransition : function(fromActivity, toActivity, redraw, id, uiid, branchData) {
+ // check if a branching's start does not connect with another branching's end
+ if (fromActivity instanceof ActivityDefs.BranchingEdgeActivity
+ && toActivity instanceof ActivityDefs.BranchingEdgeActivity
+ && fromActivity.isStart && !toActivity.isStart
+ && fromActivity.branchingActivity != toActivity.branchingActivity) {
+ alert(LABELS.CROSS_BRANCHING_ERROR);
+ return;
+ }
+
// if a child activity was detected, use the parent activity as the target
if (toActivity.parentActivity && toActivity.parentActivity instanceof DecorationDefs.Container){
toActivity = toActivity.parentActivity;
@@ -838,33 +847,34 @@
return;
}
+ // check for circular sequences
+ var activity = fromActivity;
+ do {
+ if (activity.transitions && activity.transitions.to.length > 0) {
+ activity = activity.transitions.to[0].fromActivity;
+ } else if (activity.branchingActivity && !activity.isStart) {
+ activity = activity.branchingActivity.start;
+ } else {
+ activity = null;
+ }
+
+ if (toActivity == activity) {
+ alert(LABELS.CIRCULAR_SEQUENCE_ERROR);
+ return;
+ }
+ } while (activity);
+
// user chose to create outbound transition from an activity that already has one
if (!redraw
&& fromActivity.transitions.from.length > 0
- && !(fromActivity instanceof ActivityDefs.BranchingEdgeActivity && fromActivity.isStart)
- && !(toActivity instanceof ActivityDefs.BranchingEdgeActivity && toActivity.isStart)) {
+ && !(fromActivity instanceof ActivityDefs.BranchingEdgeActivity && fromActivity.isStart)) {
if (confirm(LABELS.BRANCHING_CREATE_CONFIRM)) {
ActivityLib.addBranching(fromActivity, toActivity);
}
return;
}
- // check for circular sequences
- var candidate = fromActivity;
- do {
- if (candidate.transitions && candidate.transitions.to.length > 0) {
- candidate = candidate.transitions.to[0].fromActivity;
- } else if (candidate.branchingActivity && !candidate.isStart) {
- candidate = candidate.branchingActivity.start;
- } else {
- candidate = null;
- }
-
- if (toActivity == candidate) {
- alert(LABELS.CIRCULAR_SEQUENCE_ERROR);
- return;
- }
- } while (candidate != null);
+ // start building the transition
// branchData can be either an existing branch or a title for the new branch
var branch = branchData && branchData instanceof ActivityDefs.BranchActivity ? branchData : null,
@@ -915,9 +925,107 @@
}
}
+
+ // after adding the transition, check for self-nested branching
+ activity = fromActivity;
+ var branchingActivity = null;
+ // find the top-most enveloping branching activity, if any
+ do {
+ if (activity.transitions && activity.transitions.to.length > 0) {
+ activity = activity.transitions.to[0].fromActivity;
+
+ if (activity instanceof ActivityDefs.BranchingEdgeActivity) {
+ if (activity.isStart) {
+ // found the top branching the activity belongs to
+ branchingActivity = activity.branchingActivity;
+ } else {
+ // jump over nested branching
+ activity = activity.branchingActivity.start;
+ }
+ }
+ } else {
+ activity = null;
+ }
+ } while (activity);
+
+
+ if (branchingActivity) {
+ // look for all nested branchings
+ var nestedBranchings = ActivityLib.findNestedBranching(branchingActivity);
+ // check each of them
+ $.each(nestedBranchings, function(){
+ var branching = this;
+ // check if one branching's end does not match with another branching's start
+ $.each(branching.end.transitions.to, function(){
+ // crawl from end to start
+ var activity = this.fromActivity;
+ while (activity) {
+ if (activity instanceof ActivityDefs.BranchingEdgeActivity) {
+ if (activity.isStart) {
+ // this branching's end matches with its own start, all OK
+ if (activity.branchingActivity == branching) {
+ break;
+ }
+ // this branching's end does not match with own start, error
+ alert(LABELS.CROSS_BRANCHING_ERROR);
+ // remove the just added transition
+ ActivityLib.removeTransition(transition);
+ // tell the outer iteration loop to quit
+ transition = null;
+ return false;
+ }
+ // a nested branching encountered when crawling, just jump over it
+ activity = activity.branchingActivity.start;
+ }
+ // keep crawling
+ if (activity.transitions && activity.transitions.to.length > 0) {
+ activity = activity.transitions.to[0].fromActivity;
+ } else {
+ activity = null;
+ }
+ }
+ });
+
+ if (!transition) {
+ // there was an error, do not carry on
+ return false;
+ }
+ });
+ }
+
GeneralLib.setModified(true);
return transition;
},
+
+
+ findNestedBranching : function(branchingActivity) {
+ var nestedBranching = [];
+ $.each(branchingActivity.branches, function(){
+ var activity = this.transitionFrom.toActivity;
+ while (activity) {
+ if (activity instanceof ActivityDefs.BranchingEdgeActivity) {
+ if (activity.branchingActivity == branchingActivity){
+ break;
+ }
+ if (nestedBranching.indexOf(activity.branchingActivity) == -1) {
+ nestedBranching.push(activity.branchingActivity);
+ }
+ if (activity.isStart) {
+ nestedBranching = nestedBranching.concat(ActivityLib.findNestedBranching(activity.branchingActivity));
+ activity = activity.branchingActivity.end;
+ }
+ }
+
+ if (activity.transitions && activity.transitions.from.length > 0) {
+ activity = activity.transitions.from[0].toActivity;
+ } else {
+ activity = null;
+ }
+ }
+ });
+
+ return nestedBranching;
+ },
/**