Index: lams_central/web/includes/javascript/authoring/authoringActivity.js =================================================================== RCS file: /usr/local/cvsroot/lams_central/web/includes/javascript/authoring/authoringActivity.js,v diff -u -r1.53 -r1.54 --- lams_central/web/includes/javascript/authoring/authoringActivity.js 6 Jul 2015 09:56:21 -0000 1.53 +++ lams_central/web/includes/javascript/authoring/authoringActivity.js 8 Jul 2015 14:34:28 -0000 1.54 @@ -271,16 +271,15 @@ branching : function(x, y) { if (x == undefined || y == undefined) { // just redraw the activity - x = this.items.shape.getBBox().x; - y = this.items.shape.getBBox().y; + x = this.items.getBBox().x; + y = this.items.getBBox().y; } if (this.items) { this.items.remove(); } // create activity SVG elements - this.items = Snap.set(); var shape = paper.path(Snap.format('M {x} {y} a 8 8 0 1 0 16 0 a 8 8 0 1 0 -16 0', { 'x' : x, @@ -297,7 +296,11 @@ : LABELS.BRANCHING_END_SUFFIX)) .attr(layout.defaultTextAttributes); - this.items.push(shape).push(label); + this.items = paper.g(shape, label); + if (this.isStart) { + // uiid is needed in Monitoring + this.items.attr('uiid', this.branchingActivity.uiid); + } this.items.shape = shape; ActivityLib.activityHandlersInit(this); @@ -310,8 +313,8 @@ floatingActivity : function(x, y, ignoredParam1, ignoredParam2, childActivities) { if (x == undefined || y == undefined) { // if no new coordinates are given, just redraw the activity - x = this.items.shape.getBBox().x; - y = this.items.shape.getBBox().y; + x = this.items.getBBox().x; + y = this.items.getBBox().y; } // either check what children are on canvas or use the priovided parameter @@ -324,7 +327,7 @@ var activityX = x + layout.conf.containerActivityPadding, allElements = Snap.set(), floatingActivity = this, - box = this.items.shape.getBBox(); + box = this.items.getBBox(); $.each(this.childActivities, function(orderID){ this.parentActivity = floatingActivity; this.orderID = orderID; @@ -348,7 +351,7 @@ layout.colors.optionalActivity); } - GeneralLib.applyToSet(this.items, 'data', ['parentObject', this]); + this.items.data('parentObject', this); }, @@ -357,16 +360,15 @@ */ gate : function(x, y) { if (x == undefined || y == undefined) { - x = this.items.shape.getBBox().x; - y = this.items.shape.getBBox().y; + x = this.items.getBBox().x; + y = this.items.getBBox().y; } if (this.items) { this.items.remove(); } // create activity SVG elements - this.items = Snap.set(); var shape = paper.path(Snap.format('M {x} {y} l-9 9 v16 l9 9 h16 l9 -9 v-16 l-9 -9 z', { 'x' : x + 9, @@ -381,7 +383,9 @@ .attr(layout.defaultTextAttributes) .attr('stroke', layout.colors.gateText); - this.items.push(shape).push(label); + this.items = paper.g(shape, label); + // uiid is needed in Monitoring + this.items.attr('uiid', this.uiid); this.items.shape = shape; ActivityLib.activityHandlersInit(this); @@ -394,16 +398,15 @@ grouping : function(x, y) { if (x == undefined || y == undefined) { // just redraw the activity - x = this.items.shape.getBBox().x; - y = this.items.shape.getBBox().y; + x = this.items.getBBox().x; + y = this.items.getBBox().y; } if (this.items) { this.items.remove(); } // create activity SVG elements - this.items = Snap.set(); var shape = paper.path(Snap.format('M {x} {y} h 125 v 50 h -125 z', { 'x' : x, @@ -418,7 +421,9 @@ label = paper.text(x + 62, y + 40, ActivityLib.shortenActivityTitle(this.title)) .attr(layout.defaultTextAttributes); - this.items.push(shape).push(icon).push(label); + this.items = paper.g(shape, icon, label); + // uiid is needed in Monitoring + this.items.attr('uiid', this.uiid); this.items.shape = shape; ActivityLib.activityHandlersInit(this); @@ -431,8 +436,8 @@ optionalActivity : function(x, y, ignoredParam1, ignoredParam2, childActivities) { if (x == undefined || y == undefined) { // if no new coordinates are given, just redraw the activity - x = this.items.shape.getBBox().x; - y = this.items.shape.getBBox().y; + x = this.items.getBBox().x; + y = this.items.getBBox().y; } // either check what children are on canvas or use the priovided parameter @@ -445,11 +450,12 @@ var activityY = y + layout.conf.containerActivityPadding + 10, allElements = Snap.set(), optionalActivity = this, - box = this.items.shape.getBBox(), + box = this.items.getBBox(), boxWidth = box.width; $.each(this.childActivities, function(orderID){ this.parentActivity = optionalActivity; this.orderID = orderID + 1; + // for some reason, this.items.getBBox() can't be used here var childBox = this.items.shape.getBBox(); this.draw(x + Math.max(layout.conf.containerActivityPadding, (boxWidth - childBox.width)/2), activityY); childBox = this.items.shape.getBBox(); @@ -472,11 +478,10 @@ if (!isReadOnlyMode){ // allow transition drawing and other activity behaviour - GeneralLib.applyToSet(this.items, 'unmousedown'); - GeneralLib.applyToSet(this.items, 'mousedown', [HandlerActivityLib.activityMousedownHandler]); + this.items.unmousedown().mousedown(HandlerActivityLib.activityMousedownHandler); } - GeneralLib.applyToSet(this.items, 'data', ['parentObject', this]); + this.items.data('parentObject', this); }, @@ -486,10 +491,10 @@ parallelActivity : function(x, y) { // if no new coordinates are given, just redraw the activity or give default value if (x == undefined) { - x = this.items ? this.items.shape.getBBox().x : 0; + x = this.items ? this.items.getBBox().x : 0; } if (y == undefined) { - y = this.items ? this.items.shape.getBBox().y : 0; + y = this.items ? this.items.getBBox().y : 0; } if (this.childActivities && this.childActivities.length > 0) { @@ -501,7 +506,7 @@ this.parentActivity = optionalActivity; this.orderID = orderID + 1; this.draw(x + layout.conf.containerActivityPadding, activityY); - activityY = this.items.shape.getBBox().y2 + layout.conf.containerActivityChildrenPadding; + activityY = this.items.getBBox().y2 + layout.conf.containerActivityChildrenPadding; allElements.push(this.items.shape); }); // area containing all drawn child activities @@ -524,11 +529,10 @@ if (!isReadOnlyMode){ // allow transition drawing and other activity behaviour - GeneralLib.applyToSet(this.items, 'unmousedown'); - GeneralLib.applyToSet(this.items, 'mousedown', [HandlerActivityLib.activityMousedownHandler]); + this.items.unmousedown().mousedown(HandlerActivityLib.activityMousedownHandler); } - GeneralLib.applyToSet(this.items, 'data', ['parentObject', this]); + this.items.data('parentObject', this); }, @@ -547,7 +551,6 @@ } // create activity SVG elements - this.items = Snap.set(); var shape = paper.path(Snap.format('M {x} {y} h 125 v 50 h -125 z', { 'x' : x, @@ -563,8 +566,10 @@ label = paper.text(x + 62, y + 43, ActivityLib.shortenActivityTitle(this.title)) .attr(layout.defaultTextAttributes) .attr('fill', layout.colors.activityText); - - this.items.push(shape).push(icon).push(label); + + this.items = paper.g(shape, icon, label); + // uiid is needed in Monitoring + this.items.attr('uiid', this.uiid); this.items.shape = shape; if (this.grouping) { @@ -588,7 +593,6 @@ var points = ActivityLib.findTransitionPoints(this.fromActivity, this.toActivity); // create transition SVG elements - this.items = Snap.set(); var arrowShaft = paper.path(Snap.format('M {startX} {startY} L {endX} {endY}', points)) .attr({ 'stroke' : layout.colors.transition, @@ -607,7 +611,8 @@ 'stroke' : layout.colors.transition, 'fill' : layout.colors.transition }); - this.items.push(arrowShaft).push(arrowPath); + this.items = paper.g(arrowShaft, arrowPath); + this.items.attr('uiid', this.uiid); if (this.title) { // adjust X & Y depending on the angle, so the label does not overlap with the transition; // angle in Javascript is -90 <= a <= 270 @@ -617,22 +622,22 @@ .attr(layout.defaultTextAttributes) .attr('text-anchor', 'start'); - this.items.push(label); + this.items.append(label); } GeneralLib.toBack(this.items); // region annotations could cover grouping effect $.each(layout.regions, function(){ - GeneralLib.toBack(this.items.shape); + GeneralLib.toBack(this.items); }); + + this.items.data('parentObject', this); - GeneralLib.applyToSet(this.items, 'data', ['parentObject', this]); - if (!isReadOnlyMode){ - GeneralLib.applyToSet(this.items, 'attr', ['cursor', 'pointer']); - GeneralLib.applyToSet(this.items, 'mousedown', [HandlerTransitionLib.transitionMousedownHandler]); - GeneralLib.applyToSet(this.items, 'click', [HandlerLib.itemClickHandler]); + this.items.attr('cursor', 'pointer') + .mousedown(HandlerTransitionLib.transitionMousedownHandler) + .click(HandlerLib.itemClickHandler); } } }, @@ -648,29 +653,28 @@ * Make a new activity fully functional on canvas. */ activityHandlersInit : function(activity) { - GeneralLib.applyToSet(activity.items, 'data', ['parentObject', activity]); + activity.items.data('parentObject', activity); if (isReadOnlyMode) { if (activitiesOnlySelectable) { - GeneralLib.applyToSet(activity.items, 'click', [HandlerLib.itemClickHandler]); - GeneralLib.applyToSet(activity.items, 'attr', [{'cursor' : 'pointer'}]); + activity.items.attr('cursor', 'pointer') + .click(HandlerLib.itemClickHandler); } } else { // set all the handlers - GeneralLib.applyToSet(activity.items, 'mousedown', [HandlerActivityLib.activityMousedownHandler]); - GeneralLib.applyToSet(activity.items, 'click', [HandlerLib.itemClickHandler]); - GeneralLib.applyToSet(activity.items, 'dblclick', [HandlerActivityLib.activityDblclickHandler]); - GeneralLib.applyToSet(activity.items, 'attr', [{'cursor' : 'pointer'}]); + activity.items.attr('cursor', 'pointer') + .mousedown(HandlerActivityLib.activityMousedownHandler) + .click(HandlerLib.itemClickHandler) + .dblclick(HandlerActivityLib.activityDblclickHandler); if (activity instanceof ActivityDefs.BranchingEdgeActivity && activity.branchingActivity.end) { // highligh branching edges on hover - GeneralLib.applyToSet(activity.branchingActivity.start.items, 'hover', - [HandlerActivityLib.branchingEdgeMouseoverHandler, - HandlerActivityLib.branchingEdgeMouseoutHandler]); - GeneralLib.applyToSet(activity.branchingActivity.end.items, 'hover', - [HandlerActivityLib.branchingEdgeMouseoverHandler, - HandlerActivityLib.branchingEdgeMouseoutHandler]); + + activity.branchingActivity.start.items.hover(HandlerActivityLib.branchingEdgeMouseoverHandler, + HandlerActivityLib.branchingEdgeMouseoutHandler); + activity.branchingActivity.end.items.hover(HandlerActivityLib.branchingEdgeMouseoverHandler, + HandlerActivityLib.branchingEdgeMouseoutHandler); } } @@ -741,7 +745,7 @@ // do not draw twice if it already exists if (!activity.items.groupingEffect) { var shape = activity.items.shape, - activityBox = shape.getBBox(); + activityBox = activity.items.getBBox(); activity.items.groupingEffect = paper.rect( activityBox.x + layout.conf.groupingEffectPadding, @@ -753,12 +757,11 @@ 'fill' : shape.attr('fill') }); - GeneralLib.toBack(activity.items.groupingEffect); - activity.items.push(activity.items.groupingEffect); + activity.items.prepend(activity.items.groupingEffect); // region annotations could cover grouping effect $.each(layout.regions, function(){ - GeneralLib.toBack(this.items.shape); + GeneralLib.toBack(this.items); }); } }, @@ -820,7 +823,7 @@ 'stroke-dasharray' : '5,3', 'fill' : 'none' }); - object.items.push(object.items.selectEffect); + object.items.append(object.items.selectEffect); // if it's "import part" select children activities if (activitiesOnlySelectable) { @@ -1183,13 +1186,28 @@ /** + * Finds activity/region this shape is bound with. + */ + getParentObject : function(item) { + var parentObject = item.data('parentObject'); + if (!parentObject) { + var parentNode = item.parent(); + if (parentNode.type == 'g') { + parentObject = parentNode.data('parentObject'); + } + } + return parentObject; + }, + + + /** * Get output definitions from Tool activity */ getOutputDefinitions : function(activity){ if (!activity.toolID) { return; - } - + } + $.ajax({ url : LAMS_URL + 'authoring/author.do', data : { @@ -1205,14 +1223,14 @@ $.each(activity.outputDefinitions, function() { if (this.isDefaultGradebookMark){ activity.gradebookToolOutputDefinitionName = this.name; - return false; - } - }); - } + return false; + } + }); + } }); }, - + /** * Open separate window with activity authoring on double click. */ Index: lams_central/web/includes/javascript/authoring/authoringDecoration.js =================================================================== RCS file: /usr/local/cvsroot/lams_central/web/includes/javascript/authoring/authoringDecoration.js,v diff -u -r1.12 -r1.13 --- lams_central/web/includes/javascript/authoring/authoringDecoration.js 26 Jun 2015 08:33:23 -0000 1.12 +++ lams_central/web/includes/javascript/authoring/authoringDecoration.js 8 Jul 2015 14:34:28 -0000 1.13 @@ -76,7 +76,9 @@ } // the label - this.items = Snap.set(); + this.items = paper.g(); + // uiid is needed in Monitoring + this.items.attr('uiid', this.uiid); if (this.title) { var label = paper.text(x + 7, y + 14, this.title) .attr(layout.defaultTextAttributes) @@ -85,37 +87,36 @@ label.attr('cursor', 'pointer'); } - GeneralLib.toBack(label); - this.items.push(label); + this.items.append(label); // make sure title fits x2 = Math.max(x2, label.getBBox().x2 + 5); } // the rectangle - this.items.shape = paper.path(Snap.format('M {x} {y} H {x2} V {y2} H {x} z', + this.items.shape = paper.path(Snap.format('M {x} {y} h {width} v {height} h -{width} z', { - 'x' : x, - 'y' : y, - 'x2' : x2, - 'y2' : y2 + 'x' : x, + 'y' : y, + 'width' : x2 - x, + 'height' : y2 - y })) .attr({ 'stroke' : layout.colors.activityBorder, 'fill' : color }); - GeneralLib.toBack(this.items.shape); - this.items.push(this.items.shape); + this.items.prepend(this.items.shape); + GeneralLib.toBack(this.items); if (isReadOnlyMode){ if (activitiesOnlySelectable) { - this.items.shape.attr('cursor', 'pointer'); - GeneralLib.applyToSet(this.items, 'click',[HandlerLib.itemClickHandler]); + this.items.attr('cursor', 'pointer') + .click(HandlerLib.itemClickHandler); } } else { - this.items.shape.attr('cursor', 'pointer'); - GeneralLib.applyToSet(this.items, 'mousedown',[HandlerDecorationLib.containerMousedownHandler]); - GeneralLib.applyToSet(this.items, 'click',[HandlerLib.itemClickHandler]); + this.items.attr('cursor', 'pointer') + .mousedown(HandlerDecorationLib.containerMousedownHandler) + .click(HandlerLib.itemClickHandler); } }, @@ -159,19 +160,21 @@ this.items.remove(); } - this.items = Snap.set(); + this.items = paper.g(); + // uiid is needed in Monitoring + this.items.attr('uiid', this.uiid); this.items.shape = paper.text(x, y, this.title) .attr(layout.defaultTextAttributes) .attr('text-anchor', 'start'); - this.items.push(this.items.shape); + this.items.append(this.items.shape); - this.items.shape.attr('cursor', 'pointer'); - GeneralLib.applyToSet(this.items, 'click',[HandlerLib.itemClickHandler]); + this.items.attr('cursor', 'pointer') + .click(HandlerLib.itemClickHandler); if (!isReadOnlyMode){ - this.items.shape.mousedown(HandlerDecorationLib.labelMousedownHandler); + this.items.mousedown(HandlerDecorationLib.labelMousedownHandler); } - GeneralLib.applyToSet(this.items, 'data', ['parentObject', this]); + this.items.data('parentObject', this); } }, @@ -197,11 +200,11 @@ }) .click(function(event){ event.stopImmediatePropagation(); - var region = this.data('parentObject'); + var region = ActivityLib.getParentObject(this); region.fit(); ActivityLib.addSelectEffect(region, true); }); - this.items.push(this.items.fitButton); + this.items.append(this.items.fitButton); this.items.resizeButton = paper.path(Snap.format('M {x} {y} v {side} h -{side} z', { @@ -219,10 +222,10 @@ }); this.items.resizeButton.mousedown(HandlerDecorationLib.resizeRegionStartHandler); - this.items.push(this.items.resizeButton); + this.items.append(this.items.resizeButton); } - GeneralLib.applyToSet(this.items, 'data', ['parentObject', this]); + this.items.data('parentObject', this); } } } @@ -275,7 +278,7 @@ } }); - var parentObject = shape.data('parentObject'); + var parentObject = ActivityLib.getParentObject(shape); // store the result in the shape's object if (parentObject && !(parentObject instanceof DecorationDefs.Region)) { parentObject.childActivities = result; Index: lams_central/web/includes/javascript/authoring/authoringGeneral.js =================================================================== RCS file: /usr/local/cvsroot/lams_central/web/includes/javascript/authoring/authoringGeneral.js,v diff -u -r1.68 -r1.69 --- lams_central/web/includes/javascript/authoring/authoringGeneral.js 6 Jul 2015 09:56:20 -0000 1.68 +++ lams_central/web/includes/javascript/authoring/authoringGeneral.js 8 Jul 2015 14:34:28 -0000 1.69 @@ -2409,7 +2409,7 @@ 'yCoord' : parseInt(box.y), 'endXCoord' : isRegion ? parseInt(box.x2) : null, 'endYCoord' : isRegion ? parseInt(box.y2) : null, - 'color' : isRegion ? this.items.shape.attr('fill') : null + 'color' : isRegion ? Snap.color(this.items.shape.attr('fill')).hex : null }); }); Index: lams_central/web/includes/javascript/authoring/authoringHandler.js =================================================================== RCS file: /usr/local/cvsroot/lams_central/web/includes/javascript/authoring/authoringHandler.js,v diff -u -r1.21 -r1.22 --- lams_central/web/includes/javascript/authoring/authoringHandler.js 26 Jun 2015 08:33:23 -0000 1.21 +++ lams_central/web/includes/javascript/authoring/authoringHandler.js 8 Jul 2015 14:34:28 -0000 1.22 @@ -52,9 +52,9 @@ // show that we are in the middle of something HandlerLib.resetCanvasMode(); items.isDragged = true; - GeneralLib.applyToSet(items, 'attr', ['cursor', 'move']); + items.attr('cursor', 'move'); - var parentObject = draggedElement.data('parentObject'); + var parentObject = ActivityLib.getParentObject(draggedElement); sticky = parentObject && (parentObject instanceof ActivityDefs.ParallelActivity || parentObject instanceof ActivityDefs.OptionalActivity || parentObject instanceof ActivityDefs.FloatingActivity); @@ -63,14 +63,10 @@ // they will be redrawn when the parent is dropped if (sticky) { $.each(parentObject.childActivities, function(){ - this.items.forEach(function(item){ - item.attr('display', 'none'); - }); + this.items.attr('display', 'none'); if (this.childActivities) { $.each(this.childActivities, function() { - this.items.forEach(function(item){ - item.attr('display', 'none'); - }); + this.items.attr('display', 'none'); }); } }); @@ -83,7 +79,7 @@ var mouseup = function(mouseupEvent){ // finish dragging - restore various elements' default state items.isDragged = false; - GeneralLib.applyToSet(items, 'unmouseup'); + items.unmouseup(); HandlerLib.resetCanvasMode(true); if (layout.bin.glowEffect) { layout.bin.glowEffect.remove(); @@ -113,11 +109,11 @@ var dx = event.pageX - startX, dy = event.pageY - startY; - GeneralLib.applyToSet(items, 'transform', ['t' + dx + ' ' + dy]); + items.transform('t' + dx + ' ' + dy); - if (items.groupingEffect) { - GeneralLib.toBack(items.groupingEffect); - } +// if (items.groupingEffect) { +// GeneralLib.toBack(items.groupingEffect); +// } // highlight rubbish bin if dragged elements are over it if (HandlerLib.isElemenentBinned(event)) { @@ -147,10 +143,10 @@ */ dropObject : function(object) { // finally transform the dragged elements - var transformation = Snap.parseTransformString(object.items.shape.transform().string); - GeneralLib.applyToSet(object.items, 'transform', ['']); + var transformation = Snap.parseTransformString(object.items.transform().string); + object.items.transform(''); - var box = object.items.shape.getBBox(), + var box = object.items.getBBox(), originalCoordinates = { x : box.x, // adjust this coordinate for annotation labels @@ -186,7 +182,7 @@ return; } - var parentObject = this.data('parentObject'); + var parentObject = ActivityLib.getParentObject(this); // if it's "import part" allow multiple selection of activities if (activitiesOnlySelectable) { if (parentObject.items.selectEffect) { @@ -239,7 +235,7 @@ * Double click opens activity authoring. */ activityDblclickHandler : function(event) { - var activity = this.data('parentObject'); + var activity = ActivityLib.getParentObject(this); ActivityLib.openActivityAuthoring(activity); }, @@ -253,7 +249,7 @@ return; } - var activity = this.data('parentObject'); + var activity = ActivityLib.getParentObject(this); if (event.ctrlKey) { // when CTRL is held down, start drawing a transition HandlerTransitionLib.drawTransitionStartHandler(activity, event, x, y); @@ -287,7 +283,7 @@ * Lighthens up branching edges in the same colour for identifictation. */ branchingEdgeMouseoverHandler : function() { - var branchingActivity = this.data('parentObject').branchingActivity, + var branchingActivity = ActivityLib.getParentObject(this).branchingActivity, startItems = branchingActivity.start.items, endItems = branchingActivity.end.items; if (!startItems.isDragged && !endItems.isDragged) { @@ -301,7 +297,7 @@ * Return branching edges to their normal colours. */ branchingEdgeMouseoutHandler : function() { - var branchingActivity = this.data('parentObject').branchingActivity, + var branchingActivity = ActivityLib.getParentObject(this).branchingActivity, startItems = branchingActivity.start.items, endItems = branchingActivity.end.items; @@ -328,7 +324,7 @@ return; } - var container = this.data('parentObject'); + var container = ActivityLib.getParentObject(this); // allow transition dragging var mouseupHandler = function(event){ if (HandlerLib.isElemenentBinned(event)) { @@ -439,7 +435,7 @@ return; } - var label = this.data('parentObject'); + var label = ActivityLib.getParentObject(this); // allow transition dragging var mouseupHandler = function(event){ if (HandlerLib.isElemenentBinned(event)) { @@ -464,7 +460,7 @@ HandlerLib.resetCanvasMode(); - var region = this.data('parentObject'); + var region = ActivityLib.getParentObject(this); canvas.mousemove(function(event){ HandlerDecorationLib.resizeRegionMoveHandler(region, event); @@ -610,7 +606,7 @@ var endActivity = null, targetElement = Snap.getElementByPoint(event.pageX, event.pageY); if (targetElement) { - endActivity = targetElement.data('parentObject'); + endActivity = ActivityLib.getParentObject(targetElement); } if (endActivity && activity != endActivity) { @@ -626,7 +622,7 @@ * Starts dragging a transition. */ transitionMousedownHandler : function(event, x, y){ - var transition = this.data('parentObject'); + var transition = ActivityLib.getParentObject(this); // allow transition dragging var mouseupHandler = function(event){ if (HandlerLib.isElemenentBinned(event)) { Index: lams_central/web/includes/javascript/authoring/authoringMenu.js =================================================================== RCS file: /usr/local/cvsroot/lams_central/web/includes/javascript/authoring/authoringMenu.js,v diff -u -r1.37 -r1.38 --- lams_central/web/includes/javascript/authoring/authoringMenu.js 26 Jun 2015 08:33:23 -0000 1.37 +++ lams_central/web/includes/javascript/authoring/authoringMenu.js 8 Jul 2015 14:34:28 -0000 1.38 @@ -305,7 +305,7 @@ var startActivity = null, targetElement = Snap.getElementByPoint(event.pageX, event.pageY); if (targetElement) { - startActivity = targetElement.data('parentObject'); + startActivity = ActivityLib.getParentObject(targetElement); if (startActivity) { HandlerTransitionLib.drawTransitionStartHandler(startActivity, null, event.pageX, event.pageY); } Index: lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/MonitoringAction.java =================================================================== RCS file: /usr/local/cvsroot/lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/MonitoringAction.java,v diff -u -r1.134 -r1.135 --- lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/MonitoringAction.java 6 Apr 2015 11:57:42 -0000 1.134 +++ lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/MonitoringAction.java 8 Jul 2015 14:34:26 -0000 1.135 @@ -63,6 +63,7 @@ import org.lamsfoundation.lams.learningdesign.LearningDesign; import org.lamsfoundation.lams.learningdesign.OptionsWithSequencesActivity; import org.lamsfoundation.lams.learningdesign.SequenceActivity; +import org.lamsfoundation.lams.learningdesign.Transition; import org.lamsfoundation.lams.learningdesign.exception.LearningDesignException; import org.lamsfoundation.lams.lesson.LearnerProgress; import org.lamsfoundation.lams.lesson.Lesson; @@ -1082,11 +1083,13 @@ // few details for each activity Map activitiesMap = new TreeMap(); - for (Activity activity : (Set) lesson.getLearningDesign().getActivities()) { + LearningDesign learningDesign = lesson.getLearningDesign(); + for (Activity activity : (Set) learningDesign.getActivities()) { if ((branchingActivityId == null) || MonitoringAction.isBranchingChild(branchingActivityId, activity)) { Long activityId = activity.getActivityId(); JSONObject activityJSON = new JSONObject(); activityJSON.put("id", activityId); + activityJSON.put("uiid", activity.getActivityUIID()); activityJSON.put("title", activity.getTitle()); int activityType = activity.getActivityTypeId(); @@ -1163,6 +1166,21 @@ responseJSON.put("activities", new JSONArray(activitiesMap.values())); responseJSON.put("numberPossibleLearners", lessonDetails.getNumberPossibleLearners()); + + // on first fetch get transitions metadata so Monitoring can set their SVG elems IDs + if (WebUtil.readBooleanParam(request, "getTransitions", false)) { + JSONArray transitions = new JSONArray(); + for (Transition transition : (Set) learningDesign.getTransitions()) { + JSONObject transitionJSON = new JSONObject(); + transitionJSON.put("uiid", transition.getTransitionUIID()); + transitionJSON.put("fromID", transition.getFromActivity().getActivityId()); + transitionJSON.put("toID", transition.getToActivity().getActivityId()); + + transitions.put(transitionJSON); + } + responseJSON.put("transitions", transitions); + } + List contributeActivities = getContributeActivities(lessonId, true); // remove "attention required" marker for hidden activities in Flash Authoring if (contributeActivities != null) { Index: lams_monitoring/web/monitor.jsp =================================================================== RCS file: /usr/local/cvsroot/lams_monitoring/web/monitor.jsp,v diff -u -r1.40 -r1.41 --- lams_monitoring/web/monitor.jsp 2 Jul 2015 12:26:07 -0000 1.40 +++ lams_monitoring/web/monitor.jsp 8 Jul 2015 14:34:26 -0000 1.41 @@ -55,7 +55,7 @@ FORCE_COMPLETE_ACTIVITY_CONFIRM : decoderDiv.html('').text(), - FORCE_COMPLETE_REMOVE_CONTENT : '', + FORCE_COMPLETE_REMOVE_CONTENT : decoderDiv.html('').text(), FORCE_COMPLETE_REMOVE_CONTENT_YES : '', @@ -551,4 +551,4 @@
- + \ No newline at end of file Index: lams_monitoring/web/gate/gateInfo.jsp =================================================================== RCS file: /usr/local/cvsroot/lams_monitoring/web/gate/gateInfo.jsp,v diff -u -r1.9 -r1.10 --- lams_monitoring/web/gate/gateInfo.jsp 26 May 2014 10:11:55 -0000 1.9 +++ lams_monitoring/web/gate/gateInfo.jsp 8 Jul 2015 14:34:26 -0000 1.10 @@ -39,6 +39,7 @@ +

Index: lams_monitoring/web/includes/javascript/monitorLesson.js =================================================================== RCS file: /usr/local/cvsroot/lams_monitoring/web/includes/javascript/monitorLesson.js,v diff -u -r1.54 -r1.55 --- lams_monitoring/web/includes/javascript/monitorLesson.js 2 Jul 2015 12:38:41 -0000 1.54 +++ lams_monitoring/web/includes/javascript/monitorLesson.js 8 Jul 2015 14:34:26 -0000 1.55 @@ -38,8 +38,12 @@ // double tap support tapTimeout = 500, - lastTap = 0; + lastTap = 0, +// after first entering of branching in old SVGs layout gets a bit broken +// setting this property fixes it + branchingEntered = false; + // ********* GENERAL TABS FUNCTIONS ********* function initTabs(){ @@ -763,6 +767,8 @@ return; } sequenceRefreshInProgress = true; + // SVG modifications are made only the first time this method is called + var sequenceCanvasFirstFetch = false; if (originalSequenceCanvas) { // put bottom layer, LD SVG @@ -781,15 +787,20 @@ 'branchingActivityID' : sequenceBranchingId }, success : function(response) { + sequenceCanvasFirstFetch = true; originalSequenceCanvas = response; + // store body dimensions before manipulating HTML + // otherwise resizing will yield bad results + var width = $('body').width(), + height = $('body').height(); sequenceCanvas = $('#sequenceCanvas') // remove previously set padding and dimensions, if any .removeAttr('style') .html(originalSequenceCanvas) // if it was faded out by showBranchingSequence() - .fadeIn(); - - resizeSequenceCanvas(); + .fadeIn(function(){ + resizeSequenceCanvas(width, height); + }); } }); } @@ -811,9 +822,40 @@ data : { 'method' : 'getLessonProgress', 'lessonID' : lessonId, - 'branchingActivityID' : sequenceBranchingId + 'branchingActivityID' : sequenceBranchingId, + 'getTransitions' : sequenceCanvasFirstFetch }, success : function(response) { + if (sequenceCanvasFirstFetch) { + // FLA activities have uiids but no ids, set it here + $.each(response.activities, function(activityIndex, activity){ + $('g[uiid="' + activity.uiid + '"]', sequenceCanvas).attr('id', activity.id); + }); + + // add some metadata to activities + $.each(response.activities, function(activityIndex, activity){ + var activityGroup = $('g[id="' + activity.id + '"]', sequenceCanvas), + isGate = [3,4,5,14].indexOf(activity.type) > -1, + isOptional = activity.type == 7, + isFloating = activity.type == 15; + if (isGate) { + activityGroup.attr('class', 'gate'); + } else if (isOptional) { + activityGroup.attr('class', 'optional'); + } else if (isFloating) { + activityGroup.attr('class', 'floating'); + } + }); + + // FLA transitions have uiid but no ids; needed for forceComplete() + $.each(response.transitions, function(index, transition){ + $('g[uiid="' + transition.uiid + '"]', sequenceCanvas) + .attr('id', transition.fromID + '_to_' + transition.toID); + }); + + originalSequenceCanvas = sequenceCanvas.html(); + } + // remove the loading animation $('img#sequenceCanvasLoading', sequenceTopButtonsContainer).remove(); @@ -851,13 +893,7 @@ var isBranching = [10,11,12,13].indexOf(activity.type) > -1; if (activity.url || (isBranching && !activity.flaFormat)) { - // find the activity in SVG - var coord = getActivityCoordinates(activity); - if (!coord || !coord.elem) { - return; - } - - var activityElems = [coord.elem], + var activityGroup = $('g[id="' + activity.id + '"]'), dblClickFunction = // different behaviour for regular/branching activities isBranching ? @@ -867,31 +903,18 @@ // double click on activity shape to open Monitoring for this activity openPopUp(LAMS_URL + activity.url, "MonitorActivity", 720, 900, true, true); }; - - // find the activity image, but skip learner and attention icons - $('image:not([id^="act"])', sequenceCanvas).each(function(){ - var image = $(this), - x = +image.attr('x'), - y = +image.attr('y'); - if (x > coord.x && x < coord.x2 && y > coord.y && y < coord.y2) { - activityElems.push(image); - } - }); - // find activity group, if it is not hidden - $.each(activityElems, function(){ - $(this).css('cursor', 'pointer') - // double tap detection on mobile devices; it works also for mouse clicks - .tap(function(event){ - var currentTime = new Date().getTime(), - tapLength = currentTime - lastTap; - if (tapLength < tapTimeout && tapLength > 0) { - event.preventDefault(); - dblClickFunction(); - } - lastTap = currentTime; - }); - }); + activityGroup.css('cursor', 'pointer') + // double tap detection on mobile devices; it works also for mouse clicks + .tap(function(event){ + var currentTime = new Date().getTime(), + tapLength = currentTime - lastTap; + if (tapLength < tapTimeout && tapLength > 0) { + event.preventDefault(); + dblClickFunction(); + } + lastTap = currentTime; + }); } }); @@ -906,84 +929,104 @@ */ function forceComplete(currentActivityId, learnerId, learnerName, x, y) { autoRefreshBlocked = true; + + var foundActivities = [], + targetActivity = null; // check all activities and "users who finished lesson" bar - $('rect[id^="act"], g polygon', sequenceCanvas).add('#completedLearnersContainer').each(function(){ + // rootElement is only in Flash LDs + $('g[id]:not([id*="_to_"]):not(#rootElement)', sequenceCanvas).add('#completedLearnersContainer').each(function(){ // find which activity learner was dropped on var act = $(this), - actX = act.offset().left, - actY = act.offset().top, - actWidth = act.width(), - actHeight = act.height(); - if (!actWidth) { - actWidth = +act.attr('width'); - actHeight = +act.attr('height'); + coord = { + 'x' : act.offset().left, + 'y' : act.offset().top + } + if (act.is('g')) { + var box = act[0].getBBox(); + coord.width = box.width; + coord.height = box.height; + } else { + // end of lesson container + coord.width = act.width(); + coord.height = act.height(); } - if (!actWidth && act.is('polygon')){ - // just for Gate activity - var polygonPoints = act.attr('points').split(' '); - actWidth = +polygonPoints[5].split(',')[0] - +polygonPoints[2].split(',')[0]; - actHeight = +polygonPoints[0].split(',')[1] - +polygonPoints[3].split(',')[1]; - } - var actEndX = actX + actWidth, - actEndY = actY + actHeight; - if (x >= actX && x<= actEndX && y>= actY && y<=actEndY) { - var targetActivityId = null; - var executeForceComplete = false; + coord.x2 = coord.x + coord.width; + coord.y2 = coord.y + coord.height; + + if (x >= coord.x && x <= coord.x2 && y >= coord.y && y <= coord.y2) { + foundActivities.push(act); + } + }); + + $.each(foundActivities, function(){ + if (this.attr('class') == 'floating') { + // no force complete to support activities + targetActivity = null; + return false; + } + // the enveloping OptionalActivity has priority + if (targetActivity == null || this.attr('class') == 'optional') { + targetActivity = this; + } + }); + + if (!targetActivity) { + return; + } + + var targetActivityId = null, + executeForceComplete = false, + isEndLesson = !targetActivity.is('g'); + + if (isEndLesson) { + executeForceComplete = currentActivityId && confirm(LABELS.FORCE_COMPLETE_END_LESSON_CONFIRM + .replace('[0]',learnerName)); + } else { + var targetActivityId = +targetActivity.attr('id'); + if (currentActivityId != targetActivityId) { - if (act.attr('id') == 'completedLearnersContainer') { - executeForceComplete = currentActivityId && confirm(LABELS.FORCE_COMPLETE_END_LESSON_CONFIRM - .replace('[0]',learnerName)); - } else { - var targetActivityId = act.parent().attr('id'); - if (currentActivityId != targetActivityId) { - - var precedingActivityId = currentActivityId, - targetActivityName = act.is('polygon') ? "Gate" - : act.siblings('text[id^="TextElement"]').text(); - - // find out if we are moving learner forward or backwards - while (precedingActivityId){ - // find transition line and extract activity IDs from them - var transitionLine = $('line[id$="to_' - + precedingActivityId + '"]:not([id^="arrow"])' - , sequenceCanvas); - precedingActivityId = transitionLine.length == 1 ? - transitionLine.attr('id').split('_')[0] : null; - if (targetActivityId == precedingActivityId) { - break; - } - }; - - // check if the target activity was found or we are moving the learner from end of lesson - if (!currentActivityId || precedingActivityId) { - // move the learner backwards - $('#forceBackwardsDialog').text(LABELS.FORCE_COMPLETE_REMOVE_CONTENT - .replace('[0]', learnerName).replace('[1]', targetActivityName)) - .dialog('option', { - 'learnerId' : learnerId, - 'activityId': targetActivityId - }) - .dialog('open'); - // so autoRefreshBlocked = false is not set - return; - } else { - // move the learner forward - executeForceComplete = confirm(LABELS.FORCE_COMPLETE_ACTIVITY_CONFIRM - .replace('[0]', learnerName).replace('[1]', targetActivityName)); - } + var precedingActivityId = currentActivityId, + targetActivityName = targetActivity.attr('class') == 'gate' ? "Gate" : targetActivity.children('text').text(); + + // find out if we are moving learner forward or backwards + while (precedingActivityId){ + // find transition line and extract activity IDs from them + // it is Batik format adopted to new SVGs + var transitionLine = $('*[id$="to_' + + precedingActivityId + '"]:not([id^="arrow"])' + , sequenceCanvas); + precedingActivityId = transitionLine.length == 1 ? + transitionLine.attr('id').split('_')[0] : null; + if (targetActivityId == precedingActivityId) { + break; } - } + }; - if (executeForceComplete) { - - forceCompleteExecute(learnerId, targetActivityId, false); + // check if the target activity was found or we are moving the learner from end of lesson + if (!currentActivityId || precedingActivityId) { + // move the learner backwards + $('#forceBackwardsDialog').text(LABELS.FORCE_COMPLETE_REMOVE_CONTENT + .replace('[0]', learnerName).replace('[1]', targetActivityName)) + .dialog('option', { + 'learnerId' : learnerId, + 'activityId': targetActivityId + }) + .dialog('open'); + // so autoRefreshBlocked = false is not set + return; + } else { + // move the learner forward + executeForceComplete = confirm(LABELS.FORCE_COMPLETE_ACTIVITY_CONFIRM + .replace('[0]', learnerName).replace('[1]', targetActivityName)); } - // we found our target, stop iteration - return false; } - }); + } + if (executeForceComplete) { + forceCompleteExecute(learnerId, targetActivityId, false); + } + autoRefreshBlocked = false; } @@ -1029,16 +1072,14 @@ } // add group of users icon - var activityGroup = $('g#' + activity.id, sequenceCanvas), - // in old SVG format, add to a group; in new, go straight for the SVG root element - appendTarget = (activityGroup.length > 0 ? activityGroup : $('svg', sequenceCanvas))[0], + var appendTarget = $('svg', sequenceCanvas)[0], // branching and gates require extra adjustments isNewBranching = [10,11,12,13].indexOf(activity.type) > -1 && activity.flaFormat, isGate = [3,4,5,14].indexOf(activity.type) > -1; if (activity.learners){ var groupTitle = activity.learners.length + ' ' + LABELS.LEARNER_GROUP_COUNT + ' ' + LABELS.LEARNER_GROUP_SHOW, - // if icons do not fit in shape anymore, show a group icon + // if icons do not fit in shape anymore, show a group icon element = appendXMLElement('image', { 'id' : 'act' + activity.id + 'learnerGroup', 'x' : isNewBranching ? coord.x + 2 : (isGate ? coord.x + 10 : coord.x2 - 18), @@ -1257,42 +1298,33 @@ } } - // get either rectangle from old Batik SVG format - // or path from new Flashless Authoring format (IE and other browsers format paths differently) - var elem = $('rect[x="' + activity.x + '.0"][y="' + activity.y + '.0"], ' + - 'rect[x="' + activity.x + '"][y="' + activity.y + '"], ' + - 'path[d^="M' + activity.x + ',' + activity.y +'"], ' + - 'path[d^="M ' + activity.x + ' ' + activity.y +'"]', - sequenceCanvas); - if (elem.length == 0) { + var group = $('g[id="' + activity.id + '"]', sequenceCanvas); + if (group.length == 0) { return; } - - // if it's a rectangle, it has these attributes - var width = elem.attr('width'), + var elem = $('rect, path', group), + // if it's a rectangle, it has these attributes; rectangles are in old SVGs + width = elem.attr('width'), height = elem.attr('height'); if (width) { return { - 'elem' : elem, 'x' : activity.x, 'y' : activity.y, 'x2' : activity.x + +width, 'y2' : activity.y + +height } } else { - // extract width and height from path M,HV... or M H V ... - var match = /H\s?(\d+)\s?V\s?(\d+)/i.exec(elem.attr('d')); + // extract width and height from path M,hv... or M h v ... + var match = /h\s?(\d+)\s?v\s?(\d+)/.exec(elem.attr('d')); if (match) { return { - 'elem' : elem, 'x' : activity.x, 'y' : activity.y + 1, - 'x2' : +match[1], - 'y2' : +match[2] + 'x2' : activity.x + +match[1], + 'y2' : activity.y + +match[2] } } } - } @@ -1444,6 +1476,7 @@ function showBranchingSequence(branchingActivityId){ sequenceBranchingId = branchingActivityId; originalSequenceCanvas = null; + branchingEntered = true; $('#closeBranchingButton').show(); sequenceCanvas.fadeOut(function(){ sequenceCanvas.html(null); @@ -1464,11 +1497,6 @@ * Adjusts sequence canvas (SVG) based on space available in the dialog. */ function resizeSequenceCanvas(width, height){ - // Initial resize sends no parameters. - // When resizing the dialog, parameters are sent. - // Taking body's dimensions when resizing yields erroneous results. - width = width || $('body').width(); - height = height || $('body').height(); var sequenceCanvas = $('#sequenceCanvas'), // can it be done nicer? canvasHeight = height - $('#tabs>ul').height() - $('#sequenceTopButtonsContainer').height() @@ -1480,10 +1508,12 @@ canvasPaddingLeft = Math.max(0, canvasWidth/2 - svg.attr('width')/2); sequenceCanvas.css({ - 'padding-top' : canvasPaddingTop, - 'padding-left' : canvasPaddingLeft, - 'width' : canvasWidth - canvasPaddingLeft, - 'height' : canvasHeight - canvasPaddingTop + 'padding-top' : canvasPaddingTop, + // after first entering of Branching in old SVGs we need this adjustment + 'padding-bottom' : branchingEntered ? 20 : 0, + 'padding-left' : canvasPaddingLeft, + 'width' : canvasWidth - canvasPaddingLeft, + 'height' : canvasHeight - canvasPaddingTop }); }