@wordpress/block-editor
Version:
8 lines (7 loc) • 17.3 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../../src/store/private-actions.js"],
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { Platform } from '@wordpress/element';\nimport deprecated from '@wordpress/deprecated';\nimport { speak } from '@wordpress/a11y';\nimport { __ } from '@wordpress/i18n';\n\nconst castArray = ( maybeArray ) =>\n\tArray.isArray( maybeArray ) ? maybeArray : [ maybeArray ];\n\n/**\n * A list of private/experimental block editor settings that\n * should not become a part of the WordPress public API.\n * BlockEditorProvider will remove these settings from the\n * settings object it receives.\n *\n * @see https://github.com/WordPress/gutenberg/pull/46131\n */\nconst privateSettings = [\n\t'inserterMediaCategories',\n\t'blockInspectorAnimation',\n\t'mediaSideload',\n];\n\n/**\n * Action that updates the block editor settings and\n * conditionally preserves the experimental ones.\n *\n * @param {Object} settings Updated settings\n * @param {Object} options Options object.\n * @param {boolean} options.stripExperimentalSettings Whether to strip experimental settings.\n * @param {boolean} options.reset Whether to reset the settings.\n * @return {Object} Action object\n */\nexport function __experimentalUpdateSettings(\n\tsettings,\n\t{ stripExperimentalSettings = false, reset = false } = {}\n) {\n\tlet incomingSettings = settings;\n\n\tif ( Object.hasOwn( incomingSettings, '__unstableIsPreviewMode' ) ) {\n\t\tdeprecated(\n\t\t\t\"__unstableIsPreviewMode argument in wp.data.dispatch('core/block-editor').updateSettings\",\n\t\t\t{\n\t\t\t\tsince: '6.8',\n\t\t\t\talternative: 'isPreviewMode',\n\t\t\t}\n\t\t);\n\n\t\tincomingSettings = { ...incomingSettings };\n\t\tincomingSettings.isPreviewMode =\n\t\t\tincomingSettings.__unstableIsPreviewMode;\n\t\tdelete incomingSettings.__unstableIsPreviewMode;\n\t}\n\n\tlet cleanSettings = incomingSettings;\n\n\t// There are no plugins in the mobile apps, so there is no\n\t// need to strip the experimental settings:\n\tif ( stripExperimentalSettings && Platform.OS === 'web' ) {\n\t\tcleanSettings = {};\n\t\tfor ( const key in incomingSettings ) {\n\t\t\tif ( ! privateSettings.includes( key ) ) {\n\t\t\t\tcleanSettings[ key ] = incomingSettings[ key ];\n\t\t\t}\n\t\t}\n\t}\n\treturn {\n\t\ttype: 'UPDATE_SETTINGS',\n\t\tsettings: cleanSettings,\n\t\treset,\n\t};\n}\n\n/**\n * Hides the block interface (eg. toolbar, outline, etc.)\n *\n * @return {Object} Action object.\n */\nexport function hideBlockInterface() {\n\treturn {\n\t\ttype: 'HIDE_BLOCK_INTERFACE',\n\t};\n}\n\n/**\n * Shows the block interface (eg. toolbar, outline, etc.)\n *\n * @return {Object} Action object.\n */\nexport function showBlockInterface() {\n\treturn {\n\t\ttype: 'SHOW_BLOCK_INTERFACE',\n\t};\n}\n\n/**\n * Yields action objects used in signalling that the blocks corresponding to\n * the set of specified client IDs are to be removed.\n *\n * Compared to `removeBlocks`, this private interface exposes an additional\n * parameter; see `forceRemove`.\n *\n * @param {string|string[]} clientIds Client IDs of blocks to remove.\n * @param {boolean} selectPrevious True if the previous block\n * or the immediate parent\n * (if no previous block exists)\n * should be selected\n * when a block is removed.\n * @param {boolean} forceRemove Whether to force the operation,\n * bypassing any checks for certain\n * block types.\n */\nexport const privateRemoveBlocks =\n\t( clientIds, selectPrevious = true, forceRemove = false ) =>\n\t( { select, dispatch, registry } ) => {\n\t\tif ( ! clientIds || ! clientIds.length ) {\n\t\t\treturn;\n\t\t}\n\n\t\tclientIds = castArray( clientIds );\n\t\tconst canRemoveBlocks = select.canRemoveBlocks( clientIds );\n\n\t\tif ( ! canRemoveBlocks ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// In certain editing contexts, we'd like to prevent accidental removal\n\t\t// of important blocks. For example, in the site editor, the Query Loop\n\t\t// block is deemed important. In such cases, we'll ask the user for\n\t\t// confirmation that they intended to remove such block(s). However,\n\t\t// the editor instance is responsible for presenting those confirmation\n\t\t// prompts to the user. Any instance opting into removal prompts must\n\t\t// register using `setBlockRemovalRules()`.\n\t\t//\n\t\t// @see https://github.com/WordPress/gutenberg/pull/51145\n\t\tconst rules = ! forceRemove && select.getBlockRemovalRules();\n\n\t\tif ( rules ) {\n\t\t\tfunction flattenBlocks( blocks ) {\n\t\t\t\tconst result = [];\n\t\t\t\tconst stack = [ ...blocks ];\n\t\t\t\twhile ( stack.length ) {\n\t\t\t\t\tconst { innerBlocks, ...block } = stack.shift();\n\t\t\t\t\tstack.push( ...innerBlocks );\n\t\t\t\t\tresult.push( block );\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\tconst blockList = clientIds.map( select.getBlock );\n\t\t\tconst flattenedBlocks = flattenBlocks( blockList );\n\n\t\t\t// Find the first message and use it.\n\t\t\tlet message;\n\t\t\tfor ( const rule of rules ) {\n\t\t\t\tmessage = rule.callback( flattenedBlocks );\n\t\t\t\tif ( message ) {\n\t\t\t\t\tdispatch(\n\t\t\t\t\t\tdisplayBlockRemovalPrompt(\n\t\t\t\t\t\t\tclientIds,\n\t\t\t\t\t\t\tselectPrevious,\n\t\t\t\t\t\t\tmessage\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( selectPrevious ) {\n\t\t\tdispatch.selectPreviousBlock( clientIds[ 0 ], selectPrevious );\n\t\t}\n\n\t\t// We're batching these two actions because an extra `undo/redo` step can\n\t\t// be created, based on whether we insert a default block or not.\n\t\tregistry.batch( () => {\n\t\t\tdispatch( { type: 'REMOVE_BLOCKS', clientIds } );\n\t\t\t// To avoid a focus loss when removing the last block, assure there is\n\t\t\t// always a default block if the last of the blocks have been removed.\n\t\t\tdispatch( ensureDefaultBlock() );\n\t\t} );\n\t};\n\n/**\n * Action which will insert a default block insert action if there\n * are no other blocks at the root of the editor. This action should be used\n * in actions which may result in no blocks remaining in the editor (removal,\n * replacement, etc).\n */\nexport const ensureDefaultBlock =\n\t() =>\n\t( { select, dispatch } ) => {\n\t\t// To avoid a focus loss when removing the last block, assure there is\n\t\t// always a default block if the last of the blocks have been removed.\n\t\tconst count = select.getBlockCount();\n\t\tif ( count > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there's an custom appender, don't insert default block.\n\t\t// We have to remember to manually move the focus elsewhere to\n\t\t// prevent it from being lost though.\n\t\tconst { __unstableHasCustomAppender } = select.getSettings();\n\t\tif ( __unstableHasCustomAppender ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdispatch.insertDefaultBlock();\n\t};\n\n/**\n * Returns an action object used in signalling that a block removal prompt must\n * be displayed.\n *\n * Contrast with `setBlockRemovalRules`.\n *\n * @param {string|string[]} clientIds Client IDs of blocks to remove.\n * @param {boolean} selectPrevious True if the previous block or the\n * immediate parent (if no previous\n * block exists) should be selected\n * when a block is removed.\n * @param {string} message Message to display in the prompt.\n *\n * @return {Object} Action object.\n */\nfunction displayBlockRemovalPrompt( clientIds, selectPrevious, message ) {\n\treturn {\n\t\ttype: 'DISPLAY_BLOCK_REMOVAL_PROMPT',\n\t\tclientIds,\n\t\tselectPrevious,\n\t\tmessage,\n\t};\n}\n\n/**\n * Returns an action object used in signalling that a block removal prompt must\n * be cleared, either be cause the user has confirmed or canceled the request\n * for removal.\n *\n * @return {Object} Action object.\n */\nexport function clearBlockRemovalPrompt() {\n\treturn {\n\t\ttype: 'CLEAR_BLOCK_REMOVAL_PROMPT',\n\t};\n}\n\n/**\n * Returns an action object used to set up any rules that a block editor may\n * provide in order to prevent a user from accidentally removing certain\n * blocks. These rules are then used to display a confirmation prompt to the\n * user. For instance, in the Site Editor, the Query Loop block is important\n * enough to warrant such confirmation.\n *\n * IMPORTANT: Registering rules implicitly signals to the `privateRemoveBlocks`\n * action that the editor will be responsible for displaying block removal\n * prompts and confirming deletions. This action is meant to be used by\n * component `BlockRemovalWarningModal` only.\n *\n * The data is a record whose keys are block types (e.g. 'core/query') and\n * whose values are the explanation to be shown to users (e.g. 'Query Loop\n * displays a list of posts or pages.').\n *\n * Contrast with `displayBlockRemovalPrompt`.\n *\n * @param {Record<string,string>|false} rules Block removal rules.\n * @return {Object} Action object.\n */\nexport function setBlockRemovalRules( rules = false ) {\n\treturn {\n\t\ttype: 'SET_BLOCK_REMOVAL_RULES',\n\t\trules,\n\t};\n}\n\nexport function setStyleOverride( id, style ) {\n\treturn {\n\t\ttype: 'SET_STYLE_OVERRIDE',\n\t\tid,\n\t\tstyle,\n\t};\n}\n\nexport function deleteStyleOverride( id ) {\n\treturn {\n\t\ttype: 'DELETE_STYLE_OVERRIDE',\n\t\tid,\n\t};\n}\n\n/**\n * Action that sets the element that had focus when focus leaves the editor canvas.\n *\n * @param {Object} lastFocus The last focused element.\n *\n *\n * @return {Object} Action object.\n */\nexport function setLastFocus( lastFocus = null ) {\n\treturn {\n\t\ttype: 'LAST_FOCUS',\n\t\tlastFocus,\n\t};\n}\n\n/**\n * Returns an action object used in signalling that the user has begun to drag.\n *\n * @return {Object} Action object.\n */\nexport function startDragging() {\n\treturn {\n\t\ttype: 'START_DRAGGING',\n\t};\n}\n\n/**\n * Returns an action object used in signalling that the user has stopped dragging.\n *\n * @return {Object} Action object.\n */\nexport function stopDragging() {\n\treturn {\n\t\ttype: 'STOP_DRAGGING',\n\t};\n}\n\n/**\n * @param {string|null} clientId The block's clientId, or `null` to clear.\n *\n * @return {Object} Action object.\n */\nexport function expandBlock( clientId ) {\n\treturn {\n\t\ttype: 'SET_BLOCK_EXPANDED_IN_LIST_VIEW',\n\t\tclientId,\n\t};\n}\n\n/**\n * @param {Object} value\n * @param {string} value.rootClientId The root client ID to insert at.\n * @param {number} value.index The index to insert at.\n *\n * @return {Object} Action object.\n */\nexport function setInsertionPoint( value ) {\n\treturn {\n\t\ttype: 'SET_INSERTION_POINT',\n\t\tvalue,\n\t};\n}\n\n/**\n * Mark a contentOnly section as being edited.\n *\n * @param {string} clientId The client id of the block.\n */\nexport function editContentOnlySection( clientId ) {\n\treturn {\n\t\ttype: 'EDIT_CONTENT_ONLY_SECTION',\n\t\tclientId,\n\t};\n}\n\n/**\n * Action that stops editing a contentOnly section.\n */\nexport function stopEditingContentOnlySection() {\n\treturn {\n\t\ttype: 'EDIT_CONTENT_ONLY_SECTION',\n\t};\n}\n\n/**\n * Sets the zoom level.\n *\n * @param {number} zoom the new zoom level\n * @return {Object} Action object.\n */\nexport const setZoomLevel =\n\t( zoom = 100 ) =>\n\t( { select, dispatch } ) => {\n\t\t// When switching to zoom-out mode, we need to select the parent section\n\t\tif ( zoom !== 100 ) {\n\t\t\tconst firstSelectedClientId = select.getBlockSelectionStart();\n\t\t\tconst sectionRootClientId = select.getSectionRootClientId();\n\n\t\t\tif ( firstSelectedClientId ) {\n\t\t\t\tlet sectionClientId;\n\n\t\t\t\tif ( sectionRootClientId ) {\n\t\t\t\t\tconst sectionClientIds =\n\t\t\t\t\t\tselect.getBlockOrder( sectionRootClientId );\n\n\t\t\t\t\t// If the selected block is a section block, use it.\n\t\t\t\t\tif ( sectionClientIds?.includes( firstSelectedClientId ) ) {\n\t\t\t\t\t\tsectionClientId = firstSelectedClientId;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If the selected block is not a section block, find\n\t\t\t\t\t\t// the parent section that contains the selected block.\n\t\t\t\t\t\tsectionClientId = select\n\t\t\t\t\t\t\t.getBlockParents( firstSelectedClientId )\n\t\t\t\t\t\t\t.find( ( parent ) =>\n\t\t\t\t\t\t\t\tsectionClientIds.includes( parent )\n\t\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tsectionClientId = select.getBlockHierarchyRootClientId(\n\t\t\t\t\t\tfirstSelectedClientId\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif ( sectionClientId ) {\n\t\t\t\t\tdispatch.selectBlock( sectionClientId );\n\t\t\t\t} else {\n\t\t\t\t\tdispatch.clearSelectedBlock();\n\t\t\t\t}\n\n\t\t\t\tspeak( __( 'You are currently in zoom-out mode.' ) );\n\t\t\t}\n\t\t}\n\n\t\tdispatch( {\n\t\t\ttype: 'SET_ZOOM_LEVEL',\n\t\t\tzoom,\n\t\t} );\n\t};\n\n/**\n * Resets the Zoom state.\n * @return {Object} Action object.\n */\nexport function resetZoomLevel() {\n\treturn {\n\t\ttype: 'RESET_ZOOM_LEVEL',\n\t};\n}\n\n/**\n * Action that toggles the spotlighted block state.\n *\n * @param {string} clientId The block's clientId.\n * @param {boolean} hasBlockSpotlight The spotlight state.\n * @return {Object} Action object.\n */\nexport function toggleBlockSpotlight( clientId, hasBlockSpotlight ) {\n\treturn {\n\t\ttype: 'TOGGLE_BLOCK_SPOTLIGHT',\n\t\tclientId,\n\t\thasBlockSpotlight,\n\t};\n}\n"],
"mappings": ";AAGA,SAAS,gBAAgB;AACzB,OAAO,gBAAgB;AACvB,SAAS,aAAa;AACtB,SAAS,UAAU;AAEnB,IAAM,YAAY,CAAE,eACnB,MAAM,QAAS,UAAW,IAAI,aAAa,CAAE,UAAW;AAUzD,IAAM,kBAAkB;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AACD;AAYO,SAAS,6BACf,UACA,EAAE,4BAA4B,OAAO,QAAQ,MAAM,IAAI,CAAC,GACvD;AACD,MAAI,mBAAmB;AAEvB,MAAK,OAAO,OAAQ,kBAAkB,yBAA0B,GAAI;AACnE;AAAA,MACC;AAAA,MACA;AAAA,QACC,OAAO;AAAA,QACP,aAAa;AAAA,MACd;AAAA,IACD;AAEA,uBAAmB,EAAE,GAAG,iBAAiB;AACzC,qBAAiB,gBAChB,iBAAiB;AAClB,WAAO,iBAAiB;AAAA,EACzB;AAEA,MAAI,gBAAgB;AAIpB,MAAK,6BAA6B,SAAS,OAAO,OAAQ;AACzD,oBAAgB,CAAC;AACjB,eAAY,OAAO,kBAAmB;AACrC,UAAK,CAAE,gBAAgB,SAAU,GAAI,GAAI;AACxC,sBAAe,GAAI,IAAI,iBAAkB,GAAI;AAAA,MAC9C;AAAA,IACD;AAAA,EACD;AACA,SAAO;AAAA,IACN,MAAM;AAAA,IACN,UAAU;AAAA,IACV;AAAA,EACD;AACD;AAOO,SAAS,qBAAqB;AACpC,SAAO;AAAA,IACN,MAAM;AAAA,EACP;AACD;AAOO,SAAS,qBAAqB;AACpC,SAAO;AAAA,IACN,MAAM;AAAA,EACP;AACD;AAmBO,IAAM,sBACZ,CAAE,WAAW,iBAAiB,MAAM,cAAc,UAClD,CAAE,EAAE,QAAQ,UAAU,SAAS,MAAO;AACrC,MAAK,CAAE,aAAa,CAAE,UAAU,QAAS;AACxC;AAAA,EACD;AAEA,cAAY,UAAW,SAAU;AACjC,QAAM,kBAAkB,OAAO,gBAAiB,SAAU;AAE1D,MAAK,CAAE,iBAAkB;AACxB;AAAA,EACD;AAWA,QAAM,QAAQ,CAAE,eAAe,OAAO,qBAAqB;AAE3D,MAAK,OAAQ;AACZ,QAASA,iBAAT,SAAwB,QAAS;AAChC,YAAM,SAAS,CAAC;AAChB,YAAM,QAAQ,CAAE,GAAG,MAAO;AAC1B,aAAQ,MAAM,QAAS;AACtB,cAAM,EAAE,aAAa,GAAG,MAAM,IAAI,MAAM,MAAM;AAC9C,cAAM,KAAM,GAAG,WAAY;AAC3B,eAAO,KAAM,KAAM;AAAA,MACpB;AACA,aAAO;AAAA,IACR;AATS,wBAAAA;AAWT,UAAM,YAAY,UAAU,IAAK,OAAO,QAAS;AACjD,UAAM,kBAAkBA,eAAe,SAAU;AAGjD,QAAI;AACJ,eAAY,QAAQ,OAAQ;AAC3B,gBAAU,KAAK,SAAU,eAAgB;AACzC,UAAK,SAAU;AACd;AAAA,UACC;AAAA,YACC;AAAA,YACA;AAAA,YACA;AAAA,UACD;AAAA,QACD;AACA;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAEA,MAAK,gBAAiB;AACrB,aAAS,oBAAqB,UAAW,CAAE,GAAG,cAAe;AAAA,EAC9D;AAIA,WAAS,MAAO,MAAM;AACrB,aAAU,EAAE,MAAM,iBAAiB,UAAU,CAAE;AAG/C,aAAU,mBAAmB,CAAE;AAAA,EAChC,CAAE;AACH;AAQM,IAAM,qBACZ,MACA,CAAE,EAAE,QAAQ,SAAS,MAAO;AAG3B,QAAM,QAAQ,OAAO,cAAc;AACnC,MAAK,QAAQ,GAAI;AAChB;AAAA,EACD;AAKA,QAAM,EAAE,4BAA4B,IAAI,OAAO,YAAY;AAC3D,MAAK,6BAA8B;AAClC;AAAA,EACD;AAEA,WAAS,mBAAmB;AAC7B;AAiBD,SAAS,0BAA2B,WAAW,gBAAgB,SAAU;AACxE,SAAO;AAAA,IACN,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACD;AASO,SAAS,0BAA0B;AACzC,SAAO;AAAA,IACN,MAAM;AAAA,EACP;AACD;AAuBO,SAAS,qBAAsB,QAAQ,OAAQ;AACrD,SAAO;AAAA,IACN,MAAM;AAAA,IACN;AAAA,EACD;AACD;AAEO,SAAS,iBAAkB,IAAI,OAAQ;AAC7C,SAAO;AAAA,IACN,MAAM;AAAA,IACN;AAAA,IACA;AAAA,EACD;AACD;AAEO,SAAS,oBAAqB,IAAK;AACzC,SAAO;AAAA,IACN,MAAM;AAAA,IACN;AAAA,EACD;AACD;AAUO,SAAS,aAAc,YAAY,MAAO;AAChD,SAAO;AAAA,IACN,MAAM;AAAA,IACN;AAAA,EACD;AACD;AAOO,SAAS,gBAAgB;AAC/B,SAAO;AAAA,IACN,MAAM;AAAA,EACP;AACD;AAOO,SAAS,eAAe;AAC9B,SAAO;AAAA,IACN,MAAM;AAAA,EACP;AACD;AAOO,SAAS,YAAa,UAAW;AACvC,SAAO;AAAA,IACN,MAAM;AAAA,IACN;AAAA,EACD;AACD;AASO,SAAS,kBAAmB,OAAQ;AAC1C,SAAO;AAAA,IACN,MAAM;AAAA,IACN;AAAA,EACD;AACD;AAOO,SAAS,uBAAwB,UAAW;AAClD,SAAO;AAAA,IACN,MAAM;AAAA,IACN;AAAA,EACD;AACD;AAKO,SAAS,gCAAgC;AAC/C,SAAO;AAAA,IACN,MAAM;AAAA,EACP;AACD;AAQO,IAAM,eACZ,CAAE,OAAO,QACT,CAAE,EAAE,QAAQ,SAAS,MAAO;AAE3B,MAAK,SAAS,KAAM;AACnB,UAAM,wBAAwB,OAAO,uBAAuB;AAC5D,UAAM,sBAAsB,OAAO,uBAAuB;AAE1D,QAAK,uBAAwB;AAC5B,UAAI;AAEJ,UAAK,qBAAsB;AAC1B,cAAM,mBACL,OAAO,cAAe,mBAAoB;AAG3C,YAAK,kBAAkB,SAAU,qBAAsB,GAAI;AAC1D,4BAAkB;AAAA,QACnB,OAAO;AAGN,4BAAkB,OAChB,gBAAiB,qBAAsB,EACvC;AAAA,YAAM,CAAE,WACR,iBAAiB,SAAU,MAAO;AAAA,UACnC;AAAA,QACF;AAAA,MACD,OAAO;AACN,0BAAkB,OAAO;AAAA,UACxB;AAAA,QACD;AAAA,MACD;AAEA,UAAK,iBAAkB;AACtB,iBAAS,YAAa,eAAgB;AAAA,MACvC,OAAO;AACN,iBAAS,mBAAmB;AAAA,MAC7B;AAEA,YAAO,GAAI,qCAAsC,CAAE;AAAA,IACpD;AAAA,EACD;AAEA,WAAU;AAAA,IACT,MAAM;AAAA,IACN;AAAA,EACD,CAAE;AACH;AAMM,SAAS,iBAAiB;AAChC,SAAO;AAAA,IACN,MAAM;AAAA,EACP;AACD;AASO,SAAS,qBAAsB,UAAU,mBAAoB;AACnE,SAAO;AAAA,IACN,MAAM;AAAA,IACN;AAAA,IACA;AAAA,EACD;AACD;",
"names": ["flattenBlocks"]
}