Skip to content

Commit

Permalink
Merge branch 'main' into feature/cleanup-unused-icons
Browse files Browse the repository at this point in the history
  • Loading branch information
MrCoder authored Sep 25, 2024
2 parents db5e68c + c49490a commit 9fdb0b5
Show file tree
Hide file tree
Showing 14 changed files with 248 additions and 167 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
:labelText="labelText"
:labelPositions="labelPositions"
:assignee="entity.assignee"
:assigneePositions="assigneePositions"
/>
</div>
</div>
Expand Down Expand Up @@ -63,9 +64,22 @@ export default {
return { translate: 0, participant };
}
const labelPositions = computed(() =>
store.getters.participants.Positions().get(props.entity.name),
);
const labelPositions = computed(() => {
const positions = store.getters.participants.GetPositions(
props.entity.name,
);
// Sort the label positions in descending order to avoid index shifting when updating code
const positionArray = Array.from(positions ?? []);
return positionArray.sort((a, b) => b[0] - a[0]);
});
const assigneePositions = computed(() => {
// Sort the label positions in descending order to avoid index shifting when updating code
const assigneePositions = store.getters.participants.GetAssigneePositions(
props.entity.name,
);
const positionArray = Array.from(assigneePositions ?? []);
return positionArray.sort((a, b) => b[0] - a[0]);
});
const intersectionTop = useIntersectionTop();
const [scrollTop] = useDocumentScroll();
const translate = computed(() => {
Expand All @@ -86,7 +100,7 @@ export default {
participantOffsetTop
);
});
return { translate, participant, labelPositions };
return { translate, participant, labelPositions, assigneePositions };
},
props: {
entity: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,38 @@
<template>
<div class="flex items-center justify-center">
<template v-if="assignee">
<label class="name leading-4">{{ assignee }}:</label>
<label
title="Double click to edit"
class="name leading-4 cursor-text right hover:text-skin-message-hover hover:bg-skin-message-hover"
:class="{
'py-1 cursor-text': assigneeLabelHandler.editing,
}"
:contenteditable="
assigneeLabelHandler.editing && mode === RenderMode.Dynamic
"
@dblclick="assigneeLabelHandler.handleDblClick"
@blur="assigneeLabelHandler.handleBlur"
@keyup="assigneeLabelHandler.handleKeyup"
@keydown="assigneeLabelHandler.handleKeydown"
>{{ assignee }}</label
>
<span>:</span>
</template>
<label
title="Double click to edit"
class="name leading-4 cursor-text right hover:text-skin-message-hover hover:bg-skin-message-hover"
:class="{
'py-1 px-2 cursor-text': editing,
'py-1 cursor-text': participantLabelHandler.editing,
}"
:contenteditable="editing && mode === RenderMode.Dynamic"
@dblclick="handleDblClick"
@blur="handleBlur"
@keyup="handleKeyup"
@keydown="handleKeydown"
:contenteditable="
participantLabelHandler.editing &&
mode === RenderMode.Dynamic &&
UneditableText.indexOf(labelText) === -1
"
@dblclick="participantLabelHandler.handleDblClick"
@blur="participantLabelHandler.handleBlur"
@keyup="participantLabelHandler.handleKeyup"
@keydown="participantLabelHandler.handleKeydown"
>
{{ labelText }}
</label>
Expand All @@ -24,14 +43,19 @@ import { computed, toRefs } from "vue";
import { useStore } from "vuex";
import { useEditLabel, specialCharRegex } from "@/functions/useEditLabel";
import { RenderMode } from "@/store/Store";
import { Position } from "@/parser/Participants";
const UneditableText = ["Missing Constructor", "ZenUML"];
const props = defineProps<{
labelText: string;
labelPositions?: Set<string>;
labelPositions?: Array<[number, number]>;
assignee?: string;
assigneePositions?: Array<[number, number]>;
}>();
const { labelText, labelPositions } = toRefs(props);
const { labelText, labelPositions, assigneePositions } = toRefs(props);
const store = useStore();
const mode = computed(() => store.state.mode);
const code = computed(() => store.getters.code);
Expand All @@ -45,48 +69,48 @@ function updateCode(code: string) {
onContentChange.value(code);
}
function replaceLabelText(e: Event) {
e.preventDefault();
e.stopPropagation();
const target = e.target;
if (!(target instanceof HTMLElement)) return;
let newText = target.innerText.trim() ?? "";
function replaceLabelTextWithaPositions(positions: Array<Position>) {
return function (e: Event) {
e.preventDefault();
e.stopPropagation();
// If text is empty or same as the original label text,
// we replace it with the original label text and bail out early
if (newText === "" || newText === labelText.value) {
target.innerText = labelText.value;
return;
}
const target = e.target;
if (!(target instanceof HTMLElement)) return;
let newText = target.innerText.trim() ?? "";
if (newText.includes(" ")) {
newText = newText.replace(/\s+/g, " "); // remove extra spaces
}
// If text is empty or same as the original label text,
// we replace it with the original label text and bail out early
if (newText === "" || newText === labelText.value) {
target.innerText = labelText.value;
return;
}
// If text has special characters or space, we wrap it with double quotes
if (specialCharRegex.test(newText)) {
newText = newText.replace(/"/g, ""); // remove existing double quotes
newText = `"${newText}"`;
specialCharRegex.lastIndex = 0;
}
if (newText.includes(" ")) {
newText = newText.replace(/\s+/g, " "); // remove extra spaces
}
if (!labelPositions?.value) return;
// If text has special characters or space, we wrap it with double quotes
if (specialCharRegex.test(newText)) {
newText = newText.replace(/"/g, ""); // remove existing double quotes
newText = `"${newText}"`;
specialCharRegex.lastIndex = 0;
}
// Sort the label positions in descending order to avoid index shifting
const labelPositionsArray = Array.from(labelPositions.value);
const reversedSortedLabelPositions = labelPositionsArray.sort(
(a, b) => JSON.parse(b)[0] - JSON.parse(a)[0],
);
if (!positions || positions.length === 0) return;
let newCode = code.value;
for (const labelPosition of reversedSortedLabelPositions) {
const [start, end] = JSON.parse(labelPosition);
newCode = newCode.slice(0, start) + newText + newCode.slice(end);
}
updateCode(newCode);
let newCode = code.value;
for (const position of positions) {
const [start, end] = position;
newCode = newCode.slice(0, start) + newText + newCode.slice(end);
}
updateCode(newCode);
};
}
const { editing, handleDblClick, handleBlur, handleKeydown, handleKeyup } =
useEditLabel(replaceLabelText);
const participantLabelHandler = useEditLabel(
replaceLabelTextWithaPositions(labelPositions?.value ?? []),
);
const assigneeLabelHandler = useEditLabel(
replaceLabelTextWithaPositions(assigneePositions?.value ?? []),
);
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
:style="{ paddingLeft: `${offsetX}px` }"
:context="blockInCritical"
:selfCallIndent="selfCallIndent"
:number="`number`"
:number="number"
></block>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
:style="{ paddingLeft: `${offsetX}px` }"
:context="blockInSection"
:selfCallIndent="selfCallIndent"
:number="`number`"
:number="number"
></block>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
:classNames="messageClassNames"
:textStyle="messageTextStyle"
:context="message"
:number="`${number}`"
:number="number"
/>
<message
v-else
Expand All @@ -47,7 +47,7 @@
:participant="to"
:selfCallIndent="passOnOffset"
:rtl="rightToLeft"
:number="`${number}`"
:number="number"
/>
<message
v-if="assignee && !isSelf"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ const messageRef = ref();
const labelPosition: ComputedRef<[number, number]> = computed(() => {
// do not use .signature(). Multiple signatures are allowed, e.g. method().method1().method2()
const func = context?.value.messageBody().func();
if (!func) return [-1, -1];
return [func.start.start, func.stop.stop];
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
:classNames="messageClassNames"
:textStyle="messageTextStyle"
:context="asyncMessage"
:number="`${number}`"
:number="number"
/>
<message
v-else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,12 @@ const labelText = computed(() => {
switch (type?.value) {
case "creation":
// Extract the creation name from the content
return content?.value.match(creationRegex)?.[1];
return content?.value.match(creationRegex)?.[1] || "";
case "sync":
case "async":
case "return":
default:
return content?.value;
return content?.value || "";
}
});
const labelPosition: ComputedRef<[number, number]> = computed(() => {
Expand Down Expand Up @@ -144,6 +144,9 @@ const labelPosition: ComputedRef<[number, number]> = computed(() => {
[start, stop] = [ret?.start.start, ret?.stop.stop];
} else if (context?.value instanceof sequenceParser.ContentContext) {
[start, stop] = [context.value.start.start, context.value.stop.stop];
} else if (context?.value instanceof sequenceParser.AssignmentContext) {
const assignee = context.value.assignee();
[start, stop] = [assignee.start.start, assignee.stop.stop];
}
}
break;
Expand Down
8 changes: 8 additions & 0 deletions src/parser/Owner.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ CreationContext.prototype.Assignee = function () {
return this.creationBody()?.assignment()?.assignee()?.getFormattedText();
};

CreationContext.prototype.AssigneePosition = function () {
const assignee = this.creationBody()?.assignment()?.assignee();
if (!assignee) {
return undefined;
}
return [assignee.start.start, assignee.stop.stop + 1];
};

CreationContext.prototype.Constructor = function () {
return this.creationBody()?.construct()?.getFormattedText();
};
Expand Down
28 changes: 10 additions & 18 deletions src/parser/Participants.spec.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import { Participants } from "../parser/Participants";
import { blankParticipant, Participants } from "../parser/Participants";

describe("Participants", () => {
test("Get implicitly declared participants", () => {
const participants = new Participants();
participants.Add("A");
expect(participants.ImplicitArray()).toEqual([
expect(participants.ImplicitArray().map((p) => p.ToValue())).toEqual([
{
...blankParticipant,
name: "A",
isStarter: undefined,
stereotype: undefined,
width: undefined,
},
]);
expect(participants.Starter()).toBeUndefined();
Expand All @@ -21,16 +19,12 @@ describe("Participants", () => {
participants.Add("A");
expect(participants.ImplicitArray()).toEqual([
{
...blankParticipant,
name: "B",
isStarter: undefined,
stereotype: undefined,
width: undefined,
},
{
...blankParticipant,
name: "A",
isStarter: undefined,
stereotype: undefined,
width: undefined,
},
]);
expect(participants.Starter()).toBeUndefined();
Expand All @@ -40,24 +34,22 @@ describe("Participants", () => {
const participants = new Participants();
participants.Add("A", { isStarter: true });
expect(participants.Starter()).toEqual({
...blankParticipant,
name: "A",
isStarter: true,
stereotype: undefined,
width: undefined,
});
participants.Add("A", {
...blankParticipant,
isStarter: false,
start: 1,
end: 2,
position: [1, 2],
explicit: true,
});
expect(participants.Starter()).toEqual({
...blankParticipant,
name: "A",
isStarter: true,
stereotype: undefined,
width: undefined,
explicit: true,
positions: new Set([[1, 2]]),
});
expect(participants.GetPositions("A")?.has("[1,2]"));
});
});
Loading

0 comments on commit 9fdb0b5

Please sign in to comment.