From 891a727806853b47a472668be47ebcab4a34a746 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy Date: Wed, 12 Jun 2019 14:10:51 -0500 Subject: [PATCH 1/3] MC-17449: Deliver CSS critical path and font display swap to 2.2.x --- .../Theme/Block/Html/Header/CriticalCss.php | 58 ++++++++++++++ .../Controller/Result/AsyncCssPlugin.php | 79 +++++++++++++++++++ .../Magento/Theme/etc/adminhtml/system.xml | 20 +++++ app/code/Magento/Theme/etc/config.xml | 3 + app/code/Magento/Theme/etc/frontend/di.xml | 8 ++ .../Theme/view/frontend/layout/default.xml | 4 +- .../frontend/layout/default_head_blocks.xml | 8 ++ .../Theme/view/frontend/requirejs-config.js | 3 +- .../templates/html/header/criticalCss.phtml | 15 ++++ .../templates/html/main_css_preloader.phtml | 13 +++ .../templates/js/css_rel_preload.phtml | 10 +++ .../layout/default_head_blocks.xml | 5 ++ .../blank/web/css/source/_loaders.less | 4 + .../blank/web/css/source/_typography.less | 12 ++- .../Magento/luma/web/css/critical.css | 1 + .../Framework/View/Asset/MergeService.php | 17 +++- .../Framework/View/Layout/etc/head.xsd | 1 + .../View/Page/Config/Reader/Head.php | 5 ++ .../Framework/View/Page/Config/Renderer.php | 39 ++++++++- lib/web/css/source/lib/_typography.less | 24 +++++- 20 files changed, 319 insertions(+), 10 deletions(-) create mode 100644 app/code/Magento/Theme/Block/Html/Header/CriticalCss.php create mode 100644 app/code/Magento/Theme/Controller/Result/AsyncCssPlugin.php create mode 100644 app/code/Magento/Theme/etc/adminhtml/system.xml create mode 100644 app/code/Magento/Theme/view/frontend/templates/html/header/criticalCss.phtml create mode 100644 app/code/Magento/Theme/view/frontend/templates/html/main_css_preloader.phtml create mode 100644 app/code/Magento/Theme/view/frontend/templates/js/css_rel_preload.phtml create mode 100644 app/design/frontend/Magento/luma/web/css/critical.css diff --git a/app/code/Magento/Theme/Block/Html/Header/CriticalCss.php b/app/code/Magento/Theme/Block/Html/Header/CriticalCss.php new file mode 100644 index 0000000000000..6ac1ba344469c --- /dev/null +++ b/app/code/Magento/Theme/Block/Html/Header/CriticalCss.php @@ -0,0 +1,58 @@ +assetRepo = $assetRepo; + $this->filePath = $filePath; + } + + /** + * Returns critical css data as string. + * + * @return bool|string + */ + public function getCriticalCssData() + { + try { + $asset = $this->assetRepo->createAsset($this->filePath, ['_secure' => 'false']); + $content = $asset->getContent(); + } catch (NotFoundException $e) { + $content = ''; + } + + return $content; + } +} diff --git a/app/code/Magento/Theme/Controller/Result/AsyncCssPlugin.php b/app/code/Magento/Theme/Controller/Result/AsyncCssPlugin.php new file mode 100644 index 0000000000000..3ad9408306892 --- /dev/null +++ b/app/code/Magento/Theme/Controller/Result/AsyncCssPlugin.php @@ -0,0 +1,79 @@ +scopeConfig = $scopeConfig; + } + + /** + * Load CSS asynchronously if it is enabled in configuration. + * + * @param Http $subject + * @return void + */ + public function beforeSendResponse(Http $subject): void + { + $content = $subject->getContent(); + + if (strpos($content, 'scopeConfig->isSetFlag( + self::XML_PATH_USE_CSS_CRITICAL_PATH, + ScopeInterface::SCOPE_STORE + )) { + $cssMatches = []; + // add link rel preload to style sheets + $content = preg_replace_callback( + '@@', + function ($matches) use (&$cssMatches) { + $cssMatches[] = $matches[0]; + preg_match('@href=("|\')(.*?)\1@', $matches[0], $hrefAttribute); + $href = $hrefAttribute[2]; + if (preg_match('@media=("|\')(.*?)\1@', $matches[0], $mediaAttribute)) { + $media = $mediaAttribute[2]; + } + $media = $media ?? 'all'; + $loadCssAsync = sprintf( + '', + $media, + $href + ); + + return $loadCssAsync; + }, + $content + ); + + if (!empty($cssMatches)) { + $content = str_replace('setContent($content); + } + } + } +} diff --git a/app/code/Magento/Theme/etc/adminhtml/system.xml b/app/code/Magento/Theme/etc/adminhtml/system.xml new file mode 100644 index 0000000000000..c581e09fe1e25 --- /dev/null +++ b/app/code/Magento/Theme/etc/adminhtml/system.xml @@ -0,0 +1,20 @@ + + + + +
+ + + + Magento\Config\Model\Config\Source\Yesno + CSS files are loading synchronously by default. + + +
+
+
diff --git a/app/code/Magento/Theme/etc/config.xml b/app/code/Magento/Theme/etc/config.xml index b44691c0df963..40064acdf1f43 100644 --- a/app/code/Magento/Theme/etc/config.xml +++ b/app/code/Magento/Theme/etc/config.xml @@ -66,6 +66,9 @@ Disallow: /*SID= 1 + + 0 + diff --git a/app/code/Magento/Theme/etc/frontend/di.xml b/app/code/Magento/Theme/etc/frontend/di.xml index 7db2783cd8dfa..41b0032e1fffc 100644 --- a/app/code/Magento/Theme/etc/frontend/di.xml +++ b/app/code/Magento/Theme/etc/frontend/di.xml @@ -26,4 +26,12 @@ + + + + + + css/critical.css + + diff --git a/app/code/Magento/Theme/view/frontend/layout/default.xml b/app/code/Magento/Theme/view/frontend/layout/default.xml index c84222be19c3c..4da46ec41da54 100644 --- a/app/code/Magento/Theme/view/frontend/layout/default.xml +++ b/app/code/Magento/Theme/view/frontend/layout/default.xml @@ -102,7 +102,9 @@ - + + + diff --git a/app/code/Magento/Theme/view/frontend/layout/default_head_blocks.xml b/app/code/Magento/Theme/view/frontend/layout/default_head_blocks.xml index 38ab9c29402e9..6a1e655786098 100644 --- a/app/code/Magento/Theme/view/frontend/layout/default_head_blocks.xml +++ b/app/code/Magento/Theme/view/frontend/layout/default_head_blocks.xml @@ -12,6 +12,14 @@ diff --git a/app/design/frontend/Magento/blank/Magento_Theme/layout/default_head_blocks.xml b/app/design/frontend/Magento/blank/Magento_Theme/layout/default_head_blocks.xml index eb1c8befb3a48..3c9f6036d0dbe 100644 --- a/app/design/frontend/Magento/blank/Magento_Theme/layout/default_head_blocks.xml +++ b/app/design/frontend/Magento/blank/Magento_Theme/layout/default_head_blocks.xml @@ -10,6 +10,11 @@ + + + + + diff --git a/app/design/frontend/Magento/blank/web/css/source/_loaders.less b/app/design/frontend/Magento/blank/web/css/source/_loaders.less index 5fcba9653ef01..ed062c382442a 100644 --- a/app/design/frontend/Magento/blank/web/css/source/_loaders.less +++ b/app/design/frontend/Magento/blank/web/css/source/_loaders.less @@ -42,4 +42,8 @@ ._block-content-loading { position: relative; } + + [data-role='main-css-loader'] { + display: none; + } } diff --git a/app/design/frontend/Magento/blank/web/css/source/_typography.less b/app/design/frontend/Magento/blank/web/css/source/_typography.less index 8ce76fad97902..6807c0f692af8 100644 --- a/app/design/frontend/Magento/blank/web/css/source/_typography.less +++ b/app/design/frontend/Magento/blank/web/css/source/_typography.less @@ -12,28 +12,32 @@ @family-name: @font-family-name__base, @font-path: '@{baseDir}fonts/opensans/light/opensans-300', @font-weight: 300, - @font-style: normal + @font-style: normal, + @font-display: swap ); .lib-font-face( @family-name: @font-family-name__base, @font-path: '@{baseDir}fonts/opensans/regular/opensans-400', @font-weight: 400, - @font-style: normal + @font-style: normal, + @font-display: swap ); .lib-font-face( @family-name: @font-family-name__base, @font-path: '@{baseDir}fonts/opensans/semibold/opensans-600', @font-weight: 600, - @font-style: normal + @font-style: normal, + @font-display: swap ); .lib-font-face( @family-name: @font-family-name__base, @font-path: '@{baseDir}fonts/opensans/bold/opensans-700', @font-weight: 700, - @font-style: normal + @font-style: normal, + @font-display: swap ); } diff --git a/app/design/frontend/Magento/luma/web/css/critical.css b/app/design/frontend/Magento/luma/web/css/critical.css new file mode 100644 index 0000000000000..922a1eefa89e8 --- /dev/null +++ b/app/design/frontend/Magento/luma/web/css/critical.css @@ -0,0 +1 @@ +body{margin:0}.page-main{flex-grow:1}.product-image-wrapper{display:block;height:0;overflow:hidden;position:relative;z-index:1}.product-image-wrapper .product-image-photo{bottom:0;display:block;height:auto;left:0;margin:auto;max-width:100%;position:absolute;right:0;top:0}.product-image-container{display:inline-block}.modal-popup{position:fixed}.page-wrapper{display:flex;flex-direction:column;min-height:100vh}.action.skip:not(:focus),.block.newsletter .label,.minicart-wrapper .action.showcart .counter-label,.minicart-wrapper .action.showcart .text,.page-header .switcher .label,.product-item-actions .actions-secondary>.action span{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.alink,a{color:#006bb4;text-decoration:none}.page-header .panel.wrapper{background-color:#6e716e;color:#fff}.header.panel>.header.links{list-style:none none;float:right;font-size:0;margin-right:20px}.header.panel>.header.links>li{font-size:14px;margin:0 0 0 15px}.block-search .action.search,.block-search .block-title,.block-search .nested,.block.newsletter .title,.breadcrumbs .item,.nav-toggle,.no-display,.page-footer .switcher .options ul.dropdown,.page-header .switcher .options ul.dropdown{display:none}.block-search .label>span{height:1px;overflow:hidden;position:absolute}.logo{float:left;margin:0 0 10px 40px}.minicart-wrapper{float:right}.page-footer{margin-top:25px}.footer.content{border-top:1px solid #cecece;padding-top:20px}.block.newsletter .actions{display:table-cell;vertical-align:top;width:1%}.block-banners .banner-items,.block-banners-inline .banner-items,.block-event .slider-panel .slider,.footer.content ul,.product-items{margin:0;padding:0;list-style:none none}.copyright{background-color:#6e716e;color:#fff;box-sizing:border-box;display:block;padding:10px;text-align:center}.modal-popup,.modal-slide{visibility:hidden;opacity:0}input[type=email],input[type=number],input[type=password],input[type=search],input[type=text],input[type=url]{background:#fff;background-clip:padding-box;border:1px solid #c2c2c2;border-radius:1px;font-size:14px;height:32px;line-height:1.42857143;padding:0 9px;vertical-align:baseline;width:100%;box-sizing:border-box}.action.primary{background:#1979c3;border:1px solid #1979c3;color:#fff;font-weight:600;padding:7px 15px}.block.newsletter .form.subscribe{display:table}.footer.content .links a{color:#575757}.load.indicator{background-color:rgba(255,255,255,.7);z-index:9999;bottom:0;left:0;position:fixed;right:0;top:0;position:absolute}.load.indicator:before{background:transparent url(../images/loader-2.gif) no-repeat 50% 50%;border-radius:5px;height:160px;width:160px;bottom:0;box-sizing:border-box;content:'';left:0;margin:auto;position:absolute;right:0;top:0}.load.indicator>span{display:none}.loading-mask{bottom:0;left:0;margin:auto;position:fixed;right:0;top:0;z-index:100;background:rgba(255,255,255,.5)}.loading-mask .loader>img{bottom:0;left:0;margin:auto;position:fixed;right:0;top:0;z-index:100}.loading-mask .loader>p{display:none}body>.loading-mask{z-index:9999}._block-content-loading{position:relative}@media (min-width:768px),print{body,html{height:100%}.page-header{border:0;margin-bottom:0}.nav-sections-item-title,.section-item-content .switcher-currency,ul.header.links li.customer-welcome,ul.level0.submenu{display:none}.abs-add-clearfix-desktop:after,.abs-add-clearfix-desktop:before,.account .column.main .block.block-order-details-view:after,.account .column.main .block.block-order-details-view:before,.account .column.main .block:not(.widget) .block-content:after,.account .column.main .block:not(.widget) .block-content:before,.account .page-title-wrapper:after,.account .page-title-wrapper:before,.block-addresses-list .items.addresses:after,.block-addresses-list .items.addresses:before,.block-cart-failed .block-content:after,.block-cart-failed .block-content:before,.block-giftregistry-shared .item-options:after,.block-giftregistry-shared .item-options:before,.block-wishlist-management:after,.block-wishlist-management:before,.cart-container:after,.cart-container:before,.data.table .gift-wrapping .content:after,.data.table .gift-wrapping .content:before,.data.table .gift-wrapping .nested:after,.data.table .gift-wrapping .nested:before,.header.content:after,.header.content:before,.login-container:after,.login-container:before,.magento-rma-guest-returns .column.main .block.block-order-details-view:after,.magento-rma-guest-returns .column.main .block.block-order-details-view:before,.order-links:after,.order-links:before,.order-review-form:after,.order-review-form:before,.page-header .header.panel:after,.page-header .header.panel:before,.paypal-review .block-content:after,.paypal-review .block-content:before,.paypal-review-discount:after,.paypal-review-discount:before,.sales-guest-view .column.main .block.block-order-details-view:after,.sales-guest-view .column.main .block.block-order-details-view:before,[class^=sales-guest-] .column.main .block.block-order-details-view:after,[class^=sales-guest-] .column.main .block.block-order-details-view:before{content:'';display:table}.abs-add-clearfix-desktop:after,.account .column.main .block.block-order-details-view:after,.account .column.main .block:not(.widget) .block-content:after,.account .page-title-wrapper:after,.block-addresses-list .items.addresses:after,.block-cart-failed .block-content:after,.block-giftregistry-shared .item-options:after,.block-wishlist-management:after,.cart-container:after,.data.table .gift-wrapping .content:after,.data.table .gift-wrapping .nested:after,.header.content:after,.login-container:after,.magento-rma-guest-returns .column.main .block.block-order-details-view:after,.order-links:after,.order-review-form:after,.page-header .header.panel:after,.paypal-review .block-content:after,.paypal-review-discount:after,.sales-guest-view .column.main .block.block-order-details-view:after,[class^=sales-guest-] .column.main .block.block-order-details-view:after{clear:both}.block.category.event,.breadcrumbs,.footer.content,.header.content,.navigation,.page-header .header.panel,.page-main,.page-wrapper>.page-bottom,.page-wrapper>.widget,.top-container{box-sizing:border-box;margin-left:auto;margin-right:auto;max-width:1280px;padding-left:20px;padding-right:20px;width:auto}.panel.header{padding:10px 20px}.page-header .switcher{float:right;margin-left:15px;margin-right:-6px}.header.panel>.header.links>li>a{color:#fff}.header.content{padding:30px 20px 0}.logo{margin:-8px auto 25px 0}.minicart-wrapper{margin-left:13px}.compare.wrapper{list-style:none none}.nav-sections{margin-bottom:25px}.nav-sections-item-content>.navigation{display:block}.navigation{background:#f0f0f0;font-weight:700;height:inherit;left:auto;overflow:inherit;padding:0;position:relative;top:0;width:100%;z-index:3}.navigation ul{margin-top:0;margin-bottom:0;padding:0 8px;position:relative}.navigation .level0{margin:0 10px 0 0;display:inline-block}.navigation .level0>.level-top{color:#575757;line-height:47px;padding:0 12px}.page-main{width:100%}.page-footer{background:#f4f4f4;padding-bottom:25px}.footer.content .links{display:inline-block;padding-right:50px;vertical-align:top}.footer.content ul{padding-right:50px}.footer.content .links li{border:none;font-size:14px;margin:0 0 8px;padding:0}.footer.content .block{float:right}.block.newsletter{width:34%}}@media only screen and (max-width:767px){.compare.wrapper,.panel.wrapper,[class*=block-compare]{display:none}.footer.content .links>li{background:#f4f4f4;font-size:1.6rem;border-top:1px solid #cecece;margin:0 -15px;padding:0 15px}.page-header .header.panel,.page-main{padding-left:15px;padding-right:15px}.header.content{padding-top:10px}.nav-sections-items:after,.nav-sections-items:before{content:'';display:table}.nav-sections-items:after{clear:both}.nav-sections{width:100vw;position:fixed;left:-100vw}} diff --git a/lib/internal/Magento/Framework/View/Asset/MergeService.php b/lib/internal/Magento/Framework/View/Asset/MergeService.php index a5820a6d7651b..9cb1026df5c74 100644 --- a/lib/internal/Magento/Framework/View/Asset/MergeService.php +++ b/lib/internal/Magento/Framework/View/Asset/MergeService.php @@ -40,6 +40,21 @@ class MergeService */ protected $state; + /** + * List of supported types that can be processed by merge service + * + * @var array + */ + private $supportedMergeType = [ + 'css', + 'js', + 'eot', + 'svg', + 'ttf', + 'woff', + 'woff2', + ]; + /** * Constructor * @@ -72,7 +87,7 @@ public function getMergedAssets(array $assets, $contentType) { $isCss = $contentType == 'css'; $isJs = $contentType == 'js'; - if (!$isCss && !$isJs) { + if (!\in_array($contentType, $this->supportedMergeType, true)) { throw new \InvalidArgumentException("Merge for content type '{$contentType}' is not supported."); } diff --git a/lib/internal/Magento/Framework/View/Layout/etc/head.xsd b/lib/internal/Magento/Framework/View/Layout/etc/head.xsd index 15762dc2f0ae6..51acc5789a4f8 100644 --- a/lib/internal/Magento/Framework/View/Layout/etc/head.xsd +++ b/lib/internal/Magento/Framework/View/Layout/etc/head.xsd @@ -67,6 +67,7 @@ + diff --git a/lib/internal/Magento/Framework/View/Page/Config/Reader/Head.php b/lib/internal/Magento/Framework/View/Page/Config/Reader/Head.php index 510da2b1b1ca9..3b8de974b2a26 100644 --- a/lib/internal/Magento/Framework/View/Page/Config/Reader/Head.php +++ b/lib/internal/Magento/Framework/View/Page/Config/Reader/Head.php @@ -17,6 +17,7 @@ class Head implements Layout\ReaderInterface * Supported types */ const TYPE_HEAD = 'head'; + const HEAD_FONT = 'font'; /**#@-*/ /**#@+ @@ -56,6 +57,9 @@ protected function addContentTypeByNodeName(Layout\Element $node) case self::HEAD_SCRIPT: $node->addAttribute('content_type', 'js'); break; + case self::HEAD_FONT: + $node->addAttribute('content_type', 'font'); + break; } } @@ -85,6 +89,7 @@ function (Layout\Element $current, Layout\Element $next) { case self::HEAD_CSS: case self::HEAD_SCRIPT: case self::HEAD_LINK: + case self::HEAD_FONT: $this->addContentTypeByNodeName($node); $pageConfigStructure->addAssets($node->getAttribute('src'), $this->getAttributes($node)); break; diff --git a/lib/internal/Magento/Framework/View/Page/Config/Renderer.php b/lib/internal/Magento/Framework/View/Page/Config/Renderer.php index 183f8d34ee41f..77808b732219c 100644 --- a/lib/internal/Magento/Framework/View/Page/Config/Renderer.php +++ b/lib/internal/Magento/Framework/View/Page/Config/Renderer.php @@ -20,7 +20,29 @@ class Renderer implements RendererInterface /** * @var array */ - protected $assetTypeOrder = ['css', 'ico', 'js']; + protected $assetTypeOrder = [ + 'css', + 'ico', + 'js', + 'eot', + 'svg', + 'ttf', + 'woff', + 'woff2', + ]; + + /** + * Possible fonts type + * + * @var array + */ + const FONTS_TYPE = [ + 'eot', + 'svg', + 'ttf', + 'woff', + 'woff2', + ]; /** * @var Config @@ -315,10 +337,25 @@ protected function addDefaultAttributes($contentType, $attributes) case 'css': $attributes = ' rel="stylesheet" type="text/css" ' . ($attributes ?: ' media="all"'); break; + + case $this->canTypeBeFont($contentType): + $attributes = 'rel="preload" as="font" crossorigin="anonymous"'; + break; } return $attributes; } + /** + * Check if file type can be font + * + * @param string $type + * @return bool + */ + private function canTypeBeFont(string $type): bool + { + return \in_array($type, self::FONTS_TYPE, true); + } + /** * @param string $contentType * @param string|null $attributes diff --git a/lib/web/css/source/lib/_typography.less b/lib/web/css/source/lib/_typography.less index 62529fe08d1c8..db4eaaf584f4a 100644 --- a/lib/web/css/source/lib/_typography.less +++ b/lib/web/css/source/lib/_typography.less @@ -10,15 +10,35 @@ .lib-font-face( @family-name, @font-path, + @font-format: false, @font-weight: normal, - @font-style: normal -) { + @font-style: normal, + @font-display: auto +) when (@font-format = false) { @font-face { font-family: @family-name; src: url('@{font-path}.woff2') format('woff2'), url('@{font-path}.woff') format('woff'); font-weight: @font-weight; font-style: @font-style; + font-display: @font-display; + } +} + +.lib-font-face( + @family-name, + @font-path, + @font-format: false, + @font-weight: normal, + @font-style: normal, + @font-display: auto +) when not (@font-format = false) { + @font-face { + font-family: @family-name; + src: url('@{font-path}.@{font-format}') format(@font-format); + font-weight: @font-weight; + font-style: @font-style; + font-display: @font-display; } } From b722fca9aa4c91d72a35bee579b9aae917d18763 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy Date: Thu, 13 Jun 2019 10:06:07 -0500 Subject: [PATCH 2/3] MC-17449: Deliver CSS critical path to 2.2.x - Remove void return type; - Fix cyclomatic complexity; --- .../Controller/Result/AsyncCssPlugin.php | 2 +- .../View/Page/Config/Reader/Head.php | 77 +++++++++++-------- 2 files changed, 46 insertions(+), 33 deletions(-) diff --git a/app/code/Magento/Theme/Controller/Result/AsyncCssPlugin.php b/app/code/Magento/Theme/Controller/Result/AsyncCssPlugin.php index 3ad9408306892..ddddb2002ec4f 100644 --- a/app/code/Magento/Theme/Controller/Result/AsyncCssPlugin.php +++ b/app/code/Magento/Theme/Controller/Result/AsyncCssPlugin.php @@ -37,7 +37,7 @@ public function __construct(ScopeConfigInterface $scopeConfig) * @param Http $subject * @return void */ - public function beforeSendResponse(Http $subject): void + public function beforeSendResponse(Http $subject) { $content = $subject->getContent(); diff --git a/lib/internal/Magento/Framework/View/Page/Config/Reader/Head.php b/lib/internal/Magento/Framework/View/Page/Config/Reader/Head.php index 3b8de974b2a26..e8c4f345625de 100644 --- a/lib/internal/Magento/Framework/View/Page/Config/Reader/Head.php +++ b/lib/internal/Magento/Framework/View/Page/Config/Reader/Head.php @@ -7,6 +7,7 @@ use Magento\Framework\View\Layout; use Magento\Framework\View\Page\Config as PageConfig; +use Magento\Framework\View\Page\Config\Structure; /** * Head structure reader is intended for collecting assets, title and metadata @@ -85,43 +86,55 @@ function (Layout\Element $current, Layout\Element $next) { ); foreach ($nodes as $node) { - switch ($node->getName()) { - case self::HEAD_CSS: - case self::HEAD_SCRIPT: - case self::HEAD_LINK: - case self::HEAD_FONT: - $this->addContentTypeByNodeName($node); - $pageConfigStructure->addAssets($node->getAttribute('src'), $this->getAttributes($node)); - break; - - case self::HEAD_REMOVE: - $pageConfigStructure->removeAssets($node->getAttribute('src')); - break; - - case self::HEAD_TITLE: - $pageConfigStructure->setTitle(new \Magento\Framework\Phrase($node)); - break; - - case self::HEAD_META: - $this->setMetadata($pageConfigStructure, $node); - break; - - case self::HEAD_ATTRIBUTE: - $pageConfigStructure->setElementAttribute( - PageConfig::ELEMENT_TYPE_HEAD, - $node->getAttribute('name'), - $node->getAttribute('value') - ); - break; - - default: - break; - } + $this->processNode($node, $pageConfigStructure); } return $this; } + /** + * Process given node based on it's name. + * + * @param Layout\Element $node + * @param Structure $pageConfigStructure + * @return void + */ + private function processNode(Layout\Element $node, Structure $pageConfigStructure) + { + switch ($node->getName()) { + case self::HEAD_CSS: + case self::HEAD_SCRIPT: + case self::HEAD_LINK: + case self::HEAD_FONT: + $this->addContentTypeByNodeName($node); + $pageConfigStructure->addAssets($node->getAttribute('src'), $this->getAttributes($node)); + break; + + case self::HEAD_REMOVE: + $pageConfigStructure->removeAssets($node->getAttribute('src')); + break; + + case self::HEAD_TITLE: + $pageConfigStructure->setTitle(new \Magento\Framework\Phrase($node)); + break; + + case self::HEAD_META: + $this->setMetadata($pageConfigStructure, $node); + break; + + case self::HEAD_ATTRIBUTE: + $pageConfigStructure->setElementAttribute( + PageConfig::ELEMENT_TYPE_HEAD, + $node->getAttribute('name'), + $node->getAttribute('value') + ); + break; + + default: + break; + } + } + /** * Get all attributes for current dom element * From 764c5775afc2256668d4bba5ffdad011c6b23f6e Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy Date: Thu, 13 Jun 2019 17:24:08 -0500 Subject: [PATCH 3/3] MC-17449: Deliver CSS critical path to 2.2.x - Update async css plugin; --- app/code/Magento/Theme/Controller/Result/AsyncCssPlugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Theme/Controller/Result/AsyncCssPlugin.php b/app/code/Magento/Theme/Controller/Result/AsyncCssPlugin.php index ddddb2002ec4f..d15e5e69b1759 100644 --- a/app/code/Magento/Theme/Controller/Result/AsyncCssPlugin.php +++ b/app/code/Magento/Theme/Controller/Result/AsyncCssPlugin.php @@ -41,7 +41,7 @@ public function beforeSendResponse(Http $subject) { $content = $subject->getContent(); - if (strpos($content, 'scopeConfig->isSetFlag( + if (\is_string($content) && strpos($content, 'scopeConfig->isSetFlag( self::XML_PATH_USE_CSS_CRITICAL_PATH, ScopeInterface::SCOPE_STORE )) {