-
Notifications
You must be signed in to change notification settings - Fork 1
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
fix(prose): update typing for Link
#360
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
78ae23f
to
7bdf5d8
Compare
attrs: { | ||
href: child.permalink, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
only relevant change because we update the href
to be inside attrs
now. i searched the 2 .js
files in this directory to check if we needed to update href
fact-check me @dcshzj if this is enoguh
add to tt extension
add detailed link schema with ref to tiptap
add nullable
update generation
15f1ee4
to
330c7f8
Compare
target: Type.Union([ | ||
// NOTE: Taken with reference to | ||
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-target | ||
// There's technically 1 more property - unfencedTop but we're disallowing | ||
// because it allows embedded frames to traverse beyond its root | ||
Type.Literal("_blank"), | ||
Type.Literal("_self"), | ||
Type.Literal("_parent"), | ||
Type.Literal("_top"), | ||
]), | ||
// NOTE: The href given by tiptap here | ||
// https://github.com/ueberdosis/tiptap/blob/main/packages/extension-link/src/link.ts | ||
// defaults to `null` href but href could also be passed as `undefined` | ||
href: Type.Union([Type.String(), Type.Null()]), | ||
rel: Type.String(), | ||
class: Type.Union([Type.String(), Type.Null()]), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue: I don't think we should match the schema that Tiptap provides entirely, our schema is intended to be a subset of the schema because we only want to allow certain behaviours instead of all the available options that HTML/Tiptap provides. Adding all here means we lose the signal on what is allowed and what isn't.
In general we override the rel
and class
when we output to the user, so those properties will be ignored. For target
we should only support _blank
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done - where do i see the properties that we strip? couldn't find a Text
component
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mainly in getSanitizedInlineContent.ts:
isomer/packages/components/src/utils/getSanitizedInlineContent.ts
Lines 5 to 42 in c19c5d5
export const getSanitizedInlineContent = (content: string) => { | |
DOMPurify.addHook("beforeSanitizeElements", (curr) => { | |
// Add rel="noopener noreferrer nofollow" to all anchor tags and | |
// open them in a new tab, if they point to an external site | |
if (curr.tagName !== "A") { | |
return curr | |
} | |
const href = curr.getAttribute("href") | |
if (href && (href.startsWith("http://") || href.startsWith("https://"))) { | |
curr.setAttribute("rel", "noopener noreferrer nofollow") | |
curr.setAttribute("target", "_blank") | |
} | |
return curr | |
}) | |
const sanitizedContent = DOMPurify.sanitize(content, { | |
ALLOWED_TAGS: [ | |
"b", // bold | |
"strong", // bold | |
"i", // italic | |
"em", // italic | |
"u", // underline | |
"s", // strikethrough | |
"del", // strikethrough | |
"strike", // strikethrough | |
"sub", // subscript | |
"sup", // superscript | |
"a", // anchor | |
"br", // line break | |
"code", // code | |
], | |
ALLOWED_ATTR: ["href", "rel", "target"], | |
}) | |
return sanitizedContent | |
} |
838adf5
to
812972c
Compare
{ | ||
type: Type.Literal("link", { default: "link" }), | ||
href: Type.String(), | ||
attrs: Type.Object({ | ||
target: Type.Literal("_blank"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue: hmm this property should be optional
target: Type.Literal("_blank"), | |
target: Type.Optional(Type.Literal("_blank")), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm but we are not using Tiptap's link schema entirely. In HTML it is entirely possible to omit the target
attribute and the link will have a default behaviour of _self
. This schema means that all links must have _blank
, which may not be the case for internal links.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you're right! i misunderstood the schema here because i thought it was only validating tiptap. i'll set it to optional("_self" | "_blank")
wdyt?
Problem
We need to allow users to set
links
inside our tiptap component. However, tiptap sets tehhref
attribute inside theattrs
object whereas our validator expects a top levelhref
attribute. this causes any link insertion to break on validation.Solution
LinkMarkSchema
to beUnsafe
to avoid deeply nested typesLinkMarkSchema
to have ahref
attribute so that validation can pass