芝麻web文件管理V1.00
编辑当前文件:/home2/sdektunc/cepali.edu.mx/wp-includes/blocks/shortcode/rich-text-20241118163737.js
/******/ (() => { // webpackBootstrap /******/ "use strict"; /******/ // The require scope /******/ var __webpack_require__ = {}; /******/ /************************************************************************/ /******/ /* webpack/runtime/compat get default export */ /******/ (() => { /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = (module) => { /******/ var getter = module && module.__esModule ? /******/ () => (module['default']) : /******/ () => (module); /******/ __webpack_require__.d(getter, { a: getter }); /******/ return getter; /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/define property getters */ /******/ (() => { /******/ // define getter functions for harmony exports /******/ __webpack_require__.d = (exports, definition) => { /******/ for(var key in definition) { /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); /******/ } /******/ } /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/make namespace object */ /******/ (() => { /******/ // define __esModule on exports /******/ __webpack_require__.r = (exports) => { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ })(); /******/ /************************************************************************/ var __webpack_exports__ = {}; // ESM COMPAT FLAG __webpack_require__.r(__webpack_exports__); // EXPORTS __webpack_require__.d(__webpack_exports__, { RichTextData: () => (/* reexport */ RichTextData), __experimentalRichText: () => (/* reexport */ __experimentalRichText), __unstableCreateElement: () => (/* reexport */ createElement), __unstableToDom: () => (/* reexport */ toDom), __unstableUseRichText: () => (/* reexport */ useRichText), applyFormat: () => (/* reexport */ applyFormat), concat: () => (/* reexport */ concat), create: () => (/* reexport */ create), getActiveFormat: () => (/* reexport */ getActiveFormat), getActiveFormats: () => (/* reexport */ getActiveFormats), getActiveObject: () => (/* reexport */ getActiveObject), getTextContent: () => (/* reexport */ getTextContent), insert: () => (/* reexport */ insert), insertObject: () => (/* reexport */ insertObject), isCollapsed: () => (/* reexport */ isCollapsed), isEmpty: () => (/* reexport */ isEmpty), join: () => (/* reexport */ join), registerFormatType: () => (/* reexport */ registerFormatType), remove: () => (/* reexport */ remove_remove), removeFormat: () => (/* reexport */ removeFormat), replace: () => (/* reexport */ replace_replace), slice: () => (/* reexport */ slice), split: () => (/* reexport */ split), store: () => (/* reexport */ store), toHTMLString: () => (/* reexport */ toHTMLString), toggleFormat: () => (/* reexport */ toggleFormat), unregisterFormatType: () => (/* reexport */ unregisterFormatType), useAnchor: () => (/* reexport */ useAnchor), useAnchorRef: () => (/* reexport */ useAnchorRef) }); // NAMESPACE OBJECT: ./node_modules/@wordpress/rich-text/build-module/store/selectors.js var selectors_namespaceObject = {}; __webpack_require__.r(selectors_namespaceObject); __webpack_require__.d(selectors_namespaceObject, { getFormatType: () => (getFormatType), getFormatTypeForBareElement: () => (getFormatTypeForBareElement), getFormatTypeForClassName: () => (getFormatTypeForClassName), getFormatTypes: () => (getFormatTypes) }); // NAMESPACE OBJECT: ./node_modules/@wordpress/rich-text/build-module/store/actions.js var actions_namespaceObject = {}; __webpack_require__.r(actions_namespaceObject); __webpack_require__.d(actions_namespaceObject, { addFormatTypes: () => (addFormatTypes), removeFormatTypes: () => (removeFormatTypes) }); ;// CONCATENATED MODULE: external ["wp","data"] const external_wp_data_namespaceObject = window["wp"]["data"]; ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/store/reducer.js /** * WordPress dependencies */ /** * Reducer managing the format types * * @param {Object} state Current state. * @param {Object} action Dispatched action. * * @return {Object} Updated state. */ function formatTypes(state = {}, action) { switch (action.type) { case 'ADD_FORMAT_TYPES': return { ...state, // Key format types by their name. ...action.formatTypes.reduce((newFormatTypes, type) => ({ ...newFormatTypes, [type.name]: type }), {}) }; case 'REMOVE_FORMAT_TYPES': return Object.fromEntries(Object.entries(state).filter(([key]) => !action.names.includes(key))); } return state; } /* harmony default export */ const reducer = ((0,external_wp_data_namespaceObject.combineReducers)({ formatTypes })); ;// CONCATENATED MODULE: ./node_modules/rememo/rememo.js /** @typedef {(...args: any[]) => *[]} GetDependants */ /** @typedef {() => void} Clear */ /** * @typedef {{ * getDependants: GetDependants, * clear: Clear * }} EnhancedSelector */ /** * Internal cache entry. * * @typedef CacheNode * * @property {?CacheNode|undefined} [prev] Previous node. * @property {?CacheNode|undefined} [next] Next node. * @property {*[]} args Function arguments for cache entry. * @property {*} val Function result. */ /** * @typedef Cache * * @property {Clear} clear Function to clear cache. * @property {boolean} [isUniqueByDependants] Whether dependants are valid in * considering cache uniqueness. A cache is unique if dependents are all arrays * or objects. * @property {CacheNode?} [head] Cache head. * @property {*[]} [lastDependants] Dependants from previous invocation. */ /** * Arbitrary value used as key for referencing cache object in WeakMap tree. * * @type {{}} */ var LEAF_KEY = {}; /** * Returns the first argument as the sole entry in an array. * * @template T * * @param {T} value Value to return. * * @return {[T]} Value returned as entry in array. */ function arrayOf(value) { return [value]; } /** * Returns true if the value passed is object-like, or false otherwise. A value * is object-like if it can support property assignment, e.g. object or array. * * @param {*} value Value to test. * * @return {boolean} Whether value is object-like. */ function isObjectLike(value) { return !!value && 'object' === typeof value; } /** * Creates and returns a new cache object. * * @return {Cache} Cache object. */ function createCache() { /** @type {Cache} */ var cache = { clear: function () { cache.head = null; }, }; return cache; } /** * Returns true if entries within the two arrays are strictly equal by * reference from a starting index. * * @param {*[]} a First array. * @param {*[]} b Second array. * @param {number} fromIndex Index from which to start comparison. * * @return {boolean} Whether arrays are shallowly equal. */ function isShallowEqual(a, b, fromIndex) { var i; if (a.length !== b.length) { return false; } for (i = fromIndex; i < a.length; i++) { if (a[i] !== b[i]) { return false; } } return true; } /** * Returns a memoized selector function. The getDependants function argument is * called before the memoized selector and is expected to return an immutable * reference or array of references on which the selector depends for computing * its own return value. The memoize cache is preserved only as long as those * dependant references remain the same. If getDependants returns a different * reference(s), the cache is cleared and the selector value regenerated. * * @template {(...args: *[]) => *} S * * @param {S} selector Selector function. * @param {GetDependants=} getDependants Dependant getter returning an array of * references used in cache bust consideration. */ /* harmony default export */ function rememo(selector, getDependants) { /** @type {WeakMap<*,*>} */ var rootCache; /** @type {GetDependants} */ var normalizedGetDependants = getDependants ? getDependants : arrayOf; /** * Returns the cache for a given dependants array. When possible, a WeakMap * will be used to create a unique cache for each set of dependants. This * is feasible due to the nature of WeakMap in allowing garbage collection * to occur on entries where the key object is no longer referenced. Since * WeakMap requires the key to be an object, this is only possible when the * dependant is object-like. The root cache is created as a hierarchy where * each top-level key is the first entry in a dependants set, the value a * WeakMap where each key is the next dependant, and so on. This continues * so long as the dependants are object-like. If no dependants are object- * like, then the cache is shared across all invocations. * * @see isObjectLike * * @param {*[]} dependants Selector dependants. * * @return {Cache} Cache object. */ function getCache(dependants) { var caches = rootCache, isUniqueByDependants = true, i, dependant, map, cache; for (i = 0; i < dependants.length; i++) { dependant = dependants[i]; // Can only compose WeakMap from object-like key. if (!isObjectLike(dependant)) { isUniqueByDependants = false; break; } // Does current segment of cache already have a WeakMap? if (caches.has(dependant)) { // Traverse into nested WeakMap. caches = caches.get(dependant); } else { // Create, set, and traverse into a new one. map = new WeakMap(); caches.set(dependant, map); caches = map; } } // We use an arbitrary (but consistent) object as key for the last item // in the WeakMap to serve as our running cache. if (!caches.has(LEAF_KEY)) { cache = createCache(); cache.isUniqueByDependants = isUniqueByDependants; caches.set(LEAF_KEY, cache); } return caches.get(LEAF_KEY); } /** * Resets root memoization cache. */ function clear() { rootCache = new WeakMap(); } /* eslint-disable jsdoc/check-param-names */ /** * The augmented selector call, considering first whether dependants have * changed before passing it to underlying memoize function. * * @param {*} source Source object for derivation. * @param {...*} extraArgs Additional arguments to pass to selector. * * @return {*} Selector result. */ /* eslint-enable jsdoc/check-param-names */ function callSelector(/* source, ...extraArgs */) { var len = arguments.length, cache, node, i, args, dependants; // Create copy of arguments (avoid leaking deoptimization). args = new Array(len); for (i = 0; i < len; i++) { args[i] = arguments[i]; } dependants = normalizedGetDependants.apply(null, args); cache = getCache(dependants); // If not guaranteed uniqueness by dependants (primitive type), shallow // compare against last dependants and, if references have changed, // destroy cache to recalculate result. if (!cache.isUniqueByDependants) { if ( cache.lastDependants && !isShallowEqual(dependants, cache.lastDependants, 0) ) { cache.clear(); } cache.lastDependants = dependants; } node = cache.head; while (node) { // Check whether node arguments match arguments if (!isShallowEqual(node.args, args, 1)) { node = node.next; continue; } // At this point we can assume we've found a match // Surface matched node to head if not already if (node !== cache.head) { // Adjust siblings to point to each other. /** @type {CacheNode} */ (node.prev).next = node.next; if (node.next) { node.next.prev = node.prev; } node.next = cache.head; node.prev = null; /** @type {CacheNode} */ (cache.head).prev = node; cache.head = node; } // Return immediately return node.val; } // No cached value found. Continue to insertion phase: node = /** @type {CacheNode} */ ({ // Generate the result from original function val: selector.apply(null, args), }); // Avoid including the source object in the cache. args[0] = null; node.args = args; // Don't need to check whether node is already head, since it would // have been returned above already if it was // Shift existing head down list if (cache.head) { cache.head.prev = node; node.next = cache.head; } cache.head = node; return node.val; } callSelector.getDependants = normalizedGetDependants; callSelector.clear = clear; clear(); return /** @type {S & EnhancedSelector} */ (callSelector); } ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/store/selectors.js /** * External dependencies */ /** * Returns all the available format types. * * @param {Object} state Data state. * * @example * ```js * import { __, sprintf } from '@wordpress/i18n'; * import { store as richTextStore } from '@wordpress/rich-text'; * import { useSelect } from '@wordpress/data'; * * const ExampleComponent = () => { * const { getFormatTypes } = useSelect( * ( select ) => select( richTextStore ), * [] * ); * * const availableFormats = getFormatTypes(); * * return availableFormats ? ( *
* { availableFormats?.map( ( format ) => ( *
{ format.name }
* ) ) } *
* ) : ( * __( 'No Formats available' ) * ); * }; * ``` * * @return {Array} Format types. */ const getFormatTypes = rememo(state => Object.values(state.formatTypes), state => [state.formatTypes]); /** * Returns a format type by name. * * @param {Object} state Data state. * @param {string} name Format type name. * * @example * ```js * import { __, sprintf } from '@wordpress/i18n'; * import { store as richTextStore } from '@wordpress/rich-text'; * import { useSelect } from '@wordpress/data'; * * const ExampleComponent = () => { * const { getFormatType } = useSelect( * ( select ) => select( richTextStore ), * [] * ); * * const boldFormat = getFormatType( 'core/bold' ); * * return boldFormat ? ( *
* { Object.entries( boldFormat )?.map( ( [ key, value ] ) => ( *
* { key } : { value } *
* ) ) } *
* ) : ( * __( 'Not Found' ) * ; * }; * ``` * * @return {Object?} Format type. */ function getFormatType(state, name) { return state.formatTypes[name]; } /** * Gets the format type, if any, that can handle a bare element (without a * data-format-type attribute), given the tag name of this element. * * @param {Object} state Data state. * @param {string} bareElementTagName The tag name of the element to find a * format type for. * * @example * ```js * import { __, sprintf } from '@wordpress/i18n'; * import { store as richTextStore } from '@wordpress/rich-text'; * import { useSelect } from '@wordpress/data'; * * const ExampleComponent = () => { * const { getFormatTypeForBareElement } = useSelect( * ( select ) => select( richTextStore ), * [] * ); * * const format = getFormatTypeForBareElement( 'strong' ); * * return format &&
{ sprintf( __( 'Format name: %s' ), format.name ) }
; * } * ``` * * @return {?Object} Format type. */ function getFormatTypeForBareElement(state, bareElementTagName) { const formatTypes = getFormatTypes(state); return formatTypes.find(({ className, tagName }) => { return className === null && bareElementTagName === tagName; }) || formatTypes.find(({ className, tagName }) => { return className === null && '*' === tagName; }); } /** * Gets the format type, if any, that can handle an element, given its classes. * * @param {Object} state Data state. * @param {string} elementClassName The classes of the element to find a format * type for. * * @example * ```js * import { __, sprintf } from '@wordpress/i18n'; * import { store as richTextStore } from '@wordpress/rich-text'; * import { useSelect } from '@wordpress/data'; * * const ExampleComponent = () => { * const { getFormatTypeForClassName } = useSelect( * ( select ) => select( richTextStore ), * [] * ); * * const format = getFormatTypeForClassName( 'has-inline-color' ); * * return format &&
{ sprintf( __( 'Format name: %s' ), format.name ) }
; * }; * ``` * * @return {?Object} Format type. */ function getFormatTypeForClassName(state, elementClassName) { return getFormatTypes(state).find(({ className }) => { if (className === null) { return false; } return ` ${elementClassName} `.indexOf(` ${className} `) >= 0; }); } ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/store/actions.js /** * Returns an action object used in signalling that format types have been * added. * Ignored from documentation as registerFormatType should be used instead from @wordpress/rich-text * * @ignore * * @param {Array|Object} formatTypes Format types received. * * @return {Object} Action object. */ function addFormatTypes(formatTypes) { return { type: 'ADD_FORMAT_TYPES', formatTypes: Array.isArray(formatTypes) ? formatTypes : [formatTypes] }; } /** * Returns an action object used to remove a registered format type. * * Ignored from documentation as unregisterFormatType should be used instead from @wordpress/rich-text * * @ignore * * @param {string|Array} names Format name. * * @return {Object} Action object. */ function removeFormatTypes(names) { return { type: 'REMOVE_FORMAT_TYPES', names: Array.isArray(names) ? names : [names] }; } ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/store/index.js /** * WordPress dependencies */ /** * Internal dependencies */ const STORE_NAME = 'core/rich-text'; /** * Store definition for the rich-text namespace. * * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#createReduxStore * * @type {Object} */ const store = (0,external_wp_data_namespaceObject.createReduxStore)(STORE_NAME, { reducer: reducer, selectors: selectors_namespaceObject, actions: actions_namespaceObject }); (0,external_wp_data_namespaceObject.register)(store); ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/is-format-equal.js /** @typedef {import('./types').RichTextFormat} RichTextFormat */ /** * Optimised equality check for format objects. * * @param {?RichTextFormat} format1 Format to compare. * @param {?RichTextFormat} format2 Format to compare. * * @return {boolean} True if formats are equal, false if not. */ function isFormatEqual(format1, format2) { // Both not defined. if (format1 === format2) { return true; } // Either not defined. if (!format1 || !format2) { return false; } if (format1.type !== format2.type) { return false; } const attributes1 = format1.attributes; const attributes2 = format2.attributes; // Both not defined. if (attributes1 === attributes2) { return true; } // Either not defined. if (!attributes1 || !attributes2) { return false; } const keys1 = Object.keys(attributes1); const keys2 = Object.keys(attributes2); if (keys1.length !== keys2.length) { return false; } const length = keys1.length; // Optimise for speed. for (let i = 0; i < length; i++) { const name = keys1[i]; if (attributes1[name] !== attributes2[name]) { return false; } } return true; } ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/normalise-formats.js /** * Internal dependencies */ /** @typedef {import('./types').RichTextValue} RichTextValue */ /** * Normalises formats: ensures subsequent adjacent equal formats have the same * reference. * * @param {RichTextValue} value Value to normalise formats of. * * @return {RichTextValue} New value with normalised formats. */ function normaliseFormats(value) { const newFormats = value.formats.slice(); newFormats.forEach((formatsAtIndex, index) => { const formatsAtPreviousIndex = newFormats[index - 1]; if (formatsAtPreviousIndex) { const newFormatsAtIndex = formatsAtIndex.slice(); newFormatsAtIndex.forEach((format, formatIndex) => { const previousFormat = formatsAtPreviousIndex[formatIndex]; if (isFormatEqual(format, previousFormat)) { newFormatsAtIndex[formatIndex] = previousFormat; } }); newFormats[index] = newFormatsAtIndex; } }); return { ...value, formats: newFormats }; } ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/apply-format.js /** * Internal dependencies */ /** @typedef {import('./types').RichTextValue} RichTextValue */ /** @typedef {import('./types').RichTextFormat} RichTextFormat */ function replace(array, index, value) { array = array.slice(); array[index] = value; return array; } /** * Apply a format object to a Rich Text value from the given `startIndex` to the * given `endIndex`. Indices are retrieved from the selection if none are * provided. * * @param {RichTextValue} value Value to modify. * @param {RichTextFormat} format Format to apply. * @param {number} [startIndex] Start index. * @param {number} [endIndex] End index. * * @return {RichTextValue} A new value with the format applied. */ function applyFormat(value, format, startIndex = value.start, endIndex = value.end) { const { formats, activeFormats } = value; const newFormats = formats.slice(); // The selection is collapsed. if (startIndex === endIndex) { const startFormat = newFormats[startIndex]?.find(({ type }) => type === format.type); // If the caret is at a format of the same type, expand start and end to // the edges of the format. This is useful to apply new attributes. if (startFormat) { const index = newFormats[startIndex].indexOf(startFormat); while (newFormats[startIndex] && newFormats[startIndex][index] === startFormat) { newFormats[startIndex] = replace(newFormats[startIndex], index, format); startIndex--; } endIndex++; while (newFormats[endIndex] && newFormats[endIndex][index] === startFormat) { newFormats[endIndex] = replace(newFormats[endIndex], index, format); endIndex++; } } } else { // Determine the highest position the new format can be inserted at. let position = +Infinity; for (let index = startIndex; index < endIndex; index++) { if (newFormats[index]) { newFormats[index] = newFormats[index].filter(({ type }) => type !== format.type); const length = newFormats[index].length; if (length < position) { position = length; } } else { newFormats[index] = []; position = 0; } } for (let index = startIndex; index < endIndex; index++) { newFormats[index].splice(position, 0, format); } } return normaliseFormats({ ...value, formats: newFormats, // Always revise active formats. This serves as a placeholder for new // inputs with the format so new input appears with the format applied, // and ensures a format of the same type uses the latest values. activeFormats: [...(activeFormats?.filter(({ type }) => type !== format.type) || []), format] }); } ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/create-element.js /** * Parse the given HTML into a body element. * * Note: The current implementation will return a shared reference, reset on * each call to `createElement`. Therefore, you should not hold a reference to * the value to operate upon asynchronously, as it may have unexpected results. * * @param {HTMLDocument} document The HTML document to use to parse. * @param {string} html The HTML to parse. * * @return {HTMLBodyElement} Body element with parsed HTML. */ function createElement({ implementation }, html) { // Because `createHTMLDocument` is an expensive operation, and with this // function being internal to `rich-text` (full control in avoiding a risk // of asynchronous operations on the shared reference), a single document // is reused and reset for each call to the function. if (!createElement.body) { createElement.body = implementation.createHTMLDocument('').body; } createElement.body.innerHTML = html; return createElement.body; } ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/special-characters.js /** * Object replacement character, used as a placeholder for objects. */ const OBJECT_REPLACEMENT_CHARACTER = '\ufffc'; /** * Zero width non-breaking space, used as padding in the editable DOM tree when * it is empty otherwise. */ const ZWNBSP = '\ufeff'; ;// CONCATENATED MODULE: external ["wp","escapeHtml"] const external_wp_escapeHtml_namespaceObject = window["wp"]["escapeHtml"]; ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/get-active-formats.js /** @typedef {import('./types').RichTextValue} RichTextValue */ /** @typedef {import('./types').RichTextFormatList} RichTextFormatList */ /** * Internal dependencies */ /** * Gets the all format objects at the start of the selection. * * @param {RichTextValue} value Value to inspect. * @param {Array} EMPTY_ACTIVE_FORMATS Array to return if there are no * active formats. * * @return {RichTextFormatList} Active format objects. */ function getActiveFormats(value, EMPTY_ACTIVE_FORMATS = []) { const { formats, start, end, activeFormats } = value; if (start === undefined) { return EMPTY_ACTIVE_FORMATS; } if (start === end) { // For a collapsed caret, it is possible to override the active formats. if (activeFormats) { return activeFormats; } const formatsBefore = formats[start - 1] || EMPTY_ACTIVE_FORMATS; const formatsAfter = formats[start] || EMPTY_ACTIVE_FORMATS; // By default, select the lowest amount of formats possible (which means // the caret is positioned outside the format boundary). The user can // then use arrow keys to define `activeFormats`. if (formatsBefore.length < formatsAfter.length) { return formatsBefore; } return formatsAfter; } // If there's no formats at the start index, there are not active formats. if (!formats[start]) { return EMPTY_ACTIVE_FORMATS; } const selectedFormats = formats.slice(start, end); // Clone the formats so we're not mutating the live value. const _activeFormats = [...selectedFormats[0]]; let i = selectedFormats.length; // For performance reasons, start from the end where it's much quicker to // realise that there are no active formats. while (i--) { const formatsAtIndex = selectedFormats[i]; // If we run into any index without formats, we're sure that there's no // active formats. if (!formatsAtIndex) { return EMPTY_ACTIVE_FORMATS; } let ii = _activeFormats.length; // Loop over the active formats and remove any that are not present at // the current index. while (ii--) { const format = _activeFormats[ii]; if (!formatsAtIndex.find(_format => isFormatEqual(format, _format))) { _activeFormats.splice(ii, 1); } } // If there are no active formats, we can stop. if (_activeFormats.length === 0) { return EMPTY_ACTIVE_FORMATS; } } return _activeFormats || EMPTY_ACTIVE_FORMATS; } ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/get-format-type.js /** * WordPress dependencies */ /** * Internal dependencies */ /** @typedef {import('./register-format-type').RichTextFormatType} RichTextFormatType */ /** * Returns a registered format type. * * @param {string} name Format name. * * @return {RichTextFormatType|undefined} Format type. */ function get_format_type_getFormatType(name) { return (0,external_wp_data_namespaceObject.select)(store).getFormatType(name); } ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/to-tree.js /** * Internal dependencies */ function restoreOnAttributes(attributes, isEditableTree) { if (isEditableTree) { return attributes; } const newAttributes = {}; for (const key in attributes) { let newKey = key; if (key.startsWith('data-disable-rich-text-')) { newKey = key.slice('data-disable-rich-text-'.length); } newAttributes[newKey] = attributes[key]; } return newAttributes; } /** * Converts a format object to information that can be used to create an element * from (type, attributes and object). * * @param {Object} $1 Named parameters. * @param {string} $1.type The format type. * @param {string} $1.tagName The tag name. * @param {Object} $1.attributes The format attributes. * @param {Object} $1.unregisteredAttributes The unregistered format * attributes. * @param {boolean} $1.object Whether or not it is an object * format. * @param {boolean} $1.boundaryClass Whether or not to apply a boundary * class. * @param {boolean} $1.isEditableTree * * @return {Object} Information to be used for element creation. */ function fromFormat({ type, tagName, attributes, unregisteredAttributes, object, boundaryClass, isEditableTree }) { const formatType = get_format_type_getFormatType(type); let elementAttributes = {}; if (boundaryClass && isEditableTree) { elementAttributes['data-rich-text-format-boundary'] = 'true'; } if (!formatType) { if (attributes) { elementAttributes = { ...attributes, ...elementAttributes }; } return { type, attributes: restoreOnAttributes(elementAttributes, isEditableTree), object }; } elementAttributes = { ...unregisteredAttributes, ...elementAttributes }; for (const name in attributes) { const key = formatType.attributes ? formatType.attributes[name] : false; if (key) { elementAttributes[key] = attributes[name]; } else { elementAttributes[name] = attributes[name]; } } if (formatType.className) { if (elementAttributes.class) { elementAttributes.class = `${formatType.className} ${elementAttributes.class}`; } else { elementAttributes.class = formatType.className; } } // When a format is declared as non editable, make it non editable in the // editor. if (isEditableTree && formatType.contentEditable === false) { elementAttributes.contenteditable = 'false'; } return { type: tagName || formatType.tagName, object: formatType.object, attributes: restoreOnAttributes(elementAttributes, isEditableTree) }; } /** * Checks if both arrays of formats up until a certain index are equal. * * @param {Array} a Array of formats to compare. * @param {Array} b Array of formats to compare. * @param {number} index Index to check until. */ function isEqualUntil(a, b, index) { do { if (a[index] !== b[index]) { return false; } } while (index--); return true; } function toTree({ value, preserveWhiteSpace, createEmpty, append, getLastChild, getParent, isText, getText, remove, appendText, onStartIndex, onEndIndex, isEditableTree, placeholder }) { const { formats, replacements, text, start, end } = value; const formatsLength = formats.length + 1; const tree = createEmpty(); const activeFormats = getActiveFormats(value); const deepestActiveFormat = activeFormats[activeFormats.length - 1]; let lastCharacterFormats; let lastCharacter; append(tree, ''); for (let i = 0; i < formatsLength; i++) { const character = text.charAt(i); const shouldInsertPadding = isEditableTree && ( // Pad the line if the line is empty. !lastCharacter || // Pad the line if the previous character is a line break, otherwise // the line break won't be visible. lastCharacter === '\n'); const characterFormats = formats[i]; let pointer = getLastChild(tree); if (characterFormats) { characterFormats.forEach((format, formatIndex) => { if (pointer && lastCharacterFormats && // Reuse the last element if all formats remain the same. isEqualUntil(characterFormats, lastCharacterFormats, formatIndex)) { pointer = getLastChild(pointer); return; } const { type, tagName, attributes, unregisteredAttributes } = format; const boundaryClass = isEditableTree && format === deepestActiveFormat; const parent = getParent(pointer); const newNode = append(parent, fromFormat({ type, tagName, attributes, unregisteredAttributes, boundaryClass, isEditableTree })); if (isText(pointer) && getText(pointer).length === 0) { remove(pointer); } pointer = append(newNode, ''); }); } // If there is selection at 0, handle it before characters are inserted. if (i === 0) { if (onStartIndex && start === 0) { onStartIndex(tree, pointer); } if (onEndIndex && end === 0) { onEndIndex(tree, pointer); } } if (character === OBJECT_REPLACEMENT_CHARACTER) { const replacement = replacements[i]; if (!replacement) continue; const { type, attributes, innerHTML } = replacement; const formatType = get_format_type_getFormatType(type); if (!isEditableTree && type === 'script') { pointer = append(getParent(pointer), fromFormat({ type: 'script', isEditableTree })); append(pointer, { html: decodeURIComponent(attributes['data-rich-text-script']) }); } else if (formatType?.contentEditable === false) { // For non editable formats, render the stored inner HTML. pointer = append(getParent(pointer), fromFormat({ ...replacement, isEditableTree, boundaryClass: start === i && end === i + 1 })); if (innerHTML) { append(pointer, { html: innerHTML }); } } else { pointer = append(getParent(pointer), fromFormat({ ...replacement, object: true, isEditableTree })); } // Ensure pointer is text node. pointer = append(getParent(pointer), ''); } else if (!preserveWhiteSpace && character === '\n') { pointer = append(getParent(pointer), { type: 'br', attributes: isEditableTree ? { 'data-rich-text-line-break': 'true' } : undefined, object: true }); // Ensure pointer is text node. pointer = append(getParent(pointer), ''); } else if (!isText(pointer)) { pointer = append(getParent(pointer), character); } else { appendText(pointer, character); } if (onStartIndex && start === i + 1) { onStartIndex(tree, pointer); } if (onEndIndex && end === i + 1) { onEndIndex(tree, pointer); } if (shouldInsertPadding && i === text.length) { append(getParent(pointer), ZWNBSP); if (placeholder && text.length === 0) { append(getParent(pointer), { type: 'span', attributes: { 'data-rich-text-placeholder': placeholder, // Necessary to prevent the placeholder from catching // selection and being editable. style: 'pointer-events:none;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;' } }); } } lastCharacterFormats = characterFormats; lastCharacter = character; } return tree; } ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/to-html-string.js /** * WordPress dependencies */ /** * Internal dependencies */ /** @typedef {import('./types').RichTextValue} RichTextValue */ /** * Create an HTML string from a Rich Text value. * * @param {Object} $1 Named argements. * @param {RichTextValue} $1.value Rich text value. * @param {boolean} [$1.preserveWhiteSpace] Preserves newlines if true. * * @return {string} HTML string. */ function toHTMLString({ value, preserveWhiteSpace }) { const tree = toTree({ value, preserveWhiteSpace, createEmpty, append, getLastChild, getParent, isText, getText, remove, appendText }); return createChildrenHTML(tree.children); } function createEmpty() { return {}; } function getLastChild({ children }) { return children && children[children.length - 1]; } function append(parent, object) { if (typeof object === 'string') { object = { text: object }; } object.parent = parent; parent.children = parent.children || []; parent.children.push(object); return object; } function appendText(object, text) { object.text += text; } function getParent({ parent }) { return parent; } function isText({ text }) { return typeof text === 'string'; } function getText({ text }) { return text; } function remove(object) { const index = object.parent.children.indexOf(object); if (index !== -1) { object.parent.children.splice(index, 1); } return object; } function createElementHTML({ type, attributes, object, children }) { let attributeString = ''; for (const key in attributes) { if (!(0,external_wp_escapeHtml_namespaceObject.isValidAttributeName)(key)) { continue; } attributeString += ` ${key}="${(0,external_wp_escapeHtml_namespaceObject.escapeAttribute)(attributes[key])}"`; } if (object) { return `<${type}${attributeString}>`; } return `<${type}${attributeString}>${createChildrenHTML(children)}${type}>`; } function createChildrenHTML(children = []) { return children.map(child => { if (child.html !== undefined) { return child.html; } return child.text === undefined ? createElementHTML(child) : (0,external_wp_escapeHtml_namespaceObject.escapeEditableHTML)(child.text); }).join(''); } ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/get-text-content.js /** * Internal dependencies */ /** @typedef {import('./types').RichTextValue} RichTextValue */ /** * Get the textual content of a Rich Text value. This is similar to * `Element.textContent`. * * @param {RichTextValue} value Value to use. * * @return {string} The text content. */ function getTextContent({ text }) { return text.replace(OBJECT_REPLACEMENT_CHARACTER, ''); } ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/create.js /** * WordPress dependencies */ /** * Internal dependencies */ /** @typedef {import('./types').RichTextValue} RichTextValue */ function createEmptyValue() { return { formats: [], replacements: [], text: '' }; } function toFormat({ tagName, attributes }) { let formatType; if (attributes && attributes.class) { formatType = (0,external_wp_data_namespaceObject.select)(store).getFormatTypeForClassName(attributes.class); if (formatType) { // Preserve any additional classes. attributes.class = ` ${attributes.class} `.replace(` ${formatType.className} `, ' ').trim(); if (!attributes.class) { delete attributes.class; } } } if (!formatType) { formatType = (0,external_wp_data_namespaceObject.select)(store).getFormatTypeForBareElement(tagName); } if (!formatType) { return attributes ? { type: tagName, attributes } : { type: tagName }; } if (formatType.__experimentalCreatePrepareEditableTree && !formatType.__experimentalCreateOnChangeEditableValue) { return null; } if (!attributes) { return { formatType, type: formatType.name, tagName }; } const registeredAttributes = {}; const unregisteredAttributes = {}; const _attributes = { ...attributes }; for (const key in formatType.attributes) { const name = formatType.attributes[key]; registeredAttributes[key] = _attributes[name]; // delete the attribute and what's left is considered // to be unregistered. delete _attributes[name]; if (typeof registeredAttributes[key] === 'undefined') { delete registeredAttributes[key]; } } for (const name in _attributes) { unregisteredAttributes[name] = attributes[name]; } if (formatType.contentEditable === false) { delete unregisteredAttributes.contenteditable; } return { formatType, type: formatType.name, tagName, attributes: registeredAttributes, unregisteredAttributes }; } /** * The RichTextData class is used to instantiate a wrapper around rich text * values, with methods that can be used to transform or manipulate the data. * * - Create an empty instance: `new RichTextData()`. * - Create one from an HTML string: `RichTextData.fromHTMLString( * '
hello
' )`. * - Create one from a wrapper HTMLElement: `RichTextData.fromHTMLElement( * document.querySelector( 'p' ) )`. * - Create one from plain text: `RichTextData.fromPlainText( '1\n2' )`. * - Create one from a rich text value: `new RichTextData( { text: '...', * formats: [ ... ] } )`. * * @todo Add methods to manipulate the data, such as applyFormat, slice etc. */ class RichTextData { #value; static empty() { return new RichTextData(); } static fromPlainText(text) { return new RichTextData(create({ text })); } static fromHTMLString(html) { return new RichTextData(create({ html })); } static fromHTMLElement(htmlElement, options = {}) { const { preserveWhiteSpace = false } = options; const element = preserveWhiteSpace ? htmlElement : collapseWhiteSpace(htmlElement); const richTextData = new RichTextData(create({ element })); Object.defineProperty(richTextData, 'originalHTML', { value: htmlElement.innerHTML }); return richTextData; } constructor(init = createEmptyValue()) { this.#value = init; } toPlainText() { return getTextContent(this.#value); } // We could expose `toHTMLElement` at some point as well, but we'd only use // it internally. toHTMLString({ preserveWhiteSpace } = {}) { return this.originalHTML || toHTMLString({ value: this.#value, preserveWhiteSpace }); } valueOf() { return this.toHTMLString(); } toString() { return this.toHTMLString(); } toJSON() { return this.toHTMLString(); } get length() { return this.text.length; } get formats() { return this.#value.formats; } get replacements() { return this.#value.replacements; } get text() { return this.#value.text; } } for (const name of Object.getOwnPropertyNames(String.prototype)) { if (RichTextData.prototype.hasOwnProperty(name)) { continue; } Object.defineProperty(RichTextData.prototype, name, { value(...args) { // Should we convert back to RichTextData? return this.toHTMLString()[name](...args); } }); } /** * Create a RichText value from an `Element` tree (DOM), an HTML string or a * plain text string, with optionally a `Range` object to set the selection. If * called without any input, an empty value will be created. The optional * functions can be used to filter out content. * * A value will have the following shape, which you are strongly encouraged not * to modify without the use of helper functions: * * ```js * { * text: string, * formats: Array, * replacements: Array, * ?start: number, * ?end: number, * } * ``` * * As you can see, text and formatting are separated. `text` holds the text, * including any replacement characters for objects and lines. `formats`, * `objects` and `lines` are all sparse arrays of the same length as `text`. It * holds information about the formatting at the relevant text indices. Finally * `start` and `end` state which text indices are selected. They are only * provided if a `Range` was given. * * @param {Object} [$1] Optional named arguments. * @param {Element} [$1.element] Element to create value from. * @param {string} [$1.text] Text to create value from. * @param {string} [$1.html] HTML to create value from. * @param {Range} [$1.range] Range to create value from. * @param {boolean} [$1.__unstableIsEditableTree] * @return {RichTextValue} A rich text value. */ function create({ element, text, html, range, __unstableIsEditableTree: isEditableTree } = {}) { if (html instanceof RichTextData) { return { text: html.text, formats: html.formats, replacements: html.replacements }; } if (typeof text === 'string' && text.length > 0) { return { formats: Array(text.length), replacements: Array(text.length), text }; } if (typeof html === 'string' && html.length > 0) { // It does not matter which document this is, we're just using it to // parse. element = createElement(document, html); } if (typeof element !== 'object') { return createEmptyValue(); } return createFromElement({ element, range, isEditableTree }); } /** * Helper to accumulate the value's selection start and end from the current * node and range. * * @param {Object} accumulator Object to accumulate into. * @param {Node} node Node to create value with. * @param {Range} range Range to create value with. * @param {Object} value Value that is being accumulated. */ function accumulateSelection(accumulator, node, range, value) { if (!range) { return; } const { parentNode } = node; const { startContainer, startOffset, endContainer, endOffset } = range; const currentLength = accumulator.text.length; // Selection can be extracted from value. if (value.start !== undefined) { accumulator.start = currentLength + value.start; // Range indicates that the current node has selection. } else if (node === startContainer && node.nodeType === node.TEXT_NODE) { accumulator.start = currentLength + startOffset; // Range indicates that the current node is selected. } else if (parentNode === startContainer && node === startContainer.childNodes[startOffset]) { accumulator.start = currentLength; // Range indicates that the selection is after the current node. } else if (parentNode === startContainer && node === startContainer.childNodes[startOffset - 1]) { accumulator.start = currentLength + value.text.length; // Fallback if no child inside handled the selection. } else if (node === startContainer) { accumulator.start = currentLength; } // Selection can be extracted from value. if (value.end !== undefined) { accumulator.end = currentLength + value.end; // Range indicates that the current node has selection. } else if (node === endContainer && node.nodeType === node.TEXT_NODE) { accumulator.end = currentLength + endOffset; // Range indicates that the current node is selected. } else if (parentNode === endContainer && node === endContainer.childNodes[endOffset - 1]) { accumulator.end = currentLength + value.text.length; // Range indicates that the selection is before the current node. } else if (parentNode === endContainer && node === endContainer.childNodes[endOffset]) { accumulator.end = currentLength; // Fallback if no child inside handled the selection. } else if (node === endContainer) { accumulator.end = currentLength + endOffset; } } /** * Adjusts the start and end offsets from a range based on a text filter. * * @param {Node} node Node of which the text should be filtered. * @param {Range} range The range to filter. * @param {Function} filter Function to use to filter the text. * * @return {Object|void} Object containing range properties. */ function filterRange(node, range, filter) { if (!range) { return; } const { startContainer, endContainer } = range; let { startOffset, endOffset } = range; if (node === startContainer) { startOffset = filter(node.nodeValue.slice(0, startOffset)).length; } if (node === endContainer) { endOffset = filter(node.nodeValue.slice(0, endOffset)).length; } return { startContainer, startOffset, endContainer, endOffset }; } /** * Collapse any whitespace used for HTML formatting to one space character, * because it will also be displayed as such by the browser. * * We need to strip it from the content because we use white-space: pre-wrap for * displaying editable rich text. Without using white-space: pre-wrap, the * browser will litter the content with non breaking spaces, among other issues. * See packages/rich-text/src/component/use-default-style.js. * * @see * https://developer.mozilla.org/en-US/docs/Web/CSS/white-space-collapse#collapsing_of_white_space * * @param {HTMLElement} element * @param {boolean} isRoot * * @return {HTMLElement} New element with collapsed whitespace. */ function collapseWhiteSpace(element, isRoot = true) { const clone = element.cloneNode(true); clone.normalize(); Array.from(clone.childNodes).forEach((node, i, nodes) => { if (node.nodeType === node.TEXT_NODE) { let newNodeValue = node.nodeValue; if (/[\n\t\r\f]/.test(newNodeValue)) { newNodeValue = newNodeValue.replace(/[\n\t\r\f]+/g, ' '); } if (newNodeValue.indexOf(' ') !== -1) { newNodeValue = newNodeValue.replace(/ {2,}/g, ' '); } if (i === 0 && newNodeValue.startsWith(' ')) { newNodeValue = newNodeValue.slice(1); } else if (isRoot && i === nodes.length - 1 && newNodeValue.endsWith(' ')) { newNodeValue = newNodeValue.slice(0, -1); } node.nodeValue = newNodeValue; } else if (node.nodeType === node.ELEMENT_NODE) { collapseWhiteSpace(node, false); } }); return clone; } /** * We need to normalise line breaks to `\n` so they are consistent across * platforms and serialised properly. Not removing \r would cause it to * linger and result in double line breaks when whitespace is preserved. */ const CARRIAGE_RETURN = '\r'; /** * Removes reserved characters used by rich-text (zero width non breaking spaces * added by `toTree` and object replacement characters). * * @param {string} string */ function removeReservedCharacters(string) { // with the global flag, note that we should create a new regex each time OR // reset lastIndex state. return string.replace(new RegExp(`[${ZWNBSP}${OBJECT_REPLACEMENT_CHARACTER}${CARRIAGE_RETURN}]`, 'gu'), ''); } /** * Creates a Rich Text value from a DOM element and range. * * @param {Object} $1 Named argements. * @param {Element} [$1.element] Element to create value from. * @param {Range} [$1.range] Range to create value from. * @param {boolean} [$1.isEditableTree] * * @return {RichTextValue} A rich text value. */ function createFromElement({ element, range, isEditableTree }) { const accumulator = createEmptyValue(); if (!element) { return accumulator; } if (!element.hasChildNodes()) { accumulateSelection(accumulator, element, range, createEmptyValue()); return accumulator; } const length = element.childNodes.length; // Optimise for speed. for (let index = 0; index < length; index++) { const node = element.childNodes[index]; const tagName = node.nodeName.toLowerCase(); if (node.nodeType === node.TEXT_NODE) { const text = removeReservedCharacters(node.nodeValue); range = filterRange(node, range, removeReservedCharacters); accumulateSelection(accumulator, node, range, { text }); // Create a sparse array of the same length as `tex