mouseDown (evt, mouseTarget, startX, startY) {
      let id
      if (svgCanvas.getCurrentMode() === 'path') {
        let mouseX = startX // Was this meant to work with the other `mouseX`? (was defined globally so adding `let` to at least avoid a global)
        let mouseY = startY // Was this meant to work with the other `mouseY`? (was defined globally so adding `let` to at least avoid a global)

        const zoom = svgCanvas.getZoom()
        let x = mouseX / zoom
        let y = mouseY / zoom
        let stretchy = getElement('path_stretch_line')
        newPoint = [x, y]

        if (svgCanvas.getGridSnapping()) {
          x = snapToGrid(x)
          y = snapToGrid(y)
          mouseX = snapToGrid(mouseX)
          mouseY = snapToGrid(mouseY)
        }

        if (!stretchy) {
          stretchy = document.createElementNS(NS.SVG, 'path')
          assignAttributes(stretchy, {
            id: 'path_stretch_line',
            stroke: '#22C',
            'stroke-width': '0.5',
            fill: 'none'
          })
          getElement('selectorParentGroup').append(stretchy)
        }
        stretchy.setAttribute('display', 'inline')

        let keep = null
        let index
        // if pts array is empty, create path element with M at current point
        const drawnPath = svgCanvas.getDrawnPath()
        if (!drawnPath) {
          const dAttr = 'M' + x + ',' + y + ' ' // Was this meant to work with the other `dAttr`? (was defined globally so adding `var` to at least avoid a global)
          /* drawnPath = */ svgCanvas.setDrawnPath(svgCanvas.addSVGElementsFromJson({
            element: 'path',
            curStyles: true,
            attr: {
              d: dAttr,
              id: svgCanvas.getNextId(),
              opacity: svgCanvas.getOpacity() / 2
            }
          }))
          // set stretchy line to first point
          stretchy.setAttribute('d', ['M', mouseX, mouseY, mouseX, mouseY].join(' '))
          index = subpath ? path.segs.length : 0
          svgCanvas.addPointGrip(index, mouseX, mouseY)
        } else {
          // determine if we clicked on an existing point
          const seglist = drawnPath.pathSegList
          let i = seglist.numberOfItems
          const FUZZ = 6 / zoom
          let clickOnPoint = false
          while (i) {
            i--
            const item = seglist.getItem(i)
            const px = item.x; const py = item.y
            // found a matching point
            if (x >= (px - FUZZ) && x <= (px + FUZZ) &&
              y >= (py - FUZZ) && y <= (py + FUZZ)
            ) {
              clickOnPoint = true
              break
            }
          }

          // get path element that we are in the process of creating
          id = svgCanvas.getId()

          // Remove previous path object if previously created
          svgCanvas.removePath_(id)

          const newpath = getElement(id)
          let newseg
          let sSeg
          const len = seglist.numberOfItems
          // if we clicked on an existing point, then we are done this path, commit it
          // (i, i+1) are the x,y that were clicked on
          if (clickOnPoint) {
            // if clicked on any other point but the first OR
            // the first point was clicked on and there are less than 3 points
            // then leave the path open
            // otherwise, close the path
            if (i <= 1 && len >= 2) {
              // Create end segment
              const absX = seglist.getItem(0).x
              const absY = seglist.getItem(0).y

              sSeg = stretchy.pathSegList.getItem(1)
              newseg = sSeg.pathSegType === 4
                ? drawnPath.createSVGPathSegLinetoAbs(absX, absY)
                : drawnPath.createSVGPathSegCurvetoCubicAbs(absX, absY, sSeg.x1 / zoom, sSeg.y1 / zoom, absX, absY)

              const endseg = drawnPath.createSVGPathSegClosePath()
              seglist.appendItem(newseg)
              seglist.appendItem(endseg)
            } else if (len < 3) {
              keep = false
              return keep
            }
            stretchy.remove()

            // This will signal to commit the path
            // const element = newpath; // Other event handlers define own `element`, so this was probably not meant to interact with them or one which shares state (as there were none); I therefore adding a missing `var` to avoid a global
            /* drawnPath = */ svgCanvas.setDrawnPath(null)
            svgCanvas.setStarted(false)

            if (subpath) {
              if (path.matrix) {
                svgCanvas.remapElement(newpath, {}, path.matrix.inverse())
              }

              const newD = newpath.getAttribute('d')
              const origD = path.elem.getAttribute('d')
              path.elem.setAttribute('d', origD + newD)
              newpath.parentNode.removeChild(newpath)
              if (path.matrix) {
                svgCanvas.recalcRotatedPath()
              }
              pathActionsMethod.toEditMode(path.elem)
              path.selectPt()
              return false
            }
          // else, create a new point, update path element
          } else {
            // Checks if current target or parents are #svgcontent
            if (!(svgCanvas.getContainer() !== svgCanvas.getMouseTarget(evt) && svgCanvas.getContainer().contains(
              svgCanvas.getMouseTarget(evt)
            ))) {
              // Clicked outside canvas, so don't make point
              return false
            }

            const num = drawnPath.pathSegList.numberOfItems
            const last = drawnPath.pathSegList.getItem(num - 1)
            const lastx = last.x; const lasty = last.y

            if (evt.shiftKey) {
              const xya = snapToAngle(lastx, lasty, x, y);
              ({ x, y } = xya)
            }

            // Use the segment defined by stretchy
            sSeg = stretchy.pathSegList.getItem(1)
            newseg = sSeg.pathSegType === 4
              ? drawnPath.createSVGPathSegLinetoAbs(svgCanvas.round(x), svgCanvas.round(y))
              : drawnPath.createSVGPathSegCurvetoCubicAbs(
                svgCanvas.round(x),
                svgCanvas.round(y),
                sSeg.x1 / zoom,
                sSeg.y1 / zoom,
                sSeg.x2 / zoom,
                sSeg.y2 / zoom
              )

            drawnPath.pathSegList.appendItem(newseg)

            x *= zoom
            y *= zoom

            // set stretchy line to latest point
            stretchy.setAttribute('d', ['M', x, y, x, y].join(' '))
            index = num
            if (subpath) { index += path.segs.length }
            svgCanvas.addPointGrip(index, x, y)
          }
          // keep = true;
        }

        return undefined
      }

      // TODO: Make sure currentPath isn't null at this point
      if (!path) { return undefined }

      path.storeD();

      ({ id } = evt.target)
      let curPt
      if (id.substr(0, 14) === 'pathpointgrip_') {
        // Select this point
        curPt = path.cur_pt = Number.parseInt(id.substr(14))
        path.dragging = [startX, startY]
        const seg = path.segs[curPt]

        // only clear selection if shift is not pressed (otherwise, add
        // node to selection)
        if (!evt.shiftKey) {
          if (path.selected_pts.length <= 1 || !seg.selected) {
            path.clearSelection()
          }
          path.addPtsToSelection(curPt)
        } else if (seg.selected) {
          path.removePtFromSelection(curPt)
        } else {
          path.addPtsToSelection(curPt)
        }
      } else if (id.startsWith('ctrlpointgrip_')) {
        path.dragging = [startX, startY]

        const parts = id.split('_')[1].split('c')
        curPt = Number(parts[0])
        const ctrlNum = Number(parts[1])
        path.selectPt(curPt, ctrlNum)
      }

      // Start selection box
      if (!path.dragging) {
        let rubberBox = svgCanvas.getRubberBox()
        if (!rubberBox) {
          rubberBox = svgCanvas.setRubberBox(
            svgCanvas.selectorManager.getRubberBandBox()
          )
        }
        const zoom = svgCanvas.getZoom()
        assignAttributes(rubberBox, {
          x: startX * zoom,
          y: startY * zoom,
          width: 0,
          height: 0,
          display: 'inline'
        }, 100)
      }
      return undefined
    }
@param {MouseEvent} evt
@param {Element} mouseTarget
@param {Float} startX
@param {Float} startY
@returns {boolean|void}