-
Notifications
You must be signed in to change notification settings - Fork 3.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
"paste-html" – error when pasting content in which A tag is wrapped in a text-formatting tag (i.e. STRONG) #3350
Comments
For those facing this issue, for now, I am basically removing whatever "blocky Element" inside any text element. // Text
if (TEXT_TAGS[nodeName]) {
const attr = TEXT_TAGS[nodeName](el)
// Check for potential conflicts in the children Array
const nonTextChild = children.find(child => !Text.isText(child))
if (nonTextChild) {
// Reduce the children to only have leaf nodes (and remove whatever Block Elements we have in between)
children = children.reduce((acc: Descendant[], cur: Descendant) => {
if (!Text.isText(cur)) {
const leaves = Array.from(Node.texts(cur)).map((entry) => entry[0])
console.log(JSON.stringify(leaves, null, 4))
acc.push(...leaves)
}
return acc
}, [])
}
return children
.map(child => {
child.text = normalizeText(child.text)
return jsx(`text`, attr, child)
})
} |
The issue persists with the latest version of slate, even with this example https://github.com/ianstormtaylor/slate/blob/master/site/examples/paste-html.js |
What I did and it works for me great was to use the previous example and use the deserialize function like this:
Comparing it with the code that @lazharichir did I just added this:
It just returns what |
@MontoyaAndres's solution worked for me, however I would suggest
|
Why filter instead of find? |
Maybe I'm misunderstanding your logic, but I'm thinking the goal is to return only valid children of the text node. Since find() returns 'undefined' if there aren't any, but filter() will always return an array, it just seems cleaner to me. |
Interesting, thanks! |
in my case i just did this and it works but there was just a
|
There also needs to be a check for |
This should be fixed in Slate 0.66.0. Regarding this:
Usually the way I handle this is to never reach a paste html handler if there's already application/x-slate-fragment. That said, some would argue that it should only be treated as a slate fragment if it comes from your own domain and not from someone else's slate-based editor which likely has a different ast. |
I am still seeing this issue in paste-html example. Is example code updated with latest version? |
Can we have a proper solution here, please? We can't ignore part of the text just because of HTML order!
To
|
This one preserves both the link and its formatting style applied by the wrapping tag, for other nonText elements we can do similar (AI helps a lot with generating regexes)
|
This HTML gets correctly deserialized: <p>
<em>text</em>
<a href="#">
<em>link title</em>
</a>
<em>text</em>
</p> this not: <p>
<em>text</em>
<em>
<a href="#">link title</a>
</em>
<em>text</em>
</p> The problem here is that if ((TEXT_TAGS as any)[nodeName]) {
const attrs = (TEXT_TAGS as any)[nodeName](el);
return children.map((child) => jsx('text', attrs, child));
} I changed it to if ((TEXT_TAGS as any)[nodeName]) {
const attrs = (TEXT_TAGS as any)[nodeName](el);
if (el.children.length > 0) {
return Array.from(el.childNodes).map((child: any) => {
if (child.nodeType === Node.TEXT_NODE) {
return jsx('text', attrs, child.textContent);
} else {
const parsed = new DOMParser().parseFromString(
typeof child === 'string' ? child : child.outerHTML,
'text/html',
);
return deserialize(parsed.body);
}
});
} else {
return jsx('text', attrs, el.textContent);
}
} and it worked. The complete HTML is displayed, including the nested link with href and link title. |
Do you want to request a feature or report a bug?
Bug
What's the current behavior?
Go to https://hungerlyyak.htmlpasta.com/ and copy the content. The HTML is below:
Then, go to the paste-html example. Open your developer console. Paste the content in the Slate Editor. It triggers an error:
Uncaught Error: The <text> hyperscript tag can only contain text content as children.
This is because the
<strong>
tag becomes a text tag (withbold: true
) and then, there is anElement
nested in it ({ type: "link", url:"https://example.com/", children: [{ text: "and this A link" }] }
– which is a forbidden nesting as per Slate's constraints.Slate: 0.56.9
Browser: All
OS: Mac
What's the expected behavior?
I think the bolding should transfer and apply to the
Text leaves
nested within theLink Element
.The text was updated successfully, but these errors were encountered: