Skip to content

Commit

Permalink
[block-tools] Support hoisted block types
Browse files Browse the repository at this point in the history
Previously the html deserializer always assumed your block type is named 'block'.
This is not true for hoisted block types, where the block type name could be something else.
  • Loading branch information
skogsmaskin committed Sep 7, 2020
1 parent 4416d19 commit a346211
Show file tree
Hide file tree
Showing 6 changed files with 360 additions and 418 deletions.
26 changes: 24 additions & 2 deletions packages/@sanity/block-tools/src/HtmlDeserializer/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {flatten} from 'lodash'
import resolveJsType from '../util/resolveJsType'
import blockContentTypeFeatures from '../util/blockContentTypeFeatures'
import {
createRuleOptions,
defaultParseHtml,
Expand All @@ -22,6 +23,7 @@ let _markDefs = []
*
*/
export default class HtmlDeserializer {
blockContentType: any
rules: any[]
parseHtml: (html: string) => any
/**
Expand All @@ -44,6 +46,7 @@ export default class HtmlDeserializer {
const standardRules = createRules(blockContentType, createRuleOptions(blockContentType))
this.rules = [...rules, ...standardRules]
const parseHtml = options.parseHtml || defaultParseHtml()
this.blockContentType = blockContentType
this.parseHtml = html => {
const doc = preprocess(html, parseHtml)
return doc.body
Expand All @@ -61,6 +64,7 @@ export default class HtmlDeserializer {
const {parseHtml} = this
const fragment = parseHtml(html)
const children = Array.from(fragment.childNodes)
// Ensure that there are no blocks within blocks, and trim whitespace
const blocks = trimWhitespace(
flattenNestedBlocks(ensureRootIsBlocks(this.deserializeElements(children)))
)
Expand All @@ -76,8 +80,14 @@ export default class HtmlDeserializer {
)
})
}
// Ensure that there are no blocks within blocks, and trim whitespace
return blocks
// Set back the potentially hoisted block type
const type = this.blockContentType.of.find(findBlockType)
return blocks.map(block => {
if (block._type === 'block') {
block._type = type.name
}
return block
})
}

/**
Expand Down Expand Up @@ -257,3 +267,15 @@ export default class HtmlDeserializer {
}, [])
}
}

function findBlockType(type) {
if (type.type) {
return findBlockType(type.type)
}

if (type.name === 'block') {
return type
}

return null
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,15 @@ export default function createHTMLRules(blockContentType, options: any = {}) {
return [
// Text nodes
{
// eslint-disable-next-line complexity
deserialize(el) {
const isValidWhiteSpace =
el.nodeType === 3 &&
el.textContent.replace(/[\r\n]/g, ' ').replace(/\s\s+/g, ' ') === ' ' &&
el.nextSibling && el.nextSibling.nodeType !== 3 &&
el.previousSibling && el.previousSibling.nodeType !== 3
el.nextSibling &&
el.nextSibling.nodeType !== 3 &&
el.previousSibling &&
el.previousSibling.nodeType !== 3
const isValidText =
(isValidWhiteSpace || el.textContent !== ' ') && tagName(el.parentNode) !== 'body'
if (el.nodeName === '#text' && isValidText) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default function blockContentFeatures(blockContentType) {
const ofType = blockType.fields.find(field => field.name === 'children').type.of
const spanType = ofType.find(memberType => memberType.name === 'span')
const inlineObjectTypes = ofType.filter(memberType => memberType.name !== 'span')
const blockObjectTypes = blockContentType.of.filter(field => field.name !== 'block')
const blockObjectTypes = blockContentType.of.filter(field => field.name !== blockType.name)
return {
styles: resolveEnabledStyles(blockType),
decorators: resolveEnabledDecorators(spanType),
Expand Down Expand Up @@ -71,13 +71,13 @@ function resolveEnabledListItems(blockType) {
}

function findBlockType(type) {
if (type.name === 'block') {
return type
}

if (type.type) {
return findBlockType(type.type)
}

if (type.name === 'block') {
return type
}

return null
}

0 comments on commit a346211

Please sign in to comment.