[ Index ]

PHP Cross Reference of phpBB-3.3.3-deutsch

title

Body

[close]

/vendor/s9e/text-formatter/src/Configurator/JavaScript/ -> StylesheetCompressor.php (source)

   1  <?php
   2  
   3  /**
   4  * @package   s9e\TextFormatter
   5  * @copyright Copyright (c) 2010-2020 The s9e authors
   6  * @license   http://www.opensource.org/licenses/mit-license.php The MIT License
   7  */
   8  namespace s9e\TextFormatter\Configurator\JavaScript;
   9  
  10  use s9e\TextFormatter\Configurator\Helpers\RegexpBuilder;
  11  use s9e\TextFormatter\Configurator\JavaScript\Code;
  12  
  13  class StylesheetCompressor
  14  {
  15      /**
  16      * @var string[] List of regular expressions that match strings to deduplicate
  17      */
  18      protected $deduplicateTargets = [
  19          '<xsl:template match="',
  20          '</xsl:template>',
  21          '<xsl:apply-templates/>',
  22          '<param name="allowfullscreen" value="true"/>',
  23          '<xsl:value-of select="',
  24          '<xsl:copy-of select="@',
  25          '<iframe allowfullscreen="" scrolling="no"',
  26          'display:block;overflow:hidden;position:relative;padding-bottom:',
  27          'display:inline-block;width:100%;max-width:',
  28          ' [-:\\w]++="',
  29          '\\{[^}]++\\}',
  30          '@[-\\w]{4,}+',
  31          '(?<=<)[-:\\w]{4,}+',
  32          '(?<==")[^"]{4,}+"'
  33      ];
  34  
  35      /**
  36      * @var array Associative array of string replacements as [match => replace]
  37      */
  38      protected $dictionary;
  39  
  40      /**
  41      * @var string Prefix used for dictionary keys
  42      */
  43      protected $keyPrefix = '$';
  44  
  45      /**
  46      * @var integer Number of bytes each global substitution must save to be considered
  47      */
  48      public $minSaving = 10;
  49  
  50      /**
  51      * @var array Associative array of [string => saving]
  52      */
  53      protected $savings;
  54  
  55      /**
  56      * @var string
  57      */
  58      protected $xsl;
  59  
  60      /**
  61      * Encode given stylesheet into a compact JavaScript representation
  62      *
  63      * @param  string $xsl Original stylesheet
  64      * @return string      JavaScript representation of the compressed stylesheet
  65      */
  66  	public function encode($xsl)
  67      {
  68          $this->xsl = $xsl;
  69  
  70          $this->estimateSavings();
  71          $this->filterSavings();
  72          $this->buildDictionary();
  73  
  74          $str = $this->getCompressedStylesheet();
  75  
  76          // Split the stylesheet's string into 2000 bytes chunks to appease Google Closure Compiler
  77          $js = implode("+\n", array_map('json_encode', str_split($str, 2000)));
  78          if (!empty($this->dictionary))
  79          {
  80              $js = '(' . $js . ').replace(' . $this->getReplacementRegexp() . ',function(k){return' . json_encode($this->dictionary) . '[k];})';
  81          }
  82  
  83          return $js;
  84      }
  85  
  86      /**
  87      * Build a dictionary of all cost-effective string replacements
  88      *
  89      * @return void
  90      */
  91  	protected function buildDictionary()
  92      {
  93          $keys = $this->getAvailableKeys();
  94          rsort($keys);
  95  
  96          $this->dictionary = [];
  97          arsort($this->savings);
  98          foreach (array_keys($this->savings) as $str)
  99          {
 100              $key = array_pop($keys);
 101              if (!$key)
 102              {
 103                  break;
 104              }
 105  
 106              $this->dictionary[$key] = $str;
 107          }
 108      }
 109  
 110      /**
 111      * Estimate the savings of every possible string replacement
 112      *
 113      * @return void
 114      */
 115  	protected function estimateSavings()
 116      {
 117          $this->savings = [];
 118          foreach ($this->getStringsFrequency() as $str => $cnt)
 119          {
 120              $len             = strlen($str);
 121              $originalCost    = $cnt * $len;
 122              $replacementCost = $cnt * 2;
 123              $overhead        = $len + 6;
 124  
 125              $this->savings[$str] = $originalCost - ($replacementCost + $overhead);
 126          }
 127      }
 128  
 129      /**
 130      * Filter the savings according to the minSaving property
 131      *
 132      * @return void
 133      */
 134  	protected function filterSavings()
 135      {
 136          $this->savings = array_filter(
 137              $this->savings,
 138              function ($saving)
 139              {
 140                  return ($saving >= $this->minSaving);
 141              }
 142          );
 143      }
 144  
 145      /**
 146      * Return all the possible dictionary keys that are not present in the original stylesheet
 147      *
 148      * @return string[]
 149      */
 150  	protected function getAvailableKeys()
 151      {
 152          return array_diff($this->getPossibleKeys(), $this->getUnavailableKeys());
 153      }
 154  
 155      /**
 156      * Return the stylesheet after dictionary replacements
 157      *
 158      * @return string
 159      */
 160  	protected function getCompressedStylesheet()
 161      {
 162          return strtr($this->xsl, array_flip($this->dictionary));
 163      }
 164  
 165      /**
 166      * Return a list of possible dictionary keys
 167      *
 168      * @return string[]
 169      */
 170  	protected function getPossibleKeys()
 171      {
 172          $keys = [];
 173          foreach (range('a', 'z') as $char)
 174          {
 175              $keys[] = $this->keyPrefix . $char;
 176          }
 177  
 178          return $keys;
 179      }
 180  
 181      /**
 182      * Return a regexp that matches all used dictionary keys
 183      *
 184      * @return string
 185      */
 186  	protected function getReplacementRegexp()
 187      {
 188          return '/' . RegexpBuilder::fromList(array_keys($this->dictionary)) . '/g';
 189      }
 190  
 191      /**
 192      * Return the frequency of all deduplicatable strings
 193      *
 194      * @return array Array of [string => frequency]
 195      */
 196  	protected function getStringsFrequency()
 197      {
 198          $regexp = '(' . implode('|', $this->deduplicateTargets) . ')S';
 199          preg_match_all($regexp, $this->xsl, $matches);
 200  
 201          return array_count_values($matches[0]);
 202      }
 203  
 204      /**
 205      * Return the list of possible dictionary keys that appear in the original stylesheet
 206      *
 207      * @return string[]
 208      */
 209  	protected function getUnavailableKeys()
 210      {
 211          preg_match_all('(' . preg_quote($this->keyPrefix) . '.)', $this->xsl, $matches);
 212  
 213          return array_unique($matches[0]);
 214      }
 215  }


Generated: Sun Feb 14 20:08:31 2021 Cross-referenced by PHPXref 0.7.1