Skip to content

Commit

Permalink
Flesh out Transformer\ServerSideRendering
Browse files Browse the repository at this point in the history
  • Loading branch information
schlessera committed Jan 2, 2020
1 parent 95bf0a7 commit 8835c9a
Show file tree
Hide file tree
Showing 14 changed files with 1,656 additions and 1,170 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@
},
"autoload-dev": {
"psr-4": {
"Amp\\AmpWP\\Tests\\": "tests/php/src/"
"Amp\\AmpWP\\Tests\\": "tests/php/src/",
"Amp\\Optimizer\\Tests\\": "tests/php/optimizer/src/"
}
}
}
10 changes: 5 additions & 5 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

92 changes: 92 additions & 0 deletions optimizer/Error/CannotRemoveBoilerplate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php

namespace Amp\Optimizer\Error;

use Amp\Optimizer\Error;
use DOMElement;

final class CannotRemoveBoilerplate implements Error
{

use ErrorProperties;

/**
* Code to use for the error.
*
* @var string
*/
const CODE = 'CANNOT_REMOVE_BOILERPLATE';

const ATTRIBUTES_STRING = 'Cannot remove boilerplate as either heights, media or sizes attribute is set: ';
const RENDER_DELAYING_SCRIPT_STRING = 'Cannot remove boilerplate because the document contains a render-delaying extension: ';
const AMP_AUDIO_STRING = 'Cannot remove boilerplate because the document contains an extension that needs to know the dimensions of the browser: ';
const UNSUPPORTED_LAYOUT_STRING = 'Cannot remove boilerplate because of an unsupported layout: ';

/**
* Instantiate a CannotRemoveBoilerplate object.
*
* @param string $message Message for the error.
*/
public function __construct($message)
{
$this->code = self::CODE;
$this->message = $message;
}

/**
* Instantiate a CannotRemoveBoilerplate object for attributes that require the boilerplate to be around.
*
* @param DOMElement $element Element that contains the attributes that need the boilerplate.
* @return self
*/
public static function from_attributes_requiring_boilerplate(DOMElement $element)
{
return new self(self::ATTRIBUTES_STRING . new ElementDump($element));
}

/**
* Instantiate a CannotRemoveBoilerplate object for an amp-experiment element.
*
* @param DOMElement $element amp-experiment element.
* @return self
*/
public static function from_amp_experiment(DOMElement $element)
{
return new self(self::RENDER_DELAYING_SCRIPT_STRING . $element->tagName);
}

/**
* Instantiate a CannotRemoveBoilerplate object for an amp-audio element.
*
* @param DOMElement $element amp-audio element.
* @return self
*/
public static function from_amp_audio(DOMElement $element)
{
return new self(self::AMP_AUDIO_STRING . new ElementDump($element));
}

/**
* Instantiate a CannotRemoveBoilerplate object for an element with an unsupported layout.
*
* @param DOMElement $element Element with an unsupported layout.
* @return self
*/
public static function from_unsupported_layout(DOMElement $element)
{
return new self(self::UNSUPPORTED_LAYOUT_STRING . new ElementDump($element));
}

/**
* Instantiate a CannotRemoveBoilerplate object for an element with an unsupported layout.
*
* @param DOMElement $element Element with an unsupported layout.
* @return self
*/
public static function from_render_delaying_script(DOMElement $element)
{
$elementName = $element->hasAttribute('custom-element') ? $element->getAttribute('custom-element') : '<unknown>';

return new self(self::UNSUPPORTED_LAYOUT_STRING . $elementName);
}
}
75 changes: 75 additions & 0 deletions optimizer/Error/ElementDump.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

namespace Amp\Optimizer\Error;

use DOMAttr;
use DOMElement;

/**
* Dump an element with its attributes.
*
* This is meant for quick identification of an element and does not dump the child element or other inner content
* from that element.
*/
final class ElementDump
{

/**
* Element to dump.
*
* @var DOMElement
*/
private $element;
/**
*
*
* Defaults to 120.
*
* @var int
*/
private $truncate;

/**
* Instantiate an ElementDump object.
*
* The object is meant to be cast to a string to do its magic.
*
* @param DOMElement $element Element to dump.
* @param int $truncate Optional. Maximum length of the dumped string to truncate to. Defaults to 120.
*/
public function __construct(DOMElement $element, $truncate = 120)
{
$this->element = $element;
$this->truncate = $truncate;
}

/**
* Dump the provided element into a string.
*
* @return string Dump of the element.
*/
public function __toString()
{
static $dump = null;

if ($dump === null) {
$dump = sprintf(
'%s%s',
$this->element->tagName,
array_reduce(
iterator_to_array($this->element->attributes, true),
static function ($text, DOMAttr $attribute) {
return $text . " {$attribute->nodeName}=\"{$attribute->value}\"";
},
''
)
);

if (mb_strlen($dump) > $this->truncate) {
$dump = mb_substr($dump, 0, $this->truncate - 1) . '';
}
}

return (string)$dump;
}
}
113 changes: 58 additions & 55 deletions optimizer/TransformationEngine.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,65 +7,68 @@
final class TransformationEngine
{

/**
* Internal storage for the configuration settings.
*
* @var Configuration
*/
private $configuration;
/**
* Internal storage for the configuration settings.
*
* @var Configuration
*/
private $configuration;

/**
* Instantiate a TransformationEngine object.
*
* @param Configuration $configuration Configuration data to use for setting up the transformers.
*/
public function __construct(Configuration $configuration)
{
$this->configuration = $configuration;
}
/**
* Instantiate a TransformationEngine object.
*
* @param Configuration $configuration Configuration data to use for setting up the transformers.
*/
public function __construct(Configuration $configuration)
{
$this->configuration = $configuration;
}

/**
* Apply transformations to the provided DOM document.
*
* @param Document $document DOM document to apply the transformations to.
* @return void
*/
public function optimizeDom(Document $document)
{
foreach ($this->getTransformers() as $transformer) {
$transformer->transform($document);
}
}
/**
* Apply transformations to the provided DOM document.
*
* @param Document $document DOM document to apply the transformations to.
* @param ErrorCollection $errors Collection of errors that are collected during transformation.
* @return void
*/
public function optimizeDom(Document $document, ErrorCollection $errors)
{
foreach ($this->getTransformers() as $transformer) {
$transformer->transform($document, $errors);
}
}

/**
* Apply transformations to the provided string of HTML markup.
*
* @param string html HTML markup to apply the transformations to.
* @return string Optimized HTML string.
*/
public function optimizeHtml($html)
{
$dom = Document::from_html($html);
$this->optimizeDom($dom);
return $dom->saveHTML();
}
/**
* Apply transformations to the provided string of HTML markup.
*
* @param string $html HTML markup to apply the transformations to.
* @param ErrorCollection $errors Collection of errors that are collected during transformation.
* @return string Optimized HTML string.
*/
public function optimizeHtml($html, ErrorCollection $errors)
{
$dom = Document::from_html($html);
$this->optimizeDom($dom, $errors);

/**
* Get the array of transformers to use.
*
* @return Transformer[] Array of transformers to use.
*/
private function getTransformers()
{
static $transformers = null;
return $dom->saveHTML();
}

if (null === $transformers) {
$transformers = [];
foreach ($this->configuration->get(Configuration::KEY_TRANSFORMERS) as $transformerClass) {
$transformers[$transformerClass] = new $transformerClass();
}
}
/**
* Get the array of transformers to use.
*
* @return Transformer[] Array of transformers to use.
*/
private function getTransformers()
{
static $transformers = null;

return $transformers;
}
if (null === $transformers) {
$transformers = [];
foreach ($this->configuration->get(Configuration::KEY_TRANSFORMERS) as $transformerClass) {
$transformers[$transformerClass] = new $transformerClass();
}
}

return $transformers;
}
}
15 changes: 8 additions & 7 deletions optimizer/Transformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@
interface Transformer
{

/**
* Apply transformations to the provided DOM document.
*
* @param Document $document DOM document to apply the transformations to.
* @return void
*/
public function transform(Document $document);
/**
* Apply transformations to the provided DOM document.
*
* @param Document $document DOM document to apply the transformations to.
* @param ErrorCollection $errors Collection of errors that are collected during transformation.
* @return void
*/
public function transform(Document $document, ErrorCollection $errors);
}
Loading

0 comments on commit 8835c9a

Please sign in to comment.