diff --git a/Classes/Manipulation/RemoveComments.php b/Classes/Manipulation/RemoveComments.php
index 3187419..6cb085b 100644
--- a/Classes/Manipulation/RemoveComments.php
+++ b/Classes/Manipulation/RemoveComments.php
@@ -19,22 +19,20 @@ class RemoveComments implements ManipulationInterface
*/
public function manipulate(string $html, array $configuration = []): string
{
- if (isset($configuration['keep.'])) {
+ if (isset($configuration['keep.'])) {// DEPRECATED
$this->whiteListCommentsPatterns = $configuration['keep.'];
}
- // match all comments, styles and scripts
- $matches = [];
- preg_match_all(
- '/(?s)(()|(<[ \n\r]*style[^>]*>.*?<[ \n\r]*\/style[^>]*>)|(<[ \n\r]*script[^>]*>.*?<[ \n\r]*\/script[^>]*>))/im',
- $html,
- $matches
+ return preg_replace_callback(
+ '/\s*/',
+ function (array $match): string {
+ if ($this->keepComment($match[1])) {
+ return $match[0];
+ }
+ return '';
+ },
+ $html
);
- foreach ($matches[0] as $tag) {
- if (false === $this->keepComment($tag)) {
- $html = str_replace($tag, '', $html);
- }
- }
return $html;
}
@@ -42,25 +40,17 @@ public function manipulate(string $html, array $configuration = []): string
/**
* Check if a comment is defined to be kept in a pattern whiteListOfComments.
*/
- protected function keepComment(string $commentHtml): bool
+ protected function keepComment(string $comment): bool
{
- // if not even a comment, skip this
- if (!preg_match('/^\<\!\-\-(.*?)\-\-\>$/usi', $commentHtml)) {
- return true;
- }
-
// if not defined in white list
if (!empty($this->whiteListCommentsPatterns)) {
- $commentHtml = str_replace('', '', $commentHtml);
- $commentHtml = trim($commentHtml);
+ $comment = trim($comment);
foreach ($this->whiteListCommentsPatterns as $pattern) {
- if (!empty($pattern) && preg_match($pattern, $commentHtml)) {
+ if (preg_match($pattern, $comment)) {
return true;
}
}
}
-
return false;
}
}
diff --git a/Classes/Manipulation/RemoveGenerator.php b/Classes/Manipulation/RemoveGenerator.php
index 9a108a8..714a05e 100644
--- a/Classes/Manipulation/RemoveGenerator.php
+++ b/Classes/Manipulation/RemoveGenerator.php
@@ -16,6 +16,6 @@ public function manipulate(string $html, array $configuration = []): string
{
$regex = ']+>';
- return (string) preg_replace('/' . $regex . '/is', '', $html);
+ return (string) preg_replace('/' . $regex . '/i', '', $html);
}
}
diff --git a/Classes/Middleware/AbstractMiddleware.php b/Classes/Middleware/AbstractMiddleware.php
index 158afd7..39de605 100644
--- a/Classes/Middleware/AbstractMiddleware.php
+++ b/Classes/Middleware/AbstractMiddleware.php
@@ -10,9 +10,24 @@
use TYPO3\CMS\Core\Http\NullResponse;
use TYPO3\CMS\Core\Http\Stream;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
+use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
abstract class AbstractMiddleware implements MiddlewareInterface
{
+ /** @var ConfigurationManagerInterface */
+ protected $configurationManager;
+
+ /**
+ * Injects the Configuration Manager and loads the settings
+ *
+ * @param ConfigurationManagerInterface $configurationManager An instance of the Configuration Manager
+ */
+ public function injectConfigurationManager(
+ ConfigurationManagerInterface $configurationManager
+ ): void {
+ $this->configurationManager = $configurationManager;
+ }
+
protected function responseIsAlterable(ResponseInterface $response): bool
{
if ($response instanceof NullResponse) {
@@ -34,6 +49,19 @@ protected function responseIsAlterable(ResponseInterface $response): bool
return true;
}
+ protected function getConfiguration(ServerRequestInterface $request): array
+ {
+ if (isset($GLOBALS['TSFE']->config['config']['sourceopt.'])) {// DEPRECATED
+ return $GLOBALS['TSFE']->config['config']['sourceopt.'];
+ }
+
+ if ($request->getAttribute('site')->getSettings()->get('sourceopt')) {
+ return $request->getAttribute('site')->getSettings()->get('sourceopt');
+ }
+
+ throw new \Exception('SiteConfig:SourceOpt ist missing');
+ }
+
protected function getStringStream(string $content): StreamInterface
{
$body = new Stream('php://temp', 'rw');
diff --git a/Classes/Resource/SvgFileRepository.php b/Classes/Resource/SvgFileRepository.php
index 0b06144..7bc4a0e 100644
--- a/Classes/Resource/SvgFileRepository.php
+++ b/Classes/Resource/SvgFileRepository.php
@@ -23,6 +23,7 @@ public function findAllByStorageUids(array $storageUids): \Traversable
return $queryBuilder
->select('sys_file.storage', 'sys_file.identifier', 'sys_file.sha1')
+ ->addSelectLiteral('COUNT(*) AS ' . $queryBuilder->quoteIdentifier('count'))
->from('sys_file')
->innerJoin(
'sys_file',
diff --git a/Classes/Service/CleanHtmlService.php b/Classes/Service/CleanHtmlService.php
index 9722fa0..ffe5ca5 100644
--- a/Classes/Service/CleanHtmlService.php
+++ b/Classes/Service/CleanHtmlService.php
@@ -56,11 +56,14 @@ public function setVariables(array $config): void
$this->headerComment = $config['headerComment'];
}
- if (isset($config['formatHtml']) && is_numeric($config['formatHtml'])) {
+ if (isset($config['formatHtml']) && is_numeric($config['formatHtml'])) {// DEPRECATED
$this->formatType = (int) $config['formatHtml'];
}
+ if (isset($config['formatHtml.']['enabled']) && is_numeric($config['formatHtml.']['enabled']) && 0 <= $config['formatHtml.']['enabled']) {
+ $this->formatType = (int) $config['formatHtml.']['enabled'];
+ }
- if (isset($config['formatHtml.']['tabSize']) && is_numeric($config['formatHtml.']['tabSize'])) {
+ if (isset($config['formatHtml.']['tabSize']) && is_numeric($config['formatHtml.']['tabSize']) && 0 < $config['formatHtml.']['tabSize']) {
$this->tab = str_pad('', (int) $config['formatHtml.']['tabSize'], ' ');
}
@@ -68,7 +71,7 @@ public function setVariables(array $config): void
$this->debugComment = (bool) $config['formatHtml.']['debugComment'];
}
- if (isset($config['dropEmptySpaceChar']) && (bool) $config['dropEmptySpaceChar']) {
+ if (isset($config['dropEmptySpaceChar']) && (bool) $config['dropEmptySpaceChar']) {// DEPRECATED ?!
$this->emptySpaceChar = '';
}
}
@@ -136,7 +139,7 @@ public function clean(string $html, array $config = []): string
);
}
- if ($this->formatType > 0) {
+ if ($this->formatType) {
$html = $this->formatHtml($html);
}
diff --git a/Classes/Service/SvgStoreService.php b/Classes/Service/SvgStoreService.php
index cb6704a..f3a795d 100644
--- a/Classes/Service/SvgStoreService.php
+++ b/Classes/Service/SvgStoreService.php
@@ -201,6 +201,8 @@ private function populateCache(): bool
$file['path'] = '/' . $storageArr[$file['storage']] . $file['identifier']; // ^[/]
$file['defs'] = $this->addFileToSpriteArr($file['sha1'], $file['path']);
+// TODO ; if(--$file['count']) INLINE @
+
if (null !== $file['defs']) {
$this->svgFileArr[$file['path']] = $file['defs'];
}
@@ -232,8 +234,8 @@ function (array $match): string {
$svg = preg_replace('/\s{2,}/', ' ', $svg); // shrink whitespace
}
- $svg = preg_replace('/<([a-z\-]+)\s*(\/|>\s*<\/\1)>\s*|\s+(?=\/>)/i', '', $svg); // remove emtpy TAGs & shorten endings
- $svg = preg_replace('/<((circle|ellipse|line|path|polygon|polyline|rect|stop|use)\s[^>]+?)\s*>\s*<\/\2>/', '<$1/>', $svg); // shorten/minify TAG syntax
+ $svg = preg_replace('/<([a-z]+)\s*(\/|>\s*<\/\1)>\s*|\s+(?=\/>)/i', '', $svg); // remove emtpy TAGs & shorten endings
+ $svg = preg_replace('/<(([a-z]+)\s[^>]+?)\s*>\s*<\/\2>/i', '<$1/>', $svg); // shorten/minify TAG syntax
if (!is_dir($this->sitePath . $this->outputDir)) {
GeneralUtility::mkdir_deep($this->sitePath . $this->outputDir);
diff --git a/Configuration/Sets/SourceOpt/settings.definitions.yaml b/Configuration/Sets/SourceOpt/settings.definitions.yaml
index 0f9b2da..6a5cbca 100644
--- a/Configuration/Sets/SourceOpt/settings.definitions.yaml
+++ b/Configuration/Sets/SourceOpt/settings.definitions.yaml
@@ -1,6 +1,6 @@
categories:
sourceopt:
- label: 'SourceOpt'
+ label: 'SourceOpt[imization]'
sourceopt.cleaner:
label: 'Cleaner'
parent: sourceopt
@@ -13,58 +13,70 @@ categories:
settings:
sourceopt.enabled:
+ category: sourceopt.cleaner
label: LLL:EXT:sourceopt/Resources/Private/Language/locallang.xlf:sourceopt.enabled
- default: true
type: bool
- category: sourceopt.cleaner
+ default: true
sourceopt.removeGenerator:
+ category: sourceopt.cleaner
label: LLL:EXT:sourceopt/Resources/Private/Language/locallang.xlf:sourceopt.removeGenerator
- default: true
type: bool
- category: sourceopt.cleaner
+ default: true
sourceopt.removeComments:
+ category: sourceopt.cleaner
label: LLL:EXT:sourceopt/Resources/Private/Language/locallang.xlf:sourceopt.removeComments
- default: true
type: bool
+ default: true
+ sourceopt.keepComments:
category: sourceopt.cleaner
- sourceopt.removeComments.keep.10:
- label: LLL:EXT:sourceopt/Resources/Private/Language/locallang.xlf:sourceopt.removeCommentsKeep10
- default: '/^TYPO3SEARCH_/usi'
- type: string
- category: sourceopt.cleaner
+ label: 'Spare these listed comments [RegEx]'
+ type: stringlist
+ default:
+ - '/^TYPO3SEARCH_/usi'
sourceopt.headerComment:
- label: LLL:EXT:sourceopt/Resources/Private/Language/locallang.xlf:sourceopt.headerComment
- default: ''
- type: string
category: sourceopt.cleaner
- sourceopt.formatHtml:
- label: LLL:EXT:sourceopt/Resources/Private/Language/locallang.xlf:sourceopt.formatHtml
- default: '4'
+ label: LLL:EXT:sourceopt/Resources/Private/Language/locallang.xlf:sourceopt.headerComment
type: string
+ default: ''
+ sourceopt.formatHtml.enabled:
category: sourceopt.formater
- # enum:
- # '0': Disable
- # '1': No line break at all (code in one line)
- # '2': Minimalistic line breaks (structure defining box-elements)
- # '3': Aesthetic line breaks (important box-elements)
- # '4': Logic line breaks (all box-elements)
+ label: LLL:EXT:sourceopt/Resources/Private/Language/locallang.xlf:sourceopt.formatHtml
+ type: bool
+ default: true
sourceopt.formatHtml.tabSize:
+ category: sourceopt.formater
label: LLL:EXT:sourceopt/Resources/Private/Language/locallang.xlf:sourceopt.formatHtmlTabSize
- default: ''
- type: string
+ type: int
+ default: 4
+ sourceopt.formatHtml.indentation:
category: sourceopt.formater
+ label: LLL:EXT:sourceopt/Resources/Private/Language/locallang.xlf:sourceopt.formatHtmlIndentation
+ type: int
+ default: 2
sourceopt.formatHtml.debugComment:
+ category: sourceopt.formater
label: LLL:EXT:sourceopt/Resources/Private/Language/locallang.xlf:sourceopt.formatHtmlDebugComment
default: false
type: bool
- category: sourceopt.formater
svgstore.enabled:
+ category: sourceopt.svgstore
label: LLL:EXT:sourceopt/Resources/Private/Language/locallang.xlf:svgstore.enabled
- default: true
type: bool
+ default: true
+ svgstore.renderMode:
category: sourceopt.svgstore
+ label: LLL:EXT:sourceopt/Resources/Private/Language/locallang.xlf:svgstore.renderMode
+ type: select
+ default: symbol
+ items:
+ - label: 'Reference all SVGs (default)'
+ value: symbol
+ - label: 'Inline single-use SVGs (optimize traffic)'
+ value: distinct
+ - label: 'Inline all SVGs at HTML (not recommended)'
+ value: inline
svgstore.fileSize:
+ category: sourceopt.svgstore
label: LLL:EXT:sourceopt/Resources/Private/Language/locallang.xlf:svgstore.fileSize
- default: 50000
type: int
- category: sourceopt.svgstore
+ default: 50000
diff --git a/Configuration/Sets/SourceOpt/setup.typoscript b/Configuration/Sets/SourceOpt/setup.typoscript
deleted file mode 100644
index 540cfca..0000000
--- a/Configuration/Sets/SourceOpt/setup.typoscript
+++ /dev/null
@@ -1 +0,0 @@
-@import 'EXT:sourceopt/Configuration/TypoScript/setup.typoscript'
diff --git a/Configuration/TypoScript/constants.typoscript b/Configuration/TypoScript/constants.typoscript
index 2bbdb11..62944cf 100644
--- a/Configuration/TypoScript/constants.typoscript
+++ b/Configuration/TypoScript/constants.typoscript
@@ -7,9 +7,6 @@ sourceopt.removeGenerator = 1
# cat=plugin.sourceopt/enable/50; type=boolean; label=LLL:EXT:sourceopt/Resources/Private/Language/locallang.xlf:sourceopt.removeComments
sourceopt.removeComments = 1
-# cat=plugin.sourceopt/typo/55; type=string; label=LLL:EXT:sourceopt/Resources/Private/Language/locallang.xlf:sourceopt.removeCommentsKeep10
-sourceopt.removeComments.keep.10 = /^TYPO3SEARCH_/usi
-
# cat=plugin.sourceopt/typo/70; type=string; label=LLL:EXT:sourceopt/Resources/Private/Language/locallang.xlf:sourceopt.headerComment
sourceopt.headerComment =
diff --git a/Configuration/TypoScript/setup.typoscript b/Configuration/TypoScript/setup.typoscript
index 3ea2ad4..6b6bc4f 100644
--- a/Configuration/TypoScript/setup.typoscript
+++ b/Configuration/TypoScript/setup.typoscript
@@ -13,6 +13,9 @@ config.sourceopt {
removeGenerator = {$sourceopt.removeGenerator}
removeComments = {$sourceopt.removeComments}
removeComments.keep {
+ # for typo-search
+ 10 = /^TYPO3SEARCH_/usi
+
# TYPO3 specific comment
87 = /This website is powered by TYPO3/usi
@@ -32,9 +35,6 @@ config.sourceopt {
# Google pagespeed
104 = /^gps(e|s)/usi
-
- # for typo-search
- 10 = {$sourceopt.removeComments.keep.10}
}
}
config.svgstore {
diff --git a/README.md b/README.md
index 48b9bd8..db66a45 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@
## Version
-#### >= 5.2.5
+#### >= 5.3
https://github.com/lochmueller/sourceopt/blob/173f7bd2a44b546844961ced1f0831371badd620/composer.json#L8-L9
#### <= 5.2.0 (legacy)
@@ -59,8 +59,8 @@ Note: The following features are executed in reverse order
| sourceopt.removeComments.keep.10 | string | Spare TYPO3SEARCH-Comments from removal | /^TYPO3SEARCH_/usi |
| sourceopt.headerComment | string | Your additional (appended) header comment | `[empty]` |
| sourceopt.formatHtml | integer | Formats the code beautiful and easy readable. New lines and tabs are used in the usual way of illustrating the structure of an XML code. **Options**
https://github.com/lochmueller/sourceopt/blob/2346673ee51d2b64308e1ddb1433cea2f37eafcb/Classes/Service/CleanHtmlService.php#L156-L161 | 4 |
-| sourceopt.formatHtml.tabSize | integer | Defines the size of the tabs used for formating. If blank one tab is used. If a number is specified the specified number of blank spaces is used instead. This will only work together with `formatHtml` | `[empty]` |
-| sourceopt.formatHtml.debugComment | boolean | Includes a comment at the end of the html source code that points the numbers of open html tags. This will only work together with `formatHtml` | `[empty]`
+| sourceopt.formatHtml.tabSize | integer | Defines the amount of spaces used for formating. If blank one tab is used. If a number is specified the specified number of blank spaces is used instead. This will only work together with `formatHtml` | 0 |
+| sourceopt.formatHtml.debugComment | boolean | Includes a comment at the end of the HTML source code that points the numbers of open html tags. This will only work together with `formatHtml` | 0
### RegEx Replace
diff --git a/Resources/Private/Language/locallang.xlf b/Resources/Private/Language/locallang.xlf
index 1d4a212..c28ae89 100644
--- a/Resources/Private/Language/locallang.xlf
+++ b/Resources/Private/Language/locallang.xlf
@@ -43,6 +43,9 @@
Formatting Tab-Size: Spezify number of blank-space for formatting. If empty a tab will be used.
+
+ Formatting `count`: Spezify number of blank-space for indentation. If empty a tab will be used.
+
diff --git a/Tests/UnitTests.xml b/Tests/UnitTests.xml
index 2595430..c971005 100644
--- a/Tests/UnitTests.xml
+++ b/Tests/UnitTests.xml
@@ -12,11 +12,11 @@
stopOnIncomplete="false"
stopOnSkipped="false"
verbose="false"
->
+ >
Unit/
- ./Unit/AbstractUnitTest.php
+ ./Unit/AbstractUnitTest.php
diff --git a/composer.json b/composer.json
index e80e5fe..9202374 100644
--- a/composer.json
+++ b/composer.json
@@ -13,11 +13,6 @@
"HTML\\Sourceopt\\": "Classes/"
}
},
- "replace": {
- "maxserv/replacecontent": "*",
- "typo3-ter/replacecontent": "*",
- "typo3-ter/sourceopt": "self.version"
- },
"require-dev": {
"typo3/testing-framework": "^8.2",
"friendsofphp/php-cs-fixer": "^3.3",
@@ -29,6 +24,15 @@
"TYPO3\\CMS\\Core\\Tests\\": ".Build/vendor/typo3/cms/typo3/sysext/core/Tests/"
}
},
+ "suggest": {
+ "lochmueller/staticfilecache": "Ultra-fast TYPO3 caching via static HTML file delivery",
+ "webcoast/deferred-image-processing": "Faster TYPO3 processing via on-demand image generation"
+ },
+ "replace": {
+ "maxserv/replacecontent": "*",
+ "typo3-ter/replacecontent": "*",
+ "typo3-ter/sourceopt": "self.version"
+ },
"config": {
"vendor-dir": ".Build/vendor",
"bin-dir": ".Build/bin",