@wordpress/format-library 3.0.5 → 3.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,7 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
3
5
  Object.defineProperty(exports, "__esModule", {
4
6
  value: true
5
7
  });
@@ -23,6 +25,8 @@ var _utils = require("./utils");
23
25
 
24
26
  var _index = require("./index");
25
27
 
28
+ var _useLinkInstanceKey = _interopRequireDefault(require("./use-link-instance-key"));
29
+
26
30
  /**
27
31
  * WordPress dependencies
28
32
  */
@@ -169,7 +173,12 @@ function InlineLinkUI({
169
173
  ref: contentRef,
170
174
  value,
171
175
  settings: _index.link
172
- }); // The focusOnMount prop shouldn't evolve during render of a Popover
176
+ }); // Generate a string based key that is unique to this anchor reference.
177
+ // This is used to force re-mount the LinkControl component to avoid
178
+ // potential stale state bugs caused by the component not being remounted
179
+ // See https://github.com/WordPress/gutenberg/pull/34742.
180
+
181
+ const forceRemountKey = (0, _useLinkInstanceKey.default)(anchorRef); // The focusOnMount prop shouldn't evolve during render of a Popover
173
182
  // otherwise it causes a render of the content.
174
183
 
175
184
  const focusOnMount = (0, _element.useRef)(addingLink ? 'firstElement' : false);
@@ -202,6 +211,7 @@ function InlineLinkUI({
202
211
  onClose: stopAddingLink,
203
212
  position: "bottom center"
204
213
  }, (0, _element.createElement)(_blockEditor.__experimentalLinkControl, {
214
+ key: forceRemountKey,
205
215
  value: linkValue,
206
216
  onChange: onChangeLink,
207
217
  onRemove: removeLink,
@@ -1 +1 @@
1
- {"version":3,"sources":["@wordpress/format-library/src/link/inline.js"],"names":["InlineLinkUI","isActive","activeAttributes","addingLink","value","onChange","speak","stopAddingLink","contentRef","richLinkTextValue","getRichTextValueFromSelection","richTextText","text","nextLinkValue","setNextLinkValue","createPageEntity","userCanCreatePages","select","getSettings","blockEditorStore","_settings","__experimentalCreatePageEntity","__experimentalUserCanCreatePages","linkValue","url","type","id","opensInNewTab","target","title","removeLink","newValue","onChangeLink","nextValue","didToggleSetting","didToggleSettingForNewLink","undefined","newUrl","linkFormat","String","opensInNewWindow","newText","toInsert","length","start","end","activeFormats","anchorRef","ref","settings","focusOnMount","handleCreate","pageTitle","page","status","rendered","link","kind","createButtonText","searchTerm","mark","current","textStart","textEnd","boundary"],"mappings":"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","sourcesContent":["/**\n * WordPress dependencies\n */\nimport { useState, useRef, createInterpolateElement } from '@wordpress/element';\nimport { __, sprintf } from '@wordpress/i18n';\nimport { withSpokenMessages, Popover } from '@wordpress/components';\nimport { prependHTTP } from '@wordpress/url';\nimport {\n\tcreate,\n\tinsert,\n\tisCollapsed,\n\tapplyFormat,\n\tuseAnchorRef,\n\tremoveFormat,\n\tslice,\n\treplace,\n} from '@wordpress/rich-text';\nimport {\n\t__experimentalLinkControl as LinkControl,\n\tstore as blockEditorStore,\n} from '@wordpress/block-editor';\nimport { useSelect } from '@wordpress/data';\n\n/**\n * Internal dependencies\n */\nimport { createLinkFormat, isValidHref, getFormatBoundary } from './utils';\nimport { link as settings } from './index';\n\nfunction InlineLinkUI( {\n\tisActive,\n\tactiveAttributes,\n\taddingLink,\n\tvalue,\n\tonChange,\n\tspeak,\n\tstopAddingLink,\n\tcontentRef,\n} ) {\n\tconst richLinkTextValue = getRichTextValueFromSelection( value, isActive );\n\n\t// Get the text content minus any HTML tags.\n\tconst richTextText = richLinkTextValue.text;\n\n\t/**\n\t * Pending settings to be applied to the next link. When inserting a new\n\t * link, toggle values cannot be applied immediately, because there is not\n\t * yet a link for them to apply to. Thus, they are maintained in a state\n\t * value until the time that the link can be inserted or edited.\n\t *\n\t * @type {[Object|undefined,Function]}\n\t */\n\tconst [ nextLinkValue, setNextLinkValue ] = useState();\n\n\tconst { createPageEntity, userCanCreatePages } = useSelect( ( select ) => {\n\t\tconst { getSettings } = select( blockEditorStore );\n\t\tconst _settings = getSettings();\n\n\t\treturn {\n\t\t\tcreatePageEntity: _settings.__experimentalCreatePageEntity,\n\t\t\tuserCanCreatePages: _settings.__experimentalUserCanCreatePages,\n\t\t};\n\t}, [] );\n\n\tconst linkValue = {\n\t\turl: activeAttributes.url,\n\t\ttype: activeAttributes.type,\n\t\tid: activeAttributes.id,\n\t\topensInNewTab: activeAttributes.target === '_blank',\n\t\ttitle: richTextText,\n\t\t...nextLinkValue,\n\t};\n\n\tfunction removeLink() {\n\t\tconst newValue = removeFormat( value, 'core/link' );\n\t\tonChange( newValue );\n\t\tstopAddingLink();\n\t\tspeak( __( 'Link removed.' ), 'assertive' );\n\t}\n\n\tfunction onChangeLink( nextValue ) {\n\t\t// Merge with values from state, both for the purpose of assigning the\n\t\t// next state value, and for use in constructing the new link format if\n\t\t// the link is ready to be applied.\n\t\tnextValue = {\n\t\t\t...nextLinkValue,\n\t\t\t...nextValue,\n\t\t};\n\n\t\t// LinkControl calls `onChange` immediately upon the toggling a setting.\n\t\tconst didToggleSetting =\n\t\t\tlinkValue.opensInNewTab !== nextValue.opensInNewTab &&\n\t\t\tlinkValue.url === nextValue.url;\n\n\t\t// If change handler was called as a result of a settings change during\n\t\t// link insertion, it must be held in state until the link is ready to\n\t\t// be applied.\n\t\tconst didToggleSettingForNewLink =\n\t\t\tdidToggleSetting && nextValue.url === undefined;\n\n\t\t// If link will be assigned, the state value can be considered flushed.\n\t\t// Otherwise, persist the pending changes.\n\t\tsetNextLinkValue( didToggleSettingForNewLink ? nextValue : undefined );\n\n\t\tif ( didToggleSettingForNewLink ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst newUrl = prependHTTP( nextValue.url );\n\t\tconst linkFormat = createLinkFormat( {\n\t\t\turl: newUrl,\n\t\t\ttype: nextValue.type,\n\t\t\tid:\n\t\t\t\tnextValue.id !== undefined && nextValue.id !== null\n\t\t\t\t\t? String( nextValue.id )\n\t\t\t\t\t: undefined,\n\t\t\topensInNewWindow: nextValue.opensInNewTab,\n\t\t} );\n\n\t\tconst newText = nextValue.title || newUrl;\n\t\tif ( isCollapsed( value ) && ! isActive ) {\n\t\t\t// Scenario: we don't have any actively selected text or formats.\n\t\t\tconst toInsert = applyFormat(\n\t\t\t\tcreate( { text: newText } ),\n\t\t\t\tlinkFormat,\n\t\t\t\t0,\n\t\t\t\tnewText.length\n\t\t\t);\n\t\t\tonChange( insert( value, toInsert ) );\n\t\t} else {\n\t\t\t// Scenario: we have any active text selection or an active format\n\t\t\tlet newValue;\n\n\t\t\tif ( newText === richTextText ) {\n\t\t\t\t// If we're not updating the text then ignore\n\t\t\t\tnewValue = applyFormat( value, linkFormat );\n\t\t\t} else {\n\t\t\t\t// Create new RichText value for the new text in order that we\n\t\t\t\t// can apply formats to it.\n\t\t\t\tnewValue = create( { text: newText } );\n\n\t\t\t\t// Apply the new Link format to this new text value.\n\t\t\t\tnewValue = applyFormat(\n\t\t\t\t\tnewValue,\n\t\t\t\t\tlinkFormat,\n\t\t\t\t\t0,\n\t\t\t\t\tnewText.length\n\t\t\t\t);\n\n\t\t\t\t// Update the original (full) RichTextValue replacing the\n\t\t\t\t// target text with the *new* RichTextValue containing:\n\t\t\t\t// 1. The new text content.\n\t\t\t\t// 2. The new link format.\n\t\t\t\t// Note original formats will be lost when applying this change.\n\t\t\t\t// That is expected behaviour.\n\t\t\t\t// See: https://github.com/WordPress/gutenberg/pull/33849#issuecomment-936134179.\n\t\t\t\tnewValue = replace( value, richTextText, newValue );\n\t\t\t}\n\n\t\t\tnewValue.start = newValue.end;\n\t\t\tnewValue.activeFormats = [];\n\t\t\tonChange( newValue );\n\t\t}\n\n\t\t// Focus should only be shifted back to the formatted segment when the\n\t\t// URL is submitted.\n\t\tif ( ! didToggleSetting ) {\n\t\t\tstopAddingLink();\n\t\t}\n\n\t\tif ( ! isValidHref( newUrl ) ) {\n\t\t\tspeak(\n\t\t\t\t__(\n\t\t\t\t\t'Warning: the link has been inserted but may have errors. Please test it.'\n\t\t\t\t),\n\t\t\t\t'assertive'\n\t\t\t);\n\t\t} else if ( isActive ) {\n\t\t\tspeak( __( 'Link edited.' ), 'assertive' );\n\t\t} else {\n\t\t\tspeak( __( 'Link inserted.' ), 'assertive' );\n\t\t}\n\t}\n\n\tconst anchorRef = useAnchorRef( { ref: contentRef, value, settings } );\n\n\t// The focusOnMount prop shouldn't evolve during render of a Popover\n\t// otherwise it causes a render of the content.\n\tconst focusOnMount = useRef( addingLink ? 'firstElement' : false );\n\n\tasync function handleCreate( pageTitle ) {\n\t\tconst page = await createPageEntity( {\n\t\t\ttitle: pageTitle,\n\t\t\tstatus: 'draft',\n\t\t} );\n\n\t\treturn {\n\t\t\tid: page.id,\n\t\t\ttype: page.type,\n\t\t\ttitle: page.title.rendered,\n\t\t\turl: page.link,\n\t\t\tkind: 'post-type',\n\t\t};\n\t}\n\n\tfunction createButtonText( searchTerm ) {\n\t\treturn createInterpolateElement(\n\t\t\tsprintf(\n\t\t\t\t/* translators: %s: search term. */\n\t\t\t\t__( 'Create Page: <mark>%s</mark>' ),\n\t\t\t\tsearchTerm\n\t\t\t),\n\t\t\t{ mark: <mark /> }\n\t\t);\n\t}\n\n\treturn (\n\t\t<Popover\n\t\t\tanchorRef={ anchorRef }\n\t\t\tfocusOnMount={ focusOnMount.current }\n\t\t\tonClose={ stopAddingLink }\n\t\t\tposition=\"bottom center\"\n\t\t>\n\t\t\t<LinkControl\n\t\t\t\tvalue={ linkValue }\n\t\t\t\tonChange={ onChangeLink }\n\t\t\t\tonRemove={ removeLink }\n\t\t\t\tforceIsEditingLink={ addingLink }\n\t\t\t\thasRichPreviews\n\t\t\t\tcreateSuggestion={ createPageEntity && handleCreate }\n\t\t\t\twithCreateSuggestion={ userCanCreatePages }\n\t\t\t\tcreateSuggestionButtonText={ createButtonText }\n\t\t\t\thasTextControl\n\t\t\t/>\n\t\t</Popover>\n\t);\n}\n\nfunction getRichTextValueFromSelection( value, isActive ) {\n\t// Default to the selection ranges on the RichTextValue object.\n\tlet textStart = value.start;\n\tlet textEnd = value.end;\n\n\t// If the format is currently active then the rich text value\n\t// should always be taken from the bounds of the active format\n\t// and not the selected text.\n\tif ( isActive ) {\n\t\tconst boundary = getFormatBoundary( value, {\n\t\t\ttype: 'core/link',\n\t\t} );\n\n\t\ttextStart = boundary.start;\n\n\t\t// Text *selection* always extends +1 beyond the edge of the format.\n\t\t// We account for that here.\n\t\ttextEnd = boundary.end + 1;\n\t}\n\n\t// Get a RichTextValue containing the selected text content.\n\treturn slice( value, textStart, textEnd );\n}\n\nexport default withSpokenMessages( InlineLinkUI );\n"]}
1
+ {"version":3,"sources":["@wordpress/format-library/src/link/inline.js"],"names":["InlineLinkUI","isActive","activeAttributes","addingLink","value","onChange","speak","stopAddingLink","contentRef","richLinkTextValue","getRichTextValueFromSelection","richTextText","text","nextLinkValue","setNextLinkValue","createPageEntity","userCanCreatePages","select","getSettings","blockEditorStore","_settings","__experimentalCreatePageEntity","__experimentalUserCanCreatePages","linkValue","url","type","id","opensInNewTab","target","title","removeLink","newValue","onChangeLink","nextValue","didToggleSetting","didToggleSettingForNewLink","undefined","newUrl","linkFormat","String","opensInNewWindow","newText","toInsert","length","start","end","activeFormats","anchorRef","ref","settings","forceRemountKey","focusOnMount","handleCreate","pageTitle","page","status","rendered","link","kind","createButtonText","searchTerm","mark","current","textStart","textEnd","boundary"],"mappings":"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","sourcesContent":["/**\n * WordPress dependencies\n */\nimport { useState, useRef, createInterpolateElement } from '@wordpress/element';\nimport { __, sprintf } from '@wordpress/i18n';\nimport { withSpokenMessages, Popover } from '@wordpress/components';\nimport { prependHTTP } from '@wordpress/url';\nimport {\n\tcreate,\n\tinsert,\n\tisCollapsed,\n\tapplyFormat,\n\tuseAnchorRef,\n\tremoveFormat,\n\tslice,\n\treplace,\n} from '@wordpress/rich-text';\nimport {\n\t__experimentalLinkControl as LinkControl,\n\tstore as blockEditorStore,\n} from '@wordpress/block-editor';\nimport { useSelect } from '@wordpress/data';\n\n/**\n * Internal dependencies\n */\nimport { createLinkFormat, isValidHref, getFormatBoundary } from './utils';\nimport { link as settings } from './index';\nimport useLinkInstanceKey from './use-link-instance-key';\n\nfunction InlineLinkUI( {\n\tisActive,\n\tactiveAttributes,\n\taddingLink,\n\tvalue,\n\tonChange,\n\tspeak,\n\tstopAddingLink,\n\tcontentRef,\n} ) {\n\tconst richLinkTextValue = getRichTextValueFromSelection( value, isActive );\n\n\t// Get the text content minus any HTML tags.\n\tconst richTextText = richLinkTextValue.text;\n\n\t/**\n\t * Pending settings to be applied to the next link. When inserting a new\n\t * link, toggle values cannot be applied immediately, because there is not\n\t * yet a link for them to apply to. Thus, they are maintained in a state\n\t * value until the time that the link can be inserted or edited.\n\t *\n\t * @type {[Object|undefined,Function]}\n\t */\n\tconst [ nextLinkValue, setNextLinkValue ] = useState();\n\n\tconst { createPageEntity, userCanCreatePages } = useSelect( ( select ) => {\n\t\tconst { getSettings } = select( blockEditorStore );\n\t\tconst _settings = getSettings();\n\n\t\treturn {\n\t\t\tcreatePageEntity: _settings.__experimentalCreatePageEntity,\n\t\t\tuserCanCreatePages: _settings.__experimentalUserCanCreatePages,\n\t\t};\n\t}, [] );\n\n\tconst linkValue = {\n\t\turl: activeAttributes.url,\n\t\ttype: activeAttributes.type,\n\t\tid: activeAttributes.id,\n\t\topensInNewTab: activeAttributes.target === '_blank',\n\t\ttitle: richTextText,\n\t\t...nextLinkValue,\n\t};\n\n\tfunction removeLink() {\n\t\tconst newValue = removeFormat( value, 'core/link' );\n\t\tonChange( newValue );\n\t\tstopAddingLink();\n\t\tspeak( __( 'Link removed.' ), 'assertive' );\n\t}\n\n\tfunction onChangeLink( nextValue ) {\n\t\t// Merge with values from state, both for the purpose of assigning the\n\t\t// next state value, and for use in constructing the new link format if\n\t\t// the link is ready to be applied.\n\t\tnextValue = {\n\t\t\t...nextLinkValue,\n\t\t\t...nextValue,\n\t\t};\n\n\t\t// LinkControl calls `onChange` immediately upon the toggling a setting.\n\t\tconst didToggleSetting =\n\t\t\tlinkValue.opensInNewTab !== nextValue.opensInNewTab &&\n\t\t\tlinkValue.url === nextValue.url;\n\n\t\t// If change handler was called as a result of a settings change during\n\t\t// link insertion, it must be held in state until the link is ready to\n\t\t// be applied.\n\t\tconst didToggleSettingForNewLink =\n\t\t\tdidToggleSetting && nextValue.url === undefined;\n\n\t\t// If link will be assigned, the state value can be considered flushed.\n\t\t// Otherwise, persist the pending changes.\n\t\tsetNextLinkValue( didToggleSettingForNewLink ? nextValue : undefined );\n\n\t\tif ( didToggleSettingForNewLink ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst newUrl = prependHTTP( nextValue.url );\n\t\tconst linkFormat = createLinkFormat( {\n\t\t\turl: newUrl,\n\t\t\ttype: nextValue.type,\n\t\t\tid:\n\t\t\t\tnextValue.id !== undefined && nextValue.id !== null\n\t\t\t\t\t? String( nextValue.id )\n\t\t\t\t\t: undefined,\n\t\t\topensInNewWindow: nextValue.opensInNewTab,\n\t\t} );\n\n\t\tconst newText = nextValue.title || newUrl;\n\t\tif ( isCollapsed( value ) && ! isActive ) {\n\t\t\t// Scenario: we don't have any actively selected text or formats.\n\t\t\tconst toInsert = applyFormat(\n\t\t\t\tcreate( { text: newText } ),\n\t\t\t\tlinkFormat,\n\t\t\t\t0,\n\t\t\t\tnewText.length\n\t\t\t);\n\t\t\tonChange( insert( value, toInsert ) );\n\t\t} else {\n\t\t\t// Scenario: we have any active text selection or an active format\n\t\t\tlet newValue;\n\n\t\t\tif ( newText === richTextText ) {\n\t\t\t\t// If we're not updating the text then ignore\n\t\t\t\tnewValue = applyFormat( value, linkFormat );\n\t\t\t} else {\n\t\t\t\t// Create new RichText value for the new text in order that we\n\t\t\t\t// can apply formats to it.\n\t\t\t\tnewValue = create( { text: newText } );\n\n\t\t\t\t// Apply the new Link format to this new text value.\n\t\t\t\tnewValue = applyFormat(\n\t\t\t\t\tnewValue,\n\t\t\t\t\tlinkFormat,\n\t\t\t\t\t0,\n\t\t\t\t\tnewText.length\n\t\t\t\t);\n\n\t\t\t\t// Update the original (full) RichTextValue replacing the\n\t\t\t\t// target text with the *new* RichTextValue containing:\n\t\t\t\t// 1. The new text content.\n\t\t\t\t// 2. The new link format.\n\t\t\t\t// Note original formats will be lost when applying this change.\n\t\t\t\t// That is expected behaviour.\n\t\t\t\t// See: https://github.com/WordPress/gutenberg/pull/33849#issuecomment-936134179.\n\t\t\t\tnewValue = replace( value, richTextText, newValue );\n\t\t\t}\n\n\t\t\tnewValue.start = newValue.end;\n\t\t\tnewValue.activeFormats = [];\n\t\t\tonChange( newValue );\n\t\t}\n\n\t\t// Focus should only be shifted back to the formatted segment when the\n\t\t// URL is submitted.\n\t\tif ( ! didToggleSetting ) {\n\t\t\tstopAddingLink();\n\t\t}\n\n\t\tif ( ! isValidHref( newUrl ) ) {\n\t\t\tspeak(\n\t\t\t\t__(\n\t\t\t\t\t'Warning: the link has been inserted but may have errors. Please test it.'\n\t\t\t\t),\n\t\t\t\t'assertive'\n\t\t\t);\n\t\t} else if ( isActive ) {\n\t\t\tspeak( __( 'Link edited.' ), 'assertive' );\n\t\t} else {\n\t\t\tspeak( __( 'Link inserted.' ), 'assertive' );\n\t\t}\n\t}\n\n\tconst anchorRef = useAnchorRef( { ref: contentRef, value, settings } );\n\n\t// Generate a string based key that is unique to this anchor reference.\n\t// This is used to force re-mount the LinkControl component to avoid\n\t// potential stale state bugs caused by the component not being remounted\n\t// See https://github.com/WordPress/gutenberg/pull/34742.\n\tconst forceRemountKey = useLinkInstanceKey( anchorRef );\n\n\t// The focusOnMount prop shouldn't evolve during render of a Popover\n\t// otherwise it causes a render of the content.\n\tconst focusOnMount = useRef( addingLink ? 'firstElement' : false );\n\n\tasync function handleCreate( pageTitle ) {\n\t\tconst page = await createPageEntity( {\n\t\t\ttitle: pageTitle,\n\t\t\tstatus: 'draft',\n\t\t} );\n\n\t\treturn {\n\t\t\tid: page.id,\n\t\t\ttype: page.type,\n\t\t\ttitle: page.title.rendered,\n\t\t\turl: page.link,\n\t\t\tkind: 'post-type',\n\t\t};\n\t}\n\n\tfunction createButtonText( searchTerm ) {\n\t\treturn createInterpolateElement(\n\t\t\tsprintf(\n\t\t\t\t/* translators: %s: search term. */\n\t\t\t\t__( 'Create Page: <mark>%s</mark>' ),\n\t\t\t\tsearchTerm\n\t\t\t),\n\t\t\t{ mark: <mark /> }\n\t\t);\n\t}\n\n\treturn (\n\t\t<Popover\n\t\t\tanchorRef={ anchorRef }\n\t\t\tfocusOnMount={ focusOnMount.current }\n\t\t\tonClose={ stopAddingLink }\n\t\t\tposition=\"bottom center\"\n\t\t>\n\t\t\t<LinkControl\n\t\t\t\tkey={ forceRemountKey }\n\t\t\t\tvalue={ linkValue }\n\t\t\t\tonChange={ onChangeLink }\n\t\t\t\tonRemove={ removeLink }\n\t\t\t\tforceIsEditingLink={ addingLink }\n\t\t\t\thasRichPreviews\n\t\t\t\tcreateSuggestion={ createPageEntity && handleCreate }\n\t\t\t\twithCreateSuggestion={ userCanCreatePages }\n\t\t\t\tcreateSuggestionButtonText={ createButtonText }\n\t\t\t\thasTextControl\n\t\t\t/>\n\t\t</Popover>\n\t);\n}\n\nfunction getRichTextValueFromSelection( value, isActive ) {\n\t// Default to the selection ranges on the RichTextValue object.\n\tlet textStart = value.start;\n\tlet textEnd = value.end;\n\n\t// If the format is currently active then the rich text value\n\t// should always be taken from the bounds of the active format\n\t// and not the selected text.\n\tif ( isActive ) {\n\t\tconst boundary = getFormatBoundary( value, {\n\t\t\ttype: 'core/link',\n\t\t} );\n\n\t\ttextStart = boundary.start;\n\n\t\t// Text *selection* always extends +1 beyond the edge of the format.\n\t\t// We account for that here.\n\t\ttextEnd = boundary.end + 1;\n\t}\n\n\t// Get a RichTextValue containing the selected text content.\n\treturn slice( value, textStart, textEnd );\n}\n\nexport default withSpokenMessages( InlineLinkUI );\n"]}
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ // Weakly referenced map allows unused ids to be garbage collected.
8
+ const weakMap = new WeakMap(); // Incrementing zero-based ID value
9
+
10
+ let id = -1;
11
+ const prefix = 'link-control-instance';
12
+
13
+ function getKey(_id) {
14
+ return `${prefix}-${_id}`;
15
+ }
16
+ /**
17
+ * Builds a unique link control key for the given object reference.
18
+ *
19
+ * @param {Object} instance an unique object reference specific to this link control instance.
20
+ * @return {string} the unique key to use for this link control.
21
+ */
22
+
23
+
24
+ function useLinkInstanceKey(instance) {
25
+ if (weakMap.has(instance)) {
26
+ return getKey(weakMap.get(instance));
27
+ }
28
+
29
+ id += 1;
30
+ weakMap.set(instance, id);
31
+ return getKey(id);
32
+ }
33
+
34
+ var _default = useLinkInstanceKey;
35
+ exports.default = _default;
36
+ //# sourceMappingURL=use-link-instance-key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["@wordpress/format-library/src/link/use-link-instance-key.js"],"names":["weakMap","WeakMap","id","prefix","getKey","_id","useLinkInstanceKey","instance","has","get","set"],"mappings":";;;;;;AAAA;AACA,MAAMA,OAAO,GAAG,IAAIC,OAAJ,EAAhB,C,CAEA;;AACA,IAAIC,EAAE,GAAG,CAAC,CAAV;AAEA,MAAMC,MAAM,GAAG,uBAAf;;AAEA,SAASC,MAAT,CAAiBC,GAAjB,EAAuB;AACtB,SAAQ,GAAGF,MAAQ,IAAIE,GAAK,EAA5B;AACA;AAED;AACA;AACA;AACA;AACA;AACA;;;AACA,SAASC,kBAAT,CAA6BC,QAA7B,EAAwC;AACvC,MAAKP,OAAO,CAACQ,GAAR,CAAaD,QAAb,CAAL,EAA+B;AAC9B,WAAOH,MAAM,CAAEJ,OAAO,CAACS,GAAR,CAAaF,QAAb,CAAF,CAAb;AACA;;AAEDL,EAAAA,EAAE,IAAI,CAAN;AAEAF,EAAAA,OAAO,CAACU,GAAR,CAAaH,QAAb,EAAuBL,EAAvB;AAEA,SAAOE,MAAM,CAAEF,EAAF,CAAb;AACA;;eAEcI,kB","sourcesContent":["// Weakly referenced map allows unused ids to be garbage collected.\nconst weakMap = new WeakMap();\n\n// Incrementing zero-based ID value\nlet id = -1;\n\nconst prefix = 'link-control-instance';\n\nfunction getKey( _id ) {\n\treturn `${ prefix }-${ _id }`;\n}\n\n/**\n * Builds a unique link control key for the given object reference.\n *\n * @param {Object} instance an unique object reference specific to this link control instance.\n * @return {string} the unique key to use for this link control.\n */\nfunction useLinkInstanceKey( instance ) {\n\tif ( weakMap.has( instance ) ) {\n\t\treturn getKey( weakMap.get( instance ) );\n\t}\n\n\tid += 1;\n\n\tweakMap.set( instance, id );\n\n\treturn getKey( id );\n}\n\nexport default useLinkInstanceKey;\n"]}
@@ -16,6 +16,7 @@ import { useSelect } from '@wordpress/data';
16
16
 
17
17
  import { createLinkFormat, isValidHref, getFormatBoundary } from './utils';
18
18
  import { link as settings } from './index';
19
+ import useLinkInstanceKey from './use-link-instance-key';
19
20
 
20
21
  function InlineLinkUI({
21
22
  isActive,
@@ -156,7 +157,12 @@ function InlineLinkUI({
156
157
  ref: contentRef,
157
158
  value,
158
159
  settings
159
- }); // The focusOnMount prop shouldn't evolve during render of a Popover
160
+ }); // Generate a string based key that is unique to this anchor reference.
161
+ // This is used to force re-mount the LinkControl component to avoid
162
+ // potential stale state bugs caused by the component not being remounted
163
+ // See https://github.com/WordPress/gutenberg/pull/34742.
164
+
165
+ const forceRemountKey = useLinkInstanceKey(anchorRef); // The focusOnMount prop shouldn't evolve during render of a Popover
160
166
  // otherwise it causes a render of the content.
161
167
 
162
168
  const focusOnMount = useRef(addingLink ? 'firstElement' : false);
@@ -189,6 +195,7 @@ function InlineLinkUI({
189
195
  onClose: stopAddingLink,
190
196
  position: "bottom center"
191
197
  }, createElement(LinkControl, {
198
+ key: forceRemountKey,
192
199
  value: linkValue,
193
200
  onChange: onChangeLink,
194
201
  onRemove: removeLink,
@@ -1 +1 @@
1
- {"version":3,"sources":["@wordpress/format-library/src/link/inline.js"],"names":["useState","useRef","createInterpolateElement","__","sprintf","withSpokenMessages","Popover","prependHTTP","create","insert","isCollapsed","applyFormat","useAnchorRef","removeFormat","slice","replace","__experimentalLinkControl","LinkControl","store","blockEditorStore","useSelect","createLinkFormat","isValidHref","getFormatBoundary","link","settings","InlineLinkUI","isActive","activeAttributes","addingLink","value","onChange","speak","stopAddingLink","contentRef","richLinkTextValue","getRichTextValueFromSelection","richTextText","text","nextLinkValue","setNextLinkValue","createPageEntity","userCanCreatePages","select","getSettings","_settings","__experimentalCreatePageEntity","__experimentalUserCanCreatePages","linkValue","url","type","id","opensInNewTab","target","title","removeLink","newValue","onChangeLink","nextValue","didToggleSetting","didToggleSettingForNewLink","undefined","newUrl","linkFormat","String","opensInNewWindow","newText","toInsert","length","start","end","activeFormats","anchorRef","ref","focusOnMount","handleCreate","pageTitle","page","status","rendered","kind","createButtonText","searchTerm","mark","current","textStart","textEnd","boundary"],"mappings":"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","sourcesContent":["/**\n * WordPress dependencies\n */\nimport { useState, useRef, createInterpolateElement } from '@wordpress/element';\nimport { __, sprintf } from '@wordpress/i18n';\nimport { withSpokenMessages, Popover } from '@wordpress/components';\nimport { prependHTTP } from '@wordpress/url';\nimport {\n\tcreate,\n\tinsert,\n\tisCollapsed,\n\tapplyFormat,\n\tuseAnchorRef,\n\tremoveFormat,\n\tslice,\n\treplace,\n} from '@wordpress/rich-text';\nimport {\n\t__experimentalLinkControl as LinkControl,\n\tstore as blockEditorStore,\n} from '@wordpress/block-editor';\nimport { useSelect } from '@wordpress/data';\n\n/**\n * Internal dependencies\n */\nimport { createLinkFormat, isValidHref, getFormatBoundary } from './utils';\nimport { link as settings } from './index';\n\nfunction InlineLinkUI( {\n\tisActive,\n\tactiveAttributes,\n\taddingLink,\n\tvalue,\n\tonChange,\n\tspeak,\n\tstopAddingLink,\n\tcontentRef,\n} ) {\n\tconst richLinkTextValue = getRichTextValueFromSelection( value, isActive );\n\n\t// Get the text content minus any HTML tags.\n\tconst richTextText = richLinkTextValue.text;\n\n\t/**\n\t * Pending settings to be applied to the next link. When inserting a new\n\t * link, toggle values cannot be applied immediately, because there is not\n\t * yet a link for them to apply to. Thus, they are maintained in a state\n\t * value until the time that the link can be inserted or edited.\n\t *\n\t * @type {[Object|undefined,Function]}\n\t */\n\tconst [ nextLinkValue, setNextLinkValue ] = useState();\n\n\tconst { createPageEntity, userCanCreatePages } = useSelect( ( select ) => {\n\t\tconst { getSettings } = select( blockEditorStore );\n\t\tconst _settings = getSettings();\n\n\t\treturn {\n\t\t\tcreatePageEntity: _settings.__experimentalCreatePageEntity,\n\t\t\tuserCanCreatePages: _settings.__experimentalUserCanCreatePages,\n\t\t};\n\t}, [] );\n\n\tconst linkValue = {\n\t\turl: activeAttributes.url,\n\t\ttype: activeAttributes.type,\n\t\tid: activeAttributes.id,\n\t\topensInNewTab: activeAttributes.target === '_blank',\n\t\ttitle: richTextText,\n\t\t...nextLinkValue,\n\t};\n\n\tfunction removeLink() {\n\t\tconst newValue = removeFormat( value, 'core/link' );\n\t\tonChange( newValue );\n\t\tstopAddingLink();\n\t\tspeak( __( 'Link removed.' ), 'assertive' );\n\t}\n\n\tfunction onChangeLink( nextValue ) {\n\t\t// Merge with values from state, both for the purpose of assigning the\n\t\t// next state value, and for use in constructing the new link format if\n\t\t// the link is ready to be applied.\n\t\tnextValue = {\n\t\t\t...nextLinkValue,\n\t\t\t...nextValue,\n\t\t};\n\n\t\t// LinkControl calls `onChange` immediately upon the toggling a setting.\n\t\tconst didToggleSetting =\n\t\t\tlinkValue.opensInNewTab !== nextValue.opensInNewTab &&\n\t\t\tlinkValue.url === nextValue.url;\n\n\t\t// If change handler was called as a result of a settings change during\n\t\t// link insertion, it must be held in state until the link is ready to\n\t\t// be applied.\n\t\tconst didToggleSettingForNewLink =\n\t\t\tdidToggleSetting && nextValue.url === undefined;\n\n\t\t// If link will be assigned, the state value can be considered flushed.\n\t\t// Otherwise, persist the pending changes.\n\t\tsetNextLinkValue( didToggleSettingForNewLink ? nextValue : undefined );\n\n\t\tif ( didToggleSettingForNewLink ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst newUrl = prependHTTP( nextValue.url );\n\t\tconst linkFormat = createLinkFormat( {\n\t\t\turl: newUrl,\n\t\t\ttype: nextValue.type,\n\t\t\tid:\n\t\t\t\tnextValue.id !== undefined && nextValue.id !== null\n\t\t\t\t\t? String( nextValue.id )\n\t\t\t\t\t: undefined,\n\t\t\topensInNewWindow: nextValue.opensInNewTab,\n\t\t} );\n\n\t\tconst newText = nextValue.title || newUrl;\n\t\tif ( isCollapsed( value ) && ! isActive ) {\n\t\t\t// Scenario: we don't have any actively selected text or formats.\n\t\t\tconst toInsert = applyFormat(\n\t\t\t\tcreate( { text: newText } ),\n\t\t\t\tlinkFormat,\n\t\t\t\t0,\n\t\t\t\tnewText.length\n\t\t\t);\n\t\t\tonChange( insert( value, toInsert ) );\n\t\t} else {\n\t\t\t// Scenario: we have any active text selection or an active format\n\t\t\tlet newValue;\n\n\t\t\tif ( newText === richTextText ) {\n\t\t\t\t// If we're not updating the text then ignore\n\t\t\t\tnewValue = applyFormat( value, linkFormat );\n\t\t\t} else {\n\t\t\t\t// Create new RichText value for the new text in order that we\n\t\t\t\t// can apply formats to it.\n\t\t\t\tnewValue = create( { text: newText } );\n\n\t\t\t\t// Apply the new Link format to this new text value.\n\t\t\t\tnewValue = applyFormat(\n\t\t\t\t\tnewValue,\n\t\t\t\t\tlinkFormat,\n\t\t\t\t\t0,\n\t\t\t\t\tnewText.length\n\t\t\t\t);\n\n\t\t\t\t// Update the original (full) RichTextValue replacing the\n\t\t\t\t// target text with the *new* RichTextValue containing:\n\t\t\t\t// 1. The new text content.\n\t\t\t\t// 2. The new link format.\n\t\t\t\t// Note original formats will be lost when applying this change.\n\t\t\t\t// That is expected behaviour.\n\t\t\t\t// See: https://github.com/WordPress/gutenberg/pull/33849#issuecomment-936134179.\n\t\t\t\tnewValue = replace( value, richTextText, newValue );\n\t\t\t}\n\n\t\t\tnewValue.start = newValue.end;\n\t\t\tnewValue.activeFormats = [];\n\t\t\tonChange( newValue );\n\t\t}\n\n\t\t// Focus should only be shifted back to the formatted segment when the\n\t\t// URL is submitted.\n\t\tif ( ! didToggleSetting ) {\n\t\t\tstopAddingLink();\n\t\t}\n\n\t\tif ( ! isValidHref( newUrl ) ) {\n\t\t\tspeak(\n\t\t\t\t__(\n\t\t\t\t\t'Warning: the link has been inserted but may have errors. Please test it.'\n\t\t\t\t),\n\t\t\t\t'assertive'\n\t\t\t);\n\t\t} else if ( isActive ) {\n\t\t\tspeak( __( 'Link edited.' ), 'assertive' );\n\t\t} else {\n\t\t\tspeak( __( 'Link inserted.' ), 'assertive' );\n\t\t}\n\t}\n\n\tconst anchorRef = useAnchorRef( { ref: contentRef, value, settings } );\n\n\t// The focusOnMount prop shouldn't evolve during render of a Popover\n\t// otherwise it causes a render of the content.\n\tconst focusOnMount = useRef( addingLink ? 'firstElement' : false );\n\n\tasync function handleCreate( pageTitle ) {\n\t\tconst page = await createPageEntity( {\n\t\t\ttitle: pageTitle,\n\t\t\tstatus: 'draft',\n\t\t} );\n\n\t\treturn {\n\t\t\tid: page.id,\n\t\t\ttype: page.type,\n\t\t\ttitle: page.title.rendered,\n\t\t\turl: page.link,\n\t\t\tkind: 'post-type',\n\t\t};\n\t}\n\n\tfunction createButtonText( searchTerm ) {\n\t\treturn createInterpolateElement(\n\t\t\tsprintf(\n\t\t\t\t/* translators: %s: search term. */\n\t\t\t\t__( 'Create Page: <mark>%s</mark>' ),\n\t\t\t\tsearchTerm\n\t\t\t),\n\t\t\t{ mark: <mark /> }\n\t\t);\n\t}\n\n\treturn (\n\t\t<Popover\n\t\t\tanchorRef={ anchorRef }\n\t\t\tfocusOnMount={ focusOnMount.current }\n\t\t\tonClose={ stopAddingLink }\n\t\t\tposition=\"bottom center\"\n\t\t>\n\t\t\t<LinkControl\n\t\t\t\tvalue={ linkValue }\n\t\t\t\tonChange={ onChangeLink }\n\t\t\t\tonRemove={ removeLink }\n\t\t\t\tforceIsEditingLink={ addingLink }\n\t\t\t\thasRichPreviews\n\t\t\t\tcreateSuggestion={ createPageEntity && handleCreate }\n\t\t\t\twithCreateSuggestion={ userCanCreatePages }\n\t\t\t\tcreateSuggestionButtonText={ createButtonText }\n\t\t\t\thasTextControl\n\t\t\t/>\n\t\t</Popover>\n\t);\n}\n\nfunction getRichTextValueFromSelection( value, isActive ) {\n\t// Default to the selection ranges on the RichTextValue object.\n\tlet textStart = value.start;\n\tlet textEnd = value.end;\n\n\t// If the format is currently active then the rich text value\n\t// should always be taken from the bounds of the active format\n\t// and not the selected text.\n\tif ( isActive ) {\n\t\tconst boundary = getFormatBoundary( value, {\n\t\t\ttype: 'core/link',\n\t\t} );\n\n\t\ttextStart = boundary.start;\n\n\t\t// Text *selection* always extends +1 beyond the edge of the format.\n\t\t// We account for that here.\n\t\ttextEnd = boundary.end + 1;\n\t}\n\n\t// Get a RichTextValue containing the selected text content.\n\treturn slice( value, textStart, textEnd );\n}\n\nexport default withSpokenMessages( InlineLinkUI );\n"]}
1
+ {"version":3,"sources":["@wordpress/format-library/src/link/inline.js"],"names":["useState","useRef","createInterpolateElement","__","sprintf","withSpokenMessages","Popover","prependHTTP","create","insert","isCollapsed","applyFormat","useAnchorRef","removeFormat","slice","replace","__experimentalLinkControl","LinkControl","store","blockEditorStore","useSelect","createLinkFormat","isValidHref","getFormatBoundary","link","settings","useLinkInstanceKey","InlineLinkUI","isActive","activeAttributes","addingLink","value","onChange","speak","stopAddingLink","contentRef","richLinkTextValue","getRichTextValueFromSelection","richTextText","text","nextLinkValue","setNextLinkValue","createPageEntity","userCanCreatePages","select","getSettings","_settings","__experimentalCreatePageEntity","__experimentalUserCanCreatePages","linkValue","url","type","id","opensInNewTab","target","title","removeLink","newValue","onChangeLink","nextValue","didToggleSetting","didToggleSettingForNewLink","undefined","newUrl","linkFormat","String","opensInNewWindow","newText","toInsert","length","start","end","activeFormats","anchorRef","ref","forceRemountKey","focusOnMount","handleCreate","pageTitle","page","status","rendered","kind","createButtonText","searchTerm","mark","current","textStart","textEnd","boundary"],"mappings":"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","sourcesContent":["/**\n * WordPress dependencies\n */\nimport { useState, useRef, createInterpolateElement } from '@wordpress/element';\nimport { __, sprintf } from '@wordpress/i18n';\nimport { withSpokenMessages, Popover } from '@wordpress/components';\nimport { prependHTTP } from '@wordpress/url';\nimport {\n\tcreate,\n\tinsert,\n\tisCollapsed,\n\tapplyFormat,\n\tuseAnchorRef,\n\tremoveFormat,\n\tslice,\n\treplace,\n} from '@wordpress/rich-text';\nimport {\n\t__experimentalLinkControl as LinkControl,\n\tstore as blockEditorStore,\n} from '@wordpress/block-editor';\nimport { useSelect } from '@wordpress/data';\n\n/**\n * Internal dependencies\n */\nimport { createLinkFormat, isValidHref, getFormatBoundary } from './utils';\nimport { link as settings } from './index';\nimport useLinkInstanceKey from './use-link-instance-key';\n\nfunction InlineLinkUI( {\n\tisActive,\n\tactiveAttributes,\n\taddingLink,\n\tvalue,\n\tonChange,\n\tspeak,\n\tstopAddingLink,\n\tcontentRef,\n} ) {\n\tconst richLinkTextValue = getRichTextValueFromSelection( value, isActive );\n\n\t// Get the text content minus any HTML tags.\n\tconst richTextText = richLinkTextValue.text;\n\n\t/**\n\t * Pending settings to be applied to the next link. When inserting a new\n\t * link, toggle values cannot be applied immediately, because there is not\n\t * yet a link for them to apply to. Thus, they are maintained in a state\n\t * value until the time that the link can be inserted or edited.\n\t *\n\t * @type {[Object|undefined,Function]}\n\t */\n\tconst [ nextLinkValue, setNextLinkValue ] = useState();\n\n\tconst { createPageEntity, userCanCreatePages } = useSelect( ( select ) => {\n\t\tconst { getSettings } = select( blockEditorStore );\n\t\tconst _settings = getSettings();\n\n\t\treturn {\n\t\t\tcreatePageEntity: _settings.__experimentalCreatePageEntity,\n\t\t\tuserCanCreatePages: _settings.__experimentalUserCanCreatePages,\n\t\t};\n\t}, [] );\n\n\tconst linkValue = {\n\t\turl: activeAttributes.url,\n\t\ttype: activeAttributes.type,\n\t\tid: activeAttributes.id,\n\t\topensInNewTab: activeAttributes.target === '_blank',\n\t\ttitle: richTextText,\n\t\t...nextLinkValue,\n\t};\n\n\tfunction removeLink() {\n\t\tconst newValue = removeFormat( value, 'core/link' );\n\t\tonChange( newValue );\n\t\tstopAddingLink();\n\t\tspeak( __( 'Link removed.' ), 'assertive' );\n\t}\n\n\tfunction onChangeLink( nextValue ) {\n\t\t// Merge with values from state, both for the purpose of assigning the\n\t\t// next state value, and for use in constructing the new link format if\n\t\t// the link is ready to be applied.\n\t\tnextValue = {\n\t\t\t...nextLinkValue,\n\t\t\t...nextValue,\n\t\t};\n\n\t\t// LinkControl calls `onChange` immediately upon the toggling a setting.\n\t\tconst didToggleSetting =\n\t\t\tlinkValue.opensInNewTab !== nextValue.opensInNewTab &&\n\t\t\tlinkValue.url === nextValue.url;\n\n\t\t// If change handler was called as a result of a settings change during\n\t\t// link insertion, it must be held in state until the link is ready to\n\t\t// be applied.\n\t\tconst didToggleSettingForNewLink =\n\t\t\tdidToggleSetting && nextValue.url === undefined;\n\n\t\t// If link will be assigned, the state value can be considered flushed.\n\t\t// Otherwise, persist the pending changes.\n\t\tsetNextLinkValue( didToggleSettingForNewLink ? nextValue : undefined );\n\n\t\tif ( didToggleSettingForNewLink ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst newUrl = prependHTTP( nextValue.url );\n\t\tconst linkFormat = createLinkFormat( {\n\t\t\turl: newUrl,\n\t\t\ttype: nextValue.type,\n\t\t\tid:\n\t\t\t\tnextValue.id !== undefined && nextValue.id !== null\n\t\t\t\t\t? String( nextValue.id )\n\t\t\t\t\t: undefined,\n\t\t\topensInNewWindow: nextValue.opensInNewTab,\n\t\t} );\n\n\t\tconst newText = nextValue.title || newUrl;\n\t\tif ( isCollapsed( value ) && ! isActive ) {\n\t\t\t// Scenario: we don't have any actively selected text or formats.\n\t\t\tconst toInsert = applyFormat(\n\t\t\t\tcreate( { text: newText } ),\n\t\t\t\tlinkFormat,\n\t\t\t\t0,\n\t\t\t\tnewText.length\n\t\t\t);\n\t\t\tonChange( insert( value, toInsert ) );\n\t\t} else {\n\t\t\t// Scenario: we have any active text selection or an active format\n\t\t\tlet newValue;\n\n\t\t\tif ( newText === richTextText ) {\n\t\t\t\t// If we're not updating the text then ignore\n\t\t\t\tnewValue = applyFormat( value, linkFormat );\n\t\t\t} else {\n\t\t\t\t// Create new RichText value for the new text in order that we\n\t\t\t\t// can apply formats to it.\n\t\t\t\tnewValue = create( { text: newText } );\n\n\t\t\t\t// Apply the new Link format to this new text value.\n\t\t\t\tnewValue = applyFormat(\n\t\t\t\t\tnewValue,\n\t\t\t\t\tlinkFormat,\n\t\t\t\t\t0,\n\t\t\t\t\tnewText.length\n\t\t\t\t);\n\n\t\t\t\t// Update the original (full) RichTextValue replacing the\n\t\t\t\t// target text with the *new* RichTextValue containing:\n\t\t\t\t// 1. The new text content.\n\t\t\t\t// 2. The new link format.\n\t\t\t\t// Note original formats will be lost when applying this change.\n\t\t\t\t// That is expected behaviour.\n\t\t\t\t// See: https://github.com/WordPress/gutenberg/pull/33849#issuecomment-936134179.\n\t\t\t\tnewValue = replace( value, richTextText, newValue );\n\t\t\t}\n\n\t\t\tnewValue.start = newValue.end;\n\t\t\tnewValue.activeFormats = [];\n\t\t\tonChange( newValue );\n\t\t}\n\n\t\t// Focus should only be shifted back to the formatted segment when the\n\t\t// URL is submitted.\n\t\tif ( ! didToggleSetting ) {\n\t\t\tstopAddingLink();\n\t\t}\n\n\t\tif ( ! isValidHref( newUrl ) ) {\n\t\t\tspeak(\n\t\t\t\t__(\n\t\t\t\t\t'Warning: the link has been inserted but may have errors. Please test it.'\n\t\t\t\t),\n\t\t\t\t'assertive'\n\t\t\t);\n\t\t} else if ( isActive ) {\n\t\t\tspeak( __( 'Link edited.' ), 'assertive' );\n\t\t} else {\n\t\t\tspeak( __( 'Link inserted.' ), 'assertive' );\n\t\t}\n\t}\n\n\tconst anchorRef = useAnchorRef( { ref: contentRef, value, settings } );\n\n\t// Generate a string based key that is unique to this anchor reference.\n\t// This is used to force re-mount the LinkControl component to avoid\n\t// potential stale state bugs caused by the component not being remounted\n\t// See https://github.com/WordPress/gutenberg/pull/34742.\n\tconst forceRemountKey = useLinkInstanceKey( anchorRef );\n\n\t// The focusOnMount prop shouldn't evolve during render of a Popover\n\t// otherwise it causes a render of the content.\n\tconst focusOnMount = useRef( addingLink ? 'firstElement' : false );\n\n\tasync function handleCreate( pageTitle ) {\n\t\tconst page = await createPageEntity( {\n\t\t\ttitle: pageTitle,\n\t\t\tstatus: 'draft',\n\t\t} );\n\n\t\treturn {\n\t\t\tid: page.id,\n\t\t\ttype: page.type,\n\t\t\ttitle: page.title.rendered,\n\t\t\turl: page.link,\n\t\t\tkind: 'post-type',\n\t\t};\n\t}\n\n\tfunction createButtonText( searchTerm ) {\n\t\treturn createInterpolateElement(\n\t\t\tsprintf(\n\t\t\t\t/* translators: %s: search term. */\n\t\t\t\t__( 'Create Page: <mark>%s</mark>' ),\n\t\t\t\tsearchTerm\n\t\t\t),\n\t\t\t{ mark: <mark /> }\n\t\t);\n\t}\n\n\treturn (\n\t\t<Popover\n\t\t\tanchorRef={ anchorRef }\n\t\t\tfocusOnMount={ focusOnMount.current }\n\t\t\tonClose={ stopAddingLink }\n\t\t\tposition=\"bottom center\"\n\t\t>\n\t\t\t<LinkControl\n\t\t\t\tkey={ forceRemountKey }\n\t\t\t\tvalue={ linkValue }\n\t\t\t\tonChange={ onChangeLink }\n\t\t\t\tonRemove={ removeLink }\n\t\t\t\tforceIsEditingLink={ addingLink }\n\t\t\t\thasRichPreviews\n\t\t\t\tcreateSuggestion={ createPageEntity && handleCreate }\n\t\t\t\twithCreateSuggestion={ userCanCreatePages }\n\t\t\t\tcreateSuggestionButtonText={ createButtonText }\n\t\t\t\thasTextControl\n\t\t\t/>\n\t\t</Popover>\n\t);\n}\n\nfunction getRichTextValueFromSelection( value, isActive ) {\n\t// Default to the selection ranges on the RichTextValue object.\n\tlet textStart = value.start;\n\tlet textEnd = value.end;\n\n\t// If the format is currently active then the rich text value\n\t// should always be taken from the bounds of the active format\n\t// and not the selected text.\n\tif ( isActive ) {\n\t\tconst boundary = getFormatBoundary( value, {\n\t\t\ttype: 'core/link',\n\t\t} );\n\n\t\ttextStart = boundary.start;\n\n\t\t// Text *selection* always extends +1 beyond the edge of the format.\n\t\t// We account for that here.\n\t\ttextEnd = boundary.end + 1;\n\t}\n\n\t// Get a RichTextValue containing the selected text content.\n\treturn slice( value, textStart, textEnd );\n}\n\nexport default withSpokenMessages( InlineLinkUI );\n"]}
@@ -0,0 +1,29 @@
1
+ // Weakly referenced map allows unused ids to be garbage collected.
2
+ const weakMap = new WeakMap(); // Incrementing zero-based ID value
3
+
4
+ let id = -1;
5
+ const prefix = 'link-control-instance';
6
+
7
+ function getKey(_id) {
8
+ return `${prefix}-${_id}`;
9
+ }
10
+ /**
11
+ * Builds a unique link control key for the given object reference.
12
+ *
13
+ * @param {Object} instance an unique object reference specific to this link control instance.
14
+ * @return {string} the unique key to use for this link control.
15
+ */
16
+
17
+
18
+ function useLinkInstanceKey(instance) {
19
+ if (weakMap.has(instance)) {
20
+ return getKey(weakMap.get(instance));
21
+ }
22
+
23
+ id += 1;
24
+ weakMap.set(instance, id);
25
+ return getKey(id);
26
+ }
27
+
28
+ export default useLinkInstanceKey;
29
+ //# sourceMappingURL=use-link-instance-key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["@wordpress/format-library/src/link/use-link-instance-key.js"],"names":["weakMap","WeakMap","id","prefix","getKey","_id","useLinkInstanceKey","instance","has","get","set"],"mappings":"AAAA;AACA,MAAMA,OAAO,GAAG,IAAIC,OAAJ,EAAhB,C,CAEA;;AACA,IAAIC,EAAE,GAAG,CAAC,CAAV;AAEA,MAAMC,MAAM,GAAG,uBAAf;;AAEA,SAASC,MAAT,CAAiBC,GAAjB,EAAuB;AACtB,SAAQ,GAAGF,MAAQ,IAAIE,GAAK,EAA5B;AACA;AAED;AACA;AACA;AACA;AACA;AACA;;;AACA,SAASC,kBAAT,CAA6BC,QAA7B,EAAwC;AACvC,MAAKP,OAAO,CAACQ,GAAR,CAAaD,QAAb,CAAL,EAA+B;AAC9B,WAAOH,MAAM,CAAEJ,OAAO,CAACS,GAAR,CAAaF,QAAb,CAAF,CAAb;AACA;;AAEDL,EAAAA,EAAE,IAAI,CAAN;AAEAF,EAAAA,OAAO,CAACU,GAAR,CAAaH,QAAb,EAAuBL,EAAvB;AAEA,SAAOE,MAAM,CAAEF,EAAF,CAAb;AACA;;AAED,eAAeI,kBAAf","sourcesContent":["// Weakly referenced map allows unused ids to be garbage collected.\nconst weakMap = new WeakMap();\n\n// Incrementing zero-based ID value\nlet id = -1;\n\nconst prefix = 'link-control-instance';\n\nfunction getKey( _id ) {\n\treturn `${ prefix }-${ _id }`;\n}\n\n/**\n * Builds a unique link control key for the given object reference.\n *\n * @param {Object} instance an unique object reference specific to this link control instance.\n * @return {string} the unique key to use for this link control.\n */\nfunction useLinkInstanceKey( instance ) {\n\tif ( weakMap.has( instance ) ) {\n\t\treturn getKey( weakMap.get( instance ) );\n\t}\n\n\tid += 1;\n\n\tweakMap.set( instance, id );\n\n\treturn getKey( id );\n}\n\nexport default useLinkInstanceKey;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/format-library",
3
- "version": "3.0.5",
3
+ "version": "3.0.6",
4
4
  "description": "Format library for the WordPress editor.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -27,7 +27,7 @@
27
27
  "dependencies": {
28
28
  "@babel/runtime": "^7.13.10",
29
29
  "@wordpress/a11y": "^3.2.3",
30
- "@wordpress/block-editor": "^8.0.0",
30
+ "@wordpress/block-editor": "^8.0.1",
31
31
  "@wordpress/components": "^19.0.1",
32
32
  "@wordpress/compose": "^5.0.5",
33
33
  "@wordpress/data": "^6.1.3",
@@ -44,5 +44,5 @@
44
44
  "publishConfig": {
45
45
  "access": "public"
46
46
  },
47
- "gitHead": "393c2b5533837fd637e998d23f0124c081a10df0"
47
+ "gitHead": "f89b63995376fe6efe920d858b48268b510920e1"
48
48
  }
@@ -26,6 +26,7 @@ import { useSelect } from '@wordpress/data';
26
26
  */
27
27
  import { createLinkFormat, isValidHref, getFormatBoundary } from './utils';
28
28
  import { link as settings } from './index';
29
+ import useLinkInstanceKey from './use-link-instance-key';
29
30
 
30
31
  function InlineLinkUI( {
31
32
  isActive,
@@ -184,6 +185,12 @@ function InlineLinkUI( {
184
185
 
185
186
  const anchorRef = useAnchorRef( { ref: contentRef, value, settings } );
186
187
 
188
+ // Generate a string based key that is unique to this anchor reference.
189
+ // This is used to force re-mount the LinkControl component to avoid
190
+ // potential stale state bugs caused by the component not being remounted
191
+ // See https://github.com/WordPress/gutenberg/pull/34742.
192
+ const forceRemountKey = useLinkInstanceKey( anchorRef );
193
+
187
194
  // The focusOnMount prop shouldn't evolve during render of a Popover
188
195
  // otherwise it causes a render of the content.
189
196
  const focusOnMount = useRef( addingLink ? 'firstElement' : false );
@@ -222,6 +229,7 @@ function InlineLinkUI( {
222
229
  position="bottom center"
223
230
  >
224
231
  <LinkControl
232
+ key={ forceRemountKey }
225
233
  value={ linkValue }
226
234
  onChange={ onChangeLink }
227
235
  onRemove={ removeLink }
@@ -0,0 +1,31 @@
1
+ // Weakly referenced map allows unused ids to be garbage collected.
2
+ const weakMap = new WeakMap();
3
+
4
+ // Incrementing zero-based ID value
5
+ let id = -1;
6
+
7
+ const prefix = 'link-control-instance';
8
+
9
+ function getKey( _id ) {
10
+ return `${ prefix }-${ _id }`;
11
+ }
12
+
13
+ /**
14
+ * Builds a unique link control key for the given object reference.
15
+ *
16
+ * @param {Object} instance an unique object reference specific to this link control instance.
17
+ * @return {string} the unique key to use for this link control.
18
+ */
19
+ function useLinkInstanceKey( instance ) {
20
+ if ( weakMap.has( instance ) ) {
21
+ return getKey( weakMap.get( instance ) );
22
+ }
23
+
24
+ id += 1;
25
+
26
+ weakMap.set( instance, id );
27
+
28
+ return getKey( id );
29
+ }
30
+
31
+ export default useLinkInstanceKey;