Giter VIP home page Giter VIP logo

Comments (4)

tx0c avatar tx0c commented on June 29, 2024 1

reproduced in the local demo, with same content <pre class="ql-syntax">first line\n第一段第一段第一段第一段第一段第一段第一段第一段第一段第一段\n</pre><p>2nd 第二段第二段第二段第二段第二段第二段第二段第二段第二段第二段second-line2</p><p>第三段第三段第三段第三段第三段第三段第三段第三段第三段第三段</p>, reproduced in the MattersArticleEditor but not ReactQuill

image

from matters-editor.

tx0c avatar tx0c commented on June 29, 2024 1

the minimum reproducible content is like this:

'<pre>Pre1\n</pre><p>Para2</p><p>Para3</p><p>Para4<p><p>Para5<p><p>Para6<p>'

turning into
image

in other words: all paragraphs except the last one are eaten up into the pre block

the root cause is at https://github.com/quilljs/quill/blame/1.3.7/modules/clipboard.js#L80-L85 because quill editor initialization code is calling same clipboard.convert which detects if current savedRange is a pre code-block, then read from its .innerText only dropping all .innerHTML and early return


thematters/matters-server#2285 only fixed part of the problem: if re-initialize the editor with the complete attributes, the preferred HTML from editor.getHTML()

'<pre class="ql-syntax" spellcheck="false">Pre1\n</pre><p>para2</p><p>para3</p>...'

then for some reason, the getFormat in https://github.com/quilljs/quill/blame/1.3.7/modules/clipboard.js#L80-L85 got an empty {} formats and does not early return;

from matters-editor.

tx0c avatar tx0c commented on June 29, 2024

Should be an initialization problem in the Editor,

  1. On reloading the page, the graphql reading the draft is still showing 2nd paragraph out of the pre block,
    image
fetch("https://server-develop.matters.news/graphql", {
  "headers": {
    "accept": "*/*",
    "accept-language": "en-US,en;q=0.9",
    "content-type": "application/json",
    // ...
  },
  "referrer": "https://web-develop.matters.news/",
  "referrerPolicy": "strict-origin-when-cross-origin",
  body: JSON.stringify({
  operationName: 'DraftDetailQuery',
  variables: { id: 'RHJhZnQ6OTMyMw' },
  extensions: {
    persistedQuery: {
      version: 1,
      sha256Hash: 'b7318ad6e8c00295c68f8a947c08a6384fb8ff0a8bebfe6ae8e00b12fbe800b5'
    }
  },
  query: `
query DraftDetailQuery($id: ID!) {
  viewer {
    id
    ownCircles {
      ...DigestRichCirclePublic
      __typename
    }
    __typename
  }
  node(input: {id: $id}) {
    id
    ... on Draft {
      ...EditorDraft
      ...PublishStateDraft
      ...EditMetaDraft
      __typename
    }
    __typename
  }
}

fragment EditorDraft on Draft {
  id
  title
  publishState
  content
  summary
  summaryCustomized
  __typename
}

fragment PublishStateDraft on Draft {
  id
  publishState
  article {
    id
    title
    slug
    mediaHash
    author {
      id
      userName
      __typename
    }
    __typename
  }
  __typename
}

fragment EditMetaDraft on Draft {
  id
  publishState
  cover
  assets {
    ...Asset
    __typename
  }
  tags
  collection(input: {first: null}) {
    edges {
      node {
        ...ArticleDigestDropdownArticle
        __typename
      }
      __typename
    }
    __typename
  }
  access {
    type
    circle {
      ...DigestRichCirclePublic
      __typename
    }
    __typename
  }
  license
  __typename
}

fragment ArticleDigestDropdownArticle on Article {
  id
  title
  articleState: state
  slug
  mediaHash
  author {
    id
    userName
    ...UserDigestMiniUser
    __typename
  }
  ...ArticleDigestTitleArticle
  __typename
}

fragment UserDigestMiniUser on User {
  id
  userName
  displayName
  status {
    state
    __typename
  }
  ...AvatarUser
  __typename
}

fragment AvatarUser on User {
  avatar
  liker {
    civicLiker
    __typename
  }
  info {
    badges {
      type
      __typename
    }
    __typename
  }
  __typename
}

fragment ArticleDigestTitleArticle on Article {
  id
  title
  articleState: state
  slug
  mediaHash
  author {
    id
    userName
    __typename
  }
  __typename
}

fragment Asset on Asset {
  id
  type
  path
  __typename
}

fragment DigestRichCirclePublic on Circle {
  id
  name
  displayName
  description
  owner {
    ...UserDigestMiniUser
    __typename
  }
  ...AvatarCircle
  ...FooterCirclePublic
  __typename
}

fragment AvatarCircle on Circle {
  avatar
  __typename
}

fragment FooterCirclePublic on Circle {
  id
  ...CountsCircle
  ...PriceCirclePublic
  __typename
}

fragment CountsCircle on Circle {
  id
  members(input: {first: 0}) {
    totalCount
    __typename
  }
  works(input: {first: 0}) {
    totalCount
    __typename
  }
  __typename
}

fragment PriceCirclePublic on Circle {
  id
  name
  prices {
    amount
    currency
    __typename
  }
  __typename
}`
  }),
  // "body": "{\"operationName\":\"DraftDetailQuery\",\"variables\":{\"id\":\"RHJhZnQ6OTMyMw\"},\"extensions\":{\"persistedQuery\":{\"version\":1,\"sha256Hash\":\"b7318ad6e8c00295c68f8a947c08a6384fb8ff0a8bebfe6ae8e00b12fbe800b5\"}},\"query\":\"query DraftDetailQuery($id: ID!) {\\n  viewer {\\n    id\\n    ownCircles {\\n      ...DigestRichCirclePublic\\n      __typename\\n    }\\n    __typename\\n  }\\n  node(input: {id: $id}) {\\n    id\\n    ... on Draft {\\n      ...EditorDraft\\n      ...PublishStateDraft\\n      ...EditMetaDraft\\n      __typename\\n    }\\n    __typename\\n  }\\n}\\n\\nfragment EditorDraft on Draft {\\n  id\\n  title\\n  publishState\\n  content\\n  summary\\n  summaryCustomized\\n  __typename\\n}\\n\\nfragment PublishStateDraft on Draft {\\n  id\\n  publishState\\n  article {\\n    id\\n    title\\n    slug\\n    mediaHash\\n    author {\\n      id\\n      userName\\n      __typename\\n    }\\n    __typename\\n  }\\n  __typename\\n}\\n\\nfragment EditMetaDraft on Draft {\\n  id\\n  publishState\\n  cover\\n  assets {\\n    ...Asset\\n    __typename\\n  }\\n  tags\\n  collection(input: {first: null}) {\\n    edges {\\n      node {\\n        ...ArticleDigestDropdownArticle\\n        __typename\\n      }\\n      __typename\\n    }\\n    __typename\\n  }\\n  access {\\n    type\\n    circle {\\n      ...DigestRichCirclePublic\\n      __typename\\n    }\\n    __typename\\n  }\\n  license\\n  __typename\\n}\\n\\nfragment ArticleDigestDropdownArticle on Article {\\n  id\\n  title\\n  articleState: state\\n  slug\\n  mediaHash\\n  author {\\n    id\\n    userName\\n    ...UserDigestMiniUser\\n    __typename\\n  }\\n  ...ArticleDigestTitleArticle\\n  __typename\\n}\\n\\nfragment UserDigestMiniUser on User {\\n  id\\n  userName\\n  displayName\\n  status {\\n    state\\n    __typename\\n  }\\n  ...AvatarUser\\n  __typename\\n}\\n\\nfragment AvatarUser on User {\\n  avatar\\n  liker {\\n    civicLiker\\n    __typename\\n  }\\n  info {\\n    badges {\\n      type\\n      __typename\\n    }\\n    __typename\\n  }\\n  __typename\\n}\\n\\nfragment ArticleDigestTitleArticle on Article {\\n  id\\n  title\\n  articleState: state\\n  slug\\n  mediaHash\\n  author {\\n    id\\n    userName\\n    __typename\\n  }\\n  __typename\\n}\\n\\nfragment Asset on Asset {\\n  id\\n  type\\n  path\\n  __typename\\n}\\n\\nfragment DigestRichCirclePublic on Circle {\\n  id\\n  name\\n  displayName\\n  description\\n  owner {\\n    ...UserDigestMiniUser\\n    __typename\\n  }\\n  ...AvatarCircle\\n  ...FooterCirclePublic\\n  __typename\\n}\\n\\nfragment AvatarCircle on Circle {\\n  avatar\\n  __typename\\n}\\n\\nfragment FooterCirclePublic on Circle {\\n  id\\n  ...CountsCircle\\n  ...PriceCirclePublic\\n  __typename\\n}\\n\\nfragment CountsCircle on Circle {\\n  id\\n  members(input: {first: 0}) {\\n    totalCount\\n    __typename\\n  }\\n  works(input: {first: 0}) {\\n    totalCount\\n    __typename\\n  }\\n  __typename\\n}\\n\\nfragment PriceCirclePublic on Circle {\\n  id\\n  name\\n  prices {\\n    amount\\n    currency\\n    __typename\\n  }\\n  __typename\\n}\\n\"}",
  "method": "POST",
  "mode": "cors",
  "credentials": "include"
});
  1. After Editor initialization, it is showing the 2nd paragraph inside the pre block
    image

  2. At the moment if click the Editor to start, have the mouse editing cursor, then it automatically calls putDraft to save, with the 2nd paragraph inside the pre block
    image

BTW, if use all English in 1st & 2nd paragraph it seems not reproducing;

from matters-editor.

tx0c avatar tx0c commented on June 29, 2024

a minimum reproducing with just the Quilt editor's default QuickStart code https://quilljs.com/docs/quickstart/

the root cause why it reproduced in MattersEditor not ReactQuill is MattersEditor always calling initializing twice (because of mention reference change after DOM mount); calling quill.setContents twice caused Quill is treating 2nd time as pasting into a pre code-block, and treating all content from .innerText only, and losing all html format

> quill.setContents( { ops:[] } )             // set with an empty Delta
Delta {ops: Array(1)}
> quill.setContents(quill.clipboard.convert('<pre>pre1</pre><p>p2</p><p>p3</p><p>p4 <b>bold</b> <a href="/link/to">link</a></p>')); quill.root.innerHTML
'<pre class="ql-syntax" spellcheck="false">pre1\n</pre><p>p2</p><p>p3</p><p>p4 <strong>bold</strong> <a href="/link/to" rel="noopener noreferrer" target="_blank">link</a></p>'
> quill.setContents(quill.clipboard.convert('<pre>pre1</pre><p>p2</p><p>p3</p><p>p4 <b>bold</b> <a href="/link/to">link</a></p>')); quill.root.innerHTML
'<pre class="ql-syntax" spellcheck="false">pre1\n\np2\n\np3\n\n</pre><p>p4 bold link</p>'

image

from matters-editor.

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.