', '', '', 'xsl = $xsl; $this->estimateSavings(); $this->filterSavings(); $this->buildDictionary(); $js = \json_encode($this->getCompressedStylesheet()); if (!empty($this->dictionary)) $js .= '.replace(' . $this->getReplacementRegexp() . ',function(k){return' . \json_encode($this->dictionary) . '[k]})'; return $js; } protected function buildDictionary() { $keys = $this->getAvailableKeys(); \rsort($keys); $this->dictionary = []; \arsort($this->savings); foreach (\array_keys($this->savings) as $str) { $key = \array_pop($keys); if (!$key) break; $this->dictionary[$key] = $str; } } protected function estimateSavings() { $this->savings = []; foreach ($this->getStringsFrequency() as $str => $cnt) { $len = \strlen($str); $originalCost = $cnt * $len; $replacementCost = $cnt * 2; $overhead = $len + 6; $this->savings[$str] = $originalCost - ($replacementCost + $overhead); } } protected function filterSavings() { $this->savings = \array_filter( $this->savings, function ($saving) { return ($saving >= $this->minSaving); } ); } protected function getAvailableKeys() { return \array_diff($this->getPossibleKeys(), $this->getUnavailableKeys()); } protected function getCompressedStylesheet() { return \strtr($this->xsl, \array_flip($this->dictionary)); } protected function getPossibleKeys() { $keys = []; foreach (\range('a', 'z') as $char) $keys[] = $this->keyPrefix . $char; return $keys; } protected function getReplacementRegexp() { return '/' . RegexpBuilder::fromList(\array_keys($this->dictionary)) . '/g'; } protected function getStringsFrequency() { $regexp = '(' . \implode('|', $this->deduplicateTargets) . ')S'; \preg_match_all($regexp, $this->xsl, $matches); return \array_count_values($matches[0]); } protected function getUnavailableKeys() { \preg_match_all('(' . \preg_quote($this->keyPrefix) . '.)', $this->xsl, $matches); return \array_unique($matches[0]); } }