UNPKG

@wordpress/editor

Version:
149 lines (125 loc) 4.72 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = exports.DocumentOutline = void 0; var _element = require("@wordpress/element"); var _lodash = require("lodash"); var _i18n = require("@wordpress/i18n"); var _compose = require("@wordpress/compose"); var _data = require("@wordpress/data"); var _richText = require("@wordpress/rich-text"); var _blockEditor = require("@wordpress/block-editor"); var _item = _interopRequireDefault(require("./item")); /** * External dependencies */ /** * WordPress dependencies */ /** * Internal dependencies */ /** * Module constants */ const emptyHeadingContent = (0, _element.createElement)("em", null, (0, _i18n.__)('(Empty heading)')); const incorrectLevelContent = [(0, _element.createElement)("br", { key: "incorrect-break" }), (0, _element.createElement)("em", { key: "incorrect-message" }, (0, _i18n.__)('(Incorrect heading level)'))]; const singleH1Headings = [(0, _element.createElement)("br", { key: "incorrect-break-h1" }), (0, _element.createElement)("em", { key: "incorrect-message-h1" }, (0, _i18n.__)('(Your theme may already use a H1 for the post title)'))]; const multipleH1Headings = [(0, _element.createElement)("br", { key: "incorrect-break-multiple-h1" }), (0, _element.createElement)("em", { key: "incorrect-message-multiple-h1" }, (0, _i18n.__)('(Multiple H1 headings are not recommended)'))]; /** * Returns an array of heading blocks enhanced with the following properties: * level - An integer with the heading level. * isEmpty - Flag indicating if the heading has no content. * * @param {?Array} blocks An array of blocks. * * @return {Array} An array of heading blocks enhanced with the properties described above. */ const computeOutlineHeadings = (blocks = []) => { return (0, _lodash.flatMap)(blocks, (block = {}) => { if (block.name === 'core/heading') { return { ...block, level: block.attributes.level, isEmpty: isEmptyHeading(block) }; } return computeOutlineHeadings(block.innerBlocks); }); }; const isEmptyHeading = heading => !heading.attributes.content || heading.attributes.content.length === 0; const DocumentOutline = ({ blocks = [], title, onSelect, isTitleSupported, hasOutlineItemsDisabled }) => { const headings = computeOutlineHeadings(blocks); if (headings.length < 1) { return null; } let prevHeadingLevel = 1; // Not great but it's the simplest way to locate the title right now. const titleNode = document.querySelector('.editor-post-title__input'); const hasTitle = isTitleSupported && title && titleNode; const countByLevel = (0, _lodash.countBy)(headings, 'level'); const hasMultipleH1 = countByLevel[1] > 1; return (0, _element.createElement)("div", { className: "document-outline" }, (0, _element.createElement)("ul", null, hasTitle && (0, _element.createElement)(_item.default, { level: (0, _i18n.__)('Title'), isValid: true, onSelect: onSelect, href: `#${titleNode.id}`, isDisabled: hasOutlineItemsDisabled }, title), headings.map((item, index) => { // Headings remain the same, go up by one, or down by any amount. // Otherwise there are missing levels. const isIncorrectLevel = item.level > prevHeadingLevel + 1; const isValid = !item.isEmpty && !isIncorrectLevel && !!item.level && (item.level !== 1 || !hasMultipleH1 && !hasTitle); prevHeadingLevel = item.level; return (0, _element.createElement)(_item.default, { key: index, level: `H${item.level}`, isValid: isValid, isDisabled: hasOutlineItemsDisabled, href: `#block-${item.clientId}`, onSelect: onSelect }, item.isEmpty ? emptyHeadingContent : (0, _richText.getTextContent)((0, _richText.create)({ html: item.attributes.content })), isIncorrectLevel && incorrectLevelContent, item.level === 1 && hasMultipleH1 && multipleH1Headings, hasTitle && item.level === 1 && !hasMultipleH1 && singleH1Headings); }))); }; exports.DocumentOutline = DocumentOutline; var _default = (0, _compose.compose)((0, _data.withSelect)(select => { const { getBlocks } = select(_blockEditor.store); const { getEditedPostAttribute } = select('core/editor'); const { getPostType } = select('core'); const postType = getPostType(getEditedPostAttribute('type')); return { title: getEditedPostAttribute('title'), blocks: getBlocks(), isTitleSupported: (0, _lodash.get)(postType, ['supports', 'title'], false) }; }))(DocumentOutline); exports.default = _default; //# sourceMappingURL=index.js.map