Edit File by line

Deprecated: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in /home/sportsfever/public_html/filemanger/function.php on line 93

Warning: Undefined array key "page_file_edit_line" in /home/sportsfever/public_html/filemanger/edit_text_line.php on line 32
/home/sportsfe.../httpdocs/clone/wp-inclu.../js/dist
File: format-library.js
return false;
[500] Fix | Delete
}
[501] Fix | Delete
return true;
[502] Fix | Delete
}
[503] Fix | Delete
[504] Fix | Delete
/**
[505] Fix | Delete
* Generates the format object that will be applied to the link text.
[506] Fix | Delete
*
[507] Fix | Delete
* @param {Object} options
[508] Fix | Delete
* @param {string} options.url The href of the link.
[509] Fix | Delete
* @param {string} options.type The type of the link.
[510] Fix | Delete
* @param {string} options.id The ID of the link.
[511] Fix | Delete
* @param {boolean} options.opensInNewWindow Whether this link will open in a new window.
[512] Fix | Delete
* @param {boolean} options.nofollow Whether this link is marked as no follow relationship.
[513] Fix | Delete
* @return {Object} The final format object.
[514] Fix | Delete
*/
[515] Fix | Delete
function createLinkFormat({
[516] Fix | Delete
url,
[517] Fix | Delete
type,
[518] Fix | Delete
id,
[519] Fix | Delete
opensInNewWindow,
[520] Fix | Delete
nofollow
[521] Fix | Delete
}) {
[522] Fix | Delete
const format = {
[523] Fix | Delete
type: 'core/link',
[524] Fix | Delete
attributes: {
[525] Fix | Delete
url
[526] Fix | Delete
}
[527] Fix | Delete
};
[528] Fix | Delete
if (type) {
[529] Fix | Delete
format.attributes.type = type;
[530] Fix | Delete
}
[531] Fix | Delete
if (id) {
[532] Fix | Delete
format.attributes.id = id;
[533] Fix | Delete
}
[534] Fix | Delete
if (opensInNewWindow) {
[535] Fix | Delete
format.attributes.target = '_blank';
[536] Fix | Delete
format.attributes.rel = format.attributes.rel ? format.attributes.rel + ' noreferrer noopener' : 'noreferrer noopener';
[537] Fix | Delete
}
[538] Fix | Delete
if (nofollow) {
[539] Fix | Delete
format.attributes.rel = format.attributes.rel ? format.attributes.rel + ' nofollow' : 'nofollow';
[540] Fix | Delete
}
[541] Fix | Delete
return format;
[542] Fix | Delete
}
[543] Fix | Delete
[544] Fix | Delete
/* eslint-disable jsdoc/no-undefined-types */
[545] Fix | Delete
/**
[546] Fix | Delete
* Get the start and end boundaries of a given format from a rich text value.
[547] Fix | Delete
*
[548] Fix | Delete
*
[549] Fix | Delete
* @param {RichTextValue} value the rich text value to interrogate.
[550] Fix | Delete
* @param {string} format the identifier for the target format (e.g. `core/link`, `core/bold`).
[551] Fix | Delete
* @param {number?} startIndex optional startIndex to seek from.
[552] Fix | Delete
* @param {number?} endIndex optional endIndex to seek from.
[553] Fix | Delete
* @return {Object} object containing start and end values for the given format.
[554] Fix | Delete
*/
[555] Fix | Delete
/* eslint-enable jsdoc/no-undefined-types */
[556] Fix | Delete
function getFormatBoundary(value, format, startIndex = value.start, endIndex = value.end) {
[557] Fix | Delete
const EMPTY_BOUNDARIES = {
[558] Fix | Delete
start: null,
[559] Fix | Delete
end: null
[560] Fix | Delete
};
[561] Fix | Delete
const {
[562] Fix | Delete
formats
[563] Fix | Delete
} = value;
[564] Fix | Delete
let targetFormat;
[565] Fix | Delete
let initialIndex;
[566] Fix | Delete
if (!formats?.length) {
[567] Fix | Delete
return EMPTY_BOUNDARIES;
[568] Fix | Delete
}
[569] Fix | Delete
[570] Fix | Delete
// Clone formats to avoid modifying source formats.
[571] Fix | Delete
const newFormats = formats.slice();
[572] Fix | Delete
const formatAtStart = newFormats[startIndex]?.find(({
[573] Fix | Delete
type
[574] Fix | Delete
}) => type === format.type);
[575] Fix | Delete
const formatAtEnd = newFormats[endIndex]?.find(({
[576] Fix | Delete
type
[577] Fix | Delete
}) => type === format.type);
[578] Fix | Delete
const formatAtEndMinusOne = newFormats[endIndex - 1]?.find(({
[579] Fix | Delete
type
[580] Fix | Delete
}) => type === format.type);
[581] Fix | Delete
if (!!formatAtStart) {
[582] Fix | Delete
// Set values to conform to "start"
[583] Fix | Delete
targetFormat = formatAtStart;
[584] Fix | Delete
initialIndex = startIndex;
[585] Fix | Delete
} else if (!!formatAtEnd) {
[586] Fix | Delete
// Set values to conform to "end"
[587] Fix | Delete
targetFormat = formatAtEnd;
[588] Fix | Delete
initialIndex = endIndex;
[589] Fix | Delete
} else if (!!formatAtEndMinusOne) {
[590] Fix | Delete
// This is an edge case which will occur if you create a format, then place
[591] Fix | Delete
// the caret just before the format and hit the back ARROW key. The resulting
[592] Fix | Delete
// value object will have start and end +1 beyond the edge of the format boundary.
[593] Fix | Delete
targetFormat = formatAtEndMinusOne;
[594] Fix | Delete
initialIndex = endIndex - 1;
[595] Fix | Delete
} else {
[596] Fix | Delete
return EMPTY_BOUNDARIES;
[597] Fix | Delete
}
[598] Fix | Delete
const index = newFormats[initialIndex].indexOf(targetFormat);
[599] Fix | Delete
const walkingArgs = [newFormats, initialIndex, targetFormat, index];
[600] Fix | Delete
[601] Fix | Delete
// Walk the startIndex "backwards" to the leading "edge" of the matching format.
[602] Fix | Delete
startIndex = walkToStart(...walkingArgs);
[603] Fix | Delete
[604] Fix | Delete
// Walk the endIndex "forwards" until the trailing "edge" of the matching format.
[605] Fix | Delete
endIndex = walkToEnd(...walkingArgs);
[606] Fix | Delete
[607] Fix | Delete
// Safe guard: start index cannot be less than 0.
[608] Fix | Delete
startIndex = startIndex < 0 ? 0 : startIndex;
[609] Fix | Delete
[610] Fix | Delete
// // Return the indicies of the "edges" as the boundaries.
[611] Fix | Delete
return {
[612] Fix | Delete
start: startIndex,
[613] Fix | Delete
end: endIndex
[614] Fix | Delete
};
[615] Fix | Delete
}
[616] Fix | Delete
[617] Fix | Delete
/**
[618] Fix | Delete
* Walks forwards/backwards towards the boundary of a given format within an
[619] Fix | Delete
* array of format objects. Returns the index of the boundary.
[620] Fix | Delete
*
[621] Fix | Delete
* @param {Array} formats the formats to search for the given format type.
[622] Fix | Delete
* @param {number} initialIndex the starting index from which to walk.
[623] Fix | Delete
* @param {Object} targetFormatRef a reference to the format type object being sought.
[624] Fix | Delete
* @param {number} formatIndex the index at which we expect the target format object to be.
[625] Fix | Delete
* @param {string} direction either 'forwards' or 'backwards' to indicate the direction.
[626] Fix | Delete
* @return {number} the index of the boundary of the given format.
[627] Fix | Delete
*/
[628] Fix | Delete
function walkToBoundary(formats, initialIndex, targetFormatRef, formatIndex, direction) {
[629] Fix | Delete
let index = initialIndex;
[630] Fix | Delete
const directions = {
[631] Fix | Delete
forwards: 1,
[632] Fix | Delete
backwards: -1
[633] Fix | Delete
};
[634] Fix | Delete
const directionIncrement = directions[direction] || 1; // invalid direction arg default to forwards
[635] Fix | Delete
const inverseDirectionIncrement = directionIncrement * -1;
[636] Fix | Delete
while (formats[index] && formats[index][formatIndex] === targetFormatRef) {
[637] Fix | Delete
// Increment/decrement in the direction of operation.
[638] Fix | Delete
index = index + directionIncrement;
[639] Fix | Delete
}
[640] Fix | Delete
[641] Fix | Delete
// Restore by one in inverse direction of operation
[642] Fix | Delete
// to avoid out of bounds.
[643] Fix | Delete
index = index + inverseDirectionIncrement;
[644] Fix | Delete
return index;
[645] Fix | Delete
}
[646] Fix | Delete
const partialRight = (fn, ...partialArgs) => (...args) => fn(...args, ...partialArgs);
[647] Fix | Delete
const walkToStart = partialRight(walkToBoundary, 'backwards');
[648] Fix | Delete
const walkToEnd = partialRight(walkToBoundary, 'forwards');
[649] Fix | Delete
[650] Fix | Delete
;// CONCATENATED MODULE: ./node_modules/@wordpress/format-library/build-module/link/inline.js
[651] Fix | Delete
/**
[652] Fix | Delete
* WordPress dependencies
[653] Fix | Delete
*/
[654] Fix | Delete
[655] Fix | Delete
[656] Fix | Delete
[657] Fix | Delete
[658] Fix | Delete
[659] Fix | Delete
[660] Fix | Delete
[661] Fix | Delete
[662] Fix | Delete
[663] Fix | Delete
/**
[664] Fix | Delete
* Internal dependencies
[665] Fix | Delete
*/
[666] Fix | Delete
[667] Fix | Delete
[668] Fix | Delete
[669] Fix | Delete
const LINK_SETTINGS = [...external_wp_blockEditor_namespaceObject.__experimentalLinkControl.DEFAULT_LINK_SETTINGS, {
[670] Fix | Delete
id: 'nofollow',
[671] Fix | Delete
title: (0,external_wp_i18n_namespaceObject.__)('Mark as nofollow')
[672] Fix | Delete
}];
[673] Fix | Delete
function InlineLinkUI({
[674] Fix | Delete
isActive,
[675] Fix | Delete
activeAttributes,
[676] Fix | Delete
value,
[677] Fix | Delete
onChange,
[678] Fix | Delete
onFocusOutside,
[679] Fix | Delete
stopAddingLink,
[680] Fix | Delete
contentRef,
[681] Fix | Delete
focusOnMount
[682] Fix | Delete
}) {
[683] Fix | Delete
const richLinkTextValue = getRichTextValueFromSelection(value, isActive);
[684] Fix | Delete
[685] Fix | Delete
// Get the text content minus any HTML tags.
[686] Fix | Delete
const richTextText = richLinkTextValue.text;
[687] Fix | Delete
const {
[688] Fix | Delete
selectionChange
[689] Fix | Delete
} = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_blockEditor_namespaceObject.store);
[690] Fix | Delete
const {
[691] Fix | Delete
createPageEntity,
[692] Fix | Delete
userCanCreatePages,
[693] Fix | Delete
selectionStart
[694] Fix | Delete
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
[695] Fix | Delete
const {
[696] Fix | Delete
getSettings,
[697] Fix | Delete
getSelectionStart
[698] Fix | Delete
} = select(external_wp_blockEditor_namespaceObject.store);
[699] Fix | Delete
const _settings = getSettings();
[700] Fix | Delete
return {
[701] Fix | Delete
createPageEntity: _settings.__experimentalCreatePageEntity,
[702] Fix | Delete
userCanCreatePages: _settings.__experimentalUserCanCreatePages,
[703] Fix | Delete
selectionStart: getSelectionStart()
[704] Fix | Delete
};
[705] Fix | Delete
}, []);
[706] Fix | Delete
const linkValue = (0,external_wp_element_namespaceObject.useMemo)(() => ({
[707] Fix | Delete
url: activeAttributes.url,
[708] Fix | Delete
type: activeAttributes.type,
[709] Fix | Delete
id: activeAttributes.id,
[710] Fix | Delete
opensInNewTab: activeAttributes.target === '_blank',
[711] Fix | Delete
nofollow: activeAttributes.rel?.includes('nofollow'),
[712] Fix | Delete
title: richTextText
[713] Fix | Delete
}), [activeAttributes.id, activeAttributes.rel, activeAttributes.target, activeAttributes.type, activeAttributes.url, richTextText]);
[714] Fix | Delete
function removeLink() {
[715] Fix | Delete
const newValue = (0,external_wp_richText_namespaceObject.removeFormat)(value, 'core/link');
[716] Fix | Delete
onChange(newValue);
[717] Fix | Delete
stopAddingLink();
[718] Fix | Delete
(0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.__)('Link removed.'), 'assertive');
[719] Fix | Delete
}
[720] Fix | Delete
function onChangeLink(nextValue) {
[721] Fix | Delete
const hasLink = linkValue?.url;
[722] Fix | Delete
const isNewLink = !hasLink;
[723] Fix | Delete
[724] Fix | Delete
// Merge the next value with the current link value.
[725] Fix | Delete
nextValue = {
[726] Fix | Delete
...linkValue,
[727] Fix | Delete
...nextValue
[728] Fix | Delete
};
[729] Fix | Delete
const newUrl = (0,external_wp_url_namespaceObject.prependHTTP)(nextValue.url);
[730] Fix | Delete
const linkFormat = createLinkFormat({
[731] Fix | Delete
url: newUrl,
[732] Fix | Delete
type: nextValue.type,
[733] Fix | Delete
id: nextValue.id !== undefined && nextValue.id !== null ? String(nextValue.id) : undefined,
[734] Fix | Delete
opensInNewWindow: nextValue.opensInNewTab,
[735] Fix | Delete
nofollow: nextValue.nofollow
[736] Fix | Delete
});
[737] Fix | Delete
const newText = nextValue.title || newUrl;
[738] Fix | Delete
[739] Fix | Delete
// Scenario: we have any active text selection or an active format.
[740] Fix | Delete
let newValue;
[741] Fix | Delete
if ((0,external_wp_richText_namespaceObject.isCollapsed)(value) && !isActive) {
[742] Fix | Delete
// Scenario: we don't have any actively selected text or formats.
[743] Fix | Delete
const inserted = (0,external_wp_richText_namespaceObject.insert)(value, newText);
[744] Fix | Delete
newValue = (0,external_wp_richText_namespaceObject.applyFormat)(inserted, linkFormat, value.start, value.start + newText.length);
[745] Fix | Delete
onChange(newValue);
[746] Fix | Delete
[747] Fix | Delete
// Close the Link UI.
[748] Fix | Delete
stopAddingLink();
[749] Fix | Delete
[750] Fix | Delete
// Move the selection to the end of the inserted link outside of the format boundary
[751] Fix | Delete
// so the user can continue typing after the link.
[752] Fix | Delete
selectionChange({
[753] Fix | Delete
clientId: selectionStart.clientId,
[754] Fix | Delete
identifier: selectionStart.attributeKey,
[755] Fix | Delete
start: value.start + newText.length + 1
[756] Fix | Delete
});
[757] Fix | Delete
return;
[758] Fix | Delete
} else if (newText === richTextText) {
[759] Fix | Delete
newValue = (0,external_wp_richText_namespaceObject.applyFormat)(value, linkFormat);
[760] Fix | Delete
} else {
[761] Fix | Delete
// Scenario: Editing an existing link.
[762] Fix | Delete
[763] Fix | Delete
// Create new RichText value for the new text in order that we
[764] Fix | Delete
// can apply formats to it.
[765] Fix | Delete
newValue = (0,external_wp_richText_namespaceObject.create)({
[766] Fix | Delete
text: newText
[767] Fix | Delete
});
[768] Fix | Delete
// Apply the new Link format to this new text value.
[769] Fix | Delete
newValue = (0,external_wp_richText_namespaceObject.applyFormat)(newValue, linkFormat, 0, newText.length);
[770] Fix | Delete
[771] Fix | Delete
// Get the boundaries of the active link format.
[772] Fix | Delete
const boundary = getFormatBoundary(value, {
[773] Fix | Delete
type: 'core/link'
[774] Fix | Delete
});
[775] Fix | Delete
[776] Fix | Delete
// Split the value at the start of the active link format.
[777] Fix | Delete
// Passing "start" as the 3rd parameter is required to ensure
[778] Fix | Delete
// the second half of the split value is split at the format's
[779] Fix | Delete
// start boundary and avoids relying on the value's "end" property
[780] Fix | Delete
// which may not correspond correctly.
[781] Fix | Delete
const [valBefore, valAfter] = (0,external_wp_richText_namespaceObject.split)(value, boundary.start, boundary.start);
[782] Fix | Delete
[783] Fix | Delete
// Update the original (full) RichTextValue replacing the
[784] Fix | Delete
// target text with the *new* RichTextValue containing:
[785] Fix | Delete
// 1. The new text content.
[786] Fix | Delete
// 2. The new link format.
[787] Fix | Delete
// As "replace" will operate on the first match only, it is
[788] Fix | Delete
// run only against the second half of the value which was
[789] Fix | Delete
// split at the active format's boundary. This avoids a bug
[790] Fix | Delete
// with incorrectly targetted replacements.
[791] Fix | Delete
// See: https://github.com/WordPress/gutenberg/issues/41771.
[792] Fix | Delete
// Note original formats will be lost when applying this change.
[793] Fix | Delete
// That is expected behaviour.
[794] Fix | Delete
// See: https://github.com/WordPress/gutenberg/pull/33849#issuecomment-936134179.
[795] Fix | Delete
const newValAfter = (0,external_wp_richText_namespaceObject.replace)(valAfter, richTextText, newValue);
[796] Fix | Delete
newValue = (0,external_wp_richText_namespaceObject.concat)(valBefore, newValAfter);
[797] Fix | Delete
}
[798] Fix | Delete
onChange(newValue);
[799] Fix | Delete
[800] Fix | Delete
// Focus should only be returned to the rich text on submit if this link is not
[801] Fix | Delete
// being created for the first time. If it is then focus should remain within the
[802] Fix | Delete
// Link UI because it should remain open for the user to modify the link they have
[803] Fix | Delete
// just created.
[804] Fix | Delete
if (!isNewLink) {
[805] Fix | Delete
stopAddingLink();
[806] Fix | Delete
}
[807] Fix | Delete
if (!isValidHref(newUrl)) {
[808] Fix | Delete
(0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.__)('Warning: the link has been inserted but may have errors. Please test it.'), 'assertive');
[809] Fix | Delete
} else if (isActive) {
[810] Fix | Delete
(0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.__)('Link edited.'), 'assertive');
[811] Fix | Delete
} else {
[812] Fix | Delete
(0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.__)('Link inserted.'), 'assertive');
[813] Fix | Delete
}
[814] Fix | Delete
}
[815] Fix | Delete
const popoverAnchor = (0,external_wp_richText_namespaceObject.useAnchor)({
[816] Fix | Delete
editableContentElement: contentRef.current,
[817] Fix | Delete
settings: {
[818] Fix | Delete
...build_module_link_link,
[819] Fix | Delete
isActive
[820] Fix | Delete
}
[821] Fix | Delete
});
[822] Fix | Delete
async function handleCreate(pageTitle) {
[823] Fix | Delete
const page = await createPageEntity({
[824] Fix | Delete
title: pageTitle,
[825] Fix | Delete
status: 'draft'
[826] Fix | Delete
});
[827] Fix | Delete
return {
[828] Fix | Delete
id: page.id,
[829] Fix | Delete
type: page.type,
[830] Fix | Delete
title: page.title.rendered,
[831] Fix | Delete
url: page.link,
[832] Fix | Delete
kind: 'post-type'
[833] Fix | Delete
};
[834] Fix | Delete
}
[835] Fix | Delete
function createButtonText(searchTerm) {
[836] Fix | Delete
return (0,external_wp_element_namespaceObject.createInterpolateElement)((0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %s: search term. */
[837] Fix | Delete
(0,external_wp_i18n_namespaceObject.__)('Create page: <mark>%s</mark>'), searchTerm), {
[838] Fix | Delete
mark: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("mark", {})
[839] Fix | Delete
});
[840] Fix | Delete
}
[841] Fix | Delete
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Popover, {
[842] Fix | Delete
anchor: popoverAnchor,
[843] Fix | Delete
animate: false,
[844] Fix | Delete
onClose: stopAddingLink,
[845] Fix | Delete
onFocusOutside: onFocusOutside,
[846] Fix | Delete
placement: "bottom",
[847] Fix | Delete
offset: 8,
[848] Fix | Delete
shift: true,
[849] Fix | Delete
focusOnMount: focusOnMount,
[850] Fix | Delete
constrainTabbing: true,
[851] Fix | Delete
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_blockEditor_namespaceObject.__experimentalLinkControl, {
[852] Fix | Delete
value: linkValue,
[853] Fix | Delete
onChange: onChangeLink,
[854] Fix | Delete
onRemove: removeLink,
[855] Fix | Delete
hasRichPreviews: true,
[856] Fix | Delete
createSuggestion: createPageEntity && handleCreate,
[857] Fix | Delete
withCreateSuggestion: userCanCreatePages,
[858] Fix | Delete
createSuggestionButtonText: createButtonText,
[859] Fix | Delete
hasTextControl: true,
[860] Fix | Delete
settings: LINK_SETTINGS,
[861] Fix | Delete
showInitialSuggestions: true,
[862] Fix | Delete
suggestionsQuery: {
[863] Fix | Delete
// always show Pages as initial suggestions
[864] Fix | Delete
initialSuggestionsSearchOptions: {
[865] Fix | Delete
type: 'post',
[866] Fix | Delete
subtype: 'page',
[867] Fix | Delete
perPage: 20
[868] Fix | Delete
}
[869] Fix | Delete
}
[870] Fix | Delete
})
[871] Fix | Delete
});
[872] Fix | Delete
}
[873] Fix | Delete
function getRichTextValueFromSelection(value, isActive) {
[874] Fix | Delete
// Default to the selection ranges on the RichTextValue object.
[875] Fix | Delete
let textStart = value.start;
[876] Fix | Delete
let textEnd = value.end;
[877] Fix | Delete
[878] Fix | Delete
// If the format is currently active then the rich text value
[879] Fix | Delete
// should always be taken from the bounds of the active format
[880] Fix | Delete
// and not the selected text.
[881] Fix | Delete
if (isActive) {
[882] Fix | Delete
const boundary = getFormatBoundary(value, {
[883] Fix | Delete
type: 'core/link'
[884] Fix | Delete
});
[885] Fix | Delete
textStart = boundary.start;
[886] Fix | Delete
[887] Fix | Delete
// Text *selection* always extends +1 beyond the edge of the format.
[888] Fix | Delete
// We account for that here.
[889] Fix | Delete
textEnd = boundary.end + 1;
[890] Fix | Delete
}
[891] Fix | Delete
[892] Fix | Delete
// Get a RichTextValue containing the selected text content.
[893] Fix | Delete
return (0,external_wp_richText_namespaceObject.slice)(value, textStart, textEnd);
[894] Fix | Delete
}
[895] Fix | Delete
/* harmony default export */ const inline = (InlineLinkUI);
[896] Fix | Delete
[897] Fix | Delete
;// CONCATENATED MODULE: ./node_modules/@wordpress/format-library/build-module/link/index.js
[898] Fix | Delete
/**
[899] Fix | Delete
* WordPress dependencies
[900] Fix | Delete
*/
[901] Fix | Delete
[902] Fix | Delete
[903] Fix | Delete
[904] Fix | Delete
[905] Fix | Delete
[906] Fix | Delete
[907] Fix | Delete
[908] Fix | Delete
[909] Fix | Delete
[910] Fix | Delete
/**
[911] Fix | Delete
* Internal dependencies
[912] Fix | Delete
*/
[913] Fix | Delete
[914] Fix | Delete
[915] Fix | Delete
[916] Fix | Delete
[917] Fix | Delete
[918] Fix | Delete
const link_name = 'core/link';
[919] Fix | Delete
const link_title = (0,external_wp_i18n_namespaceObject.__)('Link');
[920] Fix | Delete
function link_Edit({
[921] Fix | Delete
isActive,
[922] Fix | Delete
activeAttributes,
[923] Fix | Delete
value,
[924] Fix | Delete
onChange,
[925] Fix | Delete
onFocus,
[926] Fix | Delete
contentRef
[927] Fix | Delete
}) {
[928] Fix | Delete
const [addingLink, setAddingLink] = (0,external_wp_element_namespaceObject.useState)(false);
[929] Fix | Delete
[930] Fix | Delete
// We only need to store the button element that opened the popover. We can ignore the other states, as they will be handled by the onFocus prop to return to the rich text field.
[931] Fix | Delete
const [openedBy, setOpenedBy] = (0,external_wp_element_namespaceObject.useState)(null);
[932] Fix | Delete
(0,external_wp_element_namespaceObject.useEffect)(() => {
[933] Fix | Delete
// When the link becomes inactive (i.e. isActive is false), reset the editingLink state
[934] Fix | Delete
// and the creatingLink state. This means that if the Link UI is displayed and the link
[935] Fix | Delete
// becomes inactive (e.g. used arrow keys to move cursor outside of link bounds), the UI will close.
[936] Fix | Delete
if (!isActive) {
[937] Fix | Delete
setAddingLink(false);
[938] Fix | Delete
}
[939] Fix | Delete
}, [isActive]);
[940] Fix | Delete
(0,external_wp_element_namespaceObject.useLayoutEffect)(() => {
[941] Fix | Delete
const editableContentElement = contentRef.current;
[942] Fix | Delete
if (!editableContentElement) {
[943] Fix | Delete
return;
[944] Fix | Delete
}
[945] Fix | Delete
function handleClick(event) {
[946] Fix | Delete
// There is a situation whereby there is an existing link in the rich text
[947] Fix | Delete
// and the user clicks on the leftmost edge of that link and fails to activate
[948] Fix | Delete
// the link format, but the click event still fires on the `<a>` element.
[949] Fix | Delete
// This causes the `editingLink` state to be set to `true` and the link UI
[950] Fix | Delete
// to be rendered in "creating" mode. We need to check isActive to see if
[951] Fix | Delete
// we have an active link format.
[952] Fix | Delete
const link = event.target.closest('[contenteditable] a');
[953] Fix | Delete
if (!link ||
[954] Fix | Delete
// other formats (e.g. bold) may be nested within the link.
[955] Fix | Delete
!isActive) {
[956] Fix | Delete
return;
[957] Fix | Delete
}
[958] Fix | Delete
setAddingLink(true);
[959] Fix | Delete
setOpenedBy({
[960] Fix | Delete
el: link,
[961] Fix | Delete
action: 'click'
[962] Fix | Delete
});
[963] Fix | Delete
}
[964] Fix | Delete
editableContentElement.addEventListener('click', handleClick);
[965] Fix | Delete
return () => {
[966] Fix | Delete
editableContentElement.removeEventListener('click', handleClick);
[967] Fix | Delete
};
[968] Fix | Delete
}, [contentRef, isActive]);
[969] Fix | Delete
function addLink(target) {
[970] Fix | Delete
const text = (0,external_wp_richText_namespaceObject.getTextContent)((0,external_wp_richText_namespaceObject.slice)(value));
[971] Fix | Delete
if (!isActive && text && (0,external_wp_url_namespaceObject.isURL)(text) && isValidHref(text)) {
[972] Fix | Delete
onChange((0,external_wp_richText_namespaceObject.applyFormat)(value, {
[973] Fix | Delete
type: link_name,
[974] Fix | Delete
attributes: {
[975] Fix | Delete
url: text
[976] Fix | Delete
}
[977] Fix | Delete
}));
[978] Fix | Delete
} else if (!isActive && text && (0,external_wp_url_namespaceObject.isEmail)(text)) {
[979] Fix | Delete
onChange((0,external_wp_richText_namespaceObject.applyFormat)(value, {
[980] Fix | Delete
type: link_name,
[981] Fix | Delete
attributes: {
[982] Fix | Delete
url: `mailto:${text}`
[983] Fix | Delete
}
[984] Fix | Delete
}));
[985] Fix | Delete
} else {
[986] Fix | Delete
if (target) {
[987] Fix | Delete
setOpenedBy({
[988] Fix | Delete
el: target,
[989] Fix | Delete
action: null // We don't need to distinguish between click or keyboard here
[990] Fix | Delete
});
[991] Fix | Delete
}
[992] Fix | Delete
setAddingLink(true);
[993] Fix | Delete
}
[994] Fix | Delete
}
[995] Fix | Delete
[996] Fix | Delete
/**
[997] Fix | Delete
* Runs when the popover is closed via escape keypress, unlinking the selected text,
[998] Fix | Delete
* but _not_ on a click outside the popover. onFocusOutside handles that.
[999] Fix | Delete
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function