diff --git a/readme.html b/readme.html index b40b60ff4..e1528c1ac 100644 --- a/readme.html +++ b/readme.html @@ -58,8 +58,8 @@

Recommendations

<⃨!⃨-⃨-⃨ ⃨w⃨p⃨:⃨p⃨a⃨r⃨a⃨g⃨r⃨a⃨p⃨h⃨ ⃨-⃨>⃨

+ * + * Example: + * + * // Find all textual ranges of image block opening delimiters. + * $images = array(); + * $processor = new WP_Block_Processor( $html ); + * while ( $processor->next_block( 'core/image' ) ) { + * $images[] = $processor->get_span(); + * } + * + * In some cases it may be useful to conditionally visit the implicit freeform + * blocks, such as when determining if a post contains freeform content that + * isn’t purely whitespace. + * + * Example: + * + * $seen_block_types = []; + * $block_type = '*'; + * $processor = new WP_Block_Processor( $html ); + * while ( $processor->next_block( $block_type ) { + * // Stop wasting time visiting freeform blocks after one has been found. + * if ( + * '*' === $block_type && + * null === $processor->get_block_type() && + * $processor->is_non_whitespace_html() + * ) { + * $block_type = null; + * $seen_block_types['core/freeform'] = true; + * continue; + * } + * + * $seen_block_types[ $processor->get_block_type() ] = true; + * } + * + * @since 6.9.0 + * + * @see self::next_delimiter() to advance to the next explicit block delimiter. + * @see self::next_token() to advance to the next block delimiter or HTML span. + * + * @param string|null $block_type Optional. If provided, advance until a block of this type is found. + * Default is to stop at any block regardless of its type. + * @return bool Whether an opening delimiter for a block was found. + */ + public function next_block( ?string $block_type = null ): bool { + while ( $this->next_delimiter( $block_type ) ) { + if ( self::CLOSER !== $this->get_delimiter_type() ) { + return true; + } + } + + return false; + } + + /** + * Advance to the next block delimiter in a document, indicating if one was found. + * + * Delimiters may include invalid JSON. This parser does not attempt to parse the + * JSON attributes until requested; when invalid, the attributes will be null. This + * matches the behavior of {@see \parse_blocks()}. To visit freeform HTML content, + * pass the wildcard “*” as the block type. + * + * Use this function to walk through the block delimiters in a document. + * + * Example delimiters: + * + * + * + * + * + * // If the wildcard `*` is provided as the block type, freeform content is matched. + * <⃨h⃨2⃨>⃨M⃨y⃨ ⃨s⃨y⃨n⃨o⃨p⃨s⃨i⃨s⃨<⃨/⃨h⃨2⃨>⃨\⃨n⃨ + * + * // Inner HTML is never freeform content, and will not be matched even with the wildcard. + * ...<⃨!⃨-⃨-⃨ ⃨/⃨w⃨p⃨:⃨l⃨i⃨s⃨t⃨ ⃨-⃨-⃨>⃨

+ * + * Example: + * + * $html = '\n'; + * $processor = new WP_Block_Processor( $html ); + * while ( $processor->next_delimiter() { + * // Runs twice, seeing both void blocks of type “core/void.” + * } + * + * $processor = new WP_Block_Processor( $html ); + * while ( $processor->next_delimiter( '*' ) ) { + * // Runs thrice, seeing the void block, the newline span, and the void block. + * } + * + * @since 6.9.0 + * + * @param string|null $block_name Optional. Keep searching until a block of this name is found. + * Defaults to visit every block regardless of type. + * @return bool Whether a block delimiter was matched. + */ + public function next_delimiter( ?string $block_name = null ): bool { + if ( ! isset( $block_name ) ) { + while ( $this->next_token() ) { + if ( ! $this->is_html() ) { + return true; + } + } + + return false; + } + + while ( $this->next_token() ) { + if ( $this->is_block_type( $block_name ) ) { + return true; + } + } + + return false; + } + + /** + * Advance to the next block delimiter or HTML span in a document, indicating if one was found. + * + * This function steps through every syntactic chunk in a document. This includes explicit + * block comment delimiters, freeform non-block content, and inner HTML segments. + * + * Example tokens: + * + * + * + * + *

Normal HTML content

+ * Plaintext content too! + * + * Example: + * + * // Find span containing wrapping HTML element surrounding inner blocks. + * $processor = new WP_Block_Processor( $html ); + * if ( ! $processor->next_block( 'gallery' ) ) { + * return null; + * } + * + * $containing_span = null; + * while ( $processor->next_token() && $processor->is_html() ) { + * $containing_span = $processor->get_span(); + * } + * + * This method will visit all HTML spans including those forming freeform non-block + * content as well as those which are part of a block’s inner HTML. + * + * @since 6.9.0 + * + * @return bool Whether a token was matched or the end of the document was reached without finding any. + */ + public function next_token(): bool { + if ( $this->last_error || self::COMPLETE === $this->state || self::INCOMPLETE_INPUT === $this->state ) { + return false; + } + + // Void tokens automatically pop off the stack of open blocks. + if ( $this->was_void ) { + array_pop( $this->open_blocks_at ); + array_pop( $this->open_blocks_length ); + $this->was_void = false; + } + + $text = $this->source_text; + $end = strlen( $text ); + + /* + * Because HTML spans are inferred after finding the next delimiter, it means that + * the parser must transition out of that HTML state and reuse the token boundaries + * it found after the HTML span. If those boundaries are before the end of the + * document it implies that a real delimiter was found; otherwise this must be the + * terminating HTML span and the parsing is complete. + */ + if ( self::HTML_SPAN === $this->state ) { + if ( $this->matched_delimiter_at >= $end ) { + $this->state = self::COMPLETE; + return false; + } + + switch ( $this->next_stack_op ) { + case 'void': + $this->was_void = true; + $this->open_blocks_at[] = $this->namespace_at; + $this->open_blocks_length[] = $this->name_at + $this->name_length - $this->namespace_at; + break; + + case 'push': + $this->open_blocks_at[] = $this->namespace_at; + $this->open_blocks_length[] = $this->name_at + $this->name_length - $this->namespace_at; + break; + + case 'pop': + array_pop( $this->open_blocks_at ); + array_pop( $this->open_blocks_length ); + break; + } + + $this->next_stack_op = null; + $this->state = self::MATCHED; + return true; + } + + $this->state = self::READY; + $after_prev_delimiter = $this->matched_delimiter_at + $this->matched_delimiter_length; + $at = $after_prev_delimiter; + + while ( $at < $end ) { + /* + * Find the next possible start of a delimiter. + * + * This follows the behavior in the official block parser, which segments a post + * by the block comment delimiters. It is possible for an HTML attribute to contain + * what looks like a block comment delimiter but which is actually an HTML attribute + * value. In such a case, the parser here will break apart the HTML and create the + * block boundary inside the HTML attribute. In other words, the block parser + * isolates sections of HTML from each other, even if that leads to malformed markup. + * + * For a more robust parse, scan through the document with the HTML API and parse + * comments once they are matched to see if they are also block delimiters. In + * practice, this nuance has not caused any known problems since developing blocks. + * + * <⃨!⃨-⃨-⃨ /wp:core/paragraph {"dropCap":true} /--> + */ + $comment_opening_at = strpos( $text, ' + $opening_whitespace_at = $comment_opening_at + 4; + if ( $opening_whitespace_at >= $end ) { + goto incomplete; + } + + $opening_whitespace_length = strspn( $text, " \t\f\r\n", $opening_whitespace_at ); + + /* + * The `wp` prefix cannot come before this point, but it may come after it + * depending on the presence of the closer. This is detected next. + */ + $wp_prefix_at = $opening_whitespace_at + $opening_whitespace_length; + if ( $wp_prefix_at >= $end ) { + goto incomplete; + } + + if ( 0 === $opening_whitespace_length ) { + $at = $this->find_html_comment_end( $comment_opening_at, $end ); + continue; + } + + // + $has_closer = false; + if ( '/' === $text[ $wp_prefix_at ] ) { + $has_closer = true; + ++$wp_prefix_at; + } + + // + if ( $wp_prefix_at < $end && 0 !== substr_compare( $text, 'wp:', $wp_prefix_at, 3 ) ) { + if ( + ( $wp_prefix_at + 2 >= $end && str_ends_with( $text, 'wp' ) ) || + ( $wp_prefix_at + 1 >= $end && str_ends_with( $text, 'w' ) ) + ) { + goto incomplete; + } + + $at = $this->find_html_comment_end( $comment_opening_at, $end ); + continue; + } + + /* + * If the block contains no namespace, this will end up masquerading with + * the block name. It’s easier to first detect the span and then determine + * if it’s a namespace of a name. + * + * + */ + $namespace_at = $wp_prefix_at + 3; + if ( $namespace_at >= $end ) { + goto incomplete; + } + + $start_of_namespace = $text[ $namespace_at ]; + + // The namespace must start with a-z. + if ( 'a' > $start_of_namespace || 'z' < $start_of_namespace ) { + $at = $this->find_html_comment_end( $comment_opening_at, $end ); + continue; + } + + $namespace_length = 1 + strspn( $text, 'abcdefghijklmnopqrstuvwxyz0123456789-_', $namespace_at + 1 ); + $separator_at = $namespace_at + $namespace_length; + if ( $separator_at >= $end ) { + goto incomplete; + } + + // + $has_separator = '/' === $text[ $separator_at ]; + if ( $has_separator ) { + $name_at = $separator_at + 1; + + if ( $name_at >= $end ) { + goto incomplete; + } + + // + $start_of_name = $text[ $name_at ]; + if ( 'a' > $start_of_name || 'z' < $start_of_name ) { + $at = $this->find_html_comment_end( $comment_opening_at, $end ); + continue; + } + + $name_length = 1 + strspn( $text, 'abcdefghijklmnopqrstuvwxyz0123456789-_', $name_at + 1 ); + } else { + $name_at = $namespace_at; + $name_length = $namespace_length; + } + + if ( $name_at + $name_length >= $end ) { + goto incomplete; + } + + /* + * For this next section of the delimiter, it could be the JSON attributes + * or it could be the end of the comment. Assume that the JSON is there and + * update if it’s not. + */ + + // + $after_name_whitespace_at = $name_at + $name_length; + $after_name_whitespace_length = strspn( $text, " \t\f\r\n", $after_name_whitespace_at ); + $json_at = $after_name_whitespace_at + $after_name_whitespace_length; + + if ( $json_at >= $end ) { + goto incomplete; + } + + if ( 0 === $after_name_whitespace_length ) { + $at = $this->find_html_comment_end( $comment_opening_at, $end ); + continue; + } + + // + $has_json = '{' === $text[ $json_at ]; + $json_length = 0; + + /* + * For the final span of the delimiter it's most efficient to find the end of the + * HTML comment and work backwards. This prevents complicated parsing inside the + * JSON span, which is not allowed to contain the HTML comment terminator. + * + * This also matches the behavior in the official block parser, + * even though it allows for matching invalid JSON content. + * + * ', $json_at ); + if ( false === $comment_closing_at ) { + goto incomplete; + } + + // + if ( '/' === $text[ $comment_closing_at - 1 ] ) { + $has_void_flag = true; + $void_flag_length = 1; + } else { + $has_void_flag = false; + $void_flag_length = 0; + } + + /* + * If there's no JSON, then the span of text after the name + * until the comment closing must be completely whitespace. + * Otherwise it’s a normal HTML comment. + */ + if ( ! $has_json ) { + if ( $after_name_whitespace_at + $after_name_whitespace_length === $comment_closing_at - $void_flag_length ) { + // This must be a block delimiter! + $this->state = self::MATCHED; + break; + } + + $at = $this->find_html_comment_end( $comment_opening_at, $end ); + continue; + } + + /* + * There's JSON, so attempt to find its boundary. + * + * @todo It’s likely faster to scan forward instead of in reverse. + * + * + */ + $after_json_whitespace_length = 0; + for ( $char_at = $comment_closing_at - $void_flag_length - 1; $char_at > $json_at; $char_at-- ) { + $char = $text[ $char_at ]; + + switch ( $char ) { + case ' ': + case "\t": + case "\f": + case "\r": + case "\n": + ++$after_json_whitespace_length; + continue 2; + + case '}': + $json_length = $char_at - $json_at + 1; + break 2; + + default: + ++$at; + continue 3; + } + } + + /* + * This covers cases where there is no terminating “}” or where + * mandatory whitespace is missing. + */ + if ( 0 === $json_length || 0 === $after_json_whitespace_length ) { + $at = $this->find_html_comment_end( $comment_opening_at, $end ); + continue; + } + + // This must be a block delimiter! + $this->state = self::MATCHED; + break; + } + + // The end of the document was reached without a match. + if ( self::MATCHED !== $this->state ) { + $this->state = self::COMPLETE; + return false; + } + + /* + * From this point forward, a delimiter has been matched. There + * might also be an HTML span that appears before the delimiter. + */ + + $this->after_previous_delimiter = $after_prev_delimiter; + + $this->matched_delimiter_at = $comment_opening_at; + $this->matched_delimiter_length = $comment_closing_at + 3 - $comment_opening_at; + + $this->namespace_at = $namespace_at; + $this->name_at = $name_at; + $this->name_length = $name_length; + + $this->json_at = $json_at; + $this->json_length = $json_length; + + /* + * When delimiters contain both the void flag and the closing flag + * they shall be interpreted as void blocks, per the spec parser. + */ + if ( $has_void_flag ) { + $this->type = self::VOID; + $this->next_stack_op = 'void'; + } elseif ( $has_closer ) { + $this->type = self::CLOSER; + $this->next_stack_op = 'pop'; + + /* + * @todo Check if the name matches and bail according to the spec parser. + * The default parser doesn’t examine the names. + */ + } else { + $this->type = self::OPENER; + $this->next_stack_op = 'push'; + } + + $this->has_closing_flag = $has_closer; + + // HTML spans are visited before the delimiter that follows them. + if ( $comment_opening_at > $after_prev_delimiter ) { + $this->state = self::HTML_SPAN; + $this->open_blocks_at[] = $after_prev_delimiter; + $this->open_blocks_length[] = 0; + $this->was_void = true; + + return true; + } + + // If there were no HTML spans then flush the enqueued stack operations immediately. + switch ( $this->next_stack_op ) { + case 'void': + $this->was_void = true; + $this->open_blocks_at[] = $namespace_at; + $this->open_blocks_length[] = $name_at + $name_length - $namespace_at; + break; + + case 'push': + $this->open_blocks_at[] = $namespace_at; + $this->open_blocks_length[] = $name_at + $name_length - $namespace_at; + break; + + case 'pop': + array_pop( $this->open_blocks_at ); + array_pop( $this->open_blocks_length ); + break; + } + + $this->next_stack_op = null; + + return true; + + incomplete: + $this->state = self::COMPLETE; + $this->last_error = self::INCOMPLETE_INPUT; + return false; + } + + /** + * Returns an array containing the names of the currently-open blocks, in order + * from outermost to innermost, with HTML spans indicated as “#html”. + * + * Example: + * + * // Freeform HTML content is an HTML span. + * $processor = new WP_Block_Processor( 'Just text' ); + * $processor->next_token(); + * array( '#text' ) === $processor->get_breadcrumbs(); + * + * $processor = new WP_Block_Processor( '' ); + * $processor->next_token(); + * array( 'core/a' ) === $processor->get_breadcrumbs(); + * $processor->next_token(); + * array( 'core/a', 'core/b' ) === $processor->get_breadcrumbs(); + * $processor->next_token(); + * // Void blocks are only open while visiting them. + * array( 'core/a', 'core/b', 'core/c' ) === $processor->get_breadcrumbs(); + * $processor->next_token(); + * // Blocks are closed before visiting their closing delimiter. + * array( 'core/a' ) === $processor->get_breadcrumbs(); + * $processor->next_token(); + * array() === $processor->get_breadcrumbs(); + * + * // Inner HTML is also an HTML span. + * $processor = new WP_Block_Processor( 'Inner HTML' ); + * $processor->next_token(); + * $processor->next_token(); + * array( 'core/a', '#html' ) === $processor->get_breadcrumbs(); + * + * @since 6.9.0 + * + * @return string[] + */ + public function get_breadcrumbs(): array { + $breadcrumbs = array_fill( 0, count( $this->open_blocks_at ), null ); + + /* + * Since HTML spans can only be at the very end, set the normalized block name for + * each open element and then work backwards after creating the array. This allows + * for the elimination of a conditional on each iteration of the loop. + */ + foreach ( $this->open_blocks_at as $i => $at ) { + $block_type = substr( $this->source_text, $at, $this->open_blocks_length[ $i ] ); + $breadcrumbs[ $i ] = self::normalize_block_type( $block_type ); + } + + if ( isset( $i ) && 0 === $this->open_blocks_length[ $i ] ) { + $breadcrumbs[ $i ] = '#html'; + } + + return $breadcrumbs; + } + + /** + * Returns the depth of the open blocks where the processor is currently matched. + * + * Depth increases before visiting openers and void blocks and decreases before + * visiting closers. HTML spans behave like void blocks. + * + * @since 6.9.0 + * + * @return int + */ + public function get_depth(): int { + return count( $this->open_blocks_at ); + } + + /** + * Extracts a block object, and all inner content, starting at a matched opening + * block delimiter, or at a matched top-level HTML span as freeform HTML content. + * + * Use this function to extract some blocks within a document, but not all. For example, + * one might want to find image galleries, parse them, modify them, and then reserialize + * them in place. + * + * Once this function returns, the parser will be matched on token following the close + * of the given block. + * + * The return type of this method is compatible with the return of {@see \parse_blocks()}. + * + * Example: + * + * $processor = new WP_Block_Processor( $post_content ); + * if ( ! $processor->next_block( 'gallery' ) ) { + * return $post_content; + * } + * + * $gallery_at = $processor->get_span()->start; + * $gallery = $processor->extract_full_block_and_advance(); + * $ends_before = $processor->get_span(); + * $ends_before = $ends_before->start ?? strlen( $post_content ); + * + * $new_gallery = update_gallery( $gallery ); + * $new_gallery = serialize_block( $new_gallery ); + * + * return ( + * substr( $post_content, 0, $gallery_at ) . + * $new_gallery . + * substr( $post_content, $ends_before ) + * ); + * + * @since 6.9.0 + * + * @return array[]|null { + * Array of block structures. + * + * @type array ...$0 { + * An associative array of a single parsed block object. See WP_Block_Parser_Block. + * + * @type string|null $blockName Name of block. + * @type array $attrs Attributes from block comment delimiters. + * @type array[] $innerBlocks List of inner blocks. An array of arrays that + * have the same structure as this one. + * @type string $innerHTML HTML from inside block comment delimiters. + * @type array $innerContent List of string fragments and null markers where + * inner blocks were found. + * } + * } + */ + public function extract_full_block_and_advance(): ?array { + if ( $this->is_html() ) { + $chunk = $this->get_html_content(); + + return array( + 'blockName' => null, + 'attrs' => array(), + 'innerBlocks' => array(), + 'innerHTML' => $chunk, + 'innerContent' => array( $chunk ), + ); + } + + $block = array( + 'blockName' => $this->get_block_type(), + 'attrs' => $this->allocate_and_return_parsed_attributes() ?? array(), + 'innerBlocks' => array(), + 'innerHTML' => '', + 'innerContent' => array(), + ); + + $depth = $this->get_depth(); + while ( $this->next_token() && $this->get_depth() > $depth ) { + if ( $this->is_html() ) { + $chunk = $this->get_html_content(); + $block['innerHTML'] .= $chunk; + $block['innerContent'][] = $chunk; + continue; + } + + /** + * Inner blocks. + * + * @todo This is a decent place to call {@link \render_block()} + * @todo Use iteration instead of recursion, or at least refactor to tail-call form. + */ + if ( $this->opens_block() ) { + $inner_block = $this->extract_full_block_and_advance(); + $block['innerBlocks'][] = $inner_block; + $block['innerContent'][] = null; + } + } + + return $block; + } + + /** + * Returns the byte-offset after the ending character of an HTML comment, + * assuming the proper starting byte offset. + * + * @since 6.9.0 + * + * @param int $comment_starting_at Where the HTML comment started, the leading `<`. + * @param int $search_end Last offset in which to search, for limiting search span. + * @return int Offset after the current HTML comment ends, or `$search_end` if no end was found. + */ + private function find_html_comment_end( int $comment_starting_at, int $search_end ): int { + $text = $this->source_text; + + // Find span-of-dashes comments which look like ``. + $span_of_dashes = strspn( $text, '-', $comment_starting_at + 2 ); + if ( + $comment_starting_at + 2 + $span_of_dashes < $search_end && + '>' === $text[ $comment_starting_at + 2 + $span_of_dashes ] + ) { + return $comment_starting_at + $span_of_dashes + 1; + } + + // Otherwise, there are other characters inside the comment, find the first `-->` or `--!>`. + $now_at = $comment_starting_at + 4; + while ( $now_at < $search_end ) { + $dashes_at = strpos( $text, '--', $now_at ); + if ( false === $dashes_at ) { + return $search_end; + } + + $closer_must_be_at = $dashes_at + 2 + strspn( $text, '-', $dashes_at + 2 ); + if ( $closer_must_be_at < $search_end && '!' === $text[ $closer_must_be_at ] ) { + ++$closer_must_be_at; + } + + if ( $closer_must_be_at < $search_end && '>' === $text[ $closer_must_be_at ] ) { + return $closer_must_be_at + 1; + } + + ++$now_at; + } + + return $search_end; + } + + /** + * Indicates if the last attempt to parse a block comment delimiter + * failed, if set, otherwise `null` if the last attempt succeeded. + * + * @since 6.9.0 + * + * @return string|null Error from last attempt at parsing next block delimiter, + * or `null` if last attempt succeeded. + */ + public function get_last_error(): ?string { + return $this->last_error; + } + + /** + * Indicates if the last attempt to parse a block’s JSON attributes failed. + * + * @see \json_last_error() + * + * @since 6.9.0 + * + * @return int JSON_ERROR_ code from last attempt to parse block JSON attributes. + */ + public function get_last_json_error(): int { + return $this->last_json_error; + } + + /** + * Returns the type of the block comment delimiter. + * + * One of: + * + * - {@see self::OPENER} + * - {@see self::CLOSER} + * - {@see self::VOID} + * - `null` + * + * @since 6.9.0 + * + * @return string|null type of the block comment delimiter, if currently matched. + */ + public function get_delimiter_type(): ?string { + switch ( $this->state ) { + case self::HTML_SPAN: + return self::VOID; + + case self::MATCHED: + return $this->type; + + default: + return null; + } + } + + /** + * Returns whether the delimiter contains the closing flag. + * + * This should be avoided except in cases of custom error-handling + * with block closers containing the void flag. For normative use, + * {@see self::get_delimiter_type()}. + * + * @since 6.9.0 + * + * @return bool Whether the currently-matched block delimiter contains the closing flag. + */ + public function has_closing_flag(): bool { + return $this->has_closing_flag; + } + + /** + * Indicates if the block delimiter represents a block of the given type. + * + * Since the “core” namespace may be implicit, it’s allowable to pass + * either the fully-qualified block type with namespace and block name + * as well as the shorthand version only containing the block name, if + * the desired block is in the “core” namespace. + * + * Since freeform HTML content is non-block content, it has no block type. + * Passing the wildcard “*” will, however, return true for all block types, + * even the implicit freeform content, though not for spans of inner HTML. + * + * Example: + * + * $is_core_paragraph = $processor->is_block_type( 'paragraph' ); + * $is_core_paragraph = $processor->is_block_type( 'core/paragraph' ); + * $is_formula = $processor->is_block_type( 'math-block/formula' ); + * + * @param string $block_type Block type name for the desired block. + * E.g. "paragraph", "core/paragraph", "math-blocks/formula". + * @return bool Whether this delimiter represents a block of the given type. + */ + public function is_block_type( string $block_type ): bool { + if ( '*' === $block_type ) { + return true; + } + + // This is a core/freeform text block, it’s special. + if ( $this->is_html() && 0 === ( $this->open_blocks_length[0] ?? null ) ) { + return ( + 'core/freeform' === $block_type || + 'freeform' === $block_type + ); + } + + return $this->are_equal_block_types( $this->source_text, $this->namespace_at, $this->name_at - $this->namespace_at + $this->name_length, $block_type, 0, strlen( $block_type ) ); + } + + /** + * Given two spans of text, indicate if they represent identical block types. + * + * This function normalizes block types to account for implicit core namespacing. + * + * Note! This function only returns valid results when the complete block types are + * represented in the span offsets and lengths. This means that the full optional + * namespace and block name must be represented in the input arguments. + * + * Example: + * + * 0 5 10 15 20 25 30 35 40 + * $text = ''; + * + * true === WP_Block_Processor::are_equal_block_types( $text, 9, 5, $text, 27, 10 ); + * false === WP_Block_Processor::are_equal_block_types( $text, 9, 5, 'my/block', 0, 8 ); + * + * @since 6.9.0 + * + * @param string $a_text Text in which first block type appears. + * @param int $a_at Byte offset into text in which first block type starts. + * @param int $a_length Byte length of first block type. + * @param string $b_text Text in which second block type appears (may be the same as the first text). + * @param int $b_at Byte offset into text in which second block type starts. + * @param int $b_length Byte length of second block type. + * @return bool Whether the spans of text represent identical block types, normalized for namespacing. + */ + public static function are_equal_block_types( string $a_text, int $a_at, int $a_length, string $b_text, int $b_at, int $b_length ): bool { + $a_ns_length = strcspn( $a_text, '/', $a_at, $a_length ); + $b_ns_length = strcspn( $b_text, '/', $b_at, $b_length ); + + $a_has_ns = $a_ns_length !== $a_length; + $b_has_ns = $b_ns_length !== $b_length; + + // Both contain namespaces. + if ( $a_has_ns && $b_has_ns ) { + if ( $a_length !== $b_length ) { + return false; + } + + $a_block_type = substr( $a_text, $a_at, $a_length ); + + return 0 === substr_compare( $b_text, $a_block_type, $b_at, $b_length ); + } + + if ( $a_has_ns ) { + $b_block_type = 'core/' . substr( $b_text, $b_at, $b_length ); + + return ( + strlen( $b_block_type ) === $a_length && + 0 === substr_compare( $a_text, $b_block_type, $a_at, $a_length ) + ); + } + + if ( $b_has_ns ) { + $a_block_type = 'core/' . substr( $a_text, $a_at, $a_length ); + + return ( + strlen( $a_block_type ) === $b_length && + 0 === substr_compare( $b_text, $a_block_type, $b_at, $b_length ) + ); + } + + // Neither contains a namespace. + if ( $a_length !== $b_length ) { + return false; + } + + $a_name = substr( $a_text, $a_at, $a_length ); + + return 0 === substr_compare( $b_text, $a_name, $b_at, $b_length ); + } + + /** + * Indicates if the matched delimiter is an opening or void delimiter of the given type, + * if a type is provided, otherwise if it opens any block or implicit freeform HTML content. + * + * This is a helper method to ease handling of code inspecting where blocks start, and for + * checking if the blocks are of a given type. The function is variadic to allow for + * checking if the delimiter opens one of many possible block types. + * + * To advance to the start of a block {@see self::next_block()}. + * + * Example: + * + * $processor = new WP_Block_Processor( $html ); + * while ( $processor->next_delimiter() ) { + * if ( $processor->opens_block( 'core/code', 'syntaxhighlighter/code' ) ) { + * echo "Found code!"; + * continue; + * } + * + * if ( $processor->opens_block( 'core/image' ) ) { + * echo "Found an image!"; + * continue; + * } + * + * if ( $processor->opens_block() ) { + * echo "Found a new block!"; + * } + * } + * + * @since 6.9.0 + * + * @see self::is_block_type() + * + * @param string[] $block_type Optional. Is the matched block type one of these? + * If none are provided, will not test block type. + * @return bool Whether the matched block delimiter opens a block, and whether it + * opens a block of one of the given block types, if provided. + */ + public function opens_block( string ...$block_type ): bool { + // HTML spans only open implicit freeform content at the top level. + if ( self::HTML_SPAN === $this->state && 1 !== count( $this->open_blocks_at ) ) { + return false; + } + + /* + * Because HTML spans are discovered after the next delimiter is found, + * the delimiter type when visiting HTML spans refers to the type of the + * following delimiter. Therefore the HTML case is handled by checking + * the state and depth of the stack of open block. + */ + if ( self::CLOSER === $this->type && ! $this->is_html() ) { + return false; + } + + if ( count( $block_type ) === 0 ) { + return true; + } + + foreach ( $block_type as $block ) { + if ( $this->is_block_type( $block ) ) { + return true; + } + } + + return false; + } + + /** + * Indicates if the matched delimiter is an HTML span. + * + * @since 6.9.0 + * + * @see self::is_non_whitespace_html() + * + * @return bool Whether the processor is matched on an HTML span. + */ + public function is_html(): bool { + return self::HTML_SPAN === $this->state; + } + + /** + * Indicates if the matched delimiter is an HTML span and comprises more + * than whitespace characters, i.e. contains real content. + * + * Many block serializers introduce newlines between block delimiters, + * so the presence of top-level non-block content does not imply that + * there are “real” freeform HTML blocks. Checking if there is content + * beyond whitespace is a more certain check, such as for determining + * whether to load CSS for the freeform or fallback block type. + * + * @since 6.9.0 + * + * @see self::is_html() + * + * @return bool Whether the currently-matched delimiter is an HTML + * span containing non-whitespace text. + */ + public function is_non_whitespace_html(): bool { + if ( ! $this->is_html() ) { + return false; + } + + $length = $this->matched_delimiter_at - $this->after_previous_delimiter; + + $whitespace_length = strspn( + $this->source_text, + " \t\f\r\n", + $this->after_previous_delimiter, + $length + ); + + return $whitespace_length !== $length; + } + + /** + * Returns the string content of a matched HTML span, or `null` otherwise. + * + * @since 6.9.0 + * + * @return string|null Raw HTML content, or `null` if not currently matched on HTML. + */ + public function get_html_content(): ?string { + if ( ! $this->is_html() ) { + return null; + } + + return substr( + $this->source_text, + $this->after_previous_delimiter, + $this->matched_delimiter_at - $this->after_previous_delimiter + ); + } + + /** + * Allocates a substring for the block type and returns the fully-qualified + * name, including the namespace, if matched on a delimiter, otherwise `null`. + * + * This function is like {@see self::get_printable_block_type()} but when + * paused on a freeform HTML block, will return `null` instead of “core/freeform”. + * The `null` behavior matches what {@see \parse_blocks()} returns but may not + * be as useful as having a string value. + * + * This function allocates a substring for the given block type. This + * allocation will be small and likely fine in most cases, but it's + * preferable to call {@see self::is_block_type()} if only needing + * to know whether the delimiter is for a given block type, as that + * function is more efficient for this purpose and avoids the allocation. + * + * Example: + * + * // Avoid. + * 'core/paragraph' = $processor->get_block_type(); + * + * // Prefer. + * $processor->is_block_type( 'core/paragraph' ); + * $processor->is_block_type( 'paragraph' ); + * $processor->is_block_type( 'core/freeform' ); + * + * // Freeform HTML content has no block type. + * $processor = new WP_Block_Processor( 'non-block content' ); + * $processor->next_token(); + * null === $processor->get_block_type(); + * + * @since 6.9.0 + * + * @see self::are_equal_block_types() + * + * @return string|null Fully-qualified block namespace and type, e.g. "core/paragraph", + * if matched on an explicit delimiter, otherwise `null`. + */ + public function get_block_type(): ?string { + if ( + self::READY === $this->state || + self::COMPLETE === $this->state || + self::INCOMPLETE_INPUT === $this->state + ) { + return null; + } + + // This is a core/freeform text block, it’s special. + if ( $this->is_html() ) { + return null; + } + + $block_type = substr( $this->source_text, $this->namespace_at, $this->name_at - $this->namespace_at + $this->name_length ); + return self::normalize_block_type( $block_type ); + } + + /** + * Allocates a printable substring for the block type and returns the fully-qualified + * name, including the namespace, if matched on a delimiter or freeform block, otherwise `null`. + * + * This function is like {@see self::get_block_type()} but when paused on a freeform + * HTML block, will return “core/freeform” instead of `null`. The `null` behavior matches + * what {@see \parse_blocks()} returns but may not be as useful as having a string value. + * + * This function allocates a substring for the given block type. This + * allocation will be small and likely fine in most cases, but it's + * preferable to call {@see self::is_block_type()} if only needing + * to know whether the delimiter is for a given block type, as that + * function is more efficient for this purpose and avoids the allocation. + * + * Example: + * + * // Avoid. + * 'core/paragraph' = $processor->get_printable_block_type(); + * + * // Prefer. + * $processor->is_block_type( 'core/paragraph' ); + * $processor->is_block_type( 'paragraph' ); + * $processor->is_block_type( 'core/freeform' ); + * + * // Freeform HTML content is given an implicit type. + * $processor = new WP_Block_Processor( 'non-block content' ); + * $processor->next_token(); + * 'core/freeform' === $processor->get_printable_block_type(); + * + * @since 6.9.0 + * + * @see self::are_equal_block_types() + * + * @return string|null Fully-qualified block namespace and type, e.g. "core/paragraph", + * if matched on an explicit delimiter or freeform block, otherwise `null`. + */ + public function get_printable_block_type(): ?string { + if ( + self::READY === $this->state || + self::COMPLETE === $this->state || + self::INCOMPLETE_INPUT === $this->state + ) { + return null; + } + + // This is a core/freeform text block, it’s special. + if ( $this->is_html() ) { + return 1 === count( $this->open_blocks_at ) + ? 'core/freeform' + : '#innerHTML'; + } + + $block_type = substr( $this->source_text, $this->namespace_at, $this->name_at - $this->namespace_at + $this->name_length ); + return self::normalize_block_type( $block_type ); + } + + /** + * Normalizes a block name to ensure that missing implicit “core” namespaces are present. + * + * Example: + * + * 'core/paragraph' === WP_Block_Processor::normalize_block_byte( 'paragraph' ); + * 'core/paragraph' === WP_Block_Processor::normalize_block_byte( 'core/paragraph' ); + * 'my/paragraph' === WP_Block_Processor::normalize_block_byte( 'my/paragraph' ); + * + * @since 6.9.0 + * + * @param string $block_type Valid block name, potentially without a namespace. + * @return string Fully-qualified block type including namespace. + */ + public static function normalize_block_type( string $block_type ): string { + return false === strpos( $block_type, '/' ) + ? "core/{$block_type}" + : $block_type; + } + + /** + * Returns a lazy wrapper around the block attributes, which can be used + * for efficiently interacting with the JSON attributes. + * + * This stub hints that there should be a lazy interface for parsing + * block attributes but doesn’t define it. It serves both as a placeholder + * for one to come as well as a guard against implementing an eager + * function in its place. + * + * @throws Exception This function is a stub for subclasses to implement + * when providing streaming attribute parsing. + * + * @since 6.9.0 + * + * @see self::allocate_and_return_parsed_attributes() + * + * @return never + */ + public function get_attributes() { + throw new Exception( 'Lazy attribute parsing not yet supported' ); + } + + /** + * Attempts to parse and return the entire JSON attributes from the delimiter, + * allocating memory and processing the JSON span in the process. + * + * This does not return any parsed attributes for a closing block delimiter + * even if there is a span of JSON content; this JSON is a parsing error. + * + * Consider calling {@see static::get_attributes()} instead if it's not + * necessary to read all the attributes at the same time, as that provides + * a more efficient mechanism for typical use cases. + * + * Since the JSON span inside the comment delimiter may not be valid JSON, + * this function will return `null` if it cannot parse the span and set the + * {@see static::get_last_json_error()} to the appropriate JSON_ERROR_ constant. + * + * If the delimiter contains no JSON span, it will also return `null`, + * but the last error will be set to {@see \JSON_ERROR_NONE}. + * + * Example: + * + * $processor = new WP_Block_Processor( '' ); + * $processor->next_delimiter(); + * $memory_hungry_and_slow_attributes = $processor->allocate_and_return_parsed_attributes(); + * $memory_hungry_and_slow_attributes === array( 'url' => 'https://wordpress.org/favicon.ico' ); + * + * $processor = new WP_Block_Processor( '' ); + * $processor->next_delimiter(); + * null = $processor->allocate_and_return_parsed_attributes(); + * JSON_ERROR_NONE = $processor->get_last_json_error(); + * + * $processor = new WP_Block_Processor( '' ); + * $processor->next_delimiter(); + * array() === $processor->allocate_and_return_parsed_attributes(); + * + * $processor = new WP_Block_Processor( '' ); + * $processor->next_delimiter(); + * null = $processor->allocate_and_return_parsed_attributes(); + * + * $processor = new WP_Block_Processor( '' ); + * $processor->next_delimiter(); + * null = $processor->allocate_and_return_parsed_attributes(); + * JSON_ERROR_CTRL_CHAR = $processor->get_last_json_error(); + * + * @since 6.9.0 + * + * @return array|null Parsed JSON attributes, if present and valid, otherwise `null`. + */ + public function allocate_and_return_parsed_attributes(): ?array { + $this->last_json_error = JSON_ERROR_NONE; + + if ( self::CLOSER === $this->type || $this->is_html() || 0 === $this->json_length ) { + return null; + } + + $json_span = substr( $this->source_text, $this->json_at, $this->json_length ); + $parsed = json_decode( $json_span, null, 512, JSON_OBJECT_AS_ARRAY | JSON_INVALID_UTF8_SUBSTITUTE ); + + $last_error = json_last_error(); + $this->last_json_error = $last_error; + + return ( JSON_ERROR_NONE === $last_error && is_array( $parsed ) ) + ? $parsed + : null; + } + + /** + * Returns the span representing the currently-matched delimiter, if matched, otherwise `null`. + * + * Example: + * + * $processor = new WP_Block_Processor( '' ); + * null === $processor->get_span(); + * + * $processor->next_delimiter(); + * WP_HTML_Span( 0, 17 ) === $processor->get_span(); + * + * @since 6.9.0 + * + * @return WP_HTML_Span|null Span of text in source text spanning matched delimiter. + */ + public function get_span(): ?WP_HTML_Span { + switch ( $this->state ) { + case self::HTML_SPAN: + return new WP_HTML_Span( $this->after_previous_delimiter, $this->matched_delimiter_at - $this->after_previous_delimiter ); + + case self::MATCHED: + return new WP_HTML_Span( $this->matched_delimiter_at, $this->matched_delimiter_length ); + + default: + return null; + } + } + + // + // Constant declarations that would otherwise pollute the top of the class. + // + + /** + * Indicates that the block comment delimiter closes an open block. + * + * @see self::$type + * + * @since 6.9.0 + */ + const CLOSER = 'closer'; + + /** + * Indicates that the block comment delimiter opens a block. + * + * @see self::$type + * + * @since 6.9.0 + */ + const OPENER = 'opener'; + + /** + * Indicates that the block comment delimiter represents a void block + * with no inner content of any kind. + * + * @see self::$type + * + * @since 6.9.0 + */ + const VOID = 'void'; + + /** + * Indicates that the processor is ready to start parsing but hasn’t yet begun. + * + * @see self::$state + * + * @since 6.9.0 + */ + const READY = 'processor-ready'; + + /** + * Indicates that the processor is matched on an explicit block delimiter. + * + * @see self::$state + * + * @since 6.9.0 + */ + const MATCHED = 'processor-matched'; + + /** + * Indicates that the processor is matched on the opening of an implicit freeform delimiter. + * + * @see self::$state + * + * @since 6.9.0 + */ + const HTML_SPAN = 'processor-html-span'; + + /** + * Indicates that the parser started parsing a block comment delimiter, but + * the input document ended before it could finish. The document was likely truncated. + * + * @see self::$state + * + * @since 6.9.0 + */ + const INCOMPLETE_INPUT = 'incomplete-input'; + + /** + * Indicates that the processor has finished parsing and has nothing left to scan. + * + * @see self::$state + * + * @since 6.9.0 + */ + const COMPLETE = 'processor-complete'; +} diff --git a/wp-includes/class-wp-block-styles-registry.php b/wp-includes/class-wp-block-styles-registry.php index 9a990173b..60c799898 100644 --- a/wp-includes/class-wp-block-styles-registry.php +++ b/wp-includes/class-wp-block-styles-registry.php @@ -140,7 +140,7 @@ final class WP_Block_Styles_Registry { * * @param string $block_name Block type name including namespace. * @param string $block_style_name Block style name. - * @return array Registered block style properties. + * @return array|null Registered block style properties or `null` if the block style is not registered. */ public function get_registered( $block_name, $block_style_name ) { if ( ! $this->is_registered( $block_name, $block_style_name ) ) { @@ -181,12 +181,12 @@ final class WP_Block_Styles_Registry { * * @since 5.3.0 * - * @param string $block_name Block type name including namespace. - * @param string $block_style_name Block style name. + * @param string|null $block_name Block type name including namespace. + * @param string|null $block_style_name Block style name. * @return bool True if the block style is registered, false otherwise. */ public function is_registered( $block_name, $block_style_name ) { - return isset( $this->registered_block_styles[ $block_name ][ $block_style_name ] ); + return isset( $block_name, $block_style_name, $this->registered_block_styles[ $block_name ][ $block_style_name ] ); } /** diff --git a/wp-includes/class-wp-block-templates-registry.php b/wp-includes/class-wp-block-templates-registry.php index 1a1c259db..eff23ccf0 100644 --- a/wp-includes/class-wp-block-templates-registry.php +++ b/wp-includes/class-wp-block-templates-registry.php @@ -60,11 +60,8 @@ final class WP_Block_Templates_Registry { } if ( $error_message ) { - _doing_it_wrong( - __METHOD__, - $error_message, - '6.7.0' - ); + _doing_it_wrong( __METHOD__, $error_message, '6.7.0' ); + return new WP_Error( $error_code, $error_message ); } @@ -204,11 +201,11 @@ final class WP_Block_Templates_Registry { * * @since 6.7.0 * - * @param string $template_name Template name. + * @param string|null $template_name Template name. * @return bool True if the template is registered, false otherwise. */ public function is_registered( $template_name ) { - return isset( $this->registered_templates[ $template_name ] ); + return isset( $template_name, $this->registered_templates[ $template_name ] ); } /** @@ -221,14 +218,12 @@ final class WP_Block_Templates_Registry { */ public function unregister( $template_name ) { if ( ! $this->is_registered( $template_name ) ) { - _doing_it_wrong( - __METHOD__, - /* translators: %s: Template name. */ - sprintf( __( 'Template "%s" is not registered.' ), $template_name ), - '6.7.0' - ); /* translators: %s: Template name. */ - return new WP_Error( 'template_not_registered', __( 'Template "%s" is not registered.' ) ); + $error_message = sprintf( __( 'Template "%s" is not registered.' ), $template_name ); + + _doing_it_wrong( __METHOD__, $error_message, '6.7.0' ); + + return new WP_Error( 'template_not_registered', $error_message ); } $unregistered_template = $this->registered_templates[ $template_name ]; diff --git a/wp-includes/class-wp-block-type-registry.php b/wp-includes/class-wp-block-type-registry.php index 49e7bd60a..969f0f0f6 100644 --- a/wp-includes/class-wp-block-type-registry.php +++ b/wp-includes/class-wp-block-type-registry.php @@ -134,7 +134,7 @@ final class WP_Block_Type_Registry { * * @since 5.0.0 * - * @param string $name Block type name including namespace. + * @param string|null $name Block type name including namespace. * @return WP_Block_Type|null The registered block type, or null if it is not registered. */ public function get_registered( $name ) { @@ -161,11 +161,11 @@ final class WP_Block_Type_Registry { * * @since 5.0.0 * - * @param string $name Block type name including namespace. + * @param string|null $name Block type name including namespace. * @return bool True if the block type is registered, false otherwise. */ public function is_registered( $name ) { - return isset( $this->registered_block_types[ $name ] ); + return isset( $name, $this->registered_block_types[ $name ] ); } public function __wakeup() { diff --git a/wp-includes/class-wp-block.php b/wp-includes/class-wp-block.php index d8fb177eb..518824618 100644 --- a/wp-includes/class-wp-block.php +++ b/wp-includes/class-wp-block.php @@ -29,7 +29,7 @@ class WP_Block { * @example "core/paragraph" * * @since 5.5.0 - * @var string + * @var string|null */ public $name; @@ -54,7 +54,6 @@ class WP_Block { * * @since 5.5.0 * @var array - * @access protected */ protected $available_context = array(); @@ -63,7 +62,6 @@ class WP_Block { * * @since 5.9.0 * @var WP_Block_Type_Registry - * @access protected */ protected $registry; @@ -116,12 +114,12 @@ class WP_Block { * @param array $block { * An associative array of a single parsed block object. See WP_Block_Parser_Block. * - * @type string $blockName Name of block. - * @type array $attrs Attributes from block comment delimiters. - * @type array $innerBlocks List of inner blocks. An array of arrays that - * have the same structure as this one. - * @type string $innerHTML HTML from inside block comment delimiters. - * @type array $innerContent List of string fragments and null markers where inner blocks were found. + * @type string|null $blockName Name of block. + * @type array $attrs Attributes from block comment delimiters. + * @type array $innerBlocks List of inner blocks. An array of arrays that + * have the same structure as this one. + * @type string $innerHTML HTML from inside block comment delimiters. + * @type array $innerContent List of string fragments and null markers where inner blocks were found. * } * @param array $available_context Optional array of ancestry context values. * @param WP_Block_Type_Registry $registry Optional block type registry. @@ -280,19 +278,15 @@ class WP_Block { * @return array The computed block attributes for the provided block bindings. */ private function process_block_bindings() { + $block_type = $this->name; $parsed_block = $this->parsed_block; $computed_attributes = array(); - $supported_block_attributes = array( - 'core/paragraph' => array( 'content' ), - 'core/heading' => array( 'content' ), - 'core/image' => array( 'id', 'url', 'title', 'alt' ), - 'core/button' => array( 'url', 'text', 'linkTarget', 'rel' ), - ); + $supported_block_attributes = get_block_bindings_supported_attributes( $block_type ); // If the block doesn't have the bindings property, isn't one of the supported // block types, or the bindings property is not an array, return the block content. if ( - ! isset( $supported_block_attributes[ $this->name ] ) || + empty( $supported_block_attributes ) || empty( $parsed_block['attrs']['metadata']['bindings'] ) || ! is_array( $parsed_block['attrs']['metadata']['bindings'] ) ) { @@ -316,7 +310,7 @@ class WP_Block { * Note that this also omits the `__default` attribute from the * resulting array. */ - foreach ( $supported_block_attributes[ $parsed_block['blockName'] ] as $attribute_name ) { + foreach ( $supported_block_attributes as $attribute_name ) { // Retain any non-pattern override bindings that might be present. $updated_bindings[ $attribute_name ] = isset( $bindings[ $attribute_name ] ) ? $bindings[ $attribute_name ] @@ -335,7 +329,7 @@ class WP_Block { foreach ( $bindings as $attribute_name => $block_binding ) { // If the attribute is not in the supported list, process next attribute. - if ( ! in_array( $attribute_name, $supported_block_attributes[ $this->name ], true ) ) { + if ( ! in_array( $attribute_name, $supported_block_attributes, true ) ) { continue; } // If no source is provided, or that source is not registered, process next attribute. @@ -389,7 +383,7 @@ class WP_Block { switch ( $block_type->attributes[ $attribute_name ]['source'] ) { case 'html': case 'rich-text': - $block_reader = new WP_HTML_Tag_Processor( $block_content ); + $block_reader = self::get_block_bindings_processor( $block_content ); // TODO: Support for CSS selectors whenever they are ready in the HTML API. // In the meantime, support comma-separated selectors by exploding them into an array. @@ -398,18 +392,6 @@ class WP_Block { $block_reader->next_tag(); $block_reader->set_bookmark( 'iterate-selectors' ); - // TODO: This shouldn't be needed when the `set_inner_html` function is ready. - // Store the parent tag and its attributes to be able to restore them later in the button. - // The button block has a wrapper while the paragraph and heading blocks don't. - if ( 'core/button' === $this->name ) { - $button_wrapper = $block_reader->get_tag(); - $button_wrapper_attribute_names = $block_reader->get_attribute_names_with_prefix( '' ); - $button_wrapper_attrs = array(); - foreach ( $button_wrapper_attribute_names as $name ) { - $button_wrapper_attrs[ $name ] = $block_reader->get_attribute( $name ); - } - } - foreach ( $selectors as $selector ) { // If the parent tag, or any of its children, matches the selector, replace the HTML. if ( strcasecmp( $block_reader->get_tag(), $selector ) === 0 || $block_reader->next_tag( @@ -417,34 +399,10 @@ class WP_Block { 'tag_name' => $selector, ) ) ) { + // TODO: Use `WP_HTML_Processor::set_inner_html` method once it's available. $block_reader->release_bookmark( 'iterate-selectors' ); - - // TODO: Use `set_inner_html` method whenever it's ready in the HTML API. - // Until then, it is hardcoded for the paragraph, heading, and button blocks. - // Store the tag and its attributes to be able to restore them later. - $selector_attribute_names = $block_reader->get_attribute_names_with_prefix( '' ); - $selector_attrs = array(); - foreach ( $selector_attribute_names as $name ) { - $selector_attrs[ $name ] = $block_reader->get_attribute( $name ); - } - $selector_markup = "<$selector>" . wp_kses_post( $source_value ) . ""; - $amended_content = new WP_HTML_Tag_Processor( $selector_markup ); - $amended_content->next_tag(); - foreach ( $selector_attrs as $attribute_key => $attribute_value ) { - $amended_content->set_attribute( $attribute_key, $attribute_value ); - } - if ( 'core/paragraph' === $this->name || 'core/heading' === $this->name ) { - return $amended_content->get_updated_html(); - } - if ( 'core/button' === $this->name ) { - $button_markup = "<$button_wrapper>{$amended_content->get_updated_html()}"; - $amended_button = new WP_HTML_Tag_Processor( $button_markup ); - $amended_button->next_tag(); - foreach ( $button_wrapper_attrs as $attribute_key => $attribute_value ) { - $amended_button->set_attribute( $attribute_key, $attribute_value ); - } - return $amended_button->get_updated_html(); - } + $block_reader->replace_rich_text( wp_kses_post( $source_value ) ); + return $block_reader->get_updated_html(); } else { $block_reader->seek( 'iterate-selectors' ); } @@ -470,6 +428,54 @@ class WP_Block { } } + private static function get_block_bindings_processor( string $block_content ) { + $internal_processor_class = new class('', WP_HTML_Processor::CONSTRUCTOR_UNLOCK_CODE) extends WP_HTML_Processor { + /** + * Replace the rich text content between a tag opener and matching closer. + * + * When stopped on a tag opener, replace the content enclosed by it and its + * matching closer with the provided rich text. + * + * @param string $rich_text The rich text to replace the original content with. + * @return bool True on success. + */ + public function replace_rich_text( $rich_text ) { + if ( $this->is_tag_closer() || ! $this->expects_closer() ) { + return false; + } + + $depth = $this->get_current_depth(); + $tag_name = $this->get_tag(); + + $this->set_bookmark( '_wp_block_bindings' ); + // The bookmark names are prefixed with `_` so the key below has an extra `_`. + $tag_opener = $this->bookmarks['__wp_block_bindings']; + $start = $tag_opener->start + $tag_opener->length; + + // Find matching tag closer. + while ( $this->next_token() && $this->get_current_depth() >= $depth ) { + } + + if ( ! $this->is_tag_closer() || $tag_name !== $this->get_tag() ) { + return false; + } + + $this->set_bookmark( '_wp_block_bindings' ); + $tag_closer = $this->bookmarks['__wp_block_bindings']; + $end = $tag_closer->start; + + $this->lexical_updates[] = new WP_HTML_Text_Replacement( + $start, + $end - $start, + $rich_text + ); + + return true; + } + }; + + return $internal_processor_class::create_fragment( $block_content ); + } /** * Generates the render output for the block. @@ -489,6 +495,13 @@ class WP_Block { public function render( $options = array() ) { global $post; + $before_wp_enqueue_scripts_count = did_action( 'wp_enqueue_scripts' ); + + // Capture the current assets queues. + $before_styles_queue = wp_styles()->queue; + $before_scripts_queue = wp_scripts()->queue; + $before_script_modules_queue = wp_script_modules()->get_queue(); + /* * There can be only one root interactive block at a time because the rendered HTML of that block contains * the rendered HTML of all its inner blocks, including any interactive block. @@ -658,6 +671,50 @@ class WP_Block { $root_interactive_block = null; } + // Capture the new assets enqueued during rendering, and restore the queues the state prior to rendering. + $after_styles_queue = wp_styles()->queue; + $after_scripts_queue = wp_scripts()->queue; + $after_script_modules_queue = wp_script_modules()->get_queue(); + + /* + * As a very special case, a dynamic block may in fact include a call to wp_head() (and thus wp_enqueue_scripts()), + * in which all of its enqueued assets are targeting wp_footer. In this case, nothing would be printed, but this + * shouldn't indicate that the just-enqueued assets should be dequeued due to it being an empty block. + */ + $just_did_wp_enqueue_scripts = ( did_action( 'wp_enqueue_scripts' ) !== $before_wp_enqueue_scripts_count ); + + $has_new_styles = ( $before_styles_queue !== $after_styles_queue ); + $has_new_scripts = ( $before_scripts_queue !== $after_scripts_queue ); + $has_new_script_modules = ( $before_script_modules_queue !== $after_script_modules_queue ); + + // Dequeue the newly enqueued assets with the existing assets if the rendered block was empty & wp_enqueue_scripts did not fire. + if ( + ! $just_did_wp_enqueue_scripts && + ( $has_new_styles || $has_new_scripts || $has_new_script_modules ) && + ( + trim( $block_content ) === '' && + /** + * Filters whether to enqueue assets for a block which has no rendered content. + * + * @since 6.9.0 + * + * @param bool $enqueue Whether to enqueue assets. + * @param string $block_name Block name. + */ + ! (bool) apply_filters( 'enqueue_empty_block_content_assets', false, $this->name ) + ) + ) { + foreach ( array_diff( $after_styles_queue, $before_styles_queue ) as $handle ) { + wp_dequeue_style( $handle ); + } + foreach ( array_diff( $after_scripts_queue, $before_scripts_queue ) as $handle ) { + wp_dequeue_script( $handle ); + } + foreach ( array_diff( $after_script_modules_queue, $before_script_modules_queue ) as $handle ) { + wp_dequeue_script_module( $handle ); + } + } + return $block_content; } } diff --git a/wp-includes/class-wp-classic-to-block-menu-converter.php b/wp-includes/class-wp-classic-to-block-menu-converter.php index 6430aab6f..b3cc81990 100644 --- a/wp-includes/class-wp-classic-to-block-menu-converter.php +++ b/wp-includes/class-wp-classic-to-block-menu-converter.php @@ -10,7 +10,6 @@ * Converts a Classic Menu to Block Menu blocks. * * @since 6.3.0 - * @access public */ class WP_Classic_To_Block_Menu_Converter { diff --git a/wp-includes/class-wp-comment-query.php b/wp-includes/class-wp-comment-query.php index 6a72c0d20..b2a9275c5 100644 --- a/wp-includes/class-wp-comment-query.php +++ b/wp-includes/class-wp-comment-query.php @@ -451,8 +451,8 @@ class WP_Comment_Query { $key = md5( serialize( $_args ) ); $last_changed = wp_cache_get_last_changed( 'comment' ); - $cache_key = "get_comments:$key:$last_changed"; - $cache_value = wp_cache_get( $cache_key, 'comment-queries' ); + $cache_key = "get_comments:$key"; + $cache_value = wp_cache_get_salted( $cache_key, 'comment-queries', $last_changed ); if ( false === $cache_value ) { $comment_ids = $this->get_comment_ids(); if ( $comment_ids ) { @@ -463,7 +463,7 @@ class WP_Comment_Query { 'comment_ids' => $comment_ids, 'found_comments' => $this->found_comments, ); - wp_cache_add( $cache_key, $cache_value, 'comment-queries' ); + wp_cache_set_salted( $cache_key, $cache_value, 'comment-queries', $last_changed ); } else { $comment_ids = $cache_value['comment_ids']; $this->found_comments = $cache_value['found_comments']; @@ -536,6 +536,7 @@ class WP_Comment_Query { * Used internally to get a list of comment IDs matching the query vars. * * @since 4.4.0 + * @since 6.9.0 Excludes the 'note' comment type, unless 'all' or the 'note' types are requested. * * @global wpdb $wpdb WordPress database abstraction object. * @@ -579,9 +580,7 @@ class WP_Comment_Query { } } - if ( ! empty( $status_clauses ) ) { - $approved_clauses[] = '( ' . implode( ' OR ', $status_clauses ) . ' )'; - } + $approved_clauses[] = '( ' . implode( ' OR ', $status_clauses ) . ' )'; } // User IDs or emails whose unapproved comments are included, regardless of $status. @@ -772,6 +771,15 @@ class WP_Comment_Query { 'NOT IN' => (array) $this->query_vars['type__not_in'], ); + // Exclude the 'note' comment type, unless 'all' types or the 'note' type explicitly are requested. + if ( + ! in_array( 'all', $raw_types['IN'], true ) && + ! in_array( 'note', $raw_types['IN'], true ) && + ! in_array( 'note', $raw_types['NOT IN'], true ) + ) { + $raw_types['NOT IN'][] = 'note'; + } + $comment_types = array(); foreach ( $raw_types as $operator => $_raw_types ) { $_raw_types = array_unique( $_raw_types ); @@ -1046,9 +1054,9 @@ class WP_Comment_Query { if ( $_parent_ids ) { $cache_keys = array(); foreach ( $_parent_ids as $parent_id ) { - $cache_keys[ $parent_id ] = "get_comment_child_ids:$parent_id:$key:$last_changed"; + $cache_keys[ $parent_id ] = "get_comment_child_ids:$parent_id:$key"; } - $cache_data = wp_cache_get_multiple( array_values( $cache_keys ), 'comment-queries' ); + $cache_data = wp_cache_get_multiple_salted( array_values( $cache_keys ), 'comment-queries', $last_changed ); foreach ( $_parent_ids as $parent_id ) { $parent_child_ids = $cache_data[ $cache_keys[ $parent_id ] ]; if ( false !== $parent_child_ids ) { @@ -1082,10 +1090,10 @@ class WP_Comment_Query { $data = array(); foreach ( $parent_map as $parent_id => $children ) { - $cache_key = "get_comment_child_ids:$parent_id:$key:$last_changed"; + $cache_key = "get_comment_child_ids:$parent_id:$key"; $data[ $cache_key ] = $children; } - wp_cache_set_multiple( $data, 'comment-queries' ); + wp_cache_set_multiple_salted( $data, 'comment-queries', $last_changed ); } ++$level; diff --git a/wp-includes/class-wp-customize-control.php b/wp-includes/class-wp-customize-control.php index e6697078d..43f0ac6d4 100644 --- a/wp-includes/class-wp-customize-control.php +++ b/wp-includes/class-wp-customize-control.php @@ -124,7 +124,7 @@ class WP_Customize_Control { /** * List of custom input attributes for control output, where attribute names are the keys and values are the values. * - * Not used for 'checkbox', 'radio', 'select', 'textarea', or 'dropdown-pages' control types. + * Not used for 'checkbox', 'radio', 'select', or 'dropdown-pages' control types. * * @since 4.0.0 * @var array @@ -201,8 +201,8 @@ class WP_Customize_Control { * Default empty array. * @type array $input_attrs List of custom input attributes for control output, where * attribute names are the keys and values are the values. Not - * used for 'checkbox', 'radio', 'select', 'textarea', or - * 'dropdown-pages' control types. Default empty array. + * used for 'checkbox', 'radio', 'select', or 'dropdown-pages' + * control types. Default empty array. * @type bool $allow_addition Show UI for adding new content, currently only used for the * dropdown-pages control. Default false. * @type array $json Deprecated. Use WP_Customize_Control::json() instead. @@ -566,6 +566,9 @@ class WP_Customize_Control { input_attrs ) ) { + $this->input_attrs['rows'] = 5; + } ?> label ) ) : ?> @@ -575,7 +578,6 @@ class WP_Customize_Control { - * - * ); - * ); - * ``` - */ -const BaseControl = Object.assign(contextConnectWithoutRef(UnconnectedBaseControl, 'BaseControl'), { +const BaseControl = Object.assign(contextConnectWithoutRef(UnconnectedBaseControl, "BaseControl"), { /** * `BaseControl.VisualLabel` is used to render a purely visual label inside a `BaseControl` component. * @@ -31793,12 +31883,10 @@ const BaseControl = Object.assign(contextConnectWithoutRef(UnconnectedBaseContro */ VisualLabel }); -/* harmony default export */ const base_control = (BaseControl); +var base_control_default = BaseControl; + ;// ./node_modules/@wordpress/components/build-module/utils/deprecated-36px-size.js -/** - * WordPress dependencies - */ function maybeWarnDeprecated36pxSize({ componentName, @@ -31806,30 +31894,18 @@ function maybeWarnDeprecated36pxSize({ size, __shouldNotWarnDeprecated36pxSize }) { - if (__shouldNotWarnDeprecated36pxSize || __next40pxDefaultSize || size !== undefined && size !== 'default') { + if (__shouldNotWarnDeprecated36pxSize || __next40pxDefaultSize || size !== void 0 && size !== "default") { return; } external_wp_deprecated_default()(`36px default size for wp.components.${componentName}`, { - since: '6.8', - version: '7.1', - hint: 'Set the `__next40pxDefaultSize` prop to true to start opting into the new default size, which will become the default in a future version.' + since: "6.8", + version: "7.1", + hint: "Set the `__next40pxDefaultSize` prop to true to start opting into the new default size, which will become the default in a future version." }); } + ;// ./node_modules/@wordpress/components/build-module/input-control/index.js -/** - * External dependencies - */ - -/** - * WordPress dependencies - */ - - - -/** - * Internal dependencies - */ @@ -31838,7 +31914,11 @@ function maybeWarnDeprecated36pxSize({ -const input_control_noop = () => {}; + + + +const input_control_noop = () => { +}; function input_control_useUniqueId(idProp) { const instanceId = (0,external_wp_compose_namespaceObject.useInstanceId)(InputControl); const id = `inspector-input-control-${instanceId}`; @@ -31848,7 +31928,7 @@ function UnforwardedInputControl(props, ref) { const { __next40pxDefaultSize, __shouldNotWarnDeprecated36pxSize, - __unstableStateReducer: stateReducer = state => state, + __unstableStateReducer: stateReducer = (state) => state, __unstableInputWidth, className, disabled = false, @@ -31857,111 +31937,78 @@ function UnforwardedInputControl(props, ref) { id: idProp, isPressEnterToChange = false, label, - labelPosition = 'top', + labelPosition = "top", onChange = input_control_noop, onValidate = input_control_noop, onKeyDown = input_control_noop, prefix, - size = 'default', + size = "default", style, suffix, value, ...restProps } = useDeprecated36pxDefaultSizeProp(props); const id = input_control_useUniqueId(idProp); - const classes = dist_clsx('components-input-control', className); + const classes = dist_clsx("components-input-control", className); const draftHookProps = useDraft({ value, onBlur: restProps.onBlur, onChange }); const helpProp = !!help ? { - 'aria-describedby': `${id}__help` + "aria-describedby": `${id}__help` } : {}; maybeWarnDeprecated36pxSize({ - componentName: 'InputControl', + componentName: "InputControl", __next40pxDefaultSize, size, __shouldNotWarnDeprecated36pxSize }); - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(base_control, { + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(base_control_default, { className: classes, - help: help, - id: id, + help, + id, __nextHasNoMarginBottom: true, - children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(input_base, { - __next40pxDefaultSize: __next40pxDefaultSize, - __unstableInputWidth: __unstableInputWidth, - disabled: disabled, + children: /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(input_base_default, { + __next40pxDefaultSize, + __unstableInputWidth, + disabled, gap: 3, - hideLabelFromVision: hideLabelFromVision, - id: id, + hideLabelFromVision, + id, justify: "left", - label: label, - labelPosition: labelPosition, - prefix: prefix, - size: size, - style: style, - suffix: suffix, - children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(input_field, { + label, + labelPosition, + prefix, + size, + style, + suffix, + children: /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(input_field_default, { ...restProps, ...helpProp, - __next40pxDefaultSize: __next40pxDefaultSize, + __next40pxDefaultSize, className: "components-input-control__input", - disabled: disabled, - id: id, - isPressEnterToChange: isPressEnterToChange, - onKeyDown: onKeyDown, - onValidate: onValidate, - paddingInlineStart: prefix ? space(1) : undefined, - paddingInlineEnd: suffix ? space(1) : undefined, - ref: ref, - size: size, - stateReducer: stateReducer, + disabled, + id, + isPressEnterToChange, + onKeyDown, + onValidate, + paddingInlineStart: prefix ? space(1) : void 0, + paddingInlineEnd: suffix ? space(1) : void 0, + ref, + size, + stateReducer, ...draftHookProps }) }) }); } - -/** - * InputControl components let users enter and edit text. This is an experimental component - * intended to (in time) merge with or replace `TextControl`. - * - * ```jsx - * import { __experimentalInputControl as InputControl } from '@wordpress/components'; - * import { useState } from 'react'; - * - * const Example = () => { - * const [ value, setValue ] = useState( '' ); - * - * return ( - * setValue( nextValue ?? '' ) } - * /> - * ); - * }; - * ``` - */ const InputControl = (0,external_wp_element_namespaceObject.forwardRef)(UnforwardedInputControl); -/* harmony default export */ const input_control = (InputControl); +var input_control_default = InputControl; + ;// ./node_modules/@wordpress/components/build-module/dashicon/index.js -/** - * @typedef OwnProps - * - * @property {import('./types').IconKey} icon Icon name - * @property {string} [className] Class name - * @property {number} [size] Size of the icon - */ - -/** - * Internal dependencies - */ - function Dashicon({ icon, className, @@ -31969,85 +32016,65 @@ function Dashicon({ style = {}, ...extraProps }) { - const iconClass = ['dashicon', 'dashicons', 'dashicons-' + icon, className].filter(Boolean).join(' '); - - // For retro-compatibility reasons (for example if people are overriding icon size with CSS), we add inline styles just if the size is different to the default - const sizeStyles = - // using `!=` to catch both 20 and "20" - // eslint-disable-next-line eqeqeq - 20 != size ? { - fontSize: `${size}px`, - width: `${size}px`, - height: `${size}px` - } : {}; + const iconClass = ["dashicon", "dashicons", "dashicons-" + icon, className].filter(Boolean).join(" "); + const sizeStyles = ( + // using `!=` to catch both 20 and "20" + // eslint-disable-next-line eqeqeq + 20 != size ? { + fontSize: `${size}px`, + width: `${size}px`, + height: `${size}px` + } : {} + ); const styles = { ...sizeStyles, ...style }; - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { className: iconClass, style: styles, ...extraProps }); } -/* harmony default export */ const dashicon = (Dashicon); +var dashicon_default = Dashicon; + ;// ./node_modules/@wordpress/components/build-module/icon/index.js -/** - * External dependencies - */ - -/** - * WordPress dependencies - */ -/** - * Internal dependencies - */ - -/** - * Renders a raw icon without any initial styling or wrappers. - * - * ```jsx - * import { wordpress } from '@wordpress/icons'; - * - * - * ``` - */ function Icon({ icon = null, - size = 'string' === typeof icon ? 20 : 24, + size = "string" === typeof icon ? 20 : 24, ...additionalProps }) { - if ('string' === typeof icon) { - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(dashicon, { - icon: icon, - size: size, + if ("string" === typeof icon) { + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(dashicon_default, { + icon, + size, ...additionalProps }); } - if ((0,external_wp_element_namespaceObject.isValidElement)(icon) && dashicon === icon.type) { + if ((0,external_wp_element_namespaceObject.isValidElement)(icon) && dashicon_default === icon.type) { return (0,external_wp_element_namespaceObject.cloneElement)(icon, { ...additionalProps }); } - if ('function' === typeof icon) { + if ("function" === typeof icon) { return (0,external_wp_element_namespaceObject.createElement)(icon, { size, ...additionalProps }); } - if (icon && (icon.type === 'svg' || icon.type === external_wp_primitives_namespaceObject.SVG)) { + if (icon && (icon.type === "svg" || icon.type === external_wp_primitives_namespaceObject.SVG)) { const appliedProps = { ...icon.props, width: size, height: size, ...additionalProps }; - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { ...appliedProps }); } @@ -32055,34 +32082,27 @@ function Icon({ return (0,external_wp_element_namespaceObject.cloneElement)(icon, { // @ts-ignore Just forwarding the size prop along size, + width: size, + height: size, ...additionalProps }); } return icon; } -/* harmony default export */ const build_module_icon = (Icon); +var icon_icon_default = Icon; + ;// ./node_modules/@wordpress/components/build-module/button/index.js -/** - * External dependencies - */ - -/** - * WordPress dependencies - */ - - - - -/** - * Internal dependencies - */ -const disabledEventsOnDisabledButton = ['onMouseDown', 'onClick']; + + + + +const disabledEventsOnDisabledButton = ["onMouseDown", "onClick"]; function button_useDeprecatedProps({ __experimentalIsFocusable, isDefault, @@ -32102,36 +32122,36 @@ function button_useDeprecatedProps({ const newProps = { accessibleWhenDisabled: __experimentalIsFocusable, // @todo Mark `isPressed` as deprecated - 'aria-pressed': isPressed, + "aria-pressed": isPressed, description: describedBy }; if (isSmall) { var _computedSize; - (_computedSize = computedSize) !== null && _computedSize !== void 0 ? _computedSize : computedSize = 'small'; + (_computedSize = computedSize) !== null && _computedSize !== void 0 ? _computedSize : computedSize = "small"; } if (isPrimary) { var _computedVariant; - (_computedVariant = computedVariant) !== null && _computedVariant !== void 0 ? _computedVariant : computedVariant = 'primary'; + (_computedVariant = computedVariant) !== null && _computedVariant !== void 0 ? _computedVariant : computedVariant = "primary"; } if (isTertiary) { var _computedVariant2; - (_computedVariant2 = computedVariant) !== null && _computedVariant2 !== void 0 ? _computedVariant2 : computedVariant = 'tertiary'; + (_computedVariant2 = computedVariant) !== null && _computedVariant2 !== void 0 ? _computedVariant2 : computedVariant = "tertiary"; } if (isSecondary) { var _computedVariant3; - (_computedVariant3 = computedVariant) !== null && _computedVariant3 !== void 0 ? _computedVariant3 : computedVariant = 'secondary'; + (_computedVariant3 = computedVariant) !== null && _computedVariant3 !== void 0 ? _computedVariant3 : computedVariant = "secondary"; } if (isDefault) { var _computedVariant4; - external_wp_deprecated_default()('wp.components.Button `isDefault` prop', { - since: '5.4', + external_wp_deprecated_default()("wp.components.Button `isDefault` prop", { + since: "5.4", alternative: 'variant="secondary"' }); - (_computedVariant4 = computedVariant) !== null && _computedVariant4 !== void 0 ? _computedVariant4 : computedVariant = 'secondary'; + (_computedVariant4 = computedVariant) !== null && _computedVariant4 !== void 0 ? _computedVariant4 : computedVariant = "secondary"; } if (isLink) { var _computedVariant5; - (_computedVariant5 = computedVariant) !== null && _computedVariant5 !== void 0 ? _computedVariant5 : computedVariant = 'link'; + (_computedVariant5 = computedVariant) !== null && _computedVariant5 !== void 0 ? _computedVariant5 : computedVariant = "link"; } return { ...newProps, @@ -32149,14 +32169,14 @@ function UnforwardedButton(props, ref) { className, disabled, icon, - iconPosition = 'left', + iconPosition = "left", iconSize, showTooltip, tooltipPosition, shortcut, label, children, - size = 'default', + size = "default", text, variant, description, @@ -32165,56 +32185,54 @@ function UnforwardedButton(props, ref) { const { href, target, - 'aria-checked': ariaChecked, - 'aria-pressed': ariaPressed, - 'aria-selected': ariaSelected, + "aria-checked": ariaChecked, + "aria-pressed": ariaPressed, + "aria-selected": ariaSelected, ...additionalProps - } = 'href' in buttonOrAnchorProps ? buttonOrAnchorProps : { - href: undefined, - target: undefined, + } = "href" in buttonOrAnchorProps ? buttonOrAnchorProps : { + href: void 0, + target: void 0, ...buttonOrAnchorProps }; - const instanceId = (0,external_wp_compose_namespaceObject.useInstanceId)(Button, 'components-button__description'); - const hasChildren = 'string' === typeof children && !!children || Array.isArray(children) && children?.[0] && children[0] !== null && - // Tooltip should not considered as a child - children?.[0]?.props?.className !== 'components-tooltip'; - const truthyAriaPressedValues = [true, 'true', 'mixed']; - const classes = dist_clsx('components-button', className, { - 'is-next-40px-default-size': __next40pxDefaultSize, - 'is-secondary': variant === 'secondary', - 'is-primary': variant === 'primary', - 'is-small': size === 'small', - 'is-compact': size === 'compact', - 'is-tertiary': variant === 'tertiary', - 'is-pressed': truthyAriaPressedValues.includes(ariaPressed), - 'is-pressed-mixed': ariaPressed === 'mixed', - 'is-busy': isBusy, - 'is-link': variant === 'link', - 'is-destructive': isDestructive, - 'has-text': !!icon && (hasChildren || text), - 'has-icon': !!icon + const instanceId = (0,external_wp_compose_namespaceObject.useInstanceId)(Button, "components-button__description"); + const hasChildren = "string" === typeof children && !!children || Array.isArray(children) && children?.[0] && children[0] !== null && // Tooltip should not considered as a child + children?.[0]?.props?.className !== "components-tooltip"; + const truthyAriaPressedValues = [true, "true", "mixed"]; + const classes = dist_clsx("components-button", className, { + "is-next-40px-default-size": __next40pxDefaultSize, + "is-secondary": variant === "secondary", + "is-primary": variant === "primary", + "is-small": size === "small", + "is-compact": size === "compact", + "is-tertiary": variant === "tertiary", + "is-pressed": truthyAriaPressedValues.includes(ariaPressed), + "is-pressed-mixed": ariaPressed === "mixed", + "is-busy": isBusy, + "is-link": variant === "link", + "is-destructive": isDestructive, + "has-text": !!icon && (hasChildren || text), + "has-icon": !!icon, + "has-icon-right": iconPosition === "right" }); const trulyDisabled = disabled && !accessibleWhenDisabled; - const Tag = href !== undefined && !disabled ? 'a' : 'button'; - const buttonProps = Tag === 'button' ? { - type: 'button', + const Tag = href !== void 0 && !disabled ? "a" : "button"; + const buttonProps = Tag === "button" ? { + type: "button", disabled: trulyDisabled, - 'aria-checked': ariaChecked, - 'aria-pressed': ariaPressed, - 'aria-selected': ariaSelected + "aria-checked": ariaChecked, + "aria-pressed": ariaPressed, + "aria-selected": ariaSelected } : {}; - const anchorProps = Tag === 'a' ? { + const anchorProps = Tag === "a" ? { href, target } : {}; const disableEventProps = {}; if (disabled && accessibleWhenDisabled) { - // In this case, the button will be disabled, but still focusable and - // perceivable by screen reader users. - buttonProps['aria-disabled'] = true; - anchorProps['aria-disabled'] = true; + buttonProps["aria-disabled"] = true; + anchorProps["aria-disabled"] = true; for (const disabledEvent of disabledEventsOnDisabledButton) { - disableEventProps[disabledEvent] = event => { + disableEventProps[disabledEvent] = (event) => { if (event) { event.stopPropagation(); event.preventDefault(); @@ -32222,104 +32240,72 @@ function UnforwardedButton(props, ref) { }; } } - - // Should show the tooltip if... - const shouldShowTooltip = !trulyDisabled && ( - // An explicit tooltip is passed or... - showTooltip && !!label || - // There's a shortcut or... - !!shortcut || - // There's a label and... - !!label && - // The children are empty and... - !children?.length && - // The tooltip is not explicitly disabled. + const shouldShowTooltip = !trulyDisabled && // An explicit tooltip is passed or... + (showTooltip && !!label || // There's a shortcut or... + !!shortcut || // There's a label and... + !!label && // The children are empty and... + !children?.length && // The tooltip is not explicitly disabled. false !== showTooltip); - const descriptionId = description ? instanceId : undefined; - const describedById = additionalProps['aria-describedby'] || descriptionId; + const descriptionId = description ? instanceId : void 0; + const describedById = additionalProps["aria-describedby"] || descriptionId; const commonProps = { className: classes, - 'aria-label': additionalProps['aria-label'] || label, - 'aria-describedby': describedById, + "aria-label": additionalProps["aria-label"] || label, + "aria-describedby": describedById, ref }; - const elementChildren = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { - children: [icon && iconPosition === 'left' && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(build_module_icon, { - icon: icon, + const elementChildren = /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { + children: [icon && iconPosition === "left" && /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(icon_icon_default, { + icon, size: iconSize - }), text && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_ReactJSXRuntime_namespaceObject.Fragment, { + }), text && /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(external_ReactJSXRuntime_namespaceObject.Fragment, { children: text - }), children, icon && iconPosition === 'right' && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(build_module_icon, { - icon: icon, + }), children, icon && iconPosition === "right" && /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(icon_icon_default, { + icon, size: iconSize })] }); - const element = Tag === 'a' ? /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("a", { + const element = Tag === "a" ? /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)("a", { ...anchorProps, ...additionalProps, ...disableEventProps, ...commonProps, children: elementChildren - }) : /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("button", { + }) : /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)("button", { ...buttonProps, ...additionalProps, ...disableEventProps, ...commonProps, children: elementChildren }); - - // In order to avoid some React reconciliation issues, we are always rendering - // the `Tooltip` component even when `shouldShowTooltip` is `false`. - // In order to make sure that the tooltip doesn't show when it shouldn't, - // we don't pass the props to the `Tooltip` component. const tooltipProps = shouldShowTooltip ? { text: children?.length && description ? description : label, shortcut, - placement: tooltipPosition && - // Convert legacy `position` values to be used with the new `placement` prop + placement: tooltipPosition && // Convert legacy `position` values to be used with the new `placement` prop positionToPlacement(tooltipPosition) } : {}; - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { - children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(tooltip, { + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { + children: [/* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(tooltip_default, { ...tooltipProps, children: element - }), description && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(visually_hidden_component, { - children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { + }), description && /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(component_component_default, { + children: /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { id: descriptionId, children: description }) })] }); } - -/** - * Lets users take actions and make choices with a single click or tap. - * - * ```jsx - * import { Button } from '@wordpress/components'; - * const Mybutton = () => ( - * - * ); - * ``` - */ const Button = (0,external_wp_element_namespaceObject.forwardRef)(UnforwardedButton); -/* harmony default export */ const build_module_button = (Button); +var button_default = Button; + ;// ./node_modules/@wordpress/components/build-module/number-control/styles/number-control-styles.js -function number_control_styles_EMOTION_STRINGIFIED_CSS_ERROR_() { return "You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."; } -/** - * External dependencies - */ +function number_control_styles_EMOTION_STRINGIFIED_CSS_ERROR_() { + return "You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."; +} -/** - * Internal dependencies - */ @@ -32336,207 +32322,157 @@ const htmlArrowStyles = ({ } return number_control_styles_ref; }; -const number_control_styles_Input = /*#__PURE__*/emotion_styled_base_browser_esm(input_control, true ? { +const number_control_styles_Input = /* @__PURE__ */ emotion_styled_base_browser_esm(input_control_default, true ? { target: "ep09it41" } : 0)(htmlArrowStyles, ";" + ( true ? "" : 0)); -const SpinButton = /*#__PURE__*/emotion_styled_base_browser_esm(build_module_button, true ? { +const SpinButton = /* @__PURE__ */ emotion_styled_base_browser_esm(button_default, true ? { target: "ep09it40" } : 0)("&&&&&{color:", COLORS.theme.accent, ";}" + ( true ? "" : 0)); -const smallSpinButtons = /*#__PURE__*/emotion_react_browser_esm_css("width:", space(5), ";min-width:", space(5), ";height:", space(5), ";" + ( true ? "" : 0), true ? "" : 0); +const smallSpinButtons = /* @__PURE__ */ emotion_react_browser_esm_css("width:", space(5), ";min-width:", space(5), ";height:", space(5), ";" + ( true ? "" : 0), true ? "" : 0); const styles = { smallSpinButtons }; + ;// ./node_modules/@wordpress/components/build-module/utils/math.js -/** - * Parses and retrieves a number value. - * - * @param {unknown} value The incoming value. - * - * @return {number} The parsed number value. - */ function getNumber(value) { const number = Number(value); return isNaN(number) ? 0 : number; } - -/** - * Safely adds 2 values. - * - * @param {Array} args Values to add together. - * - * @return {number} The sum of values. - */ function add(...args) { - return args.reduce(/** @type {(sum:number, arg: number|string) => number} */ - (sum, arg) => sum + getNumber(arg), 0); + return args.reduce( + /** @type {(sum:number, arg: number|string) => number} */ + (sum, arg) => sum + getNumber(arg), + 0 + ); } - -/** - * Safely subtracts 2 values. - * - * @param {Array} args Values to subtract together. - * - * @return {number} The difference of the values. - */ function subtract(...args) { - return args.reduce(/** @type {(diff:number, arg: number|string, index:number) => number} */ - (diff, arg, index) => { - const value = getNumber(arg); - return index === 0 ? value : diff - value; - }, 0); + return args.reduce( + /** @type {(diff:number, arg: number|string, index:number) => number} */ + (diff, arg, index) => { + const value = getNumber(arg); + return index === 0 ? value : diff - value; + }, + 0 + ); } - -/** - * Determines the decimal position of a number value. - * - * @param {number} value The number to evaluate. - * - * @return {number} The number of decimal places. - */ function getPrecision(value) { - const split = (value + '').split('.'); - return split[1] !== undefined ? split[1].length : 0; + const split = (value + "").split("."); + return split[1] !== void 0 ? split[1].length : 0; } - -/** - * Clamps a value based on a min/max range. - * - * @param {number} value The value. - * @param {number} min The minimum range. - * @param {number} max The maximum range. - * - * @return {number} The clamped value. - */ function math_clamp(value, min, max) { const baseValue = getNumber(value); return Math.max(min, Math.min(baseValue, max)); } - -/** - * Clamps a value based on a min/max range with rounding - * - * @param {number | string} value The value. - * @param {number} min The minimum range. - * @param {number} max The maximum range. - * @param {number} step A multiplier for the value. - * - * @return {number} The rounded and clamped value. - */ -function roundClamp(value = 0, min = Infinity, max = Infinity, step = 1) { +function ensureValidStep(value, min, step) { const baseValue = getNumber(value); + const minValue = getNumber(min); const stepValue = getNumber(step); - const precision = getPrecision(step); - const rounded = Math.round(baseValue / stepValue) * stepValue; - const clampedValue = math_clamp(rounded, min, max); - return precision ? getNumber(clampedValue.toFixed(precision)) : clampedValue; + const precision = Math.max(getPrecision(step), getPrecision(min)); + const tare = minValue % stepValue ? minValue : 0; + const rounded = Math.round((baseValue - tare) / stepValue) * stepValue; + const fromMin = rounded + tare; + return precision ? getNumber(fromMin.toFixed(precision)) : fromMin; } + ;// ./node_modules/@wordpress/components/build-module/h-stack/utils.js -/** - * External dependencies - */ - -/** - * Internal dependencies - */ - const H_ALIGNMENTS = { bottom: { - align: 'flex-end', - justify: 'center' + align: "flex-end", + justify: "center" }, bottomLeft: { - align: 'flex-end', - justify: 'flex-start' + align: "flex-end", + justify: "flex-start" }, bottomRight: { - align: 'flex-end', - justify: 'flex-end' + align: "flex-end", + justify: "flex-end" }, center: { - align: 'center', - justify: 'center' + align: "center", + justify: "center" }, edge: { - align: 'center', - justify: 'space-between' + align: "center", + justify: "space-between" }, left: { - align: 'center', - justify: 'flex-start' + align: "center", + justify: "flex-start" }, right: { - align: 'center', - justify: 'flex-end' + align: "center", + justify: "flex-end" }, stretch: { - align: 'stretch' + align: "stretch" }, top: { - align: 'flex-start', - justify: 'center' + align: "flex-start", + justify: "center" }, topLeft: { - align: 'flex-start', - justify: 'flex-start' + align: "flex-start", + justify: "flex-start" }, topRight: { - align: 'flex-start', - justify: 'flex-end' + align: "flex-start", + justify: "flex-end" } }; const V_ALIGNMENTS = { bottom: { - justify: 'flex-end', - align: 'center' + justify: "flex-end", + align: "center" }, bottomLeft: { - justify: 'flex-end', - align: 'flex-start' + justify: "flex-end", + align: "flex-start" }, bottomRight: { - justify: 'flex-end', - align: 'flex-end' + justify: "flex-end", + align: "flex-end" }, center: { - justify: 'center', - align: 'center' + justify: "center", + align: "center" }, edge: { - justify: 'space-between', - align: 'center' + justify: "space-between", + align: "center" }, left: { - justify: 'center', - align: 'flex-start' + justify: "center", + align: "flex-start" }, right: { - justify: 'center', - align: 'flex-end' + justify: "center", + align: "flex-end" }, stretch: { - align: 'stretch' + align: "stretch" }, top: { - justify: 'flex-start', - align: 'center' + justify: "flex-start", + align: "center" }, topLeft: { - justify: 'flex-start', - align: 'flex-start' + justify: "flex-start", + align: "flex-start" }, topRight: { - justify: 'flex-start', - align: 'flex-end' + justify: "flex-start", + align: "flex-end" } }; -function getAlignmentProps(alignment, direction = 'row') { +function getAlignmentProps(alignment, direction = "row") { if (!isValueDefined(alignment)) { return {}; } - const isVertical = direction === 'column'; + const isVertical = direction === "column"; const props = isVertical ? V_ALIGNMENTS : H_ALIGNMENTS; const alignmentProps = alignment in props ? props[alignment] : { align: alignment @@ -32544,39 +32480,18 @@ function getAlignmentProps(alignment, direction = 'row') { return alignmentProps; } + ;// ./node_modules/@wordpress/components/build-module/utils/get-valid-children.js -/** - * External dependencies - */ -/** - * WordPress dependencies - */ - - -/** - * Gets a collection of available children elements from a React component's children prop. - * - * @param children - * - * @return An array of available children. - */ function getValidChildren(children) { - if (typeof children === 'string') { + if (typeof children === "string") { return [children]; } - return external_wp_element_namespaceObject.Children.toArray(children).filter(child => (0,external_wp_element_namespaceObject.isValidElement)(child)); + return external_wp_element_namespaceObject.Children.toArray(children).filter((child) => (0,external_wp_element_namespaceObject.isValidElement)(child)); } + ;// ./node_modules/@wordpress/components/build-module/h-stack/hook.js -/** - * External dependencies - */ - -/** - * Internal dependencies - */ - @@ -32584,20 +32499,20 @@ function getValidChildren(children) { function useHStack(props) { const { - alignment = 'edge', + alignment = "edge", children, direction, spacing = 2, ...otherProps - } = useContextSystem(props, 'HStack'); + } = useContextSystem(props, "HStack"); const align = getAlignmentProps(alignment, direction); const validChildren = getValidChildren(children); const clonedChildren = validChildren.map((child, index) => { - const _isSpacer = hasConnectNamespace(child, ['Spacer']); + const _isSpacer = hasConnectNamespace(child, ["Spacer"]); if (_isSpacer) { const childElement = child; const _key = childElement.key || `hstack-${index}`; - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(flex_item_component, { + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(flex_item_component_component_default, { isBlock: true, ...childElement.props }, _key); @@ -32607,13 +32522,11 @@ function useHStack(props) { const propsForFlex = { children: clonedChildren, direction, - justify: 'center', + justify: "center", ...align, ...otherProps, gap: spacing }; - - // Omit `isColumn` because it's not used in HStack. const { isColumn, ...flexProps @@ -32621,65 +32534,24 @@ function useHStack(props) { return flexProps; } -;// ./node_modules/@wordpress/components/build-module/h-stack/component.js -/** - * Internal dependencies - */ +;// ./node_modules/@wordpress/components/build-module/h-stack/component.js function UnconnectedHStack(props, forwardedRef) { const hStackProps = useHStack(props); - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(component, { + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(component_default, { ...hStackProps, ref: forwardedRef }); } +const HStack = contextConnect(UnconnectedHStack, "HStack"); +var h_stack_component_component_default = HStack; -/** - * `HStack` (Horizontal Stack) arranges child elements in a horizontal line. - * - * `HStack` can render anything inside. - * - * ```jsx - * import { - * __experimentalHStack as HStack, - * __experimentalText as Text, - * } from `@wordpress/components`; - * - * function Example() { - * return ( - * - * Code - * is - * Poetry - * - * ); - * } - * ``` - */ -const HStack = contextConnect(UnconnectedHStack, 'HStack'); -/* harmony default export */ const h_stack_component = (HStack); ;// ./node_modules/@wordpress/components/build-module/number-control/index.js -/** - * External dependencies - */ - -/** - * WordPress dependencies - */ - - - - - - -/** - * Internal dependencies - */ @@ -32690,14 +32562,21 @@ const HStack = contextConnect(UnconnectedHStack, 'HStack'); -const number_control_noop = () => {}; + + + + + + +const number_control_noop = () => { +}; function UnforwardedNumberControl(props, forwardedRef) { const { __unstableStateReducer: stateReducerProp, className, - dragDirection = 'n', + dragDirection = "n", hideHTMLArrows = false, - spinControls = hideHTMLArrows ? 'none' : 'native', + spinControls = hideHTMLArrows ? "none" : "native", isDragEnabled = true, isShiftStepEnabled = true, label, @@ -32707,62 +32586,55 @@ function UnforwardedNumberControl(props, forwardedRef) { shiftStep = 10, step = 1, spinFactor = 1, - type: typeProp = 'number', + type: typeProp = "number", value: valueProp, - size = 'default', + size = "default", suffix, onChange = number_control_noop, __shouldNotWarnDeprecated36pxSize, ...restProps } = useDeprecated36pxDefaultSizeProp(props); maybeWarnDeprecated36pxSize({ - componentName: 'NumberControl', + componentName: "NumberControl", size, __next40pxDefaultSize: restProps.__next40pxDefaultSize, __shouldNotWarnDeprecated36pxSize }); if (hideHTMLArrows) { - external_wp_deprecated_default()('wp.components.NumberControl hideHTMLArrows prop ', { + external_wp_deprecated_default()("wp.components.NumberControl hideHTMLArrows prop ", { alternative: 'spinControls="none"', - since: '6.2', - version: '6.3' + since: "6.2", + version: "6.3" }); } const inputRef = (0,external_wp_element_namespaceObject.useRef)(); const mergedRef = (0,external_wp_compose_namespaceObject.useMergeRefs)([inputRef, forwardedRef]); - const isStepAny = step === 'any'; + const isStepAny = step === "any"; const baseStep = isStepAny ? 1 : ensureNumber(step); const baseSpin = ensureNumber(spinFactor) * baseStep; - const baseValue = roundClamp(0, min, max, baseStep); const constrainValue = (value, stepOverride) => { - // When step is "any" clamp the value, otherwise round and clamp it. - // Use '' + to convert to string for use in input value attribute. - return isStepAny ? '' + Math.min(max, Math.max(min, ensureNumber(value))) : '' + roundClamp(value, min, max, stepOverride !== null && stepOverride !== void 0 ? stepOverride : baseStep); + if (!isStepAny) { + value = ensureValidStep(value, min, stepOverride !== null && stepOverride !== void 0 ? stepOverride : baseStep); + } + return `${math_clamp(value, min, max)}`; }; - const autoComplete = typeProp === 'number' ? 'off' : undefined; - const classes = dist_clsx('components-number-control', className); + const baseValue = constrainValue(0); + const autoComplete = typeProp === "number" ? "off" : void 0; + const classes = dist_clsx("components-number-control", className); const cx = useCx(); - const spinButtonClasses = cx(size === 'small' && styles.smallSpinButtons); + const spinButtonClasses = cx(size === "small" && styles.smallSpinButtons); const spinValue = (value, direction, event) => { event?.preventDefault(); const shift = event?.shiftKey && isShiftStepEnabled; const delta = shift ? ensureNumber(shiftStep) * baseSpin : baseSpin; let nextValue = isValueEmpty(value) ? baseValue : value; - if (direction === 'up') { + if (direction === "up") { nextValue = add(nextValue, delta); - } else if (direction === 'down') { + } else if (direction === "down") { nextValue = subtract(nextValue, delta); } - return constrainValue(nextValue, shift ? delta : undefined); + return constrainValue(nextValue, shift ? delta : void 0); }; - - /** - * "Middleware" function that intercepts updates from InputControl. - * This allows us to tap into actions to transform the (next) state for - * InputControl. - * - * @return The updated state to apply to InputControl - */ const numberControlStateReducer = (state, action) => { const nextState = { ...state @@ -32773,17 +32645,9 @@ function UnforwardedNumberControl(props, forwardedRef) { } = action; const event = payload.event; const currentValue = nextState.value; - - /** - * Handles custom UP and DOWN Keyboard events - */ if (type === PRESS_UP || type === PRESS_DOWN) { - nextState.value = spinValue(currentValue, type === PRESS_UP ? 'up' : 'down', event); + nextState.value = spinValue(currentValue, type === PRESS_UP ? "up" : "down", event); } - - /** - * Handles drag to update events - */ if (type === DRAG && isDragEnabled) { const [x, y] = payload.delta; const enableShift = payload.shiftKey && isShiftStepEnabled; @@ -32791,19 +32655,19 @@ function UnforwardedNumberControl(props, forwardedRef) { let directionModifier; let delta; switch (dragDirection) { - case 'n': + case "n": delta = y; directionModifier = -1; break; - case 'e': + case "e": delta = x; directionModifier = (0,external_wp_i18n_namespaceObject.isRTL)() ? -1 : 1; break; - case 's': + case "s": delta = y; directionModifier = 1; break; - case 'w': + case "w": delta = x; directionModifier = (0,external_wp_i18n_namespaceObject.isRTL)() ? 1 : -1; break; @@ -32812,23 +32676,22 @@ function UnforwardedNumberControl(props, forwardedRef) { delta = Math.ceil(Math.abs(delta)) * Math.sign(delta); const distance = delta * modifier * directionModifier; nextState.value = constrainValue( - // @ts-expect-error TODO: Investigate if it's ok for currentValue to be undefined - add(currentValue, distance), enableShift ? modifier : undefined); + // @ts-expect-error TODO: Investigate if it's ok for currentValue to be undefined + add(currentValue, distance), + enableShift ? modifier : void 0 + ); } } - - /** - * Handles commit (ENTER key press or blur) - */ if (type === PRESS_ENTER || type === COMMIT) { - const applyEmptyValue = required === false && currentValue === ''; - nextState.value = applyEmptyValue ? currentValue : - // @ts-expect-error TODO: Investigate if it's ok for currentValue to be undefined - constrainValue(currentValue); + const applyEmptyValue = required === false && currentValue === ""; + nextState.value = applyEmptyValue ? currentValue : ( + // @ts-expect-error TODO: Investigate if it's ok for currentValue to be undefined + constrainValue(currentValue) + ); } return nextState; }; - const buildSpinButtonClickHandler = direction => event => onChange(String(spinValue(valueProp, direction, event)), { + const buildSpinButtonClickHandler = (direction) => (event) => onChange(String(spinValue(valueProp, direction, event)), { // Set event.target to the so that consumers can use // e.g. event.target.validity. event: { @@ -32836,102 +32699,90 @@ function UnforwardedNumberControl(props, forwardedRef) { target: inputRef.current } }); - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(number_control_styles_Input, { - autoComplete: autoComplete, + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(number_control_styles_Input, { + autoComplete, inputMode: "numeric", ...restProps, className: classes, - dragDirection: dragDirection, - hideHTMLArrows: spinControls !== 'native', - isDragEnabled: isDragEnabled, - label: label, - max: max === Infinity ? undefined : max, - min: min === -Infinity ? undefined : min, + dragDirection, + hideHTMLArrows: spinControls !== "native", + isDragEnabled, + label, + max: max === Infinity ? void 0 : max, + min: min === -Infinity ? void 0 : min, ref: mergedRef, - required: required, - step: step, - type: typeProp - // @ts-expect-error TODO: Resolve discrepancy between `value` types in InputControl based components - , + required, + step, + type: typeProp, value: valueProp, __unstableStateReducer: (state, action) => { var _stateReducerProp; const baseState = numberControlStateReducer(state, action); return (_stateReducerProp = stateReducerProp?.(baseState, action)) !== null && _stateReducerProp !== void 0 ? _stateReducerProp : baseState; }, - size: size, + size, __shouldNotWarnDeprecated36pxSize: true, - suffix: spinControls === 'custom' ? /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { - children: [suffix, /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(spacer_component, { + suffix: spinControls === "custom" ? /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { + children: [suffix, /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(spacer_component_component_default, { marginBottom: 0, marginRight: 2, - children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(h_stack_component, { + children: /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsxs)(h_stack_component_component_default, { spacing: 1, - children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(SpinButton, { + children: [/* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(SpinButton, { className: spinButtonClasses, - icon: library_plus, + icon: plus_default, size: "small", - label: (0,external_wp_i18n_namespaceObject.__)('Increment'), - onClick: buildSpinButtonClickHandler('up') - }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(SpinButton, { + label: (0,external_wp_i18n_namespaceObject.__)("Increment"), + onClick: buildSpinButtonClickHandler("up") + }), /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(SpinButton, { className: spinButtonClasses, - icon: library_reset, + icon: reset_default, size: "small", - label: (0,external_wp_i18n_namespaceObject.__)('Decrement'), - onClick: buildSpinButtonClickHandler('down') + label: (0,external_wp_i18n_namespaceObject.__)("Decrement"), + onClick: buildSpinButtonClickHandler("down") })] }) })] }) : suffix, - onChange: onChange + onChange }); } const NumberControl = (0,external_wp_element_namespaceObject.forwardRef)(UnforwardedNumberControl); -/* harmony default export */ const number_control = (NumberControl); +var number_control_default = NumberControl; + ;// ./node_modules/@wordpress/components/build-module/angle-picker-control/styles/angle-picker-control-styles.js -function angle_picker_control_styles_EMOTION_STRINGIFIED_CSS_ERROR_() { return "You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."; } -/** - * External dependencies - */ - -/** - * Internal dependencies - */ +function angle_picker_control_styles_EMOTION_STRINGIFIED_CSS_ERROR_() { + return "You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."; +} const CIRCLE_SIZE = 32; const INNER_CIRCLE_SIZE = 6; -const CircleRoot = /*#__PURE__*/emotion_styled_base_browser_esm("div", true ? { +const CircleRoot = /* @__PURE__ */ emotion_styled_base_browser_esm("div", true ? { target: "eln3bjz3" -} : 0)("border-radius:", config_values.radiusRound, ";border:", config_values.borderWidth, " solid ", COLORS.ui.border, ";box-sizing:border-box;cursor:grab;height:", CIRCLE_SIZE, "px;overflow:hidden;width:", CIRCLE_SIZE, "px;:active{cursor:grabbing;}" + ( true ? "" : 0)); -const CircleIndicatorWrapper = /*#__PURE__*/emotion_styled_base_browser_esm("div", true ? { +} : 0)("border-radius:", config_values_default.radiusRound, ";border:", config_values_default.borderWidth, " solid ", COLORS.ui.border, ";box-sizing:border-box;cursor:grab;height:", CIRCLE_SIZE, "px;overflow:hidden;width:", CIRCLE_SIZE, "px;:active{cursor:grabbing;}" + ( true ? "" : 0)); +const CircleIndicatorWrapper = /* @__PURE__ */ emotion_styled_base_browser_esm("div", true ? { target: "eln3bjz2" } : 0)( true ? { name: "1r307gh", styles: "box-sizing:border-box;position:relative;width:100%;height:100%;:focus-visible{outline:none;}" } : 0); -const CircleIndicator = /*#__PURE__*/emotion_styled_base_browser_esm("div", true ? { +const CircleIndicator = /* @__PURE__ */ emotion_styled_base_browser_esm("div", true ? { target: "eln3bjz1" -} : 0)("background:", COLORS.theme.accent, ";border-radius:", config_values.radiusRound, ";box-sizing:border-box;display:block;left:50%;top:4px;transform:translateX( -50% );position:absolute;width:", INNER_CIRCLE_SIZE, "px;height:", INNER_CIRCLE_SIZE, "px;" + ( true ? "" : 0)); -const UnitText = /*#__PURE__*/emotion_styled_base_browser_esm(text_component, true ? { +} : 0)("background:", COLORS.theme.accent, ";border-radius:", config_values_default.radiusRound, ";box-sizing:border-box;display:block;left:50%;top:4px;transform:translateX( -50% );position:absolute;width:", INNER_CIRCLE_SIZE, "px;height:", INNER_CIRCLE_SIZE, "px;" + ( true ? "" : 0)); +const UnitText = /* @__PURE__ */ emotion_styled_base_browser_esm(text_component_component_default, true ? { target: "eln3bjz0" } : 0)("color:", COLORS.theme.accent, ";margin-right:", space(3), ";" + ( true ? "" : 0)); + ;// ./node_modules/@wordpress/components/build-module/angle-picker-control/angle-circle.js -/** - * WordPress dependencies - */ -/** - * Internal dependencies - */ - function AngleCircle({ value, @@ -32951,17 +32802,13 @@ function AngleCircle({ y: rect.y + rect.height / 2 }; }; - const changeAngleToPosition = event => { - if (event === undefined) { + const changeAngleToPosition = (event) => { + if (event === void 0) { return; } - - // Prevent (drag) mouse events from selecting and accidentally - // triggering actions from other elements. event.preventDefault(); - // Input control needs to lose focus and by preventDefault above, it doesn't. event.target?.focus(); - if (angleCircleCenterRef.current !== undefined && onChange !== undefined) { + if (angleCircleCenterRef.current !== void 0 && onChange !== void 0) { const { x: centerX, y: centerY @@ -32973,7 +32820,7 @@ function AngleCircle({ startDrag, isDragging } = (0,external_wp_compose_namespaceObject.__experimentalUseDragging)({ - onDragStart: event => { + onDragStart: (event) => { setAngleCircleCenter(); changeAngleToPosition(event); }, @@ -32982,27 +32829,27 @@ function AngleCircle({ }); (0,external_wp_element_namespaceObject.useEffect)(() => { if (isDragging) { - if (previousCursorValueRef.current === undefined) { + if (previousCursorValueRef.current === void 0) { previousCursorValueRef.current = document.body.style.cursor; } - document.body.style.cursor = 'grabbing'; + document.body.style.cursor = "grabbing"; } else { - document.body.style.cursor = previousCursorValueRef.current || ''; - previousCursorValueRef.current = undefined; + document.body.style.cursor = previousCursorValueRef.current || ""; + previousCursorValueRef.current = void 0; } }, [isDragging]); - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(CircleRoot, { + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(CircleRoot, { ref: angleCircleRef, onMouseDown: startDrag, className: "components-angle-picker-control__angle-circle", ...props, - children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(CircleIndicatorWrapper, { + children: /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(CircleIndicatorWrapper, { style: value ? { transform: `rotate(${value}deg)` - } : undefined, + } : void 0, className: "components-angle-picker-control__angle-circle-indicator-wrapper", tabIndex: -1, - children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(CircleIndicator, { + children: /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(CircleIndicator, { className: "components-angle-picker-control__angle-circle-indicator" }) }) @@ -33018,24 +32865,13 @@ function getAngle(centerX, centerY, pointX, pointY) { } return angleInDeg; } -/* harmony default export */ const angle_circle = (AngleCircle); +var angle_circle_default = AngleCircle; + ;// ./node_modules/@wordpress/components/build-module/angle-picker-control/index.js -/** - * External dependencies - */ -/** - * WordPress dependencies - */ - - - -/** - * Internal dependencies - */ @@ -33045,77 +32881,56 @@ function getAngle(centerX, centerY, pointX, pointY) { function UnforwardedAnglePickerControl(props, ref) { const { className, - label = (0,external_wp_i18n_namespaceObject.__)('Angle'), + label = (0,external_wp_i18n_namespaceObject.__)("Angle"), onChange, value, ...restProps } = props; - const handleOnNumberChange = unprocessedValue => { - if (onChange === undefined) { + const handleOnNumberChange = (unprocessedValue) => { + if (onChange === void 0) { return; } - const inputValue = unprocessedValue !== undefined && unprocessedValue !== '' ? parseInt(unprocessedValue, 10) : 0; + const inputValue = unprocessedValue !== void 0 && unprocessedValue !== "" ? parseInt(unprocessedValue, 10) : 0; onChange(inputValue); }; - const classes = dist_clsx('components-angle-picker-control', className); - const unitText = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(UnitText, { + const classes = dist_clsx("components-angle-picker-control", className); + const unitText = /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(UnitText, { children: "\xB0" }); const [prefixedUnitText, suffixedUnitText] = (0,external_wp_i18n_namespaceObject.isRTL)() ? [unitText, null] : [null, unitText]; - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(flex_component, { + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsxs)(flex_component_component_default, { ...restProps, - ref: ref, + ref, className: classes, gap: 2, - children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(flex_block_component, { - children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(number_control, { + children: [/* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(flex_block_component_component_default, { + children: /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(number_control_default, { __next40pxDefaultSize: true, - label: label, + label, className: "components-angle-picker-control__input-field", max: 360, min: 0, onChange: handleOnNumberChange, step: "1", - value: value, + value, spinControls: "none", prefix: prefixedUnitText, suffix: suffixedUnitText }) - }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(spacer_component, { + }), /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(spacer_component_component_default, { marginBottom: "1", marginTop: "auto", - children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(angle_circle, { + children: /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(angle_circle_default, { "aria-hidden": "true", - value: value, - onChange: onChange + value, + onChange }) })] }); } - -/** - * `AnglePickerControl` is a React component to render a UI that allows users to - * pick an angle. Users can choose an angle in a visual UI with the mouse by - * dragging an angle indicator inside a circle or by directly inserting the - * desired angle in a text field. - * - * ```jsx - * import { useState } from '@wordpress/element'; - * import { AnglePickerControl } from '@wordpress/components'; - * - * function Example() { - * const [ angle, setAngle ] = useState( 0 ); - * return ( - * - * ); - * } - * ``` - */ const AnglePickerControl = (0,external_wp_element_namespaceObject.forwardRef)(UnforwardedAnglePickerControl); -/* harmony default export */ const angle_picker_control = (AnglePickerControl); +var angle_picker_control_default = AnglePickerControl; + // EXTERNAL MODULE: ./node_modules/remove-accents/index.js var remove_accents = __webpack_require__(9681); @@ -33127,102 +32942,54 @@ const external_wp_a11y_namespaceObject = window["wp"]["a11y"]; ;// external ["wp","keycodes"] const external_wp_keycodes_namespaceObject = window["wp"]["keycodes"]; ;// ./node_modules/@wordpress/components/build-module/utils/strings.js -/** - * External dependencies - */ - -/** - * All unicode characters that we consider "dash-like": - * - `\u007e`: ~ (tilde) - * - `\u00ad`: ­ (soft hyphen) - * - `\u2053`: ⁓ (swung dash) - * - `\u207b`: ⁻ (superscript minus) - * - `\u208b`: ₋ (subscript minus) - * - `\u2212`: − (minus sign) - * - `\\p{Pd}`: any other Unicode dash character - */ const ALL_UNICODE_DASH_CHARACTERS = new RegExp(/[\u007e\u00ad\u2053\u207b\u208b\u2212\p{Pd}]/gu); -const normalizeTextString = value => { - return remove_accents_default()(value).toLocaleLowerCase().replace(ALL_UNICODE_DASH_CHARACTERS, '-'); +const normalizeTextString = (value) => { + return remove_accents_default()(value).normalize("NFKC").toLocaleLowerCase().replace(ALL_UNICODE_DASH_CHARACTERS, "-"); }; - -/** - * Converts any string to kebab case. - * Backwards compatible with Lodash's `_.kebabCase()`. - * Backwards compatible with `_wp_to_kebab_case()`. - * - * @see https://lodash.com/docs/4.17.15#kebabCase - * @see https://developer.wordpress.org/reference/functions/_wp_to_kebab_case/ - * - * @param str String to convert. - * @return Kebab-cased string - */ function kebabCase(str) { var _str$toString; - let input = (_str$toString = str?.toString?.()) !== null && _str$toString !== void 0 ? _str$toString : ''; - - // See https://github.com/lodash/lodash/blob/b185fcee26b2133bd071f4aaca14b455c2ed1008/lodash.js#L4970 - input = input.replace(/['\u2019]/, ''); + let input = (_str$toString = str?.toString?.()) !== null && _str$toString !== void 0 ? _str$toString : ""; + input = input.replace(/['\u2019]/, ""); return paramCase(input, { - splitRegexp: [/(?!(?:1ST|2ND|3RD|[4-9]TH)(?![a-z]))([a-z0-9])([A-Z])/g, - // fooBar => foo-bar, 3Bar => 3-bar - /(?!(?:1st|2nd|3rd|[4-9]th)(?![a-z]))([0-9])([a-z])/g, - // 3bar => 3-bar - /([A-Za-z])([0-9])/g, - // Foo3 => foo-3, foo3 => foo-3 - /([A-Z])([A-Z][a-z])/g // FOOBar => foo-bar + splitRegexp: [ + /(?!(?:1ST|2ND|3RD|[4-9]TH)(?![a-z]))([a-z0-9])([A-Z])/g, + // fooBar => foo-bar, 3Bar => 3-bar + /(?!(?:1st|2nd|3rd|[4-9]th)(?![a-z]))([0-9])([a-z])/g, + // 3bar => 3-bar + /([A-Za-z])([0-9])/g, + // Foo3 => foo-3, foo3 => foo-3 + /([A-Z])([A-Z][a-z])/g + // FOOBar => foo-bar ] }); } - -/** - * Escapes the RegExp special characters. - * - * @param string Input string. - * - * @return Regex-escaped string. - */ function escapeRegExp(string) { - return string.replace(/[\\^$.*+?()[\]{}|]/g, '\\$&'); + return string.replace(/[\\^$.*+?()[\]{}|]/g, "\\$&"); } + ;// ./node_modules/@wordpress/components/build-module/autocomplete/get-default-use-items.js -/** - * External dependencies - */ - - -/** - * WordPress dependencies - */ -/** - * Internal dependencies - */ function filterOptions(search, options = [], maxResults = 10) { const filtered = []; for (let i = 0; i < options.length; i++) { const option = options[i]; - - // Merge label into keywords. let { keywords = [] } = option; - if ('string' === typeof option.label) { + if ("string" === typeof option.label) { keywords = [...keywords, option.label]; } - const isMatch = keywords.some(keyword => search.test(remove_accents_default()(keyword))); + const isMatch = keywords.some((keyword) => search.test(remove_accents_default()(keyword))); if (!isMatch) { continue; } filtered.push(option); - - // Abort early if max reached. if (filtered.length === maxResults) { break; } @@ -33230,27 +32997,16 @@ function filterOptions(search, options = [], maxResults = 10) { return filtered; } function getDefaultUseItems(autocompleter) { - return filterValue => { + return (filterValue) => { const [items, setItems] = (0,external_wp_element_namespaceObject.useState)([]); - /* - * We support both synchronous and asynchronous retrieval of completer options - * but internally treat all as async so we maintain a single, consistent code path. - * - * Because networks can be slow, and the internet is wonderfully unpredictable, - * we don't want two promises updating the state at once. This ensures that only - * the most recent promise will act on `optionsData`. This doesn't use the state - * because `setState` is batched, and so there's no guarantee that setting - * `activePromise` in the state would result in it actually being in `this.state` - * before the promise resolves and we check to see if this is the active promise or not. - */ (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { const { options, isDebounced } = autocompleter; const loadOptions = (0,external_wp_compose_namespaceObject.debounce)(() => { - const promise = Promise.resolve(typeof options === 'function' ? options(filterValue) : options).then(optionsData => { - if (promise.canceled) { + const promise2 = Promise.resolve(typeof options === "function" ? options(filterValue) : options).then((optionsData) => { + if (promise2.canceled) { return; } const keyedOptions = optionsData.map((optionData, optionIndex) => ({ @@ -33260,12 +33016,10 @@ function getDefaultUseItems(autocompleter) { keywords: autocompleter.getOptionKeywords ? autocompleter.getOptionKeywords(optionData) : [], isDisabled: autocompleter.isOptionDisabled ? autocompleter.isOptionDisabled(optionData) : false })); - - // Create a regular expression to filter the options. - const search = new RegExp('(?:\\b|\\s|^)' + escapeRegExp(filterValue), 'i'); + const search = new RegExp("(?:\\b|\\s|^)" + escapeRegExp(filterValue), "i"); setItems(filterOptions(search, keyedOptions)); }); - return promise; + return promise2; }, isDebounced ? 250 : 0); const promise = loadOptions(); return () => { @@ -33279,6 +33033,7 @@ function getDefaultUseItems(autocompleter) { }; } + ;// ./node_modules/@floating-ui/react-dom/dist/floating-ui.react-dom.mjs @@ -33555,83 +33310,27 @@ function useFloating(options) { ;// ./node_modules/@wordpress/icons/build-module/library/close.js -/** - * WordPress dependencies - */ -const close_close = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { - xmlns: "http://www.w3.org/2000/svg", - viewBox: "0 0 24 24", - children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { - d: "m13.06 12 6.47-6.47-1.06-1.06L12 10.94 5.53 4.47 4.47 5.53 10.94 12l-6.47 6.47 1.06 1.06L12 13.06l6.47 6.47 1.06-1.06L13.06 12Z" - }) -}); -/* harmony default export */ const library_close = (close_close); +var close_default = /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { d: "m13.06 12 6.47-6.47-1.06-1.06L12 10.94 5.53 4.47 4.47 5.53 10.94 12l-6.47 6.47 1.06 1.06L12 13.06l6.47 6.47 1.06-1.06L13.06 12Z" }) }); + ;// ./node_modules/@wordpress/components/build-module/scroll-lock/index.js -/** - * WordPress dependencies - */ - -/* - * Setting `overflow: hidden` on html and body elements resets body scroll in iOS. - * Save scroll top so we can restore it after locking scroll. - * - * NOTE: It would be cleaner and possibly safer to find a localized solution such - * as preventing default on certain touchmove events. - */ let previousScrollTop = 0; function setLocked(locked) { const scrollingElement = document.scrollingElement || document.body; if (locked) { previousScrollTop = scrollingElement.scrollTop; } - const methodName = locked ? 'add' : 'remove'; - scrollingElement.classList[methodName]('lockscroll'); - - // Adding the class to the document element seems to be necessary in iOS. - document.documentElement.classList[methodName]('lockscroll'); + const methodName = locked ? "add" : "remove"; + scrollingElement.classList[methodName]("lockscroll"); + document.documentElement.classList[methodName]("lockscroll"); if (!locked) { scrollingElement.scrollTop = previousScrollTop; } } let lockCounter = 0; - -/** - * ScrollLock is a content-free React component for declaratively preventing - * scroll bleed from modal UI to the page body. This component applies a - * `lockscroll` class to the `document.documentElement` and - * `document.scrollingElement` elements to stop the body from scrolling. When it - * is present, the lock is applied. - * - * ```jsx - * import { ScrollLock, Button } from '@wordpress/components'; - * import { useState } from '@wordpress/element'; - * - * const MyScrollLock = () => { - * const [ isScrollLocked, setIsScrollLocked ] = useState( false ); - * - * const toggleLock = () => { - * setIsScrollLocked( ( locked ) => ! locked ) ); - * }; - * - * return ( - *
- * - * { isScrollLocked && } - *

- * Scroll locked: - * { isScrollLocked ? 'Yes' : 'No' } - *

- *
- * ); - * }; - * ``` - */ function ScrollLock() { (0,external_wp_element_namespaceObject.useEffect)(() => { if (lockCounter === 0) { @@ -33647,93 +33346,78 @@ function ScrollLock() { }, []); return null; } -/* harmony default export */ const scroll_lock = (ScrollLock); +var scroll_lock_default = ScrollLock; + ;// ./node_modules/@wordpress/components/build-module/slot-fill/bubbles-virtually/slot-fill-context.js -/** - * WordPress dependencies - */ - -/** - * Internal dependencies - */ - const initialContextValue = { slots: (0,external_wp_compose_namespaceObject.observableMap)(), fills: (0,external_wp_compose_namespaceObject.observableMap)(), registerSlot: () => { - true ? external_wp_warning_default()('Components must be wrapped within `SlotFillProvider`. ' + 'See https://developer.wordpress.org/block-editor/components/slot-fill/') : 0; + true ? external_wp_warning_default()("Components must be wrapped within `SlotFillProvider`. See https://developer.wordpress.org/block-editor/components/slot-fill/") : 0; + }, + updateSlot: () => { + }, + unregisterSlot: () => { + }, + registerFill: () => { + }, + unregisterFill: () => { }, - updateSlot: () => {}, - unregisterSlot: () => {}, - registerFill: () => {}, - unregisterFill: () => {}, // This helps the provider know if it's using the default context value or not. isDefault: true }; const SlotFillContext = (0,external_wp_element_namespaceObject.createContext)(initialContextValue); -/* harmony default export */ const slot_fill_context = (SlotFillContext); +SlotFillContext.displayName = "SlotFillContext"; +var slot_fill_context_default = SlotFillContext; + ;// ./node_modules/@wordpress/components/build-module/slot-fill/bubbles-virtually/use-slot.js -/** - * WordPress dependencies - */ -/** - * Internal dependencies - */ - function useSlot(name) { - const registry = (0,external_wp_element_namespaceObject.useContext)(slot_fill_context); + const registry = (0,external_wp_element_namespaceObject.useContext)(slot_fill_context_default); const slot = (0,external_wp_compose_namespaceObject.useObservableValue)(registry.slots, name); return { ...slot }; } + ;// ./node_modules/@wordpress/components/build-module/slot-fill/context.js -/** - * WordPress dependencies - */ - -/** - * Internal dependencies - */ - const initialValue = { slots: (0,external_wp_compose_namespaceObject.observableMap)(), fills: (0,external_wp_compose_namespaceObject.observableMap)(), - registerSlot: () => {}, - unregisterSlot: () => {}, - registerFill: () => {}, - unregisterFill: () => {}, - updateFill: () => {} + registerSlot: () => { + }, + unregisterSlot: () => { + }, + registerFill: () => { + }, + unregisterFill: () => { + }, + updateFill: () => { + } }; const context_SlotFillContext = (0,external_wp_element_namespaceObject.createContext)(initialValue); -/* harmony default export */ const context = (context_SlotFillContext); +context_SlotFillContext.displayName = "SlotFillContext"; +var context_default = context_SlotFillContext; + ;// ./node_modules/@wordpress/components/build-module/slot-fill/fill.js -/** - * WordPress dependencies - */ -/** - * Internal dependencies - */ - function Fill({ name, children }) { - const registry = (0,external_wp_element_namespaceObject.useContext)(context); + const registry = (0,external_wp_element_namespaceObject.useContext)(context_default); const instanceRef = (0,external_wp_element_namespaceObject.useRef)({}); const childrenRef = (0,external_wp_element_namespaceObject.useRef)(children); (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { @@ -33750,38 +33434,22 @@ function Fill({ return null; } + ;// ./node_modules/@wordpress/components/build-module/slot-fill/slot.js -/** - * External dependencies - */ - -/** - * WordPress dependencies - */ -/** - * Internal dependencies - */ - -/** - * Whether the argument is a function. - * - * @param maybeFunc The argument to check. - * @return True if the argument is a function, false otherwise. - */ function isFunction(maybeFunc) { - return typeof maybeFunc === 'function'; + return typeof maybeFunc === "function"; } function addKeysToChildren(children) { return external_wp_element_namespaceObject.Children.map(children, (child, childIndex) => { - if (!child || typeof child === 'string') { + if (!child || typeof child === "string") { return child; } let childKey = childIndex; - if (typeof child === 'object' && 'key' in child && child?.key) { + if (typeof child === "object" && "key" in child && child?.key) { childKey = child.key; } return (0,external_wp_element_namespaceObject.cloneElement)(child, { @@ -33791,7 +33459,7 @@ function addKeysToChildren(children) { } function Slot(props) { var _useObservableValue; - const registry = (0,external_wp_element_namespaceObject.useContext)(context); + const registry = (0,external_wp_element_namespaceObject.useContext)(context_default); const instanceRef = (0,external_wp_element_namespaceObject.useRef)({}); const { name, @@ -33805,24 +33473,24 @@ function Slot(props) { }, [registry, name]); let fills = (_useObservableValue = (0,external_wp_compose_namespaceObject.useObservableValue)(registry.fills, name)) !== null && _useObservableValue !== void 0 ? _useObservableValue : []; const currentSlot = (0,external_wp_compose_namespaceObject.useObservableValue)(registry.slots, name); - - // Fills should only be rendered in the currently registered instance of the slot. if (currentSlot !== instanceRef.current) { fills = []; } - const renderedFills = fills.map(fill => { + const renderedFills = fills.map((fill) => { const fillChildren = isFunction(fill.children) ? fill.children(fillProps) : fill.children; return addKeysToChildren(fillChildren); }).filter( - // In some cases fills are rendered only when some conditions apply. - // This ensures that we only use non-empty fills when rendering, i.e., - // it allows us to render wrappers only when the fills are actually present. - element => !(0,external_wp_element_namespaceObject.isEmptyElement)(element)); - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_ReactJSXRuntime_namespaceObject.Fragment, { + // In some cases fills are rendered only when some conditions apply. + // This ensures that we only use non-empty fills when rendering, i.e., + // it allows us to render wrappers only when the fills are actually present. + (element) => !(0,external_wp_element_namespaceObject.isEmptyElement)(element) + ); + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(external_ReactJSXRuntime_namespaceObject.Fragment, { children: isFunction(children) ? children(renderedFills) : renderedFills }); } -/* harmony default export */ const slot = (Slot); +var slot_default = Slot; + ;// ./node_modules/@wordpress/components/node_modules/uuid/dist/esm-browser/native.js const randomUUID = typeof crypto !== 'undefined' && crypto.randomUUID && crypto.randomUUID.bind(crypto); @@ -33913,31 +33581,19 @@ function v4(options, buf, offset) { /* harmony default export */ const esm_browser_v4 = (v4); ;// ./node_modules/@wordpress/components/build-module/style-provider/index.js -/** - * External dependencies - */ -/** - * Internal dependencies - */ - -const uuidCache = new Set(); -// Use a weak map so that when the container is detached it's automatically -// dereferenced to avoid memory leak. -const containerCacheMap = new WeakMap(); -const memoizedCreateCacheWithContainer = container => { +const uuidCache = /* @__PURE__ */ new Set(); +const containerCacheMap = /* @__PURE__ */ new WeakMap(); +const memoizedCreateCacheWithContainer = (container) => { if (containerCacheMap.has(container)) { return containerCacheMap.get(container); } - - // Emotion only accepts alphabetical and hyphenated keys so we just - // strip the numbers from the UUID. It _should_ be fine. - let key = esm_browser_v4().replace(/[0-9]/g, ''); + let key = esm_browser_v4().replace(/[0-9]/g, ""); while (uuidCache.has(key)) { - key = esm_browser_v4().replace(/[0-9]/g, ''); + key = esm_browser_v4().replace(/[0-9]/g, ""); } uuidCache.add(key); const cache = emotion_cache_browser_esm({ @@ -33956,24 +33612,18 @@ function StyleProvider(props) { return null; } const cache = memoizedCreateCacheWithContainer(document.head); - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(CacheProvider, { + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(CacheProvider, { value: cache, - children: children + children }); } -/* harmony default export */ const style_provider = (StyleProvider); +var style_provider_default = StyleProvider; + ;// ./node_modules/@wordpress/components/build-module/slot-fill/bubbles-virtually/fill.js -/** - * WordPress dependencies - */ -/** - * Internal dependencies - */ - function fill_Fill({ @@ -33981,13 +33631,9 @@ function fill_Fill({ children }) { var _slot$fillProps; - const registry = (0,external_wp_element_namespaceObject.useContext)(slot_fill_context); + const registry = (0,external_wp_element_namespaceObject.useContext)(slot_fill_context_default); const slot = (0,external_wp_compose_namespaceObject.useObservableValue)(registry.slots, name); const instanceRef = (0,external_wp_element_namespaceObject.useRef)({}); - - // We register fills so we can keep track of their existence. - // Slots can use the `useSlotFills` hook to know if there're already fills - // registered so they can choose to render themselves or not. (0,external_wp_element_namespaceObject.useEffect)(() => { const instance = instanceRef.current; registry.registerFill(name, instance); @@ -33996,33 +33642,18 @@ function fill_Fill({ if (!slot || !slot.ref.current) { return null; } - - // When using a `Fill`, the `children` will be rendered in the document of the - // `Slot`. This means that we need to wrap the `children` in a `StyleProvider` - // to make sure we're referencing the right document/iframe (instead of the - // context of the `Fill`'s parent). - const wrappedChildren = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(style_provider, { + const wrappedChildren = /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(style_provider_default, { document: slot.ref.current.ownerDocument, - children: typeof children === 'function' ? children((_slot$fillProps = slot.fillProps) !== null && _slot$fillProps !== void 0 ? _slot$fillProps : {}) : children + children: typeof children === "function" ? children((_slot$fillProps = slot.fillProps) !== null && _slot$fillProps !== void 0 ? _slot$fillProps : {}) : children }); return (0,external_wp_element_namespaceObject.createPortal)(wrappedChildren, slot.ref.current); } + ;// ./node_modules/@wordpress/components/build-module/slot-fill/bubbles-virtually/slot.js -/** - * External dependencies - */ - -/** - * WordPress dependencies - */ -/** - * Internal dependencies - */ - function slot_Slot(props, forwardedRef) { @@ -34035,13 +33666,8 @@ function slot_Slot(props, forwardedRef) { children, ...restProps } = props; - const registry = (0,external_wp_element_namespaceObject.useContext)(slot_fill_context); + const registry = (0,external_wp_element_namespaceObject.useContext)(slot_fill_context_default); const ref = (0,external_wp_element_namespaceObject.useRef)(null); - - // We don't want to unregister and register the slot whenever - // `fillProps` change, which would cause the fill to be re-mounted. Instead, - // we can just update the slot (see hook below). - // For more context, see https://github.com/WordPress/gutenberg/pull/44403#discussion_r994415973 const fillPropsRef = (0,external_wp_element_namespaceObject.useRef)(fillProps); (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { fillPropsRef.current = fillProps; @@ -34053,29 +33679,23 @@ function slot_Slot(props, forwardedRef) { (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { registry.updateSlot(name, ref, fillPropsRef.current); }); - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(component, { - as: as, + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(component_default, { + as, ref: (0,external_wp_compose_namespaceObject.useMergeRefs)([forwardedRef, ref]), ...restProps }); } -/* harmony default export */ const bubbles_virtually_slot = ((0,external_wp_element_namespaceObject.forwardRef)(slot_Slot)); +var slot_slot_default = (0,external_wp_element_namespaceObject.forwardRef)(slot_Slot); + ;// external ["wp","isShallowEqual"] const external_wp_isShallowEqual_namespaceObject = window["wp"]["isShallowEqual"]; var external_wp_isShallowEqual_default = /*#__PURE__*/__webpack_require__.n(external_wp_isShallowEqual_namespaceObject); ;// ./node_modules/@wordpress/components/build-module/slot-fill/bubbles-virtually/slot-fill-provider.js -/** - * WordPress dependencies - */ -/** - * Internal dependencies - */ - function createSlotRegistry() { const slots = (0,external_wp_compose_namespaceObject.observableMap)(); @@ -34091,9 +33711,6 @@ function createSlotRegistry() { if (!slot) { return; } - - // Make sure we're not unregistering a slot registered by another element - // See https://github.com/WordPress/gutenberg/pull/19242#issuecomment-590295412 if (slot.ref !== ref) { return; } @@ -34116,14 +33733,14 @@ function createSlotRegistry() { }); }; const registerFill = (name, ref) => { - fills.set(name, [...(fills.get(name) || []), ref]); + fills.set(name, [...fills.get(name) || [], ref]); }; const unregisterFill = (name, ref) => { const fillsForName = fills.get(name); if (!fillsForName) { return; } - fills.set(name, fillsForName.filter(fillRef => fillRef !== ref)); + fills.set(name, fillsForName.filter((fillRef) => fillRef !== ref)); }; return { slots, @@ -34139,22 +33756,16 @@ function SlotFillProvider({ children }) { const [registry] = (0,external_wp_element_namespaceObject.useState)(createSlotRegistry); - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(slot_fill_context.Provider, { + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(slot_fill_context_default.Provider, { value: registry, - children: children + children }); } + ;// ./node_modules/@wordpress/components/build-module/slot-fill/provider.js -/** - * WordPress dependencies - */ -/** - * Internal dependencies - */ - function provider_createSlotRegistry() { @@ -34164,16 +33775,13 @@ function provider_createSlotRegistry() { slots.set(name, instance); } function unregisterSlot(name, instance) { - // If a previous instance of a Slot by this name unmounts, do nothing, - // as the slot and its fills should only be removed for the current - // known instance. if (slots.get(name) !== instance) { return; } slots.delete(name); } function registerFill(name, instance, children) { - fills.set(name, [...(fills.get(name) || []), { + fills.set(name, [...fills.get(name) || [], { instance, children }]); @@ -34183,23 +33791,22 @@ function provider_createSlotRegistry() { if (!fillsForName) { return; } - fills.set(name, fillsForName.filter(fill => fill.instance !== instance)); + fills.set(name, fillsForName.filter((fill) => fill.instance !== instance)); } function updateFill(name, instance, children) { const fillsForName = fills.get(name); if (!fillsForName) { return; } - const fillForInstance = fillsForName.find(f => f.instance === instance); + const fillForInstance = fillsForName.find((f) => f.instance === instance); if (!fillForInstance) { return; } if (fillForInstance.children === children) { return; } - fills.set(name, fillsForName.map(f => { + fills.set(name, fillsForName.map((f) => { if (f.instance === instance) { - // Replace with new record with updated `children`. return { instance, children @@ -34222,26 +33829,16 @@ function provider_SlotFillProvider({ children }) { const [contextValue] = (0,external_wp_element_namespaceObject.useState)(provider_createSlotRegistry); - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(context.Provider, { + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(context_default.Provider, { value: contextValue, - children: children + children }); } -/* harmony default export */ const provider = (provider_SlotFillProvider); +var provider_default = provider_SlotFillProvider; + ;// ./node_modules/@wordpress/components/build-module/slot-fill/index.js -/** - * External dependencies - */ -/** - * WordPress dependencies - */ - - -/** - * Internal dependencies - */ @@ -34253,13 +33850,10 @@ function provider_SlotFillProvider({ function slot_fill_Fill(props) { - // We're adding both Fills here so they can register themselves before - // their respective slot has been registered. Only the Fill that has a slot - // will render. The other one will return null. - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { - children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Fill, { + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { + children: [/* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(Fill, { ...props - }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(fill_Fill, { + }), /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(fill_Fill, { ...props })] }); @@ -34270,12 +33864,12 @@ function UnforwardedSlot(props, ref) { ...restProps } = props; if (bubblesVirtually) { - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(bubbles_virtually_slot, { + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(slot_slot_default, { ...restProps, - ref: ref + ref }); } - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(slot, { + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(slot_default, { ...restProps }); } @@ -34284,35 +33878,31 @@ function Provider({ children, passthrough = false }) { - const parent = (0,external_wp_element_namespaceObject.useContext)(slot_fill_context); + const parent = (0,external_wp_element_namespaceObject.useContext)(slot_fill_context_default); if (!parent.isDefault && passthrough) { - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_ReactJSXRuntime_namespaceObject.Fragment, { - children: children + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(external_ReactJSXRuntime_namespaceObject.Fragment, { + children }); } - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(provider, { - children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(SlotFillProvider, { - children: children + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(provider_default, { + children: /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(SlotFillProvider, { + children }) }); } -Provider.displayName = 'SlotFillProvider'; +Provider.displayName = "SlotFillProvider"; function createSlotFill(key) { - const baseName = typeof key === 'symbol' ? key.description : key; - const FillComponent = props => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(slot_fill_Fill, { + const baseName = typeof key === "symbol" ? key.description : key; + const FillComponent = (props) => /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(slot_fill_Fill, { name: key, ...props }); FillComponent.displayName = `${baseName}Fill`; - const SlotComponent = props => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(slot_fill_Slot, { + const SlotComponent = (props) => /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(slot_fill_Slot, { name: key, ...props }); SlotComponent.displayName = `${baseName}Slot`; - /** - * @deprecated 6.8.0 - * Please use `slotFill.name` instead of `slotFill.Slot.__unstableName`. - */ SlotComponent.__unstableName = key; return { name: key, @@ -34321,15 +33911,12 @@ function createSlotFill(key) { }; } -;// ./node_modules/@wordpress/components/build-module/popover/overlay-middlewares.js -/** - * External dependencies - */ +;// ./node_modules/@wordpress/components/build-module/popover/overlay-middlewares.js function overlayMiddlewares() { return [{ - name: 'overlay', + name: "overlay", fn({ rects }) { @@ -34344,13 +33931,9 @@ function overlayMiddlewares() { const { firstElementChild } = (_elements$floating = elements.floating) !== null && _elements$floating !== void 0 ? _elements$floating : {}; - - // Only HTMLElement instances have the `style` property. if (!(firstElementChild instanceof HTMLElement)) { return; } - - // Reduce the height of the popover to the available space. Object.assign(firstElementChild.style, { width: `${rects.reference.width}px`, height: `${rects.reference.height}px` @@ -34359,28 +33942,8 @@ function overlayMiddlewares() { })]; } + ;// ./node_modules/@wordpress/components/build-module/popover/index.js -/** - * External dependencies - */ - - - - - -/** - * WordPress dependencies - */ - - - - - - - -/** - * Internal dependencies - */ @@ -34389,38 +33952,38 @@ function overlayMiddlewares() { -/** - * Name of slot in which popover should fill. - * - * @type {string} - */ -const SLOT_NAME = 'Popover'; -// An SVG displaying a triangle facing down, filled with a solid -// color and bordered in such a way to create an arrow-like effect. -// Keeping the SVG's viewbox squared simplify the arrow positioning -// calculations. -const ArrowTriangle = () => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_primitives_namespaceObject.SVG, { + + + + + + + +const SLOT_NAME = "Popover"; +const OVERFLOW_PADDING = 8; +const ArrowTriangle = () => /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_primitives_namespaceObject.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100", className: "components-popover__triangle", role: "presentation", - children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { + children: [/* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { className: "components-popover__triangle-bg", d: "M 0 0 L 50 50 L 100 0" - }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { + }), /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { className: "components-popover__triangle-border", d: "M 0 0 L 50 50 L 100 0", vectorEffect: "non-scaling-stroke" })] }); -const slotNameContext = (0,external_wp_element_namespaceObject.createContext)(undefined); -const fallbackContainerClassname = 'components-popover__fallback-container'; +const slotNameContext = (0,external_wp_element_namespaceObject.createContext)(void 0); +slotNameContext.displayName = "__unstableSlotNameContext"; +const fallbackContainerClassname = "components-popover__fallback-container"; const getPopoverFallbackContainer = () => { - let container = document.body.querySelector('.' + fallbackContainerClassname); + let container = document.body.querySelector("." + fallbackContainerClassname); if (!container) { - container = document.createElement('div'); + container = document.createElement("div"); container.className = fallbackContainerClassname; document.body.append(container); } @@ -34436,9 +33999,9 @@ const UnforwardedPopover = (props, forwardedRef) => { className, noArrow = true, position, - placement: placementProp = 'bottom-start', + placement: placementProp = "bottom-start", offset: offsetProp = 0, - focusOnMount = 'firstElement', + focusOnMount = "firstElement", anchor, expandOnMobile, onFocusOutside, @@ -34457,77 +34020,72 @@ const UnforwardedPopover = (props, forwardedRef) => { isAlternate, // Rest ...contentProps - } = useContextSystem(props, 'Popover'); + } = useContextSystem(props, "Popover"); let computedFlipProp = flip; let computedResizeProp = resize; - if (__unstableForcePosition !== undefined) { - external_wp_deprecated_default()('`__unstableForcePosition` prop in wp.components.Popover', { - since: '6.1', - version: '6.3', - alternative: '`flip={ false }` and `resize={ false }`' + if (__unstableForcePosition !== void 0) { + external_wp_deprecated_default()("`__unstableForcePosition` prop in wp.components.Popover", { + since: "6.1", + version: "6.3", + alternative: "`flip={ false }` and `resize={ false }`" }); - - // Back-compat, set the `flip` and `resize` props - // to `false` to replicate `__unstableForcePosition`. computedFlipProp = !__unstableForcePosition; computedResizeProp = !__unstableForcePosition; } - if (anchorRef !== undefined) { - external_wp_deprecated_default()('`anchorRef` prop in wp.components.Popover', { - since: '6.1', - alternative: '`anchor` prop' + if (anchorRef !== void 0) { + external_wp_deprecated_default()("`anchorRef` prop in wp.components.Popover", { + since: "6.1", + alternative: "`anchor` prop" }); } - if (anchorRect !== undefined) { - external_wp_deprecated_default()('`anchorRect` prop in wp.components.Popover', { - since: '6.1', - alternative: '`anchor` prop' + if (anchorRect !== void 0) { + external_wp_deprecated_default()("`anchorRect` prop in wp.components.Popover", { + since: "6.1", + alternative: "`anchor` prop" }); } - if (getAnchorRect !== undefined) { - external_wp_deprecated_default()('`getAnchorRect` prop in wp.components.Popover', { - since: '6.1', - alternative: '`anchor` prop' + if (getAnchorRect !== void 0) { + external_wp_deprecated_default()("`getAnchorRect` prop in wp.components.Popover", { + since: "6.1", + alternative: "`anchor` prop" }); } - const computedVariant = isAlternate ? 'toolbar' : variant; - if (isAlternate !== undefined) { - external_wp_deprecated_default()('`isAlternate` prop in wp.components.Popover', { - since: '6.2', + const computedVariant = isAlternate ? "toolbar" : variant; + if (isAlternate !== void 0) { + external_wp_deprecated_default()("`isAlternate` prop in wp.components.Popover", { + since: "6.2", alternative: "`variant` prop with the `'toolbar'` value" }); } const arrowRef = (0,external_wp_element_namespaceObject.useRef)(null); const [fallbackReferenceElement, setFallbackReferenceElement] = (0,external_wp_element_namespaceObject.useState)(null); - const anchorRefFallback = (0,external_wp_element_namespaceObject.useCallback)(node => { + const anchorRefFallback = (0,external_wp_element_namespaceObject.useCallback)((node) => { setFallbackReferenceElement(node); }, []); - const isMobileViewport = (0,external_wp_compose_namespaceObject.useViewportMatch)('medium', '<'); + const isMobileViewport = (0,external_wp_compose_namespaceObject.useViewportMatch)("medium", "<"); const isExpanded = expandOnMobile && isMobileViewport; const hasArrow = !isExpanded && !noArrow; const normalizedPlacementFromProps = position ? positionToPlacement(position) : placementProp; - const middleware = [...(placementProp === 'overlay' ? overlayMiddlewares() : []), offset(offsetProp), computedFlipProp && floating_ui_dom_flip(), computedResizeProp && floating_ui_dom_size({ + const middleware = [...placementProp === "overlay" ? overlayMiddlewares() : [], offset(offsetProp), computedFlipProp && floating_ui_dom_flip(), computedResizeProp && floating_ui_dom_size({ + padding: OVERFLOW_PADDING, apply(sizeProps) { var _refs$floating$curren; const { firstElementChild } = (_refs$floating$curren = refs.floating.current) !== null && _refs$floating$curren !== void 0 ? _refs$floating$curren : {}; - - // Only HTMLElement instances have the `style` property. if (!(firstElementChild instanceof HTMLElement)) { return; } - - // Reduce the height of the popover to the available space. Object.assign(firstElementChild.style, { - maxHeight: `${sizeProps.availableHeight}px`, - overflow: 'auto' + maxHeight: `${Math.max(0, sizeProps.availableHeight)}px`, + overflow: "auto" }); } }), shift && floating_ui_dom_shift({ crossAxis: true, limiter: floating_ui_dom_limitShift(), - padding: 1 // Necessary to avoid flickering at the edge of the viewport. + padding: 1 + // Necessary to avoid flickering at the edge of the viewport. }), floating_ui_react_dom_arrow({ element: arrowRef })]; @@ -34536,9 +34094,7 @@ const UnforwardedPopover = (props, forwardedRef) => { let onDialogClose; if (onClose || onFocusOutside) { onDialogClose = (type, event) => { - // Ideally the popover should have just a single onClose prop and - // not three props that potentially do the same thing. - if (type === 'focus-outside' && onFocusOutside) { + if (type === "focus-outside" && onFocusOutside) { onFocusOutside(event); } else if (onClose) { onClose(); @@ -34566,21 +34122,17 @@ const UnforwardedPopover = (props, forwardedRef) => { arrow: arrowData } } = useFloating({ - placement: normalizedPlacementFromProps === 'overlay' ? undefined : normalizedPlacementFromProps, + placement: normalizedPlacementFromProps === "overlay" ? void 0 : normalizedPlacementFromProps, middleware, whileElementsMounted: (referenceParam, floatingParam, updateParam) => autoUpdate(referenceParam, floatingParam, updateParam, { layoutShift: false, animationFrame: true }) }); - const arrowCallbackRef = (0,external_wp_element_namespaceObject.useCallback)(node => { + const arrowCallbackRef = (0,external_wp_element_namespaceObject.useCallback)((node) => { arrowRef.current = node; update(); }, [update]); - - // When any of the possible anchor "sources" change, - // recompute the reference element (real or virtual) and its owner document. - const anchorRefTop = anchorRef?.top; const anchorRefBottom = anchorRef?.bottom; const anchorRefStartContainer = anchorRef?.startContainer; @@ -34596,7 +34148,7 @@ const UnforwardedPopover = (props, forwardedRef) => { refs.setReference(resultingReferenceElement); }, [anchor, anchorRef, anchorRefTop, anchorRefBottom, anchorRefStartContainer, anchorRefCurrent, anchorRect, getAnchorRect, fallbackReferenceElement, refs]); const mergedFloatingRef = (0,external_wp_compose_namespaceObject.useMergeRefs)([refs.setFloating, dialogRef, forwardedRef]); - const style = isExpanded ? undefined : { + const style = isExpanded ? void 0 : { position: strategy, top: 0, left: 0, @@ -34630,129 +34182,102 @@ const UnforwardedPopover = (props, forwardedRef) => { ...style } }; - - // When Floating UI has finished positioning and Framer Motion has finished animating - // the popover, add the `is-positioned` class to signal that all transitions have finished. const isPositioned = (!shouldAnimate || animationFinished) && x !== null && y !== null; - let content = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(motion.div, { + let content = /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsxs)(motion.div, { className: dist_clsx(className, { - 'is-expanded': isExpanded, - 'is-positioned': isPositioned, + "is-expanded": isExpanded, + "is-positioned": isPositioned, // Use the 'alternate' classname for 'toolbar' variant for back compat. - [`is-${computedVariant === 'toolbar' ? 'alternate' : computedVariant}`]: computedVariant + [`is-${computedVariant === "toolbar" ? "alternate" : computedVariant}`]: computedVariant }), ...animationProps, ...contentProps, ref: mergedFloatingRef, ...dialogProps, tabIndex: -1, - children: [isExpanded && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(scroll_lock, {}), isExpanded && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { + children: [isExpanded && /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(scroll_lock_default, {}), isExpanded && /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { className: "components-popover__header", - children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { + children: [/* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { className: "components-popover__header-title", children: headerTitle - }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(build_module_button, { + }), /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(button_default, { className: "components-popover__close", size: "small", - icon: library_close, + icon: close_default, onClick: onClose, - label: (0,external_wp_i18n_namespaceObject.__)('Close') + label: (0,external_wp_i18n_namespaceObject.__)("Close") })] - }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { + }), /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { className: "components-popover__content", - children: children - }), hasArrow && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { + children + }), hasArrow && /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { ref: arrowCallbackRef, - className: ['components-popover__arrow', `is-${computedPlacement.split('-')[0]}`].join(' '), + className: ["components-popover__arrow", `is-${computedPlacement.split("-")[0]}`].join(" "), style: { - left: typeof arrowData?.x !== 'undefined' && Number.isFinite(arrowData.x) ? `${arrowData.x}px` : '', - top: typeof arrowData?.y !== 'undefined' && Number.isFinite(arrowData.y) ? `${arrowData.y}px` : '' + left: typeof arrowData?.x !== "undefined" && Number.isFinite(arrowData.x) ? `${arrowData.x}px` : "", + top: typeof arrowData?.y !== "undefined" && Number.isFinite(arrowData.y) ? `${arrowData.y}px` : "" }, - children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ArrowTriangle, {}) + children: /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(ArrowTriangle, {}) })] }); const shouldRenderWithinSlot = slot.ref && !inline; const hasAnchor = anchorRef || anchorRect || anchor; if (shouldRenderWithinSlot) { - content = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(slot_fill_Fill, { + content = /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(slot_fill_Fill, { name: slotName, children: content }); } else if (!inline) { - content = (0,external_wp_element_namespaceObject.createPortal)(/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(StyleProvider, { - document: document, + content = (0,external_wp_element_namespaceObject.createPortal)(/* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(StyleProvider, { + document, children: content }), getPopoverFallbackContainer()); } if (hasAnchor) { return content; } - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { - children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { + children: [/* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { ref: anchorRefFallback }), content] }); }; - -/** - * `Popover` renders its content in a floating modal. If no explicit anchor is passed via props, it anchors to its parent element by default. - * - * ```jsx - * import { Button, Popover } from '@wordpress/components'; - * import { useState } from '@wordpress/element'; - * - * const MyPopover = () => { - * const [ isVisible, setIsVisible ] = useState( false ); - * const toggleVisible = () => { - * setIsVisible( ( state ) => ! state ); - * }; - * - * return ( - * - * ); - * }; - * ``` - * - */ -const popover_Popover = contextConnect(UnforwardedPopover, 'Popover'); -function PopoverSlot({ +const PopoverSlot = (0,external_wp_element_namespaceObject.forwardRef)(({ name = SLOT_NAME -}, ref) { - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(slot_fill_Slot, { +}, ref) => { + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(slot_fill_Slot, { bubblesVirtually: true, - name: name, + name, className: "popover-slot", - ref: ref + ref }); -} +}); +const popover_Popover = Object.assign(contextConnect(UnforwardedPopover, "Popover"), { + /** + * Renders a slot that is used internally by Popover for rendering content. + */ + Slot: Object.assign(PopoverSlot, { + displayName: "Popover.Slot" + }), + /** + * Provides a context to manage popover slot names. + * + * This is marked as unstable and should not be used directly. + */ + __unstableSlotNameProvider: Object.assign(slotNameContext.Provider, { + displayName: "Popover.__unstableSlotNameProvider" + }) +}); +var popover_default = popover_Popover; -// @ts-expect-error For Legacy Reasons -popover_Popover.Slot = (0,external_wp_element_namespaceObject.forwardRef)(PopoverSlot); -// @ts-expect-error For Legacy Reasons -popover_Popover.__unstableSlotNameProvider = slotNameContext.Provider; -/* harmony default export */ const popover = (popover_Popover); ;// ./node_modules/@wordpress/components/build-module/autocomplete/autocompleter-ui.js -/** - * External dependencies - */ - - -/** - * WordPress dependencies - */ -/** - * Internal dependencies - */ @@ -34766,24 +34291,24 @@ function ListBox({ instanceId, listBoxId, className, - Component = 'div' + Component = "div" }) { - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Component, { + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(Component, { id: listBoxId, role: "listbox", className: "components-autocomplete__results", - children: items.map((option, index) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(build_module_button, { + children: items.map((option, index) => /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(button_default, { id: `components-autocomplete-item-${instanceId}-${option.key}`, role: "option", __next40pxDefaultSize: true, "aria-selected": index === selectedIndex, accessibleWhenDisabled: true, disabled: option.isDisabled, - className: dist_clsx('components-autocomplete__result', className, { + className: dist_clsx("components-autocomplete__result", className, { // Unused, for backwards compatibility. - 'is-selected': index === selectedIndex + "is-selected": index === selectedIndex }), - variant: index === selectedIndex ? 'primary' : undefined, + variant: index === selectedIndex ? "primary" : void 0, onClick: () => onSelect(option), children: option.label }, option.key)) @@ -34810,15 +34335,10 @@ function getAutoCompleterUI(autocompleter) { }); const [needsA11yCompat, setNeedsA11yCompat] = (0,external_wp_element_namespaceObject.useState)(false); const popoverRef = (0,external_wp_element_namespaceObject.useRef)(null); - const popoverRefs = (0,external_wp_compose_namespaceObject.useMergeRefs)([popoverRef, (0,external_wp_compose_namespaceObject.useRefEffect)(node => { + const popoverRefs = (0,external_wp_compose_namespaceObject.useMergeRefs)([popoverRef, (0,external_wp_compose_namespaceObject.useRefEffect)((node) => { if (!contentRef.current) { return; } - - // If the popover is rendered in a different document than - // the content, we need to duplicate the options list in the - // content document so that it's available to the screen - // readers, which check the DOM ID based aria-* attributes. setNeedsA11yCompat(node.ownerDocument !== contentRef.current.ownerDocument); }, [contentRef])]); useOnClickOutside(popoverRef, reset); @@ -34829,49 +34349,53 @@ function getAutoCompleterUI(autocompleter) { } if (!!options.length) { if (filterValue) { - debouncedSpeak((0,external_wp_i18n_namespaceObject.sprintf)(/* translators: %d: number of results. */ - (0,external_wp_i18n_namespaceObject._n)('%d result found, use up and down arrow keys to navigate.', '%d results found, use up and down arrow keys to navigate.', options.length), options.length), 'assertive'); + debouncedSpeak((0,external_wp_i18n_namespaceObject.sprintf)( + /* translators: %d: number of results. */ + (0,external_wp_i18n_namespaceObject._n)("%d result found, use up and down arrow keys to navigate.", "%d results found, use up and down arrow keys to navigate.", options.length), + options.length + ), "assertive"); } else { - debouncedSpeak((0,external_wp_i18n_namespaceObject.sprintf)(/* translators: %d: number of results. */ - (0,external_wp_i18n_namespaceObject._n)('Initial %d result loaded. Type to filter all available results. Use up and down arrow keys to navigate.', 'Initial %d results loaded. Type to filter all available results. Use up and down arrow keys to navigate.', options.length), options.length), 'assertive'); + debouncedSpeak((0,external_wp_i18n_namespaceObject.sprintf)( + /* translators: %d: number of results. */ + (0,external_wp_i18n_namespaceObject._n)("Initial %d result loaded. Type to filter all available results. Use up and down arrow keys to navigate.", "Initial %d results loaded. Type to filter all available results. Use up and down arrow keys to navigate.", options.length), + options.length + ), "assertive"); } } else { - debouncedSpeak((0,external_wp_i18n_namespaceObject.__)('No results.'), 'assertive'); + debouncedSpeak((0,external_wp_i18n_namespaceObject.__)("No results."), "assertive"); } } (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { onChangeOptions(items); announce(items); - // We want to avoid introducing unexpected side effects. - // See https://github.com/WordPress/gutenberg/pull/41820 }, [items]); if (items.length === 0) { return null; } - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { - children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(popover, { + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { + children: [/* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(popover_default, { focusOnMount: false, onClose: onReset, placement: "top-start", className: "components-autocomplete__popover", anchor: popoverAnchor, ref: popoverRefs, - children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ListBox, { - items: items, - onSelect: onSelect, - selectedIndex: selectedIndex, - instanceId: instanceId, - listBoxId: listBoxId, - className: className + children: /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(ListBox, { + items, + onSelect, + selectedIndex, + instanceId, + listBoxId, + className }) - }), contentRef.current && needsA11yCompat && (0,external_ReactDOM_namespaceObject.createPortal)(/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ListBox, { - items: items, - onSelect: onSelect, - selectedIndex: selectedIndex, - instanceId: instanceId, - listBoxId: listBoxId, - className: className, - Component: visually_hidden_component + }), contentRef.current && needsA11yCompat && (0,external_ReactDOM_namespaceObject.createPortal)(/* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(ListBox, { + items, + onSelect, + selectedIndex, + instanceId, + listBoxId, + className, + Component: component_component_default }), contentRef.current.ownerDocument.body)] }); } @@ -34879,74 +34403,60 @@ function getAutoCompleterUI(autocompleter) { } function useOnClickOutside(ref, handler) { (0,external_wp_element_namespaceObject.useEffect)(() => { - const listener = event => { - // Do nothing if clicking ref's element or descendent elements, or if the ref is not referencing an element + const listener = (event) => { if (!ref.current || ref.current.contains(event.target)) { return; } handler(event); }; - document.addEventListener('mousedown', listener); - document.addEventListener('touchstart', listener); + document.addEventListener("mousedown", listener); + document.addEventListener("touchstart", listener); return () => { - document.removeEventListener('mousedown', listener); - document.removeEventListener('touchstart', listener); + document.removeEventListener("mousedown", listener); + document.removeEventListener("touchstart", listener); }; }, [handler, ref]); } -;// ./node_modules/@wordpress/components/build-module/autocomplete/index.js -/** - * External dependencies - */ - -/** - * WordPress dependencies - */ - - - - - - -/** - * Internal dependencies - */ - - - - -const getNodeText = node => { +;// ./node_modules/@wordpress/components/build-module/utils/get-node-text.js +const getNodeText = (node) => { if (node === null) { - return ''; + return ""; } switch (typeof node) { - case 'string': - case 'number': + case "string": + case "number": return node.toString(); - break; - case 'boolean': - return ''; - break; - case 'object': - { - if (node instanceof Array) { - return node.map(getNodeText).join(''); - } - if ('props' in node) { - return getNodeText(node.props.children); - } - break; + case "object": { + if (node instanceof Array) { + return node.map(getNodeText).join(""); } + if ("props" in node) { + return getNodeText(node.props.children); + } + return ""; + } default: - return ''; + return ""; } - return ''; }; -const EMPTY_FILTERED_OPTIONS = []; +var get_node_text_default = getNodeText; -// Used for generating the instance ID + +;// ./node_modules/@wordpress/components/build-module/autocomplete/index.js + + + + + + + + + + + +const EMPTY_FILTERED_OPTIONS = []; const AUTOCOMPLETE_HOOK_REFERENCE = {}; function useAutocomplete({ record, @@ -34958,7 +34468,7 @@ function useAutocomplete({ const instanceId = (0,external_wp_compose_namespaceObject.useInstanceId)(AUTOCOMPLETE_HOOK_REFERENCE); const [selectedIndex, setSelectedIndex] = (0,external_wp_element_namespaceObject.useState)(0); const [filteredOptions, setFilteredOptions] = (0,external_wp_element_namespaceObject.useState)(EMPTY_FILTERED_OPTIONS); - const [filterValue, setFilterValue] = (0,external_wp_element_namespaceObject.useState)(''); + const [filterValue, setFilterValue] = (0,external_wp_element_namespaceObject.useState)(""); const [autocompleter, setAutocompleter] = (0,external_wp_element_namespaceObject.useState)(null); const [AutocompleterUI, setAutocompleterUI] = (0,external_wp_element_namespaceObject.useState)(null); const backspacingRef = (0,external_wp_element_namespaceObject.useRef)(false); @@ -34982,46 +34492,36 @@ function useAutocomplete({ } if (getOptionCompletion) { const completion = getOptionCompletion(option.value, filterValue); - const isCompletionObject = obj => { - return obj !== null && typeof obj === 'object' && 'action' in obj && obj.action !== undefined && 'value' in obj && obj.value !== undefined; + const isCompletionObject = (obj) => { + return obj !== null && typeof obj === "object" && "action" in obj && obj.action !== void 0 && "value" in obj && obj.value !== void 0; }; const completionObject = isCompletionObject(completion) ? completion : { - action: 'insert-at-caret', + action: "insert-at-caret", value: completion }; - if ('replace' === completionObject.action) { + if ("replace" === completionObject.action) { onReplace([completionObject.value]); - // When replacing, the component will unmount, so don't reset - // state (below) on an unmounted component. return; - } else if ('insert-at-caret' === completionObject.action) { + } else if ("insert-at-caret" === completionObject.action) { insertCompletion(completionObject.value); } } - - // Reset autocomplete state after insertion rather than before - // so insertion events don't cause the completion menu to redisplay. reset(); + contentRef.current?.focus(); } function reset() { setSelectedIndex(0); setFilteredOptions(EMPTY_FILTERED_OPTIONS); - setFilterValue(''); + setFilterValue(""); setAutocompleter(null); setAutocompleterUI(null); } - - /** - * Load options for an autocompleter. - * - * @param {Array} options - */ function onChangeOptions(options) { setSelectedIndex(options.length === filteredOptions.length ? selectedIndex : 0); setFilteredOptions(options); } function handleKeyDown(event) { - backspacingRef.current = event.key === 'Backspace'; + backspacingRef.current = event.key === "Backspace"; if (!autocompleter) { return; } @@ -35032,54 +34532,44 @@ function useAutocomplete({ return; } switch (event.key) { - case 'ArrowUp': - { - const newIndex = (selectedIndex === 0 ? filteredOptions.length : selectedIndex) - 1; - setSelectedIndex(newIndex); - // See the related PR as to why this is necessary: https://github.com/WordPress/gutenberg/pull/54902. - if ((0,external_wp_keycodes_namespaceObject.isAppleOS)()) { - (0,external_wp_a11y_namespaceObject.speak)(getNodeText(filteredOptions[newIndex].label), 'assertive'); - } - break; + case "ArrowUp": { + const newIndex = (selectedIndex === 0 ? filteredOptions.length : selectedIndex) - 1; + setSelectedIndex(newIndex); + if ((0,external_wp_keycodes_namespaceObject.isAppleOS)()) { + (0,external_wp_a11y_namespaceObject.speak)(get_node_text_default(filteredOptions[newIndex].label), "assertive"); } - case 'ArrowDown': - { - const newIndex = (selectedIndex + 1) % filteredOptions.length; - setSelectedIndex(newIndex); - if ((0,external_wp_keycodes_namespaceObject.isAppleOS)()) { - (0,external_wp_a11y_namespaceObject.speak)(getNodeText(filteredOptions[newIndex].label), 'assertive'); - } - break; + break; + } + case "ArrowDown": { + const newIndex = (selectedIndex + 1) % filteredOptions.length; + setSelectedIndex(newIndex); + if ((0,external_wp_keycodes_namespaceObject.isAppleOS)()) { + (0,external_wp_a11y_namespaceObject.speak)(get_node_text_default(filteredOptions[newIndex].label), "assertive"); } - case 'Escape': + break; + } + case "Escape": setAutocompleter(null); setAutocompleterUI(null); event.preventDefault(); break; - case 'Enter': + case "Enter": select(filteredOptions[selectedIndex]); break; - case 'ArrowLeft': - case 'ArrowRight': + case "ArrowLeft": + case "ArrowRight": reset(); return; default: return; } - - // Any handled key should prevent original behavior. This relies on - // the early return in the default case. event.preventDefault(); } - - // textContent is a primitive (string), memoizing is not strictly necessary - // but this is a preemptive performance improvement, since the autocompleter - // is a potential bottleneck for the editor type metric. const textContent = (0,external_wp_element_namespaceObject.useMemo)(() => { if ((0,external_wp_richText_namespaceObject.isCollapsed)(record)) { return (0,external_wp_richText_namespaceObject.getTextContent)((0,external_wp_richText_namespaceObject.slice)(record, 0)); } - return ''; + return ""; }, [record]); (0,external_wp_element_namespaceObject.useEffect)(() => { if (!textContent) { @@ -35088,13 +34578,10 @@ function useAutocomplete({ } return; } - - // Find the completer with the highest triggerPrefix index in the - // textContent. const completer = completers.reduce((lastTrigger, currentCompleter) => { - const triggerIndex = textContent.lastIndexOf(currentCompleter.triggerPrefix); + const triggerIndex2 = textContent.lastIndexOf(currentCompleter.triggerPrefix); const lastTriggerIndex = lastTrigger !== null ? textContent.lastIndexOf(lastTrigger.triggerPrefix) : -1; - return triggerIndex > lastTriggerIndex ? currentCompleter : lastTrigger; + return triggerIndex2 > lastTriggerIndex ? currentCompleter : lastTrigger; }, null); if (!completer) { if (autocompleter) { @@ -35108,34 +34595,13 @@ function useAutocomplete({ } = completer; const triggerIndex = textContent.lastIndexOf(triggerPrefix); const textWithoutTrigger = textContent.slice(triggerIndex + triggerPrefix.length); - const tooDistantFromTrigger = textWithoutTrigger.length > 50; // 50 chars seems to be a good limit. - // This is a final barrier to prevent the effect from completing with - // an extremely long string, which causes the editor to slow-down - // significantly. This could happen, for example, if `matchingWhileBackspacing` - // is true and one of the "words" end up being too long. If that's the case, - // it will be caught by this guard. + const tooDistantFromTrigger = textWithoutTrigger.length > 50; if (tooDistantFromTrigger) { return; } const mismatch = filteredOptions.length === 0; const wordsFromTrigger = textWithoutTrigger.split(/\s/); - // We need to allow the effect to run when not backspacing and if there - // was a mismatch. i.e when typing a trigger + the match string or when - // clicking in an existing trigger word on the page. We do that if we - // detect that we have one word from trigger in the current textual context. - // - // Ex.: "Some text @a" <-- "@a" will be detected as the trigger word and - // allow the effect to run. It will run until there's a mismatch. const hasOneTriggerWord = wordsFromTrigger.length === 1; - // This is used to allow the effect to run when backspacing and if - // "touching" a word that "belongs" to a trigger. We consider a "trigger - // word" any word up to the limit of 3 from the trigger character. - // Anything beyond that is ignored if there's a mismatch. This allows - // us to "escape" a mismatch when backspacing, but still imposing some - // sane limits. - // - // Ex: "Some text @marcelo sekkkk" <--- "kkkk" caused a mismatch, but - // if the user presses backspace here, it will show the completion popup again. const matchingWhileBackspacing = backspacingRef.current && wordsFromTrigger.length <= 3; if (mismatch && !(matchingWhileBackspacing || hasOneTriggerWord)) { if (autocompleter) { @@ -35143,7 +34609,7 @@ function useAutocomplete({ } return; } - const textAfterSelection = (0,external_wp_richText_namespaceObject.getTextContent)((0,external_wp_richText_namespaceObject.slice)(record, undefined, (0,external_wp_richText_namespaceObject.getTextContent)(record).length)); + const textAfterSelection = (0,external_wp_richText_namespaceObject.getTextContent)((0,external_wp_richText_namespaceObject.slice)(record, void 0, (0,external_wp_richText_namespaceObject.getTextContent)(record).length)); if (allowContext && !allowContext(textContent.slice(0, triggerIndex), textAfterSelection)) { if (autocompleter) { reset(); @@ -35164,47 +34630,44 @@ function useAutocomplete({ } const safeTrigger = escapeRegExp(completer.triggerPrefix); const text = remove_accents_default()(textContent); - const match = text.slice(text.lastIndexOf(completer.triggerPrefix)).match(new RegExp(`${safeTrigger}([\u0000-\uFFFF]*)$`)); + const match = text.slice(text.lastIndexOf(completer.triggerPrefix)).match(new RegExp(`${safeTrigger}([\0-\uFFFF]*)$`)); const query = match && match[1]; setAutocompleter(completer); setAutocompleterUI(() => completer !== autocompleter ? getAutoCompleterUI(completer) : AutocompleterUI); - setFilterValue(query === null ? '' : query); - // We want to avoid introducing unexpected side effects. - // See https://github.com/WordPress/gutenberg/pull/41820 + setFilterValue(query === null ? "" : query); }, [textContent]); const { - key: selectedKey = '' + key: selectedKey = "" } = filteredOptions[selectedIndex] || {}; const { className } = autocompleter || {}; const isExpanded = !!autocompleter && filteredOptions.length > 0; - const listBoxId = isExpanded ? `components-autocomplete-listbox-${instanceId}` : undefined; + const listBoxId = isExpanded ? `components-autocomplete-listbox-${instanceId}` : void 0; const activeId = isExpanded ? `components-autocomplete-item-${instanceId}-${selectedKey}` : null; - const hasSelection = record.start !== undefined; + const hasSelection = record.start !== void 0; + const showPopover = !!textContent && hasSelection && !!AutocompleterUI; return { listBoxId, activeId, onKeyDown: withIgnoreIMEEvents(handleKeyDown), - popover: hasSelection && AutocompleterUI && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(AutocompleterUI, { - className: className, - filterValue: filterValue, - instanceId: instanceId, - listBoxId: listBoxId, - selectedIndex: selectedIndex, - onChangeOptions: onChangeOptions, + popover: showPopover && /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(AutocompleterUI, { + className, + filterValue, + instanceId, + listBoxId, + selectedIndex, + onChangeOptions, onSelect: select, value: record, - contentRef: contentRef, - reset: reset + contentRef, + reset }) }; } function useLastDifferentValue(value) { - const history = (0,external_wp_element_namespaceObject.useRef)(new Set()); + const history = (0,external_wp_element_namespaceObject.useRef)(/* @__PURE__ */ new Set()); history.current.add(value); - - // Keep the history size to 2. if (history.current.size > 2) { history.current.delete(Array.from(history.current)[0]); } @@ -35227,17 +34690,15 @@ function useAutocompleteProps(options) { contentRef: ref }); onKeyDownRef.current = onKeyDown; - const mergedRefs = (0,external_wp_compose_namespaceObject.useMergeRefs)([ref, (0,external_wp_compose_namespaceObject.useRefEffect)(element => { + const mergedRefs = (0,external_wp_compose_namespaceObject.useMergeRefs)([ref, (0,external_wp_compose_namespaceObject.useRefEffect)((element) => { function _onKeyDown(event) { onKeyDownRef.current?.(event); } - element.addEventListener('keydown', _onKeyDown); + element.addEventListener("keydown", _onKeyDown); return () => { - element.removeEventListener('keydown', _onKeyDown); + element.removeEventListener("keydown", _onKeyDown); }; }, [])]); - - // We only want to show the popover if the user has typed something. const didUserInput = record.text !== previousRecord?.text; if (!didUserInput) { return { @@ -35247,9 +34708,9 @@ function useAutocompleteProps(options) { return { ref: mergedRefs, children: popover, - 'aria-autocomplete': listBoxId ? 'list' : undefined, - 'aria-owns': listBoxId, - 'aria-activedescendant': activeId + "aria-autocomplete": listBoxId ? "list" : void 0, + "aria-owns": listBoxId, + "aria-activedescendant": activeId }; } function Autocomplete({ @@ -35261,35 +34722,22 @@ function Autocomplete({ popover, ...props } = useAutocomplete(options); - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { children: [children(props), isSelected && popover] }); } + ;// ./node_modules/@wordpress/components/build-module/base-control/hooks.js -/** - * WordPress dependencies - */ -/** - * Internal dependencies - */ - -/** - * Generate props for the `BaseControl` and the inner control itself. - * - * Namely, it takes care of generating a unique `id`, properly associating it with the `label` and `help` elements. - * - * @param props - */ function useBaseControlProps(props) { const { help, id: preferredId, ...restProps } = props; - const uniqueId = (0,external_wp_compose_namespaceObject.useInstanceId)(base_control, 'wp-components-base-control', preferredId); + const uniqueId = (0,external_wp_compose_namespaceObject.useInstanceId)(base_control_default, "wp-components-base-control", preferredId); return { baseControlProps: { id: uniqueId, @@ -35298,114 +34746,84 @@ function useBaseControlProps(props) { }, controlProps: { id: uniqueId, - ...(!!help ? { - 'aria-describedby': `${uniqueId}__help` - } : {}) + ...!!help ? { + "aria-describedby": `${uniqueId}__help` + } : {} } }; } + ;// ./node_modules/@wordpress/icons/build-module/library/link.js -/** - * WordPress dependencies - */ -const link_link = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { - xmlns: "http://www.w3.org/2000/svg", - viewBox: "0 0 24 24", - children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { - d: "M10 17.389H8.444A5.194 5.194 0 1 1 8.444 7H10v1.5H8.444a3.694 3.694 0 0 0 0 7.389H10v1.5ZM14 7h1.556a5.194 5.194 0 0 1 0 10.39H14v-1.5h1.556a3.694 3.694 0 0 0 0-7.39H14V7Zm-4.5 6h5v-1.5h-5V13Z" - }) -}); -/* harmony default export */ const library_link = (link_link); +var link_default = /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { d: "M10 17.389H8.444A5.194 5.194 0 1 1 8.444 7H10v1.5H8.444a3.694 3.694 0 0 0 0 7.389H10v1.5ZM14 7h1.556a5.194 5.194 0 0 1 0 10.39H14v-1.5h1.556a3.694 3.694 0 0 0 0-7.39H14V7Zm-4.5 6h5v-1.5h-5V13Z" }) }); + ;// ./node_modules/@wordpress/icons/build-module/library/link-off.js -/** - * WordPress dependencies - */ -const linkOff = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { - xmlns: "http://www.w3.org/2000/svg", - viewBox: "0 0 24 24", - children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { - d: "M17.031 4.703 15.576 4l-1.56 3H14v.03l-2.324 4.47H9.5V13h1.396l-1.502 2.889h-.95a3.694 3.694 0 0 1 0-7.389H10V7H8.444a5.194 5.194 0 1 0 0 10.389h.17L7.5 19.53l1.416.719L15.049 8.5h.507a3.694 3.694 0 0 1 0 7.39H14v1.5h1.556a5.194 5.194 0 0 0 .273-10.383l1.202-2.304Z" - }) -}); -/* harmony default export */ const link_off = (linkOff); +var link_off_default = /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { d: "M17.031 4.703 15.576 4l-1.56 3H14v.03l-2.324 4.47H9.5V13h1.396l-1.502 2.889h-.95a3.694 3.694 0 0 1 0-7.389H10V7H8.444a5.194 5.194 0 1 0 0 10.389h.17L7.5 19.53l1.416.719L15.049 8.5h.507a3.694 3.694 0 0 1 0 7.39H14v1.5h1.556a5.194 5.194 0 0 0 .273-10.383l1.202-2.304Z" }) }); + ;// ./node_modules/@wordpress/components/build-module/border-box-control/styles.js -function border_box_control_styles_EMOTION_STRINGIFIED_CSS_ERROR_() { return "You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."; } -/** - * External dependencies - */ +function border_box_control_styles_EMOTION_STRINGIFIED_CSS_ERROR_() { + return "You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."; +} -/** - * Internal dependencies - */ - -const borderBoxControl = /*#__PURE__*/emotion_react_browser_esm_css( true ? "" : 0, true ? "" : 0); -const linkedBorderControl = () => /*#__PURE__*/emotion_react_browser_esm_css("flex:1;", rtl({ - marginRight: '24px' +const borderBoxControl = /* @__PURE__ */ emotion_react_browser_esm_css( true ? "" : 0, true ? "" : 0); +const linkedBorderControl = () => /* @__PURE__ */ emotion_react_browser_esm_css("flex:1;", rtl({ + marginRight: "24px" })(), ";" + ( true ? "" : 0), true ? "" : 0); const wrapper = true ? { name: "bjn8wh", styles: "position:relative" } : 0; -const borderBoxControlLinkedButton = size => { - return /*#__PURE__*/emotion_react_browser_esm_css("position:absolute;top:", size === '__unstable-large' ? '8px' : '3px', ";", rtl({ +const borderBoxControlLinkedButton = (size) => { + return /* @__PURE__ */ emotion_react_browser_esm_css("position:absolute;top:", size === "__unstable-large" ? "8px" : "3px", ";", rtl({ right: 0 })(), " line-height:0;" + ( true ? "" : 0), true ? "" : 0); }; -const borderBoxStyleWithFallback = border => { +const borderBoxStyleWithFallback = (border) => { const { color = COLORS.gray[200], - style = 'solid', - width = config_values.borderWidth + style = "solid", + width = config_values_default.borderWidth } = border || {}; - const clampedWidth = width !== config_values.borderWidth ? `clamp(1px, ${width}, 10px)` : width; - const hasVisibleBorder = !!width && width !== '0' || !!color; - const borderStyle = hasVisibleBorder ? style || 'solid' : style; + const clampedWidth = width !== config_values_default.borderWidth ? `clamp(1px, ${width}, 10px)` : width; + const hasVisibleBorder = !!width && width !== "0" || !!color; + const borderStyle = hasVisibleBorder ? style || "solid" : style; return `${color} ${borderStyle} ${clampedWidth}`; }; const borderBoxControlVisualizer = (borders, size) => { - return /*#__PURE__*/emotion_react_browser_esm_css("position:absolute;top:", size === '__unstable-large' ? '20px' : '15px', ";right:", size === '__unstable-large' ? '39px' : '29px', ";bottom:", size === '__unstable-large' ? '20px' : '15px', ";left:", size === '__unstable-large' ? '39px' : '29px', ";border-top:", borderBoxStyleWithFallback(borders?.top), ";border-bottom:", borderBoxStyleWithFallback(borders?.bottom), ";", rtl({ + return /* @__PURE__ */ emotion_react_browser_esm_css("position:absolute;top:", size === "__unstable-large" ? "20px" : "15px", ";right:", size === "__unstable-large" ? "39px" : "29px", ";bottom:", size === "__unstable-large" ? "20px" : "15px", ";left:", size === "__unstable-large" ? "39px" : "29px", ";border-top:", borderBoxStyleWithFallback(borders?.top), ";border-bottom:", borderBoxStyleWithFallback(borders?.bottom), ";", rtl({ borderLeft: borderBoxStyleWithFallback(borders?.left) })(), " ", rtl({ borderRight: borderBoxStyleWithFallback(borders?.right) })(), ";" + ( true ? "" : 0), true ? "" : 0); }; -const borderBoxControlSplitControls = size => /*#__PURE__*/emotion_react_browser_esm_css("position:relative;flex:1;width:", size === '__unstable-large' ? undefined : '80%', ";" + ( true ? "" : 0), true ? "" : 0); +const borderBoxControlSplitControls = (size) => /* @__PURE__ */ emotion_react_browser_esm_css("position:relative;flex:1;width:", size === "__unstable-large" ? void 0 : "80%", ";" + ( true ? "" : 0), true ? "" : 0); const centeredBorderControl = true ? { name: "1nwbfnf", styles: "grid-column:span 2;margin:0 auto" } : 0; -const rightBorderControl = () => /*#__PURE__*/emotion_react_browser_esm_css(rtl({ - marginLeft: 'auto' +const rightBorderControl = () => /* @__PURE__ */ emotion_react_browser_esm_css(rtl({ + marginLeft: "auto" })(), ";" + ( true ? "" : 0), true ? "" : 0); + ;// ./node_modules/@wordpress/components/build-module/border-box-control/border-box-control-linked-button/hook.js -/** - * WordPress dependencies - */ -/** - * Internal dependencies - */ - function useBorderBoxControlLinkedButton(props) { const { className, - size = 'default', + size = "default", ...otherProps - } = useContextSystem(props, 'BorderBoxControlLinkedButton'); - - // Generate class names. + } = useContextSystem(props, "BorderBoxControlLinkedButton"); const cx = useCx(); const classes = (0,external_wp_element_namespaceObject.useMemo)(() => { return cx(borderBoxControlLinkedButton(size), className); @@ -35416,17 +34834,11 @@ function useBorderBoxControlLinkedButton(props) { }; } + ;// ./node_modules/@wordpress/components/build-module/border-box-control/border-box-control-linked-button/component.js -/** - * WordPress dependencies - */ -/** - * Internal dependencies - */ - @@ -35436,41 +34848,33 @@ const BorderBoxControlLinkedButton = (props, forwardedRef) => { isLinked, ...buttonProps } = useBorderBoxControlLinkedButton(props); - const label = isLinked ? (0,external_wp_i18n_namespaceObject.__)('Unlink sides') : (0,external_wp_i18n_namespaceObject.__)('Link sides'); - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(build_module_button, { + const label = isLinked ? (0,external_wp_i18n_namespaceObject.__)("Unlink sides") : (0,external_wp_i18n_namespaceObject.__)("Link sides"); + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(button_default, { ...buttonProps, size: "small", - icon: isLinked ? library_link : link_off, + icon: isLinked ? link_default : link_off_default, iconSize: 24, - label: label, + label, ref: forwardedRef, - className: className + className }); }; -const ConnectedBorderBoxControlLinkedButton = contextConnect(BorderBoxControlLinkedButton, 'BorderBoxControlLinkedButton'); -/* harmony default export */ const border_box_control_linked_button_component = (ConnectedBorderBoxControlLinkedButton); +const ConnectedBorderBoxControlLinkedButton = contextConnect(BorderBoxControlLinkedButton, "BorderBoxControlLinkedButton"); +var border_box_control_linked_button_component_component_default = ConnectedBorderBoxControlLinkedButton; + ;// ./node_modules/@wordpress/components/build-module/border-box-control/border-box-control-visualizer/hook.js -/** - * WordPress dependencies - */ -/** - * Internal dependencies - */ - function useBorderBoxControlVisualizer(props) { const { className, value, - size = 'default', + size = "default", ...otherProps - } = useContextSystem(props, 'BorderBoxControlVisualizer'); - - // Generate class names. + } = useContextSystem(props, "BorderBoxControlVisualizer"); const cx = useCx(); const classes = (0,external_wp_element_namespaceObject.useMemo)(() => { return cx(borderBoxControlVisualizer(value, size), className); @@ -35482,10 +34886,8 @@ function useBorderBoxControlVisualizer(props) { }; } + ;// ./node_modules/@wordpress/components/build-module/border-box-control/border-box-control-visualizer/component.js -/** - * Internal dependencies - */ @@ -35495,82 +34897,62 @@ const BorderBoxControlVisualizer = (props, forwardedRef) => { value, ...otherProps } = useBorderBoxControlVisualizer(props); - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(component, { + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(component_default, { ...otherProps, ref: forwardedRef }); }; -const ConnectedBorderBoxControlVisualizer = contextConnect(BorderBoxControlVisualizer, 'BorderBoxControlVisualizer'); -/* harmony default export */ const border_box_control_visualizer_component = (ConnectedBorderBoxControlVisualizer); +const ConnectedBorderBoxControlVisualizer = contextConnect(BorderBoxControlVisualizer, "BorderBoxControlVisualizer"); +var border_box_control_visualizer_component_component_default = ConnectedBorderBoxControlVisualizer; + ;// ./node_modules/@wordpress/icons/build-module/library/line-solid.js -/** - * WordPress dependencies - */ -const lineSolid = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { - xmlns: "http://www.w3.org/2000/svg", - viewBox: "0 0 24 24", - children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { - d: "M5 11.25h14v1.5H5z" - }) -}); -/* harmony default export */ const line_solid = (lineSolid); +var line_solid_default = /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { d: "M5 11.25h14v1.5H5z" }) }); + ;// ./node_modules/@wordpress/icons/build-module/library/line-dashed.js -/** - * WordPress dependencies - */ -const lineDashed = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { - xmlns: "http://www.w3.org/2000/svg", - viewBox: "0 0 24 24", - children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { +var line_dashed_default = /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)( + external_wp_primitives_namespaceObject.Path, + { fillRule: "evenodd", d: "M5 11.25h3v1.5H5v-1.5zm5.5 0h3v1.5h-3v-1.5zm8.5 0h-3v1.5h3v-1.5z", clipRule: "evenodd" - }) -}); -/* harmony default export */ const line_dashed = (lineDashed); + } +) }); + ;// ./node_modules/@wordpress/icons/build-module/library/line-dotted.js -/** - * WordPress dependencies - */ -const lineDotted = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { - xmlns: "http://www.w3.org/2000/svg", - viewBox: "0 0 24 24", - children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { +var line_dotted_default = /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)( + external_wp_primitives_namespaceObject.Path, + { fillRule: "evenodd", d: "M5.25 11.25h1.5v1.5h-1.5v-1.5zm3 0h1.5v1.5h-1.5v-1.5zm4.5 0h-1.5v1.5h1.5v-1.5zm1.5 0h1.5v1.5h-1.5v-1.5zm4.5 0h-1.5v1.5h1.5v-1.5z", clipRule: "evenodd" - }) -}); -/* harmony default export */ const line_dotted = (lineDotted); + } +) }); + ;// ./node_modules/@wordpress/components/build-module/toggle-group-control/toggle-group-control/styles.js -function toggle_group_control_styles_EMOTION_STRINGIFIED_CSS_ERROR_() { return "You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."; } -/** - * External dependencies - */ +function toggle_group_control_styles_EMOTION_STRINGIFIED_CSS_ERROR_() { + return "You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."; +} -/** - * Internal dependencies - */ const toggleGroupControl = ({ isBlock, isDeselectable, size -}) => /*#__PURE__*/emotion_react_browser_esm_css("background:", COLORS.ui.background, ";border:1px solid transparent;border-radius:", config_values.radiusSmall, ";display:inline-flex;min-width:0;position:relative;", toggleGroupControlSize(size), " ", !isDeselectable && enclosingBorders(isBlock), "@media not ( prefers-reduced-motion ){&[data-indicator-animated]::before{transition-property:transform,border-radius;transition-duration:0.2s;transition-timing-function:ease-out;}}&::before{content:'';position:absolute;pointer-events:none;background:", COLORS.theme.foreground, ";outline:2px solid transparent;outline-offset:-3px;--antialiasing-factor:100;border-radius:calc(\n\t\t\t\t", config_values.radiusXSmall, " /\n\t\t\t\t\t(\n\t\t\t\t\t\tvar( --selected-width, 0 ) /\n\t\t\t\t\t\t\tvar( --antialiasing-factor )\n\t\t\t\t\t)\n\t\t\t)/", config_values.radiusXSmall, ";left:-1px;width:calc( var( --antialiasing-factor ) * 1px );height:calc( var( --selected-height, 0 ) * 1px );transform-origin:left top;transform:translateX( calc( var( --selected-left, 0 ) * 1px ) ) scaleX(\n\t\t\t\tcalc(\n\t\t\t\t\tvar( --selected-width, 0 ) / var( --antialiasing-factor )\n\t\t\t\t)\n\t\t\t);}" + ( true ? "" : 0), true ? "" : 0); -const enclosingBorders = isBlock => { - const enclosingBorder = /*#__PURE__*/emotion_react_browser_esm_css("border-color:", COLORS.ui.border, ";" + ( true ? "" : 0), true ? "" : 0); - return /*#__PURE__*/emotion_react_browser_esm_css(isBlock && enclosingBorder, " &:hover{border-color:", COLORS.ui.borderHover, ";}&:focus-within{border-color:", COLORS.ui.borderFocus, ";box-shadow:", config_values.controlBoxShadowFocus, ";z-index:1;outline:2px solid transparent;outline-offset:-2px;}" + ( true ? "" : 0), true ? "" : 0); +}) => /* @__PURE__ */ emotion_react_browser_esm_css("background:", COLORS.ui.background, ";border:1px solid transparent;border-radius:", config_values_default.radiusSmall, ";display:inline-flex;min-width:0;position:relative;", toggleGroupControlSize(size), " ", !isDeselectable && enclosingBorders(isBlock), "@media not ( prefers-reduced-motion ){&[data-indicator-animated]::before{transition-property:transform,border-radius;transition-duration:0.2s;transition-timing-function:ease-out;}}&::before{content:'';position:absolute;pointer-events:none;background:", COLORS.theme.foreground, ";outline:2px solid transparent;outline-offset:-3px;--antialiasing-factor:100;border-radius:calc(\n ", config_values_default.radiusXSmall, " /\n (\n var( --selected-width, 0 ) /\n var( --antialiasing-factor )\n )\n )/", config_values_default.radiusXSmall, ";left:-1px;width:calc( var( --antialiasing-factor ) * 1px );height:calc( var( --selected-height, 0 ) * 1px );transform-origin:left top;transform:translateX( calc( var( --selected-left, 0 ) * 1px ) ) scaleX(\n calc(\n var( --selected-width, 0 ) / var( --antialiasing-factor )\n )\n );}" + ( true ? "" : 0), true ? "" : 0); +const enclosingBorders = (isBlock) => { + const enclosingBorder = /* @__PURE__ */ emotion_react_browser_esm_css("border-color:", COLORS.ui.border, ";" + ( true ? "" : 0), true ? "" : 0); + return /* @__PURE__ */ emotion_react_browser_esm_css(isBlock && enclosingBorder, " &:hover{border-color:", COLORS.ui.borderHover, ";}&:focus-within{border-color:", COLORS.ui.borderFocus, ";box-shadow:", config_values_default.controlBoxShadowFocus, ";z-index:1;outline:2px solid transparent;outline-offset:-2px;}" + ( true ? "" : 0), true ? "" : 0); }; var styles_ref = true ? { name: "1aqh2c7", @@ -35580,10 +34962,10 @@ var _ref2 = true ? { name: "1ndywgm", styles: "min-height:36px;padding:2px" } : 0; -const toggleGroupControlSize = size => { +const toggleGroupControlSize = (size) => { const styles = { default: _ref2, - '__unstable-large': styles_ref + "__unstable-large": styles_ref }; return styles[size]; }; @@ -35591,13 +34973,14 @@ const toggle_group_control_styles_block = true ? { name: "7whenc", styles: "display:flex;width:100%" } : 0; -const VisualLabelWrapper = /*#__PURE__*/emotion_styled_base_browser_esm("div", true ? { +const VisualLabelWrapper = /* @__PURE__ */ emotion_styled_base_browser_esm("div", true ? { target: "eakva830" } : 0)( true ? { name: "zjik7", styles: "display:flex" } : 0); + ;// ./node_modules/@ariakit/core/esm/radio/radio-store.js "use client"; @@ -35714,37 +35097,16 @@ var RadioGroup = forwardRef2(function RadioGroup2(props) { ;// ./node_modules/@wordpress/components/build-module/toggle-group-control/context.js -/** - * WordPress dependencies - */ - - -/** - * Internal dependencies - */ const ToggleGroupControlContext = (0,external_wp_element_namespaceObject.createContext)({}); +ToggleGroupControlContext.displayName = "ToggleGroupControlContext"; const useToggleGroupControlContext = () => (0,external_wp_element_namespaceObject.useContext)(ToggleGroupControlContext); -/* harmony default export */ const toggle_group_control_context = (ToggleGroupControlContext); +var context_context_default = ToggleGroupControlContext; + ;// ./node_modules/@wordpress/components/build-module/toggle-group-control/toggle-group-control/utils.js -/** - * WordPress dependencies - */ - -/** - * Internal dependencies - */ - -/** - * Used to determine, via an internal heuristics, whether an `undefined` value - * received for the `value` prop should be interpreted as the component being - * used in uncontrolled mode, or as an "empty" value for controlled mode. - * - * @param valueProp The received `value` - */ function useComputeControlledOrUncontrolledValue(valueProp) { const isInitialRenderRef = (0,external_wp_element_namespaceObject.useRef)(true); const prevValueProp = (0,external_wp_compose_namespaceObject.usePrevious)(valueProp); @@ -35754,45 +35116,28 @@ function useComputeControlledOrUncontrolledValue(valueProp) { isInitialRenderRef.current = false; } }, []); - - // Assume the component is being used in controlled mode on the first re-render - // that has a different `valueProp` from the previous render. const isControlled = prevIsControlledRef.current || !isInitialRenderRef.current && prevValueProp !== valueProp; (0,external_wp_element_namespaceObject.useEffect)(() => { prevIsControlledRef.current = isControlled; }, [isControlled]); if (isControlled) { - // When in controlled mode, use `''` instead of `undefined` return { - value: valueProp !== null && valueProp !== void 0 ? valueProp : '', - defaultValue: undefined + value: valueProp !== null && valueProp !== void 0 ? valueProp : "", + defaultValue: void 0 }; } - - // When in uncontrolled mode, the `value` should be intended as the initial value return { - value: undefined, + value: void 0, defaultValue: valueProp }; } + ;// ./node_modules/@wordpress/components/build-module/toggle-group-control/toggle-group-control/as-radio-group.js -/** - * External dependencies - */ - - - -/** - * WordPress dependencies - */ -/** - * Internal dependencies - */ @@ -35808,36 +35153,26 @@ function UnforwardedToggleGroupControlAsRadioGroup({ setSelectedElement, ...otherProps }, forwardedRef) { - const generatedId = (0,external_wp_compose_namespaceObject.useInstanceId)(ToggleGroupControlAsRadioGroup, 'toggle-group-control-as-radio-group'); + const generatedId = (0,external_wp_compose_namespaceObject.useInstanceId)(ToggleGroupControlAsRadioGroup, "toggle-group-control-as-radio-group"); const baseId = idProp || generatedId; - - // Use a heuristic to understand if the component is being used in controlled - // or uncontrolled mode, and consequently: - // - when controlled, convert `undefined` values to `''` (ie. "no value") - // - use the `value` prop as the `defaultValue` when uncontrolled const { value, defaultValue } = useComputeControlledOrUncontrolledValue(valueProp); - - // `useRadioStore`'s `setValue` prop can be called with `null`, while - // the component's `onChange` prop only expects `undefined` - const wrappedOnChangeProp = onChangeProp ? v => { - onChangeProp(v !== null && v !== void 0 ? v : undefined); - } : undefined; + const wrappedOnChangeProp = onChangeProp ? (v) => { + onChangeProp(v !== null && v !== void 0 ? v : void 0); + } : void 0; const radio = useRadioStore({ defaultValue, value, setValue: wrappedOnChangeProp, rtl: (0,external_wp_i18n_namespaceObject.isRTL)() }); - const selectedValue = useStoreState(radio, 'value'); + const selectedValue = useStoreState(radio, "value"); const setValue = radio.setValue; - - // Ensures that the active id is also reset after the value is "reset" by the consumer. (0,external_wp_element_namespaceObject.useEffect)(() => { - if (selectedValue === '') { - radio.setActiveId(undefined); + if (selectedValue === "") { + radio.setActiveId(void 0); } }, [radio, selectedValue]); const groupContextValue = (0,external_wp_element_namespaceObject.useMemo)(() => ({ @@ -35851,69 +35186,53 @@ function UnforwardedToggleGroupControlAsRadioGroup({ setValue, setSelectedElement }), [baseId, isAdaptiveWidth, radio, selectedValue, setSelectedElement, setValue, size]); - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(toggle_group_control_context.Provider, { + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(context_context_default.Provider, { value: groupContextValue, - children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(RadioGroup, { + children: /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(RadioGroup, { store: radio, "aria-label": label, - render: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(component, {}), + render: /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(component_default, {}), ...otherProps, id: baseId, ref: forwardedRef, - children: children + children }) }); } const ToggleGroupControlAsRadioGroup = (0,external_wp_element_namespaceObject.forwardRef)(UnforwardedToggleGroupControlAsRadioGroup); -;// ./node_modules/@wordpress/components/build-module/utils/hooks/use-controlled-value.js -/** - * WordPress dependencies - */ -/** - * Simplified and improved implementation of useControlledState. - * - * @param props - * @param props.defaultValue - * @param props.value - * @param props.onChange - * @return The controlled value and the value setter. - */ +;// ./node_modules/@wordpress/components/build-module/utils/hooks/use-controlled-value.js + function useControlledValue({ defaultValue, onChange, value: valueProp }) { - const hasValue = typeof valueProp !== 'undefined'; + const hasValue = typeof valueProp !== "undefined"; const initialValue = hasValue ? valueProp : defaultValue; const [state, setState] = (0,external_wp_element_namespaceObject.useState)(initialValue); const value = hasValue ? valueProp : state; + const uncontrolledSetValue = (0,external_wp_element_namespaceObject.useCallback)((nextValue, ...args) => { + setState(nextValue); + onChange?.(nextValue, ...args); + }, [onChange]); let setValue; - if (hasValue && typeof onChange === 'function') { + if (hasValue && typeof onChange === "function") { setValue = onChange; - } else if (!hasValue && typeof onChange === 'function') { - setValue = nextValue => { - onChange(nextValue); - setState(nextValue); - }; + } else if (!hasValue && typeof onChange === "function") { + setValue = uncontrolledSetValue; } else { setValue = setState; } return [value, setValue]; } + ;// ./node_modules/@wordpress/components/build-module/toggle-group-control/toggle-group-control/as-button-group.js -/** - * WordPress dependencies - */ -/** - * Internal dependencies - */ - @@ -35929,13 +35248,8 @@ function UnforwardedToggleGroupControlAsButtonGroup({ setSelectedElement, ...otherProps }, forwardedRef) { - const generatedId = (0,external_wp_compose_namespaceObject.useInstanceId)(ToggleGroupControlAsButtonGroup, 'toggle-group-control-as-button-group'); + const generatedId = (0,external_wp_compose_namespaceObject.useInstanceId)(ToggleGroupControlAsButtonGroup, "toggle-group-control-as-button-group"); const baseId = idProp || generatedId; - - // Use a heuristic to understand if the component is being used in controlled - // or uncontrolled mode, and consequently: - // - when controlled, convert `undefined` values to `''` (ie. "no value") - // - use the `value` prop as the `defaultValue` when uncontrolled const { value, defaultValue @@ -35954,36 +35268,25 @@ function UnforwardedToggleGroupControlAsButtonGroup({ size, setSelectedElement }), [baseId, selectedValue, setSelectedValue, isAdaptiveWidth, size, setSelectedElement]); - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(toggle_group_control_context.Provider, { + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(context_context_default.Provider, { value: groupContextValue, - children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(component, { + children: /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(component_default, { "aria-label": label, ...otherProps, ref: forwardedRef, role: "group", - children: children + children }) }); } const ToggleGroupControlAsButtonGroup = (0,external_wp_element_namespaceObject.forwardRef)(UnforwardedToggleGroupControlAsButtonGroup); + ;// ./node_modules/@wordpress/components/build-module/utils/element-rect.js -/* eslint-disable jsdoc/require-param */ -/** - * WordPress dependencies - */ - -/** - * The position and dimensions of an element, relative to its offset parent. - */ - -/** - * An `ElementOffsetRect` object with all values set to zero. - */ const NULL_ELEMENT_OFFSET_RECT = { - element: undefined, + element: void 0, top: 0, right: 0, bottom: 0, @@ -35991,26 +35294,8 @@ const NULL_ELEMENT_OFFSET_RECT = { width: 0, height: 0 }; - -/** - * Returns the position and dimensions of an element, relative to its offset - * parent, with subpixel precision. Values reflect the real measures before any - * potential scaling distortions along the X and Y axes. - * - * Useful in contexts where plain `getBoundingClientRect` calls or `ResizeObserver` - * entries are not suitable, such as when the element is transformed, and when - * `element.offset` methods are not precise enough. - * - * **Note:** in some contexts, like when the scale is 0, this method will fail - * because it's impossible to calculate a scaling ratio. When that happens, it - * will return `undefined`. - */ function getElementOffsetRect(element) { var _offsetParent$getBoun, _offsetParent$scrollL, _offsetParent$scrollT; - // Position and dimension values computed with `getBoundingClientRect` have - // subpixel precision, but are affected by distortions since they represent - // the "real" measures, or in other words, the actual final values as rendered - // by the browser. const rect = element.getBoundingClientRect(); if (rect.width === 0 || rect.height === 0) { return; @@ -36019,14 +35304,8 @@ function getElementOffsetRect(element) { const offsetParentRect = (_offsetParent$getBoun = offsetParent?.getBoundingClientRect()) !== null && _offsetParent$getBoun !== void 0 ? _offsetParent$getBoun : NULL_ELEMENT_OFFSET_RECT; const offsetParentScrollX = (_offsetParent$scrollL = offsetParent?.scrollLeft) !== null && _offsetParent$scrollL !== void 0 ? _offsetParent$scrollL : 0; const offsetParentScrollY = (_offsetParent$scrollT = offsetParent?.scrollTop) !== null && _offsetParent$scrollT !== void 0 ? _offsetParent$scrollT : 0; - - // Computed widths and heights have subpixel precision, and are not affected - // by distortions. const computedWidth = parseFloat(getComputedStyle(element).width); const computedHeight = parseFloat(getComputedStyle(element).height); - - // We can obtain the current scale factor for the element by comparing "computed" - // dimensions with the "real" ones. const scaleX = computedWidth / rect.width; const scaleY = computedHeight / rect.height; return { @@ -36045,25 +35324,10 @@ function getElementOffsetRect(element) { }; } const POLL_RATE = 100; - -/** - * Tracks the position and dimensions of an element, relative to its offset - * parent. The element can be changed dynamically. - * - * When no element is provided (`null` or `undefined`), the hook will return - * a "null" rect, in which all values are `0` and `element` is `undefined`. - * - * **Note:** sometimes, the measurement will fail (see `getElementOffsetRect`'s - * documentation for more details). When that happens, this hook will attempt - * to measure again after a frame, and if that fails, it will poll every 100 - * milliseconds until it succeeds. - */ function useTrackElementOffsetRect(targetElement, deps = []) { const [indicatorPosition, setIndicatorPosition] = (0,external_wp_element_namespaceObject.useState)(NULL_ELEMENT_OFFSET_RECT); const intervalRef = (0,external_wp_element_namespaceObject.useRef)(); const measure = (0,external_wp_compose_namespaceObject.useEvent)(() => { - // Check that the targetElement is still attached to the DOM, in case - // it was removed since the last `measure` call. if (targetElement && targetElement.isConnected) { const elementOffsetRect = getElementOffsetRect(targetElement); if (elementOffsetRect) { @@ -36091,44 +35355,17 @@ function useTrackElementOffsetRect(targetElement, deps = []) { setIndicatorPosition(NULL_ELEMENT_OFFSET_RECT); } }, [setElement, targetElement]); - - // Escape hatch to force a remeasurement when something else changes rather - // than the target elements' ref or size (for example, the target element - // can change its position within the tablist). (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { measure(); - // `measure` is a stable function, so it's safe to omit it from the deps array. - // deps can't be statically analyzed by ESLint }, deps); return indicatorPosition; } -/* eslint-enable jsdoc/require-param */ ;// ./node_modules/@wordpress/components/build-module/utils/hooks/use-on-value-update.js -/* eslint-disable jsdoc/require-param */ -/** - * WordPress dependencies - */ - -/** - * Context object for the `onUpdate` callback of `useOnValueUpdate`. - */ - -/** - * Calls the `onUpdate` callback when the `value` changes. - */ -function useOnValueUpdate( -/** - * The value to watch for changes. - */ -value, -/** - * Callback to fire when the value changes. - */ -onUpdate) { +function useOnValueUpdate(value, onUpdate) { const previousValueRef = (0,external_wp_element_namespaceObject.useRef)(value); const updateCallbackEvent = (0,external_wp_compose_namespaceObject.useEvent)(onUpdate); (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { @@ -36140,60 +35377,20 @@ onUpdate) { } }, [updateCallbackEvent, value]); } -/* eslint-enable jsdoc/require-param */ + ;// ./node_modules/@wordpress/components/build-module/utils/hooks/use-animated-offset-rect.js -/* eslint-disable jsdoc/require-param */ - -/** - * WordPress dependencies - */ - - -/** - * Internal dependencies - */ -/** - * A utility used to animate something in a container component based on the "offset - * rect" (position relative to the container and size) of a subelement. For example, - * this is useful to render an indicator for the selected option of a component, and - * to animate it when the selected option changes. - * - * Takes in a container element and the up-to-date "offset rect" of the target - * subelement, obtained with `useTrackElementOffsetRect`. Then it does the following: - * - * - Adds CSS variables with rect information to the container, so that the indicator - * can be rendered and animated with them. These are kept up-to-date, enabling CSS - * transitions on change. - * - Sets an attribute (`data-subelement-animated` by default) when the tracked - * element changes, so that the target (e.g. the indicator) can be animated to its - * new size and position. - * - Removes the attribute when the animation is done. - * - * The need for the attribute is due to the fact that the rect might update in - * situations other than when the tracked element changes, e.g. the tracked element - * might be resized. In such cases, there is no need to animate the indicator, and - * the change in size or position of the indicator needs to be reflected immediately. - */ -function useAnimatedOffsetRect( -/** - * The container element. - */ -container, -/** - * The rect of the tracked element. - */ -rect, { - prefix = 'subelement', +function useAnimatedOffsetRect(container, rect, { + prefix = "subelement", dataAttribute = `${prefix}-animated`, transitionEndFilter = () => true, roundRect = false } = {}) { const setProperties = (0,external_wp_compose_namespaceObject.useEvent)(() => { - Object.keys(rect).forEach(property => property !== 'element' && container?.style.setProperty(`--${prefix}-${property}`, String(roundRect ? Math.floor(rect[property]) : rect[property]))); + Object.keys(rect).forEach((property) => property !== "element" && container?.style.setProperty(`--${prefix}-${property}`, String(roundRect ? Math.floor(rect[property]) : rect[property]))); }); (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { setProperties(); @@ -36201,9 +35398,8 @@ rect, { useOnValueUpdate(rect.element, ({ previousValue }) => { - // Only enable the animation when moving from one element to another. if (rect.element && previousValue) { - container?.setAttribute(`data-${dataAttribute}`, ''); + container?.setAttribute(`data-${dataAttribute}`, ""); } }); (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { @@ -36212,25 +35408,13 @@ rect, { container?.removeAttribute(`data-${dataAttribute}`); } } - container?.addEventListener('transitionend', onTransitionEnd); - return () => container?.removeEventListener('transitionend', onTransitionEnd); + container?.addEventListener("transitionend", onTransitionEnd); + return () => container?.removeEventListener("transitionend", onTransitionEnd); }, [dataAttribute, container, transitionEndFilter]); } -/* eslint-enable jsdoc/require-param */ + ;// ./node_modules/@wordpress/components/build-module/toggle-group-control/toggle-group-control/component.js -/** - * External dependencies - */ - -/** - * WordPress dependencies - */ - - -/** - * Internal dependencies - */ @@ -36257,20 +35441,20 @@ function UnconnectedToggleGroupControl(props, forwardedRef) { hideLabelFromVision = false, help, onChange, - size = 'default', + size = "default", value, children, ...otherProps - } = useContextSystem(props, 'ToggleGroupControl'); - const normalizedSize = __next40pxDefaultSize && size === 'default' ? '__unstable-large' : size; + } = useContextSystem(props, "ToggleGroupControl"); + const normalizedSize = __next40pxDefaultSize && size === "default" ? "__unstable-large" : size; const [selectedElement, setSelectedElement] = (0,external_wp_element_namespaceObject.useState)(); const [controlElement, setControlElement] = (0,external_wp_element_namespaceObject.useState)(); const refs = (0,external_wp_compose_namespaceObject.useMergeRefs)([setControlElement, forwardedRef]); - const selectedRect = useTrackElementOffsetRect(value !== null && value !== undefined ? selectedElement : undefined); + const selectedRect = useTrackElementOffsetRect(value !== null && value !== void 0 ? selectedElement : void 0); useAnimatedOffsetRect(controlElement, selectedRect, { - prefix: 'selected', - dataAttribute: 'indicator-animated', - transitionEndFilter: event => event.pseudoElement === '::before', + prefix: "selected", + dataAttribute: "indicator-animated", + transitionEndFilter: (event) => event.pseudoElement === "::before", roundRect: true }); const cx = useCx(); @@ -36281,71 +35465,36 @@ function UnconnectedToggleGroupControl(props, forwardedRef) { }), isBlock && toggle_group_control_styles_block, className), [className, cx, isBlock, isDeselectable, normalizedSize]); const MainControl = isDeselectable ? ToggleGroupControlAsButtonGroup : ToggleGroupControlAsRadioGroup; maybeWarnDeprecated36pxSize({ - componentName: 'ToggleGroupControl', + componentName: "ToggleGroupControl", size, __next40pxDefaultSize, __shouldNotWarnDeprecated36pxSize }); - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(base_control, { - help: help, - __nextHasNoMarginBottom: __nextHasNoMarginBottom, + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsxs)(base_control_default, { + help, + __nextHasNoMarginBottom, __associatedWPComponentName: "ToggleGroupControl", - children: [!hideLabelFromVision && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(VisualLabelWrapper, { - children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(base_control.VisualLabel, { + children: [!hideLabelFromVision && /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(VisualLabelWrapper, { + children: /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(base_control_default.VisualLabel, { children: label }) - }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(MainControl, { + }), /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(MainControl, { ...otherProps, - setSelectedElement: setSelectedElement, + setSelectedElement, className: classes, - isAdaptiveWidth: isAdaptiveWidth, - label: label, - onChange: onChange, + isAdaptiveWidth, + label, + onChange, ref: refs, size: normalizedSize, - value: value, - children: children + value, + children })] }); } +const ToggleGroupControl = contextConnect(UnconnectedToggleGroupControl, "ToggleGroupControl"); +var toggle_group_control_component_component_default = ToggleGroupControl; -/** - * `ToggleGroupControl` is a form component that lets users choose options - * represented in horizontal segments. To render options for this control use - * `ToggleGroupControlOption` component. - * - * This component is intended for selecting a single persistent value from a set of options, - * similar to a how a radio button group would work. If you simply want a toggle to switch between views, - * use a `TabPanel` instead. - * - * Only use this control when you know for sure the labels of items inside won't - * wrap. For items with longer labels, you can consider a `SelectControl` or a - * `CustomSelectControl` component instead. - * - * ```jsx - * import { - * __experimentalToggleGroupControl as ToggleGroupControl, - * __experimentalToggleGroupControlOption as ToggleGroupControlOption, - * } from '@wordpress/components'; - * - * function Example() { - * return ( - * - * - * - * - * ); - * } - * ``` - */ -const ToggleGroupControl = contextConnect(UnconnectedToggleGroupControl, 'ToggleGroupControl'); -/* harmony default export */ const toggle_group_control_component = (ToggleGroupControl); ;// ./node_modules/@ariakit/react-core/esm/__chunks/NLEBE274.js "use client"; @@ -36481,16 +35630,12 @@ var Radio = memo2( ;// ./node_modules/@wordpress/components/build-module/toggle-group-control/toggle-group-control-option-base/styles.js -function toggle_group_control_option_base_styles_EMOTION_STRINGIFIED_CSS_ERROR_() { return "You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."; } -/** - * External dependencies - */ +function toggle_group_control_option_base_styles_EMOTION_STRINGIFIED_CSS_ERROR_() { + return "You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."; +} -/** - * Internal dependencies - */ -const LabelView = /*#__PURE__*/emotion_styled_base_browser_esm("div", true ? { +const LabelView = /* @__PURE__ */ emotion_styled_base_browser_esm("div", true ? { target: "et6ln9s1" } : 0)( true ? { name: "sln1fl", @@ -36505,41 +35650,29 @@ const buttonView = ({ isIcon, isPressed, size -}) => /*#__PURE__*/emotion_react_browser_esm_css("align-items:center;appearance:none;background:transparent;border:none;border-radius:", config_values.radiusXSmall, ";color:", COLORS.theme.gray[700], ";fill:currentColor;cursor:pointer;display:flex;font-family:inherit;height:100%;justify-content:center;line-height:100%;outline:none;padding:0 12px;position:relative;text-align:center;@media not ( prefers-reduced-motion ){transition:background ", config_values.transitionDurationFast, " linear,color ", config_values.transitionDurationFast, " linear,font-weight 60ms linear;}user-select:none;width:100%;z-index:2;&::-moz-focus-inner{border:0;}&[disabled]{opacity:0.4;cursor:default;}&:active{background:", COLORS.ui.background, ";}", isDeselectable && deselectable, " ", isIcon && isIconStyles({ +}) => /* @__PURE__ */ emotion_react_browser_esm_css("align-items:center;appearance:none;background:transparent;border:none;border-radius:", config_values_default.radiusXSmall, ";color:", COLORS.theme.gray[700], ";fill:currentColor;cursor:pointer;display:flex;font-family:inherit;height:100%;justify-content:center;line-height:100%;outline:none;padding:0 12px;position:relative;text-align:center;@media not ( prefers-reduced-motion ){transition:background ", config_values_default.transitionDurationFast, " linear,color ", config_values_default.transitionDurationFast, " linear,font-weight 60ms linear;}user-select:none;width:100%;z-index:2;&::-moz-focus-inner{border:0;}&[disabled]{opacity:0.4;cursor:default;}&:active{background:", COLORS.ui.background, ";}", isDeselectable && deselectable, " ", isIcon && isIconStyles({ size }), " ", isPressed && pressed, ";" + ( true ? "" : 0), true ? "" : 0); -const pressed = /*#__PURE__*/emotion_react_browser_esm_css("color:", COLORS.theme.foregroundInverted, ";&:active{background:transparent;}" + ( true ? "" : 0), true ? "" : 0); -const deselectable = /*#__PURE__*/emotion_react_browser_esm_css("color:", COLORS.theme.foreground, ";&:focus{box-shadow:inset 0 0 0 1px ", COLORS.ui.background, ",0 0 0 ", config_values.borderWidthFocus, " ", COLORS.theme.accent, ";outline:2px solid transparent;}" + ( true ? "" : 0), true ? "" : 0); -const ButtonContentView = /*#__PURE__*/emotion_styled_base_browser_esm("div", true ? { +const pressed = /* @__PURE__ */ emotion_react_browser_esm_css("color:", COLORS.theme.foregroundInverted, ";&:active{background:transparent;}" + ( true ? "" : 0), true ? "" : 0); +const deselectable = /* @__PURE__ */ emotion_react_browser_esm_css("color:", COLORS.theme.foreground, ";&:focus{box-shadow:inset 0 0 0 1px ", COLORS.ui.background, ",0 0 0 ", config_values_default.borderWidthFocus, " ", COLORS.theme.accent, ";outline:2px solid transparent;}" + ( true ? "" : 0), true ? "" : 0); +const ButtonContentView = /* @__PURE__ */ emotion_styled_base_browser_esm("div", true ? { target: "et6ln9s0" -} : 0)("display:flex;font-size:", config_values.fontSize, ";line-height:1;" + ( true ? "" : 0)); +} : 0)("display:flex;font-size:", config_values_default.fontSize, ";line-height:1;" + ( true ? "" : 0)); const isIconStyles = ({ - size = 'default' + size = "default" }) => { const iconButtonSizes = { - default: '30px', - '__unstable-large': '32px' + default: "30px", + "__unstable-large": "32px" }; - return /*#__PURE__*/emotion_react_browser_esm_css("color:", COLORS.theme.foreground, ";height:", iconButtonSizes[size], ";aspect-ratio:1;padding-left:0;padding-right:0;" + ( true ? "" : 0), true ? "" : 0); + return /* @__PURE__ */ emotion_react_browser_esm_css("color:", COLORS.theme.foreground, ";height:", iconButtonSizes[size], ";aspect-ratio:1;padding-left:0;padding-right:0;" + ( true ? "" : 0), true ? "" : 0); }; + ;// ./node_modules/@wordpress/components/build-module/toggle-group-control/toggle-group-control-option-base/component.js -/** - * External dependencies - */ -/** - * WordPress dependencies - */ - - - -/** - * Internal dependencies - */ - @@ -36556,27 +35689,27 @@ const WithToolTip = ({ children }) => { if (showTooltip && text) { - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(tooltip, { - text: text, + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(tooltip_default, { + text, placement: "top", - children: children + children }); } - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_ReactJSXRuntime_namespaceObject.Fragment, { - children: children + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(external_ReactJSXRuntime_namespaceObject.Fragment, { + children }); }; function ToggleGroupControlOptionBase(props, forwardedRef) { const toggleGroupControlContext = useToggleGroupControlContext(); - const id = (0,external_wp_compose_namespaceObject.useInstanceId)(ToggleGroupControlOptionBase, toggleGroupControlContext.baseId || 'toggle-group-control-option-base'); + const id = (0,external_wp_compose_namespaceObject.useInstanceId)(ToggleGroupControlOptionBase, toggleGroupControlContext.baseId || "toggle-group-control-option-base"); const buttonProps = useContextSystem({ ...props, id - }, 'ToggleGroupControlOptionBase'); + }, "ToggleGroupControlOptionBase"); const { isBlock = false, isDeselectable = false, - size = 'default' + size = "default" } = toggleGroupControlContext; const { className, @@ -36598,7 +35731,7 @@ function ToggleGroupControlOptionBase(props, forwardedRef) { }), className), [cx, isDeselectable, isIcon, isPressed, size, className]); const buttonOnClick = () => { if (isDeselectable && isPressed) { - toggleGroupControlContext.setValue(undefined); + toggleGroupControlContext.setValue(void 0); } else { toggleGroupControlContext.setValue(value); } @@ -36606,7 +35739,7 @@ function ToggleGroupControlOptionBase(props, forwardedRef) { const commonProps = { ...otherButtonProps, className: itemClasses, - 'data-value': value, + "data-value": value, ref: forwardedRef }; const labelRef = (0,external_wp_element_namespaceObject.useRef)(null); @@ -36615,82 +35748,46 @@ function ToggleGroupControlOptionBase(props, forwardedRef) { toggleGroupControlContext.setSelectedElement(labelRef.current); } }, [isPressed, toggleGroupControlContext]); - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(component_LabelView, { + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(component_LabelView, { ref: labelRef, className: labelViewClasses, - children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(WithToolTip, { - showTooltip: showTooltip, - text: otherButtonProps['aria-label'], - children: isDeselectable ? /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("button", { + children: /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(WithToolTip, { + showTooltip, + text: otherButtonProps["aria-label"], + children: isDeselectable ? /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)("button", { ...commonProps, - disabled: disabled, + disabled, "aria-pressed": isPressed, type: "button", onClick: buttonOnClick, - children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(component_ButtonContentView, { - children: children + children: /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(component_ButtonContentView, { + children }) - }) : /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Radio, { - disabled: disabled, + }) : /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(Radio, { + disabled, onFocusVisible: () => { - const selectedValueIsEmpty = toggleGroupControlContext.value === null || toggleGroupControlContext.value === ''; - - // Conditions ensure that the first visible focus to a radio group - // without a selected option will not automatically select the option. + const selectedValueIsEmpty = toggleGroupControlContext.value === null || toggleGroupControlContext.value === ""; if (!selectedValueIsEmpty || toggleGroupControlContext.activeItemIsNotFirstItem?.()) { toggleGroupControlContext.setValue(value); } }, - render: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("button", { + render: /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)("button", { type: "button", ...commonProps }), - value: value, - children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(component_ButtonContentView, { - children: children + value, + children: /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(component_ButtonContentView, { + children }) }) }) }); } +const ConnectedToggleGroupControlOptionBase = contextConnect(ToggleGroupControlOptionBase, "ToggleGroupControlOptionBase"); +var toggle_group_control_option_base_component_component_default = ConnectedToggleGroupControlOptionBase; -/** - * `ToggleGroupControlOptionBase` is a form component and is meant to be used as an internal, - * generic component for any children of `ToggleGroupControl`. - * - * @example - * ```jsx - * import { - * __experimentalToggleGroupControl as ToggleGroupControl, - * __experimentalToggleGroupControlOptionBase as ToggleGroupControlOptionBase, - * } from '@wordpress/components'; - * - * function Example() { - * return ( - * - * - * - * - * ); - * } - * ``` - */ -const ConnectedToggleGroupControlOptionBase = contextConnect(ToggleGroupControlOptionBase, 'ToggleGroupControlOptionBase'); -/* harmony default export */ const toggle_group_control_option_base_component = (ConnectedToggleGroupControlOptionBase); ;// ./node_modules/@wordpress/components/build-module/toggle-group-control/toggle-group-control-option-icon/component.js -/** - * External dependencies - */ - -/** - * WordPress dependencies - */ - - -/** - * Internal dependencies - */ @@ -36701,113 +35798,67 @@ function UnforwardedToggleGroupControlOptionIcon(props, ref) { label, ...restProps } = props; - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(toggle_group_control_option_base_component, { + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(toggle_group_control_option_base_component_component_default, { ...restProps, isIcon: true, "aria-label": label, showTooltip: true, - ref: ref, - children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(build_module_icon, { - icon: icon + ref, + children: /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(icon_icon_default, { + icon }) }); } - -/** - * `ToggleGroupControlOptionIcon` is a form component which is meant to be used as a - * child of `ToggleGroupControl` and displays an icon. - * - * ```jsx - * - * import { - * __experimentalToggleGroupControl as ToggleGroupControl, - * __experimentalToggleGroupControlOptionIcon as ToggleGroupControlOptionIcon, - * from '@wordpress/components'; - * import { formatLowercase, formatUppercase } from '@wordpress/icons'; - * - * function Example() { - * return ( - * - * - * - * - * ); - * } - * ``` - */ const ToggleGroupControlOptionIcon = (0,external_wp_element_namespaceObject.forwardRef)(UnforwardedToggleGroupControlOptionIcon); -/* harmony default export */ const toggle_group_control_option_icon_component = (ToggleGroupControlOptionIcon); +var toggle_group_control_option_icon_component_component_default = ToggleGroupControlOptionIcon; + ;// ./node_modules/@wordpress/components/build-module/border-control/border-control-style-picker/component.js -/** - * WordPress dependencies - */ -/** - * Internal dependencies - */ - const BORDER_STYLES = [{ - label: (0,external_wp_i18n_namespaceObject.__)('Solid'), - icon: line_solid, - value: 'solid' + label: (0,external_wp_i18n_namespaceObject.__)("Solid"), + icon: line_solid_default, + value: "solid" }, { - label: (0,external_wp_i18n_namespaceObject.__)('Dashed'), - icon: line_dashed, - value: 'dashed' + label: (0,external_wp_i18n_namespaceObject.__)("Dashed"), + icon: line_dashed_default, + value: "dashed" }, { - label: (0,external_wp_i18n_namespaceObject.__)('Dotted'), - icon: line_dotted, - value: 'dotted' + label: (0,external_wp_i18n_namespaceObject.__)("Dotted"), + icon: line_dotted_default, + value: "dotted" }]; function UnconnectedBorderControlStylePicker({ onChange, ...restProps }, forwardedRef) { - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(toggle_group_control_component, { + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(toggle_group_control_component_component_default, { __nextHasNoMarginBottom: true, __next40pxDefaultSize: true, ref: forwardedRef, isDeselectable: true, - onChange: value => { + onChange: (value) => { onChange?.(value); }, ...restProps, - children: BORDER_STYLES.map(borderStyle => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(toggle_group_control_option_icon_component, { + children: BORDER_STYLES.map((borderStyle) => /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(toggle_group_control_option_icon_component_component_default, { value: borderStyle.value, icon: borderStyle.icon, label: borderStyle.label }, borderStyle.value)) }); } -const BorderControlStylePicker = contextConnect(UnconnectedBorderControlStylePicker, 'BorderControlStylePicker'); -/* harmony default export */ const border_control_style_picker_component = (BorderControlStylePicker); +const BorderControlStylePicker = contextConnect(UnconnectedBorderControlStylePicker, "BorderControlStylePicker"); +var border_control_style_picker_component_component_default = BorderControlStylePicker; + ;// ./node_modules/@wordpress/components/build-module/color-indicator/index.js -/** - * External dependencies - */ - -/** - * WordPress dependencies - */ -/** - * Internal dependencies - */ function UnforwardedColorIndicator(props, forwardedRef) { const { @@ -36815,8 +35866,8 @@ function UnforwardedColorIndicator(props, forwardedRef) { colorValue, ...additionalProps } = props; - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { - className: dist_clsx('component-color-indicator', className), + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { + className: dist_clsx("component-color-indicator", className), style: { background: colorValue }, @@ -36824,39 +35875,18 @@ function UnforwardedColorIndicator(props, forwardedRef) { ...additionalProps }); } - -/** - * ColorIndicator is a React component that renders a specific color in a - * circle. It's often used to summarize a collection of used colors in a child - * component. - * - * ```jsx - * import { ColorIndicator } from '@wordpress/components'; - * - * const MyColorIndicator = () => ; - * ``` - */ const ColorIndicator = (0,external_wp_element_namespaceObject.forwardRef)(UnforwardedColorIndicator); -/* harmony default export */ const color_indicator = (ColorIndicator); +var color_indicator_default = ColorIndicator; + ;// ./node_modules/colord/plugins/a11y.mjs var a11y_o=function(o){var t=o/255;return t<.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)},a11y_t=function(t){return.2126*a11y_o(t.r)+.7152*a11y_o(t.g)+.0722*a11y_o(t.b)};/* harmony default export */ function a11y(o){o.prototype.luminance=function(){return o=a11y_t(this.rgba),void 0===(r=2)&&(r=0),void 0===n&&(n=Math.pow(10,r)),Math.round(n*o)/n+0;var o,r,n},o.prototype.contrast=function(r){void 0===r&&(r="#FFF");var n,a,i,e,v,u,d,c=r instanceof o?r:new o(r);return e=this.rgba,v=c.toRgb(),u=a11y_t(e),d=a11y_t(v),n=u>d?(u+.05)/(d+.05):(d+.05)/(u+.05),void 0===(a=2)&&(a=0),void 0===i&&(i=Math.pow(10,a)),Math.floor(i*n)/i+0},o.prototype.isReadable=function(o,t){return void 0===o&&(o="#FFF"),void 0===t&&(t={}),this.contrast(o)>=(e=void 0===(i=(r=t).size)?"normal":i,"AAA"===(a=void 0===(n=r.level)?"AA":n)&&"normal"===e?7:"AA"===a&&"large"===e?3:4.5);var r,n,a,i,e}} ;// ./node_modules/@wordpress/components/build-module/dropdown/index.js -/** - * External dependencies - */ - -/** - * WordPress dependencies - */ -/** - * Internal dependencies - */ @@ -36880,17 +35910,14 @@ const UnconnectedDropdown = (props, forwardedRef) => { position, // From context system variant - } = useContextSystem(props, 'Dropdown'); - if (position !== undefined) { - external_wp_deprecated_default()('`position` prop in wp.components.Dropdown', { - since: '6.2', - alternative: '`popoverProps.placement` prop', - hint: 'Note that the `position` prop will override any values passed through the `popoverProps.placement` prop.' + } = useContextSystem(props, "Dropdown"); + if (position !== void 0) { + external_wp_deprecated_default()("`position` prop in wp.components.Dropdown", { + since: "6.2", + alternative: "`popoverProps.placement` prop", + hint: "Note that the `position` prop will override any values passed through the `popoverProps.placement` prop." }); } - - // Use internal state instead of a ref to make sure that the component - // re-renders when the popover's anchor updates. const [fallbackPopoverAnchor, setFallbackPopoverAnchor] = (0,external_wp_element_namespaceObject.useState)(null); const containerRef = (0,external_wp_element_namespaceObject.useRef)(); const [isOpen, setIsOpen] = useControlledValue({ @@ -36898,13 +35925,6 @@ const UnconnectedDropdown = (props, forwardedRef) => { value: open, onChange: onToggle }); - - /** - * Closes the popover when focus leaves it unless the toggle was pressed or - * focus has moved to a separate dialog. The former is to let the toggle - * handle closing the popover and the latter is to preserve presence in - * case a dialog has opened, allowing focus to return when it's dismissed. - */ function closeIfFocusOutside() { if (!containerRef.current) { return; @@ -36926,115 +35946,55 @@ const UnconnectedDropdown = (props, forwardedRef) => { onToggle: () => setIsOpen(!isOpen), onClose: close }; - const popoverPropsHaveAnchor = !!popoverProps?.anchor || - // Note: `anchorRef`, `getAnchorRect` and `anchorRect` are deprecated and + const popoverPropsHaveAnchor = !!popoverProps?.anchor || // Note: `anchorRef`, `getAnchorRect` and `anchorRect` are deprecated and // be removed from `Popover` from WordPress 6.3 !!popoverProps?.anchorRef || !!popoverProps?.getAnchorRect || !!popoverProps?.anchorRect; - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { - className: className, - ref: (0,external_wp_compose_namespaceObject.useMergeRefs)([containerRef, forwardedRef, setFallbackPopoverAnchor]) - // Some UAs focus the closest focusable parent when the toggle is - // clicked. Making this div focusable ensures such UAs will focus - // it and `closeIfFocusOutside` can tell if the toggle was clicked. - , + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { + className, + ref: (0,external_wp_compose_namespaceObject.useMergeRefs)([containerRef, forwardedRef, setFallbackPopoverAnchor]), tabIndex: -1, - style: style, - children: [renderToggle(args), isOpen && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(popover, { - position: position, + style, + children: [renderToggle(args), isOpen && /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(popover_default, { + position, onClose: close, onFocusOutside: closeIfFocusOutside, - expandOnMobile: expandOnMobile, - headerTitle: headerTitle, - focusOnMount: focusOnMount - // This value is used to ensure that the dropdowns - // align with the editor header by default. - , + expandOnMobile, + headerTitle, + focusOnMount, offset: 13, - anchor: !popoverPropsHaveAnchor ? fallbackPopoverAnchor : undefined, - variant: variant, + anchor: !popoverPropsHaveAnchor ? fallbackPopoverAnchor : void 0, + variant, ...popoverProps, - className: dist_clsx('components-dropdown__content', popoverProps?.className, contentClassName), + className: dist_clsx("components-dropdown__content", popoverProps?.className, contentClassName), children: renderContent(args) })] }); }; +const Dropdown = contextConnect(UnconnectedDropdown, "Dropdown"); +var dropdown_default = Dropdown; -/** - * Renders a button that opens a floating content modal when clicked. - * - * ```jsx - * import { Button, Dropdown } from '@wordpress/components'; - * - * const MyDropdown = () => ( - * ( - * - * ) } - * renderContent={ () =>
This is the content of the dropdown.
} - * /> - * ); - * ``` - */ -const Dropdown = contextConnect(UnconnectedDropdown, 'Dropdown'); -/* harmony default export */ const dropdown = (Dropdown); ;// ./node_modules/@wordpress/components/build-module/input-control/input-suffix-wrapper.js -/** - * External dependencies - */ - -/** - * Internal dependencies - */ - function UnconnectedInputControlSuffixWrapper(props, forwardedRef) { - const derivedProps = useContextSystem(props, 'InputControlSuffixWrapper'); - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PrefixSuffixWrapper, { + const derivedProps = useContextSystem(props, "InputControlSuffixWrapper"); + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(PrefixSuffixWrapper, { ...derivedProps, ref: forwardedRef }); } +const InputControlSuffixWrapper = contextConnect(UnconnectedInputControlSuffixWrapper, "InputControlSuffixWrapper"); +var input_suffix_wrapper_default = InputControlSuffixWrapper; -/** - * A convenience wrapper for the `suffix` when you want to apply - * standard padding in accordance with the size variant. - * - * ```jsx - * import { - * __experimentalInputControl as InputControl, - * __experimentalInputControlSuffixWrapper as InputControlSuffixWrapper, - * } from '@wordpress/components'; - * - * %} - * /> - * ``` - */ -const InputControlSuffixWrapper = contextConnect(UnconnectedInputControlSuffixWrapper, 'InputControlSuffixWrapper'); -/* harmony default export */ const input_suffix_wrapper = (InputControlSuffixWrapper); ;// ./node_modules/@wordpress/components/build-module/select-control/styles/select-control-styles.js -function select_control_styles_EMOTION_STRINGIFIED_CSS_ERROR_() { return "You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."; } -/** - * External dependencies - */ +function select_control_styles_EMOTION_STRINGIFIED_CSS_ERROR_() { + return "You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."; +} -/** - * Internal dependencies - */ @@ -37044,9 +36004,9 @@ const select_control_styles_disabledStyles = ({ disabled }) => { if (!disabled) { - return ''; + return ""; } - return /*#__PURE__*/emotion_react_browser_esm_css("color:", COLORS.ui.textDisabled, ";cursor:default;" + ( true ? "" : 0), true ? "" : 0); + return /* @__PURE__ */ emotion_react_browser_esm_css("color:", COLORS.ui.textDisabled, ";cursor:default;" + ( true ? "" : 0), true ? "" : 0); }; var select_control_styles_ref2 = true ? { name: "1lv1yo7", @@ -37055,22 +36015,20 @@ var select_control_styles_ref2 = true ? { const inputBaseVariantStyles = ({ variant }) => { - if (variant === 'minimal') { + if (variant === "minimal") { return select_control_styles_ref2; } - return ''; + return ""; }; -const StyledInputBase = /*#__PURE__*/emotion_styled_base_browser_esm(input_base, true ? { +const StyledInputBase = /* @__PURE__ */ emotion_styled_base_browser_esm(input_base_default, true ? { target: "e1mv6sxx3" } : 0)("color:", COLORS.theme.foreground, ";cursor:pointer;", select_control_styles_disabledStyles, " ", inputBaseVariantStyles, ";" + ( true ? "" : 0)); const select_control_styles_sizeStyles = ({ __next40pxDefaultSize, multiple, - selectSize = 'default' + selectSize = "default" }) => { if (multiple) { - // When `multiple`, just use the native browser styles - // without setting explicit height. return; } const sizes = { @@ -37092,7 +36050,7 @@ const select_control_styles_sizeStyles = ({ paddingTop: 0, paddingBottom: 0 }, - '__unstable-large': { + "__unstable-large": { height: 40, minHeight: 40, paddingTop: 0, @@ -37103,19 +36061,19 @@ const select_control_styles_sizeStyles = ({ sizes.default = sizes.compact; } const style = sizes[selectSize] || sizes.default; - return /*#__PURE__*/emotion_react_browser_esm_css(style, true ? "" : 0, true ? "" : 0); + return /* @__PURE__ */ emotion_react_browser_esm_css(style, true ? "" : 0, true ? "" : 0); }; const chevronIconSize = 18; const sizePaddings = ({ __next40pxDefaultSize, multiple, - selectSize = 'default' + selectSize = "default" }) => { const padding = { - default: config_values.controlPaddingX, - small: config_values.controlPaddingXSmall, - compact: config_values.controlPaddingXSmall, - '__unstable-large': config_values.controlPaddingX + default: config_values_default.controlPaddingX, + small: config_values_default.controlPaddingXSmall, + compact: config_values_default.controlPaddingXSmall, + "__unstable-large": config_values_default.controlPaddingX }; if (!__next40pxDefaultSize) { padding.default = padding.compact; @@ -37124,17 +36082,17 @@ const sizePaddings = ({ return rtl({ paddingLeft: selectedPadding, paddingRight: selectedPadding + chevronIconSize, - ...(multiple ? { + ...multiple ? { paddingTop: selectedPadding, paddingBottom: selectedPadding - } : {}) + } : {} }); }; const overflowStyles = ({ multiple }) => { return { - overflow: multiple ? 'auto' : 'hidden' + overflow: multiple ? "auto" : "hidden" }; }; var select_control_styles_ref = true ? { @@ -37144,112 +36102,65 @@ var select_control_styles_ref = true ? { const variantStyles = ({ variant }) => { - if (variant === 'minimal') { + if (variant === "minimal") { return select_control_styles_ref; } - return ''; + return ""; }; - -// TODO: Resolve need to use &&& to increase specificity -// https://github.com/WordPress/gutenberg/issues/18483 - -const Select = /*#__PURE__*/emotion_styled_base_browser_esm("select", true ? { +const Select = /* @__PURE__ */ emotion_styled_base_browser_esm("select", true ? { target: "e1mv6sxx2" } : 0)("&&&{appearance:none;background:transparent;box-sizing:border-box;border:none;box-shadow:none!important;color:currentColor;cursor:inherit;display:block;font-family:inherit;margin:0;width:100%;max-width:none;white-space:nowrap;text-overflow:ellipsis;", fontSizeStyles, ";", select_control_styles_sizeStyles, ";", sizePaddings, ";", overflowStyles, " ", variantStyles, ";}" + ( true ? "" : 0)); -const DownArrowWrapper = /*#__PURE__*/emotion_styled_base_browser_esm("div", true ? { +const DownArrowWrapper = /* @__PURE__ */ emotion_styled_base_browser_esm("div", true ? { target: "e1mv6sxx1" } : 0)("margin-inline-end:", space(-1), ";line-height:0;path{fill:currentColor;}" + ( true ? "" : 0)); -const InputControlSuffixWrapperWithClickThrough = /*#__PURE__*/emotion_styled_base_browser_esm(input_suffix_wrapper, true ? { +const InputControlSuffixWrapperWithClickThrough = /* @__PURE__ */ emotion_styled_base_browser_esm(input_suffix_wrapper_default, true ? { target: "e1mv6sxx0" } : 0)("position:absolute;pointer-events:none;", rtl({ right: 0 }), ";" + ( true ? "" : 0)); + ;// ./node_modules/@wordpress/icons/build-module/icon/index.js -/** - * WordPress dependencies - */ +var build_module_icon_icon_default = (0,external_wp_element_namespaceObject.forwardRef)( + ({ icon, size = 24, ...props }, ref) => { + return (0,external_wp_element_namespaceObject.cloneElement)(icon, { + width: size, + height: size, + ...props, + ref + }); + } +); -/** @typedef {{icon: JSX.Element, size?: number} & import('@wordpress/primitives').SVGProps} IconProps */ - -/** - * Return an SVG icon. - * - * @param {IconProps} props icon is the SVG component to render - * size is a number specifying the icon size in pixels - * Other props will be passed to wrapped SVG component - * @param {import('react').ForwardedRef} ref The forwarded ref to the SVG element. - * - * @return {JSX.Element} Icon component - */ -function icon_Icon({ - icon, - size = 24, - ...props -}, ref) { - return (0,external_wp_element_namespaceObject.cloneElement)(icon, { - width: size, - height: size, - ...props, - ref - }); -} -/* harmony default export */ const icons_build_module_icon = ((0,external_wp_element_namespaceObject.forwardRef)(icon_Icon)); ;// ./node_modules/@wordpress/icons/build-module/library/chevron-down.js -/** - * WordPress dependencies - */ -const chevronDown = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { - viewBox: "0 0 24 24", - xmlns: "http://www.w3.org/2000/svg", - children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { - d: "M17.5 11.6L12 16l-5.5-4.4.9-1.2L12 14l4.5-3.6 1 1.2z" - }) -}); -/* harmony default export */ const chevron_down = (chevronDown); +var chevron_down_default = /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { d: "M17.5 11.6L12 16l-5.5-4.4.9-1.2L12 14l4.5-3.6 1 1.2z" }) }); + ;// ./node_modules/@wordpress/components/build-module/select-control/chevron-down.js -/** - * WordPress dependencies - */ -/** - * Internal dependencies - */ - const SelectControlChevronDown = () => { - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(InputControlSuffixWrapperWithClickThrough, { - children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(DownArrowWrapper, { - children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(icons_build_module_icon, { - icon: chevron_down, + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(InputControlSuffixWrapperWithClickThrough, { + children: /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(DownArrowWrapper, { + children: /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(build_module_icon_icon_default, { + icon: chevron_down_default, size: chevronIconSize }) }) }); }; -/* harmony default export */ const select_control_chevron_down = (SelectControlChevronDown); +var chevron_down_chevron_down_default = SelectControlChevronDown; + ;// ./node_modules/@wordpress/components/build-module/select-control/index.js -/** - * External dependencies - */ - - -/** - * WordPress dependencies - */ -/** - * Internal dependencies - */ @@ -37271,8 +36182,8 @@ function SelectOptions({ ...optionProps }, index) => { const key = id || `${label}-${value}-${index}`; - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("option", { - value: value, + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)("option", { + value, ...optionProps, children: label }, key); @@ -37289,26 +36200,24 @@ function UnforwardedSelectControl(props, ref) { multiple = false, onChange, options = [], - size = 'default', + size = "default", value: valueProp, - labelPosition = 'top', + labelPosition = "top", children, prefix, suffix, - variant = 'default', + variant = "default", __next40pxDefaultSize = false, __nextHasNoMarginBottom = false, __shouldNotWarnDeprecated36pxSize, ...restProps } = useDeprecated36pxDefaultSizeProp(props); const id = select_control_useUniqueId(idProp); - const helpId = help ? `${id}__help` : undefined; - - // Disable reason: A select with an onchange throws a warning. + const helpId = help ? `${id}__help` : void 0; if (!options?.length && !children) { return null; } - const handleOnChange = event => { + const handleOnChange = (event) => { if (props.multiple) { const selectedOptions = Array.from(event.target.options).filter(({ selected @@ -37325,135 +36234,67 @@ function UnforwardedSelectControl(props, ref) { event }); }; - const classes = dist_clsx('components-select-control', className); + const classes = dist_clsx("components-select-control", className); maybeWarnDeprecated36pxSize({ - componentName: 'SelectControl', + componentName: "SelectControl", __next40pxDefaultSize, size, __shouldNotWarnDeprecated36pxSize }); - return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(base_control, { - help: help, - id: id, - __nextHasNoMarginBottom: __nextHasNoMarginBottom, + return /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(base_control_default, { + help, + id, + className: classes, + __nextHasNoMarginBottom, __associatedWPComponentName: "SelectControl", - children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(StyledInputBase, { - className: classes, - disabled: disabled, - hideLabelFromVision: hideLabelFromVision, - id: id, - isBorderless: variant === 'minimal', - label: label, - size: size, - suffix: suffix || !multiple && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(select_control_chevron_down, {}), - prefix: prefix, - labelPosition: labelPosition, - __unstableInputWidth: variant === 'minimal' ? 'auto' : undefined, - variant: variant, - __next40pxDefaultSize: __next40pxDefaultSize, - children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Select, { + children: /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(StyledInputBase, { + disabled, + hideLabelFromVision, + id, + isBorderless: variant === "minimal", + label, + size, + suffix: suffix || !multiple && /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(chevron_down_chevron_down_default, {}), + prefix, + labelPosition, + __unstableInputWidth: variant === "minimal" ? "auto" : void 0, + variant, + __next40pxDefaultSize, + children: /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(Select, { ...restProps, - __next40pxDefaultSize: __next40pxDefaultSize, + __next40pxDefaultSize, "aria-describedby": helpId, className: "components-select-control__input", - disabled: disabled, - id: id, - multiple: multiple, + disabled, + id, + multiple, onChange: handleOnChange, - ref: ref, + ref, selectSize: size, value: valueProp, - variant: variant, - children: children || /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(SelectOptions, { - options: options + variant, + children: children || /* @__PURE__ */ (0,external_ReactJSXRuntime_namespaceObject.jsx)(SelectOptions, { + options }) }) }) }); } - -/** - * `SelectControl` allows users to select from a single or multiple option menu. - * It functions as a wrapper around the browser's native `,