Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Opens in new Tab control into Link Preview #53566

Merged
merged 9 commits into from
Aug 15, 2023
25 changes: 24 additions & 1 deletion packages/block-editor/src/components/link-control/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,27 @@ function LinkControl( {
onEditClick={ () => setIsEditingLink( true ) }
hasRichPreviews={ hasRichPreviews }
hasUnlinkControl={ shownUnlinkControl }
additionalControls={ () => {
// Expose the "Opens in new tab" settings in the preview
// as it is the most common setting to change.
if (
settings?.find(
( setting ) => setting.id === 'opensInNewTab'
)
) {
return (
<LinkSettings
value={ internalControlValue }
settings={ settings }
onChange={ ( { opensInNewTab } ) => {
onChange( {
opensInNewTab,
} );
} }
/>
);
}
} }
onRemove={ () => {
onRemove();
setIsEditingLink( true );
Expand All @@ -424,7 +445,9 @@ function LinkControl( {
>
<LinkSettings
value={ internalControlValue }
settings={ settings }
settings={ settings?.filter(
( { id } ) => id === 'opensInNewTab'
) }
onChange={ createSetInternalSettingValueHandler(
settingsKeys
) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export default function LinkPreview( {
hasRichPreviews = false,
hasUnlinkControl = false,
onRemove,
additionalControls,
} ) {
// Avoid fetching if rich previews are not desired.
const showRichPreviews = hasRichPreviews ? value?.url : null;
Expand Down Expand Up @@ -167,6 +168,8 @@ export default function LinkPreview( {
) }
</div>
) }

{ additionalControls && additionalControls() }
</div>
);
}
45 changes: 10 additions & 35 deletions packages/format-library/src/link/inline.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* WordPress dependencies
*/
import { useState, useRef, createInterpolateElement } from '@wordpress/element';
import { useRef, createInterpolateElement } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';
import { speak } from '@wordpress/a11y';
import { Popover } from '@wordpress/components';
Expand Down Expand Up @@ -45,16 +45,6 @@ function InlineLinkUI( {
// Get the text content minus any HTML tags.
const richTextText = richLinkTextValue.text;

/**
* Pending settings to be applied to the next link. When inserting a new
* link, toggle values cannot be applied immediately, because there is not
* yet a link for them to apply to. Thus, they are maintained in a state
* value until the time that the link can be inserted or edited.
*
* @type {[Object|undefined,Function]}
*/
const [ nextLinkValue, setNextLinkValue ] = useState();

const { createPageEntity, userCanCreatePages } = useSelect( ( select ) => {
const { getSettings } = select( blockEditorStore );
const _settings = getSettings();
Expand All @@ -71,7 +61,6 @@ function InlineLinkUI( {
id: activeAttributes.id,
opensInNewTab: activeAttributes.target === '_blank',
title: richTextText,
...nextLinkValue,
};

function removeLink() {
Expand All @@ -82,32 +71,18 @@ function InlineLinkUI( {
}

function onChangeLink( nextValue ) {
getdave marked this conversation as resolved.
Show resolved Hide resolved
// Merge with values from state, both for the purpose of assigning the
// next state value, and for use in constructing the new link format if
// the link is ready to be applied.
nextValue = {
...nextLinkValue,
...nextValue,
};

// LinkControl calls `onChange` immediately upon the toggling a setting.
// Before merging the next value with the current link value, check if
// the setting was toggled.
const didToggleSetting =
linkValue.opensInNewTab !== nextValue.opensInNewTab &&
linkValue.url === nextValue.url;

// If change handler was called as a result of a settings change during
// link insertion, it must be held in state until the link is ready to
// be applied.
const didToggleSettingForNewLink =
didToggleSetting && nextValue.url === undefined;
nextValue.url === undefined;

// If link will be assigned, the state value can be considered flushed.
// Otherwise, persist the pending changes.
setNextLinkValue( didToggleSettingForNewLink ? nextValue : undefined );

if ( didToggleSettingForNewLink ) {
return;
}
// Merge the next value with the current link value.
nextValue = {
...linkValue,
...nextValue,
};

const newUrl = prependHTTP( nextValue.url );
const linkFormat = createLinkFormat( {
Expand Down Expand Up @@ -192,7 +167,7 @@ function InlineLinkUI( {
// Focus should only be shifted back to the formatted segment when the
// URL is submitted.
if ( ! didToggleSetting ) {
stopAddingLink();
// stopAddingLink();
}

if ( ! isValidHref( newUrl ) ) {
Expand Down