* All rights reserved * * This script is part of the TYPO3 project. The TYPO3 project is * free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * The GNU General Public License can be found at * http://www.gnu.org/copyleft/gpl.html. * * This script is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ use JShrink\Minifier; use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; /** * This class contains the parsing and replacing functionality for javascript files */ class ScriptmergerJavascript extends ScriptmergerBase { /** * holds the javascript code * * Structure: * - $file * |-content => string * |-basename => string (base name of $file without file prefix) * |-minify-ignore => bool * |-merge-ignore => bool * * @var array */ protected $javascript = array(); /** * Controller for the processing of the javascript files. * * @return void */ public function process() { // fetch all javascript content $this->getFiles(); // minify, compress and merging foreach ($this->javascript as $section => $javascriptBySection) { $mergedContent = ''; $positionOfMergedFile = NULL; foreach ($javascriptBySection as $index => $javascriptProperties) { $newFile = ''; // file should be minified if ($this->configuration['javascript.']['minify.']['enable'] === '1' && !$javascriptProperties['minify-ignore'] ) { $newFile = $this->minifyFile($javascriptProperties); } // file should be merged if ($this->configuration['javascript.']['merge.']['enable'] === '1' && !$javascriptProperties['merge-ignore'] ) { if ($positionOfMergedFile === NULL) { $positionOfMergedFile = $javascriptProperties['position-key']; } $mergedContent .= $javascriptProperties['content'] . LF; unset($this->javascript[$section][$index]); continue; } // file should be compressed instead? if ($this->configuration['javascript.']['compress.']['enable'] === '1' && function_exists('gzcompress') && !$javascriptProperties['compress-ignore'] ) { $newFile = $this->compressFile($javascriptProperties); } // minification or compression was used if ($newFile !== '') { $this->javascript[$section][$index]['file'] = $newFile; $this->javascript[$section][$index]['content'] = $javascriptProperties['content']; $this->javascript[$section][$index]['basename'] = $javascriptProperties['basename']; } } // save merged content inside a new file if ($this->configuration['javascript.']['merge.']['enable'] === '1' && $mergedContent !== '') { // create property array $properties = array( 'content' => $mergedContent, 'basename' => $section . '-' . md5($mergedContent) . '.merged' ); // write merged file in any case $newFile = $this->tempDirectories['merged'] . $properties['basename'] . '.js'; if (!file_exists($newFile)) { $this->writeFile($newFile, $properties['content']); } // file should be compressed if ($this->configuration['javascript.']['compress.']['enable'] === '1' && function_exists('gzcompress') ) { $newFile = $this->compressFile($properties); } // add new entry $this->javascript[$section][] = array( 'file' => $newFile, 'content' => $properties['content'], 'basename' => $properties['basename'], 'position-key' => $positionOfMergedFile, ); } } // write javascript content back to the document $this->writeToDocument(); } /** * This method parses the output content and saves any found javascript files or inline code * into the "javascript" class property. The output content is cleaned up of the found results. * * @return array js files */ protected function getFiles() { // init $javascriptTags = array( 'head' => array(), 'body' => array() ); // create search pattern $searchScriptsPattern = '/' . '))' . // It fetches the src attribute. '(?=.+?(?:data-ignore="(.*?)"|>))' . // and the data-ignore attribute of the tag. '[^>]*?>' . // Finally we finish the parsing of the opening tag '.*?<\/script>\s*' . // until the closing tag. '/is'; // filter pattern for the inDoc scripts (fetches the content) $filterInDocumentPattern = '/' . '' . // The expression removes the opening script tag '(?:.*?\/\*)?' . // senseless