Skip to content

Commit

Permalink
feat: parseHTML for attributes should return the value instead of an …
Browse files Browse the repository at this point in the history
…object now, fix #1863
  • Loading branch information
philippkuehn committed Sep 8, 2021
1 parent d3285e9 commit 8a3b47a
Show file tree
Hide file tree
Showing 17 changed files with 38 additions and 92 deletions.
8 changes: 2 additions & 6 deletions demos/src/Examples/Tables/React/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -36,7 +32,7 @@ export const tableHTML = `
<table style="width:100%">
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Lastname</th>
<th>Age</th>
</tr>
<tr>
Expand Down
6 changes: 1 addition & 5 deletions demos/src/Examples/Tables/Vue/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
6 changes: 1 addition & 5 deletions demos/src/Experiments/Embeds/Vue/iframe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,7 @@ export default Node.create({
},
allowfullscreen: {
default: this.options.allowFullscreen,
parseHTML: () => {
return {
allowfullscreen: this.options.allowFullscreen,
}
},
parseHTML: () => this.options.allowFullscreen,
},
}
},
Expand Down
18 changes: 3 additions & 15 deletions demos/src/Experiments/Figure/Vue/figure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'),
},
}
},
Expand Down
12 changes: 3 additions & 9 deletions docs/src/docPages/guide/custom-extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -187,7 +183,7 @@ const CustomParagraph = Paragraph.extend({
You can completly disable the rendering of attributes with `rendered: false`.

#### Extend existing attributes
If you want to add an attribute to an extension and keep existing attributes, you can access them through `this.parent()`.
If you want to add an attribute to an extension and keep existing attributes, you can access them through `this.parent()`.

In some cases, it is undefined, so make sure to check for that case, or use optional chaining `this.parent?.()`

Expand Down Expand Up @@ -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',
},
},
},
Expand Down
20 changes: 12 additions & 8 deletions packages/core/src/helpers/injectExtensionAttributesToParseRule.ts
Original file line number Diff line number Diff line change
@@ -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`).
Expand All @@ -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))

const filteredAttributes = Object.fromEntries(Object.entries(attributes)
.filter(([, value]) => value !== undefined && value !== null))
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`)
}

if (value === null || value === undefined) {
return items
}

return {
...items,
...filteredAttributes,
[item.name]: value,
}
}, {})

Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}

Expand Down
4 changes: 1 addition & 3 deletions packages/extension-code-block/src/code-block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,7 @@ export const CodeBlock = Node.create<CodeBlockOptions>({
return null
}

return {
language,
}
return language
},
renderHTML: attributes => {
if (!attributes.language) {
Expand Down
6 changes: 1 addition & 5 deletions packages/extension-color/src/color.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}
Expand All @@ -43,11 +44,6 @@ export const Color = Extension.create<ColorOptions>({
style: `color: ${attributes.color}`,
}
},
parseHTML: element => {
return {
color: element.style.color.replace(/['"]+/g, ''),
}
},
},
},
},
Expand Down
4 changes: 1 addition & 3 deletions packages/extension-font-family/src/font-family.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}
Expand All @@ -43,9 +44,6 @@ export const FontFamily = Extension.create<FontFamilyOptions>({
style: `font-family: ${attributes.fontFamily}`,
}
},
parseHTML: element => ({
fontFamily: element.style.fontFamily.replace(/['"]+/g, ''),
}),
},
},
},
Expand Down
6 changes: 1 addition & 5 deletions packages/extension-highlight/src/highlight.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}
Expand Down
12 changes: 2 additions & 10 deletions packages/extension-mention/src/mention.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}
Expand All @@ -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 {}
Expand Down
8 changes: 4 additions & 4 deletions packages/extension-ordered-list/src/ordered-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
},
},
}
},
Expand Down
4 changes: 1 addition & 3 deletions packages/extension-table-cell/src/table-cell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ export const TableCell = Node.create<TableCellOptions>({
? [parseInt(colwidth, 10)]
: null

return {
colwidth: value,
}
return value
},
},
}
Expand Down
4 changes: 1 addition & 3 deletions packages/extension-table-header/src/table-header.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@ export const TableHeader = Node.create<TableHeaderOptions>({
? [parseInt(colwidth, 10)]
: null

return {
colwidth: value,
}
return value
},
},
}
Expand Down
6 changes: 2 additions & 4 deletions packages/extension-task-item/src/task-item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
}
},
Expand Down
4 changes: 1 addition & 3 deletions packages/extension-text-align/src/text-align.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}
Expand Down

0 comments on commit 8a3b47a

Please sign in to comment.