Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added media package with implemented Compressors and combiners

  • Loading branch information...
commit 1b0405dadd95877181acfba8d0e65c60ab9a0ede 1 parent 55cdc73
@kaviththiranga authored
View
88 libraries/joomla/media/combiner.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ * @package Joomla.Platform
+ * @subpackage Media
+ *
+ * @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
+ * @license GNU General Public License version 2 or later; see LICENSE
+ */
+
+defined('JPATH_PLATFORM') or die;
+
+/**
+ * Interface for Javascript/CSS combiner classes.
+ *
+ * @package Joomla.Platform
+ * @subpackage Media
+ * @since 12.1
+ */
+abstract class JMediaCombiner
+{
+ public $sources = array();
+
+ protected $_combined = null;
+
+ protected $_options = array();
+
+
+ public function __construct($options = array())
+ {
+ // Merge user defined options with default options
+ $this->_options = array_merge($options, $this->_options);
+ }
+
+ /**
+ * Gives a combiner object for CSS/JS
+ *
+ * @param string $type Type of compressor needed
+ * @param array $options options for the compressor
+ *
+ * @return JMediaCombiner Returns a JMediaCombiner object
+ *
+ * @since 12.1
+ */
+ public static function getInstance($type, $options = array())
+ {
+
+ // Derive the class name from the type.
+ $class = 'JMediaCombiner' . ucfirst(strtolower($type));
+
+ // Load the class
+ jimport('joomla.media.combiner.' . $class);
+
+ // If the class still doesn't exist we have nothing left to do but throw an exception. We did our best.
+ if (!class_exists($class))
+ {
+ throw new RuntimeException(JText::sprintf('JMEDIA_ERROR_LOAD_COMBINOR', $type));
+ }
+
+ // Create our new JMediaCompressor class based on the options given.
+ try
+ {
+ $instance = new $class($options);
+ }
+ catch (RuntimeException $e)
+ {
+ throw new RuntimeException(JText::sprintf('JLIB_DATABASE_ERROR_CONNECT_DATABASE', $e->getMessage()));
+ }
+
+ return $instance;
+ }
+
+ public static function combineFiles($files, $options = array(), $destination = null)
+ {
+ $type = JFile::getExt($files[0]);
+
+ foreach ($files as $file)
+ {
+ if ($type != JFile::getExt($file))
+ {
+ throw new RuntimeException(JText::sprintf('JMEDIA_COMBINE_ERROR_MULTIPLE_FILE_TYPES'), $type);
+ }
+ }
+
+ $combiner = self::getInstance($type);
+
+ $combiner->combine($files);
+ }
+}
View
62 libraries/joomla/media/combiner/css.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ * @package Joomla.Platform
+ * @subpackage Media
+ *
+ * @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
+ * @license GNU General Public License version 2 or later; see LICENSE
+ */
+
+defined('JPATH_PLATFORM') or die;
+
+/**
+ * CSS combiner classes.
+ *
+ * @package Joomla.Platform
+ * @subpackage Media
+ * @since 12.1
+ */
+class JMediaCombinerCss extends JMediaCombiner
+{
+ /**
+ * Constructor of css combiner
+ *
+ * @param Array $options options
+ *
+ * @since 12.1
+ */
+ public function __construct($options = array())
+ {
+ $this->_options = array('COMPRESS' => false);
+ parent::__construct($options);
+ }
+
+ /**
+ * Method to combine a set of files and save to single file.
+ *
+ * @param Array $files Paths of files to combine.
+ * @param string $destination Path to the destination file.
+ *
+ * @return string Combined css code
+ *
+ * @since 12.1
+ */
+ public function combine($files, $destination = null)
+ {
+ foreach ($files as $file)
+ {
+ $this->_combined .= JFile::read($file) . "\n\n";
+ }
+
+ if ($this->_options['COMPRESS'])
+ {
+ $compressor = JMediaCompressorCss::getInstance('css', $this->_options);
+ $compressor->setUncompressed($this->_combined);
+ $compressor->compress();
+
+ $this->_combined = $compressor->getCompressed();
+ }
+
+ return $this->_combined;
+ }
+}
View
54 libraries/joomla/media/combiner/js.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * @package Joomla.Platform
+ * @subpackage Media
+ *
+ * @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
+ * @license GNU General Public License version 2 or later; see LICENSE
+ */
+
+defined('JPATH_PLATFORM') or die;
+
+/**
+ * Javascript combiner classe.
+ *
+ * @package Joomla.Platform
+ * @subpackage Compress
+ * @since 12.1
+ */
+class JMediaCombinerJs
+{
+
+ public function __construct($options = array())
+ {
+ $this->_options = array('COMPRESS' => false);
+ parent::__construct($options);
+ }
+
+ /**
+ * Method to combine a set of files and save to single file.
+ *
+ * @param Array $files Paths of files to combine.
+ * @param string $destination Path to the destination file.
+ *
+ * @since 12.1
+ */
+ public function combine($files, $destination)
+ {
+ foreach ($files as $file)
+ {
+ $this->_combined .= JFile::read($file)."\n\n";
+ }
+
+ if ($this->_options['COMPRESS'])
+ {
+ $compressor = JMediaCompressorCss::getInstance('js', $this->_options);
+ $compressor->setUncompressed($this->_combined);
+ $compressor->compress();
+
+ $this->_combined = $compressor->getCompressed();
+ }
+
+ return $this->_combined;
+ }
+}
View
284 libraries/joomla/media/compressor.php
@@ -0,0 +1,284 @@
+<?php
+/**
+ * @package Joomla.Platform
+ * @subpackage Media
+ *
+ * @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
+ * @license GNU General Public License version 2 or later; see LICENSE
+ */
+
+defined('JPATH_PLATFORM') or die;
+
+/**
+ * Javascript and CSS Compressor Class.
+ *
+ * @package Joomla.Platform
+ * @subpackage Media
+ * @since 12.1
+ */
+abstract class JMediaCompressor
+{
+ /**
+ * @var String To hold uncompressed Code.
+ * @since 12.1
+ */
+ public $uncompressed = null;
+
+ /**
+ * @var int length of uncompressed Code.
+ * @since 12.1
+ */
+ public $length;
+
+ /**
+ * @var Array Compression options for CSS Minifier.
+ * @since 12.1
+ */
+ protected $_options = array();
+
+ /**
+ * @var String To hold compressed Code.
+ * @since 12.1
+ */
+ protected $_compressed = null;
+
+ /**
+ * Method to set uncompressed code.
+ *
+ * @param string $uncompressed Uncomressed Code.
+ *
+ * @return void
+ *
+ * @since 12.1
+ */
+ public function setUncompressed($uncompressed)
+ {
+ $this->uncompressed = $uncompressed;
+ $this->length = strlen($this->uncompressed);
+ }
+
+ /**
+ * Method to set compression options.
+ *
+ * @param Array $options options to compress.
+ *
+ * @return void
+ *
+ * @since 12.1
+ */
+ public function setOptions($options)
+ {
+ // Merge user defined options with default options
+ $this->_options = array_merge($options, $this->_options);
+ }
+
+ /**
+ * Object Constructor takes two parameters.
+ *
+ * @param Array $options Compression options for Minifier.
+ *
+ * @since 12.1
+ */
+ public function __construct($options = array())
+ {
+ // Merge user defined options with default options
+ $this->_options = array_merge($options, $this->_options);
+ }
+
+ /**
+ * Method to get compressed code.
+ *
+ * @return String compressed code.
+ *
+ * @since 12.1
+ */
+ public function getCompressed()
+ {
+ return trim($this->_compressed);
+ }
+
+ /**
+ * Method to get compressed ratio.
+ *
+ * @return double Compressed ratio.
+ *
+ * @since 12.1
+ */
+ public function getRatio()
+ {
+ return $ratio = 0.0 + ( strlen($this->_compressed) / $this->length * 100 );
+ }
+
+ /**
+ * Get a list of available compressors
+ *
+ * @return array An array of available compressors
+ *
+ * @since 11.1
+ */
+ public static function getCompressors()
+ {
+ // Instantiate variables.
+ $compressors = array();
+
+ // Get a list of types.
+ $types = JFolder::files(__DIR__ . '/compressor');
+
+ // Loop through the types and find the ones that are available.
+ foreach ($types as $type)
+ {
+ // Ignore some files.
+ if ($type == 'index.html')
+ {
+ continue;
+ }
+
+ // Derive the class name from the type.
+ $class = str_ireplace('.php', '', trim($type));
+
+ // Load the class
+ jimport('joomla.media.compressor.' . $class);
+
+ // If the class doesn't exist we have nothing left to do but look at the next type. We did our best.
+ if (!class_exists('JMediaCompressor' . ucfirst($class)))
+ {
+ continue;
+ }
+
+ // Sweet! Our class exists, so now we just need to know if it passes its test method.
+ if ($class::isSupported())
+ {
+ // Connector names should not have file extensions.
+ $compressors[] = $class;
+ }
+ }
+
+ return $compressors;
+ }
+
+ /**
+ * Compress a CSS/JS file with given options
+ *
+ * @param string $sourcefile The full file path of the source file.
+ * @param array $options An asssociative array with options. Eg: force overwirte, prefix for minified files
+ * @param string $destination The full file path of the destination file.
+ *
+ * @return boolean false on failure.
+ *
+ * @since 12.1
+ */
+ public static function compressFile( $sourcefile, $options = array(), $destination = null )
+ {
+ // Detect the extension of file
+ $type = JFile::getExt(strtolower($sourcefile));
+
+ $compressor = self::getInstance($type, $options);
+
+ $uncompressed = JFile::read($sourcefile);
+
+ // Sets force overwrite option
+ $force = array_key_exists('overwrite', $options) && !empty($options['overwrite']) ?
+ $options['overwrite'] : false;
+
+ if ($destination === null)
+ {
+ if (array_key_exists('PREFIX', $options) && !empty($options['PREFIX']))
+ {
+ $destination = str_ireplace('.' . $type, '.' . $options['PREFIX'] . '.' . $type, $sourcefile);
+ }
+ else
+ {
+ $destination = str_ireplace('.' . $type, '.min.' . $type, $sourcefile);
+ }
+ }
+
+ if (!$uncompressed)
+ {
+ throw new JMediaException("Error reading the file (" . $sourcefile . ") contents");
+ }
+
+ $compressor->setUncompressed($uncompressed);
+
+ try
+ {
+ $compressor->compress();
+ }
+ catch (Exception $e)
+ {
+ return false;
+ }
+
+ if (JFile::write($destination, $compressor->getCompressed()))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Gives a compressor object for CSS/JS
+ *
+ * @param string $type Type of compressor needed
+ * @param array $options options for the compressor
+ *
+ * @return JMediaCompressor Returns a JMediaCompressor object
+ *
+ * @since 12.1
+ */
+ public static function getInstance($type, $options = array())
+ {
+
+ // Derive the class name from the type.
+ $class = 'JMediaCompressor' . ucfirst(strtolower($type));
+
+ // Load the class
+ jimport('joomla.media.compressor.' . $class);
+
+ // If the class still doesn't exist we have nothing left to do but throw an exception. We did our best.
+ if (!class_exists($class))
+ {
+ throw new RuntimeException(JText::sprintf('JMEDIA_ERROR_LOAD_COMPRESSOR', $type));
+ }
+
+ // Create our new JMediaCompressor class based on the options given.
+ try
+ {
+ $instance = new $class($options);
+ }
+ catch (RuntimeException $e)
+ {
+ throw new RuntimeException(JText::sprintf('JLIB_DATABASE_ERROR_CONNECT_DATABASE', $e->getMessage()));
+ }
+
+ return $instance;
+ }
+
+ /**
+ * Method to test if supported
+ *
+ * @param string $sourceFile file to test
+ *
+ * @return boolean true or false
+ *
+ * @since 12.1
+ */
+ public static function isSupported($sourceFile)
+ {
+ $compressors = self::getCompressors();
+
+ foreach ($compressors as $class)
+ {
+ if (strtolower(str_ireplace('JMediaCompressor', '', $class)) === strtolower(JFile::getExt($sourceFile)))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+}
View
246 libraries/joomla/media/compressor/css.php
@@ -0,0 +1,246 @@
+<?php
+/**
+ * @package Joomla.Platform
+ * @subpackage Media
+ *
+ * @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
+ * @license GNU General Public License version 2 or later; see LICENSE
+ */
+
+defined('JPATH_PLATFORM') or die;
+
+/**
+ * CSS Compressor Class.
+ *
+ * @package Joomla.Platform
+ * @subpackage Media
+ * @since 12.1
+ */
+class JMediaCompressorCss extends JMediaCompressor
+{
+ /**
+ * CSS hack for a browser
+ * @var boolean
+ *
+ * @since 12.1
+ */
+ private $_inHack = false;
+
+ /**
+ * Object constructor
+ *
+ * @param Array $options Compression options for CSS Minifier.
+ *
+ * @since 12.1
+ */
+ public function __construct($options = array())
+ {
+ $this->_options = array('REMOVE_COMMENTS' => true, 'MIN_COLOR_CODES' => true, 'LIMIT_LINE_LENGTH' => true);
+ parent::__construct($options);
+ }
+
+ /**
+ * Method to compress the code.
+ *
+ * @return Void
+ *
+ * @since 12.1
+ */
+ public function compress()
+ {
+ if ($this->uncompressed === null)
+ {
+ throw new RuntimeException(JText::sprintf('JMEDIA_CSS_COMPRESSION_ERROR_UNCOMPRESSED_NOTSET'));
+ }
+
+ $this->_compressed = str_replace("\r\n", "\n", $this->uncompressed);
+
+ $this->_compressed = $this->_preServe($this->_compressed);
+
+ /* Process all valid comments and apply call back, handleComments() function will return relavent replacements
+ * Second argument is to tell call $this->_handleComments() method and get replacement patterns for matches
+ * Delimiter '~' is used because using '/' will make this regex pattern ambigious
+ */
+ $this->_compressed = preg_replace_callback('~\\s*/\\*([\\s\\S]*?)\\*/\\s*~', array($this,'_handleComments'), $this->_compressed);
+
+ $this->_compressed = $this->_removeWS($this->_compressed);
+
+ // Handle selectors - match a start of a selector and pass them to $this->_handleSelectors() to get replacements
+ // /x is used turn on free-spacing mode in regex patterns
+ $this->_compressed = preg_replace_callback('/(?:\\s*[^~>+,\\s]+\\s*[,>+~])+\\s*[^~>+,\\s]+{/', array($this,'_handleSelectors') , $this->_compressed);
+
+ if ($this->_options['MIN_COLOR_CODES'])
+ {
+ $this->_compressed = $this->_minColorCodes($this->_compressed);
+ }
+
+ if ($this->_options['LIMIT_LINE_LENGTH'])
+ {
+ $this->_compressed = $this->_breakInToLines($this->_compressed);
+ }
+
+ $this->_compressed = preg_replace('/:first-l(etter|ine)\\{/', ':first-l$1 {', $this->_compressed);
+
+ }
+
+ /**
+ * Method to preserve special browser hacks - Will add 'keep' word infront of comments
+ *
+ * @param string $source source css code
+ *
+ * @return string modified css code
+ *
+ * @since 12.1
+ */
+ private function _preServe($source)
+ {
+ // Preserve empty comment after '>'
+ $patterns [] = '~>/\\*\\s*\\*/~';
+ $replacements[] = '>/*keep*/';
+
+ // Preserve empty comment between property and value
+ $patterns [] = '~/\\*\\s*\\*/\\s*:~';
+ $replacements[] = '/*keep*/:';
+
+ $patterns [] = '~:\\s*/\\*\\s*\\*/~';
+ $replacements[] = ':/*keep*/';
+
+ return preg_replace($patterns, $replacements, $source);
+ }
+
+ /**
+ * Method to detect which replacement patterne to use for identified comments
+ *
+ * @param Array $matches bacreferences from preg_replace_callback()
+ *
+ * @return string replacements for comments
+ *
+ * @since 12.1
+ */
+ private function _handleComments($matches)
+ {
+ // Do not replace the preserved and need to keep comments
+ if ($matches[1] === 'keep')
+ {
+ return '/*';
+ }
+
+ return '';
+ }
+
+ /**
+ * Method to process css selectors and identify replacements
+ *
+ * @param array $matches bacreferences from preg_replace_callback()
+ *
+ * @return String replacements for selectors
+ *
+ * @since 12.1
+ */
+ private function _handleSelectors($matches)
+ {
+ // Remove space around combinators
+ return preg_replace('/\\s*([,>+~])\\s*/', '$1', $matches[0]);
+ }
+
+ /**
+ * Method to remove unnecessary white spaces
+ *
+ * @param string $source source css code
+ *
+ * @return string white space removed css code
+ *
+ * @since 12.1
+ */
+ private function _removeWS($source)
+ {
+ // Remove spaces around ;
+ $patterns[] = '/\\s*;\\s*/';
+
+ $replacements[] = ';';
+
+ // Remove spaces around {} and final ; inside {}
+ $patterns[] = '/\\s*{\\s*/';
+
+ $replacements[] = '{';
+
+ $patterns[] = '/;?\\s*}\\s*/';
+
+ $replacements[] = '}';
+
+ // Remove spaces around urls
+ // X is used turn on free-spacing mode in regex patterns
+ $patterns[] = '/url\\( # url(
+ \\s*
+ ([^\\)]+?) # match 1 is url
+ \\s*
+ \\) # )
+ /x';
+
+ $replacements[] = 'url($1)';
+
+ $patterns[] = '/@import\\s+url/';
+
+ $replacements[] = '@import url';
+
+ // Remove tabs and spaces around a new line
+
+ $patterns[] = '/[ \\t]*\\n+\\s*/';
+
+ $replacements[] = "\n";
+
+ // Remove spaces around css rules and colons
+ // X is used turn on free-spacing mode in regex patterns
+ $patterns[] = '/\\s* ([{;]) # match 1 = start of block
+ \\s*
+ ([\\*_]?[\\w\\-]+) # match 2 = property
+ \\s* : \\s*
+ (\\b|[#\'"-]) # match 3 = start of value
+ /x';
+
+ // Using backreferences 1, 2 and 3
+ $replacements[] = '$1$2:$3';
+
+ $tmp = preg_replace($patterns, $replacements, $source);
+
+ return $tmp;
+ }
+
+ /**
+ * Method to minimize colour codes
+ *
+ * @param string $source Source css code
+ *
+ * @return string modified css code
+ *
+ * @since 12.1
+ */
+ private function _minColorCodes($source)
+ {
+ return preg_replace('/([^=])#([a-f\\d])\\2([a-f\\d])\\3([a-f\\d])\\4([\\s;\\}])/i', '$1#$2$3$4$5' , $source);
+ }
+
+ /**
+ * Method to break minified code in to new lines to limit line lengths (optional)
+ *
+ * @param string $source Source css code
+ *
+ * @return string modified css code
+ *
+ * @since 12.1
+ */
+ private function _breakInToLines($source)
+ {
+ // Insert a newline between desendant selectors
+ $source = preg_replace('/([\\w#\\.\\*]+)\\s+([\\w#\\.\\*]+){/', "$1\n$2{" , $source);
+
+ // Insert a new line after 1st numeric value found within a padding, margin, border or outline property
+ $source = preg_replace('/
+ ((?:padding|margin|border|outline):\\d+(?:px|em)?) # match 1 = 1st numeric string (eg: 10px)
+ \\s+
+ /x', "$1\n" , $source
+ );
+ return $source;
+ }
+
+}
View
472 libraries/joomla/media/compressor/js.php
@@ -0,0 +1,472 @@
+<?php
+/**
+ * @package Joomla.Platform
+ * @subpackage Media
+ *
+ * @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
+ * @license GNU General Public License version 2 or later; see LICENSE
+ */
+
+defined('JPATH_PLATFORM') or die;
+
+/**
+ * Javascript Compressor Class.
+ *
+ * @package Joomla.Platform
+ * @subpackage Media
+ *
+ * @since 12.1
+ */
+class JMediaCompressorJs extends JMediaCompressor
+{
+
+ /**
+ * Used to track the index
+ *
+ * @var String
+ * @since 12.1
+ */
+ private $_a = "\n";
+
+ /**
+ * Used to track the index.
+ *
+ *@var String
+ *@since 12.1
+ */
+ private $_b = '';
+
+ /**
+ * Next available Index to process.
+ *
+ * @var int
+ * @since 12.1
+ */
+ private $_nextIndex = 0;
+
+ /**
+ * length of uncompressed code after CR and LF chars are replaced with CR
+ *
+ * @var int
+ * @since 12.1
+ */
+ private $_startLength = 0;
+
+ /**
+ * to hold a preloaded char to peek nextindex
+ *
+ * @var char
+ * @since 12.1
+ */
+ private $_preLoaded = null;
+
+ /**
+ * last preocessed char used to identify keywords
+ *
+ * @var char
+ * @since 12.1
+ */
+ private $_previousChar = null;
+
+ /**
+ * Object Constructor one parameters.
+ *
+ * @param Array $options Compression options for CSS Minifier.
+ *
+ * @since 12.1
+ */
+ public function __construct($options = array())
+ {
+ $this->_options = array('REMOVE_COMMENTS' => true, 'CHANGE_ENCODING' => true);
+
+ parent::__construct($options);
+ }
+
+ /**
+ * Method to compress the code.
+ *
+ * @return void
+ *
+ * @since 12.1
+ */
+ public function compress()
+ {
+ if ($this->uncompressed === null)
+ {
+ throw new RuntimeException(JText::sprintf('JMEDIA_JS_COMPRESSION_ERROR_UNCOMPRESSED_NOTSET'));
+ }
+ $encoding = $this->_changeCharEncoding();
+
+ $this->uncompressed = str_replace("\r\n", "\n", $this->uncompressed);
+ $this->_startLength = strlen($this->uncompressed);
+
+ /* Commands to determine start point of switch in _executeCommand()
+ * Command 1 : Keep A
+ * Command 2 : Delete A
+ * Command 3 : Delete A to B
+ */
+ $this->_executeCommand(3);
+
+ while ($this->_a !== null)
+ {
+ $cmd = 1;
+
+ if ($this->_a === ' ')
+ {
+ if (($this->_previousChar === '+' || $this->_previousChar === '-') && ($this->_b === $this->_previousChar))
+ {
+ // Do nothing
+ }
+ elseif (!$this->_checkAlphaNum($this->_b))
+ {
+ $cmd = 2;
+ }
+ }
+ elseif ($this->_a === "\n")
+ {
+ if ($this->_b === ' ')
+ {
+ $cmd = 3;
+ }
+ elseif ( $this->_b === null || (strpos('{[(+-', $this->_b) === false && !$this->_checkAlphaNum($this->_b)))
+ {
+ $cmd = 2;
+ }
+ }
+ elseif (!$this->_checkAlphaNum($this->_a))
+ {
+ if ($this->_b === ' ' || ($this->_b === "\n" && (false === strpos('}])+-"\'', $this->_a))))
+ {
+ $cmd = 3;
+ }
+ }
+
+ $this->_executeCommand($cmd);
+
+ }// End While
+
+ // Resets multibyte encoding type
+ if ($encoding !== null)
+ {
+ mb_internal_encoding($encoding);
+ }
+
+ }
+
+ /**
+ * Method to execute commands
+ *
+ * @param int $cmd command number to execute
+ *
+ * @return void
+ *
+ * @throws JMediaException
+ *
+ * @since 12.1
+ */
+ private function _executeCommand($cmd)
+ {
+ // Prevent + + or - - becomes ++ or --
+ if ($cmd === 3 && ($this->_a === '+' || $this->_a === '-') && $this->_b === ' ' )
+ {
+ if ($this->uncompressed[$this->_nextIndex] === $this->_a)
+ {
+ $cmd = 1;
+ }
+ }
+
+ switch ($cmd)
+ {
+ case 1 :
+ $this->_compressed .= $this->_a;
+ $this->_previousChar = $this->_a;
+
+ case 2 :
+ $this->_a = $this->_b;
+
+ if ($this->_a === "'" || $this->_a === '"')
+ {
+ while (true)
+ {
+ $this->_compressed .= $this->_a;
+ $this->_previousChar = $this->_a;
+
+ $this->_a = $this->_next();
+
+ if ($this->_a === $this->_b)
+ {
+ break;
+ }
+
+ if ($this->_a === '\n')
+ {
+ throw new JMediaException("Unterminated string at index " . $this->_nextIndex);
+ }
+
+ if ($this->_a === '\\')
+ {
+ $this->_compressed .= $this->_a;
+ $this->_previousChar = $this->_a;
+
+ $this->_a = $this->_next();
+ }
+ }
+ }
+
+ case 3 :
+ $this->_b = $this->_getB();
+
+ if ($this->_b === '/' && $this->_checkRegExp())
+ {
+ $this->_compressed .= $this->_a . $this->_b;
+
+ while (true)
+ {
+ $this->_a = $this->_next();
+
+ if ($this->_a === '/')
+ {
+ break;
+ }
+ elseif ($this->_a === '\\')
+ {
+ $this->_compressed .= $this->_a;
+ $this->_a = $this->_next();
+ }
+ elseif (ord($this->_a) <= 10)
+ {
+ throw new JMediaException("Unterminated Regular expression at index" . $this->_nextIndex);
+ }
+
+ $this->_compressed .= $this->_a;
+ $this->_previousChar = $this->_a;
+ }
+
+ $this->_b = $this->_getB();
+ }
+ }// End switch
+ }
+
+ /**
+ * Method to check whether a char is alpha numeric
+ *
+ * @param char $char char to be checked
+ *
+ * @return boolean true if char is alpha numeric
+ *
+ * @since 12.1
+ */
+ private function _checkAlphaNum($char)
+ {
+ if (preg_match('/^[0-9a-zA-Z_\\$\\\\]$/', $char) || ord($char) > 126)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Method to check a regular expression
+ *
+ * @return boolean true if that part is a regexp
+ *
+ * @since 12.1
+ */
+ private function _checkRegExp()
+ {
+ if (strpos("\n:[!&|?{;(,=", $this->_a) !== false)
+ {
+ return true;
+ }
+
+ if ($this->_a === ' ')
+ {
+ if (strlen($this->_compressed) < 2)
+ {
+ return true;
+ }
+
+ $matches = array();
+
+ if (preg_match('/(?:case|else|in|return|typeof)$/', $this->_compressed, $matches))
+ {
+ if ($this->_compressed === $matches[0])
+ {
+ return true;
+ }
+ // Assure it is a keyword
+ $previousChar = substr($this->_compressed, strlen($this->_compressed) - strlen($matches[0]) - 1, 1);
+
+ if (!$this->_checkAlphaNum($previousChar))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Method to change multi-byte encoding
+ *
+ * @return string current multibyte encoding type
+ *
+ * @since 12.1
+ */
+ private function _changeCharEncoding()
+ {
+ $encoding = mb_internal_encoding();
+
+ if (function_exists('mb_strlen') && (ini_get('mbstring.func_overload') == 2) && $this->_options['CHANGE_ENCODING'])
+ {
+ mb_internal_encoding('8bit');
+ }
+
+ return $encoding;
+ }
+
+ /**
+ * Method to get char at next index
+ *
+ * @return char next available char
+ *
+ * @since 12.1
+ */
+ private function _next()
+ {
+ $char = null;
+
+ if ($this->_nextIndex < $this->_startLength)
+ {
+ $char = $this->uncompressed[$this->_nextIndex];
+ $this->_nextIndex++;
+ }
+ else
+ {
+ return null;
+ }
+
+ if ($char === "\r" || $char === "\n")
+ {
+ return "\n";
+ }
+
+ // Control chars are replaced with space
+ if (ord($char) < 32)
+ {
+ return ' ';
+ }
+
+ return $char;
+ }
+
+ /**
+ * Method to get next available char for point B
+ *
+ * @return char next B
+ *
+ * @since 12.1
+ */
+ private function _getB()
+ {
+ $nextB = $this->_next();
+
+ if ($nextB !== '/')
+ {
+ return $nextB;
+ }
+
+ $this->_preLoaded = $this->uncompressed[$this->_nextIndex];
+
+ if ($this->_preLoaded === '/' || $this->_preLoaded === '*')
+ {
+ return $this->_handleComments();
+ }
+ else
+ {
+ return $nextB;
+ }
+
+ }
+
+ /**
+ * Method to handle comments when getting next B
+ *
+ * @return string Immediate char on newline after single line comment or space if a multiline comment or the whole comment in some conditions
+ *
+ * @since 12.1
+ */
+ private function _handleComments()
+ {
+ $comment = '';
+
+ if ($this->_preLoaded === '/')
+ {
+ while (true)
+ {
+ $tmp = $this->_next();
+ $comment .= $tmp;
+
+ if (ord($tmp) <= 10)// End of line
+ {
+ // Keep IE conditional comment
+ if (preg_match('/^\\/@(?:cc_on|if|elif|else|end)\\b/', $comment))
+ {
+ $comment = "/{$comment}";
+ }
+ if ($this->_options['REMOVE_COMMENTS'])
+ {
+ return $tmp;
+ }
+ else
+ {
+ return $comment;
+ }
+ }
+ }
+ }
+ elseif ($this->_preLoaded === '*')
+ {
+ $this->_next();
+
+ while (true)
+ {
+ $tmp = $this->_next();
+
+ if ($tmp === '*')
+ {
+ if ($this->uncompressed[$this->_nextIndex] === '/')// End of comment
+ {
+ $this->_next();
+
+ // Keep comments preserved by YUI Compressor
+ if (0 === strpos($comment, '!'))
+ {
+ return "\n/*!" . substr($comment, 1) . "*/\n";
+ }
+
+ // Keep IE conditional comment
+ if (preg_match('/^@(?:cc_on|if|elif|else|end)\\b/', $comment))
+ {
+ return "/*{$comment}*/";
+ }
+
+ return ' ';
+ }
+ }
+ elseif ($tmp === null)
+ {
+ throw new JMediaException("Unterminated multiline comment at index" . $this->_nextIndex);
+ }
+
+ $comment .= $tmp;
+ }
+ }
+
+ return $comment;
+ }
+}
View
22 libraries/joomla/media/exception.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * @package Joomla.Platform
+ * @subpackage Media
+ * @since 12.1
+ */
+
+//igonre
+
+defined('JPATH_PLATFORM') or die;
+
+/**
+ * Compressor Exception Class.
+ *
+ * @package Joomla.Platform
+ * @subpackage Media
+ * @since 12.1
+ */
+class JMediaException extends Exception
+{
+
+}
Please sign in to comment.
Something went wrong with that request. Please try again.