} props.contentRef Ref to the block
* editor iframe canvas.
*/
function EditTemplateBlocksNotification({
contentRef
}) {
const {
onNavigateToEntityRecord,
templateId
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getEditorSettings,
getCurrentTemplateId
} = select(store_store);
return {
onNavigateToEntityRecord: getEditorSettings().onNavigateToEntityRecord,
templateId: getCurrentTemplateId()
};
}, []);
const canEditTemplate = (0,external_wp_data_namespaceObject.useSelect)(select => !!select(external_wp_coreData_namespaceObject.store).canUser('create', {
kind: 'postType',
name: 'wp_template'
}), []);
const [isDialogOpen, setIsDialogOpen] = (0,external_wp_element_namespaceObject.useState)(false);
(0,external_wp_element_namespaceObject.useEffect)(() => {
const handleDblClick = event => {
if (!canEditTemplate) {
return;
}
if (!event.target.classList.contains('is-root-container') || event.target.dataset?.type === 'core/template-part') {
return;
}
if (!event.defaultPrevented) {
event.preventDefault();
setIsDialogOpen(true);
}
};
const canvas = contentRef.current;
canvas?.addEventListener('dblclick', handleDblClick);
return () => {
canvas?.removeEventListener('dblclick', handleDblClick);
};
}, [contentRef, canEditTemplate]);
if (!canEditTemplate) {
return null;
}
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalConfirmDialog, {
isOpen: isDialogOpen,
confirmButtonText: (0,external_wp_i18n_namespaceObject.__)('Edit template'),
onConfirm: () => {
setIsDialogOpen(false);
onNavigateToEntityRecord({
postId: templateId,
postType: 'wp_template'
});
},
onCancel: () => setIsDialogOpen(false),
size: "medium",
children: (0,external_wp_i18n_namespaceObject.__)('You’ve tried to select a block that is part of a template, which may be used on other posts and pages. Would you like to edit the template?')
});
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/components/resizable-editor/resize-handle.js
/**
* WordPress dependencies
*/
const DELTA_DISTANCE = 20; // The distance to resize per keydown in pixels.
function ResizeHandle({
direction,
resizeWidthBy
}) {
function handleKeyDown(event) {
const {
keyCode
} = event;
if (direction === 'left' && keyCode === external_wp_keycodes_namespaceObject.LEFT || direction === 'right' && keyCode === external_wp_keycodes_namespaceObject.RIGHT) {
resizeWidthBy(DELTA_DISTANCE);
} else if (direction === 'left' && keyCode === external_wp_keycodes_namespaceObject.RIGHT || direction === 'right' && keyCode === external_wp_keycodes_namespaceObject.LEFT) {
resizeWidthBy(-DELTA_DISTANCE);
}
}
const resizeHandleVariants = {
active: {
opacity: 1,
scaleY: 1.3
}
};
const resizableHandleHelpId = `resizable-editor__resize-help-${direction}`;
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, {
children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Tooltip, {
text: (0,external_wp_i18n_namespaceObject.__)('Drag to resize'),
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__unstableMotion.button, {
className: `editor-resizable-editor__resize-handle is-${direction}`,
"aria-label": (0,external_wp_i18n_namespaceObject.__)('Drag to resize'),
"aria-describedby": resizableHandleHelpId,
onKeyDown: handleKeyDown,
variants: resizeHandleVariants,
whileFocus: "active",
whileHover: "active",
whileTap: "active",
role: "separator",
"aria-orientation": "vertical"
}, "handle")
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.VisuallyHidden, {
id: resizableHandleHelpId,
children: (0,external_wp_i18n_namespaceObject.__)('Use left and right arrow keys to resize the canvas.')
})]
});
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/components/resizable-editor/index.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
// Removes the inline styles in the drag handles.
const HANDLE_STYLES_OVERRIDE = {
position: undefined,
userSelect: undefined,
cursor: undefined,
width: undefined,
height: undefined,
top: undefined,
right: undefined,
bottom: undefined,
left: undefined
};
function ResizableEditor({
className,
enableResizing,
height,
children
}) {
const [width, setWidth] = (0,external_wp_element_namespaceObject.useState)('100%');
const resizableRef = (0,external_wp_element_namespaceObject.useRef)();
const resizeWidthBy = (0,external_wp_element_namespaceObject.useCallback)(deltaPixels => {
if (resizableRef.current) {
setWidth(resizableRef.current.offsetWidth + deltaPixels);
}
}, []);
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ResizableBox, {
className: dist_clsx('editor-resizable-editor', className, {
'is-resizable': enableResizing
}),
ref: api => {
resizableRef.current = api?.resizable;
},
size: {
width: enableResizing ? width : '100%',
height: enableResizing && height ? height : '100%'
},
onResizeStop: (event, direction, element) => {
setWidth(element.style.width);
},
minWidth: 300,
maxWidth: "100%",
maxHeight: "100%",
enable: {
left: enableResizing,
right: enableResizing
},
showHandle: enableResizing
// The editor is centered horizontally, resizing it only
// moves half the distance. Hence double the ratio to correctly
// align the cursor to the resizer handle.
,
resizeRatio: 2,
handleComponent: {
left: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ResizeHandle, {
direction: "left",
resizeWidthBy: resizeWidthBy
}),
right: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ResizeHandle, {
direction: "right",
resizeWidthBy: resizeWidthBy
})
},
handleClasses: undefined,
handleStyles: {
left: HANDLE_STYLES_OVERRIDE,
right: HANDLE_STYLES_OVERRIDE
},
children: children
});
}
/* harmony default export */ const resizable_editor = (ResizableEditor);
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/components/visual-editor/use-select-nearest-editable-block.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const DISTANCE_THRESHOLD = 500;
function clamp(value, min, max) {
return Math.min(Math.max(value, min), max);
}
function distanceFromRect(x, y, rect) {
const dx = x - clamp(x, rect.left, rect.right);
const dy = y - clamp(y, rect.top, rect.bottom);
return Math.sqrt(dx * dx + dy * dy);
}
function useSelectNearestEditableBlock({
isEnabled = true
} = {}) {
const {
getEnabledClientIdsTree,
getBlockName,
getBlockOrder
} = unlock((0,external_wp_data_namespaceObject.useSelect)(external_wp_blockEditor_namespaceObject.store));
const {
selectBlock
} = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_blockEditor_namespaceObject.store);
return (0,external_wp_compose_namespaceObject.useRefEffect)(element => {
if (!isEnabled) {
return;
}
const selectNearestEditableBlock = (x, y) => {
const editableBlockClientIds = getEnabledClientIdsTree().flatMap(({
clientId
}) => {
const blockName = getBlockName(clientId);
if (blockName === 'core/template-part') {
return [];
}
if (blockName === 'core/post-content') {
const innerBlocks = getBlockOrder(clientId);
if (innerBlocks.length) {
return innerBlocks;
}
}
return [clientId];
});
let nearestDistance = Infinity,
nearestClientId = null;
for (const clientId of editableBlockClientIds) {
const block = element.querySelector(`[data-block="${clientId}"]`);
if (!block) {
continue;
}
const rect = block.getBoundingClientRect();
const distance = distanceFromRect(x, y, rect);
if (distance < nearestDistance && distance < DISTANCE_THRESHOLD) {
nearestDistance = distance;
nearestClientId = clientId;
}
}
if (nearestClientId) {
selectBlock(nearestClientId);
}
};
const handleClick = event => {
const shouldSelect = event.target === element || event.target.classList.contains('is-root-container');
if (shouldSelect) {
selectNearestEditableBlock(event.clientX, event.clientY);
}
};
element.addEventListener('click', handleClick);
return () => element.removeEventListener('click', handleClick);
}, [isEnabled]);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/components/visual-editor/index.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const {
LayoutStyle,
useLayoutClasses,
useLayoutStyles,
ExperimentalBlockCanvas: BlockCanvas,
useFlashEditableBlocks,
useZoomOutModeExit
} = unlock(external_wp_blockEditor_namespaceObject.privateApis);
/**
* These post types have a special editor where they don't allow you to fill the title
* and they don't apply the layout styles.
*/
const visual_editor_DESIGN_POST_TYPES = [PATTERN_POST_TYPE, TEMPLATE_POST_TYPE, NAVIGATION_POST_TYPE, TEMPLATE_PART_POST_TYPE];
/**
* Given an array of nested blocks, find the first Post Content
* block inside it, recursing through any nesting levels,
* and return its attributes.
*
* @param {Array} blocks A list of blocks.
*
* @return {Object | undefined} The Post Content block.
*/
function getPostContentAttributes(blocks) {
for (let i = 0; i < blocks.length; i++) {
if (blocks[i].name === 'core/post-content') {
return blocks[i].attributes;
}
if (blocks[i].innerBlocks.length) {
const nestedPostContent = getPostContentAttributes(blocks[i].innerBlocks);
if (nestedPostContent) {
return nestedPostContent;
}
}
}
}
function checkForPostContentAtRootLevel(blocks) {
for (let i = 0; i < blocks.length; i++) {
if (blocks[i].name === 'core/post-content') {
return true;
}
}
return false;
}
function VisualEditor({
// Ideally as we unify post and site editors, we won't need these props.
autoFocus,
styles,
disableIframe = false,
iframeProps,
contentRef,
className
}) {
const [resizeObserver, sizes] = (0,external_wp_compose_namespaceObject.useResizeObserver)();
const isMobileViewport = (0,external_wp_compose_namespaceObject.useViewportMatch)('small', '<');
const isTabletViewport = (0,external_wp_compose_namespaceObject.useViewportMatch)('medium', '<');
const {
renderingMode,
postContentAttributes,
editedPostTemplate = {},
wrapperBlockName,
wrapperUniqueId,
deviceType,
isFocusedEntity,
isDesignPostType,
postType,
isPreview
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getCurrentPostId,
getCurrentPostType,
getCurrentTemplateId,
getEditorSettings,
getRenderingMode,
getDeviceType
} = select(store_store);
const {
getPostType,
getEditedEntityRecord
} = select(external_wp_coreData_namespaceObject.store);
const postTypeSlug = getCurrentPostType();
const _renderingMode = getRenderingMode();
let _wrapperBlockName;
if (postTypeSlug === PATTERN_POST_TYPE) {
_wrapperBlockName = 'core/block';
} else if (_renderingMode === 'post-only') {
_wrapperBlockName = 'core/post-content';
}
const editorSettings = getEditorSettings();
const supportsTemplateMode = editorSettings.supportsTemplateMode;
const postTypeObject = getPostType(postTypeSlug);
const currentTemplateId = getCurrentTemplateId();
const template = currentTemplateId ? getEditedEntityRecord('postType', TEMPLATE_POST_TYPE, currentTemplateId) : undefined;
return {
renderingMode: _renderingMode,
postContentAttributes: editorSettings.postContentAttributes,
isDesignPostType: visual_editor_DESIGN_POST_TYPES.includes(postTypeSlug),
// Post template fetch returns a 404 on classic themes, which
// messes with e2e tests, so check it's a block theme first.
editedPostTemplate: postTypeObject?.viewable && supportsTemplateMode ? template : undefined,
wrapperBlockName: _wrapperBlockName,
wrapperUniqueId: getCurrentPostId(),
deviceType: getDeviceType(),
isFocusedEntity: !!editorSettings.onNavigateToPreviousEntityRecord,
postType: postTypeSlug,
isPreview: editorSettings.__unstableIsPreviewMode
};
}, []);
const {
isCleanNewPost
} = (0,external_wp_data_namespaceObject.useSelect)(store_store);
const {
hasRootPaddingAwareAlignments,
themeHasDisabledLayoutStyles,
themeSupportsLayout,
isZoomedOut
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getSettings,
isZoomOut: _isZoomOut
} = unlock(select(external_wp_blockEditor_namespaceObject.store));
const _settings = getSettings();
return {
themeHasDisabledLayoutStyles: _settings.disableLayoutStyles,
themeSupportsLayout: _settings.supportsLayout,
hasRootPaddingAwareAlignments: _settings.__experimentalFeatures?.useRootPaddingAwareAlignments,
isZoomedOut: _isZoomOut()
};
}, []);
const deviceStyles = (0,external_wp_blockEditor_namespaceObject.__experimentalUseResizeCanvas)(deviceType);
const [globalLayoutSettings] = (0,external_wp_blockEditor_namespaceObject.useSettings)('layout');
// fallbackLayout is used if there is no Post Content,
// and for Post Title.
const fallbackLayout = (0,external_wp_element_namespaceObject.useMemo)(() => {
if (renderingMode !== 'post-only' || isDesignPostType) {
return {
type: 'default'
};
}
if (themeSupportsLayout) {
// We need to ensure support for wide and full alignments,
// so we add the constrained type.
return {
...globalLayoutSettings,
type: 'constrained'
};
}
// Set default layout for classic themes so all alignments are supported.
return {
type: 'default'
};
}, [renderingMode, themeSupportsLayout, globalLayoutSettings, isDesignPostType]);
const newestPostContentAttributes = (0,external_wp_element_namespaceObject.useMemo)(() => {
if (!editedPostTemplate?.content && !editedPostTemplate?.blocks && postContentAttributes) {
return postContentAttributes;
}
// When in template editing mode, we can access the blocks directly.
if (editedPostTemplate?.blocks) {
return getPostContentAttributes(editedPostTemplate?.blocks);
}
// If there are no blocks, we have to parse the content string.
// Best double-check it's a string otherwise the parse function gets unhappy.
const parseableContent = typeof editedPostTemplate?.content === 'string' ? editedPostTemplate?.content : '';
return getPostContentAttributes((0,external_wp_blocks_namespaceObject.parse)(parseableContent)) || {};
}, [editedPostTemplate?.content, editedPostTemplate?.blocks, postContentAttributes]);
const hasPostContentAtRootLevel = (0,external_wp_element_namespaceObject.useMemo)(() => {
if (!editedPostTemplate?.content && !editedPostTemplate?.blocks) {
return false;
}
// When in template editing mode, we can access the blocks directly.
if (editedPostTemplate?.blocks) {
return checkForPostContentAtRootLevel(editedPostTemplate?.blocks);
}
// If there are no blocks, we have to parse the content string.
// Best double-check it's a string otherwise the parse function gets unhappy.
const parseableContent = typeof editedPostTemplate?.content === 'string' ? editedPostTemplate?.content : '';
return checkForPostContentAtRootLevel((0,external_wp_blocks_namespaceObject.parse)(parseableContent)) || false;
}, [editedPostTemplate?.content, editedPostTemplate?.blocks]);
const {
layout = {},
align = ''
} = newestPostContentAttributes || {};
const postContentLayoutClasses = useLayoutClasses(newestPostContentAttributes, 'core/post-content');
const blockListLayoutClass = dist_clsx({
'is-layout-flow': !themeSupportsLayout
}, themeSupportsLayout && postContentLayoutClasses, align && `align${align}`);
const postContentLayoutStyles = useLayoutStyles(newestPostContentAttributes, 'core/post-content', '.block-editor-block-list__layout.is-root-container');
// Update type for blocks using legacy layouts.
const postContentLayout = (0,external_wp_element_namespaceObject.useMemo)(() => {
return layout && (layout?.type === 'constrained' || layout?.inherit || layout?.contentSize || layout?.wideSize) ? {
...globalLayoutSettings,
...layout,
type: 'constrained'
} : {
...globalLayoutSettings,
...layout,
type: 'default'
};
}, [layout?.type, layout?.inherit, layout?.contentSize, layout?.wideSize, globalLayoutSettings]);
// If there is a Post Content block we use its layout for the block list;
// if not, this must be a classic theme, in which case we use the fallback layout.
const blockListLayout = postContentAttributes ? postContentLayout : fallbackLayout;
const postEditorLayout = blockListLayout?.type === 'default' && !hasPostContentAtRootLevel ? fallbackLayout : blockListLayout;
const observeTypingRef = (0,external_wp_blockEditor_namespaceObject.__unstableUseTypingObserver)();
const titleRef = (0,external_wp_element_namespaceObject.useRef)();
(0,external_wp_element_namespaceObject.useEffect)(() => {
if (!autoFocus || !isCleanNewPost()) {
return;
}
titleRef?.current?.focus();
}, [autoFocus, isCleanNewPost]);
// Add some styles for alignwide/alignfull Post Content and its children.
const alignCSS = `.is-root-container.alignwide { max-width: var(--wp--style--global--wide-size); margin-left: auto; margin-right: auto;}
.is-root-container.alignwide:where(.is-layout-flow) > :not(.alignleft):not(.alignright) { max-width: var(--wp--style--global--wide-size);}
.is-root-container.alignfull { max-width: none; margin-left: auto; margin-right: auto;}
.is-root-container.alignfull:where(.is-layout-flow) > :not(.alignleft):not(.alignright) { max-width: none;}`;
const localRef = (0,external_wp_element_namespaceObject.useRef)();
const typewriterRef = (0,external_wp_blockEditor_namespaceObject.__unstableUseTypewriter)();
contentRef = (0,external_wp_compose_namespaceObject.useMergeRefs)([localRef, contentRef, renderingMode === 'post-only' ? typewriterRef : null, useFlashEditableBlocks({
isEnabled: renderingMode === 'template-locked'
}), useSelectNearestEditableBlock({
isEnabled: renderingMode === 'template-locked'
}), useZoomOutModeExit()]);
const zoomOutProps = isZoomedOut && !isTabletViewport ? {
scale: 'default',
frameSize: '40px'
} : {};
const forceFullHeight = postType === NAVIGATION_POST_TYPE;
const enableResizing = [NAVIGATION_POST_TYPE, TEMPLATE_PART_POST_TYPE, PATTERN_POST_TYPE].includes(postType) &&
// Disable in previews / view mode.
!isPreview &&
// Disable resizing in mobile viewport.
!isMobileViewport &&
// Dsiable resizing in zoomed-out mode.
!isZoomedOut;
const shouldIframe = !disableIframe || ['Tablet', 'Mobile'].includes(deviceType);
const iframeStyles = (0,external_wp_element_namespaceObject.useMemo)(() => {
return [...(styles !== null && styles !== void 0 ? styles : []), {
// Ensures margins of children are contained so that the body background paints behind them.
// Otherwise, the background of html (when zoomed out) would show there and appear broken. It’s
// important mostly for post-only views yet conceivably an issue in templated views too.
css: `:where(.block-editor-iframe__body){display:flow-root;}.is-root-container{display:flow-root;${
// Some themes will have `min-height: 100vh` for the root container,
// which isn't a requirement in auto resize mode.
enableResizing ? 'min-height:0!important;' : ''}}`
}];
}, [styles, enableResizing]);
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", {
className: dist_clsx('editor-visual-editor',
// this class is here for backward compatibility reasons.
'edit-post-visual-editor', className, {
'has-padding': isFocusedEntity || enableResizing,
'is-resizable': enableResizing,
'is-iframed': shouldIframe
}),
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(resizable_editor, {
enableResizing: enableResizing,
height: sizes.height && !forceFullHeight ? sizes.height : '100%',
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(BlockCanvas, {
shouldIframe: shouldIframe,
contentRef: contentRef,
styles: iframeStyles,
height: "100%",
iframeProps: {
...iframeProps,
...zoomOutProps,
style: {
...iframeProps?.style,
...deviceStyles
}
},
children: [themeSupportsLayout && !themeHasDisabledLayoutStyles && renderingMode === 'post-only' && !isDesignPostType && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, {
children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(LayoutStyle, {
selector: ".editor-visual-editor__post-title-wrapper",
layout: fallbackLayout
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(LayoutStyle, {
selector: ".block-editor-block-list__layout.is-root-container",
layout: postEditorLayout
}), align && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(LayoutStyle, {
css: alignCSS
}), postContentLayoutStyles && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(LayoutStyle, {
layout: postContentLayout,
css: postContentLayoutStyles
})]
}), renderingMode === 'post-only' && !isDesignPostType && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", {
className: dist_clsx('editor-visual-editor__post-title-wrapper',
// The following class is only here for backward comapatibility
// some themes might be using it to style the post title.
'edit-post-visual-editor__post-title-wrapper', {
'has-global-padding': hasRootPaddingAwareAlignments
}),
contentEditable: false,
ref: observeTypingRef,
style: {
// This is using inline styles
// so it's applied for both iframed and non iframed editors.
marginTop: '4rem'
},
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(post_title, {
ref: titleRef
})
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_blockEditor_namespaceObject.RecursionProvider, {
blockName: wrapperBlockName,
uniqueId: wrapperUniqueId,
children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_blockEditor_namespaceObject.BlockList, {
className: dist_clsx('is-' + deviceType.toLowerCase() + '-preview', renderingMode !== 'post-only' || isDesignPostType ? 'wp-site-blocks' : `${blockListLayoutClass} wp-block-post-content` // Ensure root level blocks receive default/flow blockGap styling rules.
),
layout: blockListLayout,
dropZoneElement:
// When iframed, pass in the html element of the iframe to
// ensure the drop zone extends to the edges of the iframe.
disableIframe ? localRef.current : localRef.current?.parentNode,
__unstableDisableDropZone:
// In template preview mode, disable drop zones at the root of the template.
renderingMode === 'template-locked' ? true : false
}), renderingMode === 'template-locked' && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(EditTemplateBlocksNotification, {
contentRef: localRef
})]
}),
// Avoid resize listeners when not needed,
// these will trigger unnecessary re-renders
// when animating the iframe width.
enableResizing && resizeObserver]
})
})
});
}
/* harmony default export */ const visual_editor = (VisualEditor);
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/components/editor-interface/index.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const interfaceLabels = {
/* translators: accessibility text for the editor top bar landmark region. */
header: (0,external_wp_i18n_namespaceObject.__)('Editor top bar'),
/* translators: accessibility text for the editor content landmark region. */
body: (0,external_wp_i18n_namespaceObject.__)('Editor content'),
/* translators: accessibility text for the editor settings landmark region. */
sidebar: (0,external_wp_i18n_namespaceObject.__)('Editor settings'),
/* translators: accessibility text for the editor publish landmark region. */
actions: (0,external_wp_i18n_namespaceObject.__)('Editor publish'),
/* translators: accessibility text for the editor footer landmark region. */
footer: (0,external_wp_i18n_namespaceObject.__)('Editor footer')
};
function EditorInterface({
className,
styles,
children,
forceIsDirty,
contentRef,
disableIframe,
autoFocus,
customSaveButton,
customSavePanel,
forceDisableBlockTools,
title,
iframeProps
}) {
const {
mode,
isRichEditingEnabled,
isInserterOpened,
isListViewOpened,
isDistractionFree,
isPreviewMode,
showBlockBreadcrumbs,
documentLabel,
isZoomOut
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
get
} = select(external_wp_preferences_namespaceObject.store);
const {
getEditorSettings,
getPostTypeLabel
} = select(store_store);
const editorSettings = getEditorSettings();
const postTypeLabel = getPostTypeLabel();
const {
isZoomOut: _isZoomOut
} = unlock(select(external_wp_blockEditor_namespaceObject.store));
return {
mode: select(store_store).getEditorMode(),
isRichEditingEnabled: editorSettings.richEditingEnabled,
isInserterOpened: select(store_store).isInserterOpened(),
isListViewOpened: select(store_store).isListViewOpened(),
isDistractionFree: get('core', 'distractionFree'),
isPreviewMode: editorSettings.__unstableIsPreviewMode,
showBlockBreadcrumbs: get('core', 'showBlockBreadcrumbs'),
documentLabel:
// translators: Default label for the Document in the Block Breadcrumb.
postTypeLabel || (0,external_wp_i18n_namespaceObject._x)('Document', 'noun, breadcrumb'),
isZoomOut: _isZoomOut()
};
}, []);
const isLargeViewport = (0,external_wp_compose_namespaceObject.useViewportMatch)('medium');
const secondarySidebarLabel = isListViewOpened ? (0,external_wp_i18n_namespaceObject.__)('Document Overview') : (0,external_wp_i18n_namespaceObject.__)('Block Library');
// Local state for save panel.
// Note 'truthy' callback implies an open panel.
const [entitiesSavedStatesCallback, setEntitiesSavedStatesCallback] = (0,external_wp_element_namespaceObject.useState)(false);
const closeEntitiesSavedStates = (0,external_wp_element_namespaceObject.useCallback)(arg => {
if (typeof entitiesSavedStatesCallback === 'function') {
entitiesSavedStatesCallback(arg);
}
setEntitiesSavedStatesCallback(false);
}, [entitiesSavedStatesCallback]);
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(interface_skeleton, {
isDistractionFree: isDistractionFree,
className: dist_clsx('editor-editor-interface', className, {
'is-entity-save-view-open': !!entitiesSavedStatesCallback,
'is-distraction-free': isDistractionFree && !isPreviewMode
}),
labels: {
...interfaceLabels,
secondarySidebar: secondarySidebarLabel
},
header: !isPreviewMode && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(components_header, {
forceIsDirty: forceIsDirty,
setEntitiesSavedStatesCallback: setEntitiesSavedStatesCallback,
customSaveButton: customSaveButton,
forceDisableBlockTools: forceDisableBlockTools,
title: title,
isEditorIframed: !disableIframe
}),
editorNotices: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(editor_notices, {}),
secondarySidebar: !isPreviewMode && mode === 'visual' && (isInserterOpened && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(InserterSidebar, {}) || isListViewOpened && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ListViewSidebar, {})),
sidebar: !isPreviewMode && !isDistractionFree && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(complementary_area.Slot, {
scope: "core"
}),
content: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, {
children: [!isDistractionFree && !isPreviewMode && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(editor_notices, {}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(content_slot_fill.Slot, {
children: ([editorCanvasView]) => editorCanvasView ? editorCanvasView : /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, {
children: [!isPreviewMode && (mode === 'text' || !isRichEditingEnabled) && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(TextEditor
// We should auto-focus the canvas (title) on load.
// eslint-disable-next-line jsx-a11y/no-autofocus
, {
autoFocus: autoFocus
}), !isPreviewMode && !isLargeViewport && mode === 'visual' && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_blockEditor_namespaceObject.BlockToolbar, {
hideDragHandle: true
}), (isPreviewMode || isRichEditingEnabled && mode === 'visual') && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(visual_editor, {
styles: styles,
contentRef: contentRef,
disableIframe: disableIframe
// We should auto-focus the canvas (title) on load.
// eslint-disable-next-line jsx-a11y/no-autofocus
,
autoFocus: autoFocus,
iframeProps: iframeProps
}), children]
})
})]
}),
footer: !isPreviewMode && !isDistractionFree && isLargeViewport && showBlockBreadcrumbs && isRichEditingEnabled && !isZoomOut && mode === 'visual' && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_blockEditor_namespaceObject.BlockBreadcrumb, {
rootLabelText: documentLabel
}),
actions: !isPreviewMode ? customSavePanel || /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(SavePublishPanels, {
closeEntitiesSavedStates: closeEntitiesSavedStates,
isEntitiesSavedStatesOpen: entitiesSavedStatesCallback,
setEntitiesSavedStatesCallback: setEntitiesSavedStatesCallback,
forceIsDirtyPublishPanel: forceIsDirty
}) : undefined
});
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/components/pattern-overrides-panel/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const {
OverridesPanel
} = unlock(external_wp_patterns_namespaceObject.privateApis);
function PatternOverridesPanel() {
const supportsPatternOverridesPanel = (0,external_wp_data_namespaceObject.useSelect)(select => select(store_store).getCurrentPostType() === 'wp_block', []);
if (!supportsPatternOverridesPanel) {
return null;
}
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(OverridesPanel, {});
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/components/post-actions/actions.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function usePostActions({
postType,
onActionPerformed,
context
}) {
const {
defaultActions
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getEntityActions
} = unlock(select(store_store));
return {
defaultActions: getEntityActions('postType', postType)
};
}, [postType]);
const {
registerPostTypeActions
} = unlock((0,external_wp_data_namespaceObject.useDispatch)(store_store));
(0,external_wp_element_namespaceObject.useEffect)(() => {
registerPostTypeActions(postType);
}, [registerPostTypeActions, postType]);
return (0,external_wp_element_namespaceObject.useMemo)(() => {
// Filter actions based on provided context. If not provided
// all actions are returned. We'll have a single entry for getting the actions
// and the consumer should provide the context to filter the actions, if needed.
// Actions should also provide the `context` they support, if it's specific, to
// compare with the provided context to get all the actions.
// Right now the only supported context is `list`.
const actions = defaultActions.filter(action => {
if (!action.context) {
return true;
}
return action.context === context;
});
if (onActionPerformed) {
for (let i = 0; i < actions.length; ++i) {
if (actions[i].callback) {
const existingCallback = actions[i].callback;
actions[i] = {
...actions[i],
callback: (items, argsObject) => {
existingCallback(items, {
...argsObject,
onActionPerformed: _items => {
if (argsObject?.onActionPerformed) {
argsObject.onActionPerformed(_items);
}
onActionPerformed(actions[i].id, _items);
}
});
}
};
}
if (actions[i].RenderModal) {
const ExistingRenderModal = actions[i].RenderModal;
actions[i] = {
...actions[i],
RenderModal: props => {
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ExistingRenderModal, {
...props,
onActionPerformed: _items => {
if (props.onActionPerformed) {
props.onActionPerformed(_items);
}
onActionPerformed(actions[i].id, _items);
}
});
}
};
}
}
}
return actions;
}, [defaultActions, onActionPerformed, context]);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/components/post-actions/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const {
DropdownMenuV2,
kebabCase
} = unlock(external_wp_components_namespaceObject.privateApis);
function PostActions({
postType,
postId,
onActionPerformed
}) {
const [isActionsMenuOpen, setIsActionsMenuOpen] = (0,external_wp_element_namespaceObject.useState)(false);
const {
item,
permissions
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getEditedEntityRecord,
getEntityRecordPermissions
} = unlock(select(external_wp_coreData_namespaceObject.store));
return {
item: getEditedEntityRecord('postType', postType, postId),
permissions: getEntityRecordPermissions('postType', postType, postId)
};
}, [postId, postType]);
const itemWithPermissions = (0,external_wp_element_namespaceObject.useMemo)(() => {
return {
...item,
permissions
};
}, [item, permissions]);
const allActions = usePostActions({
postType,
onActionPerformed
});
const actions = (0,external_wp_element_namespaceObject.useMemo)(() => {
return allActions.filter(action => {
return !action.isEligible || action.isEligible(itemWithPermissions);
});
}, [allActions, itemWithPermissions]);
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(DropdownMenuV2, {
open: isActionsMenuOpen,
trigger: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, {
size: "small",
icon: more_vertical,
label: (0,external_wp_i18n_namespaceObject.__)('Actions'),
disabled: !actions.length,
accessibleWhenDisabled: true,
className: "editor-all-actions-button",
onClick: () => setIsActionsMenuOpen(!isActionsMenuOpen)
}),
onOpenChange: setIsActionsMenuOpen,
placement: "bottom-end",
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ActionsDropdownMenuGroup, {
actions: actions,
item: itemWithPermissions,
onClose: () => {
setIsActionsMenuOpen(false);
}
})
});
}
// From now on all the functions on this file are copied as from the dataviews packages,
// The editor packages should not be using the dataviews packages directly,
// and the dataviews package should not be using the editor packages directly,
// so duplicating the code here seems like the least bad option.
// Copied as is from packages/dataviews/src/item-actions.js
function DropdownMenuItemTrigger({
action,
onClick,
items
}) {
const label = typeof action.label === 'string' ? action.label : action.label(items);
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(DropdownMenuV2.Item, {
onClick: onClick,
hideOnClick: !action.RenderModal,
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(DropdownMenuV2.ItemLabel, {
children: label
})
});
}
// Copied as is from packages/dataviews/src/item-actions.js
// With an added onClose prop.
function ActionWithModal({
action,
item,
ActionTrigger,
onClose
}) {
const [isModalOpen, setIsModalOpen] = (0,external_wp_element_namespaceObject.useState)(false);
const actionTriggerProps = {
action,
onClick: () => setIsModalOpen(true),
items: [item]
};
const {
RenderModal,
hideModalHeader
} = action;
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, {
children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ActionTrigger, {
...actionTriggerProps
}), isModalOpen && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Modal, {
title: action.modalHeader || action.label,
__experimentalHideHeader: !!hideModalHeader,
onRequestClose: () => {
setIsModalOpen(false);
},
overlayClassName: `editor-action-modal editor-action-modal__${kebabCase(action.id)}`,
focusOnMount: "firstContentElement",
size: "small",
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(RenderModal, {
items: [item],
closeModal: () => {
setIsModalOpen(false);
onClose();
}
})
})]
});
}
// Copied as is from packages/dataviews/src/item-actions.js
// With an added onClose prop.
function ActionsDropdownMenuGroup({
actions,
item,
onClose
}) {
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(DropdownMenuV2.Group, {
children: actions.map(action => {
if (action.RenderModal) {
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ActionWithModal, {
action: action,
item: item,
ActionTrigger: DropdownMenuItemTrigger,
onClose: onClose
}, action.id);
}
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(DropdownMenuItemTrigger, {
action: action,
onClick: () => action.callback([item]),
items: [item]
}, action.id);
})
});
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/components/post-card-panel/index.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function PostCardPanel({
postType,
postId,
onActionPerformed
}) {
const {
isFrontPage,
isPostsPage,
title,
icon,
isSync
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
__experimentalGetTemplateInfo
} = select(store_store);
const {
canUser,
getEditedEntityRecord
} = select(external_wp_coreData_namespaceObject.store);
const siteSettings = canUser('read', {
kind: 'root',
name: 'site'
}) ? getEditedEntityRecord('root', 'site') : undefined;
const _record = getEditedEntityRecord('postType', postType, postId);
const _templateInfo = [TEMPLATE_POST_TYPE, TEMPLATE_PART_POST_TYPE].includes(postType) && __experimentalGetTemplateInfo(_record);
let _isSync = false;
if (GLOBAL_POST_TYPES.includes(postType)) {
if (PATTERN_POST_TYPE === postType) {
// When the post is first created, the top level wp_pattern_sync_status is not set so get meta value instead.
const currentSyncStatus = _record?.meta?.wp_pattern_sync_status === 'unsynced' ? 'unsynced' : _record?.wp_pattern_sync_status;
_isSync = currentSyncStatus !== 'unsynced';
} else {
_isSync = true;
}
}
return {
title: _templateInfo?.title || _record?.title,
icon: unlock(select(store_store)).getPostIcon(postType, {
area: _record?.area
}),
isSync: _isSync,
isFrontPage: siteSettings?.page_on_front === postId,
isPostsPage: siteSettings?.page_for_posts === postId
};
}, [postId, postType]);
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", {
className: "editor-post-card-panel",
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalHStack, {
spacing: 2,
className: "editor-post-card-panel__header",
align: "flex-start",
children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Icon, {
className: dist_clsx('editor-post-card-panel__icon', {
'is-sync': isSync
}),
icon: icon
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalText, {
numberOfLines: 2,
truncate: true,
className: "editor-post-card-panel__title",
weight: 500,
as: "h2",
lineHeight: "20px",
children: [title ? (0,external_wp_htmlEntities_namespaceObject.decodeEntities)(title) : (0,external_wp_i18n_namespaceObject.__)('No title'), isFrontPage && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", {
className: "editor-post-card-panel__title-badge",
children: (0,external_wp_i18n_namespaceObject.__)('Homepage')
}), isPostsPage && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", {
className: "editor-post-card-panel__title-badge",
children: (0,external_wp_i18n_namespaceObject.__)('Posts Page')
})]
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PostActions, {
postType: postType,
postId: postId,
onActionPerformed: onActionPerformed
})]
})
});
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/components/post-content-information/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
// Taken from packages/editor/src/components/time-to-read/index.js.
const post_content_information_AVERAGE_READING_RATE = 189;
// This component renders the wordcount and reading time for the post.
function PostContentInformation() {
const {
postContent
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getEditedPostAttribute,
getCurrentPostType,
getCurrentPostId
} = select(store_store);
const {
canUser
} = select(external_wp_coreData_namespaceObject.store);
const {
getEntityRecord
} = select(external_wp_coreData_namespaceObject.store);
const siteSettings = canUser('read', {
kind: 'root',
name: 'site'
}) ? getEntityRecord('root', 'site') : undefined;
const postType = getCurrentPostType();
const _id = getCurrentPostId();
const isPostsPage = +_id === siteSettings?.page_for_posts;
const showPostContentInfo = !isPostsPage && ![TEMPLATE_POST_TYPE, TEMPLATE_PART_POST_TYPE].includes(postType);
return {
postContent: showPostContentInfo && getEditedPostAttribute('content')
};
}, []);
/*
* translators: If your word count is based on single characters (e.g. East Asian characters),
* enter 'characters_excluding_spaces' or 'characters_including_spaces'. Otherwise, enter 'words'.
* Do not translate into your own language.
*/
const wordCountType = (0,external_wp_i18n_namespaceObject._x)('words', 'Word count type. Do not translate!');
const wordsCounted = (0,external_wp_element_namespaceObject.useMemo)(() => postContent ? (0,external_wp_wordcount_namespaceObject.count)(postContent, wordCountType) : 0, [postContent, wordCountType]);
if (!wordsCounted) {
return null;
}
const readingTime = Math.round(wordsCounted / post_content_information_AVERAGE_READING_RATE);
const wordsCountText = (0,external_wp_i18n_namespaceObject.sprintf)(
// translators: %s: the number of words in the post.
(0,external_wp_i18n_namespaceObject._n)('%s word', '%s words', wordsCounted), wordsCounted.toLocaleString());
const minutesText = readingTime <= 1 ? (0,external_wp_i18n_namespaceObject.__)('1 minute') : (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %s: the number of minutes to read the post. */
(0,external_wp_i18n_namespaceObject._n)('%s minute', '%s minutes', readingTime), readingTime.toLocaleString());
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", {
className: "editor-post-content-information",
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalText, {
children: (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: 1: How many words a post has. 2: the number of minutes to read the post (e.g. 130 words, 2 minutes read time.) */
(0,external_wp_i18n_namespaceObject.__)('%1$s, %2$s read time.'), wordsCountText, minutesText)
})
});
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/components/post-format/panel.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Renders the Post Author Panel component.
*
* @return {Component} The component to be rendered.
*/
function panel_PostFormat() {
const {
postFormat
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getEditedPostAttribute
} = select(store_store);
const _postFormat = getEditedPostAttribute('format');
return {
postFormat: _postFormat !== null && _postFormat !== void 0 ? _postFormat : 'standard'
};
}, []);
const activeFormat = POST_FORMATS.find(format => format.id === postFormat);
// Use internal state instead of a ref to make sure that the component
// re-renders when the popover's anchor updates.
const [popoverAnchor, setPopoverAnchor] = (0,external_wp_element_namespaceObject.useState)(null);
// Memoize popoverProps to avoid returning a new object every time.
const popoverProps = (0,external_wp_element_namespaceObject.useMemo)(() => ({
// Anchor the popover to the middle of the entire row so that it doesn't
// move around when the label changes.
anchor: popoverAnchor,
placement: 'left-start',
offset: 36,
shift: true
}), [popoverAnchor]);
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(post_format_check, {
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(post_panel_row, {
label: (0,external_wp_i18n_namespaceObject.__)('Format'),
ref: setPopoverAnchor,
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Dropdown, {
popoverProps: popoverProps,
contentClassName: "editor-post-format__dialog",
focusOnMount: true,
renderToggle: ({
isOpen,
onToggle
}) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, {
size: "compact",
variant: "tertiary",
"aria-expanded": isOpen,
"aria-label": (0,external_wp_i18n_namespaceObject.sprintf)(
// translators: %s: Current post format.
(0,external_wp_i18n_namespaceObject.__)('Change format: %s'), activeFormat?.caption),
onClick: onToggle,
children: activeFormat?.caption
}),
renderContent: ({
onClose
}) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", {
className: "editor-post-format__dialog-content",
children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_blockEditor_namespaceObject.__experimentalInspectorPopoverHeader, {
title: (0,external_wp_i18n_namespaceObject.__)('Format'),
onClose: onClose
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PostFormat, {})]
})
})
})
});
}
/* harmony default export */ const post_format_panel = (panel_PostFormat);
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/components/post-last-edited-panel/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function PostLastEditedPanel() {
const modified = (0,external_wp_data_namespaceObject.useSelect)(select => select(store_store).getEditedPostAttribute('modified'), []);
const lastEditedText = modified && (0,external_wp_i18n_namespaceObject.sprintf)(
// translators: %s: Human-readable time difference, e.g. "2 days ago".
(0,external_wp_i18n_namespaceObject.__)('Last edited %s.'), (0,external_wp_date_namespaceObject.humanTimeDiff)(modified));
if (!lastEditedText) {
return null;
}
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", {
className: "editor-post-last-edited-panel",
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalText, {
children: lastEditedText
})
});
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/components/post-panel-section/index.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
function PostPanelSection({
className,
children
}) {
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalVStack, {
className: dist_clsx('editor-post-panel__section', className),
children: children
});
}
/* harmony default export */ const post_panel_section = (PostPanelSection);
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/components/blog-title/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const blog_title_EMPTY_OBJECT = {};
function BlogTitle() {
const {
editEntityRecord
} = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_coreData_namespaceObject.store);
const {
postsPageTitle,
postsPageId,
isTemplate,
postSlug
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getEntityRecord,
getEditedEntityRecord,
canUser
} = select(external_wp_coreData_namespaceObject.store);
const siteSettings = canUser('read', {
kind: 'root',
name: 'site'
}) ? getEntityRecord('root', 'site') : undefined;
const _postsPageRecord = siteSettings?.page_for_posts ? getEditedEntityRecord('postType', 'page', siteSettings?.page_for_posts) : blog_title_EMPTY_OBJECT;
const {
getEditedPostAttribute,
getCurrentPostType
} = select(store_store);
return {
postsPageId: _postsPageRecord?.id,
postsPageTitle: _postsPageRecord?.title,
isTemplate: getCurrentPostType() === TEMPLATE_POST_TYPE,
postSlug: getEditedPostAttribute('slug')
};
}, []);
// Use internal state instead of a ref to make sure that the component
// re-renders when the popover's anchor updates.
const [popoverAnchor, setPopoverAnchor] = (0,external_wp_element_namespaceObject.useState)(null);
// Memoize popoverProps to avoid returning a new object every time.
const popoverProps = (0,external_wp_element_namespaceObject.useMemo)(() => ({
// Anchor the popover to the middle of the entire row so that it doesn't
// move around when the label changes.
anchor: popoverAnchor,
placement: 'left-start',
offset: 36,
shift: true
}), [popoverAnchor]);
if (!isTemplate || !['home', 'index'].includes(postSlug) || !postsPageId) {
return null;
}
const setPostsPageTitle = newValue => {
editEntityRecord('postType', 'page', postsPageId, {
title: newValue
});
};
const decodedTitle = (0,external_wp_htmlEntities_namespaceObject.decodeEntities)(postsPageTitle);
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(post_panel_row, {
label: (0,external_wp_i18n_namespaceObject.__)('Blog title'),
ref: setPopoverAnchor,
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Dropdown, {
popoverProps: popoverProps,
contentClassName: "editor-blog-title-dropdown__content",
focusOnMount: true,
renderToggle: ({
isOpen,
onToggle
}) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, {
size: "compact",
variant: "tertiary",
"aria-expanded": isOpen,
"aria-label": (0,external_wp_i18n_namespaceObject.sprintf)(
// translators: %s: Current post link.
(0,external_wp_i18n_namespaceObject.__)('Change blog title: %s'), decodedTitle),
onClick: onToggle,
children: decodedTitle
}),
renderContent: ({
onClose
}) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, {
children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_blockEditor_namespaceObject.__experimentalInspectorPopoverHeader, {
title: (0,external_wp_i18n_namespaceObject.__)('Blog title'),
onClose: onClose
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalInputControl, {
placeholder: (0,external_wp_i18n_namespaceObject.__)('No title'),
size: "__unstable-large",
value: postsPageTitle,
onChange: (0,external_wp_compose_namespaceObject.debounce)(setPostsPageTitle, 300),
label: (0,external_wp_i18n_namespaceObject.__)('Blog title'),
help: (0,external_wp_i18n_namespaceObject.__)('Set the Posts Page title. Appears in search results, and when the page is shared on social media.'),
hideLabelFromVision: true
})]
})
})
});
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/components/posts-per-page/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function PostsPerPage() {
const {
editEntityRecord
} = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_coreData_namespaceObject.store);
const {
postsPerPage,
isTemplate,
postSlug
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getEditedPostAttribute,
getCurrentPostType
} = select(store_store);
const {
getEditedEntityRecord,
canUser
} = select(external_wp_coreData_namespaceObject.store);
const siteSettings = canUser('read', {
kind: 'root',
name: 'site'
}) ? getEditedEntityRecord('root', 'site') : undefined;
return {
isTemplate: getCurrentPostType() === TEMPLATE_POST_TYPE,
postSlug: getEditedPostAttribute('slug'),
postsPerPage: siteSettings?.posts_per_page || 1
};
}, []);
// Use internal state instead of a ref to make sure that the component
// re-renders when the popover's anchor updates.
const [popoverAnchor, setPopoverAnchor] = (0,external_wp_element_namespaceObject.useState)(null);
// Memoize popoverProps to avoid returning a new object every time.
const popoverProps = (0,external_wp_element_namespaceObject.useMemo)(() => ({
// Anchor the popover to the middle of the entire row so that it doesn't
// move around when the label changes.
anchor: popoverAnchor,
placement: 'left-start',
offset: 36,
shift: true
}), [popoverAnchor]);
if (!isTemplate || !['home', 'index'].includes(postSlug)) {
return null;
}
const setPostsPerPage = newValue => {
editEntityRecord('root', 'site', undefined, {
posts_per_page: newValue
});
};
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(post_panel_row, {
label: (0,external_wp_i18n_namespaceObject.__)('Posts per page'),
ref: setPopoverAnchor,
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Dropdown, {
popoverProps: popoverProps,
contentClassName: "editor-posts-per-page-dropdown__content",
focusOnMount: true,
renderToggle: ({
isOpen,
onToggle
}) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, {
size: "compact",
variant: "tertiary",
"aria-expanded": isOpen,
"aria-label": (0,external_wp_i18n_namespaceObject.__)('Change posts per page'),
onClick: onToggle,
children: postsPerPage
}),
renderContent: ({
onClose
}) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, {
children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_blockEditor_namespaceObject.__experimentalInspectorPopoverHeader, {
title: (0,external_wp_i18n_namespaceObject.__)('Posts per page'),
onClose: onClose
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalNumberControl, {
placeholder: 0,
value: postsPerPage,
size: "__unstable-large",
spinControls: "custom",
step: "1",
min: "1",
onChange: setPostsPerPage,
label: (0,external_wp_i18n_namespaceObject.__)('Posts per page'),
help: (0,external_wp_i18n_namespaceObject.__)('Set the default number of posts to display on blog pages, including categories and tags. Some templates may override this setting.'),
hideLabelFromVision: true
})]
})
})
});
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/components/site-discussion/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const site_discussion_COMMENT_OPTIONS = [{
label: (0,external_wp_i18n_namespaceObject._x)('Open', 'Adjective: e.g. "Comments are open"'),
value: 'open',
description: (0,external_wp_i18n_namespaceObject.__)('Visitors can add new comments and replies.')
}, {
label: (0,external_wp_i18n_namespaceObject.__)('Closed'),
value: '',
description: [(0,external_wp_i18n_namespaceObject.__)('Visitors cannot add new comments or replies.'), (0,external_wp_i18n_namespaceObject.__)('Existing comments remain visible.')].join(' ')
}];
function SiteDiscussion() {
const {
editEntityRecord
} = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_coreData_namespaceObject.store);
const {
allowCommentsOnNewPosts,
isTemplate,
postSlug
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getEditedPostAttribute,
getCurrentPostType
} = select(store_store);
const {
getEditedEntityRecord,
canUser
} = select(external_wp_coreData_namespaceObject.store);
const siteSettings = canUser('read', {
kind: 'root',
name: 'site'
}) ? getEditedEntityRecord('root', 'site') : undefined;
return {
isTemplate: getCurrentPostType() === TEMPLATE_POST_TYPE,
postSlug: getEditedPostAttribute('slug'),
allowCommentsOnNewPosts: siteSettings?.default_comment_status || ''
};
}, []);
// Use internal state instead of a ref to make sure that the component
// re-renders when the popover's anchor updates.
const [popoverAnchor, setPopoverAnchor] = (0,external_wp_element_namespaceObject.useState)(null);
// Memoize popoverProps to avoid returning a new object every time.
const popoverProps = (0,external_wp_element_namespaceObject.useMemo)(() => ({
// Anchor the popover to the middle of the entire row so that it doesn't
// move around when the label changes.
anchor: popoverAnchor,
placement: 'left-start',
offset: 36,
shift: true
}), [popoverAnchor]);
if (!isTemplate || !['home', 'index'].includes(postSlug)) {
return null;
}
const setAllowCommentsOnNewPosts = newValue => {
editEntityRecord('root', 'site', undefined, {
default_comment_status: newValue ? 'open' : null
});
};
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(post_panel_row, {
label: (0,external_wp_i18n_namespaceObject.__)('Discussion'),
ref: setPopoverAnchor,
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Dropdown, {
popoverProps: popoverProps,
contentClassName: "editor-site-discussion-dropdown__content",
focusOnMount: true,
renderToggle: ({
isOpen,
onToggle
}) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, {
size: "compact",
variant: "tertiary",
"aria-expanded": isOpen,
"aria-label": (0,external_wp_i18n_namespaceObject.__)('Change discussion settings'),
onClick: onToggle,
children: allowCommentsOnNewPosts ? (0,external_wp_i18n_namespaceObject.__)('Comments open') : (0,external_wp_i18n_namespaceObject.__)('Comments closed')
}),
renderContent: ({
onClose
}) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, {
children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_blockEditor_namespaceObject.__experimentalInspectorPopoverHeader, {
title: (0,external_wp_i18n_namespaceObject.__)('Discussion'),
onClose: onClose
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalVStack, {
spacing: 3,
children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalText, {
children: (0,external_wp_i18n_namespaceObject.__)('Changes will apply to new posts only. Individual posts may override these settings.')
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.RadioControl, {
className: "editor-site-discussion__options",
hideLabelFromVision: true,
label: (0,external_wp_i18n_namespaceObject.__)('Comment status'),
options: site_discussion_COMMENT_OPTIONS,
onChange: setAllowCommentsOnNewPosts,
selected: allowCommentsOnNewPosts
})]
})]
})
})
});
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/components/sidebar/post-summary.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Module Constants
*/
const post_summary_PANEL_NAME = 'post-status';
function PostSummary({
onActionPerformed
}) {
const {
isRemovedPostStatusPanel,
postType,
postId
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
// We use isEditorPanelRemoved to hide the panel if it was programatically removed. We do
// not use isEditorPanelEnabled since this panel should not be disabled through the UI.
const {
isEditorPanelRemoved,
getCurrentPostType,
getCurrentPostId
} = select(store_store);
return {
isRemovedPostStatusPanel: isEditorPanelRemoved(post_summary_PANEL_NAME),
postType: getCurrentPostType(),
postId: getCurrentPostId()
};
}, []);
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(post_panel_section, {
className: "editor-post-summary",
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(plugin_post_status_info.Slot, {
children: fills => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_ReactJSXRuntime_namespaceObject.Fragment, {
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalVStack, {
spacing: 4,
children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PostCardPanel, {
postType: postType,
postId: postId,
onActionPerformed: onActionPerformed
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PostFeaturedImagePanel, {
withPanelBody: false
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PrivatePostExcerptPanel, {}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalVStack, {
spacing: 1,
children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PostContentInformation, {}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PostLastEditedPanel, {})]
}), !isRemovedPostStatusPanel && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalVStack, {
spacing: 4,
children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalVStack, {
spacing: 1,
children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PostStatus, {}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PostSchedulePanel, {}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PostURLPanel, {}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(panel, {}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PostTemplatePanel, {}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PostDiscussionPanel, {}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PrivatePostLastRevision, {}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PageAttributesPanel, {}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PostSyncStatus, {}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlogTitle, {}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PostsPerPage, {}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(SiteDiscussion, {}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(post_format_panel, {}), fills]
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PostTrash, {
onActionPerformed: onActionPerformed
})]
})]
})
})
})
});
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/components/post-transform-panel/hooks.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const {
EXCLUDED_PATTERN_SOURCES,
PATTERN_TYPES: hooks_PATTERN_TYPES
} = unlock(external_wp_patterns_namespaceObject.privateApis);
function injectThemeAttributeInBlockTemplateContent(block, currentThemeStylesheet) {
block.innerBlocks = block.innerBlocks.map(innerBlock => {
return injectThemeAttributeInBlockTemplateContent(innerBlock, currentThemeStylesheet);
});
if (block.name === 'core/template-part' && block.attributes.theme === undefined) {
block.attributes.theme = currentThemeStylesheet;
}
return block;
}
/**
* Filter all patterns and return only the ones that are compatible with the current template.
*
* @param {Array} patterns An array of patterns.
* @param {Object} template The current template.
* @return {Array} Array of patterns that are compatible with the current template.
*/
function filterPatterns(patterns, template) {
// Filter out duplicates.
const filterOutDuplicatesByName = (currentItem, index, items) => index === items.findIndex(item => currentItem.name === item.name);
// Filter out core/directory patterns not included in theme.json.
const filterOutExcludedPatternSources = pattern => !EXCLUDED_PATTERN_SOURCES.includes(pattern.source);
// Looks for patterns that have the same template type as the current template,
// or have a block type that matches the current template area.
const filterCompatiblePatterns = pattern => pattern.templateTypes?.includes(template.slug) || pattern.blockTypes?.includes('core/template-part/' + template.area);
return patterns.filter((pattern, index, items) => {
return filterOutDuplicatesByName(pattern, index, items) && filterOutExcludedPatternSources(pattern) && filterCompatiblePatterns(pattern);
});
}
function preparePatterns(patterns, currentThemeStylesheet) {
return patterns.map(pattern => ({
...pattern,
keywords: pattern.keywords || [],
type: hooks_PATTERN_TYPES.theme,
blocks: (0,external_wp_blocks_namespaceObject.parse)(pattern.content, {
__unstableSkipMigrationLogs: true
}).map(block => injectThemeAttributeInBlockTemplateContent(block, currentThemeStylesheet))
}));
}
function useAvailablePatterns(template) {
const {
blockPatterns,
restBlockPatterns,
currentThemeStylesheet
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
var _settings$__experimen;
const {
getEditorSettings
} = select(store_store);
const settings = getEditorSettings();
return {
blockPatterns: (_settings$__experimen = settings.__experimentalAdditionalBlockPatterns) !== null && _settings$__experimen !== void 0 ? _settings$__experimen : settings.__experimentalBlockPatterns,
restBlockPatterns: select(external_wp_coreData_namespaceObject.store).getBlockPatterns(),
currentThemeStylesheet: select(external_wp_coreData_namespaceObject.store).getCurrentTheme().stylesheet
};
}, []);
return (0,external_wp_element_namespaceObject.useMemo)(() => {
const mergedPatterns = [...(blockPatterns || []), ...(restBlockPatterns || [])];
const filteredPatterns = filterPatterns(mergedPatterns, template);
return preparePatterns(filteredPatterns, template, currentThemeStylesheet);
}, [blockPatterns, restBlockPatterns, template, currentThemeStylesheet]);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/components/post-transform-panel/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function post_transform_panel_TemplatesList({
availableTemplates,
onSelect
}) {
const shownTemplates = (0,external_wp_compose_namespaceObject.useAsyncList)(availableTemplates);
if (!availableTemplates || availableTemplates?.length === 0) {
return null;
}
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_blockEditor_namespaceObject.__experimentalBlockPatternsList, {
label: (0,external_wp_i18n_namespaceObject.__)('Templates'),
blockPatterns: availableTemplates,
shownPatterns: shownTemplates,
onClickPattern: onSelect,
showTitlesAsTooltip: true
});
}
function PostTransform() {
const {
record,
postType,
postId
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getCurrentPostType,
getCurrentPostId
} = select(store_store);
const {
getEditedEntityRecord
} = select(external_wp_coreData_namespaceObject.store);
const type = getCurrentPostType();
const id = getCurrentPostId();
return {
postType: type,
postId: id,
record: getEditedEntityRecord('postType', type, id)
};
}, []);
const {
editEntityRecord
} = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_coreData_namespaceObject.store);
const availablePatterns = useAvailablePatterns(record);
const onTemplateSelect = async selectedTemplate => {
await editEntityRecord('postType', postType, postId, {
blocks: selectedTemplate.blocks,
content: (0,external_wp_blocks_namespaceObject.serialize)(selectedTemplate.blocks)
});
};
if (!availablePatterns?.length) {
return null;
}
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.PanelBody, {
title: (0,external_wp_i18n_namespaceObject.__)('Design'),
initialOpen: record.type === TEMPLATE_PART_POST_TYPE,
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(post_transform_panel_TemplatesList, {
availableTemplates: availablePatterns,
onSelect: onTemplateSelect
})
});
}
function PostTransformPanel() {
const {
postType
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getCurrentPostType
} = select(store_store);
return {
postType: getCurrentPostType()
};
}, []);
if (![TEMPLATE_PART_POST_TYPE, TEMPLATE_POST_TYPE].includes(postType)) {
return null;
}
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PostTransform, {});
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/components/sidebar/constants.js
const sidebars = {
document: 'edit-post/document',
block: 'edit-post/block'
};
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/components/sidebar/header.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const {
Tabs
} = unlock(external_wp_components_namespaceObject.privateApis);
const SidebarHeader = (_, ref) => {
const {
documentLabel
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getPostTypeLabel
} = select(store_store);
return {
documentLabel:
// translators: Default label for the Document sidebar tab, not selected.
getPostTypeLabel() || (0,external_wp_i18n_namespaceObject._x)('Document', 'noun, sidebar')
};
}, []);
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(Tabs.TabList, {
ref: ref,
children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Tabs.Tab, {
tabId: sidebars.document
// Used for focus management in the SettingsSidebar component.
,
"data-tab-id": sidebars.document,
children: documentLabel
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Tabs.Tab, {
tabId: sidebars.block
// Used for focus management in the SettingsSidebar component.
,
"data-tab-id": sidebars.block,
children: (0,external_wp_i18n_namespaceObject.__)('Block')
})]
});
};
/* harmony default export */ const sidebar_header = ((0,external_wp_element_namespaceObject.forwardRef)(SidebarHeader));
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/components/template-content-panel/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const {
BlockQuickNavigation
} = unlock(external_wp_blockEditor_namespaceObject.privateApis);
const template_content_panel_POST_CONTENT_BLOCK_TYPES = ['core/post-title', 'core/post-featured-image', 'core/post-content'];
const TEMPLATE_PART_BLOCK = 'core/template-part';
function TemplateContentPanel() {
const postContentBlockTypes = (0,external_wp_element_namespaceObject.useMemo)(() => (0,external_wp_hooks_namespaceObject.applyFilters)('editor.postContentBlockTypes', template_content_panel_POST_CONTENT_BLOCK_TYPES), []);
const {
clientIds,
postType,
renderingMode
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getCurrentPostType,
getPostBlocksByName,
getRenderingMode
} = unlock(select(store_store));
const _postType = getCurrentPostType();
return {
postType: _postType,
clientIds: getPostBlocksByName(TEMPLATE_POST_TYPE === _postType ? TEMPLATE_PART_BLOCK : postContentBlockTypes),
renderingMode: getRenderingMode()
};
}, [postContentBlockTypes]);
const {
enableComplementaryArea
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
if (renderingMode === 'post-only' && postType !== TEMPLATE_POST_TYPE || clientIds.length === 0) {
return null;
}
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.PanelBody, {
title: (0,external_wp_i18n_namespaceObject.__)('Content'),
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockQuickNavigation, {
clientIds: clientIds,
onSelect: () => {
enableComplementaryArea('core', 'edit-post/document');
}
})
});
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/components/template-part-content-panel/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const {
BlockQuickNavigation: template_part_content_panel_BlockQuickNavigation
} = unlock(external_wp_blockEditor_namespaceObject.privateApis);
function TemplatePartContentPanelInner() {
const blockTypes = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getBlockTypes
} = select(external_wp_blocks_namespaceObject.store);
return getBlockTypes();
}, []);
const themeBlockNames = (0,external_wp_element_namespaceObject.useMemo)(() => {
return blockTypes.filter(blockType => {
return blockType.category === 'theme';
}).map(({
name
}) => name);
}, [blockTypes]);
const themeBlocks = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getBlocksByName
} = select(external_wp_blockEditor_namespaceObject.store);
return getBlocksByName(themeBlockNames);
}, [themeBlockNames]);
if (themeBlocks.length === 0) {
return null;
}
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.PanelBody, {
title: (0,external_wp_i18n_namespaceObject.__)('Content'),
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(template_part_content_panel_BlockQuickNavigation, {
clientIds: themeBlocks
})
});
}
function TemplatePartContentPanel() {
const postType = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getCurrentPostType
} = select(store_store);
return getCurrentPostType();
}, []);
if (postType !== TEMPLATE_PART_POST_TYPE) {
return null;
}
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(TemplatePartContentPanelInner, {});
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/components/provider/use-auto-switch-editor-sidebars.js
/**
* WordPress dependencies
*/
/**
* This listener hook monitors for block selection and triggers the appropriate
* sidebar state.
*/
function useAutoSwitchEditorSidebars() {
const {
hasBlockSelection
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
return {
hasBlockSelection: !!select(external_wp_blockEditor_namespaceObject.store).getBlockSelectionStart()
};
}, []);
const {
getActiveComplementaryArea
} = (0,external_wp_data_namespaceObject.useSelect)(store);
const {
enableComplementaryArea
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
const {
get: getPreference
} = (0,external_wp_data_namespaceObject.useSelect)(external_wp_preferences_namespaceObject.store);
(0,external_wp_element_namespaceObject.useEffect)(() => {
const activeGeneralSidebar = getActiveComplementaryArea('core');
const isEditorSidebarOpened = ['edit-post/document', 'edit-post/block'].includes(activeGeneralSidebar);
const isDistractionFree = getPreference('core', 'distractionFree');
if (!isEditorSidebarOpened || isDistractionFree) {
return;
}
if (hasBlockSelection) {
enableComplementaryArea('core', 'edit-post/block');
} else {
enableComplementaryArea('core', 'edit-post/document');
}
}, [hasBlockSelection, getActiveComplementaryArea, enableComplementaryArea, getPreference]);
}
/* harmony default export */ const use_auto_switch_editor_sidebars = (useAutoSwitchEditorSidebars);
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/components/sidebar/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const {
Tabs: sidebar_Tabs
} = unlock(external_wp_components_namespaceObject.privateApis);
const SIDEBAR_ACTIVE_BY_DEFAULT = external_wp_element_namespaceObject.Platform.select({
web: true,
native: false
});
const SidebarContent = ({
tabName,
keyboardShortcut,
onActionPerformed,
extraPanels
}) => {
const tabListRef = (0,external_wp_element_namespaceObject.useRef)(null);
// Because `PluginSidebar` renders a `ComplementaryArea`, we
// need to forward the `Tabs` context so it can be passed through the
// underlying slot/fill.
const tabsContextValue = (0,external_wp_element_namespaceObject.useContext)(sidebar_Tabs.Context);
// This effect addresses a race condition caused by tabbing from the last
// block in the editor into the settings sidebar. Without this effect, the
// selected tab and browser focus can become separated in an unexpected way
// (e.g the "block" tab is focused, but the "post" tab is selected).
(0,external_wp_element_namespaceObject.useEffect)(() => {
const tabsElements = Array.from(tabListRef.current?.querySelectorAll('[role="tab"]') || []);
const selectedTabElement = tabsElements.find(
// We are purposefully using a custom `data-tab-id` attribute here
// because we don't want rely on any assumptions about `Tabs`
// component internals.
element => element.getAttribute('data-tab-id') === tabName);
const activeElement = selectedTabElement?.ownerDocument.activeElement;
const tabsHasFocus = tabsElements.some(element => {
return activeElement && activeElement.id === element.id;
});
if (tabsHasFocus && selectedTabElement && selectedTabElement.id !== activeElement?.id) {
selectedTabElement?.focus();
}
}, [tabName]);
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PluginSidebar, {
identifier: tabName,
header: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(sidebar_Tabs.Context.Provider, {
value: tabsContextValue,
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(sidebar_header, {
ref: tabListRef
})
}),
closeLabel: (0,external_wp_i18n_namespaceObject.__)('Close Settings')
// This classname is added so we can apply a corrective negative
// margin to the panel.
// see https://github.com/WordPress/gutenberg/pull/55360#pullrequestreview-1737671049
,
className: "editor-sidebar__panel",
headerClassName: "editor-sidebar__panel-tabs",
title: /* translators: button label text should, if possible, be under 16 characters. */
(0,external_wp_i18n_namespaceObject._x)('Settings', 'sidebar button label'),
toggleShortcut: keyboardShortcut,
icon: (0,external_wp_i18n_namespaceObject.isRTL)() ? drawer_left : drawer_right,
isActiveByDefault: SIDEBAR_ACTIVE_BY_DEFAULT,
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(sidebar_Tabs.Context.Provider, {
value: tabsContextValue,
children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(sidebar_Tabs.TabPanel, {
tabId: sidebars.document,
focusable: false,
children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PostSummary, {
onActionPerformed: onActionPerformed
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(plugin_document_setting_panel.Slot, {}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(TemplateContentPanel, {}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(TemplatePartContentPanel, {}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PostTransformPanel, {}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(post_taxonomies_panel, {}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PatternOverridesPanel, {}), extraPanels]
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(sidebar_Tabs.TabPanel, {
tabId: sidebars.block,
focusable: false,
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_blockEditor_namespaceObject.BlockInspector, {})
})]
})
});
};
const Sidebar = ({
extraPanels,
onActionPerformed
}) => {
use_auto_switch_editor_sidebars();
const {
tabName,
keyboardShortcut,
showSummary
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const shortcut = select(external_wp_keyboardShortcuts_namespaceObject.store).getShortcutRepresentation('core/editor/toggle-sidebar');
const sidebar = select(store).getActiveComplementaryArea('core');
const _isEditorSidebarOpened = [sidebars.block, sidebars.document].includes(sidebar);
let _tabName = sidebar;
if (!_isEditorSidebarOpened) {
_tabName = !!select(external_wp_blockEditor_namespaceObject.store).getBlockSelectionStart() ? sidebars.block : sidebars.document;
}
return {
tabName: _tabName,
keyboardShortcut: shortcut,
showSummary: ![TEMPLATE_POST_TYPE, TEMPLATE_PART_POST_TYPE, NAVIGATION_POST_TYPE].includes(select(store_store).getCurrentPostType())
};
}, []);
const {
enableComplementaryArea
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
const onTabSelect = (0,external_wp_element_namespaceObject.useCallback)(newSelectedTabId => {
if (!!newSelectedTabId) {
enableComplementaryArea('core', newSelectedTabId);
}
}, [enableComplementaryArea]);
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(sidebar_Tabs, {
selectedTabId: tabName,
onSelect: onTabSelect,
selectOnMove: false,
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(SidebarContent, {
tabName: tabName,
keyboardShortcut: keyboardShortcut,
showSummary: showSummary,
onActionPerformed: onActionPerformed,
extraPanels: extraPanels
})
});
};
/* harmony default export */ const components_sidebar = (Sidebar);
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/components/editor/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function Editor({
postType,
postId,
templateId,
settings,
children,
initialEdits,
// This could be part of the settings.
onActionPerformed,
// The following abstractions are not ideal but necessary
// to account for site editor and post editor differences for now.
extraContent,
extraSidebarPanels,
...props
}) {
const {
post,
template,
hasLoadedPost
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getEntityRecord,
hasFinishedResolution
} = select(external_wp_coreData_namespaceObject.store);
return {
post: getEntityRecord('postType', postType, postId),
template: templateId ? getEntityRecord('postType', TEMPLATE_POST_TYPE, templateId) : undefined,
hasLoadedPost: hasFinishedResolution('getEntityRecord', ['postType', postType, postId])
};
}, [postType, postId, templateId]);
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, {
children: [hasLoadedPost && !post && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Notice, {
status: "warning",
isDismissible: false,
children: (0,external_wp_i18n_namespaceObject.__)("You attempted to edit an item that doesn't exist. Perhaps it was deleted?")
}), !!post && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(ExperimentalEditorProvider, {
post: post,
__unstableTemplate: template,
settings: settings,
initialEdits: initialEdits,
useSubRegistry: false,
children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(EditorInterface, {
...props,
children: extraContent
}), children, /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(components_sidebar, {
onActionPerformed: onActionPerformed,
extraPanels: extraSidebarPanels
})]
})]
});
}
/* harmony default export */ const editor = (Editor);
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/components/preferences-modal/enable-publish-sidebar.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const {
PreferenceBaseOption: enable_publish_sidebar_PreferenceBaseOption
} = unlock(external_wp_preferences_namespaceObject.privateApis);
/* harmony default export */ const enable_publish_sidebar = ((0,external_wp_compose_namespaceObject.compose)((0,external_wp_data_namespaceObject.withSelect)(select => ({
isChecked: select(store_store).isPublishSidebarEnabled()
})), (0,external_wp_data_namespaceObject.withDispatch)(dispatch => {
const {
enablePublishSidebar,
disablePublishSidebar
} = dispatch(store_store);
return {
onChange: isEnabled => isEnabled ? enablePublishSidebar() : disablePublishSidebar()
};
}))(enable_publish_sidebar_PreferenceBaseOption));
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/components/block-manager/checklist.js
/**
* WordPress dependencies
*/
function BlockTypesChecklist({
blockTypes,
value,
onItemChange
}) {
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("ul", {
className: "editor-block-manager__checklist",
children: blockTypes.map(blockType => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("li", {
className: "editor-block-manager__checklist-item",
children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.CheckboxControl, {
__nextHasNoMarginBottom: true,
label: blockType.title,
checked: value.includes(blockType.name),
onChange: (...args) => onItemChange(blockType.name, ...args)
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_blockEditor_namespaceObject.BlockIcon, {
icon: blockType.icon
})]
}, blockType.name))
});
}
/* harmony default export */ const checklist = (BlockTypesChecklist);
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/components/block-manager/category.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function BlockManagerCategory({
title,
blockTypes
}) {
const instanceId = (0,external_wp_compose_namespaceObject.useInstanceId)(BlockManagerCategory);
const {
allowedBlockTypes,
hiddenBlockTypes
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getEditorSettings
} = select(store_store);
const {
get
} = select(external_wp_preferences_namespaceObject.store);
return {
allowedBlockTypes: getEditorSettings().allowedBlockTypes,
hiddenBlockTypes: get('core', 'hiddenBlockTypes')
};
}, []);
const filteredBlockTypes = (0,external_wp_element_namespaceObject.useMemo)(() => {
if (allowedBlockTypes === true) {
return blockTypes;
}
return blockTypes.filter(({
name
}) => {
return allowedBlockTypes?.includes(name);
});
}, [allowedBlockTypes, blockTypes]);
const {
showBlockTypes,
hideBlockTypes
} = unlock((0,external_wp_data_namespaceObject.useDispatch)(store_store));
const toggleVisible = (0,external_wp_element_namespaceObject.useCallback)((blockName, nextIsChecked) => {
if (nextIsChecked) {
showBlockTypes(blockName);
} else {
hideBlockTypes(blockName);
}
}, [showBlockTypes, hideBlockTypes]);
const toggleAllVisible = (0,external_wp_element_namespaceObject.useCallback)(nextIsChecked => {
const blockNames = blockTypes.map(({
name
}) => name);
if (nextIsChecked) {
showBlockTypes(blockNames);
} else {
hideBlockTypes(blockNames);
}
}, [blockTypes, showBlockTypes, hideBlockTypes]);
if (!filteredBlockTypes.length) {
return null;
}
const checkedBlockNames = filteredBlockTypes.map(({
name
}) => name).filter(type => !(hiddenBlockTypes !== null && hiddenBlockTypes !== void 0 ? hiddenBlockTypes : []).includes(type));
const titleId = 'editor-block-manager__category-title-' + instanceId;
const isAllChecked = checkedBlockNames.length === filteredBlockTypes.length;
const isIndeterminate = !isAllChecked && checkedBlockNames.length > 0;
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", {
role: "group",
"aria-labelledby": titleId,
className: "editor-block-manager__category",
children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.CheckboxControl, {
__nextHasNoMarginBottom: true,
checked: isAllChecked,
onChange: toggleAllVisible,
className: "editor-block-manager__category-title",
indeterminate: isIndeterminate,
label: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", {
id: titleId,
children: title
})
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(checklist, {
blockTypes: filteredBlockTypes,
value: checkedBlockNames,
onItemChange: toggleVisible
})]
});
}
/* harmony default export */ const block_manager_category = (BlockManagerCategory);
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/components/block-manager/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function BlockManager() {
const debouncedSpeak = (0,external_wp_compose_namespaceObject.useDebounce)(external_wp_a11y_namespaceObject.speak, 500);
const [search, setSearch] = (0,external_wp_element_namespaceObject.useState)('');
const {
showBlockTypes
} = unlock((0,external_wp_data_namespaceObject.useDispatch)(store_store));
const {
blockTypes,
categories,
hasBlockSupport,
isMatchingSearchTerm,
numberOfHiddenBlocks
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
var _select$get;
// Some hidden blocks become unregistered
// by removing for instance the plugin that registered them, yet
// they're still remain as hidden by the user's action.
// We consider "hidden", blocks which were hidden and
// are still registered.
const _blockTypes = select(external_wp_blocks_namespaceObject.store).getBlockTypes();
const hiddenBlockTypes = ((_select$get = select(external_wp_preferences_namespaceObject.store).get('core', 'hiddenBlockTypes')) !== null && _select$get !== void 0 ? _select$get : []).filter(hiddenBlock => {
return _blockTypes.some(registeredBlock => registeredBlock.name === hiddenBlock);
});
return {
blockTypes: _blockTypes,
categories: select(external_wp_blocks_namespaceObject.store).getCategories(),
hasBlockSupport: select(external_wp_blocks_namespaceObject.store).hasBlockSupport,
isMatchingSearchTerm: select(external_wp_blocks_namespaceObject.store).isMatchingSearchTerm,
numberOfHiddenBlocks: Array.isArray(hiddenBlockTypes) && hiddenBlockTypes.length
};
}, []);
function enableAllBlockTypes(newBlockTypes) {
const blockNames = newBlockTypes.map(({
name
}) => name);
showBlockTypes(blockNames);
}
const filteredBlockTypes = blockTypes.filter(blockType => hasBlockSupport(blockType, 'inserter', true) && (!search || isMatchingSearchTerm(blockType, search)) && (!blockType.parent || blockType.parent.includes('core/post-content')));
// Announce search results on change
(0,external_wp_element_namespaceObject.useEffect)(() => {
if (!search) {
return;
}
const count = filteredBlockTypes.length;
const resultsFoundMessage = (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %d: number of results. */
(0,external_wp_i18n_namespaceObject._n)('%d result found.', '%d results found.', count), count);
debouncedSpeak(resultsFoundMessage);
}, [filteredBlockTypes?.length, search, debouncedSpeak]);
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", {
className: "editor-block-manager__content",
children: [!!numberOfHiddenBlocks && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", {
className: "editor-block-manager__disabled-blocks-count",
children: [(0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %d: number of blocks. */
(0,external_wp_i18n_namespaceObject._n)('%d block is hidden.', '%d blocks are hidden.', numberOfHiddenBlocks), numberOfHiddenBlocks), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, {
__next40pxDefaultSize: true,
variant: "link",
onClick: () => enableAllBlockTypes(filteredBlockTypes),
children: (0,external_wp_i18n_namespaceObject.__)('Reset')
})]
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.SearchControl, {
__nextHasNoMarginBottom: true,
label: (0,external_wp_i18n_namespaceObject.__)('Search for a block'),
placeholder: (0,external_wp_i18n_namespaceObject.__)('Search for a block'),
value: search,
onChange: nextSearch => setSearch(nextSearch),
className: "editor-block-manager__search"
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", {
tabIndex: "0",
role: "region",
"aria-label": (0,external_wp_i18n_namespaceObject.__)('Available block types'),
className: "editor-block-manager__results",
children: [filteredBlockTypes.length === 0 && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("p", {
className: "editor-block-manager__no-results",
children: (0,external_wp_i18n_namespaceObject.__)('No blocks found.')
}), categories.map(category => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_manager_category, {
title: category.title,
blockTypes: filteredBlockTypes.filter(blockType => blockType.category === category.slug)
}, category.slug)), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_manager_category, {
title: (0,external_wp_i18n_namespaceObject.__)('Uncategorized'),
blockTypes: filteredBlockTypes.filter(({
category
}) => !category)
})]
})]
});
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/components/preferences-modal/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const {
PreferencesModal,
PreferencesModalTabs,
PreferencesModalSection,
PreferenceToggleControl
} = unlock(external_wp_preferences_namespaceObject.privateApis);
function EditorPreferencesModal({
extraSections = {}
}) {
const isActive = (0,external_wp_data_namespaceObject.useSelect)(select => {
return select(store).isModalActive('editor/preferences');
}, []);
const {
closeModal
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
if (!isActive) {
return null;
}
// Please wrap all contents inside PreferencesModalContents to prevent all
// hooks from executing when the modal is not open.
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PreferencesModal, {
closeModal: closeModal,
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PreferencesModalContents, {
extraSections: extraSections
})
});
}
function PreferencesModalContents({
extraSections = {}
}) {
const isLargeViewport = (0,external_wp_compose_namespaceObject.useViewportMatch)('medium');
const showBlockBreadcrumbsOption = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getEditorSettings
} = select(store_store);
const {
get
} = select(external_wp_preferences_namespaceObject.store);
const isRichEditingEnabled = getEditorSettings().richEditingEnabled;
const isDistractionFreeEnabled = get('core', 'distractionFree');
return !isDistractionFreeEnabled && isLargeViewport && isRichEditingEnabled;
}, [isLargeViewport]);
const {
setIsListViewOpened,
setIsInserterOpened
} = (0,external_wp_data_namespaceObject.useDispatch)(store_store);
const {
set: setPreference
} = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_preferences_namespaceObject.store);
const hasStarterPatterns = !!useStartPatterns().length;
const sections = (0,external_wp_element_namespaceObject.useMemo)(() => [{
name: 'general',
tabLabel: (0,external_wp_i18n_namespaceObject.__)('General'),
content: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, {
children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(PreferencesModalSection, {
title: (0,external_wp_i18n_namespaceObject.__)('Interface'),
children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PreferenceToggleControl, {
scope: "core",
featureName: "showListViewByDefault",
help: (0,external_wp_i18n_namespaceObject.__)('Opens the List View sidebar by default.'),
label: (0,external_wp_i18n_namespaceObject.__)('Always open List View')
}), showBlockBreadcrumbsOption && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PreferenceToggleControl, {
scope: "core",
featureName: "showBlockBreadcrumbs",
help: (0,external_wp_i18n_namespaceObject.__)('Display the block hierarchy trail at the bottom of the editor.'),
label: (0,external_wp_i18n_namespaceObject.__)('Show block breadcrumbs')
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PreferenceToggleControl, {
scope: "core",
featureName: "allowRightClickOverrides",
help: (0,external_wp_i18n_namespaceObject.__)('Allows contextual List View menus via right-click, overriding browser defaults.'),
label: (0,external_wp_i18n_namespaceObject.__)('Allow right-click contextual menus')
}), hasStarterPatterns && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PreferenceToggleControl, {
scope: "core",
featureName: "enableChoosePatternModal",
help: (0,external_wp_i18n_namespaceObject.__)('Shows starter patterns when creating a new page.'),
label: (0,external_wp_i18n_namespaceObject.__)('Show starter patterns')
})]
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(PreferencesModalSection, {
title: (0,external_wp_i18n_namespaceObject.__)('Document settings'),
description: (0,external_wp_i18n_namespaceObject.__)('Select what settings are shown in the document panel.'),
children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(enable_plugin_document_setting_panel.Slot, {}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(post_taxonomies, {
taxonomyWrapper: (content, taxonomy) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(enable_panel, {
label: taxonomy.labels.menu_name,
panelName: `taxonomy-panel-${taxonomy.slug}`
})
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(post_featured_image_check, {
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(enable_panel, {
label: (0,external_wp_i18n_namespaceObject.__)('Featured image'),
panelName: "featured-image"
})
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(post_excerpt_check, {
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(enable_panel, {
label: (0,external_wp_i18n_namespaceObject.__)('Excerpt'),
panelName: "post-excerpt"
})
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(post_type_support_check, {
supportKeys: ['comments', 'trackbacks'],
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(enable_panel, {
label: (0,external_wp_i18n_namespaceObject.__)('Discussion'),
panelName: "discussion-panel"
})
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(page_attributes_check, {
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(enable_panel, {
label: (0,external_wp_i18n_namespaceObject.__)('Page attributes'),
panelName: "page-attributes"
})
})]
}), isLargeViewport && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PreferencesModalSection, {
title: (0,external_wp_i18n_namespaceObject.__)('Publishing'),
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(enable_publish_sidebar, {
help: (0,external_wp_i18n_namespaceObject.__)('Review settings, such as visibility and tags.'),
label: (0,external_wp_i18n_namespaceObject.__)('Enable pre-publish checks')
})
}), extraSections?.general]
})
}, {
name: 'appearance',
tabLabel: (0,external_wp_i18n_namespaceObject.__)('Appearance'),
content: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(PreferencesModalSection, {
title: (0,external_wp_i18n_namespaceObject.__)('Appearance'),
description: (0,external_wp_i18n_namespaceObject.__)('Customize the editor interface to suit your needs.'),
children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PreferenceToggleControl, {
scope: "core",
featureName: "fixedToolbar",
onToggle: () => setPreference('core', 'distractionFree', false),
help: (0,external_wp_i18n_namespaceObject.__)('Access all block and document tools in a single place.'),
label: (0,external_wp_i18n_namespaceObject.__)('Top toolbar')
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PreferenceToggleControl, {
scope: "core",
featureName: "distractionFree",
onToggle: () => {
setPreference('core', 'fixedToolbar', true);
setIsInserterOpened(false);
setIsListViewOpened(false);
},
help: (0,external_wp_i18n_namespaceObject.__)('Reduce visual distractions by hiding the toolbar and other elements to focus on writing.'),
label: (0,external_wp_i18n_namespaceObject.__)('Distraction free')
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PreferenceToggleControl, {
scope: "core",
featureName: "focusMode",
help: (0,external_wp_i18n_namespaceObject.__)('Highlights the current block and fades other content.'),
label: (0,external_wp_i18n_namespaceObject.__)('Spotlight mode')
}), extraSections?.appearance]
})
}, {
name: 'accessibility',
tabLabel: (0,external_wp_i18n_namespaceObject.__)('Accessibility'),
content: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, {
children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PreferencesModalSection, {
title: (0,external_wp_i18n_namespaceObject.__)('Navigation'),
description: (0,external_wp_i18n_namespaceObject.__)('Optimize the editing experience for enhanced control.'),
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PreferenceToggleControl, {
scope: "core",
featureName: "keepCaretInsideBlock",
help: (0,external_wp_i18n_namespaceObject.__)('Keeps the text cursor within the block boundaries, aiding users with screen readers by preventing unintentional cursor movement outside the block.'),
label: (0,external_wp_i18n_namespaceObject.__)('Contain text cursor inside block')
})
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PreferencesModalSection, {
title: (0,external_wp_i18n_namespaceObject.__)('Interface'),
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PreferenceToggleControl, {
scope: "core",
featureName: "showIconLabels",
label: (0,external_wp_i18n_namespaceObject.__)('Show button text labels'),
help: (0,external_wp_i18n_namespaceObject.__)('Show text instead of icons on buttons across the interface.')
})
})]
})
}, {
name: 'blocks',
tabLabel: (0,external_wp_i18n_namespaceObject.__)('Blocks'),
content: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, {
children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PreferencesModalSection, {
title: (0,external_wp_i18n_namespaceObject.__)('Inserter'),
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PreferenceToggleControl, {
scope: "core",
featureName: "mostUsedBlocks",
help: (0,external_wp_i18n_namespaceObject.__)('Adds a category with the most frequently used blocks in the inserter.'),
label: (0,external_wp_i18n_namespaceObject.__)('Show most used blocks')
})
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PreferencesModalSection, {
title: (0,external_wp_i18n_namespaceObject.__)('Manage block visibility'),
description: (0,external_wp_i18n_namespaceObject.__)("Disable blocks that you don't want to appear in the inserter. They can always be toggled back on later."),
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockManager, {})
})]
})
}, window.__experimentalMediaProcessing && {
name: 'media',
tabLabel: (0,external_wp_i18n_namespaceObject.__)('Media'),
content: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_ReactJSXRuntime_namespaceObject.Fragment, {
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(PreferencesModalSection, {
title: (0,external_wp_i18n_namespaceObject.__)('General'),
description: (0,external_wp_i18n_namespaceObject.__)('Customize options related to the media upload flow.'),
children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PreferenceToggleControl, {
scope: "core/media",
featureName: "optimizeOnUpload",
help: (0,external_wp_i18n_namespaceObject.__)('Compress media items before uploading to the server.'),
label: (0,external_wp_i18n_namespaceObject.__)('Pre-upload compression')
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PreferenceToggleControl, {
scope: "core/media",
featureName: "requireApproval",
help: (0,external_wp_i18n_namespaceObject.__)('Require approval step when optimizing existing media.'),
label: (0,external_wp_i18n_namespaceObject.__)('Approval step')
})]
})
})
}].filter(Boolean), [showBlockBreadcrumbsOption, extraSections, setIsInserterOpened, setIsListViewOpened, setPreference, isLargeViewport, hasStarterPatterns]);
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PreferencesModalTabs, {
sections: sections
});
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/bindings/pattern-overrides.js
/**
* WordPress dependencies
*/
const CONTENT = 'content';
/* harmony default export */ const pattern_overrides = ({
name: 'core/pattern-overrides',
getValues({
select,
clientId,
context,
bindings
}) {
const patternOverridesContent = context['pattern/overrides'];
const {
getBlockAttributes
} = select(external_wp_blockEditor_namespaceObject.store);
const currentBlockAttributes = getBlockAttributes(clientId);
const overridesValues = {};
for (const attributeName of Object.keys(bindings)) {
const overridableValue = patternOverridesContent?.[currentBlockAttributes?.metadata?.name]?.[attributeName];
// If it has not been overriden, return the original value.
// Check undefined because empty string is a valid value.
if (overridableValue === undefined) {
overridesValues[attributeName] = currentBlockAttributes[attributeName];
continue;
} else {
overridesValues[attributeName] = overridableValue === '' ? undefined : overridableValue;
}
}
return overridesValues;
},
setValues({
select,
dispatch,
clientId,
bindings
}) {
const {
getBlockAttributes,
getBlockParentsByBlockName,
getBlocks
} = select(external_wp_blockEditor_namespaceObject.store);
const currentBlockAttributes = getBlockAttributes(clientId);
const blockName = currentBlockAttributes?.metadata?.name;
if (!blockName) {
return;
}
const [patternClientId] = getBlockParentsByBlockName(clientId, 'core/block', true);
// Extract the updated attributes from the source bindings.
const attributes = Object.entries(bindings).reduce((attrs, [key, {
newValue
}]) => {
attrs[key] = newValue;
return attrs;
}, {});
// If there is no pattern client ID, sync blocks with the same name and same attributes.
if (!patternClientId) {
const syncBlocksWithSameName = blocks => {
for (const block of blocks) {
if (block.attributes?.metadata?.name === blockName) {
dispatch(external_wp_blockEditor_namespaceObject.store).updateBlockAttributes(block.clientId, attributes);
}
syncBlocksWithSameName(block.innerBlocks);
}
};
syncBlocksWithSameName(getBlocks());
return;
}
const currentBindingValue = getBlockAttributes(patternClientId)?.[CONTENT];
dispatch(external_wp_blockEditor_namespaceObject.store).updateBlockAttributes(patternClientId, {
[CONTENT]: {
...currentBindingValue,
[blockName]: {
...currentBindingValue?.[blockName],
...Object.entries(attributes).reduce((acc, [key, value]) => {
// TODO: We need a way to represent `undefined` in the serialized overrides.
// Also see: https://github.com/WordPress/gutenberg/pull/57249#discussion_r1452987871
// We use an empty string to represent undefined for now until
// we support a richer format for overrides and the block bindings API.
acc[key] = value === undefined ? '' : value;
return acc;
}, {})
}
}
});
},
canUserEditValue: () => true
});
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/bindings/post-meta.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Gets a list of post meta fields with their values and labels
* to be consumed in the needed callbacks.
* If the value is not available based on context, like in templates,
* it falls back to the default value, label, or key.
*
* @param {Object} select The select function from the data store.
* @param {Object} context The context provided.
* @return {Object} List of post meta fields with their value and label.
*
* @example
* ```js
* {
* field_1_key: {
* label: 'Field 1 Label',
* value: 'Field 1 Value',
* },
* field_2_key: {
* label: 'Field 2 Label',
* value: 'Field 2 Value',
* },
* ...
* }
* ```
*/
function getPostMetaFields(select, context) {
const {
getEditedEntityRecord
} = select(external_wp_coreData_namespaceObject.store);
const {
getRegisteredPostMeta
} = unlock(select(external_wp_coreData_namespaceObject.store));
let entityMetaValues;
// Try to get the current entity meta values.
if (context?.postType && context?.postId) {
entityMetaValues = getEditedEntityRecord('postType', context?.postType, context?.postId).meta;
}
const registeredFields = getRegisteredPostMeta(context?.postType);
const metaFields = {};
Object.entries(registeredFields || {}).forEach(([key, props]) => {
// Don't include footnotes or private fields.
if (key !== 'footnotes' && key.charAt(0) !== '_') {
var _entityMetaValues$key;
metaFields[key] = {
label: props.title || key,
value: // When using the entity value, an empty string IS a valid value.
(_entityMetaValues$key = entityMetaValues?.[key]) !== null && _entityMetaValues$key !== void 0 ? _entityMetaValues$key :
// When using the default, an empty string IS NOT a valid value.
props.default || undefined,
type: props.type
};
}
});
if (!Object.keys(metaFields || {}).length) {
return null;
}
return metaFields;
}
/* harmony default export */ const post_meta = ({
name: 'core/post-meta',
getValues({
select,
context,
bindings
}) {
const metaFields = getPostMetaFields(select, context);
const newValues = {};
for (const [attributeName, source] of Object.entries(bindings)) {
var _ref;
// Use the value, the field label, or the field key.
const fieldKey = source.args.key;
const {
value: fieldValue,
label: fieldLabel
} = metaFields?.[fieldKey] || {};
newValues[attributeName] = (_ref = fieldValue !== null && fieldValue !== void 0 ? fieldValue : fieldLabel) !== null && _ref !== void 0 ? _ref : fieldKey;
}
return newValues;
},
setValues({
dispatch,
context,
bindings
}) {
const newMeta = {};
Object.values(bindings).forEach(({
args,
newValue
}) => {
newMeta[args.key] = newValue;
});
dispatch(external_wp_coreData_namespaceObject.store).editEntityRecord('postType', context?.postType, context?.postId, {
meta: newMeta
});
},
canUserEditValue({
select,
context,
args
}) {
// Lock editing in query loop.
if (context?.query || context?.queryId) {
return false;
}
const postType = context?.postType || select(store_store).getCurrentPostType();
// Check that editing is happening in the post editor and not a template.
if (postType === 'wp_template') {
return false;
}
const fieldValue = getPostMetaFields(select, context)?.[args.key]?.value;
// Empty string or `false` could be a valid value, so we need to check if the field value is undefined.
if (fieldValue === undefined) {
return false;
}
// Check that custom fields metabox is not enabled.
const areCustomFieldsEnabled = select(store_store).getEditorSettings().enableCustomFields;
if (areCustomFieldsEnabled) {
return false;
}
// Check that the user has the capability to edit post meta.
const canUserEdit = select(external_wp_coreData_namespaceObject.store).canUser('update', {
kind: 'postType',
name: context?.postType,
id: context?.postId
});
if (!canUserEdit) {
return false;
}
return true;
},
getFieldsList({
select,
context
}) {
return getPostMetaFields(select, context);
}
});
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/bindings/api.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Function to register core block bindings sources provided by the editor.
*
* @example
* ```js
* import { registerCoreBlockBindingsSources } from '@wordpress/editor';
*
* registerCoreBlockBindingsSources();
* ```
*/
function registerCoreBlockBindingsSources() {
(0,external_wp_blocks_namespaceObject.registerBlockBindingsSource)(pattern_overrides);
(0,external_wp_blocks_namespaceObject.registerBlockBindingsSource)(post_meta);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/private-apis.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const {
store: interfaceStore,
...remainingInterfaceApis
} = build_module_namespaceObject;
const privateApis = {};
lock(privateApis, {
CreateTemplatePartModal: CreateTemplatePartModal,
BackButton: back_button,
EntitiesSavedStatesExtensible: EntitiesSavedStatesExtensible,
Editor: editor,
EditorContentSlotFill: content_slot_fill,
GlobalStylesProvider: GlobalStylesProvider,
mergeBaseAndUserConfigs: mergeBaseAndUserConfigs,
PluginPostExcerpt: post_excerpt_plugin,
PostCardPanel: PostCardPanel,
PreferencesModal: EditorPreferencesModal,
usePostActions: usePostActions,
ToolsMoreMenuGroup: tools_more_menu_group,
ViewMoreMenuGroup: view_more_menu_group,
ResizableEditor: resizable_editor,
registerCoreBlockBindingsSources: registerCoreBlockBindingsSources,
// This is a temporary private API while we're updating the site editor to use EditorProvider.
interfaceStore,
...remainingInterfaceApis
});
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/dataviews/api.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* @typedef {import('@wordpress/dataviews').Action} Action
*/
/**
* Registers a new DataViews action.
*
* This is an experimental API and is subject to change.
* it's only available in the Gutenberg plugin for now.
*
* @param {string} kind Entity kind.
* @param {string} name Entity name.
* @param {Action} config Action configuration.
*/
function api_registerEntityAction(kind, name, config) {
const {
registerEntityAction: _registerEntityAction
} = unlock((0,external_wp_data_namespaceObject.dispatch)(store_store));
if (false) {}
}
/**
* Unregisters a DataViews action.
*
* This is an experimental API and is subject to change.
* it's only available in the Gutenberg plugin for now.
*
* @param {string} kind Entity kind.
* @param {string} name Entity name.
* @param {string} actionId Action ID.
*/
function api_unregisterEntityAction(kind, name, actionId) {
const {
unregisterEntityAction: _unregisterEntityAction
} = unlock((0,external_wp_data_namespaceObject.dispatch)(store_store));
if (false) {}
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/editor/build-module/index.js
/**
* Internal dependencies
*/
/*
* Backward compatibility
*/
})();
(window.wp = window.wp || {}).editor = __webpack_exports__;
/******/ })()
; www/wwwroot/fashionmodelquicktrack.com/wp-admin/js/editor.js 0000755 00000127750 14744621727 0020440 0 ustar 00 /**
* @output wp-admin/js/editor.js
*/
window.wp = window.wp || {};
( function( $, wp ) {
wp.editor = wp.editor || {};
/**
* Utility functions for the editor.
*
* @since 2.5.0
*/
function SwitchEditors() {
var tinymce, $$,
exports = {};
function init() {
if ( ! tinymce && window.tinymce ) {
tinymce = window.tinymce;
$$ = tinymce.$;
/**
* Handles onclick events for the Visual/Text tabs.
*
* @since 4.3.0
*
* @return {void}
*/
$$( document ).on( 'click', function( event ) {
var id, mode,
target = $$( event.target );
if ( target.hasClass( 'wp-switch-editor' ) ) {
id = target.attr( 'data-wp-editor-id' );
mode = target.hasClass( 'switch-tmce' ) ? 'tmce' : 'html';
switchEditor( id, mode );
}
});
}
}
/**
* Returns the height of the editor toolbar(s) in px.
*
* @since 3.9.0
*
* @param {Object} editor The TinyMCE editor.
* @return {number} If the height is between 10 and 200 return the height,
* else return 30.
*/
function getToolbarHeight( editor ) {
var node = $$( '.mce-toolbar-grp', editor.getContainer() )[0],
height = node && node.clientHeight;
if ( height && height > 10 && height < 200 ) {
return parseInt( height, 10 );
}
return 30;
}
/**
* Switches the editor between Visual and Text mode.
*
* @since 2.5.0
*
* @memberof switchEditors
*
* @param {string} id The id of the editor you want to change the editor mode for. Default: `content`.
* @param {string} mode The mode you want to switch to. Default: `toggle`.
* @return {void}
*/
function switchEditor( id, mode ) {
id = id || 'content';
mode = mode || 'toggle';
var editorHeight, toolbarHeight, iframe,
editor = tinymce.get( id ),
wrap = $$( '#wp-' + id + '-wrap' ),
htmlSwitch = wrap.find( '.switch-tmce' ),
tmceSwitch = wrap.find( '.switch-html' ),
$textarea = $$( '#' + id ),
textarea = $textarea[0];
if ( 'toggle' === mode ) {
if ( editor && ! editor.isHidden() ) {
mode = 'html';
} else {
mode = 'tmce';
}
}
if ( 'tmce' === mode || 'tinymce' === mode ) {
// If the editor is visible we are already in `tinymce` mode.
if ( editor && ! editor.isHidden() ) {
return false;
}
// Insert closing tags for any open tags in QuickTags.
if ( typeof( window.QTags ) !== 'undefined' ) {
window.QTags.closeAllTags( id );
}
editorHeight = parseInt( textarea.style.height, 10 ) || 0;
addHTMLBookmarkInTextAreaContent( $textarea );
if ( editor ) {
editor.show();
// No point to resize the iframe in iOS.
if ( ! tinymce.Env.iOS && editorHeight ) {
toolbarHeight = getToolbarHeight( editor );
editorHeight = editorHeight - toolbarHeight + 14;
// Sane limit for the editor height.
if ( editorHeight > 50 && editorHeight < 5000 ) {
editor.theme.resizeTo( null, editorHeight );
}
}
focusHTMLBookmarkInVisualEditor( editor );
} else {
tinymce.init( window.tinyMCEPreInit.mceInit[ id ] );
}
wrap.removeClass( 'html-active' ).addClass( 'tmce-active' );
tmceSwitch.attr( 'aria-pressed', false );
htmlSwitch.attr( 'aria-pressed', true );
$textarea.attr( 'aria-hidden', true );
window.setUserSetting( 'editor', 'tinymce' );
} else if ( 'html' === mode ) {
// If the editor is hidden (Quicktags is shown) we don't need to switch.
if ( editor && editor.isHidden() ) {
return false;
}
if ( editor ) {
// Don't resize the textarea in iOS.
// The iframe is forced to 100% height there, we shouldn't match it.
if ( ! tinymce.Env.iOS ) {
iframe = editor.iframeElement;
editorHeight = iframe ? parseInt( iframe.style.height, 10 ) : 0;
if ( editorHeight ) {
toolbarHeight = getToolbarHeight( editor );
editorHeight = editorHeight + toolbarHeight - 14;
// Sane limit for the textarea height.
if ( editorHeight > 50 && editorHeight < 5000 ) {
textarea.style.height = editorHeight + 'px';
}
}
}
var selectionRange = null;
selectionRange = findBookmarkedPosition( editor );
editor.hide();
if ( selectionRange ) {
selectTextInTextArea( editor, selectionRange );
}
} else {
// There is probably a JS error on the page.
// The TinyMCE editor instance doesn't exist. Show the textarea.
$textarea.css({ 'display': '', 'visibility': '' });
}
wrap.removeClass( 'tmce-active' ).addClass( 'html-active' );
tmceSwitch.attr( 'aria-pressed', true );
htmlSwitch.attr( 'aria-pressed', false );
$textarea.attr( 'aria-hidden', false );
window.setUserSetting( 'editor', 'html' );
}
}
/**
* Checks if a cursor is inside an HTML tag or comment.
*
* In order to prevent breaking HTML tags when selecting text, the cursor
* must be moved to either the start or end of the tag.
*
* This will prevent the selection marker to be inserted in the middle of an HTML tag.
*
* This function gives information whether the cursor is inside a tag or not, as well as
* the tag type, if it is a closing tag and check if the HTML tag is inside a shortcode tag,
* e.g. `[caption]..`.
*
* @param {string} content The test content where the cursor is.
* @param {number} cursorPosition The cursor position inside the content.
*
* @return {(null|Object)} Null if cursor is not in a tag, Object if the cursor is inside a tag.
*/
function getContainingTagInfo( content, cursorPosition ) {
var lastLtPos = content.lastIndexOf( '<', cursorPosition - 1 ),
lastGtPos = content.lastIndexOf( '>', cursorPosition );
if ( lastLtPos > lastGtPos || content.substr( cursorPosition, 1 ) === '>' ) {
// Find what the tag is.
var tagContent = content.substr( lastLtPos ),
tagMatch = tagContent.match( /<\s*(\/)?(\w+|\!-{2}.*-{2})/ );
if ( ! tagMatch ) {
return null;
}
var tagType = tagMatch[2],
closingGt = tagContent.indexOf( '>' );
return {
ltPos: lastLtPos,
gtPos: lastLtPos + closingGt + 1, // Offset by one to get the position _after_ the character.
tagType: tagType,
isClosingTag: !! tagMatch[1]
};
}
return null;
}
/**
* Checks if the cursor is inside a shortcode
*
* If the cursor is inside a shortcode wrapping tag, e.g. `[caption]` it's better to
* move the selection marker to before or after the shortcode.
*
* For example `[caption]` rewrites/removes anything that's between the `[caption]` tag and the
* `` tag inside.
*
* `[caption]ThisIsGone[caption]`
*
* Moving the selection to before or after the short code is better, since it allows to select
* something, instead of just losing focus and going to the start of the content.
*
* @param {string} content The text content to check against.
* @param {number} cursorPosition The cursor position to check.
*
* @return {(undefined|Object)} Undefined if the cursor is not wrapped in a shortcode tag.
* Information about the wrapping shortcode tag if it's wrapped in one.
*/
function getShortcodeWrapperInfo( content, cursorPosition ) {
var contentShortcodes = getShortCodePositionsInText( content );
for ( var i = 0; i < contentShortcodes.length; i++ ) {
var element = contentShortcodes[ i ];
if ( cursorPosition >= element.startIndex && cursorPosition <= element.endIndex ) {
return element;
}
}
}
/**
* Gets a list of unique shortcodes or shortcode-lookalikes in the content.
*
* @param {string} content The content we want to scan for shortcodes.
*/
function getShortcodesInText( content ) {
var shortcodes = content.match( /\[+([\w_-])+/g ),
result = [];
if ( shortcodes ) {
for ( var i = 0; i < shortcodes.length; i++ ) {
var shortcode = shortcodes[ i ].replace( /^\[+/g, '' );
if ( result.indexOf( shortcode ) === -1 ) {
result.push( shortcode );
}
}
}
return result;
}
/**
* Gets all shortcodes and their positions in the content
*
* This function returns all the shortcodes that could be found in the textarea content
* along with their character positions and boundaries.
*
* This is used to check if the selection cursor is inside the boundaries of a shortcode
* and move it accordingly, to avoid breakage.
*
* @link adjustTextAreaSelectionCursors
*
* The information can also be used in other cases when we need to lookup shortcode data,
* as it's already structured!
*
* @param {string} content The content we want to scan for shortcodes
*/
function getShortCodePositionsInText( content ) {
var allShortcodes = getShortcodesInText( content ), shortcodeInfo;
if ( allShortcodes.length === 0 ) {
return [];
}
var shortcodeDetailsRegexp = wp.shortcode.regexp( allShortcodes.join( '|' ) ),
shortcodeMatch, // Define local scope for the variable to be used in the loop below.
shortcodesDetails = [];
while ( shortcodeMatch = shortcodeDetailsRegexp.exec( content ) ) {
/**
* Check if the shortcode should be shown as plain text.
*
* This corresponds to the [[shortcode]] syntax, which doesn't parse the shortcode
* and just shows it as text.
*/
var showAsPlainText = shortcodeMatch[1] === '[';
shortcodeInfo = {
shortcodeName: shortcodeMatch[2],
showAsPlainText: showAsPlainText,
startIndex: shortcodeMatch.index,
endIndex: shortcodeMatch.index + shortcodeMatch[0].length,
length: shortcodeMatch[0].length
};
shortcodesDetails.push( shortcodeInfo );
}
/**
* Get all URL matches, and treat them as embeds.
*
* Since there isn't a good way to detect if a URL by itself on a line is a previewable
* object, it's best to treat all of them as such.
*
* This means that the selection will capture the whole URL, in a similar way shrotcodes
* are treated.
*/
var urlRegexp = new RegExp(
'(^|[\\n\\r][\\n\\r]|)(https?:\\/\\/[^\s"]+?)(<\\/p>\s*|[\\n\\r][\\n\\r]|$)', 'gi'
);
while ( shortcodeMatch = urlRegexp.exec( content ) ) {
shortcodeInfo = {
shortcodeName: 'url',
showAsPlainText: false,
startIndex: shortcodeMatch.index,
endIndex: shortcodeMatch.index + shortcodeMatch[ 0 ].length,
length: shortcodeMatch[ 0 ].length,
urlAtStartOfContent: shortcodeMatch[ 1 ] === '',
urlAtEndOfContent: shortcodeMatch[ 3 ] === ''
};
shortcodesDetails.push( shortcodeInfo );
}
return shortcodesDetails;
}
/**
* Generate a cursor marker element to be inserted in the content.
*
* `span` seems to be the least destructive element that can be used.
*
* Using DomQuery syntax to create it, since it's used as both text and as a DOM element.
*
* @param {Object} domLib DOM library instance.
* @param {string} content The content to insert into the cursor marker element.
*/
function getCursorMarkerSpan( domLib, content ) {
return domLib( '' ).css( {
display: 'inline-block',
width: 0,
overflow: 'hidden',
'line-height': 0
} )
.html( content ? content : '' );
}
/**
* Gets adjusted selection cursor positions according to HTML tags, comments, and shortcodes.
*
* Shortcodes and HTML codes are a bit of a special case when selecting, since they may render
* content in Visual mode. If we insert selection markers somewhere inside them, it's really possible
* to break the syntax and render the HTML tag or shortcode broken.
*
* @link getShortcodeWrapperInfo
*
* @param {string} content Textarea content that the cursors are in
* @param {{cursorStart: number, cursorEnd: number}} cursorPositions Cursor start and end positions
*
* @return {{cursorStart: number, cursorEnd: number}}
*/
function adjustTextAreaSelectionCursors( content, cursorPositions ) {
var voidElements = [
'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',
'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr'
];
var cursorStart = cursorPositions.cursorStart,
cursorEnd = cursorPositions.cursorEnd,
// Check if the cursor is in a tag and if so, adjust it.
isCursorStartInTag = getContainingTagInfo( content, cursorStart );
if ( isCursorStartInTag ) {
/**
* Only move to the start of the HTML tag (to select the whole element) if the tag
* is part of the voidElements list above.
*
* This list includes tags that are self-contained and don't need a closing tag, according to the
* HTML5 specification.
*
* This is done in order to make selection of text a bit more consistent when selecting text in
* `` tags or such.
*
* In cases where the tag is not a void element, the cursor is put to the end of the tag,
* so it's either between the opening and closing tag elements or after the closing tag.
*/
if ( voidElements.indexOf( isCursorStartInTag.tagType ) !== -1 ) {
cursorStart = isCursorStartInTag.ltPos;
} else {
cursorStart = isCursorStartInTag.gtPos;
}
}
var isCursorEndInTag = getContainingTagInfo( content, cursorEnd );
if ( isCursorEndInTag ) {
cursorEnd = isCursorEndInTag.gtPos;
}
var isCursorStartInShortcode = getShortcodeWrapperInfo( content, cursorStart );
if ( isCursorStartInShortcode && ! isCursorStartInShortcode.showAsPlainText ) {
/**
* If a URL is at the start or the end of the content,
* the selection doesn't work, because it inserts a marker in the text,
* which breaks the embedURL detection.
*
* The best way to avoid that and not modify the user content is to
* adjust the cursor to either after or before URL.
*/
if ( isCursorStartInShortcode.urlAtStartOfContent ) {
cursorStart = isCursorStartInShortcode.endIndex;
} else {
cursorStart = isCursorStartInShortcode.startIndex;
}
}
var isCursorEndInShortcode = getShortcodeWrapperInfo( content, cursorEnd );
if ( isCursorEndInShortcode && ! isCursorEndInShortcode.showAsPlainText ) {
if ( isCursorEndInShortcode.urlAtEndOfContent ) {
cursorEnd = isCursorEndInShortcode.startIndex;
} else {
cursorEnd = isCursorEndInShortcode.endIndex;
}
}
return {
cursorStart: cursorStart,
cursorEnd: cursorEnd
};
}
/**
* Adds text selection markers in the editor textarea.
*
* Adds selection markers in the content of the editor `textarea`.
* The method directly manipulates the `textarea` content, to allow TinyMCE plugins
* to run after the markers are added.
*
* @param {Object} $textarea TinyMCE's textarea wrapped as a DomQuery object
*/
function addHTMLBookmarkInTextAreaContent( $textarea ) {
if ( ! $textarea || ! $textarea.length ) {
// If no valid $textarea object is provided, there's nothing we can do.
return;
}
var textArea = $textarea[0],
textAreaContent = textArea.value,
adjustedCursorPositions = adjustTextAreaSelectionCursors( textAreaContent, {
cursorStart: textArea.selectionStart,
cursorEnd: textArea.selectionEnd
} ),
htmlModeCursorStartPosition = adjustedCursorPositions.cursorStart,
htmlModeCursorEndPosition = adjustedCursorPositions.cursorEnd,
mode = htmlModeCursorStartPosition !== htmlModeCursorEndPosition ? 'range' : 'single',
selectedText = null,
cursorMarkerSkeleton = getCursorMarkerSpan( $$, '' ).attr( 'data-mce-type','bookmark' );
if ( mode === 'range' ) {
var markedText = textArea.value.slice( htmlModeCursorStartPosition, htmlModeCursorEndPosition ),
bookMarkEnd = cursorMarkerSkeleton.clone().addClass( 'mce_SELRES_end' );
selectedText = [
markedText,
bookMarkEnd[0].outerHTML
].join( '' );
}
textArea.value = [
textArea.value.slice( 0, htmlModeCursorStartPosition ), // Text until the cursor/selection position.
cursorMarkerSkeleton.clone() // Cursor/selection start marker.
.addClass( 'mce_SELRES_start' )[0].outerHTML,
selectedText, // Selected text with end cursor/position marker.
textArea.value.slice( htmlModeCursorEndPosition ) // Text from last cursor/selection position to end.
].join( '' );
}
/**
* Focuses the selection markers in Visual mode.
*
* The method checks for existing selection markers inside the editor DOM (Visual mode)
* and create a selection between the two nodes using the DOM `createRange` selection API.
*
* If there is only a single node, select only the single node through TinyMCE's selection API
*
* @param {Object} editor TinyMCE editor instance.
*/
function focusHTMLBookmarkInVisualEditor( editor ) {
var startNode = editor.$( '.mce_SELRES_start' ).attr( 'data-mce-bogus', 1 ),
endNode = editor.$( '.mce_SELRES_end' ).attr( 'data-mce-bogus', 1 );
if ( startNode.length ) {
editor.focus();
if ( ! endNode.length ) {
editor.selection.select( startNode[0] );
} else {
var selection = editor.getDoc().createRange();
selection.setStartAfter( startNode[0] );
selection.setEndBefore( endNode[0] );
editor.selection.setRng( selection );
}
}
scrollVisualModeToStartElement( editor, startNode );
removeSelectionMarker( startNode );
removeSelectionMarker( endNode );
editor.save();
}
/**
* Removes selection marker and the parent node if it is an empty paragraph.
*
* By default TinyMCE wraps loose inline tags in a `
`.
* When removing selection markers an empty `
` may be left behind, remove it.
*
* @param {Object} $marker The marker to be removed from the editor DOM, wrapped in an instance of `editor.$`
*/
function removeSelectionMarker( $marker ) {
var $markerParent = $marker.parent();
$marker.remove();
//Remove empty paragraph left over after removing the marker.
if ( $markerParent.is( 'p' ) && ! $markerParent.children().length && ! $markerParent.text() ) {
$markerParent.remove();
}
}
/**
* Scrolls the content to place the selected element in the center of the screen.
*
* Takes an element, that is usually the selection start element, selected in
* `focusHTMLBookmarkInVisualEditor()` and scrolls the screen so the element appears roughly
* in the middle of the screen.
*
* I order to achieve the proper positioning, the editor media bar and toolbar are subtracted
* from the window height, to get the proper viewport window, that the user sees.
*
* @param {Object} editor TinyMCE editor instance.
* @param {Object} element HTMLElement that should be scrolled into view.
*/
function scrollVisualModeToStartElement( editor, element ) {
var elementTop = editor.$( element ).offset().top,
TinyMCEContentAreaTop = editor.$( editor.getContentAreaContainer() ).offset().top,
toolbarHeight = getToolbarHeight( editor ),
edTools = $( '#wp-content-editor-tools' ),
edToolsHeight = 0,
edToolsOffsetTop = 0,
$scrollArea;
if ( edTools.length ) {
edToolsHeight = edTools.height();
edToolsOffsetTop = edTools.offset().top;
}
var windowHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight,
selectionPosition = TinyMCEContentAreaTop + elementTop,
visibleAreaHeight = windowHeight - ( edToolsHeight + toolbarHeight );
// There's no need to scroll if the selection is inside the visible area.
if ( selectionPosition < visibleAreaHeight ) {
return;
}
/**
* The minimum scroll height should be to the top of the editor, to offer a consistent
* experience.
*
* In order to find the top of the editor, we calculate the offset of `#wp-content-editor-tools` and
* subtracting the height. This gives the scroll position where the top of the editor tools aligns with
* the top of the viewport (under the Master Bar)
*/
var adjustedScroll;
if ( editor.settings.wp_autoresize_on ) {
$scrollArea = $( 'html,body' );
adjustedScroll = Math.max( selectionPosition - visibleAreaHeight / 2, edToolsOffsetTop - edToolsHeight );
} else {
$scrollArea = $( editor.contentDocument ).find( 'html,body' );
adjustedScroll = elementTop;
}
$scrollArea.animate( {
scrollTop: parseInt( adjustedScroll, 10 )
}, 100 );
}
/**
* This method was extracted from the `SaveContent` hook in
* `wp-includes/js/tinymce/plugins/wordpress/plugin.js`.
*
* It's needed here, since the method changes the content a bit, which confuses the cursor position.
*
* @param {Object} event TinyMCE event object.
*/
function fixTextAreaContent( event ) {
// Keep empty paragraphs :(
event.content = event.content.replace( /
(?:
|\u00a0|\uFEFF| )*<\/p>/g, '
' );
}
/**
* Finds the current selection position in the Visual editor.
*
* Find the current selection in the Visual editor by inserting marker elements at the start
* and end of the selection.
*
* Uses the standard DOM selection API to achieve that goal.
*
* Check the notes in the comments in the code below for more information on some gotchas
* and why this solution was chosen.
*
* @param {Object} editor The editor where we must find the selection.
* @return {(null|Object)} The selection range position in the editor.
*/
function findBookmarkedPosition( editor ) {
// Get the TinyMCE `window` reference, since we need to access the raw selection.
var TinyMCEWindow = editor.getWin(),
selection = TinyMCEWindow.getSelection();
if ( ! selection || selection.rangeCount < 1 ) {
// no selection, no need to continue.
return;
}
/**
* The ID is used to avoid replacing user generated content, that may coincide with the
* format specified below.
* @type {string}
*/
var selectionID = 'SELRES_' + Math.random();
/**
* Create two marker elements that will be used to mark the start and the end of the range.
*
* The elements have hardcoded style that makes them invisible. This is done to avoid seeing
* random content flickering in the editor when switching between modes.
*/
var spanSkeleton = getCursorMarkerSpan( editor.$, selectionID ),
startElement = spanSkeleton.clone().addClass( 'mce_SELRES_start' ),
endElement = spanSkeleton.clone().addClass( 'mce_SELRES_end' );
/**
* Inspired by:
* @link https://stackoverflow.com/a/17497803/153310
*
* Why do it this way and not with TinyMCE's bookmarks?
*
* TinyMCE's bookmarks are very nice when working with selections and positions, BUT
* there is no way to determine the precise position of the bookmark when switching modes, since
* TinyMCE does some serialization of the content, to fix things like shortcodes, run plugins, prettify
* HTML code and so on. In this process, the bookmark markup gets lost.
*
* If we decide to hook right after the bookmark is added, we can see where the bookmark is in the raw HTML
* in TinyMCE. Unfortunately this state is before the serialization, so any visual markup in the content will
* throw off the positioning.
*
* To avoid this, we insert two custom `span`s that will serve as the markers at the beginning and end of the
* selection.
*
* Why not use TinyMCE's selection API or the DOM API to wrap the contents? Because if we do that, this creates
* a new node, which is inserted in the dom. Now this will be fine, if we worked with fixed selections to
* full nodes. Unfortunately in our case, the user can select whatever they like, which means that the
* selection may start in the middle of one node and end in the middle of a completely different one. If we
* wrap the selection in another node, this will create artifacts in the content.
*
* Using the method below, we insert the custom `span` nodes at the start and at the end of the selection.
* This helps us not break the content and also gives us the option to work with multi-node selections without
* breaking the markup.
*/
var range = selection.getRangeAt( 0 ),
startNode = range.startContainer,
startOffset = range.startOffset,
boundaryRange = range.cloneRange();
/**
* If the selection is on a shortcode with Live View, TinyMCE creates a bogus markup,
* which we have to account for.
*/
if ( editor.$( startNode ).parents( '.mce-offscreen-selection' ).length > 0 ) {
startNode = editor.$( '[data-mce-selected]' )[0];
/**
* Marking the start and end element with `data-mce-object-selection` helps
* discern when the selected object is a Live Preview selection.
*
* This way we can adjust the selection to properly select only the content, ignoring
* whitespace inserted around the selected object by the Editor.
*/
startElement.attr( 'data-mce-object-selection', 'true' );
endElement.attr( 'data-mce-object-selection', 'true' );
editor.$( startNode ).before( startElement[0] );
editor.$( startNode ).after( endElement[0] );
} else {
boundaryRange.collapse( false );
boundaryRange.insertNode( endElement[0] );
boundaryRange.setStart( startNode, startOffset );
boundaryRange.collapse( true );
boundaryRange.insertNode( startElement[0] );
range.setStartAfter( startElement[0] );
range.setEndBefore( endElement[0] );
selection.removeAllRanges();
selection.addRange( range );
}
/**
* Now the editor's content has the start/end nodes.
*
* Unfortunately the content goes through some more changes after this step, before it gets inserted
* in the `textarea`. This means that we have to do some minor cleanup on our own here.
*/
editor.on( 'GetContent', fixTextAreaContent );
var content = removep( editor.getContent() );
editor.off( 'GetContent', fixTextAreaContent );
startElement.remove();
endElement.remove();
var startRegex = new RegExp(
']*\\s*class="mce_SELRES_start"[^>]+>\\s*' + selectionID + '[^<]*<\\/span>(\\s*)'
);
var endRegex = new RegExp(
'(\\s*)]*\\s*class="mce_SELRES_end"[^>]+>\\s*' + selectionID + '[^<]*<\\/span>'
);
var startMatch = content.match( startRegex ),
endMatch = content.match( endRegex );
if ( ! startMatch ) {
return null;
}
var startIndex = startMatch.index,
startMatchLength = startMatch[0].length,
endIndex = null;
if (endMatch) {
/**
* Adjust the selection index, if the selection contains a Live Preview object or not.
*
* Check where the `data-mce-object-selection` attribute is set above for more context.
*/
if ( startMatch[0].indexOf( 'data-mce-object-selection' ) !== -1 ) {
startMatchLength -= startMatch[1].length;
}
var endMatchIndex = endMatch.index;
if ( endMatch[0].indexOf( 'data-mce-object-selection' ) !== -1 ) {
endMatchIndex -= endMatch[1].length;
}
// We need to adjust the end position to discard the length of the range start marker.
endIndex = endMatchIndex - startMatchLength;
}
return {
start: startIndex,
end: endIndex
};
}
/**
* Selects text in the TinyMCE `textarea`.
*
* Selects the text in TinyMCE's textarea that's between `selection.start` and `selection.end`.
*
* For `selection` parameter:
* @link findBookmarkedPosition
*
* @param {Object} editor TinyMCE's editor instance.
* @param {Object} selection Selection data.
*/
function selectTextInTextArea( editor, selection ) {
// Only valid in the text area mode and if we have selection.
if ( ! selection ) {
return;
}
var textArea = editor.getElement(),
start = selection.start,
end = selection.end || selection.start;
if ( textArea.focus ) {
// Wait for the Visual editor to be hidden, then focus and scroll to the position.
setTimeout( function() {
textArea.setSelectionRange( start, end );
if ( textArea.blur ) {
// Defocus before focusing.
textArea.blur();
}
textArea.focus();
}, 100 );
}
}
// Restore the selection when the editor is initialized. Needed when the Text editor is the default.
$( document ).on( 'tinymce-editor-init.keep-scroll-position', function( event, editor ) {
if ( editor.$( '.mce_SELRES_start' ).length ) {
focusHTMLBookmarkInVisualEditor( editor );
}
} );
/**
* Replaces tags with two line breaks. "Opposite" of wpautop().
*
* Replaces
tags with two line breaks except where the
has attributes.
* Unifies whitespace.
* Indents
, and for better readability.
*
* @since 2.5.0
*
* @memberof switchEditors
*
* @param {string} html The content from the editor.
* @return {string} The content with stripped paragraph tags.
*/
function removep( html ) {
var blocklist = 'blockquote|ul|ol|li|dl|dt|dd|table|thead|tbody|tfoot|tr|th|td|h[1-6]|fieldset|figure',
blocklist1 = blocklist + '|div|p',
blocklist2 = blocklist + '|pre',
preserve_linebreaks = false,
preserve_br = false,
preserve = [];
if ( ! html ) {
return '';
}
// Protect script and style tags.
if ( html.indexOf( '