docs: function (event, embedderFrameId, elementInstanceId, guestInstanceId, params) {
    const embedder = event.sender
    // Destroy the old guest when attaching.
    const key = `${embedder.id}-${elementInstanceId}`
    const oldGuestInstanceId = embedderElementsMap[key]
    if (oldGuestInstanceId != null) {
      // Reattachment to the same guest is just a no-op.
      if (oldGuestInstanceId === guestInstanceId) {
        return
      }
  
      const oldGuestInstance = guestInstances[oldGuestInstanceId]
      if (oldGuestInstance) {
        oldGuestInstance.guest.detachFromOuterFrame()
      }
    }
  
    const guestInstance = guestInstances[guestInstanceId]
    // If this isn't a valid guest instance then do nothing.
    if (!guestInstance) {
      throw new Error(`Invalid guestInstanceId: ${guestInstanceId}`)
    }
    const { guest } = guestInstance
    if (guest.hostWebContents !== event.sender) {
      throw new Error(`Access denied to guestInstanceId: ${guestInstanceId}`)
    }
  
    // If this guest is already attached to an element then remove it
    if (guestInstance.elementInstanceId) {
      const oldKey = `${guestInstance.embedder.id}-${guestInstance.elementInstanceId}`
      delete embedderElementsMap[oldKey]
  
      // Remove guest from embedder if moving across web views
      if (guest.viewInstanceId !== params.instanceId) {
        webViewManager.removeGuest(guestInstance.embedder, guestInstanceId)
        guestInstance.embedder._sendInternal(`ELECTRON_GUEST_VIEW_INTERNAL_DESTROY_GUEST-${guest.viewInstanceId}`)
      }
    }
  
    const webPreferences = {
      guestInstanceId: guestInstanceId,
      nodeIntegration: params.nodeintegration != null ? params.nodeintegration : false,
      nodeIntegrationInSubFrames: params.nodeintegrationinsubframes != null ? params.nodeintegrationinsubframes : false,
      enableRemoteModule: params.enableremotemodule,
      plugins: params.plugins,
      zoomFactor: embedder.getZoomFactor(),
      webSecurity: !params.disablewebsecurity,
      enableBlinkFeatures: params.blinkfeatures,
      disableBlinkFeatures: params.disableblinkfeatures
    }
  
    // parse the 'webpreferences' attribute string, if set
    // this uses the same parsing rules as window.open uses for its features
    if (typeof params.webpreferences === 'string') {
      parseFeaturesString(params.webpreferences, function (key, value) {
        if (value === undefined) {
          // no value was specified, default it to true
          value = true
        }
        webPreferences[key] = value
      })
    }
  
    if (params.preload) {
      webPreferences.preloadURL = params.preload
    }
  
    // Return null from native window.open if allowpopups is unset
    if (webPreferences.nativeWindowOpen === true && !params.allowpopups) {
      webPreferences.disablePopups = true
    }
  
    // Security options that guest will always inherit from embedder
    const inheritedWebPreferences = new Map([
      ['contextIsolation', true],
      ['javascript', false],
      ['nativeWindowOpen', true],
      ['nodeIntegration', false],
      ['enableRemoteModule', false],
      ['sandbox', true],
      ['nodeIntegrationInSubFrames', false]
    ])
  
    // Inherit certain option values from embedder
    const lastWebPreferences = embedder.getLastWebPreferences()
    for (const [name, value] of inheritedWebPreferences) {
      if (lastWebPreferences[name] === value) {
        webPreferences[name] = value
      }
    }
  
    embedder.emit('will-attach-webview', event, webPreferences, params)
    if (event.defaultPrevented) {
      if (guest.viewInstanceId == null) guest.viewInstanceId = params.instanceId
      guest.destroy()
      return
    }
  
    guest.attachParams = params
    embedderElementsMap[key] = guestInstanceId
  
    guest.setEmbedder(embedder)
    guestInstance.embedder = embedder
    guestInstance.elementInstanceId = elementInstanceId
  
    watchEmbedder(embedder)
  
    webViewManager.addGuest(guestInstanceId, elementInstanceId, embedder, guest, webPreferences)
    guest.attachToIframe(embedder, embedderFrameId)
  }