You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@daffodil.apache.org by rs...@apache.org on 2023/08/15 21:03:05 UTC

[daffodil-vscode] branch main updated: Implement Byte Insertion Keybinds Hotfix

This is an automated email from the ASF dual-hosted git repository.

rstrickland pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/daffodil-vscode.git


The following commit(s) were added to refs/heads/main by this push:
     new dc09b8c  Implement Byte Insertion Keybinds Hotfix
dc09b8c is described below

commit dc09b8cd72873a64a87a417efdc0e5fef53896d0
Author: Robert Strickland <st...@gmail.com>
AuthorDate: Tue Aug 15 11:18:29 2023 -0500

    Implement Byte Insertion Keybinds Hotfix
    
    - Fixes issue where byte insertions did not have associated keybinds.
    
    Closes #813
---
 .../CustomByteDisplay/SelectedByteEdit.svelte      | 34 ++++++++----
 src/svelte/src/components/dataEditor.svelte        |  9 ++-
 src/svelte/src/utilities/elementKeypressEvents.ts  | 64 ++++++++++++++++++++++
 src/svelte/src/utilities/enterKeypressEvents.ts    | 44 ---------------
 4 files changed, 94 insertions(+), 57 deletions(-)

diff --git a/src/svelte/src/components/DataDisplays/CustomByteDisplay/SelectedByteEdit.svelte b/src/svelte/src/components/DataDisplays/CustomByteDisplay/SelectedByteEdit.svelte
index b46adb4..f78424d 100644
--- a/src/svelte/src/components/DataDisplays/CustomByteDisplay/SelectedByteEdit.svelte
+++ b/src/svelte/src/components/DataDisplays/CustomByteDisplay/SelectedByteEdit.svelte
@@ -35,7 +35,7 @@ limitations under the License.
     editorActionsAllowed,
     bytesPerRow,
   } from '../../../stores'
-  import { enterKeypressEvents } from '../../../utilities/enterKeypressEvents'
+  import { elementKeypressEventMap } from '../../../utilities/elementKeypressEvents'
   import type { ByteValue, EditAction } from './BinaryData'
   import {
     UIThemeCSSClass,
@@ -86,14 +86,6 @@ limitations under the License.
     },
   }
 
-  enterKeypressEvents.register({
-    id: actionElements.input.id,
-    run: () => {
-      if (invalid || inProgress) return
-      applyChanges('byte-input')
-    },
-  })
-
   export let byte: ByteValue
   let target: HTMLDivElement
   let targetParent: HTMLDivElement
@@ -140,6 +132,23 @@ limitations under the License.
     }
   }
 
+  elementKeypressEventMap.register('Enter', {
+    elementId: actionElements.input.id,
+    run: (keyEvent: KeyboardEvent) => {
+      if (is_input_invalid() || is_input_inprogress()) return
+      if (keyEvent.shiftKey && !keyEvent.ctrlKey) applyChanges('insert-after')
+      else if (!keyEvent.shiftKey && keyEvent.ctrlKey)
+        applyChanges('insert-before')
+      else applyChanges('byte-input')
+    },
+  })
+  elementKeypressEventMap.register('Delete', {
+    elementId: actionElements.input.id,
+    run: (keyEvent: KeyboardEvent) => {
+      applyChanges('delete')
+    },
+  })
+
   onMount(() => {
     target = document.getElementById(targetElementId) as HTMLDivElement
     if (target) targetParent = target.parentElement as HTMLDivElement
@@ -159,7 +168,12 @@ limitations under the License.
 
     return restore_original_target
   })
-
+  function is_input_invalid() {
+    return invalid
+  }
+  function is_input_inprogress() {
+    return inProgress
+  }
   function grab_action_element_refs() {
     for (const element in actionElements)
       actionElements[element as Actions].HTMLRef = document.getElementById(
diff --git a/src/svelte/src/components/dataEditor.svelte b/src/svelte/src/components/dataEditor.svelte
index 4cb9c24..8af8309 100644
--- a/src/svelte/src/components/dataEditor.svelte
+++ b/src/svelte/src/components/dataEditor.svelte
@@ -48,7 +48,10 @@ limitations under the License.
   import Main from './Main.svelte'
   import { EditByteModes, NUM_LINES_DISPLAYED } from '../stores/configuration'
   import ServerMetrics from './ServerMetrics/ServerMetrics.svelte'
-  import { enterKeypressEvents } from '../utilities/enterKeypressEvents'
+  import {
+    elementKeypressEventMap,
+    key_is_mappable,
+  } from '../utilities/elementKeypressEvents'
   import type {
     EditEvent,
     ViewportData_t,
@@ -235,8 +238,8 @@ limitations under the License.
 
   function handleKeyBind(event: Event) {
     const kbdEvent = event as KeyboardEvent
-    if (kbdEvent.key === 'Enter') {
-      enterKeypressEvents.run(document.activeElement.id)
+    if (key_is_mappable(kbdEvent.key)) {
+      elementKeypressEventMap.run(document.activeElement.id, kbdEvent)
       return
     }
     if ($editMode === EditByteModes.Multiple) return
diff --git a/src/svelte/src/utilities/elementKeypressEvents.ts b/src/svelte/src/utilities/elementKeypressEvents.ts
new file mode 100644
index 0000000..8cbabc8
--- /dev/null
+++ b/src/svelte/src/utilities/elementKeypressEvents.ts
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+type ElementKeypressEventKey = 'Enter' | 'Delete'
+const MappableKeys: { [k in ElementKeypressEventKey]: true } = {
+  Enter: true,
+  Delete: true,
+}
+
+type ElementKeypressEvent = {
+  elementId: string
+  run: (keyEvent: KeyboardEvent) => void
+}
+
+class ElementKeypressEventMap {
+  // private events: Array<ElementKeypressEvent> = []
+  private events: {
+    [key in ElementKeypressEventKey]: Array<ElementKeypressEvent>
+  } = {
+    Delete: [],
+    Enter: [],
+  }
+
+  public register(key: ElementKeypressEventKey, event: ElementKeypressEvent) {
+    this.remove_and_replace(key, event)
+  }
+
+  public run(elementId: string, keyEvent: KeyboardEvent) {
+    this.events[keyEvent.key].forEach((eventItem) => {
+      if (eventItem.elementId === elementId) eventItem.run(keyEvent)
+    })
+  }
+
+  private remove_and_replace(
+    key: ElementKeypressEventKey,
+    event: ElementKeypressEvent
+  ) {
+    const replaceIndex = this.events[key].findIndex((storedEvent) => {
+      return storedEvent.elementId === event.elementId
+    })
+
+    replaceIndex >= 0
+      ? (this.events[key][replaceIndex] = event)
+      : this.events[key].push(event)
+  }
+}
+export function key_is_mappable(eventKey: string): boolean {
+  return MappableKeys[eventKey as ElementKeypressEventKey] === true
+}
+
+export let elementKeypressEventMap = new ElementKeypressEventMap()
diff --git a/src/svelte/src/utilities/enterKeypressEvents.ts b/src/svelte/src/utilities/enterKeypressEvents.ts
deleted file mode 100644
index cc487e9..0000000
--- a/src/svelte/src/utilities/enterKeypressEvents.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-type EnterKeypressEvent = {
-  id: string
-  run: () => void
-}
-
-class EnterKeypressEvents {
-  private events: Array<EnterKeypressEvent> = []
-
-  public register(event: EnterKeypressEvent) {
-    this.remove(event.id)
-    this.events.push(event)
-  }
-
-  public run(elementId: string) {
-    this.events.forEach((eventItem) => {
-      if (eventItem.id === elementId) eventItem.run()
-    })
-  }
-
-  private remove(eventId: string) {
-    this.events = this.events.filter((event) => {
-      return event.id === eventId
-    })
-  }
-}
-
-export let enterKeypressEvents = new EnterKeypressEvents()