@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 152 lines 3.5 kB view raw
1<?php 2 3final class CeleritySpriteGenerator extends Phobject { 4 5 public function buildTokenSheet() { 6 $icons = $this->getDirectoryList('tokens_1x'); 7 $scales = array( 8 '1x' => 1, 9 '2x' => 2, 10 ); 11 $template = id(new PhutilSprite()) 12 ->setSourceSize(18, 18); 13 14 $sprites = array(); 15 $prefix = 'tokens_'; 16 foreach ($icons as $icon) { 17 $sprite = id(clone $template) 18 ->setName('tokens-'.$icon) 19 ->setTargetCSS('.tokens-'.$icon); 20 21 foreach ($scales as $scale_key => $scale) { 22 $path = $this->getPath($prefix.$scale_key.'/'.$icon.'.png'); 23 $sprite->setSourceFile($path, $scale); 24 } 25 $sprites[] = $sprite; 26 } 27 28 $sheet = $this->buildSheet('tokens', true); 29 $sheet->setScales($scales); 30 foreach ($sprites as $sprite) { 31 $sheet->addSprite($sprite); 32 } 33 34 return $sheet; 35 } 36 37 public function buildLoginSheet() { 38 $icons = $this->getDirectoryList('login_1x'); 39 $scales = array( 40 '1x' => 1, 41 '2x' => 2, 42 ); 43 $template = id(new PhutilSprite()) 44 ->setSourceSize(28, 28); 45 46 $sprites = array(); 47 $prefix = 'login_'; 48 foreach ($icons as $icon) { 49 $sprite = id(clone $template) 50 ->setName('login-'.$icon) 51 ->setTargetCSS('.login-'.$icon); 52 53 foreach ($scales as $scale_key => $scale) { 54 $path = $this->getPath($prefix.$scale_key.'/'.$icon.'.png'); 55 $sprite->setSourceFile($path, $scale); 56 } 57 $sprites[] = $sprite; 58 } 59 60 $sheet = $this->buildSheet('login', true); 61 $sheet->setScales($scales); 62 foreach ($sprites as $sprite) { 63 $sheet->addSprite($sprite); 64 } 65 66 return $sheet; 67 } 68 69 private function getPath($to_path = null) { 70 $root = dirname(phutil_get_library_root('phabricator')); 71 return $root.'/resources/sprite/'.$to_path; 72 } 73 74 private function getDirectoryList($dir) { 75 $path = $this->getPath($dir); 76 77 $result = array(); 78 79 $images = Filesystem::listDirectory($path, $include_hidden = false); 80 foreach ($images as $image) { 81 if (!preg_match('/\.png$/', $image)) { 82 throw new Exception( 83 pht( 84 "Expected file '%s' in '%s' to be a sprite source ending in '%s'.", 85 $image, 86 $path, 87 '.png')); 88 } 89 $result[] = substr($image, 0, -4); 90 } 91 92 return $result; 93 } 94 95 private function buildSheet( 96 $name, 97 $has_retina, 98 $type = null, 99 $extra_css = '') { 100 101 $sheet = new PhutilSpriteSheet(); 102 103 $at = '@'; 104 105 switch ($type) { 106 case PhutilSpriteSheet::TYPE_STANDARD: 107 default: 108 $type = PhutilSpriteSheet::TYPE_STANDARD; 109 $repeat_rule = 'no-repeat'; 110 break; 111 case PhutilSpriteSheet::TYPE_REPEAT_X: 112 $repeat_rule = 'repeat-x'; 113 break; 114 case PhutilSpriteSheet::TYPE_REPEAT_Y: 115 $repeat_rule = 'repeat-y'; 116 break; 117 } 118 119 $retina_rules = null; 120 if ($has_retina) { 121 $retina_rules = <<<EOCSS 122@media 123only screen and (-webkit-min-device-pixel-ratio: 1.5), 124only screen and (min-resolution: 1.5dppx) { 125 .sprite-{$name}{$extra_css} { 126 background-image: url(/rsrc/image/sprite-{$name}-X2.png); 127 background-size: {X}px {Y}px; 128 } 129} 130EOCSS; 131 } 132 133 $sheet->setSheetType($type); 134 $sheet->setCSSHeader(<<<EOCSS 135/** 136 * @provides sprite-{$name}-css 137 * {$at}generated 138 */ 139 140.sprite-{$name}{$extra_css} { 141 background-image: url(/rsrc/image/sprite-{$name}.png); 142 background-repeat: {$repeat_rule}; 143} 144 145{$retina_rules} 146 147EOCSS 148); 149 150 return $sheet; 151 } 152}