125 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			PHP
		
	
	
			
		
		
	
	
			125 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			PHP
		
	
	
| <?php
 | |
| 
 | |
| namespace Drupal\advagg\Asset;
 | |
| 
 | |
| use Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher;
 | |
| use Drupal\Core\Cache\CacheBackendInterface;
 | |
| use Drupal\Core\Config\ConfigFactoryInterface;
 | |
| 
 | |
| /**
 | |
|  * The CSS Optimizer.
 | |
|  */
 | |
| class CssOptimizer extends AssetOptimizer {
 | |
| 
 | |
|   /**
 | |
|    * {@inheritdoc}
 | |
|    */
 | |
|   public function __construct(ConfigFactoryInterface $config_factory, ContainerAwareEventDispatcher $event_dispatcher, CacheBackendInterface $cache) {
 | |
|     $this->extension = 'css';
 | |
|     parent::__construct($config_factory, $event_dispatcher, $cache);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * {@inheritdoc}
 | |
|    */
 | |
|   protected function addDnsPrefetch(array $asset) {
 | |
|     $prefetch = [];
 | |
|     if (!isset($asset['contents'])) {
 | |
|       return $prefetch;
 | |
|     }
 | |
|     $matches = [];
 | |
|     $pattern = '%url\(\s*+[\'"]?+(http:\/\/|https:\/\/|\/\/)([^\'"()\s]++)[\'"]?+\s*+\)%i';
 | |
|     preg_match_all($pattern, $asset['contents'], $matches);
 | |
|     if (!empty($matches[1])) {
 | |
|       foreach ($matches[1] as $key => $match) {
 | |
|         $parse = @parse_url($match . $matches[2][$key]);
 | |
|         if (!empty($parse['host'])) {
 | |
|           $prefetch[] = $parse['host'];
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     return $prefetch;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * {@inheritdoc}
 | |
|    */
 | |
|   protected function fixType(array &$asset) {
 | |
|     // Default asset type to file if not set/invalid.
 | |
|     if (!in_array($asset['type'], ['file', 'external', 'settings'])) {
 | |
|       $asset['type'] = 'file';
 | |
|     }
 | |
| 
 | |
|     $path = $asset['data'];
 | |
| 
 | |
|     if ($asset['type'] === 'external') {
 | |
|       // If type is external but path doesn't start with http, https, or //
 | |
|       // change it to file.
 | |
|       if (stripos($path, 'http') !== 0 && stripos($path, '//') !== 0) {
 | |
|         $asset['type'] = 'file';
 | |
|       }
 | |
|       // If type is external and starts with http, https, or // but points to
 | |
|       // this host change to file, but move it to the top of the aggregation
 | |
|       // stack as long as css.preserve_external is not set.
 | |
|       elseif (stripos($path, $this->basePath) !== FALSE && !$this->config->get('css.preserve_external')) {
 | |
|         $asset['type'] = 'file';
 | |
|         $asset['group'] = CSS_BASE;
 | |
|         $asset['every_page'] = TRUE;
 | |
|         $asset['weight'] = -40000;
 | |
|         $asset['data'] = substr($asset['data'], stripos($asset['data'], $this->basePath) + $this->basePathLen);
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     // If type is file but it starts with http, https, or // change it to
 | |
|     // external.
 | |
|     elseif ($asset['type'] === 'file' && (stripos($path, 'http') === 0 || (stripos($path, '//') === 0))) {
 | |
|       $asset['type'] = 'external';
 | |
|     }
 | |
| 
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * {@inheritdoc}
 | |
|    */
 | |
|   protected function optimizeFile(array &$asset, array $data) {
 | |
|     $contents = $this->updateUrls($data['contents'], $asset['data']);
 | |
|     if ((int) \Drupal::VERSION < 10 && $this->config->get('css.combine_media') && $asset['media'] !== 'all') {
 | |
|       $contents = "@media {$asset['media']}{{$contents}}";
 | |
|       $asset['media'] = 'all';
 | |
|     }
 | |
|     $asset_event = new AssetOptimizationEvent($contents, $asset, $data);
 | |
|     $this->eventDispatcher->dispatch($asset_event, AssetOptimizationEvent::CSS);
 | |
|     $contents = $asset_event->getContent();
 | |
|     $asset = $asset_event->getAsset();
 | |
| 
 | |
|     // If file contents are unaltered return FALSE.
 | |
|     if ($contents === $data['contents'] && !$this->gZip) {
 | |
|       return FALSE;
 | |
|     }
 | |
|     return $this->writeFile($contents, $data['cid']);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Update any internal urls.
 | |
|    *
 | |
|    * @param string $contents
 | |
|    *   The file contents.
 | |
|    * @param string $path
 | |
|    *   The file path.
 | |
|    *
 | |
|    * @return string
 | |
|    *   The updated contents.
 | |
|    */
 | |
|   public function updateUrls($contents, $path) {
 | |
|     // Determine the file's directory including the Drupal base path.
 | |
|     $directory = base_path() . dirname($path) . '/';
 | |
| 
 | |
|     // Alter all internal url() paths. Leave external paths alone. We don't need
 | |
|     // to normalize absolute paths here because that will be done later. Also
 | |
|     // ignore SVG paths (# or %23). Expected form: url("/images/file.jpg") which
 | |
|     // gets converted to url("${directory}/images/file.jpg").
 | |
|     return preg_replace('/url\(\s*([\'"]?)(?![a-z]+:|\/+|\#|\%23+)([^\'")]+)([\'"]?)\s*\)/i', 'url(\1' . $directory . '\2\3)', $contents);
 | |
|   }
 | |
| 
 | |
| }
 |