a
, so the browser splits the paragraph and the live element's // text is truncated at that point — the fingerprint becomes a prefix of the // stored block. Used as a last-resort recovery, unique-match only. public static function matches( array $block, array $fingerprint, string $renderedText = '', bool $prefix = false ): bool { if (isset($fingerprint['service'])) { $service = (string) ($block['attrs']['service'] ?? ''); if ($service !== (string) $fingerprint['service']) { return false; } } if (isset($fingerprint['text'])) { $want = self::normalize((string) $fingerprint['text']); // Visible text lives in attrs.label for dynamic items (nav // link/submenu) and in innerHTML for static text blocks (paragraph, // heading, button) — accept either, plus the rendered text if given. $candidates = [ self::normalize((string) ($block['attrs']['label'] ?? '')), self::normalize(self::stripText((string) ($block['innerHTML'] ?? ''))), ]; if ($renderedText !== '') { $candidates[] = self::normalize(self::stripText($renderedText)); } $textOk = false; foreach ($candidates as $candidate) { $hit = $prefix ? ($want !== '' && strncmp($candidate, $want, strlen($want)) === 0) : ($candidate === $want); if ($hit) { $textOk = true; break; } } if (!$textOk) { return false; } } return true; } private static function stripText(string $html): string { return html_entity_decode(wp_strip_all_tags($html), ENT_QUOTES); } // Fold wptexturize's typographic substitutions back to ASCII: the client // reads the block's text from the rendered (texturized) DOM while this // fingerprints the raw stored markup, so without folding an apostrophe // alone ("Woody's" vs "Woody’s") falses a 409. Must stay in lockstep with // normalizeText in src/QuickEdit/lib/fingerprint.js. private static function normalize(string $value): string { $value = strtr($value, [ "\u{2018}" => "'", "\u{2019}" => "'", "\u{201A}" => "'", "\u{201B}" => "'", "\u{201C}" => '"', "\u{201D}" => '"', "\u{201E}" => '"', "\u{201F}" => '"', "\u{2012}" => '-', "\u{2013}" => '-', "\u{2014}" => '-', "\u{2015}" => '-', "\u{2026}" => '...', "\u{00A0}" => ' ', "\u{2009}" => ' ', "\u{202F}" => ' ', ]); $value = (string) preg_replace('/-{2,}/', '-', $value); return trim((string) preg_replace('/\s+/', ' ', $value)); } }