updateContextPanel () {
    let elem = this.editor.selectedElement
    // If element has just been deleted, consider it null
    if (!elem?.parentNode) {
      elem = null
    }
    const currentLayerName = this.editor.svgCanvas
      .getCurrentDrawing()
      .getCurrentLayerName()
    const currentMode = this.editor.svgCanvas.getMode()
    const unit =
      this.editor.configObj.curConfig.baseUnit !== 'px'
        ? this.editor.configObj.curConfig.baseUnit
        : null

    const isNode = currentMode === 'pathedit'
    const menuItems = document.getElementById('se-cmenu_canvas')
    this.hideTool('selected_panel')
    this.hideTool('multiselected_panel')
    this.hideTool('g_panel')
    this.hideTool('rect_panel')
    this.hideTool('circle_panel')
    this.hideTool('ellipse_panel')
    this.hideTool('line_panel')
    this.hideTool('text_panel')
    this.hideTool('image_panel')
    this.hideTool('container_panel')
    this.hideTool('use_panel')
    this.hideTool('a_panel')
    this.hideTool('xy_panel')
    if (elem) {
      const elname = elem.nodeName

      const angle = this.editor.svgCanvas.getRotationAngle(elem)
      $id('angle').value = angle

      const blurval = this.editor.svgCanvas.getBlur(elem) * 10
      $id('blur').value = blurval

      if (
        this.editor.svgCanvas.addedNew &&
        elname === 'image' &&
        this.editor.svgCanvas.getMode() === 'image' &&
        !this.editor.svgCanvas.getHref(elem).startsWith('data:')
      ) {
        /* await */ this.promptImgURL({ cancelDeletes: true })
      }

      if (!isNode && currentMode !== 'pathedit') {
        this.displayTool('selected_panel')
        // Elements in this array already have coord fields
        if (['line', 'circle', 'ellipse', 'polygon'].includes(elname)) {
          this.hideTool('xy_panel')
        } else {
          let x
          let y

          // Get BBox vals for g, polyline and path
          if (['g', 'polyline', 'path'].includes(elname)) {
            const bb = this.editor.svgCanvas.getStrokedBBox([elem])
            if (bb) {
              ;({ x, y } = bb)
            }
          } else {
            x = elem.getAttribute('x')
            y = elem.getAttribute('y')
          }

          if (unit) {
            x = convertUnit(x)
            y = convertUnit(y)
          }
          /**
           * Updates the value of an input field if needed
           * @param {string} id - The ID of the input element to be updated.
           * @param {number} newValue - The new numeric value to set in the input field.
           */
          const updateValue = (id, newValue) => {
            const currentValue = $id(id).value // Get current value from the field
            // do nothing if nothing changed...
            if (parseFloat(currentValue) === newValue) {
              return
            }
            $id(id).value = newValue
          }

          updateValue('selected_x', x)
          updateValue('selected_y', y)

          this.displayTool('xy_panel')
        }

        // Elements in this array cannot be converted to a path
        if (['image', 'text', 'path', 'g', 'use'].includes(elname)) {
          this.hideTool('tool_topath')
        } else {
          this.displayTool('tool_topath')
        }
        if (elname === 'path') {
          this.displayTool('tool_reorient')
        } else {
          this.hideTool('tool_reorient')
        }
        $id('tool_reorient').disabled = angle === 0
      } else {
        const point = this.path.getNodePoint()
        $id('tool_add_subpath').pressed = false
        !this.path.canDeleteNodes
          ? $id('tool_node_delete').classList.add('disabled')
          : $id('tool_node_delete').classList.remove('disabled')

        // Show open/close button based on selected point
        // setIcon('#tool_openclose_path', path.closed_subpath ? 'open_path' : 'close_path');

        if (point) {
          const segType = $id('seg_type')
          if (unit) {
            point.x = convertUnit(point.x)
            point.y = convertUnit(point.y)
          }
          $id('path_node_x').value = point.x
          $id('path_node_y').value = point.y
          if (point.type) {
            segType.value = point.type
            segType.removeAttribute('disabled')
          } else {
            segType.value = 4
            segType.setAttribute('disabled', 'disabled')
          }
        }
        return
      }

      // update contextual tools here
      const panels = {
        g: [],
        a: [],
        rect: ['rx', 'width', 'height'],
        image: ['width', 'height'],
        circle: ['cx', 'cy', 'r'],
        ellipse: ['cx', 'cy', 'rx', 'ry'],
        line: ['x1', 'y1', 'x2', 'y2'],
        text: [],
        use: []
      }

      const { tagName } = elem

      let linkHref = null
      if (tagName === 'a') {
        linkHref = this.editor.svgCanvas.getHref(elem)
        this.displayTool('g_panel')
      }
      // siblings
      if (elem.parentNode) {
        const selements = Array.prototype.filter.call(
          elem.parentNode.children,
          function (child) {
            return child !== elem
          }
        )
        if (elem.parentNode.tagName === 'a' && !selements.length) {
          this.displayTool('a_panel')
          linkHref = this.editor.svgCanvas.getHref(elem.parentNode)
        }
      }

      // Hide/show the make_link buttons
      if (linkHref) {
        this.displayTool('tool_make_link')
        this.displayTool('tool_make_link_multi')
        $id('link_url').value = linkHref
      } else {
        this.hideTool('tool_make_link')
        this.hideTool('tool_make_link_multi')
      }

      if (panels[tagName]) {
        const curPanel = panels[tagName]
        this.displayTool(tagName + '_panel')

        curPanel.forEach(item => {
          let attrVal = elem.getAttribute(item)
          if (this.editor.configObj.curConfig.baseUnit !== 'px' && elem[item]) {
            const bv = elem[item].baseVal.value
            attrVal = convertUnit(bv)
          }
          $id(`${tagName}_${item}`).value = attrVal || 0
        })

        if (tagName === 'text') {
          this.displayTool('text_panel')
          $id('tool_italic').pressed = this.editor.svgCanvas.getItalic()
          $id('tool_bold').pressed = this.editor.svgCanvas.getBold()
          $id('tool_text_decoration_underline').pressed =
            this.editor.svgCanvas.hasTextDecoration('underline')
          $id('tool_text_decoration_linethrough').pressed =
            this.editor.svgCanvas.hasTextDecoration('line-through')
          $id('tool_text_decoration_overline').pressed =
            this.editor.svgCanvas.hasTextDecoration('overline')
          $id('tool_font_family').value = elem.getAttribute('font-family')
          $id('tool_text_anchor').setAttribute(
            'value',
            elem.getAttribute('text-anchor')
          )
          $id('font_size').value = elem.getAttribute('font-size')
          $id('tool_letter_spacing').value =
            elem.getAttribute('letter-spacing') ?? 0
          $id('tool_word_spacing').value =
            elem.getAttribute('word-spacing') ?? 0
          $id('tool_text_length').value = elem.getAttribute('textLength') ?? 0
          $id('tool_length_adjust').value =
            elem.getAttribute('lengthAdjust') ?? 0
          $id('text').value = elem.textContent
          if (this.editor.svgCanvas.addedNew) {
            // Timeout needed for IE9
            setTimeout(() => {
              $id('text').focus()
              $id('text').select()
            }, 100)
          }
          // text
        } else if (
          tagName === 'image' &&
          this.editor.svgCanvas.getMode() === 'image'
        ) {
          this.editor.svgCanvas.setImageURL(this.editor.svgCanvas.getHref(elem))
          // image
        } else if (tagName === 'g' || tagName === 'use') {
          this.displayTool('container_panel')
          const title = this.editor.svgCanvas.getTitle()
          const label = $id('g_title')
          label.value = title
          $id('g_title').disabled = tagName === 'use'
        }
      }
      menuItems.setAttribute(
        (tagName === 'g' ? 'en' : 'dis') + 'ablemenuitems',
        '#ungroup'
      )
      menuItems.setAttribute(
        (tagName === 'g' || !this.multiselected ? 'dis' : 'en') +
          'ablemenuitems',
        '#group'
      )

      // if (elem)
    } else if (this.multiselected) {
      // Check if all selected elements are 'text' nodes, if yes enable text panel
      const selElems = this.editor.svgCanvas.getSelectedElements()
      if (selElems.every(elem => elem.tagName === 'text')) {
        this.displayTool('text_panel')
      }

      this.displayTool('multiselected_panel')
      menuItems.setAttribute('enablemenuitems', '#group')
      menuItems.setAttribute('disablemenuitems', '#ungroup')
    } else {
      menuItems.setAttribute(
        'disablemenuitems',
        '#delete,#cut,#copy,#group,#ungroup,#move_front,#move_up,#move_down,#move_back'
      )
    }

    // update history buttons
    $id('tool_undo').disabled =
      this.editor.svgCanvas.undoMgr.getUndoStackSize() === 0
    $id('tool_redo').disabled =
      this.editor.svgCanvas.undoMgr.getRedoStackSize() === 0

    this.editor.svgCanvas.addedNew = false

    if ((elem && !isNode) || this.multiselected) {
      // update the selected elements' layer
      $id('selLayerNames').removeAttribute('disabled')
      $id('selLayerNames').value = currentLayerName
      $id('selLayerNames').setAttribute('value', currentLayerName)

      // Enable regular menu options
      const canCMenu = document.getElementById('se-cmenu_canvas')
      canCMenu.setAttribute(
        'enablemenuitems',
        '#delete,#cut,#copy,#move_front,#move_up,#move_down,#move_back'
      )
    } else {
      $id('selLayerNames').setAttribute('disabled', 'disabled')
    }
  }
Updates the context panel tools based on the selected element.
@returns {void}