Repository: vuejs/vue-next
File: packages/runtime-dom/src/apiCustomElement.ts (TypeScript)

Code before:
   */
  private _childStyles?: Map<string, HTMLStyleElement[]>
  private _ob?: MutationObserver | null = null
  private _slots?: Record<string, Node[]>

  constructor(
    /**
     * Component def - note this may be an AsyncWrapper, and this._def will
     * be overwritten by the inner component when resolved.
     */
    private _def: InnerComponentDef,
    private _props: Record<string, any> = {},
    private _createApp: CreateAppFunction<Element> = createApp,
  ) {
    super()
    if (this.shadowRoot && _createApp !== createApp) {
      this._root = this.shadowRoot
    } else {
      if (__DEV__ && this.shadowRoot) {
        warn(
          `Custom element has pre-rendered declarative shadow root but is not ` +
            `defined as hydratable. Use \`defineSSRCustomElement\`.`,
        )
      }
      if (_def.shadowRoot !== false) {
        this.attachShadow(extend({ mode: 'open' }, _def.shadowRootOptions))
        this._root = this.shadowRoot!
      } else {
        this._root = this
      }
    }

    if (!(this._def as ComponentOptions).__asyncLoader) {
      // for sync component defs we can immediately resolve props
      this._resolveProps(this._def)
    }
  }

  connectedCallback(): void {
    // avoid resolving component if it's not connected
    if (!this.isConnected) return

    if (!this.shadowRoot) {
      this._parseSlots()
    }
    this._connected = true

    // locate nearest Vue custom element parent for provide/inject
    let parent: Node | null = this
    while (
      (parent = parent && (parent.parentNode || (parent as ShadowRoot).host))

Review comment (suggestion):
```suggestion
        this.attachShadow(extend({}, _def.shadowRootOptions,{ mode: 'open' }))
```
to avoid `mode` being overwritten

Code after:
   */
  private _childStyles?: Map<string, HTMLStyleElement[]>
  private _ob?: MutationObserver | null = null
  private _slots?: Record<string, Node[]>

  constructor(
    /**
     * Component def - note this may be an AsyncWrapper, and this._def will
     * be overwritten by the inner component when resolved.
     */
    private _def: InnerComponentDef,
    private _props: Record<string, any> = {},
    private _createApp: CreateAppFunction<Element> = createApp,
  ) {
    super()
    if (this.shadowRoot && _createApp !== createApp) {
      this._root = this.shadowRoot
    } else {
      if (__DEV__ && this.shadowRoot) {
        warn(
          `Custom element has pre-rendered declarative shadow root but is not ` +
            `defined as hydratable. Use \`defineSSRCustomElement\`.`,
        )
      }
      if (_def.shadowRoot !== false) {
        this.attachShadow(
          extend({}, _def.shadowRootOptions, {
            mode: 'open',
          }) as ShadowRootInit,
        )
        this._root = this.shadowRoot!
      } else {
        this._root = this
      }
    }
  }

  connectedCallback(): void {
    // avoid resolving component if it's not connected
    if (!this.isConnected) return

    // avoid re-parsing slots if already resolved
    if (!this.shadowRoot && !this._resolved) {
      this._parseSlots()
    }
    this._connected = true

    // locate nearest Vue custom element parent for provide/inject
    let parent: Node | null = this
    while (
      (parent = parent && (parent.parentNode || (parent as ShadowRoot).host))