diff --git a/src/components/LabelSlot.vue b/src/components/LabelSlot.vue index ce05674..d7f91bc 100644 --- a/src/components/LabelSlot.vue +++ b/src/components/LabelSlot.vue @@ -234,11 +234,7 @@ export default Vue.extend({ }, focused(): boolean { - // We need to keep update of the label slots structure's "isFocused" flag, because using the keyboard to navigate will not - // update this flag -- but we always end up here when the focus (for slots) is updated. - const isSlotFocused = this.appStore.isEditableFocused(this.coreSlotInfo); - (this.$parent as InstanceType).isFocused = isSlotFocused; - return isSlotFocused; + return this.appStore.isEditableFocused(this.coreSlotInfo); }, UID(): string { @@ -337,6 +333,9 @@ export default Vue.extend({ // Event callback equivalent to what would happen for a focus event callback // (the spans don't get focus anymore because the containg editable div grab it) onGetCaret(event: MouseEvent): void { + let parent = this.$parent as InstanceType; + Vue.nextTick(() => parent.updatePrependText()); + // If the user's code is being executed, or if the frame is disabled, we don't focus any slot, but we make sure we show the adequate frame cursor instead. if(this.isPythonExecuting || this.isDisabled){ event.stopImmediatePropagation(); @@ -508,6 +507,9 @@ export default Vue.extend({ // Event callback equivalent to what would happen for a blur event callback // (the spans don't get focus anymore because the containg editable div grab it) onLoseCaret(keepIgnoreKeyEventFlagOn?: boolean): void { + let parent = this.$parent as InstanceType; + Vue.nextTick(() => parent.updatePrependText()); + // Before anything, we make sure that the current frame still exists. if(this.appStore.frameObjects[this.frameId] != undefined){ if(!this.debugAC) { diff --git a/src/components/LabelSlotsStructure.vue b/src/components/LabelSlotsStructure.vue index ca1611a..7c1d81d 100644 --- a/src/components/LabelSlotsStructure.vue +++ b/src/components/LabelSlotsStructure.vue @@ -63,7 +63,6 @@ export default Vue.extend({ data: function() { return { ignoreBracketEmphasisCheck: false, // cf. isSlotEmphasised() - isFocused: false, prependText: "", // This is updated properly in updatePrependText() }; }, @@ -101,7 +100,7 @@ export default Vue.extend({ if (this.subSlots.length == 1) { // If we are on an optional label slots structure that doesn't contain anything yet, we only show the placeholder if we're focused const isOptionalEmpty = (this.appStore.frameObjects[this.frameId].frameType.labels[this.labelIndex].optionalSlot??false) && this.subSlots.length == 1 && this.subSlots[0].code.length == 0; - if(isOptionalEmpty && !this.isFocused){ + if(isOptionalEmpty && !this.isFocused()){ return [" "]; } return [(isFuncCallFrame) ? getFunctionCallDefaultText(this.frameId) : this.defaultText]; @@ -394,7 +393,6 @@ export default Vue.extend({ }, onFocus(){ - this.isFocused = true; this.updatePrependText(); // When the application gains focus again, the browser might try to give the first span of a div the focus (because the div may have been focused) // even if we have the blue caret showing. We do not let this happen. @@ -405,7 +403,6 @@ export default Vue.extend({ }, blurEditableSlot(){ - this.isFocused = false; this.updatePrependText(); // If a flag to ignore editable slot focus is set, we just revert it and do nothing else if(this.appStore.bypassEditableSlotBlurErrorCheck){ @@ -456,6 +453,18 @@ export default Vue.extend({ }, 200); }, + isFocused() { + // We check if we are the parent of the currently focused element, as it may be a contenteditable item within us: + var selectedElement = window.getSelection()?.focusNode; + while (selectedElement != null) { + if (selectedElement instanceof Element && selectedElement.id === this.labelSlotsStructDivId) { + return true; + } + selectedElement = selectedElement.parentNode; + } + return false; + }, + updatePrependText() { if (this.prependSelfWhenInClass) { const isInClass = useStore().frameObjects[getParentId(useStore().frameObjects[this.frameId])]?.frameType.type == DefIdentifiers.classdef; @@ -464,7 +473,7 @@ export default Vue.extend({ } else { const empty = this.subSlots.length == 0 || !this.subSlots.some((s) => s.code !== ""); - this.prependText = (this.isFocused || !empty) ? "self," : "self"; + this.prependText = (this.isFocused() || !empty) ? "self," : "self"; } } else {