0

I have this extension where it allows user to make a list of notes, and it starts to watch the focused element's user input using content scripts, and if user activates an option in it, it will start the function.

let Notes // Declare the Notes variable outside the function to make it accessible globally

const createNoteListContainer = (notes) => {
  // Create a <div> element to hold the list of notes
  const focusedElement = document.activeElement
  const focusedElementRect = focusedElement.getBoundingClientRect()
  const noteListContainer = document.createElement('ul')
  noteListContainer.style.backgroundColor = 'white'
  noteListContainer.style.Color = 'black'
  noteListContainer.classList.add('note-list-container')
  noteListContainer.style.position = 'absolute'
  noteListContainer.style.zIndex = 9999
  noteListContainer.style.padding = '10px'
  noteListContainer.style.boxShadow = '0 3px 10px 0 rgba(0,0,0,.2)'
  noteListContainer.style.borderRadius = '10px'
  noteListContainer.style.listStyle = 'none'
  noteListContainer.style.paddingLeft = '0'
  noteListContainer.style.maxHeight = '180px'
  noteListContainer.style.width = `${focusedElement.clientWidth}px`
  noteListContainer.style.marginTop = '10px'
  noteListContainer.style.overflowY = 'auto'
  noteListContainer.style.overflowX = 'hidden'

  // Add the notes to the note list container
  notes.forEach((note) => {
    const noteItem = document.createElement('li')
    const noteTitle = document.createElement('h4')
    const noteBody = document.createElement('p')
    noteTitle.style.fontWeight = 'bolder'
    noteTitle.style.fontSize = '16px'
    noteTitle.style.color = 'black'
    noteBody.style.color = 'black'
    noteItem.style.minHeight = '60px'
    noteItem.style.cursor = 'pointer'
    noteItem.style.width = '100%'
    noteItem.style.background = '#fff'
    noteItem.style.borderBottom = '1px solid rgba(0,0,0,.15)'
    noteItem.style.margin = '0 5px'
    noteItem.style.padding = '0 5px'
    noteItem.style.borderRadius = '3px'
    noteItem.addEventListener('mouseenter', () => {
      noteItem.style.background = '#f5f7f9'
    })
    noteItem.addEventListener('mouseleave', () => {
      noteItem.style.background = '#fff'
    })

    noteTitle.textContent = note.title
    noteBody.textContent = note.text
    noteItem.appendChild(noteTitle)
    noteItem.appendChild(noteBody)
    noteListContainer.appendChild(noteItem)
  })
  const distanceToBottom = getDistanceToBottomOfScreen(focusedElement)

  // Calculate the position based on the page height and focused element position
  const containerTop =
    distanceToBottom > 150
      ? focusedElementRect.top + focusedElement.clientHeight
      : focusedElementRect.bottom - 280
  noteListContainer.style.top = `${containerTop}px`
  noteListContainer.style.left = `${focusedElementRect.left}px`

  // Add the note list container to the document body
  document.body.appendChild(noteListContainer)
}
function getDistanceToBottomOfScreen(focusedElement) {
  // Get the bounding rectangle of the active element relative to the viewport
  const elementRect = focusedElement.getBoundingClientRect()

  // Get the viewport height
  const viewportHeight =
    window.innerHeight || document.documentElement.clientHeight

  // Calculate the distance from the bottom of the active element to the bottom of the screen
  const distanceToBottom = viewportHeight - elementRect.bottom
  return distanceToBottom
}
const RenderNotesList = async () => {
  const focusedElement = document.activeElement
  if (focusedElement.parentNode.className.includes('ant-dropdown-trigger')) {
    return
  }
  const checkElement = document.querySelector('.note-list-container')
  if (checkElement) {
    checkElement.remove()
  }
  const result = await chrome.storage.local.get(['AdvancedMode', 'Notes'])
  if (result.AdvancedMode) {
    Notes = result.Notes
    const input = focusedElement.value
    const matchingNotes = input
      ? Notes.filter((oldNote) => {
          return oldNote.title.toUpperCase().startsWith(input.toUpperCase())
        })
      : []
    if (matchingNotes.length > 0) {
      createNoteListContainer(matchingNotes)
    } else {
      if (checkElement) {
        checkElement.remove()
      }
    }
  }
}

const handleKeyboardInput = async (event) => {
  if (
    event.keyCode === 13
  ) {
    handleEnterInput(event)
  } else {
    RenderNotesList()
  }
}
const handleEnterInput = (event) => {
  const focusedElement = document.activeElement
  const checkElement = document.querySelector('.note-list-container')

  if (checkElement) {
    event.preventDefault()
    focusedElement.value = checkElement.querySelector('li p').innerHTML
    focusedElement.dispatchEvent(
      new Event('input', {
        bubbles: true,
      }),
    )
    checkElement.parentNode.removeChild(checkElement)
  }
}
document.activeElement.addEventListener('keydown', handleKeyboardInput, true)

my issue right now is that if the input (or textarea) does an action on the enter key being pressed (e.g: send a message or search for something) and there is an element with the class name " .note-list-container" the event.preventDefault() doesn't stop the action, how do I make it stop the action? i checked event.cancelable and its true I tried event.stopPropagation() still didn't work, I tried changing the keydown to keyup and keypress and didn't work.

mark
  • 51
  • 4
  • The site may be using event delegation (listening on document or window), so you need to attach the listener on `window` instead of document.activeElement, then check event.target ([example](/a/72085937)). – wOxxOm Jul 29 '23 at 07:28

0 Answers0