Skip to content

Commit

Permalink
Merge pull request #251 from ampproject/add/14-minify-html-transformer
Browse files Browse the repository at this point in the history
  • Loading branch information
schlessera committed Jul 1, 2021
2 parents 92fa40b + 0d2ea51 commit ce85ecc
Show file tree
Hide file tree
Showing 8 changed files with 717 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/Dom/Document.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ final class Document extends DOMDocument

// Regex patterns used for securing and restoring the doctype node.
const HTML_SECURE_DOCTYPE_IF_NOT_FIRST_PATTERN = '/(^[^<]*(?>\s*<!--[^>]*>\s*)+<)(!)(doctype)(\s+[^>]+?)(>)/i';
const HTML_RESTORE_DOCTYPE_PATTERN = '/(^[^<]*(?>\s*<!--[^>]*>\s*)+<)'
const HTML_RESTORE_DOCTYPE_PATTERN = '/(^[^<]*(?>\s*<!--[^>]*>\s*)*<)'
. '(!--amp-)(doctype)(\s+[^>]+?)(-->)/i';

// Regex pattern used for removing Internet Explorer conditional comments.
Expand Down
141 changes: 141 additions & 0 deletions src/Optimizer/Configuration/MinifyHtmlConfiguration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
<?php

namespace AmpProject\Optimizer\Configuration;

use AmpProject\Optimizer\Exception\InvalidConfigurationValue;
use InvalidArgumentException;

/**
* Configuration for the MinifyHtml transformer.
*
* @property bool $minify Whether minification is enabled.
* @property bool $minifyAmpScript Whether amp-script minification is enabled.
* @property bool $minifyJSON Whether JSON data minification is enabled.
* @property bool $collapseWhitespace Whether collapsing whitespace is enabled.
* @property bool $removeComments Whether comments should be removed.
* @property bool $canCollapseWhitespace Whether whitespace can be collapsed.
* @property bool $inBody Whether the node is in the body.
* @property string $commentIgnorePattern Regex pattern of comments to keep.
*
* @package ampproject/amp-toolbox
*/
final class MinifyHtmlConfiguration extends BaseTransformerConfiguration
{

/**
* Whether minification is enabled.
*
* @var bool
*/
const MINIFY = 'minify';

/**
* Whether amp-script minification is enabled.
*
* @var bool
*/
const MINIFY_AMP_SCRIPT = 'minifyAmpScript';

/**
* Whether JSON data minification is enabled.
*
* @var bool
*/
const MINIFY_JSON = 'minifyJSON';

/**
* Whether collapsing whitespace is enabled.
*
* @var bool
*/
const COLLAPSE_WHITESPACE = 'collapseWhitespace';

/**
* Whether comments should be removed.
*
* @var bool
*/
const REMOVE_COMMENTS = 'removeComments';

/**
* Regular expression pattern of comments to keep.
*
* @var string
*/
const COMMENT_IGNORE_PATTERN = 'commentIgnorePattern';

/**
* Get the associative array of allowed keys and their respective default values.
*
* The array index is the key and the array value is the key's default value.
*
* @return array Associative array of allowed keys and their respective default values.
*/
protected function getAllowedKeys()
{
return [
self::MINIFY => true,
self::MINIFY_AMP_SCRIPT => false,
self::MINIFY_JSON => true,
self::COLLAPSE_WHITESPACE => true,
self::REMOVE_COMMENTS => true,
self::COMMENT_IGNORE_PATTERN => '',
];
}

/**
* Validate an individual configuration entry.
*
* @param string $key Key of the configuration entry to validate.
* @param mixed $value Value of the configuration entry to validate.
* @return mixed Validated value.
*/
protected function validate($key, $value)
{
switch ($key) {
case self::MINIFY:
case self::MINIFY_JSON:
case self::COLLAPSE_WHITESPACE:
case self::REMOVE_COMMENTS:
if (! is_bool($value)) {
throw InvalidConfigurationValue::forInvalidSubValueType(
self::class,
$key,
'boolean',
is_object($value) ? get_class($value) : gettype($value)
);
}
break;

case self::MINIFY_AMP_SCRIPT:
if (! is_bool($value)) {
throw InvalidConfigurationValue::forInvalidSubValueType(
self::class,
$key,
'boolean',
is_object($value) ? get_class($value) : gettype($value)
);
}

if ($value) {
$message = 'Script minification feature is not implemented yet.';
throw new InvalidArgumentException($message);
}
break;

case self::COMMENT_IGNORE_PATTERN:
if (! is_string($value)) {
throw InvalidConfigurationValue::forInvalidSubValueType(
self::class,
self::COMMENT_IGNORE_PATTERN,
'string',
is_object($value) ? get_class($value) : gettype($value)
);
}
$value = trim($value);
break;
}

return $value;
}
}
3 changes: 3 additions & 0 deletions src/Optimizer/DefaultConfiguration.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace AmpProject\Optimizer;

use AmpProject\Optimizer\Configuration\AmpRuntimeCssConfiguration;
use AmpProject\Optimizer\Configuration\MinifyHtmlConfiguration;
use AmpProject\Optimizer\Configuration\OptimizeAmpBindConfiguration;
use AmpProject\Optimizer\Configuration\OptimizeHeroImagesConfiguration;
use AmpProject\Optimizer\Configuration\PreloadHeroImageConfiguration;
Expand All @@ -12,6 +13,7 @@
use AmpProject\Optimizer\Exception\UnknownConfigurationClass;
use AmpProject\Optimizer\Exception\UnknownConfigurationKey;
use AmpProject\Optimizer\Transformer\AmpRuntimeCss;
use AmpProject\Optimizer\Transformer\MinifyHtml;
use AmpProject\Optimizer\Transformer\OptimizeAmpBind;
use AmpProject\Optimizer\Transformer\OptimizeHeroImages;
use AmpProject\Optimizer\Transformer\PreloadHeroImage;
Expand Down Expand Up @@ -49,6 +51,7 @@ class DefaultConfiguration implements Configuration
PreloadHeroImage::class => PreloadHeroImageConfiguration::class,
RewriteAmpUrls::class => RewriteAmpUrlsConfiguration::class,
TransformedIdentifier::class => TransformedIdentifierConfiguration::class,
MinifyHtml::class => MinifyHtmlConfiguration::class,
];

/**
Expand Down
37 changes: 37 additions & 0 deletions src/Optimizer/Error/InvalidJson.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace AmpProject\Optimizer\Error;

use AmpProject\Optimizer\Error;

/**
* Optimizer error object for invalid JSON data.
*
* @package ampproject/amp-toolbox
*/
final class InvalidJson implements Error
{
use ErrorProperties;

/**
* Instantiate an InvalidJson object after decoding JSON data.
*
* @return self
*/
public static function fromLastErrorMsgAfterDecoding()
{
$errorMsg = 'Error decoding JSON: ' . json_last_error_msg();
return new self($errorMsg);
}

/**
* Instantiate an InvalidJson object after encoding JSON data.
*
* @return self
*/
public static function fromLastErrorMsgAfterEncoding()
{
$errorMsg = 'Error encoding JSON: ' . json_last_error_msg();
return new self($errorMsg);
}
}
Loading

0 comments on commit ce85ecc

Please sign in to comment.