mirror of
https://github.com/ueberdosis/tiptap.git
synced 2025-01-18 06:03:22 +08:00
feat: parseHTML for attributes should return the value instead of an object now, fix #1863
This commit is contained in:
parent
d3285e9308
commit
8a3b47a529
@ -16,11 +16,7 @@ const CustomTableCell = TableCell.extend({
|
||||
// and add a new one …
|
||||
backgroundColor: {
|
||||
default: null,
|
||||
parseHTML: element => {
|
||||
return {
|
||||
backgroundColor: element.getAttribute('data-background-color'),
|
||||
}
|
||||
},
|
||||
parseHTML: element => element.getAttribute('data-background-color'),
|
||||
renderHTML: attributes => {
|
||||
return {
|
||||
'data-background-color': attributes.backgroundColor,
|
||||
|
@ -76,11 +76,7 @@ const CustomTableCell = TableCell.extend({
|
||||
// and add a new one …
|
||||
backgroundColor: {
|
||||
default: null,
|
||||
parseHTML: element => {
|
||||
return {
|
||||
backgroundColor: element.getAttribute('data-background-color'),
|
||||
}
|
||||
},
|
||||
parseHTML: element => element.getAttribute('data-background-color'),
|
||||
renderHTML: attributes => {
|
||||
return {
|
||||
'data-background-color': attributes.backgroundColor,
|
||||
|
@ -42,11 +42,7 @@ export default Node.create({
|
||||
},
|
||||
allowfullscreen: {
|
||||
default: this.options.allowFullscreen,
|
||||
parseHTML: () => {
|
||||
return {
|
||||
allowfullscreen: this.options.allowFullscreen,
|
||||
}
|
||||
},
|
||||
parseHTML: () => this.options.allowFullscreen,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
@ -57,29 +57,17 @@ export const Figure = Node.create<FigureOptions>({
|
||||
return {
|
||||
src: {
|
||||
default: null,
|
||||
parseHTML: element => {
|
||||
return {
|
||||
src: element.querySelector('img')?.getAttribute('src'),
|
||||
}
|
||||
},
|
||||
parseHTML: element => element.querySelector('img')?.getAttribute('src'),
|
||||
},
|
||||
|
||||
alt: {
|
||||
default: null,
|
||||
parseHTML: element => {
|
||||
return {
|
||||
alt: element.querySelector('img')?.getAttribute('alt'),
|
||||
}
|
||||
},
|
||||
parseHTML: element => element.querySelector('img')?.getAttribute('alt'),
|
||||
},
|
||||
|
||||
title: {
|
||||
default: null,
|
||||
parseHTML: element => {
|
||||
return {
|
||||
title: element.querySelector('img')?.getAttribute('title'),
|
||||
}
|
||||
},
|
||||
parseHTML: element => element.querySelector('img')?.getAttribute('title'),
|
||||
},
|
||||
}
|
||||
},
|
||||
|
@ -163,11 +163,7 @@ const CustomParagraph = Paragraph.extend({
|
||||
color: {
|
||||
default: null,
|
||||
// Customize the HTML parsing (for example, to load the initial content)
|
||||
parseHTML: element => {
|
||||
return {
|
||||
color: element.getAttribute('data-color'),
|
||||
}
|
||||
},
|
||||
parseHTML: element => element.getAttribute('data-color'),
|
||||
// … and customize the HTML rendering.
|
||||
renderHTML: attributes => {
|
||||
return {
|
||||
@ -228,9 +224,7 @@ const TextAlign = Extension.create({
|
||||
renderHTML: attributes => ({
|
||||
style: `text-align: ${attributes.textAlign}`,
|
||||
}),
|
||||
parseHTML: element => ({
|
||||
textAlign: element.style.textAlign || 'left',
|
||||
}),
|
||||
parseHTML: element => element.style.textAlign || 'left',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { ParseRule } from 'prosemirror-model'
|
||||
import { ExtensionAttribute } from '../types'
|
||||
import fromString from '../utilities/fromString'
|
||||
import isObject from '../utilities/isObject'
|
||||
|
||||
/**
|
||||
* This function merges extension attributes into parserule attributes (`attrs` or `getAttrs`).
|
||||
@ -27,18 +28,21 @@ export default function injectExtensionAttributesToParseRule(parseRule: ParseRul
|
||||
const newAttributes = extensionAttributes
|
||||
.filter(item => item.attribute.rendered)
|
||||
.reduce((items, item) => {
|
||||
const attributes = item.attribute.parseHTML
|
||||
? item.attribute.parseHTML(node as HTMLElement) || {}
|
||||
: {
|
||||
[item.name]: fromString((node as HTMLElement).getAttribute(item.name)),
|
||||
const value = item.attribute.parseHTML
|
||||
? item.attribute.parseHTML(node as HTMLElement)
|
||||
: fromString((node as HTMLElement).getAttribute(item.name))
|
||||
|
||||
if (isObject(value)) {
|
||||
console.warn(`[tiptap warn]: BREAKING CHANGE: "parseHTML" for your attribute "${item.name}" returns an object but should return the value itself. If this is expected you can ignore this message. This warning will be removed in one of the next releases. Further information: https://github.com/ueberdosis/tiptap/issues/1863`)
|
||||
}
|
||||
|
||||
const filteredAttributes = Object.fromEntries(Object.entries(attributes)
|
||||
.filter(([, value]) => value !== undefined && value !== null))
|
||||
if (value === null || value === undefined) {
|
||||
return items
|
||||
}
|
||||
|
||||
return {
|
||||
...items,
|
||||
...filteredAttributes,
|
||||
[item.name]: value,
|
||||
}
|
||||
}, {})
|
||||
|
||||
|
@ -98,7 +98,7 @@ export type Attribute = {
|
||||
default: any,
|
||||
rendered?: boolean,
|
||||
renderHTML?: ((attributes: Record<string, any>) => Record<string, any> | null) | null,
|
||||
parseHTML?: ((element: HTMLElement) => Record<string, any> | null) | null,
|
||||
parseHTML?: ((element: HTMLElement) => any | null) | null,
|
||||
keepOnSplit: boolean,
|
||||
}
|
||||
|
||||
|
@ -58,9 +58,7 @@ export const CodeBlock = Node.create<CodeBlockOptions>({
|
||||
return null
|
||||
}
|
||||
|
||||
return {
|
||||
language,
|
||||
}
|
||||
return language
|
||||
},
|
||||
renderHTML: attributes => {
|
||||
if (!attributes.language) {
|
||||
|
@ -34,6 +34,7 @@ export const Color = Extension.create<ColorOptions>({
|
||||
attributes: {
|
||||
color: {
|
||||
default: null,
|
||||
parseHTML: element => element.style.color.replace(/['"]+/g, ''),
|
||||
renderHTML: attributes => {
|
||||
if (!attributes.color) {
|
||||
return {}
|
||||
@ -43,11 +44,6 @@ export const Color = Extension.create<ColorOptions>({
|
||||
style: `color: ${attributes.color}`,
|
||||
}
|
||||
},
|
||||
parseHTML: element => {
|
||||
return {
|
||||
color: element.style.color.replace(/['"]+/g, ''),
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -34,6 +34,7 @@ export const FontFamily = Extension.create<FontFamilyOptions>({
|
||||
attributes: {
|
||||
fontFamily: {
|
||||
default: null,
|
||||
parseHTML: element => element.style.fontFamily.replace(/['"]+/g, ''),
|
||||
renderHTML: attributes => {
|
||||
if (!attributes.fontFamily) {
|
||||
return {}
|
||||
@ -43,9 +44,6 @@ export const FontFamily = Extension.create<FontFamilyOptions>({
|
||||
style: `font-family: ${attributes.fontFamily}`,
|
||||
}
|
||||
},
|
||||
parseHTML: element => ({
|
||||
fontFamily: element.style.fontFamily.replace(/['"]+/g, ''),
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -48,11 +48,7 @@ export const Highlight = Mark.create<HighlightOptions>({
|
||||
return {
|
||||
color: {
|
||||
default: null,
|
||||
parseHTML: element => {
|
||||
return {
|
||||
color: element.getAttribute('data-color') || element.style.backgroundColor,
|
||||
}
|
||||
},
|
||||
parseHTML: element => element.getAttribute('data-color') || element.style.backgroundColor,
|
||||
renderHTML: attributes => {
|
||||
if (!attributes.color) {
|
||||
return {}
|
||||
|
@ -68,11 +68,7 @@ export const Mention = Node.create<MentionOptions>({
|
||||
return {
|
||||
id: {
|
||||
default: null,
|
||||
parseHTML: element => {
|
||||
return {
|
||||
id: element.getAttribute('data-id'),
|
||||
}
|
||||
},
|
||||
parseHTML: element => element.getAttribute('data-id'),
|
||||
renderHTML: attributes => {
|
||||
if (!attributes.id) {
|
||||
return {}
|
||||
@ -86,11 +82,7 @@ export const Mention = Node.create<MentionOptions>({
|
||||
|
||||
label: {
|
||||
default: null,
|
||||
parseHTML: element => {
|
||||
return {
|
||||
label: element.getAttribute('data-label'),
|
||||
}
|
||||
},
|
||||
parseHTML: element => element.getAttribute('data-label'),
|
||||
renderHTML: attributes => {
|
||||
if (!attributes.label) {
|
||||
return {}
|
||||
|
@ -33,11 +33,11 @@ export const OrderedList = Node.create<OrderedListOptions>({
|
||||
return {
|
||||
start: {
|
||||
default: 1,
|
||||
parseHTML: element => ({
|
||||
start: element.hasAttribute('start')
|
||||
parseHTML: element => {
|
||||
return element.hasAttribute('start')
|
||||
? parseInt(element.getAttribute('start') || '', 10)
|
||||
: 1,
|
||||
}),
|
||||
: 1
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
@ -29,9 +29,7 @@ export const TableCell = Node.create<TableCellOptions>({
|
||||
? [parseInt(colwidth, 10)]
|
||||
: null
|
||||
|
||||
return {
|
||||
colwidth: value,
|
||||
}
|
||||
return value
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -28,9 +28,7 @@ export const TableHeader = Node.create<TableHeaderOptions>({
|
||||
? [parseInt(colwidth, 10)]
|
||||
: null
|
||||
|
||||
return {
|
||||
colwidth: value,
|
||||
}
|
||||
return value
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -26,13 +26,11 @@ export const TaskItem = Node.create<TaskItemOptions>({
|
||||
return {
|
||||
checked: {
|
||||
default: false,
|
||||
parseHTML: element => ({
|
||||
checked: element.getAttribute('data-checked') === 'true',
|
||||
}),
|
||||
keepOnSplit: false,
|
||||
parseHTML: element => element.getAttribute('data-checked') === 'true',
|
||||
renderHTML: attributes => ({
|
||||
'data-checked': attributes.checked,
|
||||
}),
|
||||
keepOnSplit: false,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
@ -37,9 +37,7 @@ export const TextAlign = Extension.create<TextAlignOptions>({
|
||||
attributes: {
|
||||
textAlign: {
|
||||
default: this.options.defaultAlignment,
|
||||
parseHTML: element => ({
|
||||
textAlign: element.style.textAlign || this.options.defaultAlignment,
|
||||
}),
|
||||
parseHTML: element => element.style.textAlign || this.options.defaultAlignment,
|
||||
renderHTML: attributes => {
|
||||
if (attributes.textAlign === this.options.defaultAlignment) {
|
||||
return {}
|
||||
|
Loading…
Reference in New Issue
Block a user