{
  "version": 3,
  "sources": ["../../../src/api/parser/get-block-attributes.ts"],
  "sourcesContent": ["/**\n * External dependencies\n */\n// @ts-ignore\nimport { parse as hpqParse } from 'hpq';\nimport memoize from 'memize';\n\n/**\n * WordPress dependencies\n */\nimport { applyFilters } from '@wordpress/hooks';\nimport { RichTextData } from '@wordpress/rich-text';\n\n/**\n * Internal dependencies\n */\nimport {\n\tattr,\n\thtml,\n\ttext,\n\tquery,\n\tnode,\n\tchildren,\n\tprop,\n\trichText,\n} from '../matchers';\nimport { normalizeBlockType, getDefault } from '../utils';\nimport type { BlockAttribute, BlockType } from '../../types';\n\n/**\n * Higher-order hpq matcher which enhances an attribute matcher to return true\n * or false depending on whether the original matcher returns undefined. This\n * is useful for boolean attributes (e.g. disabled) whose attribute values may\n * be technically falsey (empty string), though their mere presence should be\n * enough to infer as true.\n *\n * @param matcher Original hpq matcher.\n *\n * @return Enhanced hpq matcher.\n */\nexport const toBooleanAttributeMatcher =\n\t( matcher: ( value: unknown ) => unknown ) =>\n\t( value: unknown ): boolean =>\n\t\tmatcher( value ) !== undefined;\n\n/**\n * Returns true if value is of the given JSON schema type, or false otherwise.\n *\n * @see http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.25\n *\n * @param value Value to test.\n * @param type  Type to test.\n *\n * @return Whether value is of type.\n */\nexport function isOfType( value: unknown, type: string ): boolean {\n\tswitch ( type ) {\n\t\tcase 'rich-text':\n\t\t\treturn value instanceof RichTextData;\n\n\t\tcase 'string':\n\t\t\treturn typeof value === 'string';\n\n\t\tcase 'boolean':\n\t\t\treturn typeof value === 'boolean';\n\n\t\tcase 'object':\n\t\t\treturn !! value && value.constructor === Object;\n\n\t\tcase 'null':\n\t\t\treturn value === null;\n\n\t\tcase 'array':\n\t\t\treturn Array.isArray( value );\n\n\t\tcase 'integer':\n\t\tcase 'number':\n\t\t\treturn typeof value === 'number';\n\t}\n\n\treturn true;\n}\n\n/**\n * Returns true if value is of an array of given JSON schema types, or false\n * otherwise.\n *\n * @see http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.25\n *\n * @param value Value to test.\n * @param types Types to test.\n *\n * @return Whether value is of types.\n */\nexport function isOfTypes( value: unknown, types: string[] ): boolean {\n\treturn types.some( ( type ) => isOfType( value, type ) );\n}\n\n/**\n * Given an attribute key, an attribute's schema, a block's raw content and the\n * commentAttributes returns the attribute value depending on its source\n * definition of the given attribute key.\n *\n * @param attributeKey      Attribute key.\n * @param attributeSchema   Attribute's schema.\n * @param innerDOM          Parsed DOM of block's inner HTML.\n * @param commentAttributes Block's comment attributes.\n * @param innerHTML         Raw HTML from block node's innerHTML property.\n *\n * @return Attribute value.\n */\nexport function getBlockAttribute(\n\tattributeKey: string,\n\tattributeSchema: BlockAttribute,\n\tinnerDOM: Node,\n\tcommentAttributes: Record< string, unknown >,\n\tinnerHTML: string | Node\n): unknown {\n\tlet value;\n\n\tswitch ( attributeSchema.source ) {\n\t\t// An undefined source means that it's an attribute serialized to the\n\t\t// block's \"comment\".\n\t\tcase undefined:\n\t\t\tvalue = commentAttributes\n\t\t\t\t? commentAttributes[ attributeKey ]\n\t\t\t\t: undefined;\n\t\t\tbreak;\n\t\t// raw source means that it's the original raw block content.\n\t\tcase 'raw':\n\t\t\tvalue = innerHTML;\n\t\t\tbreak;\n\t\tcase 'attribute':\n\t\tcase 'property':\n\t\tcase 'html':\n\t\tcase 'text':\n\t\tcase 'rich-text':\n\t\tcase 'children':\n\t\tcase 'node':\n\t\tcase 'query':\n\t\tcase 'tag':\n\t\t\tvalue = parseWithAttributeSchema( innerDOM, attributeSchema );\n\t\t\tbreak;\n\t}\n\n\tif (\n\t\t! isValidByType( value, attributeSchema.type ) ||\n\t\t! isValidByEnum( value, attributeSchema.enum )\n\t) {\n\t\t// Reject the value if it is not valid. Reverting to the undefined\n\t\t// value ensures the default is respected, if applicable.\n\t\tvalue = undefined;\n\t}\n\n\tif ( value === undefined ) {\n\t\tvalue = getDefault( attributeSchema );\n\t}\n\n\treturn value;\n}\n\n/**\n * Returns true if value is valid per the given block attribute schema type\n * definition, or false otherwise.\n *\n * @see https://json-schema.org/latest/json-schema-validation.html#rfc.section.6.1.1\n *\n * @param value Value to test.\n * @param type  Block attribute schema type.\n *\n * @return Whether value is valid.\n */\nexport function isValidByType(\n\tvalue: unknown,\n\ttype: string | string[] | undefined\n): boolean {\n\treturn (\n\t\ttype === undefined ||\n\t\tisOfTypes( value, Array.isArray( type ) ? type : [ type ] )\n\t);\n}\n\n/**\n * Returns true if value is valid per the given block attribute schema enum\n * definition, or false otherwise.\n *\n * @see https://json-schema.org/latest/json-schema-validation.html#rfc.section.6.1.2\n *\n * @param value   Value to test.\n * @param enumSet Block attribute schema enum.\n *\n * @return Whether value is valid.\n */\nexport function isValidByEnum(\n\tvalue: unknown,\n\tenumSet: unknown[] | undefined\n): boolean {\n\treturn ! Array.isArray( enumSet ) || enumSet.includes( value );\n}\n\n// Returns an hpq matcher given a source object.\nexport const matcherFromSource = memoize(\n\t(\n\t\tsourceConfig: BlockAttribute\n\t): ( ( domNode: Element ) => unknown ) | undefined => {\n\t\tswitch ( sourceConfig.source ) {\n\t\t\tcase 'attribute': {\n\t\t\t\tlet matcher = attr(\n\t\t\t\t\tsourceConfig.selector,\n\t\t\t\t\tsourceConfig.attribute\n\t\t\t\t);\n\t\t\t\tif ( sourceConfig.type === 'boolean' ) {\n\t\t\t\t\tmatcher = toBooleanAttributeMatcher( matcher );\n\t\t\t\t}\n\t\t\t\treturn matcher;\n\t\t\t}\n\t\t\tcase 'html':\n\t\t\t\treturn html( sourceConfig.selector, sourceConfig.multiline );\n\t\t\tcase 'text':\n\t\t\t\treturn text( sourceConfig.selector );\n\t\t\tcase 'rich-text':\n\t\t\t\treturn richText(\n\t\t\t\t\tsourceConfig.selector,\n\t\t\t\t\tsourceConfig.__unstablePreserveWhiteSpace\n\t\t\t\t);\n\t\t\tcase 'children':\n\t\t\t\treturn children( sourceConfig.selector );\n\t\t\tcase 'node':\n\t\t\t\treturn node( sourceConfig.selector );\n\t\t\tcase 'query':\n\t\t\t\tconst subMatchers = Object.fromEntries(\n\t\t\t\t\tObject.entries( sourceConfig.query! ).map(\n\t\t\t\t\t\t( [ key, subSourceConfig ] ) => [\n\t\t\t\t\t\t\tkey,\n\t\t\t\t\t\t\tmatcherFromSource( subSourceConfig ),\n\t\t\t\t\t\t]\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t\treturn query( sourceConfig.selector, subMatchers );\n\t\t\tcase 'tag': {\n\t\t\t\tconst matcher = prop( sourceConfig.selector, 'nodeName' );\n\t\t\t\treturn ( domNode: Node ) =>\n\t\t\t\t\t( matcher( domNode ) as string )?.toLowerCase();\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.error(\n\t\t\t\t\t`Unknown source type \"${ sourceConfig.source }\"`\n\t\t\t\t);\n\t\t\t\treturn undefined;\n\t\t}\n\t}\n);\n\n/**\n * Parse a HTML string into DOM tree.\n *\n * @param innerHTML HTML string or already parsed DOM node.\n *\n * @return Parsed DOM node.\n */\nfunction parseHtml( innerHTML: string | Node ): Node {\n\treturn hpqParse( innerHTML, ( h: Node ) => h );\n}\n\n/**\n * Given a block's raw content and an attribute's schema returns the attribute's\n * value depending on its source.\n *\n * @param innerHTML       Block's raw content.\n * @param attributeSchema Attribute's schema.\n *\n * @return Attribute value.\n */\nexport function parseWithAttributeSchema(\n\tinnerHTML: string | Node,\n\tattributeSchema: BlockAttribute\n): unknown {\n\treturn matcherFromSource( attributeSchema )!(\n\t\tparseHtml( innerHTML ) as Element\n\t);\n}\n\n/**\n * Returns the block attributes of a registered block node given its type.\n *\n * @param blockTypeOrName Block type or name.\n * @param innerHTML       Raw block content.\n * @param attributes      Known block attributes (from delimiters).\n *\n * @return All block attributes.\n */\nexport function getBlockAttributes(\n\tblockTypeOrName: string | BlockType,\n\tinnerHTML: string | Node,\n\tattributes: Record< string, unknown > = {}\n): Record< string, unknown > {\n\tconst doc = parseHtml( innerHTML );\n\tconst blockType = normalizeBlockType( blockTypeOrName );\n\n\tconst blockAttributes = Object.fromEntries(\n\t\tObject.entries( blockType?.attributes ?? {} ).map(\n\t\t\t( [ key, schema ] ) => [\n\t\t\t\tkey,\n\t\t\t\tgetBlockAttribute( key, schema, doc, attributes, innerHTML ),\n\t\t\t]\n\t\t)\n\t);\n\n\treturn applyFilters(\n\t\t'blocks.getBlockAttributes',\n\t\tblockAttributes,\n\t\tblockType,\n\t\tinnerHTML,\n\t\tattributes\n\t) as Record< string, unknown >;\n}\n"],
  "mappings": "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",
  "names": ["memoize", "hpqParse"]
}
