diff --git a/Gruntfile.js b/Gruntfile.js
index 31d3d308..0f7cf5e6 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -66,6 +66,16 @@ module.exports = function(grunt) {
}
]
},
+ dot: {
+ files: [
+ {
+ expand: true,
+ cwd: 'node_modules/dot',
+ src: ['**/*.min.js'],
+ dest: 'dist/dependencies'
+ }
+ ]
+ },
app: {
files: [
{
diff --git a/app/app.js b/app/app.js
index a911bb01..0e97aa49 100644
--- a/app/app.js
+++ b/app/app.js
@@ -39,6 +39,10 @@ import {
downloadSVG,
setEncoded
} from './domain-story-modeler/features/export/svgDownload';
+import {
+ initStoryDownload,
+ downloadStory
+} from './domain-story-modeler/features/export/storyDownload';
import { downloadPNG } from './domain-story-modeler/features/export/pngDownload';
import {
loadPersistedDST,
@@ -166,6 +170,7 @@ let modal = document.getElementById('modal'),
),
pngSaveButton = document.getElementById('buttonPNG'),
svgSaveButton = document.getElementById('buttonSVG'),
+ storySaveButton = document.getElementById('buttonDownloadStory'),
wpsLogoButton = document.getElementById('closeWPSLogoInfo'),
dstLogoButton = document.getElementById('closeDSTLogoInfo'),
exportConfigurationButton = document.getElementById(
@@ -221,6 +226,7 @@ function initialize(
modeler.on('commandStack.changed', exportArtifacts);
initReplay(canvas, selection);
+ initStoryDownload(canvas, selection, modeler);
initElementRegistry(elementRegistry);
initImports(elementRegistry, version, modeler, eventBus, saveSVG);
@@ -538,6 +544,13 @@ pngSaveButton.addEventListener('click', function() {
closeImageDownloadDialog();
});
+storySaveButton.addEventListener('click', function() {
+ const filename =
+ title.innerText + '_' + new Date().toISOString().slice(0, 10);
+ downloadStory(filename);
+ closeImageDownloadDialog();
+});
+
incompleteStoryDialogButtonCancel.addEventListener('click', function() {
modal.style.display = 'none';
incompleteStoryDialog.style.display = 'none';
diff --git a/app/domain-story-modeler/features/export/storyDownload.js b/app/domain-story-modeler/features/export/storyDownload.js
new file mode 100644
index 00000000..7aea596d
--- /dev/null
+++ b/app/domain-story-modeler/features/export/storyDownload.js
@@ -0,0 +1,261 @@
+'use strict';
+
+import { sanitizeForDesktop } from '../../util/Sanitizer';
+import { GROUP } from '../../language/elementTypes';
+import {
+ getActivitesFromActors,
+ wasInitialized,
+} from '../../language/canvasElementRegistry';
+import { traceActivities } from '../replay/initializeReplay';
+import doT from 'dot';
+import { editMode, presentationMode, showCurrentStep } from '../replay/replayFunctions';
+
+let canvas;
+let selection;
+
+let multiplexSecret;
+let multiplexId;
+
+let replayOn = false;
+let currentStep = 0;
+let replaySteps = [];
+let initialViewbox;
+
+let errorStep = 0;
+
+let dsModeler;
+
+let modal = document.getElementById('modal');
+let incompleteStoryDialog = document.getElementById('incompleteStoryInfo');
+
+export function initStoryDownload(inCanvas, inSelection, modeler) {
+ canvas = inCanvas;
+ selection = inSelection;
+ dsModeler = modeler;
+
+ // cors.bridged.cc is a CORS ANYWHERE server. For details: https://blog.bridged.xyz/cors-anywhere-for-everyone-free-reliable-cors-proxy-service-73507192714e
+ fetch('https://cors.bridged.cc/https://reveal-multiplex.glitch.me/token', { headers: { 'x-requested-with':'XMLHttpRequest' } }).then(res => res.json()).then((out) => {
+ multiplexSecret=out.secret;
+ multiplexId=out.socketId;
+ }).catch(err => console.error(err));
+}
+
+export async function downloadStory(filename) {
+ var svgData = [];
+ currentStep = 0;
+
+ // export all sentences of domain story
+ startReplay();
+ try {
+ const result = await dsModeler.saveSVG({ });
+ svgData.push({ content: createSVGData(result.svg), transition: 'slide' });
+ } catch (err) {
+ alert('There was an error exporting the SVG.\n' + err);
+ }
+ while (currentStep < replaySteps.length - 1) {
+ nextStep();
+ try {
+ const result = await dsModeler.saveSVG({ });
+ svgData.push({ content: createSVGData(result.svg), transition: 'slide' });
+ } catch (err) {
+ alert('There was an error exporting the SVG.\n' + err);
+ }
+ }
+ stopReplay();
+
+ // create download for presentation
+ let revealjsTemplate = document.getElementById('revealjs-template');
+ var dots = doT.template(revealjsTemplate.innerHTML);
+ var revealjsData = { };
+ revealjsData.script = 'script'; // don't change this!!
+ revealjsData.title = document.getElementById('title').innerHTML;
+ revealjsData.description = document.getElementById('infoText').innerHTML;
+ revealjsData.sentences = svgData;
+ revealjsData.multiplexSecret = multiplexSecret;
+ revealjsData.multiplexId = multiplexId;
+ let element;
+ element = document.createElement('a');
+ element.setAttribute(
+ 'href',
+ 'data:text/html;charset=UTF-8,' + dots(revealjsData)
+ );
+ element.setAttribute('download', sanitizeForDesktop(filename) + '.html');
+ element.style.display = 'none';
+ document.body.appendChild(element);
+ element.click();
+ document.body.removeChild(element);
+}
+
+function startReplay() {
+ if (wasInitialized()) {
+ initialViewbox = canvas.viewbox();
+ let activities = getActivitesFromActors();
+
+ if (!replayOn && activities.length > 0) {
+ replaySteps = traceActivities(activities);
+
+ if (isStoryConsecutivelyNumbered(replaySteps)) {
+ replayOn = true;
+ presentationMode(selection);
+ currentStep = 0;
+ showCurrentStep(currentStep, replaySteps, canvas);
+ } else {
+ let errorText = '\nThe numbers: ';
+ for (let i = 0; i < replaySteps.length; i++) {
+ if (errorStep[i]) {
+ errorText += i + 1 + ',';
+ }
+ }
+ errorText = errorText.substring(0, errorText.length - 1);
+ errorText += ' are missing!';
+
+ let oldText = incompleteStoryDialog.getElementsByTagName('text');
+ if (oldText) {
+ for (let i = 0; i < oldText.length; i++) {
+ incompleteStoryDialog.removeChild(oldText[i]);
+ }
+ }
+
+ let text = document.createElement('text');
+ text.innerHTML =
+ ' The activities in this Domain Story are not numbered consecutively.
' +
+ 'Please fix the numbering in order to replay the story.
' +
+ errorText;
+ incompleteStoryDialog.appendChild(text);
+ incompleteStoryDialog.style.display = 'block';
+ modal.style.display = 'block';
+ }
+ }
+ }
+}
+
+function stopReplay() {
+ if (replayOn) {
+ editMode();
+
+ // show all canvas elements
+ let allObjects = [];
+ let groupObjects = [];
+ let canvasObjects = canvas._rootElement.children;
+ let i = 0;
+
+ for (i = 0; i < canvasObjects.length; i++) {
+ if (canvasObjects[i].type.includes(GROUP)) {
+ groupObjects.push(canvasObjects[i]);
+ } else {
+ allObjects.push(canvasObjects[i]);
+ }
+ }
+
+ i = groupObjects.length - 1;
+ while (groupObjects.length >= 1) {
+ let currentgroup = groupObjects.pop();
+ currentgroup.children.forEach(child => {
+ if (child.type.includes(GROUP)) {
+ groupObjects.push(child);
+ } else {
+ allObjects.push(child);
+ }
+ allObjects.push(currentgroup);
+ });
+ i = groupObjects.length - 1;
+ }
+ allObjects.forEach(element => {
+ let domObject = document.querySelector(
+ '[data-element-id=' + element.id + ']'
+ );
+ domObject.style.display = 'block';
+ });
+
+ replayOn = false;
+ currentStep = 0;
+ canvas.viewbox(initialViewbox);
+ }
+}
+
+function nextStep() {
+ if (replayOn) {
+ if (currentStep < replaySteps.length - 1) {
+ currentStep += 1;
+ showCurrentStep(currentStep, replaySteps, canvas);
+ }
+ }
+}
+
+function isStoryConsecutivelyNumbered(replaySteps) {
+ errorStep = [];
+ let complete = true;
+ for (let i = 0; i < replaySteps.length; i++) {
+ if (!replaySteps[i].activities[0]) {
+ complete = false;
+ errorStep[i] = true;
+ } else {
+ errorStep[i] = false;
+ }
+ }
+ return complete;
+}
+
+/*
+---------------------------
+SVG handling starts here
+----------------------------
+*/
+
+function createSVGData(svg) {
+
+ let data = JSON.parse(JSON.stringify(svg));
+
+ // to ensure that the title and description are inside the SVG container and do not overlapp with any elements,
+ // we change the confines of the SVG viewbox
+ let viewBoxIndex = data.indexOf('width="');
+
+ let viewBox = viewBoxCoordinates(data);
+
+ let xLeft, xRight, yUp, yDown;
+ let bounds = '';
+ let splitViewBox = viewBox.split(/\s/);
+
+ xLeft = +splitViewBox[0];
+ yUp = +splitViewBox[1];
+ xRight = +splitViewBox[2];
+ yDown = +splitViewBox[3];
+
+ if (xRight < 300) {
+ xRight += 300;
+ }
+
+ bounds =
+ 'width="100%"' +
+ ' height="auto" ' +
+ ' preserveAspectRatio="xMidYMid meet"' +
+ ' viewBox="' +
+ xLeft +
+ ' ' +
+ yUp +
+ ' ' +
+ xRight +
+ ' ' +
+ (yDown + 30);
+ let dataStart = data.substring(0, viewBoxIndex);
+ viewBoxIndex = data.indexOf('" version');
+ let dataEnd = data.substring(viewBoxIndex);
+ dataEnd.substring(viewBoxIndex);
+
+ data = dataStart + bounds + dataEnd;
+
+ let insertIndex = data.indexOf('');
+ if (insertIndex < 0) {
+ insertIndex = data.indexOf('version="1.2">') + 14;
+ } else {
+ insertIndex += 7;
+ }
+
+ return encodeURIComponent(data);
+}
+
+function viewBoxCoordinates(svg) {
+ const ViewBoxCoordinate = /width="([^"]+)"\s+height="([^"]+)"\s+viewBox="([^"]+)"/;
+ const match = svg.match(ViewBoxCoordinate);
+ return match[3];
+}
diff --git a/app/domain-story-modeler/features/replay/replay.js b/app/domain-story-modeler/features/replay/replay.js
index 49134445..f46af859 100644
--- a/app/domain-story-modeler/features/replay/replay.js
+++ b/app/domain-story-modeler/features/replay/replay.js
@@ -1,15 +1,12 @@
'use strict';
-import { CONNECTION, GROUP } from '../../language/elementTypes';
+import { GROUP } from '../../language/elementTypes';
import {
getActivitesFromActors,
- getAllCanvasObjects,
wasInitialized,
- getAllGroups,
- getAllActivities,
- getAllConnections
} from '../../language/canvasElementRegistry';
import { traceActivities } from './initializeReplay';
+import { editMode, presentationMode, showCurrentStep } from './replayFunctions';
let canvas;
let selection;
@@ -26,7 +23,6 @@ let startReplayButton = document.getElementById('buttonStartReplay');
let nextStepButton = document.getElementById('buttonNextStep');
let previousStepButton = document.getElementById('buttonPreviousStep');
let stopReplayButton = document.getElementById('buttonStopReplay');
-let currentReplayStepLabel = document.getElementById('replayStep');
let incompleteStoryDialog = document.getElementById('incompleteStoryInfo');
export function getReplayOn() {
@@ -61,9 +57,9 @@ export function initReplay(inCanvas, inSelection) {
if (isStoryConsecutivelyNumbered(replaySteps)) {
replayOn = true;
- presentationMode();
+ presentationMode(selection);
currentStep = 0;
- showCurrentStep();
+ showCurrentStep(currentStep, replaySteps, canvas);
} else {
let errorText = '\nThe numbers: ';
for (let i = 0; i < replaySteps.length; i++) {
@@ -151,7 +147,7 @@ function nextStep() {
if (replayOn) {
if (currentStep < replaySteps.length - 1) {
currentStep += 1;
- showCurrentStep();
+ showCurrentStep(currentStep, replaySteps, canvas);
}
}
}
@@ -160,7 +156,7 @@ function previousStep() {
if (replayOn) {
if (currentStep > 0) {
currentStep -= 1;
- showCurrentStep();
+ showCurrentStep(currentStep, replaySteps, canvas);
}
}
}
@@ -182,266 +178,3 @@ export function isStoryConsecutivelyNumbered(replaySteps) {
}
return complete;
}
-
-export function getAllShown(stepsUntilNow) {
- let shownElements = [];
-
- // for each step until the current one, add all referenced elements to the list of shown elements
- stepsUntilNow.forEach(step => {
- if (step.groups && step.groups.length > 0) {
- step.groups.forEach(group => {
- shownElements.push(group);
- });
- } else {
-
- // add the source of the step and their annotations to the shown elements
- step.sources.forEach(source => {
-
- shownElements.push(source);
- if (source.outgoing) {
- source.outgoing.forEach(out => {
- if (out.type.includes(CONNECTION)) {
- shownElements.push(out, out.target);
- }
- });
- }
- });
-
- // add the target of the step and their annotations to the shown elements
- step.targets.forEach(target => {
- shownElements.push(target);
- if (target.outgoing) {
- target.outgoing.forEach(out => {
- if (out.type.includes(CONNECTION)) {
- shownElements.push(out, out.target);
- }
- });
- }
-
- // add each activity to the step
- step.activities.forEach(activity => {
- shownElements.push(activity);
- });
- });
- }
- });
-
- return shownElements;
-}
-
-function removeHighlights() {
- const numberBackgroundColour = '#42aebb';
- const numberColour = 'white';
-
- const allActivities = getAllActivities();
- const allConnections = getAllConnections();
-
- allActivities.forEach(activity => {
- const activityDomObject = document.querySelector(
- '[data-element-id=' + activity.id + ']'
- ).getElementsByTagName('polyline')[0];
-
- activityDomObject.style.stroke = activity.businessObject.pickedColor || 'black';
- activityDomObject.style.strokeWidth = 1.5;
-
- const { numberBackgroundDom, numberTextDom } = getNumberDomForActivity(activityDomObject);
- if (numberBackgroundDom && numberTextDom) {
- numberBackgroundDom.style.fill = numberBackgroundColour;
- numberTextDom.style.fill = numberColour;
- }
-
- });
-
- allConnections.forEach(connnection => {
- const connectionDomObject = document.querySelector(
- '[data-element-id=' + connnection.id + ']'
- ).getElementsByTagName('polyline')[0];
-
- connectionDomObject.style.stroke = connnection.businessObject.pickedColor || 'black';
- connectionDomObject.style.strokeWidth = 1.5;
-
- });
-}
-
-function hightlightStep(step) {
- const highlightColour = 'black';
- const numberBackgroundHighlightColour = 'orange';
- const numberHighlightColour = 'black';
-
- if (!step.groups) {
-
- step.activities.forEach(activity => {
- const activityDomObject = document.querySelector(
- '[data-element-id=' + activity.id + ']'
- ).getElementsByTagName('polyline')[0];
-
- activityDomObject.style.stroke = highlightColour;
- activityDomObject.style.strokeWidth = 4;
-
- const { numberBackgroundDom, numberTextDom } = getNumberDomForActivity(activityDomObject);
- if (numberTextDom && numberBackgroundDom) {
- numberBackgroundDom.style.fill = numberBackgroundHighlightColour;
- numberTextDom.style.fill = numberHighlightColour;
- }
-
- });
- }
-}
-
-function getNumberDomForActivity(activity) {
- const numberDOMS = activity.parentElement.getElementsByClassName('djs-labelNumber');
- return {
- numberBackgroundDom: numberDOMS[0],
- numberTextDom: numberDOMS[1]
- };
-}
-
-// get all elements, that are supposed to be hidden in the current step
-export function getAllNotShown(allObjects, shownElements) {
- let notShownElements = [];
-
- // every element that is not referenced in shownElements
- // and is neither a group (since they are not refeenced in allObjects),
- // nor an annotation conntected to a group should be hidden
- allObjects.forEach(element => {
- if (!shownElements.includes(element)) {
- if (element.type.includes(CONNECTION)) {
- if (!element.source.type.includes(GROUP)) {
- notShownElements.push(element);
- } else {
- shownElements.push(element.target);
- }
- } else {
- notShownElements.push(element);
- }
- }
- });
- return notShownElements;
-}
-
-// replay functions
-function presentationMode() {
-
- removeSelectionAndEditing();
-
- const contextPadElements = document.getElementsByClassName('djs-context-pad');
- const paletteElements = document.getElementsByClassName('djs-palette');
-
- const infoContainer = document.getElementById('infoContainer');
- infoContainer.style.display = 'none';
-
- const editModeButtons = document.getElementById('editModeButtons');
- editModeButtons.style.display = 'none';
- editModeButtons.style.pointerEvents = 'none';
-
- const presentationModeButtons = document.getElementById(
- 'presentationModeButtons'
- );
- presentationModeButtons.style.display = 'block';
- presentationModeButtons.style.pointerEvents = 'all';
-
- const headerAndCanvas = document.getElementsByClassName('headerAndCanvas')[0];
- headerAndCanvas.style.gridTemplateRows = '0px 50px 1px auto';
-
- const headlineAndButtons = document.getElementById('headlineAndButtons');
- headlineAndButtons.style.gridTemplateColumns = 'auto 230px 3px';
-
- let i = 0;
- for (i = 0; i < contextPadElements.length; i++) {
- contextPadElements[i].style.display = 'none';
- }
-
- for (i = 0; i < paletteElements.length; i++) {
- paletteElements[i].style.display = 'none';
- }
-
- currentReplayStepLabel.style.opacity = 1;
-}
-
-function removeSelectionAndEditing() {
- selection.select([]);
- const directEditingBoxes = document.getElementsByClassName('djs-direct-editing-parent');
-
- if (directEditingBoxes.length > 0) {
- const directEditing = directEditingBoxes[0];
- directEditing.parentElement.removeChild(directEditing);
- }
-}
-
-function editMode() {
- removeHighlights();
-
- const contextPadElements = document.getElementsByClassName('djs-context-pad');
- const paletteElements = document.getElementsByClassName('djs-palette');
-
- const infoContainer = document.getElementById('infoContainer');
- infoContainer.style.display = 'block';
- infoContainer.style.height = '75px';
-
- let editModeButtons = document.getElementById('editModeButtons');
- editModeButtons.style.display = 'inherit';
- editModeButtons.style.pointerEvents = 'all';
-
- let presentationModeButtons = document.getElementById(
- 'presentationModeButtons'
- );
- presentationModeButtons.style.display = 'none';
- presentationModeButtons.style.pointerEvents = 'none';
-
- let headerAndCanvas = document.getElementsByClassName('headerAndCanvas')[0];
- headerAndCanvas.style.gridTemplateRows = '0px 125px 1px auto';
-
- let headlineAndButtons = document.getElementById('headlineAndButtons');
- headlineAndButtons.style.gridTemplateColumns = 'auto 390px 3px';
-
- let i = 0;
- for (i = 0; i < contextPadElements.length; i++) {
- contextPadElements[i].style.display = 'block';
- }
-
- for (i = 0; i < paletteElements.length; i++) {
- paletteElements[i].style.display = 'block';
- }
- currentReplayStepLabel.style.opacity = 0;
-}
-
-function showCurrentStep() {
- let stepsUntilNow = [];
- let allObjects = [];
- let i = 0;
-
- currentReplayStepLabel.innerText =
- currentStep + 1 + ' / ' + replaySteps.length;
-
- for (i = 0; i <= currentStep; i++) {
- stepsUntilNow.push(replaySteps[i]);
- }
-
- allObjects = getAllCanvasObjects(canvas);
- getAllGroups().forEach(group => {
- allObjects.push(group);
- });
-
- let shownElements = getAllShown(stepsUntilNow);
-
- const notShownElements = getAllNotShown(allObjects, shownElements);
-
- removeHighlights();
- hightlightStep(replaySteps[currentStep]);
-
- // hide all elements, that are not to be shown
- notShownElements.forEach(element => {
- const domObject = document.querySelector(
- '[data-element-id=' + element.id + ']'
- );
- domObject.style.display = 'none';
- });
-
- shownElements.forEach(element => {
- const domObject = document.querySelector(
- '[data-element-id=' + element.id + ']'
- );
- domObject.style.display = 'block';
- });
-
-}
diff --git a/app/domain-story-modeler/features/replay/replayFunctions.js b/app/domain-story-modeler/features/replay/replayFunctions.js
new file mode 100644
index 00000000..6eb61454
--- /dev/null
+++ b/app/domain-story-modeler/features/replay/replayFunctions.js
@@ -0,0 +1,267 @@
+import { getAllActivities, getAllCanvasObjects, getAllConnections, getAllGroups } from '../../language/canvasElementRegistry';
+import { CONNECTION, GROUP } from '../../language/elementTypes';
+
+let currentReplayStepLabel = document.getElementById('replayStep');
+
+export function showCurrentStep(currentStep, replaySteps, canvas) {
+ let stepsUntilNow = [];
+ let allObjects = [];
+ let i = 0;
+
+ currentReplayStepLabel.innerText =
+ currentStep + 1 + ' / ' + replaySteps.length;
+
+ for (i = 0; i <= currentStep; i++) {
+ stepsUntilNow.push(replaySteps[i]);
+ }
+
+ allObjects = getAllCanvasObjects(canvas);
+ getAllGroups().forEach(group => {
+ allObjects.push(group);
+ });
+
+ let shownElements = getAllShown(stepsUntilNow);
+
+ const notShownElements = getAllNotShown(allObjects, shownElements);
+
+ removeHighlights();
+ hightlightStep(replaySteps[currentStep]);
+
+ // hide all elements, that are not to be shown
+ notShownElements.forEach(element => {
+ const domObject = document.querySelector(
+ '[data-element-id=' + element.id + ']'
+ );
+ domObject.style.display = 'none';
+ });
+
+ shownElements.forEach(element => {
+ const domObject = document.querySelector(
+ '[data-element-id=' + element.id + ']'
+ );
+ domObject.style.display = 'block';
+ });
+}
+
+function getAllShown(stepsUntilNow) {
+ let shownElements = [];
+
+ // for each step until the current one, add all referenced elements to the list of shown elements
+ stepsUntilNow.forEach(step => {
+ if (step.groups && step.groups.length > 0) {
+ step.groups.forEach(group => {
+ shownElements.push(group);
+ });
+ } else {
+
+ // add the source of the step and their annotations to the shown elements
+ step.sources.forEach(source => {
+
+ shownElements.push(source);
+ if (source.outgoing) {
+ source.outgoing.forEach(out => {
+ if (out.type.includes(CONNECTION)) {
+ shownElements.push(out, out.target);
+ }
+ });
+ }
+ });
+
+ // add the target of the step and their annotations to the shown elements
+ step.targets.forEach(target => {
+ shownElements.push(target);
+ if (target.outgoing) {
+ target.outgoing.forEach(out => {
+ if (out.type.includes(CONNECTION)) {
+ shownElements.push(out, out.target);
+ }
+ });
+ }
+
+ // add each activity to the step
+ step.activities.forEach(activity => {
+ shownElements.push(activity);
+ });
+ });
+ }
+ });
+
+ return shownElements;
+}
+
+function hightlightStep(step) {
+ const highlightColour = 'black';
+ const numberBackgroundHighlightColour = 'orange';
+ const numberHighlightColour = 'black';
+
+ if (!step.groups) {
+
+ step.activities.forEach(activity => {
+ const activityDomObject = document.querySelector(
+ '[data-element-id=' + activity.id + ']'
+ ).getElementsByTagName('polyline')[0];
+
+ activityDomObject.style.stroke = highlightColour;
+ activityDomObject.style.strokeWidth = 4;
+
+ const { numberBackgroundDom, numberTextDom } = getNumberDomForActivity(activityDomObject);
+ if (numberTextDom && numberBackgroundDom) {
+ numberBackgroundDom.style.fill = numberBackgroundHighlightColour;
+ numberTextDom.style.fill = numberHighlightColour;
+ }
+
+ });
+ }
+}
+
+// get all elements, that are supposed to be hidden in the current step
+function getAllNotShown(allObjects, shownElements) {
+ let notShownElements = [];
+
+ // every element that is not referenced in shownElements
+ // and is neither a group (since they are not refeenced in allObjects),
+ // nor an annotation conntected to a group should be hidden
+ allObjects.forEach(element => {
+ if (!shownElements.includes(element)) {
+ if (element.type.includes(CONNECTION)) {
+ if (!element.source.type.includes(GROUP)) {
+ notShownElements.push(element);
+ } else {
+ shownElements.push(element.target);
+ }
+ } else {
+ notShownElements.push(element);
+ }
+ }
+ });
+ return notShownElements;
+}
+
+
+// replay functions
+export function presentationMode(selected) {
+
+ removeSelectionAndEditing(selected);
+
+ const contextPadElements = document.getElementsByClassName('djs-context-pad');
+ const paletteElements = document.getElementsByClassName('djs-palette');
+
+ const infoContainer = document.getElementById('infoContainer');
+ infoContainer.style.display = 'none';
+
+ const editModeButtons = document.getElementById('editModeButtons');
+ editModeButtons.style.display = 'none';
+ editModeButtons.style.pointerEvents = 'none';
+
+ const presentationModeButtons = document.getElementById(
+ 'presentationModeButtons'
+ );
+ presentationModeButtons.style.display = 'block';
+ presentationModeButtons.style.pointerEvents = 'all';
+
+ const headerAndCanvas = document.getElementsByClassName('headerAndCanvas')[0];
+ headerAndCanvas.style.gridTemplateRows = '0px 50px 1px auto';
+
+ const headlineAndButtons = document.getElementById('headlineAndButtons');
+ headlineAndButtons.style.gridTemplateColumns = 'auto 230px 3px';
+
+ let i = 0;
+ for (i = 0; i < contextPadElements.length; i++) {
+ contextPadElements[i].style.display = 'none';
+ }
+
+ for (i = 0; i < paletteElements.length; i++) {
+ paletteElements[i].style.display = 'none';
+ }
+
+ currentReplayStepLabel.style.opacity = 1;
+}
+
+export function editMode() {
+ removeHighlights();
+
+ const contextPadElements = document.getElementsByClassName('djs-context-pad');
+ const paletteElements = document.getElementsByClassName('djs-palette');
+
+ const infoContainer = document.getElementById('infoContainer');
+ infoContainer.style.display = 'block';
+ infoContainer.style.height = '75px';
+
+ let editModeButtons = document.getElementById('editModeButtons');
+ editModeButtons.style.display = 'inherit';
+ editModeButtons.style.pointerEvents = 'all';
+
+ let presentationModeButtons = document.getElementById(
+ 'presentationModeButtons'
+ );
+ presentationModeButtons.style.display = 'none';
+ presentationModeButtons.style.pointerEvents = 'none';
+
+ let headerAndCanvas = document.getElementsByClassName('headerAndCanvas')[0];
+ headerAndCanvas.style.gridTemplateRows = '0px 125px 1px auto';
+
+ let headlineAndButtons = document.getElementById('headlineAndButtons');
+ headlineAndButtons.style.gridTemplateColumns = 'auto 390px 3px';
+
+ let i = 0;
+ for (i = 0; i < contextPadElements.length; i++) {
+ contextPadElements[i].style.display = 'block';
+ }
+
+ for (i = 0; i < paletteElements.length; i++) {
+ paletteElements[i].style.display = 'block';
+ }
+ currentReplayStepLabel.style.opacity = 0;
+}
+
+function removeSelectionAndEditing(selected) {
+ selected.select([]);
+ const directEditingBoxes = document.getElementsByClassName('djs-direct-editing-parent');
+
+ if (directEditingBoxes.length > 0) {
+ const directEditing = directEditingBoxes[0];
+ directEditing.parentElement.removeChild(directEditing);
+ }
+}
+
+function removeHighlights() {
+ const numberBackgroundColour = '#42aebb';
+ const numberColour = 'white';
+
+ const allActivities = getAllActivities();
+ const allConnections = getAllConnections();
+
+ allActivities.forEach(activity => {
+ const activityDomObject = document.querySelector(
+ '[data-element-id=' + activity.id + ']'
+ ).getElementsByTagName('polyline')[0];
+
+ activityDomObject.style.stroke = activity.businessObject.pickedColor || 'black';
+ activityDomObject.style.strokeWidth = 1.5;
+
+ const { numberBackgroundDom, numberTextDom } = getNumberDomForActivity(activityDomObject);
+ if (numberBackgroundDom && numberTextDom) {
+ numberBackgroundDom.style.fill = numberBackgroundColour;
+ numberTextDom.style.fill = numberColour;
+ }
+
+ });
+
+ allConnections.forEach(connnection => {
+ const connectionDomObject = document.querySelector(
+ '[data-element-id=' + connnection.id + ']'
+ ).getElementsByTagName('polyline')[0];
+
+ connectionDomObject.style.stroke = connnection.businessObject.pickedColor || 'black';
+ connectionDomObject.style.strokeWidth = 1.5;
+
+ });
+}
+
+function getNumberDomForActivity(activity) {
+ const numberDOMS = activity.parentElement.getElementsByClassName('djs-labelNumber');
+ return {
+ numberBackgroundDom: numberDOMS[0],
+ numberTextDom: numberDOMS[1]
+ };
+}
diff --git a/app/index.html b/app/index.html
index ff113890..796853eb 100644
--- a/app/index.html
+++ b/app/index.html
@@ -44,7 +44,7 @@