@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
at upstream/main 94 lines 2.4 kB view raw
1<?php 2 3/** 4 * API for replacing whitespace characters and some control characters with 5 * their printable representations. This is useful for debugging and 6 * displaying more helpful error messages to users. 7 * 8 */ 9final class PHUIInvisibleCharacterView extends AphrontView { 10 11 private $inputText; 12 private $plainText = false; 13 14 // This is a list of the common invisible characters that are 15 // actually typeable. Other invisible characters will simply 16 // be displayed as their hex representations. 17 private static $invisibleChars = array( 18 "\x00" => 'NULL', 19 "\t" => 'TAB', 20 "\n" => 'NEWLINE', 21 "\x20" => 'SPACE', 22 ); 23 24 public function __construct($input_text) { 25 $this->inputText = $input_text; 26 } 27 28 public function setPlainText($plain_text) { 29 $this->plainText = $plain_text; 30 return $this; 31 } 32 33 public function getStringParts() { 34 $input_text = $this->inputText; 35 $text_array = phutil_utf8v($input_text); 36 37 for ($ii = 0; $ii < count($text_array); $ii++) { 38 $char = $text_array[$ii]; 39 $char_hex = bin2hex($char); 40 if (array_key_exists($char, self::$invisibleChars)) { 41 $text_array[$ii] = array( 42 'special' => true, 43 'value' => '<'.self::$invisibleChars[$char].'>', 44 ); 45 } else if (ord($char) < 32) { 46 $text_array[$ii] = array( 47 'special' => true, 48 'value' => '<0x'.$char_hex.'>', 49 ); 50 } else { 51 $text_array[$ii] = array( 52 'special' => false, 53 'value' => $char, 54 ); 55 } 56 } 57 return $text_array; 58 } 59 60 private function renderHtmlArray() { 61 $html_array = array(); 62 $parts = $this->getStringParts(); 63 foreach ($parts as $part) { 64 if ($part['special']) { 65 $html_array[] = phutil_tag( 66 'span', 67 array('class' => 'invisible-special'), 68 $part['value']); 69 } else { 70 $html_array[] = $part['value']; 71 } 72 } 73 return $html_array; 74 } 75 76 private function renderPlainText() { 77 $parts = $this->getStringParts(); 78 $res = ''; 79 foreach ($parts as $part) { 80 $res .= $part['value']; 81 } 82 return $res; 83 } 84 85 public function render() { 86 require_celerity_resource('phui-invisible-character-view-css'); 87 if ($this->plainText) { 88 return $this->renderPlainText(); 89 } else { 90 return $this->renderHtmlArray(); 91 } 92 } 93 94}