diff --git a/amd/build/learningmap.min.js b/amd/build/learningmap.min.js index 55057a0..4f93552 100644 --- a/amd/build/learningmap.min.js +++ b/amd/build/learningmap.min.js @@ -1,3 +1,3 @@ -define("mod_learningmap/learningmap",["exports","core/notification","core/templates","mod_learningmap/placestore"],(function(_exports,_notification,_templates,_placestore){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_templates=_interopRequireDefault(_templates),_placestore=_interopRequireDefault(_placestore);const targetPoints_firstPoint=1,targetPoints_secondPoint=2,targetPoints_bezierPoint=3,pathTypes_line=1,pathTypes_quadraticbezier=2;_exports.init=()=>{var offset,dragel,pathsToUpdateFirstPoint,pathsToUpdateSecondPoint;_templates.default.prefetchTemplates(["mod_learningmap/cssskeleton"]);var selectedElement=null,firstPlace=null,secondPlace=null,lastTarget=null,elementForActivitySelector=null,touchstart=!1,touchend=!1,touchmove=0;let mapdiv=document.getElementById("learningmap-editor-map"),code=document.getElementById("id_svgcode"),activitySetting=document.getElementById("learningmap-activity-setting"),activitySelector=document.getElementById("learningmap-activity-selector"),activityStarting=document.getElementById("learningmap-activity-starting"),activityTarget=document.getElementById("learningmap-activity-target"),activityHiddenWarning=document.getElementById("learningmap-activity-hidden-warning"),advancedSettingsIcon=document.getElementById("learningmap-advanced-settings-icon"),treeView=document.querySelector(".fp-viewbar .fp-vb-tree");treeView&&treeView.setAttribute("style","display: none;");let iconView=document.querySelector(".fp-viewbar .fp-vb-icons");iconView&&setTimeout((()=>{iconView.dispatchEvent(new Event("click"))}),1e3),activitySelector&&(activitySelector.addEventListener("change",(function(){if(_placestore.default.setActivityId(elementForActivitySelector,activitySelector.value),activitySelector.value){let text=document.getElementById("text"+elementForActivitySelector);text&&(text.textContent=activitySelector.querySelector('option[value="'+activitySelector.value+'"]').textContent);let title=document.getElementById("title"+elementForActivitySelector);title&&(title.textContent=activitySelector.querySelector('option[value="'+activitySelector.value+'"]').textContent),document.getElementById(elementForActivitySelector).classList.remove("learningmap-emptyplace")}else document.getElementById(elementForActivitySelector).classList.add("learningmap-emptyplace");updateActivities(),updateCode()})),activityStarting.addEventListener("change",(function(){activityStarting.checked?_placestore.default.addStartingPlace(elementForActivitySelector):_placestore.default.removeStartingPlace(elementForActivitySelector),updateCode()})),activityTarget.addEventListener("change",(function(){activityTarget.checked?(_placestore.default.addTargetPlace(elementForActivitySelector),document.getElementById(elementForActivitySelector).classList.add("learningmap-targetplace")):(_placestore.default.removeTargetPlace(elementForActivitySelector),document.getElementById(elementForActivitySelector).classList.remove("learningmap-targetplace")),updateCode()})));let placestoreInput=document.getElementsByName("placestore")[0];if(placestoreInput&&_placestore.default.loadJSON(placestoreInput.value),updateActivities(),advancedSettingsIcon){let advancedSettings=document.getElementById("learningmap-advanced-settings");advancedSettingsIcon.addEventListener("click",(function(){null===advancedSettings.getAttribute("hidden")?hideAdvancedSettings():(advancedSettings.removeAttribute("hidden"),hideContextMenu())}));let advancedSettingsClose=document.getElementById("learningmap-advanced-settings-close");advancedSettingsClose&&advancedSettingsClose.addEventListener("click",(function(){advancedSettings.setAttribute("hidden","")})),advancedSettingsLogic("hidepaths",_placestore.default.getHidePaths,_placestore.default.setHidePaths),advancedSettingsLogic("usecheckmark",_placestore.default.getUseCheckmark,_placestore.default.setUseCheckmark),advancedSettingsLogic("hover",_placestore.default.getHover,_placestore.default.setHover),advancedSettingsLogic("pulse",_placestore.default.getPulse,_placestore.default.setPulse),advancedSettingsLogic("showall",_placestore.default.getShowall,_placestore.default.setShowall),advancedSettingsLogic("hidestroke",_placestore.default.getHideStroke,_placestore.default.setHideStroke),advancedSettingsLogic("showtext",_placestore.default.getShowText,_placestore.default.setShowText,(function(){let options=Array.from(activitySelector.getElementsByTagName("option")),places=_placestore.default.getPlaces();for(const place of places)if(null===document.getElementById("text"+place.id)){let content="";for(const option of options)if(option.value==place.linkedActivity){content=option.textContent;break}let placeNode=document.getElementById(place.id),textNode=text("text"+place.id,content,placeNode.cx.baseVal.value,placeNode.cy.baseVal.value);placeNode.parentNode.appendChild(textNode)}})),advancedSettingsLogic("slicemode",_placestore.default.getSliceMode,_placestore.default.setSliceMode),advancedSettingsLogic("showwaygone",_placestore.default.getShowWayGone,_placestore.default.setShowWayGone)}colorChooserLogic("stroke","text"),colorChooserLogic("place"),colorChooserLogic("visited"),code&&mapdiv&&(mapdiv.innerHTML=code.value),refreshBackgroundImage(),function(){let background=document.getElementById("learningmap-background-image");background&&background.addEventListener("load",(function(){background.removeAttribute("height");let height=parseInt(background.getBBox().height),width=background.getBBox().width;_placestore.default.setBackgroundDimensions(width,height),svg.setAttribute("viewBox","0 0 "+_placestore.default.width+" "+_placestore.default.height),background.setAttribute("width",width),background.setAttribute("height",height),updateCode()}))}(),updateCode();let svg=document.getElementById("learningmap-svgmap-"+_placestore.default.getMapid());function showContextMenu(e){if(unselectAll(),hideAdvancedSettings(),activitySetting&&null!==document.getElementById(e.target.id))if(e.touches&&(e=e.touches[0]),e.target.classList.contains("learningmap-place")){e.target.classList.add("learningmap-selected-activity-selector");let activityId=_placestore.default.getActivityId(e.target.id),scalingFactor=mapdiv.clientWidth/800;activitySetting.style.setProperty("--pos-x",e.target.cx.baseVal.value*scalingFactor+"px"),activitySetting.style.setProperty("--pos-y",e.target.cy.baseVal.value*scalingFactor+"px"),activitySetting.style.setProperty("--map-width",mapdiv.clientWidth+"px"),activitySetting.style.setProperty("--map-height",mapdiv.clientHeight+"px"),activitySetting.style.display="block",document.getElementById("learningmap-activity-selector").value=activityId,document.getElementById("learningmap-activity-starting").checked=_placestore.default.isStartingPlace(e.target.id),document.getElementById("learningmap-activity-target").checked=_placestore.default.isTargetPlace(e.target.id),elementForActivitySelector=e.target.id,updateActivities()}else hideContextMenu(),hideAdvancedSettings()}function hideContextMenu(){let e=document.getElementById(elementForActivitySelector);e&&e.classList.remove("learningmap-selected-activity-selector"),activitySetting.style.display="none"}!function(el){dragel=el,el&&(el.addEventListener("mousedown",startDrag),el.addEventListener("mousemove",drag),el.addEventListener("mouseup",endDrag),el.addEventListener("mouseleave",endDrag),el.addEventListener("touchstart",(function(evt){evt.cancelable&&evt.preventDefault();evt.target.classList.contains("learningmap-draggable")||"text"==evt.target.nodeName||"path"==evt.target.nodeName?(touchstart?(dblclickHandler(evt),touchstart=!1):(touchstart=!0,touchmove=0,touchend=!1,setTimeout((evt=>{touchmove<3&&!touchend&&(evt.touches&&(evt=evt.touches[0]),showContextMenu(evt))}),2e3,evt),setTimeout((()=>{touchstart=!1}),300)),startDrag(evt)):touchstart?(dblclickHandler(evt),touchstart=!1):(touchstart=!0,touchend=!1,touchmove=0,setTimeout((()=>{touchstart=!1}),300))})),el.addEventListener("touchmove",drag),el.addEventListener("touchend",endTouch),el.addEventListener("touchleave",endTouch),el.addEventListener("touchcancel",endTouch));function startDrag(evt){if(evt.cancelable&&evt.preventDefault(),pathsToUpdateFirstPoint=[],pathsToUpdateSecondPoint=[],evt.target.classList.contains("learningmap-draggable"))selectedElement=evt.target,(offset=getMousePosition(evt)).x-=parseInt(selectedElement.getAttributeNS(null,"cx")),offset.y-=parseInt(selectedElement.getAttributeNS(null,"cy")),pathsToUpdateFirstPoint=_placestore.default.getPathsWithFid(selectedElement.id),pathsToUpdateSecondPoint=_placestore.default.getPathsWithSid(selectedElement.id);else if("text"==evt.target.nodeName){let place=(selectedElement=evt.target).parentNode.querySelector(".learningmap-place");(offset=getMousePosition(evt)).x-=parseInt(selectedElement.getAttributeNS(null,"dx"))+place.cx.baseVal.value,offset.y-=parseInt(selectedElement.getAttributeNS(null,"dy"))+place.cy.baseVal.value}else if("path"==evt.target.nodeName){selectedElement=evt.target,offset=getMousePosition(evt);let pathPoint=transformCoordinates(evt.layerX,evt.layerY);offset.x+=pathPoint.x,offset.y+=pathPoint.y}}function drag(evt){if(evt.cancelable&&evt.preventDefault(),touchmove++,selectedElement){var coord=getMousePosition(evt);let cx=coord.x-offset.x,cy=coord.y-offset.y;if("text"==selectedElement.nodeName){let place=selectedElement.parentNode.querySelector(".learningmap-place"),dx=coord.x-offset.x-place.cx.baseVal.value,dy=coord.y-offset.y-place.cy.baseVal.value;selectedElement.setAttributeNS(null,"dx",dx),selectedElement.setAttributeNS(null,"dy",dy)}if("path"==selectedElement.nodeName&&selectedElement.setAttribute("d",updatePathDeclaration(selectedElement.getAttribute("d"),coord.x,coord.y,targetPoints_bezierPoint)),"circle"==selectedElement.nodeName){selectedElement.setAttributeNS(null,"cx",cx),selectedElement.setAttributeNS(null,"cy",cy);let textNode=document.getElementById("text"+selectedElement.id);null!==textNode&&(textNode.setAttributeNS(null,"x",cx),textNode.setAttributeNS(null,"y",cy)),pathsToUpdateFirstPoint.forEach((function(path){let pathNode=document.getElementById(path.id);null!==pathNode&&("path"==pathNode.nodeName?pathNode.setAttribute("d",updatePathDeclaration(pathNode.getAttribute("d"),cx,cy,targetPoints_firstPoint)):(pathNode.setAttribute("x1",cx),pathNode.setAttribute("y1",cy)))})),pathsToUpdateSecondPoint.forEach((function(path){let pathNode=document.getElementById(path.id);null!==pathNode&&("path"==pathNode.nodeName?pathNode.setAttribute("d",updatePathDeclaration(pathNode.getAttribute("d"),cx,cy,targetPoints_secondPoint)):(pathNode.setAttribute("x2",cx),pathNode.setAttribute("y2",cy)))}))}}}function endDrag(evt){evt.cancelable&&evt.preventDefault(),selectedElement=null,unselectAll(),updateCode()}function endTouch(evt){selectedElement=null,touchend=!0,touchmove<3&&touchstart?clickHandler(evt):endDrag(evt),evt.cancelable&&evt.preventDefault()}function updatePathDeclaration(oldDefinition,targetX,targetY){let targetP=arguments.length>3&&void 0!==arguments[3]?arguments[3]:targetPoints_firstPoint,parts=oldDefinition.split(" "),fromX=0,fromY=0,toX=0,toY=0,bezierX=0,bezierY=0,pathType=pathTypes_line;for(let i=0;i2&&void 0!==arguments[2]?arguments[2]:null,text=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,link=document.createElementNS("http://www.w3.org/2000/svg","a");link.setAttribute("id",id),link.setAttribute("xlink:href",""),link.appendChild(child),null!==title&&link.appendChild(title);null!==text&&link.appendChild(text);return link}(function(x,y,r,classes,id){let circle=document.createElementNS("http://www.w3.org/2000/svg","circle");return circle.setAttribute("class",classes),circle.setAttribute("id",id),circle.setAttribute("cx",x),circle.setAttribute("cy",y),circle.setAttribute("r",r),circle}(cx,cy,10,"learningmap-place learningmap-draggable learningmap-emptyplace",placeId),linkId,function(id){let title=document.createElementNS("http://www.w3.org/2000/svg","title");return title.setAttribute("id",id),title}("title"+placeId),text("text"+placeId,"",cx,cy))),_placestore.default.addPlace(placeId,linkId)}(event):event.target.classList.contains("learningmap-place")?lastTarget==event.target.id?(lastTarget=null,clickHandler(event)):function(event){let place=document.getElementById(event.target.id),parent=place.parentNode;id=event.target.id,_placestore.default.getTouchingPaths(id).forEach((function(e){removePath(e.id)})),_placestore.default.removePlace(event.target.id),parent.removeChild(place),parent.parentNode.removeChild(parent),updateCode();var id}(event):event.target.classList.contains("learningmap-path")&&removePath(event.target.id),updateCode()}function text(id,content,x,y){let text=document.createElementNS("http://www.w3.org/2000/svg","text");return text.setAttribute("id",id),text.setAttribute("x",x),text.setAttribute("y",y),text.setAttribute("dx",15),text.setAttribute("dy",15),text.textContent=content,text}function clickHandler(event){if(event.preventDefault(),hideContextMenu(),hideAdvancedSettings(),event.target.classList.contains("learningmap-place")&&null===selectedElement)if(null===firstPlace)firstPlace=event.target.id,document.getElementById(firstPlace).classList.add("learningmap-selected");else{secondPlace=event.target.id;let fid=parseInt(firstPlace.replace("p","")),sid=parseInt(secondPlace.replace("p",""));if(sid==fid)return;if(sid0){let background=document.getElementById("learningmap-background-image"),backgroundurl=previewimage[0].getAttribute("src").split("?")[0];previewimage[0].getAttribute("src").split("?")[1].includes("&oid=")&&(backgroundurl+="?oid="+previewimage[0].getAttribute("src").split("&oid=")[1]),background.setAttribute("xlink:href",backgroundurl)}}function updateCSS(){_templates.default.renderForPromise("mod_learningmap/cssskeleton",_placestore.default.getPlacestore()).then((_ref=>{let{html:html,js:js}=_ref;return _templates.default.replaceNode("#learningmap-svgstyle",html,js),updateCode(),!0})).catch((ex=>(0,_notification.exception)(ex)))}function updateActivities(){let activities=_placestore.default.getAllActivities(),options=Array.from(activitySelector.getElementsByTagName("option"));activityHiddenWarning.setAttribute("hidden",""),options.forEach((function(n){activities.includes(n.value)?(n.classList.add("learningmap-used-activity"),n.selected&&1==n.getAttribute("data-activity-hidden")&&activityHiddenWarning.removeAttribute("hidden")):n.classList.remove("learningmap-used-activity")}))}function colorChooserLogic(name){let secondValue=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",colorChooser=document.getElementById("learningmap-color-"+name);colorChooser&&(colorChooser.addEventListener("change",(function(){_placestore.default.setColor(name,colorChooser.value),""!=secondValue&&_placestore.default.setColor(secondValue,colorChooser.value),updateCSS()})),colorChooser.value=_placestore.default.getColor(name))}function advancedSettingsLogic(name,getCall,setCall){let callback=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,settingItem=document.getElementById("learningmap-advanced-setting-"+name);settingItem&&(settingItem.checked=getCall.call(_placestore.default),settingItem.addEventListener("change",(function(){setCall.call(_placestore.default,settingItem.checked),null!==callback&&callback(),updateCSS()})))}function hideAdvancedSettings(){document.getElementById("learningmap-advanced-settings").setAttribute("hidden","")}}})); +define("mod_learningmap/learningmap",["exports","core/notification","core/templates","mod_learningmap/placestore"],(function(_exports,_notification,_templates,_placestore){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_templates=_interopRequireDefault(_templates),_placestore=_interopRequireDefault(_placestore);const targetPoints_firstPoint=1,targetPoints_secondPoint=2,targetPoints_bezierPoint=3,pathTypes_line=1,pathTypes_quadraticbezier=2;_exports.init=()=>{var offset,dragel,pathsToUpdateFirstPoint,pathsToUpdateSecondPoint;_templates.default.prefetchTemplates(["mod_learningmap/cssskeleton"]);var selectedElement=null,firstPlace=null,secondPlace=null,lastTarget=null,elementForActivitySelector=null,touchstart=!1,touchend=!1,touchmove=0;let mapdiv=document.getElementById("learningmap-editor-map"),code=document.getElementById("id_svgcode"),activitySetting=document.getElementById("learningmap-activity-setting"),activitySelector=document.getElementById("learningmap-activity-selector"),activityStarting=document.getElementById("learningmap-activity-starting"),activityTarget=document.getElementById("learningmap-activity-target"),activityHiddenWarning=document.getElementById("learningmap-activity-hidden-warning"),advancedSettingsIcon=document.getElementById("learningmap-advanced-settings-icon"),treeView=document.querySelector(".fp-viewbar .fp-vb-tree");treeView&&treeView.setAttribute("style","display: none;");let iconView=document.querySelector(".fp-viewbar .fp-vb-icons");iconView&&setTimeout((()=>{iconView.dispatchEvent(new Event("click"))}),1e3),activitySelector&&(activitySelector.addEventListener("change",(function(){if(_placestore.default.setActivityId(elementForActivitySelector,activitySelector.value),activitySelector.value){let text=document.getElementById("text"+elementForActivitySelector);text&&(text.textContent=wrapInCdata(activitySelector.querySelector('option[value="'+activitySelector.value+'"]').textContent));let title=document.getElementById("title"+elementForActivitySelector);title&&(title.textContent=wrapInCdata(activitySelector.querySelector('option[value="'+activitySelector.value+'"]').textContent)),document.getElementById(elementForActivitySelector).classList.remove("learningmap-emptyplace")}else document.getElementById(elementForActivitySelector).classList.add("learningmap-emptyplace");updateActivities(),updateCode()})),activityStarting.addEventListener("change",(function(){activityStarting.checked?_placestore.default.addStartingPlace(elementForActivitySelector):_placestore.default.removeStartingPlace(elementForActivitySelector),updateCode()})),activityTarget.addEventListener("change",(function(){activityTarget.checked?(_placestore.default.addTargetPlace(elementForActivitySelector),document.getElementById(elementForActivitySelector).classList.add("learningmap-targetplace")):(_placestore.default.removeTargetPlace(elementForActivitySelector),document.getElementById(elementForActivitySelector).classList.remove("learningmap-targetplace")),updateCode()})));let placestoreInput=document.getElementsByName("placestore")[0];if(placestoreInput&&_placestore.default.loadJSON(placestoreInput.value),updateActivities(),advancedSettingsIcon){let advancedSettings=document.getElementById("learningmap-advanced-settings");advancedSettingsIcon.addEventListener("click",(function(){null===advancedSettings.getAttribute("hidden")?hideAdvancedSettings():(advancedSettings.removeAttribute("hidden"),hideContextMenu())}));let advancedSettingsClose=document.getElementById("learningmap-advanced-settings-close");advancedSettingsClose&&advancedSettingsClose.addEventListener("click",(function(){advancedSettings.setAttribute("hidden","")})),advancedSettingsLogic("hidepaths",_placestore.default.getHidePaths,_placestore.default.setHidePaths),advancedSettingsLogic("usecheckmark",_placestore.default.getUseCheckmark,_placestore.default.setUseCheckmark),advancedSettingsLogic("hover",_placestore.default.getHover,_placestore.default.setHover),advancedSettingsLogic("pulse",_placestore.default.getPulse,_placestore.default.setPulse),advancedSettingsLogic("showall",_placestore.default.getShowall,_placestore.default.setShowall),advancedSettingsLogic("hidestroke",_placestore.default.getHideStroke,_placestore.default.setHideStroke),advancedSettingsLogic("showtext",_placestore.default.getShowText,_placestore.default.setShowText,(function(){let options=Array.from(activitySelector.getElementsByTagName("option")),places=_placestore.default.getPlaces();for(const place of places)if(null===document.getElementById("text"+place.id)){let content="";for(const option of options)if(option.value==place.linkedActivity){content=option.textContent;break}let placeNode=document.getElementById(place.id),textNode=text("text"+place.id,content,placeNode.cx.baseVal.value,placeNode.cy.baseVal.value);placeNode.parentNode.appendChild(textNode)}})),advancedSettingsLogic("slicemode",_placestore.default.getSliceMode,_placestore.default.setSliceMode),advancedSettingsLogic("showwaygone",_placestore.default.getShowWayGone,_placestore.default.setShowWayGone)}colorChooserLogic("stroke","text"),colorChooserLogic("place"),colorChooserLogic("visited"),code&&mapdiv&&(mapdiv.innerHTML=code.value),refreshBackgroundImage(),function(){let background=document.getElementById("learningmap-background-image");background&&background.addEventListener("load",(function(){background.removeAttribute("height");let height=parseInt(background.getBBox().height),width=background.getBBox().width;_placestore.default.setBackgroundDimensions(width,height),svg.setAttribute("viewBox","0 0 "+_placestore.default.width+" "+_placestore.default.height),background.setAttribute("width",width),background.setAttribute("height",height),updateCode()}))}(),updateCode();let svg=document.getElementById("learningmap-svgmap-"+_placestore.default.getMapid());function showContextMenu(e){if(unselectAll(),hideAdvancedSettings(),activitySetting&&null!==document.getElementById(e.target.id))if(e.touches&&(e=e.touches[0]),e.target.classList.contains("learningmap-place")){e.target.classList.add("learningmap-selected-activity-selector");let activityId=_placestore.default.getActivityId(e.target.id),scalingFactor=mapdiv.clientWidth/800;activitySetting.style.setProperty("--pos-x",e.target.cx.baseVal.value*scalingFactor+"px"),activitySetting.style.setProperty("--pos-y",e.target.cy.baseVal.value*scalingFactor+"px"),activitySetting.style.setProperty("--map-width",mapdiv.clientWidth+"px"),activitySetting.style.setProperty("--map-height",mapdiv.clientHeight+"px"),activitySetting.style.display="block",document.getElementById("learningmap-activity-selector").value=activityId,document.getElementById("learningmap-activity-starting").checked=_placestore.default.isStartingPlace(e.target.id),document.getElementById("learningmap-activity-target").checked=_placestore.default.isTargetPlace(e.target.id),elementForActivitySelector=e.target.id,updateActivities()}else hideContextMenu(),hideAdvancedSettings()}function hideContextMenu(){let e=document.getElementById(elementForActivitySelector);e&&e.classList.remove("learningmap-selected-activity-selector"),activitySetting.style.display="none"}!function(el){dragel=el,el&&(el.addEventListener("mousedown",startDrag),el.addEventListener("mousemove",drag),el.addEventListener("mouseup",endDrag),el.addEventListener("mouseleave",endDrag),el.addEventListener("touchstart",(function(evt){evt.cancelable&&evt.preventDefault();evt.target.classList.contains("learningmap-draggable")||"text"==evt.target.nodeName||"path"==evt.target.nodeName?(touchstart?(dblclickHandler(evt),touchstart=!1):(touchstart=!0,touchmove=0,touchend=!1,setTimeout((evt=>{touchmove<3&&!touchend&&(evt.touches&&(evt=evt.touches[0]),showContextMenu(evt))}),2e3,evt),setTimeout((()=>{touchstart=!1}),300)),startDrag(evt)):touchstart?(dblclickHandler(evt),touchstart=!1):(touchstart=!0,touchend=!1,touchmove=0,setTimeout((()=>{touchstart=!1}),300))})),el.addEventListener("touchmove",drag),el.addEventListener("touchend",endTouch),el.addEventListener("touchleave",endTouch),el.addEventListener("touchcancel",endTouch));function startDrag(evt){if(evt.cancelable&&evt.preventDefault(),pathsToUpdateFirstPoint=[],pathsToUpdateSecondPoint=[],evt.target.classList.contains("learningmap-draggable"))selectedElement=evt.target,(offset=getMousePosition(evt)).x-=parseInt(selectedElement.getAttributeNS(null,"cx")),offset.y-=parseInt(selectedElement.getAttributeNS(null,"cy")),pathsToUpdateFirstPoint=_placestore.default.getPathsWithFid(selectedElement.id),pathsToUpdateSecondPoint=_placestore.default.getPathsWithSid(selectedElement.id);else if("text"==evt.target.nodeName){let place=(selectedElement=evt.target).parentNode.querySelector(".learningmap-place");(offset=getMousePosition(evt)).x-=parseInt(selectedElement.getAttributeNS(null,"dx"))+place.cx.baseVal.value,offset.y-=parseInt(selectedElement.getAttributeNS(null,"dy"))+place.cy.baseVal.value}else if("path"==evt.target.nodeName){selectedElement=evt.target,offset=getMousePosition(evt);let pathPoint=transformCoordinates(evt.layerX,evt.layerY);offset.x+=pathPoint.x,offset.y+=pathPoint.y}}function drag(evt){if(evt.cancelable&&evt.preventDefault(),touchmove++,selectedElement){var coord=getMousePosition(evt);let cx=coord.x-offset.x,cy=coord.y-offset.y;if("text"==selectedElement.nodeName){let place=selectedElement.parentNode.querySelector(".learningmap-place"),dx=coord.x-offset.x-place.cx.baseVal.value,dy=coord.y-offset.y-place.cy.baseVal.value;selectedElement.setAttributeNS(null,"dx",dx),selectedElement.setAttributeNS(null,"dy",dy)}if("path"==selectedElement.nodeName&&selectedElement.setAttribute("d",updatePathDeclaration(selectedElement.getAttribute("d"),coord.x,coord.y,targetPoints_bezierPoint)),"circle"==selectedElement.nodeName){selectedElement.setAttributeNS(null,"cx",cx),selectedElement.setAttributeNS(null,"cy",cy);let textNode=document.getElementById("text"+selectedElement.id);null!==textNode&&(textNode.setAttributeNS(null,"x",cx),textNode.setAttributeNS(null,"y",cy)),pathsToUpdateFirstPoint.forEach((function(path){let pathNode=document.getElementById(path.id);null!==pathNode&&("path"==pathNode.nodeName?pathNode.setAttribute("d",updatePathDeclaration(pathNode.getAttribute("d"),cx,cy,targetPoints_firstPoint)):(pathNode.setAttribute("x1",cx),pathNode.setAttribute("y1",cy)))})),pathsToUpdateSecondPoint.forEach((function(path){let pathNode=document.getElementById(path.id);null!==pathNode&&("path"==pathNode.nodeName?pathNode.setAttribute("d",updatePathDeclaration(pathNode.getAttribute("d"),cx,cy,targetPoints_secondPoint)):(pathNode.setAttribute("x2",cx),pathNode.setAttribute("y2",cy)))}))}}}function endDrag(evt){evt.cancelable&&evt.preventDefault(),selectedElement=null,unselectAll(),updateCode()}function endTouch(evt){selectedElement=null,touchend=!0,touchmove<3&&touchstart?clickHandler(evt):endDrag(evt),evt.cancelable&&evt.preventDefault()}function updatePathDeclaration(oldDefinition,targetX,targetY){let targetP=arguments.length>3&&void 0!==arguments[3]?arguments[3]:targetPoints_firstPoint,parts=oldDefinition.split(" "),fromX=0,fromY=0,toX=0,toY=0,bezierX=0,bezierY=0,pathType=pathTypes_line;for(let i=0;i2&&void 0!==arguments[2]?arguments[2]:null,text=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,link=document.createElementNS("http://www.w3.org/2000/svg","a");link.setAttribute("id",id),link.setAttribute("xlink:href",""),link.appendChild(child),null!==title&&link.appendChild(title);null!==text&&link.appendChild(text);return link}(function(x,y,r,classes,id){let circle=document.createElementNS("http://www.w3.org/2000/svg","circle");return circle.setAttribute("class",classes),circle.setAttribute("id",id),circle.setAttribute("cx",x),circle.setAttribute("cy",y),circle.setAttribute("r",r),circle}(cx,cy,10,"learningmap-place learningmap-draggable learningmap-emptyplace",placeId),linkId,function(id){let title=document.createElementNS("http://www.w3.org/2000/svg","title");return title.setAttribute("id",id),title}("title"+placeId),text("text"+placeId,"",cx,cy))),_placestore.default.addPlace(placeId,linkId)}(event):event.target.classList.contains("learningmap-place")?lastTarget==event.target.id?(lastTarget=null,clickHandler(event)):function(event){let place=document.getElementById(event.target.id),parent=place.parentNode;id=event.target.id,_placestore.default.getTouchingPaths(id).forEach((function(e){removePath(e.id)})),_placestore.default.removePlace(event.target.id),parent.removeChild(place),parent.parentNode.removeChild(parent),updateCode();var id}(event):event.target.classList.contains("learningmap-path")&&removePath(event.target.id),updateCode()}function text(id,content,x,y){let text=document.createElementNS("http://www.w3.org/2000/svg","text");return text.setAttribute("id",id),text.setAttribute("x",x),text.setAttribute("y",y),text.setAttribute("dx",15),text.setAttribute("dy",15),text.textContent=wrapInCdata(content),text}function clickHandler(event){if(event.preventDefault(),hideContextMenu(),hideAdvancedSettings(),event.target.classList.contains("learningmap-place")&&null===selectedElement)if(null===firstPlace)firstPlace=event.target.id,document.getElementById(firstPlace).classList.add("learningmap-selected");else{secondPlace=event.target.id;let fid=parseInt(firstPlace.replace("p","")),sid=parseInt(secondPlace.replace("p",""));if(sid==fid)return;if(sid0){let background=document.getElementById("learningmap-background-image"),backgroundurl=previewimage[0].getAttribute("src").split("?")[0];previewimage[0].getAttribute("src").split("?")[1].includes("&oid=")&&(backgroundurl+="?oid="+previewimage[0].getAttribute("src").split("&oid=")[1]),background.setAttribute("xlink:href",backgroundurl)}}function updateCSS(){_templates.default.renderForPromise("mod_learningmap/cssskeleton",_placestore.default.getPlacestore()).then((_ref=>{let{html:html,js:js}=_ref;return _templates.default.replaceNode("#learningmap-svgstyle",html,js),updateCode(),!0})).catch((ex=>(0,_notification.exception)(ex)))}function updateActivities(){let activities=_placestore.default.getAllActivities(),options=Array.from(activitySelector.getElementsByTagName("option"));activityHiddenWarning.setAttribute("hidden",""),options.forEach((function(n){activities.includes(n.value)?(n.classList.add("learningmap-used-activity"),n.selected&&1==n.getAttribute("data-activity-hidden")&&activityHiddenWarning.removeAttribute("hidden")):n.classList.remove("learningmap-used-activity")}))}function colorChooserLogic(name){let secondValue=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",colorChooser=document.getElementById("learningmap-color-"+name);colorChooser&&(colorChooser.addEventListener("change",(function(){_placestore.default.setColor(name,colorChooser.value),""!=secondValue&&_placestore.default.setColor(secondValue,colorChooser.value),updateCSS()})),colorChooser.value=_placestore.default.getColor(name))}function advancedSettingsLogic(name,getCall,setCall){let callback=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,settingItem=document.getElementById("learningmap-advanced-setting-"+name);settingItem&&(settingItem.checked=getCall.call(_placestore.default),settingItem.addEventListener("change",(function(){setCall.call(_placestore.default,settingItem.checked),null!==callback&&callback(),updateCSS()})))}function hideAdvancedSettings(){document.getElementById("learningmap-advanced-settings").setAttribute("hidden","")}function wrapInCdata(data){return""}}})); //# sourceMappingURL=learningmap.min.js.map \ No newline at end of file diff --git a/amd/build/learningmap.min.js.map b/amd/build/learningmap.min.js.map index c79bdf7..d469215 100644 --- a/amd/build/learningmap.min.js.map +++ b/amd/build/learningmap.min.js.map @@ -1 +1 @@ -{"version":3,"file":"learningmap.min.js","sources":["../src/learningmap.js"],"sourcesContent":["import {exception as displayException} from 'core/notification';\nimport Templates from 'core/templates';\nimport placestore from 'mod_learningmap/placestore';\n\nconst circleRadius = 10;\n\n// Constants for updatePathDeclaration.\nconst targetPoints = {\n firstPoint: 1,\n secondPoint: 2,\n bezierPoint: 3,\n};\n\nconst pathTypes = {\n line: 1,\n quadraticbezier: 2,\n};\n\nexport const init = () => {\n // Load the needed template on startup for better execution speed.\n Templates.prefetchTemplates(['mod_learningmap/cssskeleton']);\n\n // Variable for storing the mouse offset\n var offset;\n\n // Variable for draggable element\n var dragel;\n\n // Variables for storing the paths that need update of the first or\n // the second coordinates.\n var pathsToUpdateFirstPoint, pathsToUpdateSecondPoint;\n\n // Variables for handling the currently selected elements\n var selectedElement = null,\n firstPlace = null,\n secondPlace = null,\n lastTarget = null;\n\n // Variable for storing the selected element for the activity selector\n var elementForActivitySelector = null;\n\n // Variables for simulating double click on touch devices, set when the\n // corresponding events are handled\n var touchstart = false;\n var touchend = false;\n // Counter for touchmove events\n var touchmove = 0;\n\n // DOM nodes for the editor\n let mapdiv = document.getElementById('learningmap-editor-map');\n let code = document.getElementById('id_svgcode');\n\n // DOM nodes for the activity selector\n let activitySetting = document.getElementById('learningmap-activity-setting');\n let activitySelector = document.getElementById('learningmap-activity-selector');\n let activityStarting = document.getElementById('learningmap-activity-starting');\n let activityTarget = document.getElementById('learningmap-activity-target');\n let activityHiddenWarning = document.getElementById('learningmap-activity-hidden-warning');\n let advancedSettingsIcon = document.getElementById('learningmap-advanced-settings-icon');\n\n // Hide tree view as there is no preview file we can attach to\n let treeView = document.querySelector('.fp-viewbar .fp-vb-tree');\n if (treeView) {\n treeView.setAttribute('style', 'display: none;');\n }\n\n // Trigger click event on icon view to ensure that tree view is not active.\n let iconView = document.querySelector('.fp-viewbar .fp-vb-icons');\n if (iconView) {\n // Handle possible delay in form loading.\n setTimeout(() => {\n iconView.dispatchEvent(new Event('click'));\n }, 1000);\n }\n\n // Attach listeners to the activity selector\n if (activitySelector) {\n // Show places that are not linked to an activity\n activitySelector.addEventListener('change', function() {\n placestore.setActivityId(elementForActivitySelector, activitySelector.value);\n if (activitySelector.value) {\n let text = document.getElementById('text' + elementForActivitySelector);\n if (text) {\n text.textContent = activitySelector.querySelector('option[value=\"' + activitySelector.value + '\"]').textContent;\n }\n let title = document.getElementById('title' + elementForActivitySelector);\n if (title) {\n title.textContent =\n activitySelector.querySelector('option[value=\"' + activitySelector.value + '\"]').textContent;\n }\n document.getElementById(elementForActivitySelector).classList.remove('learningmap-emptyplace');\n } else {\n document.getElementById(elementForActivitySelector).classList.add('learningmap-emptyplace');\n }\n updateActivities();\n updateCode();\n });\n // Add / remove a place to the starting places array\n activityStarting.addEventListener('change', function() {\n if (activityStarting.checked) {\n placestore.addStartingPlace(elementForActivitySelector);\n } else {\n placestore.removeStartingPlace(elementForActivitySelector);\n }\n updateCode();\n });\n // Add / remove a place to the target places array\n activityTarget.addEventListener('change', function() {\n if (activityTarget.checked) {\n placestore.addTargetPlace(elementForActivitySelector);\n document.getElementById(elementForActivitySelector).classList.add('learningmap-targetplace');\n } else {\n placestore.removeTargetPlace(elementForActivitySelector);\n document.getElementById(elementForActivitySelector).classList.remove('learningmap-targetplace');\n }\n updateCode();\n });\n }\n\n // Load placestore values from the hidden input field\n let placestoreInput = document.getElementsByName('placestore')[0];\n if (placestoreInput) {\n placestore.loadJSON(placestoreInput.value);\n }\n\n // Mark all activities in the placestore as \"used\".\n updateActivities();\n\n // Attach listeners to the advanced settings div\n if (advancedSettingsIcon) {\n let advancedSettings = document.getElementById('learningmap-advanced-settings');\n advancedSettingsIcon.addEventListener('click', function() {\n if (advancedSettings.getAttribute('hidden') === null) {\n hideAdvancedSettings();\n } else {\n advancedSettings.removeAttribute('hidden');\n hideContextMenu();\n }\n });\n let advancedSettingsClose = document.getElementById('learningmap-advanced-settings-close');\n if (advancedSettingsClose) {\n advancedSettingsClose.addEventListener('click', function() {\n advancedSettings.setAttribute('hidden', '');\n });\n }\n\n advancedSettingsLogic('hidepaths', placestore.getHidePaths, placestore.setHidePaths);\n advancedSettingsLogic('usecheckmark', placestore.getUseCheckmark, placestore.setUseCheckmark);\n advancedSettingsLogic('hover', placestore.getHover, placestore.setHover);\n advancedSettingsLogic('pulse', placestore.getPulse, placestore.setPulse);\n advancedSettingsLogic('showall', placestore.getShowall, placestore.setShowall);\n advancedSettingsLogic('hidestroke', placestore.getHideStroke, placestore.setHideStroke);\n advancedSettingsLogic('showtext', placestore.getShowText, placestore.setShowText, fixPlaceLabels);\n advancedSettingsLogic('slicemode', placestore.getSliceMode, placestore.setSliceMode);\n advancedSettingsLogic('showwaygone', placestore.getShowWayGone, placestore.setShowWayGone);\n }\n\n // Attach listener to the color choosers\n colorChooserLogic('stroke', 'text');\n colorChooserLogic('place');\n colorChooserLogic('visited');\n\n // Get SVG code from the (hidden) textarea field\n if (code && mapdiv) {\n mapdiv.innerHTML = code.value;\n }\n // Reload background image to get the correct width and height values\n refreshBackgroundImage();\n registerBackgroundListener();\n updateCode();\n\n // Enable dragging of places\n let svg = document.getElementById('learningmap-svgmap-' + placestore.getMapid());\n makeDraggable(svg);\n\n // Refresh stylesheet values from placestore\n updateCSS();\n\n // Add listeners for clicking and context menu\n if (mapdiv) {\n mapdiv.addEventListener('dblclick', dblclickHandler);\n mapdiv.addEventListener('click', clickHandler);\n\n mapdiv.addEventListener('contextmenu', function(e) {\n e.preventDefault();\n showContextMenu(e);\n }, false);\n }\n /**\n * Shows the context menu at the current mouse position\n * @param {*} e\n */\n function showContextMenu(e) {\n unselectAll();\n hideAdvancedSettings();\n // Check for the existence of the target (could have vanished since the event started).\n if (activitySetting && document.getElementById(e.target.id) !== null) {\n if (e.touches) {\n e = e.touches[0];\n }\n if (e.target.classList.contains('learningmap-place')) {\n e.target.classList.add('learningmap-selected-activity-selector');\n let activityId = placestore.getActivityId(e.target.id);\n let scalingFactor = mapdiv.clientWidth / 800;\n activitySetting.style.setProperty('--pos-x', e.target.cx.baseVal.value * scalingFactor + 'px');\n activitySetting.style.setProperty('--pos-y', e.target.cy.baseVal.value * scalingFactor + 'px');\n activitySetting.style.setProperty('--map-width', mapdiv.clientWidth + 'px');\n activitySetting.style.setProperty('--map-height', mapdiv.clientHeight + 'px');\n activitySetting.style.display = 'block';\n document.getElementById('learningmap-activity-selector').value = activityId;\n document.getElementById('learningmap-activity-starting').checked = placestore.isStartingPlace(e.target.id);\n document.getElementById('learningmap-activity-target').checked = placestore.isTargetPlace(e.target.id);\n elementForActivitySelector = e.target.id;\n updateActivities();\n } else {\n hideContextMenu();\n hideAdvancedSettings();\n }\n }\n }\n\n /**\n * Hides the context menu\n */\n function hideContextMenu() {\n let e = document.getElementById(elementForActivitySelector);\n if (e) {\n e.classList.remove('learningmap-selected-activity-selector');\n }\n activitySetting.style.display = 'none';\n }\n\n let backgroundfileNode = document.getElementById('id_backgroundfile_fieldset');\n if (backgroundfileNode) {\n let observer = new MutationObserver(refreshBackgroundImage);\n observer.observe(backgroundfileNode, {attributes: true, childList: true, subtree: true});\n }\n\n /**\n * Helper function for getting the right coordinates from the mouse\n * @param {*} evt\n * @returns {object}\n */\n function getMousePosition(evt) {\n if (evt.touches) {\n evt = evt.touches[0];\n }\n return transformCoordinates(evt.clientX, evt.clientY);\n }\n\n /**\n * Transforms client coordinates to SVG coordinates\n * @param {number} x x coordinate to transform\n * @param {number} y y coordinate to transform\n * @returns {object} Object containing transformed x and y coordinate\n */\n function transformCoordinates(x, y) {\n var CTM = dragel.getScreenCTM();\n return {\n x: (x - CTM.e) / CTM.a,\n y: (y - CTM.f) / CTM.d\n };\n }\n\n /**\n * Enables dragging on an DOM node\n * @param {*} el\n */\n function makeDraggable(el) {\n dragel = el;\n if (el) {\n el.addEventListener('mousedown', startDrag);\n el.addEventListener('mousemove', drag);\n el.addEventListener('mouseup', endDrag);\n el.addEventListener('mouseleave', endDrag);\n el.addEventListener('touchstart', startTouch);\n el.addEventListener('touchmove', drag);\n el.addEventListener('touchend', endTouch);\n el.addEventListener('touchleave', endTouch);\n el.addEventListener('touchcancel', endTouch);\n }\n\n /**\n * Function called whenn dragging starts.\n * @param {*} evt\n */\n function startDrag(evt) {\n if (evt.cancelable) {\n evt.preventDefault();\n }\n pathsToUpdateFirstPoint = [];\n pathsToUpdateSecondPoint = [];\n if (evt.target.classList.contains('learningmap-draggable')) {\n selectedElement = evt.target;\n offset = getMousePosition(evt);\n offset.x -= parseInt(selectedElement.getAttributeNS(null, \"cx\"));\n offset.y -= parseInt(selectedElement.getAttributeNS(null, \"cy\"));\n // Get paths that need to be updated.\n pathsToUpdateFirstPoint = placestore.getPathsWithFid(selectedElement.id);\n pathsToUpdateSecondPoint = placestore.getPathsWithSid(selectedElement.id);\n } else if (evt.target.nodeName == 'text') {\n selectedElement = evt.target;\n let place = selectedElement.parentNode.querySelector('.learningmap-place');\n offset = getMousePosition(evt);\n offset.x -= parseInt(selectedElement.getAttributeNS(null, \"dx\")) + place.cx.baseVal.value;\n offset.y -= parseInt(selectedElement.getAttributeNS(null, \"dy\")) + place.cy.baseVal.value;\n } else if (evt.target.nodeName == 'path') {\n selectedElement = evt.target;\n offset = getMousePosition(evt);\n let pathPoint = transformCoordinates(evt.layerX, evt.layerY);\n offset.x += pathPoint.x;\n offset.y += pathPoint.y;\n }\n }\n\n /**\n * Function called during dragging. Continuously updates circles center coordinates and the\n * coordinates of the touching paths.\n * @param {*} evt\n */\n function drag(evt) {\n if (evt.cancelable) {\n evt.preventDefault();\n }\n // Count touchmove events\n touchmove++;\n if (selectedElement) {\n var coord = getMousePosition(evt);\n let cx = coord.x - offset.x;\n let cy = coord.y - offset.y;\n if (selectedElement.nodeName == 'text') {\n let place = selectedElement.parentNode.querySelector('.learningmap-place');\n // Calculate the delta from the current mouse position to the corresponding place.\n // coord: current mouse position\n // offset: delta from the mouse position to the coordinates of the text node\n let dx = coord.x - offset.x - place.cx.baseVal.value;\n let dy = coord.y - offset.y - place.cy.baseVal.value;\n selectedElement.setAttributeNS(null, \"dx\", dx);\n selectedElement.setAttributeNS(null, \"dy\", dy);\n }\n if (selectedElement.nodeName == 'path') {\n selectedElement.setAttribute(\n 'd',\n updatePathDeclaration(selectedElement.getAttribute('d'), coord.x, coord.y, targetPoints.bezierPoint)\n );\n }\n if (selectedElement.nodeName == 'circle') {\n selectedElement.setAttributeNS(null, \"cx\", cx);\n selectedElement.setAttributeNS(null, \"cy\", cy);\n let textNode = document.getElementById('text' + selectedElement.id);\n if (textNode !== null) {\n textNode.setAttributeNS(null, 'x', cx);\n textNode.setAttributeNS(null, 'y', cy);\n }\n pathsToUpdateFirstPoint.forEach(function(path) {\n let pathNode = document.getElementById(path.id);\n if (pathNode !== null) {\n if (pathNode.nodeName == 'path') {\n pathNode.setAttribute(\n 'd',\n updatePathDeclaration(pathNode.getAttribute('d'), cx, cy, targetPoints.firstPoint)\n );\n } else {\n pathNode.setAttribute('x1', cx);\n pathNode.setAttribute('y1', cy);\n }\n }\n });\n\n pathsToUpdateSecondPoint.forEach(function(path) {\n let pathNode = document.getElementById(path.id);\n if (pathNode !== null) {\n if (pathNode.nodeName == 'path') {\n pathNode.setAttribute(\n 'd',\n updatePathDeclaration(pathNode.getAttribute('d'), cx, cy, targetPoints.secondPoint)\n );\n } else {\n pathNode.setAttribute('x2', cx);\n pathNode.setAttribute('y2', cy);\n }\n }\n });\n }\n }\n }\n\n /**\n * Function called when dragging ends.\n * @param {*} evt\n */\n function endDrag(evt) {\n if (evt.cancelable) {\n evt.preventDefault();\n }\n selectedElement = null;\n unselectAll();\n updateCode();\n }\n\n /**\n * Function called when touchstart event occurs.\n * @param {*} evt\n */\n function startTouch(evt) {\n if (evt.cancelable) {\n evt.preventDefault();\n }\n if (\n evt.target.classList.contains('learningmap-draggable') ||\n evt.target.nodeName == 'text' ||\n evt.target.nodeName == 'path'\n ) {\n if (!touchstart) {\n touchstart = true;\n touchmove = 0;\n touchend = false;\n setTimeout(\n (evt) => {\n if (touchmove < 3 && !touchend) {\n if (evt.touches) {\n evt = evt.touches[0];\n }\n showContextMenu(evt);\n }\n },\n 2000,\n evt\n );\n setTimeout(\n () => {\n touchstart = false;\n },\n 300);\n } else {\n dblclickHandler(evt);\n touchstart = false;\n }\n startDrag(evt);\n } else {\n if (!touchstart) {\n touchstart = true;\n touchend = false;\n touchmove = 0;\n setTimeout(\n () => {\n touchstart = false;\n },\n 300);\n } else {\n dblclickHandler(evt);\n touchstart = false;\n }\n }\n }\n\n /**\n * Function called when touchend, touchleave or touchcancel event occurs.\n * @param {*} evt\n */\n function endTouch(evt) {\n selectedElement = null;\n touchend = true;\n // If there was only a small move (<3 move events), this also counts as a click.\n if (touchmove < 3 && touchstart) {\n clickHandler(evt);\n } else {\n endDrag(evt);\n }\n if (evt.cancelable) {\n evt.preventDefault();\n }\n }\n\n /**\n * Updates the path declaration of lines and quadratic bezier curves setting one of the points.\n * @param {string} oldDefinition SVG path definition string\n * @param {number} targetX x coordinate of the point to set\n * @param {number} targetY y coordinate of the point to set\n * @param {number} targetP Which point to change (you can use the targetPoints constants here)\n * @returns {string} Updated SVG path definition\n */\n function updatePathDeclaration(oldDefinition, targetX, targetY, targetP = targetPoints.firstPoint) {\n let parts = oldDefinition.split(' ');\n let fromX = 0;\n let fromY = 0;\n let toX = 0;\n let toY = 0;\n let bezierX = 0;\n let bezierY = 0;\n let pathType = pathTypes.line;\n\n // The d attribute of an SVG path in a learning map can have two different formats (in this version):\n // \"M x1 y1 L x2 y2\" Line from x1, y1 to x2, y2\n // \"M x1 y2 Q x3 y3 x2 y2\" Quadratic bezier curve inside the triangle defined by x1, y1, x2, y2 and x3, y3.\n for (let i = 0; i < parts.length; i++) {\n // Every path contains the first point in that way.\n if (parts[i] == 'M') {\n fromX = parseInt(parts[i + 1]);\n fromY = parseInt(parts[i + 2]);\n i += 2;\n }\n // This path is a direct line, so there are only two points in total.\n if (parts[i] == 'L') {\n toX = parseInt(parts[i + 1]);\n toY = parseInt(parts[i + 2]);\n i += 2;\n }\n // This path is a bezier curve, there are three points in total.\n if (parts[i] == 'Q') {\n bezierX = parseInt(parts[i + 1]);\n bezierY = parseInt(parts[i + 2]);\n toX = parseInt(parts[i + 3]);\n toY = parseInt(parts[i + 4]);\n i += 4;\n pathType = pathTypes.quadraticbezier;\n }\n }\n\n switch (targetP) {\n case targetPoints.firstPoint:\n fromX = targetX;\n fromY = targetY;\n break;\n case targetPoints.secondPoint:\n toX = targetX;\n toY = targetY;\n break;\n case targetPoints.bezierPoint:\n // Calculate the third triangle point for the bezier curve.\n bezierX = targetX * 2 - (fromX + toX) * 0.5;\n bezierY = targetY * 2 - (fromY + toY) * 0.5;\n pathType = pathTypes.quadraticbezier;\n break;\n }\n\n if (pathType == pathTypes.quadraticbezier) {\n return 'M ' + fromX + ' ' + fromY + ' Q ' + bezierX + ' ' + bezierY + ', ' + toX + ' ' + toY;\n } else {\n return 'M ' + fromX + ' ' + fromY + ' L ' + toX + ' ' + toY;\n }\n }\n }\n\n /**\n * Updates the form fields for the SVG code and the placestore from the editor.\n */\n function updateCode() {\n if (code && mapdiv) {\n code.innerHTML = mapdiv.innerHTML;\n }\n if (placestoreInput) {\n document.getElementsByName('placestore')[0].value = JSON.stringify(placestore.getPlacestore());\n }\n }\n\n /**\n * Handles double clicks on the map\n * @param {*} event\n */\n function dblclickHandler(event) {\n hideContextMenu();\n hideAdvancedSettings();\n unselectAll();\n if (event.target.classList.contains('learningmap-mapcontainer') ||\n event.target.classList.contains('learningmap-background-image')) {\n addPlace(event);\n } else if (event.target.classList.contains('learningmap-place')) {\n if (lastTarget == event.target.id) {\n lastTarget = null;\n clickHandler(event);\n } else {\n removePlace(event);\n }\n } else if (event.target.classList.contains('learningmap-path')) {\n removePath(event.target.id);\n }\n updateCode();\n }\n\n /**\n * Returns an empty title tag with the given id.\n * @param {*} id id for the title\n * @returns {any}\n */\n function title(id) {\n let title = document.createElementNS('http://www.w3.org/2000/svg', 'title');\n title.setAttribute('id', id);\n return title;\n }\n\n /**\n * Returns an text tag with the given id.\n * @param {*} id id for the text\n * @param {*} content content of the tag\n * @param {*} x x coordinate of the text\n * @param {*} y y coordinate of the text\n * @returns {any}\n */\n function text(id, content, x, y) {\n let text = document.createElementNS('http://www.w3.org/2000/svg', 'text');\n text.setAttribute('id', id);\n text.setAttribute('x', x);\n text.setAttribute('y', y);\n // Default value for delta: Circle radius * 1.5 (as a padding)\n text.setAttribute('dx', circleRadius * 1.5);\n text.setAttribute('dy', circleRadius * 1.5);\n text.textContent = content;\n return text;\n }\n\n /**\n * Returns a circle tag with the given dimensions.\n * @param {*} x x coordinate of the center\n * @param {*} y y coordinate of the center\n * @param {*} r radius\n * @param {*} classes classes to add\n * @param {*} id id of the circle\n * @returns {any}\n */\n function circle(x, y, r, classes, id) {\n let circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');\n circle.setAttribute('class', classes);\n circle.setAttribute('id', id);\n circle.setAttribute('cx', x);\n circle.setAttribute('cy', y);\n circle.setAttribute('r', r);\n return circle;\n }\n\n /**\n * Returns a path between two points.\n * @param {*} x1 x coordinate of the first point\n * @param {*} y1 y coordinate of the first point\n * @param {*} x2 x coordinate of the second point\n * @param {*} y2 y coordinate of the second point\n * @param {*} classes CSS classes to set\n * @param {*} id id of the path\n * @returns {any}\n */\n function path(x1, y1, x2, y2, classes, id) {\n let path = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n path.setAttribute('class', classes);\n path.setAttribute('id', id);\n path.setAttribute('d', 'M ' + x1 + ' ' + y1 + ' L ' + x2 + ' ' + y2);\n return path;\n }\n\n /**\n * Returns a link around a given child element. This function also adds a title element next\n * to the child for accessibility.\n * @param {*} child child item to set the link on\n * @param {*} id id of the link\n * @param {*} title title of the link\n * @param {*} text text to describe the link\n * @returns {any}\n */\n function link(child, id, title = null, text = null) {\n let link = document.createElementNS('http://www.w3.org/2000/svg', 'a');\n link.setAttribute('id', id);\n link.setAttribute('xlink:href', '');\n link.appendChild(child);\n if (title !== null) {\n link.appendChild(title);\n }\n if (text !== null) {\n link.appendChild(text);\n }\n return link;\n }\n\n /**\n * Adds a place on the SVG map. This function also prepares the code for linking activities\n * and adding titles (for accessibility).\n * @param {*} event event causing the command\n */\n function addPlace(event) {\n let placesgroup = document.getElementById('placesGroup');\n let placeId = 'p' + placestore.getId();\n let linkId = 'a' + placestore.getId();\n var CTM = event.target.getScreenCTM();\n if (event.touches) {\n event = event.touches[0];\n }\n let cx = (event.clientX - CTM.e) / CTM.a;\n let cy = (event.clientY - CTM.f) / CTM.d;\n placesgroup.appendChild(\n link(\n circle(cx, cy, circleRadius, 'learningmap-place learningmap-draggable learningmap-emptyplace', placeId),\n linkId,\n title('title' + placeId),\n text('text' + placeId, '', cx, cy)\n )\n );\n placestore.addPlace(placeId, linkId);\n }\n\n /**\n * Handles single clicks on the background image.\n * @param {*} event click event\n * @returns {void}\n */\n function clickHandler(event) {\n event.preventDefault();\n hideContextMenu();\n hideAdvancedSettings();\n if (event.target.classList.contains('learningmap-place') && selectedElement === null) {\n if (firstPlace === null) {\n firstPlace = event.target.id;\n document.getElementById(firstPlace).classList.add('learningmap-selected');\n } else {\n secondPlace = event.target.id;\n let fid = parseInt(firstPlace.replace('p', ''));\n let sid = parseInt(secondPlace.replace('p', ''));\n if (sid == fid) {\n return;\n }\n if (sid < fid) {\n let z = sid;\n sid = fid;\n fid = z;\n }\n addPath(fid, sid);\n let first = document.getElementById(firstPlace);\n if (first) {\n first.classList.remove('learningmap-selected');\n }\n firstPlace = null;\n lastTarget = secondPlace;\n secondPlace = null;\n }\n } else {\n unselectAll();\n firstPlace = null;\n }\n }\n /**\n * Removes the classes 'learningmap-selected' and 'learningmap-selectet-activity-selector'\n * from all nodes\n */\n function unselectAll() {\n Array.from(document.getElementsByClassName('learningmap-selected')).forEach(function(e) {\n e.classList.remove('learningmap-selected');\n });\n Array.from(document.getElementsByClassName('learningmap-selected-activity-selector')).forEach(function(e) {\n e.classList.remove('learningmap-selected-activity-selector');\n });\n }\n\n /**\n * Adds a path between two places.\n * @param {number} fid id of the first place (meant to be the smaller one)\n * @param {number} sid id of the second place (meant to be the bigger one)\n */\n function addPath(fid, sid) {\n let pid = 'p' + fid + '_' + sid;\n if (document.getElementById(pid) === null) {\n let pathsgroup = document.getElementById('pathsGroup');\n let first = document.getElementById('p' + fid);\n let second = document.getElementById('p' + sid);\n if (pathsgroup && first && second) {\n pathsgroup.appendChild(\n path(\n first.cx.baseVal.value,\n first.cy.baseVal.value,\n second.cx.baseVal.value,\n second.cy.baseVal.value,\n 'learningmap-path',\n pid\n )\n );\n placestore.addPath(pid, 'p' + fid, 'p' + sid);\n }\n }\n }\n\n /**\n * Removes a place from the SVG and the placestore. This function also removes all\n * touching paths and entries in statringplaces / targetplaces linking to the removed\n * place.\n * @param {any} event event causing the remove order\n */\n function removePlace(event) {\n let place = document.getElementById(event.target.id);\n let parent = place.parentNode;\n removePathsTouchingPlace(event.target.id);\n placestore.removePlace(event.target.id);\n parent.removeChild(place);\n parent.parentNode.removeChild(parent);\n\n updateCode();\n }\n\n /**\n * Removes all paths touching a certain place\n * @param {number} id id of the place\n */\n function removePathsTouchingPlace(id) {\n placestore.getTouchingPaths(id).forEach(\n function(e) {\n removePath(e.id);\n }\n );\n }\n\n /**\n * Removes a path from the SVG and from the placestore\n * @param {number} id id of the path\n */\n function removePath(id) {\n let path = document.getElementById(id);\n if (path !== null) {\n path.parentNode.removeChild(path);\n placestore.removePath(id);\n }\n }\n\n /**\n * Sets the background image of the SVG to the current image in filemanager.\n */\n function refreshBackgroundImage() {\n let previewimage = document.getElementsByClassName('realpreview');\n if (previewimage.length > 0) {\n let background = document.getElementById('learningmap-background-image');\n let backgroundurl = previewimage[0].getAttribute('src').split('?')[0];\n // If the uploaded file reuses the filename of a previously uploaded image, they differ\n // only in the oid. So one has to append the oid to the url.\n if (previewimage[0].getAttribute('src').split('?')[1].includes('&oid=')) {\n backgroundurl += '?oid=' + previewimage[0].getAttribute('src').split('&oid=')[1];\n }\n background.setAttribute('xlink:href', backgroundurl);\n }\n }\n\n /**\n * Adds an eventListener to the background image for watching file changes and updating\n * height and width of the image.\n */\n function registerBackgroundListener() {\n let background = document.getElementById('learningmap-background-image');\n if (background) {\n background.addEventListener('load', function() {\n background.removeAttribute('height');\n let height = parseInt(background.getBBox().height);\n let width = background.getBBox().width;\n placestore.setBackgroundDimensions(width, height);\n svg.setAttribute('viewBox', '0 0 ' + placestore.width + ' ' + placestore.height);\n background.setAttribute('width', width);\n background.setAttribute('height', height);\n updateCode();\n });\n }\n }\n\n /**\n * Updates CSS code inside the SVG (called, when one of the colors is changed).\n * Calls updateCode() when completed.\n */\n function updateCSS() {\n Templates.renderForPromise('mod_learningmap/cssskeleton', placestore.getPlacestore())\n .then(({html, js}) => {\n Templates.replaceNode('#learningmap-svgstyle', html, js);\n updateCode();\n return true;\n })\n .catch(ex => displayException(ex));\n }\n\n /**\n * Updates the activity selector to highlight the activities already used\n * and to show the alert for hidden activities.\n */\n function updateActivities() {\n let activities = placestore.getAllActivities();\n let options = Array.from(activitySelector.getElementsByTagName('option'));\n activityHiddenWarning.setAttribute('hidden', '');\n options.forEach(function(n) {\n if (activities.includes(n.value)) {\n n.classList.add('learningmap-used-activity');\n if (n.selected) {\n if (n.getAttribute('data-activity-hidden') == true) {\n activityHiddenWarning.removeAttribute('hidden');\n }\n }\n } else {\n n.classList.remove('learningmap-used-activity');\n }\n });\n }\n\n /**\n * Adds the event listener to the color chooser buttons.\n * @param {*} name name of the color\n * @param {*} secondValue name of a second placestore value that has to be changed along\n */\n function colorChooserLogic(name, secondValue = '') {\n let colorChooser = document.getElementById('learningmap-color-' + name);\n if (colorChooser) {\n colorChooser.addEventListener('change', function() {\n placestore.setColor(name, colorChooser.value);\n if (secondValue != '') {\n placestore.setColor(secondValue, colorChooser.value);\n }\n updateCSS();\n });\n colorChooser.value = placestore.getColor(name);\n }\n }\n\n /**\n * Adds the event listener to advanced settings menu items\n * @param {*} name Name of the item\n * @param {*} getCall Method of placestore to call to read value\n * @param {*} setCall Method of placestore to call to save value\n * @param {*} callback Additional callback after value is saved\n */\n function advancedSettingsLogic(name, getCall, setCall, callback = null) {\n let settingItem = document.getElementById('learningmap-advanced-setting-' + name);\n if (settingItem) {\n settingItem.checked = getCall.call(placestore);\n settingItem.addEventListener('change', function() {\n setCall.call(placestore, settingItem.checked);\n if (callback !== null) {\n callback();\n }\n updateCSS();\n });\n }\n }\n\n /**\n * Adds missing text nodes\n */\n function fixPlaceLabels() {\n let options = Array.from(activitySelector.getElementsByTagName('option'));\n let places = placestore.getPlaces();\n for (const place of places) {\n if (document.getElementById('text' + place.id) === null) {\n let content = '';\n for (const option of options) {\n if (option.value == place.linkedActivity) {\n content = option.textContent;\n break;\n }\n }\n let placeNode = document.getElementById(place.id);\n let textNode = text('text' + place.id, content, placeNode.cx.baseVal.value, placeNode.cy.baseVal.value);\n placeNode.parentNode.appendChild(textNode);\n }\n }\n }\n\n /**\n * Hides the advanced settings menu.\n */\n function hideAdvancedSettings() {\n let advancedSettings = document.getElementById('learningmap-advanced-settings');\n advancedSettings.setAttribute('hidden', '');\n }\n};\n"],"names":["targetPoints","pathTypes","offset","dragel","pathsToUpdateFirstPoint","pathsToUpdateSecondPoint","prefetchTemplates","selectedElement","firstPlace","secondPlace","lastTarget","elementForActivitySelector","touchstart","touchend","touchmove","mapdiv","document","getElementById","code","activitySetting","activitySelector","activityStarting","activityTarget","activityHiddenWarning","advancedSettingsIcon","treeView","querySelector","setAttribute","iconView","setTimeout","dispatchEvent","Event","addEventListener","setActivityId","value","text","textContent","title","classList","remove","add","updateActivities","updateCode","checked","addStartingPlace","removeStartingPlace","addTargetPlace","removeTargetPlace","placestoreInput","getElementsByName","loadJSON","advancedSettings","getAttribute","hideAdvancedSettings","removeAttribute","hideContextMenu","advancedSettingsClose","advancedSettingsLogic","placestore","getHidePaths","setHidePaths","getUseCheckmark","setUseCheckmark","getHover","setHover","getPulse","setPulse","getShowall","setShowall","getHideStroke","setHideStroke","getShowText","setShowText","options","Array","from","getElementsByTagName","places","getPlaces","place","id","content","option","linkedActivity","placeNode","textNode","cx","baseVal","cy","parentNode","appendChild","getSliceMode","setSliceMode","getShowWayGone","setShowWayGone","colorChooserLogic","innerHTML","refreshBackgroundImage","background","height","parseInt","getBBox","width","setBackgroundDimensions","svg","registerBackgroundListener","getMapid","showContextMenu","e","unselectAll","target","touches","contains","activityId","getActivityId","scalingFactor","clientWidth","style","setProperty","clientHeight","display","isStartingPlace","isTargetPlace","el","startDrag","drag","endDrag","evt","cancelable","preventDefault","nodeName","dblclickHandler","endTouch","getMousePosition","x","getAttributeNS","y","getPathsWithFid","getPathsWithSid","pathPoint","transformCoordinates","layerX","layerY","coord","dx","dy","setAttributeNS","updatePathDeclaration","forEach","path","pathNode","clickHandler","oldDefinition","targetX","targetY","targetP","parts","split","fromX","fromY","toX","toY","bezierX","bezierY","pathType","i","length","makeDraggable","updateCSS","backgroundfileNode","MutationObserver","observe","attributes","childList","subtree","clientX","clientY","CTM","getScreenCTM","a","f","d","JSON","stringify","getPlacestore","event","placesgroup","placeId","getId","linkId","child","link","createElementNS","r","classes","circle","addPlace","parent","getTouchingPaths","removePath","removePlace","removeChild","circleRadius","fid","replace","sid","z","pid","pathsgroup","first","second","x1","y1","x2","y2","addPath","getElementsByClassName","previewimage","backgroundurl","includes","renderForPromise","then","_ref","html","js","replaceNode","catch","ex","activities","getAllActivities","n","selected","name","secondValue","colorChooser","setColor","getColor","getCall","setCall","callback","settingItem","call"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"learningmap.min.js","sources":["../src/learningmap.js"],"sourcesContent":["import {exception as displayException} from 'core/notification';\nimport Templates from 'core/templates';\nimport placestore from 'mod_learningmap/placestore';\n\nconst circleRadius = 10;\n\n// Constants for updatePathDeclaration.\nconst targetPoints = {\n firstPoint: 1,\n secondPoint: 2,\n bezierPoint: 3,\n};\n\nconst pathTypes = {\n line: 1,\n quadraticbezier: 2,\n};\n\nexport const init = () => {\n // Load the needed template on startup for better execution speed.\n Templates.prefetchTemplates(['mod_learningmap/cssskeleton']);\n\n // Variable for storing the mouse offset\n var offset;\n\n // Variable for draggable element\n var dragel;\n\n // Variables for storing the paths that need update of the first or\n // the second coordinates.\n var pathsToUpdateFirstPoint, pathsToUpdateSecondPoint;\n\n // Variables for handling the currently selected elements\n var selectedElement = null,\n firstPlace = null,\n secondPlace = null,\n lastTarget = null;\n\n // Variable for storing the selected element for the activity selector\n var elementForActivitySelector = null;\n\n // Variables for simulating double click on touch devices, set when the\n // corresponding events are handled\n var touchstart = false;\n var touchend = false;\n // Counter for touchmove events\n var touchmove = 0;\n\n // DOM nodes for the editor\n let mapdiv = document.getElementById('learningmap-editor-map');\n let code = document.getElementById('id_svgcode');\n\n // DOM nodes for the activity selector\n let activitySetting = document.getElementById('learningmap-activity-setting');\n let activitySelector = document.getElementById('learningmap-activity-selector');\n let activityStarting = document.getElementById('learningmap-activity-starting');\n let activityTarget = document.getElementById('learningmap-activity-target');\n let activityHiddenWarning = document.getElementById('learningmap-activity-hidden-warning');\n let advancedSettingsIcon = document.getElementById('learningmap-advanced-settings-icon');\n\n // Hide tree view as there is no preview file we can attach to\n let treeView = document.querySelector('.fp-viewbar .fp-vb-tree');\n if (treeView) {\n treeView.setAttribute('style', 'display: none;');\n }\n\n // Trigger click event on icon view to ensure that tree view is not active.\n let iconView = document.querySelector('.fp-viewbar .fp-vb-icons');\n if (iconView) {\n // Handle possible delay in form loading.\n setTimeout(() => {\n iconView.dispatchEvent(new Event('click'));\n }, 1000);\n }\n\n // Attach listeners to the activity selector\n if (activitySelector) {\n // Show places that are not linked to an activity\n activitySelector.addEventListener('change', function() {\n placestore.setActivityId(elementForActivitySelector, activitySelector.value);\n if (activitySelector.value) {\n let text = document.getElementById('text' + elementForActivitySelector);\n if (text) {\n text.textContent = wrapInCdata(\n activitySelector.querySelector('option[value=\"' + activitySelector.value + '\"]').textContent\n );\n }\n let title = document.getElementById('title' + elementForActivitySelector);\n if (title) {\n title.textContent = wrapInCdata(\n activitySelector.querySelector('option[value=\"' + activitySelector.value + '\"]').textContent\n );\n }\n document.getElementById(elementForActivitySelector).classList.remove('learningmap-emptyplace');\n } else {\n document.getElementById(elementForActivitySelector).classList.add('learningmap-emptyplace');\n }\n updateActivities();\n updateCode();\n });\n // Add / remove a place to the starting places array\n activityStarting.addEventListener('change', function() {\n if (activityStarting.checked) {\n placestore.addStartingPlace(elementForActivitySelector);\n } else {\n placestore.removeStartingPlace(elementForActivitySelector);\n }\n updateCode();\n });\n // Add / remove a place to the target places array\n activityTarget.addEventListener('change', function() {\n if (activityTarget.checked) {\n placestore.addTargetPlace(elementForActivitySelector);\n document.getElementById(elementForActivitySelector).classList.add('learningmap-targetplace');\n } else {\n placestore.removeTargetPlace(elementForActivitySelector);\n document.getElementById(elementForActivitySelector).classList.remove('learningmap-targetplace');\n }\n updateCode();\n });\n }\n\n // Load placestore values from the hidden input field\n let placestoreInput = document.getElementsByName('placestore')[0];\n if (placestoreInput) {\n placestore.loadJSON(placestoreInput.value);\n }\n\n // Mark all activities in the placestore as \"used\".\n updateActivities();\n\n // Attach listeners to the advanced settings div\n if (advancedSettingsIcon) {\n let advancedSettings = document.getElementById('learningmap-advanced-settings');\n advancedSettingsIcon.addEventListener('click', function() {\n if (advancedSettings.getAttribute('hidden') === null) {\n hideAdvancedSettings();\n } else {\n advancedSettings.removeAttribute('hidden');\n hideContextMenu();\n }\n });\n let advancedSettingsClose = document.getElementById('learningmap-advanced-settings-close');\n if (advancedSettingsClose) {\n advancedSettingsClose.addEventListener('click', function() {\n advancedSettings.setAttribute('hidden', '');\n });\n }\n\n advancedSettingsLogic('hidepaths', placestore.getHidePaths, placestore.setHidePaths);\n advancedSettingsLogic('usecheckmark', placestore.getUseCheckmark, placestore.setUseCheckmark);\n advancedSettingsLogic('hover', placestore.getHover, placestore.setHover);\n advancedSettingsLogic('pulse', placestore.getPulse, placestore.setPulse);\n advancedSettingsLogic('showall', placestore.getShowall, placestore.setShowall);\n advancedSettingsLogic('hidestroke', placestore.getHideStroke, placestore.setHideStroke);\n advancedSettingsLogic('showtext', placestore.getShowText, placestore.setShowText, fixPlaceLabels);\n advancedSettingsLogic('slicemode', placestore.getSliceMode, placestore.setSliceMode);\n advancedSettingsLogic('showwaygone', placestore.getShowWayGone, placestore.setShowWayGone);\n }\n\n // Attach listener to the color choosers\n colorChooserLogic('stroke', 'text');\n colorChooserLogic('place');\n colorChooserLogic('visited');\n\n // Get SVG code from the (hidden) textarea field\n if (code && mapdiv) {\n mapdiv.innerHTML = code.value;\n }\n // Reload background image to get the correct width and height values\n refreshBackgroundImage();\n registerBackgroundListener();\n updateCode();\n\n // Enable dragging of places\n let svg = document.getElementById('learningmap-svgmap-' + placestore.getMapid());\n makeDraggable(svg);\n\n // Refresh stylesheet values from placestore\n updateCSS();\n\n // Add listeners for clicking and context menu\n if (mapdiv) {\n mapdiv.addEventListener('dblclick', dblclickHandler);\n mapdiv.addEventListener('click', clickHandler);\n\n mapdiv.addEventListener('contextmenu', function(e) {\n e.preventDefault();\n showContextMenu(e);\n }, false);\n }\n /**\n * Shows the context menu at the current mouse position\n * @param {*} e\n */\n function showContextMenu(e) {\n unselectAll();\n hideAdvancedSettings();\n // Check for the existence of the target (could have vanished since the event started).\n if (activitySetting && document.getElementById(e.target.id) !== null) {\n if (e.touches) {\n e = e.touches[0];\n }\n if (e.target.classList.contains('learningmap-place')) {\n e.target.classList.add('learningmap-selected-activity-selector');\n let activityId = placestore.getActivityId(e.target.id);\n let scalingFactor = mapdiv.clientWidth / 800;\n activitySetting.style.setProperty('--pos-x', e.target.cx.baseVal.value * scalingFactor + 'px');\n activitySetting.style.setProperty('--pos-y', e.target.cy.baseVal.value * scalingFactor + 'px');\n activitySetting.style.setProperty('--map-width', mapdiv.clientWidth + 'px');\n activitySetting.style.setProperty('--map-height', mapdiv.clientHeight + 'px');\n activitySetting.style.display = 'block';\n document.getElementById('learningmap-activity-selector').value = activityId;\n document.getElementById('learningmap-activity-starting').checked = placestore.isStartingPlace(e.target.id);\n document.getElementById('learningmap-activity-target').checked = placestore.isTargetPlace(e.target.id);\n elementForActivitySelector = e.target.id;\n updateActivities();\n } else {\n hideContextMenu();\n hideAdvancedSettings();\n }\n }\n }\n\n /**\n * Hides the context menu\n */\n function hideContextMenu() {\n let e = document.getElementById(elementForActivitySelector);\n if (e) {\n e.classList.remove('learningmap-selected-activity-selector');\n }\n activitySetting.style.display = 'none';\n }\n\n let backgroundfileNode = document.getElementById('id_backgroundfile_fieldset');\n if (backgroundfileNode) {\n let observer = new MutationObserver(refreshBackgroundImage);\n observer.observe(backgroundfileNode, {attributes: true, childList: true, subtree: true});\n }\n\n /**\n * Helper function for getting the right coordinates from the mouse\n * @param {*} evt\n * @returns {object}\n */\n function getMousePosition(evt) {\n if (evt.touches) {\n evt = evt.touches[0];\n }\n return transformCoordinates(evt.clientX, evt.clientY);\n }\n\n /**\n * Transforms client coordinates to SVG coordinates\n * @param {number} x x coordinate to transform\n * @param {number} y y coordinate to transform\n * @returns {object} Object containing transformed x and y coordinate\n */\n function transformCoordinates(x, y) {\n var CTM = dragel.getScreenCTM();\n return {\n x: (x - CTM.e) / CTM.a,\n y: (y - CTM.f) / CTM.d\n };\n }\n\n /**\n * Enables dragging on an DOM node\n * @param {*} el\n */\n function makeDraggable(el) {\n dragel = el;\n if (el) {\n el.addEventListener('mousedown', startDrag);\n el.addEventListener('mousemove', drag);\n el.addEventListener('mouseup', endDrag);\n el.addEventListener('mouseleave', endDrag);\n el.addEventListener('touchstart', startTouch);\n el.addEventListener('touchmove', drag);\n el.addEventListener('touchend', endTouch);\n el.addEventListener('touchleave', endTouch);\n el.addEventListener('touchcancel', endTouch);\n }\n\n /**\n * Function called whenn dragging starts.\n * @param {*} evt\n */\n function startDrag(evt) {\n if (evt.cancelable) {\n evt.preventDefault();\n }\n pathsToUpdateFirstPoint = [];\n pathsToUpdateSecondPoint = [];\n if (evt.target.classList.contains('learningmap-draggable')) {\n selectedElement = evt.target;\n offset = getMousePosition(evt);\n offset.x -= parseInt(selectedElement.getAttributeNS(null, \"cx\"));\n offset.y -= parseInt(selectedElement.getAttributeNS(null, \"cy\"));\n // Get paths that need to be updated.\n pathsToUpdateFirstPoint = placestore.getPathsWithFid(selectedElement.id);\n pathsToUpdateSecondPoint = placestore.getPathsWithSid(selectedElement.id);\n } else if (evt.target.nodeName == 'text') {\n selectedElement = evt.target;\n let place = selectedElement.parentNode.querySelector('.learningmap-place');\n offset = getMousePosition(evt);\n offset.x -= parseInt(selectedElement.getAttributeNS(null, \"dx\")) + place.cx.baseVal.value;\n offset.y -= parseInt(selectedElement.getAttributeNS(null, \"dy\")) + place.cy.baseVal.value;\n } else if (evt.target.nodeName == 'path') {\n selectedElement = evt.target;\n offset = getMousePosition(evt);\n let pathPoint = transformCoordinates(evt.layerX, evt.layerY);\n offset.x += pathPoint.x;\n offset.y += pathPoint.y;\n }\n }\n\n /**\n * Function called during dragging. Continuously updates circles center coordinates and the\n * coordinates of the touching paths.\n * @param {*} evt\n */\n function drag(evt) {\n if (evt.cancelable) {\n evt.preventDefault();\n }\n // Count touchmove events\n touchmove++;\n if (selectedElement) {\n var coord = getMousePosition(evt);\n let cx = coord.x - offset.x;\n let cy = coord.y - offset.y;\n if (selectedElement.nodeName == 'text') {\n let place = selectedElement.parentNode.querySelector('.learningmap-place');\n // Calculate the delta from the current mouse position to the corresponding place.\n // coord: current mouse position\n // offset: delta from the mouse position to the coordinates of the text node\n let dx = coord.x - offset.x - place.cx.baseVal.value;\n let dy = coord.y - offset.y - place.cy.baseVal.value;\n selectedElement.setAttributeNS(null, \"dx\", dx);\n selectedElement.setAttributeNS(null, \"dy\", dy);\n }\n if (selectedElement.nodeName == 'path') {\n selectedElement.setAttribute(\n 'd',\n updatePathDeclaration(selectedElement.getAttribute('d'), coord.x, coord.y, targetPoints.bezierPoint)\n );\n }\n if (selectedElement.nodeName == 'circle') {\n selectedElement.setAttributeNS(null, \"cx\", cx);\n selectedElement.setAttributeNS(null, \"cy\", cy);\n let textNode = document.getElementById('text' + selectedElement.id);\n if (textNode !== null) {\n textNode.setAttributeNS(null, 'x', cx);\n textNode.setAttributeNS(null, 'y', cy);\n }\n pathsToUpdateFirstPoint.forEach(function(path) {\n let pathNode = document.getElementById(path.id);\n if (pathNode !== null) {\n if (pathNode.nodeName == 'path') {\n pathNode.setAttribute(\n 'd',\n updatePathDeclaration(pathNode.getAttribute('d'), cx, cy, targetPoints.firstPoint)\n );\n } else {\n pathNode.setAttribute('x1', cx);\n pathNode.setAttribute('y1', cy);\n }\n }\n });\n\n pathsToUpdateSecondPoint.forEach(function(path) {\n let pathNode = document.getElementById(path.id);\n if (pathNode !== null) {\n if (pathNode.nodeName == 'path') {\n pathNode.setAttribute(\n 'd',\n updatePathDeclaration(pathNode.getAttribute('d'), cx, cy, targetPoints.secondPoint)\n );\n } else {\n pathNode.setAttribute('x2', cx);\n pathNode.setAttribute('y2', cy);\n }\n }\n });\n }\n }\n }\n\n /**\n * Function called when dragging ends.\n * @param {*} evt\n */\n function endDrag(evt) {\n if (evt.cancelable) {\n evt.preventDefault();\n }\n selectedElement = null;\n unselectAll();\n updateCode();\n }\n\n /**\n * Function called when touchstart event occurs.\n * @param {*} evt\n */\n function startTouch(evt) {\n if (evt.cancelable) {\n evt.preventDefault();\n }\n if (\n evt.target.classList.contains('learningmap-draggable') ||\n evt.target.nodeName == 'text' ||\n evt.target.nodeName == 'path'\n ) {\n if (!touchstart) {\n touchstart = true;\n touchmove = 0;\n touchend = false;\n setTimeout(\n (evt) => {\n if (touchmove < 3 && !touchend) {\n if (evt.touches) {\n evt = evt.touches[0];\n }\n showContextMenu(evt);\n }\n },\n 2000,\n evt\n );\n setTimeout(\n () => {\n touchstart = false;\n },\n 300);\n } else {\n dblclickHandler(evt);\n touchstart = false;\n }\n startDrag(evt);\n } else {\n if (!touchstart) {\n touchstart = true;\n touchend = false;\n touchmove = 0;\n setTimeout(\n () => {\n touchstart = false;\n },\n 300);\n } else {\n dblclickHandler(evt);\n touchstart = false;\n }\n }\n }\n\n /**\n * Function called when touchend, touchleave or touchcancel event occurs.\n * @param {*} evt\n */\n function endTouch(evt) {\n selectedElement = null;\n touchend = true;\n // If there was only a small move (<3 move events), this also counts as a click.\n if (touchmove < 3 && touchstart) {\n clickHandler(evt);\n } else {\n endDrag(evt);\n }\n if (evt.cancelable) {\n evt.preventDefault();\n }\n }\n\n /**\n * Updates the path declaration of lines and quadratic bezier curves setting one of the points.\n * @param {string} oldDefinition SVG path definition string\n * @param {number} targetX x coordinate of the point to set\n * @param {number} targetY y coordinate of the point to set\n * @param {number} targetP Which point to change (you can use the targetPoints constants here)\n * @returns {string} Updated SVG path definition\n */\n function updatePathDeclaration(oldDefinition, targetX, targetY, targetP = targetPoints.firstPoint) {\n let parts = oldDefinition.split(' ');\n let fromX = 0;\n let fromY = 0;\n let toX = 0;\n let toY = 0;\n let bezierX = 0;\n let bezierY = 0;\n let pathType = pathTypes.line;\n\n // The d attribute of an SVG path in a learning map can have two different formats (in this version):\n // \"M x1 y1 L x2 y2\" Line from x1, y1 to x2, y2\n // \"M x1 y2 Q x3 y3 x2 y2\" Quadratic bezier curve inside the triangle defined by x1, y1, x2, y2 and x3, y3.\n for (let i = 0; i < parts.length; i++) {\n // Every path contains the first point in that way.\n if (parts[i] == 'M') {\n fromX = parseInt(parts[i + 1]);\n fromY = parseInt(parts[i + 2]);\n i += 2;\n }\n // This path is a direct line, so there are only two points in total.\n if (parts[i] == 'L') {\n toX = parseInt(parts[i + 1]);\n toY = parseInt(parts[i + 2]);\n i += 2;\n }\n // This path is a bezier curve, there are three points in total.\n if (parts[i] == 'Q') {\n bezierX = parseInt(parts[i + 1]);\n bezierY = parseInt(parts[i + 2]);\n toX = parseInt(parts[i + 3]);\n toY = parseInt(parts[i + 4]);\n i += 4;\n pathType = pathTypes.quadraticbezier;\n }\n }\n\n switch (targetP) {\n case targetPoints.firstPoint:\n fromX = targetX;\n fromY = targetY;\n break;\n case targetPoints.secondPoint:\n toX = targetX;\n toY = targetY;\n break;\n case targetPoints.bezierPoint:\n // Calculate the third triangle point for the bezier curve.\n bezierX = targetX * 2 - (fromX + toX) * 0.5;\n bezierY = targetY * 2 - (fromY + toY) * 0.5;\n pathType = pathTypes.quadraticbezier;\n break;\n }\n\n if (pathType == pathTypes.quadraticbezier) {\n return 'M ' + fromX + ' ' + fromY + ' Q ' + bezierX + ' ' + bezierY + ', ' + toX + ' ' + toY;\n } else {\n return 'M ' + fromX + ' ' + fromY + ' L ' + toX + ' ' + toY;\n }\n }\n }\n\n /**\n * Updates the form fields for the SVG code and the placestore from the editor.\n */\n function updateCode() {\n if (code && mapdiv) {\n code.innerHTML = mapdiv.innerHTML;\n }\n if (placestoreInput) {\n document.getElementsByName('placestore')[0].value = JSON.stringify(placestore.getPlacestore());\n }\n }\n\n /**\n * Handles double clicks on the map\n * @param {*} event\n */\n function dblclickHandler(event) {\n hideContextMenu();\n hideAdvancedSettings();\n unselectAll();\n if (event.target.classList.contains('learningmap-mapcontainer') ||\n event.target.classList.contains('learningmap-background-image')) {\n addPlace(event);\n } else if (event.target.classList.contains('learningmap-place')) {\n if (lastTarget == event.target.id) {\n lastTarget = null;\n clickHandler(event);\n } else {\n removePlace(event);\n }\n } else if (event.target.classList.contains('learningmap-path')) {\n removePath(event.target.id);\n }\n updateCode();\n }\n\n /**\n * Returns an empty title tag with the given id.\n * @param {*} id id for the title\n * @returns {any}\n */\n function title(id) {\n let title = document.createElementNS('http://www.w3.org/2000/svg', 'title');\n title.setAttribute('id', id);\n return title;\n }\n\n /**\n * Returns an text tag with the given id.\n * @param {*} id id for the text\n * @param {*} content content of the tag\n * @param {*} x x coordinate of the text\n * @param {*} y y coordinate of the text\n * @returns {any}\n */\n function text(id, content, x, y) {\n let text = document.createElementNS('http://www.w3.org/2000/svg', 'text');\n text.setAttribute('id', id);\n text.setAttribute('x', x);\n text.setAttribute('y', y);\n // Default value for delta: Circle radius * 1.5 (as a padding)\n text.setAttribute('dx', circleRadius * 1.5);\n text.setAttribute('dy', circleRadius * 1.5);\n text.textContent = wrapInCdata(content);\n return text;\n }\n\n /**\n * Returns a circle tag with the given dimensions.\n * @param {*} x x coordinate of the center\n * @param {*} y y coordinate of the center\n * @param {*} r radius\n * @param {*} classes classes to add\n * @param {*} id id of the circle\n * @returns {any}\n */\n function circle(x, y, r, classes, id) {\n let circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');\n circle.setAttribute('class', classes);\n circle.setAttribute('id', id);\n circle.setAttribute('cx', x);\n circle.setAttribute('cy', y);\n circle.setAttribute('r', r);\n return circle;\n }\n\n /**\n * Returns a path between two points.\n * @param {*} x1 x coordinate of the first point\n * @param {*} y1 y coordinate of the first point\n * @param {*} x2 x coordinate of the second point\n * @param {*} y2 y coordinate of the second point\n * @param {*} classes CSS classes to set\n * @param {*} id id of the path\n * @returns {any}\n */\n function path(x1, y1, x2, y2, classes, id) {\n let path = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n path.setAttribute('class', classes);\n path.setAttribute('id', id);\n path.setAttribute('d', 'M ' + x1 + ' ' + y1 + ' L ' + x2 + ' ' + y2);\n return path;\n }\n\n /**\n * Returns a link around a given child element. This function also adds a title element next\n * to the child for accessibility.\n * @param {*} child child item to set the link on\n * @param {*} id id of the link\n * @param {*} title title of the link\n * @param {*} text text to describe the link\n * @returns {any}\n */\n function link(child, id, title = null, text = null) {\n let link = document.createElementNS('http://www.w3.org/2000/svg', 'a');\n link.setAttribute('id', id);\n link.setAttribute('xlink:href', '');\n link.appendChild(child);\n if (title !== null) {\n link.appendChild(title);\n }\n if (text !== null) {\n link.appendChild(text);\n }\n return link;\n }\n\n /**\n * Adds a place on the SVG map. This function also prepares the code for linking activities\n * and adding titles (for accessibility).\n * @param {*} event event causing the command\n */\n function addPlace(event) {\n let placesgroup = document.getElementById('placesGroup');\n let placeId = 'p' + placestore.getId();\n let linkId = 'a' + placestore.getId();\n var CTM = event.target.getScreenCTM();\n if (event.touches) {\n event = event.touches[0];\n }\n let cx = (event.clientX - CTM.e) / CTM.a;\n let cy = (event.clientY - CTM.f) / CTM.d;\n placesgroup.appendChild(\n link(\n circle(cx, cy, circleRadius, 'learningmap-place learningmap-draggable learningmap-emptyplace', placeId),\n linkId,\n title('title' + placeId),\n text('text' + placeId, '', cx, cy)\n )\n );\n placestore.addPlace(placeId, linkId);\n }\n\n /**\n * Handles single clicks on the background image.\n * @param {*} event click event\n * @returns {void}\n */\n function clickHandler(event) {\n event.preventDefault();\n hideContextMenu();\n hideAdvancedSettings();\n if (event.target.classList.contains('learningmap-place') && selectedElement === null) {\n if (firstPlace === null) {\n firstPlace = event.target.id;\n document.getElementById(firstPlace).classList.add('learningmap-selected');\n } else {\n secondPlace = event.target.id;\n let fid = parseInt(firstPlace.replace('p', ''));\n let sid = parseInt(secondPlace.replace('p', ''));\n if (sid == fid) {\n return;\n }\n if (sid < fid) {\n let z = sid;\n sid = fid;\n fid = z;\n }\n addPath(fid, sid);\n let first = document.getElementById(firstPlace);\n if (first) {\n first.classList.remove('learningmap-selected');\n }\n firstPlace = null;\n lastTarget = secondPlace;\n secondPlace = null;\n }\n } else {\n unselectAll();\n firstPlace = null;\n }\n }\n /**\n * Removes the classes 'learningmap-selected' and 'learningmap-selectet-activity-selector'\n * from all nodes\n */\n function unselectAll() {\n Array.from(document.getElementsByClassName('learningmap-selected')).forEach(function(e) {\n e.classList.remove('learningmap-selected');\n });\n Array.from(document.getElementsByClassName('learningmap-selected-activity-selector')).forEach(function(e) {\n e.classList.remove('learningmap-selected-activity-selector');\n });\n }\n\n /**\n * Adds a path between two places.\n * @param {number} fid id of the first place (meant to be the smaller one)\n * @param {number} sid id of the second place (meant to be the bigger one)\n */\n function addPath(fid, sid) {\n let pid = 'p' + fid + '_' + sid;\n if (document.getElementById(pid) === null) {\n let pathsgroup = document.getElementById('pathsGroup');\n let first = document.getElementById('p' + fid);\n let second = document.getElementById('p' + sid);\n if (pathsgroup && first && second) {\n pathsgroup.appendChild(\n path(\n first.cx.baseVal.value,\n first.cy.baseVal.value,\n second.cx.baseVal.value,\n second.cy.baseVal.value,\n 'learningmap-path',\n pid\n )\n );\n placestore.addPath(pid, 'p' + fid, 'p' + sid);\n }\n }\n }\n\n /**\n * Removes a place from the SVG and the placestore. This function also removes all\n * touching paths and entries in statringplaces / targetplaces linking to the removed\n * place.\n * @param {any} event event causing the remove order\n */\n function removePlace(event) {\n let place = document.getElementById(event.target.id);\n let parent = place.parentNode;\n removePathsTouchingPlace(event.target.id);\n placestore.removePlace(event.target.id);\n parent.removeChild(place);\n parent.parentNode.removeChild(parent);\n\n updateCode();\n }\n\n /**\n * Removes all paths touching a certain place\n * @param {number} id id of the place\n */\n function removePathsTouchingPlace(id) {\n placestore.getTouchingPaths(id).forEach(\n function(e) {\n removePath(e.id);\n }\n );\n }\n\n /**\n * Removes a path from the SVG and from the placestore\n * @param {number} id id of the path\n */\n function removePath(id) {\n let path = document.getElementById(id);\n if (path !== null) {\n path.parentNode.removeChild(path);\n placestore.removePath(id);\n }\n }\n\n /**\n * Sets the background image of the SVG to the current image in filemanager.\n */\n function refreshBackgroundImage() {\n let previewimage = document.getElementsByClassName('realpreview');\n if (previewimage.length > 0) {\n let background = document.getElementById('learningmap-background-image');\n let backgroundurl = previewimage[0].getAttribute('src').split('?')[0];\n // If the uploaded file reuses the filename of a previously uploaded image, they differ\n // only in the oid. So one has to append the oid to the url.\n if (previewimage[0].getAttribute('src').split('?')[1].includes('&oid=')) {\n backgroundurl += '?oid=' + previewimage[0].getAttribute('src').split('&oid=')[1];\n }\n background.setAttribute('xlink:href', backgroundurl);\n }\n }\n\n /**\n * Adds an eventListener to the background image for watching file changes and updating\n * height and width of the image.\n */\n function registerBackgroundListener() {\n let background = document.getElementById('learningmap-background-image');\n if (background) {\n background.addEventListener('load', function() {\n background.removeAttribute('height');\n let height = parseInt(background.getBBox().height);\n let width = background.getBBox().width;\n placestore.setBackgroundDimensions(width, height);\n svg.setAttribute('viewBox', '0 0 ' + placestore.width + ' ' + placestore.height);\n background.setAttribute('width', width);\n background.setAttribute('height', height);\n updateCode();\n });\n }\n }\n\n /**\n * Updates CSS code inside the SVG (called, when one of the colors is changed).\n * Calls updateCode() when completed.\n */\n function updateCSS() {\n Templates.renderForPromise('mod_learningmap/cssskeleton', placestore.getPlacestore())\n .then(({html, js}) => {\n Templates.replaceNode('#learningmap-svgstyle', html, js);\n updateCode();\n return true;\n })\n .catch(ex => displayException(ex));\n }\n\n /**\n * Updates the activity selector to highlight the activities already used\n * and to show the alert for hidden activities.\n */\n function updateActivities() {\n let activities = placestore.getAllActivities();\n let options = Array.from(activitySelector.getElementsByTagName('option'));\n activityHiddenWarning.setAttribute('hidden', '');\n options.forEach(function(n) {\n if (activities.includes(n.value)) {\n n.classList.add('learningmap-used-activity');\n if (n.selected) {\n if (n.getAttribute('data-activity-hidden') == true) {\n activityHiddenWarning.removeAttribute('hidden');\n }\n }\n } else {\n n.classList.remove('learningmap-used-activity');\n }\n });\n }\n\n /**\n * Adds the event listener to the color chooser buttons.\n * @param {*} name name of the color\n * @param {*} secondValue name of a second placestore value that has to be changed along\n */\n function colorChooserLogic(name, secondValue = '') {\n let colorChooser = document.getElementById('learningmap-color-' + name);\n if (colorChooser) {\n colorChooser.addEventListener('change', function() {\n placestore.setColor(name, colorChooser.value);\n if (secondValue != '') {\n placestore.setColor(secondValue, colorChooser.value);\n }\n updateCSS();\n });\n colorChooser.value = placestore.getColor(name);\n }\n }\n\n /**\n * Adds the event listener to advanced settings menu items\n * @param {*} name Name of the item\n * @param {*} getCall Method of placestore to call to read value\n * @param {*} setCall Method of placestore to call to save value\n * @param {*} callback Additional callback after value is saved\n */\n function advancedSettingsLogic(name, getCall, setCall, callback = null) {\n let settingItem = document.getElementById('learningmap-advanced-setting-' + name);\n if (settingItem) {\n settingItem.checked = getCall.call(placestore);\n settingItem.addEventListener('change', function() {\n setCall.call(placestore, settingItem.checked);\n if (callback !== null) {\n callback();\n }\n updateCSS();\n });\n }\n }\n\n /**\n * Adds missing text nodes\n */\n function fixPlaceLabels() {\n let options = Array.from(activitySelector.getElementsByTagName('option'));\n let places = placestore.getPlaces();\n for (const place of places) {\n if (document.getElementById('text' + place.id) === null) {\n let content = '';\n for (const option of options) {\n if (option.value == place.linkedActivity) {\n content = option.textContent;\n break;\n }\n }\n let placeNode = document.getElementById(place.id);\n let textNode = text('text' + place.id, content, placeNode.cx.baseVal.value, placeNode.cy.baseVal.value);\n placeNode.parentNode.appendChild(textNode);\n }\n }\n }\n\n /**\n * Hides the advanced settings menu.\n */\n function hideAdvancedSettings() {\n let advancedSettings = document.getElementById('learningmap-advanced-settings');\n advancedSettings.setAttribute('hidden', '');\n }\n\n /**\n * Wraps content in a CDATA tag\n * @param {string} data Content to wrap\n * @returns {string} Wrapped content\n */\n function wrapInCdata(data) {\n return '';\n }\n};\n"],"names":["targetPoints","pathTypes","offset","dragel","pathsToUpdateFirstPoint","pathsToUpdateSecondPoint","prefetchTemplates","selectedElement","firstPlace","secondPlace","lastTarget","elementForActivitySelector","touchstart","touchend","touchmove","mapdiv","document","getElementById","code","activitySetting","activitySelector","activityStarting","activityTarget","activityHiddenWarning","advancedSettingsIcon","treeView","querySelector","setAttribute","iconView","setTimeout","dispatchEvent","Event","addEventListener","setActivityId","value","text","textContent","wrapInCdata","title","classList","remove","add","updateActivities","updateCode","checked","addStartingPlace","removeStartingPlace","addTargetPlace","removeTargetPlace","placestoreInput","getElementsByName","loadJSON","advancedSettings","getAttribute","hideAdvancedSettings","removeAttribute","hideContextMenu","advancedSettingsClose","advancedSettingsLogic","placestore","getHidePaths","setHidePaths","getUseCheckmark","setUseCheckmark","getHover","setHover","getPulse","setPulse","getShowall","setShowall","getHideStroke","setHideStroke","getShowText","setShowText","options","Array","from","getElementsByTagName","places","getPlaces","place","id","content","option","linkedActivity","placeNode","textNode","cx","baseVal","cy","parentNode","appendChild","getSliceMode","setSliceMode","getShowWayGone","setShowWayGone","colorChooserLogic","innerHTML","refreshBackgroundImage","background","height","parseInt","getBBox","width","setBackgroundDimensions","svg","registerBackgroundListener","getMapid","showContextMenu","e","unselectAll","target","touches","contains","activityId","getActivityId","scalingFactor","clientWidth","style","setProperty","clientHeight","display","isStartingPlace","isTargetPlace","el","startDrag","drag","endDrag","evt","cancelable","preventDefault","nodeName","dblclickHandler","endTouch","getMousePosition","x","getAttributeNS","y","getPathsWithFid","getPathsWithSid","pathPoint","transformCoordinates","layerX","layerY","coord","dx","dy","setAttributeNS","updatePathDeclaration","forEach","path","pathNode","clickHandler","oldDefinition","targetX","targetY","targetP","parts","split","fromX","fromY","toX","toY","bezierX","bezierY","pathType","i","length","makeDraggable","updateCSS","backgroundfileNode","MutationObserver","observe","attributes","childList","subtree","clientX","clientY","CTM","getScreenCTM","a","f","d","JSON","stringify","getPlacestore","event","placesgroup","placeId","getId","linkId","child","link","createElementNS","r","classes","circle","addPlace","parent","getTouchingPaths","removePath","removePlace","removeChild","circleRadius","fid","replace","sid","z","pid","pathsgroup","first","second","x1","y1","x2","y2","addPath","getElementsByClassName","previewimage","backgroundurl","includes","renderForPromise","then","_ref","html","js","replaceNode","catch","ex","activities","getAllActivities","n","selected","name","secondValue","colorChooser","setColor","getColor","getCall","setCall","callback","settingItem","call","data"],"mappings":"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"} \ No newline at end of file diff --git a/amd/src/learningmap.js b/amd/src/learningmap.js index 9343c49..d26729b 100644 --- a/amd/src/learningmap.js +++ b/amd/src/learningmap.js @@ -81,12 +81,15 @@ export const init = () => { if (activitySelector.value) { let text = document.getElementById('text' + elementForActivitySelector); if (text) { - text.textContent = activitySelector.querySelector('option[value="' + activitySelector.value + '"]').textContent; + text.textContent = wrapInCdata( + activitySelector.querySelector('option[value="' + activitySelector.value + '"]').textContent + ); } let title = document.getElementById('title' + elementForActivitySelector); if (title) { - title.textContent = - activitySelector.querySelector('option[value="' + activitySelector.value + '"]').textContent; + title.textContent = wrapInCdata( + activitySelector.querySelector('option[value="' + activitySelector.value + '"]').textContent + ); } document.getElementById(elementForActivitySelector).classList.remove('learningmap-emptyplace'); } else { @@ -605,7 +608,7 @@ export const init = () => { // Default value for delta: Circle radius * 1.5 (as a padding) text.setAttribute('dx', circleRadius * 1.5); text.setAttribute('dy', circleRadius * 1.5); - text.textContent = content; + text.textContent = wrapInCdata(content); return text; } @@ -957,4 +960,13 @@ export const init = () => { let advancedSettings = document.getElementById('learningmap-advanced-settings'); advancedSettings.setAttribute('hidden', ''); } + + /** + * Wraps content in a CDATA tag + * @param {string} data Content to wrap + * @returns {string} Wrapped content + */ + function wrapInCdata(data) { + return ''; + } };