Giter VIP home page Giter VIP logo

Comments (8)

braincomb avatar braincomb commented on July 21, 2024 3

Can confirm same issue with v3.44.0 on Firefox.

from sanity.

mariusGundersen avatar mariusGundersen commented on July 21, 2024 3

I've been trying to fix this. The problem is that Editable handlePaste awaits the onPaste prop callback, which doesn't work in Firefox. It also doesn't work in Chrome if the promise actually has any sort of delay. Probably it doesn't, which is why it works in Chrome but not in Firefox. This onPaste prop callback is the PortableTextInput handlePaste function, which looks like this:

    (input) => {
      const {event} = input
      extractPastedFiles(event.clipboardData)
        .then((files) => {
          return files.length > 0 ? files : []
        })
        .then((files) => {
          handleFiles(files)
        })
      return onPaste?.(input)
    }

So the promise chain here isn't awaited, which means it runs in parallel with the promise chain in the other function, which only depends on onPaste in the above code snippet. As noted in a previous comment, this onPaste is undefined, so there is nothing to await. This is actually checked for in Editable and it used to work, because the onPaste prop used to be just forwarded, before this commit.

This can be fixed if the code in Editable checks if the onPaste response is a promise or if it is undefined. It also needs to be wrapped with try/catch in order to behave the same, but that shouldn't be too difficult to do. It would be simpler to make the entire function async, but I'm not sure if that is OK with how it transpiles, so probably best to manually handle the promise chain and then duplicate the error handling. So to summarize, the method should look like this:

const handlePaste = useCallback(
    (event: ClipboardEvent<HTMLDivElement>): Promise<void> | void => {
      event.preventDefault()
      if (!slateEditor.selection) {
        return
      }
      if (!onPaste) {
        debug('Pasting normally')
        slateEditor.insertData(event.clipboardData)
        return
      }

      try{
        const value = PortableTextEditor.getValue(portableTextEditor)
        const ptRange = toPortableTextRange(value, slateEditor.selection, schemaTypes)
        const path = ptRange?.focus.path || []
        const result = onPaste({
            event,
            value,
            path,
            schemaTypes,
          })
          change$.next({type: 'loading', isLoading: true})
          if(!result){
            debug('No result from custom paste handler, pasting normally')
            slateEditor.insertData(event.clipboardData)
            return
          } else {
            Promise.resolve(result)
            .then((result) => {
              debug('Custom paste function from client resolved', result)
              change$.next({type: 'loading', isLoading: true})
              if (!result || !result.insert) {
                debug('No result from custom paste handler, pasting normally')
                slateEditor.insertData(event.clipboardData)
                return
              }
              if (result && result.insert) {
                slateEditor.insertFragment(
                  toSlateValue(result.insert as PortableTextBlock[], {schemaTypes}),
                )
                change$.next({type: 'loading', isLoading: false})
                return
              }
              console.warn('Your onPaste function returned something unexpected:', result)
            })
            .catch((error) => {
              change$.next({type: 'loading', isLoading: false})
              console.error(error) // eslint-disable-line no-console
            })
          }
      }catch(error){
        change$.next({type: 'loading', isLoading: false})
        console.error(error) // eslint-disable-line no-console
      }
    },
    [change$, onPaste, portableTextEditor, schemaTypes, slateEditor],
  )

from sanity.

ulumills avatar ulumills commented on July 21, 2024

Same issue here—it appears to be a Firefox-specific compatibility issue. When I switch to Chrome I can paste as normal.

Looking in the debugger, I see this in a comment above the error message:

We previously had support for reading datatransfer of strings here but decided to remove it since we don't handle it in higher up in the stack yet. If one day we want to support data transfer from a string value (e.g. copy+paste from a field to another), an earlier version of this file includes an implementation that uses DataTransferItem.getAsString to read the string value into a File

from sanity.

devmatteini avatar devmatteini commented on July 21, 2024

Same issue here, we are using sanity 3.43.0 with Node 18.

It works fine with Chrome and Safari.

from sanity.

mariusGundersen avatar mariusGundersen commented on July 21, 2024

Weirdly this warning is logged in Chrome as well, but there content is pasted. From the source it seems like this is all called from here, but the majority of this function deals with pasted files, which are ignored. It's the last line, return onPaste?.(input), which is what is really doing the pasting work.

from sanity.

mariusGundersen avatar mariusGundersen commented on July 21, 2024

Turns out the onPaste is undefined, so the call isn't being done.

But I found the problem, it is here. When debugging this function it turns out that event.clipboardData has content in this function, but not inside the .then((result) => {....}) callback, so it seems like event.clipboardData gets wiped after waiting for the promise to resolve.

Testing a bit and it seems like both Chrome and Firefox clear the clipboardData after awaiting a short timeout, but Chrome does not clear it when the promise resolves right await:

bucket.addEventListener('paste', async e => {
  bucket.textContent = 'Pasted!\n';
  new Promise(r => r()).then(r => {
    writeln(`Promised ${e.clipboardData.items.length}`); // this outputs 0 in Firefox but 2 in Chrome
  })
  new Promise(r => setTimeout(r, 1)).then(() => {
    writeln(`Timeout ${e.clipboardData.items.length}`);    // this outputs 0 in both Firefox and Chrome
  })
}, false);

You can try it out in both Chrome and Firefox here: https://codepen.io/mariusgundersen/full/dyEvbdj

from sanity.

jordanl17 avatar jordanl17 commented on July 21, 2024

An update has been made to the portable-text-editor specifically around pasting in Firefox. This update is released in v3.49.0. Could you please try this latest version to confirm whether this has resolved the issues you found?

from sanity.

braincomb avatar braincomb commented on July 21, 2024

An update has been made to the portable-text-editor specifically around pasting in Firefox. This update is released in v3.49.0. Could you please try this latest version to confirm whether this has resolved the issues you found?

Tested with Firefox 128.0. Pasting works!

Thanks!

from sanity.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.