From cf1e82af24e8c441a35c5e39687c9e146d69e7dc Mon Sep 17 00:00:00 2001 From: Alain Schlesser Date: Fri, 29 May 2020 09:39:43 +0200 Subject: [PATCH 01/18] Update spec test suite and local fallbacks --- .../resources/local_fallback/rtv/metadata | 2 +- lib/optimizer/resources/local_fallback/v0.css | 2 +- ...alid.html => expected_output.default.html} | 0 .../body-only/expected_output.lts.html | 17 ++ ...utput.html => expected_output.paired.html} | 0 ...alid.html => expected_output.default.html} | 0 .../hello-world/expected_output.lts.html | 25 ++ ...utput.html => expected_output.paired.html} | 0 ...alid.html => expected_output.default.html} | 0 .../markdown/expected_output.lts.html | 261 ++++++++++++++++++ ...utput.html => expected_output.paired.html} | 0 .../adds_srcset/expected_output.html | 13 + .../OptimizeImages/adds_srcset/input.html | 13 + .../expected_output.html | 14 + .../ignores_data_uris_amp-iframe/input.html | 13 + .../expected_output.html | 10 + .../ignores_data_uris_amp-img/input.html | 9 + .../expected_output.html | 14 + .../ignores_data_uris_amp-video/input.html | 13 + .../expected_output.html | 10 + .../ignores_tiny_images_intrinsic/input.html | 9 + .../expected_output.html | 10 + .../ignores_tiny_images_responsive/input.html | 9 + .../expected_output.html | 20 -- .../expected_output.html | 19 ++ .../input.html | 22 +- .../expected_output.html | 30 ++ .../input.html | 31 +++ .../expected_output.html | 24 ++ .../input.html | 21 +- .../expected_output.html | 20 -- 31 files changed, 567 insertions(+), 64 deletions(-) rename lib/optimizer/tests/spec/end-to-end/body-only/{expected_output.valid.html => expected_output.default.html} (100%) create mode 100644 lib/optimizer/tests/spec/end-to-end/body-only/expected_output.lts.html rename lib/optimizer/tests/spec/end-to-end/body-only/{expected_output.html => expected_output.paired.html} (100%) rename lib/optimizer/tests/spec/end-to-end/hello-world/{expected_output.valid.html => expected_output.default.html} (100%) create mode 100644 lib/optimizer/tests/spec/end-to-end/hello-world/expected_output.lts.html rename lib/optimizer/tests/spec/end-to-end/hello-world/{expected_output.html => expected_output.paired.html} (100%) rename lib/optimizer/tests/spec/end-to-end/markdown/{expected_output.valid.html => expected_output.default.html} (100%) create mode 100644 lib/optimizer/tests/spec/end-to-end/markdown/expected_output.lts.html rename lib/optimizer/tests/spec/end-to-end/markdown/{expected_output.html => expected_output.paired.html} (100%) create mode 100644 lib/optimizer/tests/spec/transformers/valid/OptimizeImages/adds_srcset/expected_output.html create mode 100644 lib/optimizer/tests/spec/transformers/valid/OptimizeImages/adds_srcset/input.html create mode 100644 lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_data_uris_amp-iframe/expected_output.html create mode 100644 lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_data_uris_amp-iframe/input.html create mode 100644 lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_data_uris_amp-img/expected_output.html create mode 100644 lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_data_uris_amp-img/input.html create mode 100644 lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_data_uris_amp-video/expected_output.html create mode 100644 lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_data_uris_amp-video/input.html create mode 100644 lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_tiny_images_intrinsic/expected_output.html create mode 100644 lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_tiny_images_intrinsic/input.html create mode 100644 lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_tiny_images_responsive/expected_output.html create mode 100644 lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_tiny_images_responsive/input.html delete mode 100644 lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/boilerplate_then_noscript_not_removed_due_to_attribute/expected_output.html create mode 100644 lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_heights_attribute_to_css/expected_output.html rename lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/{boilerplate_then_noscript_not_removed_due_to_attribute => converts_heights_attribute_to_css}/input.html (76%) create mode 100644 lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_media_attribute_to_css/expected_output.html create mode 100644 lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_media_attribute_to_css/input.html create mode 100644 lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_sizes_attribute_to_css/expected_output.html rename lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/{noscript_then_boilerplate_not_removed_due_to_attribute => converts_sizes_attribute_to_css}/input.html (76%) delete mode 100644 lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/noscript_then_boilerplate_not_removed_due_to_attribute/expected_output.html diff --git a/lib/optimizer/resources/local_fallback/rtv/metadata b/lib/optimizer/resources/local_fallback/rtv/metadata index 027f378ccb3..7b12435a509 100644 --- a/lib/optimizer/resources/local_fallback/rtv/metadata +++ b/lib/optimizer/resources/local_fallback/rtv/metadata @@ -1 +1 @@ -{"ampRuntimeVersion":"012004252135000","ampCssUrl":"https://cdn.ampproject.org/rtv/012004252135000/v0.css","canaryPercentage":"0.005","diversions":["002005050322000","022004252135000","032005050322000","042005062312000","052004252135000","102005050322000"],"ltsRuntimeVersion":"012004030010070","ltsCssUrl":"https://cdn.ampproject.org/rtv/012004030010070/v0.css"} \ No newline at end of file +{"ampRuntimeVersion":"012005151844001","ampCssUrl":"https://cdn.ampproject.org/rtv/012005151844001/v0.css","canaryPercentage":"0.005","diversions":["002005150002001","002005220120000","022005151844001","032005150002001","032005220120000","042005272217000","052005151844001"],"ltsRuntimeVersion":"012005152259000","ltsCssUrl":"https://cdn.ampproject.org/rtv/012005152259000/v0.css"} \ No newline at end of file diff --git a/lib/optimizer/resources/local_fallback/v0.css b/lib/optimizer/resources/local_fallback/v0.css index d3ec1fdd807..7d86666090b 100644 --- a/lib/optimizer/resources/local_fallback/v0.css +++ b/lib/optimizer/resources/local_fallback/v0.css @@ -1,3 +1,3 @@ html{overflow-x:hidden!important}html.i-amphtml-fie{height:100%!important;width:100%!important}html:not([amp4ads]),html:not([amp4ads]) body{height:auto!important}html:not([amp4ads]) body{margin:0!important}body{-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;-ms-text-size-adjust:100%;text-size-adjust:100%}html.i-amphtml-singledoc.i-amphtml-embedded{-ms-touch-action:pan-y;touch-action:pan-y}html.i-amphtml-fie>body,html.i-amphtml-singledoc>body{overflow:visible!important}html.i-amphtml-fie:not(.i-amphtml-inabox)>body,html.i-amphtml-singledoc:not(.i-amphtml-inabox)>body{position:relative!important}html.i-amphtml-webview>body{overflow-x:hidden!important;overflow-y:visible!important;min-height:100vh!important}html.i-amphtml-ios-embed-legacy>body{overflow-x:hidden!important;overflow-y:auto!important;position:absolute!important}html.i-amphtml-ios-embed{overflow-y:auto!important;position:static}#i-amphtml-wrapper{overflow-x:hidden!important;overflow-y:auto!important;position:absolute!important;top:0!important;left:0!important;right:0!important;bottom:0!important;margin:0!important;display:block!important}html.i-amphtml-ios-embed.i-amphtml-ios-overscroll,html.i-amphtml-ios-embed.i-amphtml-ios-overscroll>#i-amphtml-wrapper{-webkit-overflow-scrolling:touch!important}#i-amphtml-wrapper>body{position:relative!important;border-top:1px solid transparent!important}#i-amphtml-wrapper+body{visibility:visible}#i-amphtml-wrapper+body .i-amphtml-lightbox-element,#i-amphtml-wrapper+body[i-amphtml-lightbox]{visibility:hidden}#i-amphtml-wrapper+body[i-amphtml-lightbox] .i-amphtml-lightbox-element{visibility:visible}#i-amphtml-wrapper.i-amphtml-scroll-disabled,.i-amphtml-scroll-disabled{overflow-x:hidden!important;overflow-y:hidden!important}amp-instagram{padding:54px 0px 0px!important;background-color:#fff}amp-iframe iframe{box-sizing:border-box!important}[amp-access][amp-access-hide]{display:none}[subscriptions-dialog],body:not(.i-amphtml-subs-ready) [subscriptions-action],body:not(.i-amphtml-subs-ready) [subscriptions-section]{display:none!important}amp-experiment,amp-live-list>[update],amp-share-tracking{display:none}.i-amphtml-jank-meter{position:fixed;background-color:rgba(232,72,95,0.5);bottom:0;right:0;color:#fff;font-size:16px;z-index:1000;padding:5px}amp-list[resizable-children]>.i-amphtml-loading-container.amp-hidden{display:none!important}amp-list [fetch-error],amp-list[load-more] [load-more-button],amp-list[load-more] [load-more-end],amp-list[load-more] [load-more-failed],amp-list[load-more] [load-more-loading]{display:none}amp-list[diffable] div[role=list]{display:block}amp-story-page,amp-story[standalone]{min-height:1px!important;display:block!important;height:100%!important;margin:0!important;padding:0!important;overflow:hidden!important;width:100%!important}amp-story[standalone]{background-color:#202125!important;position:relative!important}amp-story-page{background-color:#757575}amp-story .amp-active>div{display:none!important}amp-story-page:not(:first-of-type):not([distance]):not([active]){transform:translateY(1000vh)!important}amp-autocomplete{position:relative!important;display:inline-block!important}amp-autocomplete>input,amp-autocomplete>textarea{padding:0.5rem;border:1px solid rgba(0,0,0,0.33)}.i-amphtml-autocomplete-results,amp-autocomplete>input,amp-autocomplete>textarea{font-size:1rem;line-height:1.5rem}[amp-fx^=fly-in]{visibility:hidden} -/*# sourceURL=/css/ampdoc.css*/[hidden]{display:none!important}.i-amphtml-element{display:inline-block}.i-amphtml-blurry-placeholder{transition:opacity 0.3s cubic-bezier(0.0,0.0,0.2,1)!important}[layout=nodisplay]:not(.i-amphtml-element){display:none!important}.i-amphtml-layout-fixed,[layout=fixed][width][height]:not(.i-amphtml-layout-fixed){display:inline-block;position:relative}.i-amphtml-layout-responsive,[layout=responsive][width][height]:not(.i-amphtml-layout-responsive),[width][height][sizes]:not(.i-amphtml-layout-responsive){display:block;position:relative}.i-amphtml-layout-intrinsic{display:inline-block;position:relative;max-width:100%}.i-amphtml-intrinsic-sizer{max-width:100%;display:block!important}.i-amphtml-layout-container,.i-amphtml-layout-fixed-height,[layout=container],[layout=fixed-height][height]{display:block;position:relative}.i-amphtml-layout-fill,[layout=fill]:not(.i-amphtml-layout-fill){display:block;overflow:hidden!important;position:absolute;top:0;left:0;bottom:0;right:0}.i-amphtml-layout-flex-item,[layout=flex-item]:not(.i-amphtml-layout-flex-item){display:block;position:relative;-ms-flex:1 1 auto;flex:1 1 auto}.i-amphtml-layout-fluid{position:relative}.i-amphtml-layout-size-defined{overflow:hidden!important}.i-amphtml-layout-awaiting-size{position:absolute!important;top:auto!important;bottom:auto!important}i-amphtml-sizer{display:block!important}.i-amphtml-blurry-placeholder,.i-amphtml-fill-content{display:block;height:0;max-height:100%;max-width:100%;min-height:100%;min-width:100%;width:0;margin:auto}.i-amphtml-layout-size-defined .i-amphtml-fill-content{position:absolute;top:0;left:0;bottom:0;right:0}.i-amphtml-layout-intrinsic .i-amphtml-sizer{max-width:100%}.i-amphtml-replaced-content,.i-amphtml-screen-reader{padding:0!important;border:none!important}.i-amphtml-screen-reader{position:fixed!important;top:0px!important;left:0px!important;width:4px!important;height:4px!important;opacity:0!important;overflow:hidden!important;margin:0!important;display:block!important;visibility:visible!important}.i-amphtml-screen-reader~.i-amphtml-screen-reader{left:8px!important}.i-amphtml-screen-reader~.i-amphtml-screen-reader~.i-amphtml-screen-reader{left:12px!important}.i-amphtml-screen-reader~.i-amphtml-screen-reader~.i-amphtml-screen-reader~.i-amphtml-screen-reader{left:16px!important}.i-amphtml-unresolved{position:relative;overflow:hidden!important}.i-amphtml-select-disabled{-webkit-user-select:none!important;-moz-user-select:none!important;-ms-user-select:none!important;user-select:none!important}.i-amphtml-notbuilt,[layout]:not(.i-amphtml-element){position:relative;overflow:hidden!important;color:transparent!important}.i-amphtml-notbuilt:not(.i-amphtml-layout-container)>*,[layout]:not([layout=container]):not(.i-amphtml-element)>*{display:none}.i-amphtml-ghost{visibility:hidden!important}.i-amphtml-element>[placeholder],[layout]:not(.i-amphtml-element)>[placeholder]{display:block}.i-amphtml-element>[placeholder].amp-hidden,.i-amphtml-element>[placeholder].hidden{visibility:hidden}.i-amphtml-element:not(.amp-notsupported)>[fallback],.i-amphtml-layout-container>[placeholder].amp-hidden,.i-amphtml-layout-container>[placeholder].hidden{display:none}.i-amphtml-layout-size-defined>[fallback],.i-amphtml-layout-size-defined>[placeholder]{position:absolute!important;top:0!important;left:0!important;right:0!important;bottom:0!important;z-index:1}.i-amphtml-notbuilt>[placeholder]{display:block!important}.i-amphtml-hidden-by-media-query{display:none!important}.i-amphtml-element-error{background:red!important;color:#fff!important;position:relative!important}.i-amphtml-element-error:before{content:attr(error-message)}i-amp-scroll-container,i-amphtml-scroll-container{position:absolute;top:0;left:0;right:0;bottom:0;display:block}i-amp-scroll-container.amp-active,i-amphtml-scroll-container.amp-active{overflow:auto;-webkit-overflow-scrolling:touch}.i-amphtml-loading-container{display:block!important;pointer-events:none;z-index:1}.i-amphtml-notbuilt>.i-amphtml-loading-container{display:block!important}.i-amphtml-loading-container.amp-hidden{visibility:hidden}.i-amphtml-element>[overflow]{cursor:pointer;position:relative;z-index:2;visibility:hidden;display:initial}.i-amphtml-element>[overflow].amp-visible{visibility:visible}template{display:none!important}.amp-border-box,.amp-border-box *,.amp-border-box :after,.amp-border-box :before{box-sizing:border-box}amp-pixel{display:none!important}amp-analytics,amp-story-auto-ads{position:fixed!important;top:0!important;width:1px!important;height:1px!important;overflow:hidden!important;visibility:hidden}html.i-amphtml-fie>amp-analytics{position:initial!important}[visible-when-invalid]:not(.visible),form [submit-error],form [submit-success],form [submitting]{display:none}amp-accordion{display:block!important}amp-accordion>section{float:none!important}amp-accordion>section>*{float:none!important;display:block!important;overflow:hidden!important;position:relative!important}amp-accordion,amp-accordion>section{margin:0}amp-accordion>section>:last-child{display:none!important}amp-accordion>section[expanded]>:last-child{display:block!important} +/*# sourceURL=/css/ampdoc.css*/[hidden]{display:none!important}.i-amphtml-element{display:inline-block}.i-amphtml-blurry-placeholder{transition:opacity 0.3s cubic-bezier(0.0,0.0,0.2,1)!important;pointer-events:none}[layout=nodisplay]:not(.i-amphtml-element){display:none!important}.i-amphtml-layout-fixed,[layout=fixed][width][height]:not(.i-amphtml-layout-fixed){display:inline-block;position:relative}.i-amphtml-layout-responsive,[layout=responsive][width][height]:not(.i-amphtml-layout-responsive),[width][height][heights]:not([layout]):not(.i-amphtml-layout-responsive),[width][height][sizes]:not([layout]):not(.i-amphtml-layout-responsive){display:block;position:relative}.i-amphtml-layout-intrinsic,[layout=intrinsic][width][height]:not(.i-amphtml-layout-intrinsic){display:inline-block;position:relative;max-width:100%}.i-amphtml-layout-intrinsic .i-amphtml-sizer{max-width:100%}.i-amphtml-intrinsic-sizer{max-width:100%;display:block!important}.i-amphtml-layout-container,.i-amphtml-layout-fixed-height,[layout=container],[layout=fixed-height][height]:not(.i-amphtml-layout-fixed-height){display:block;position:relative}.i-amphtml-layout-fill,[layout=fill]:not(.i-amphtml-layout-fill){display:block;overflow:hidden!important;position:absolute;top:0;left:0;bottom:0;right:0}.i-amphtml-layout-flex-item,[layout=flex-item]:not(.i-amphtml-layout-flex-item){display:block;position:relative;-ms-flex:1 1 auto;flex:1 1 auto}.i-amphtml-layout-fluid{position:relative}.i-amphtml-layout-size-defined{overflow:hidden!important}.i-amphtml-layout-awaiting-size{position:absolute!important;top:auto!important;bottom:auto!important}i-amphtml-sizer{display:block!important}.i-amphtml-blurry-placeholder,.i-amphtml-fill-content{display:block;height:0;max-height:100%;max-width:100%;min-height:100%;min-width:100%;width:0;margin:auto}.i-amphtml-layout-size-defined .i-amphtml-fill-content{position:absolute;top:0;left:0;bottom:0;right:0}.i-amphtml-replaced-content,.i-amphtml-screen-reader{padding:0!important;border:none!important}.i-amphtml-screen-reader{position:fixed!important;top:0px!important;left:0px!important;width:4px!important;height:4px!important;opacity:0!important;overflow:hidden!important;margin:0!important;display:block!important;visibility:visible!important}.i-amphtml-screen-reader~.i-amphtml-screen-reader{left:8px!important}.i-amphtml-screen-reader~.i-amphtml-screen-reader~.i-amphtml-screen-reader{left:12px!important}.i-amphtml-screen-reader~.i-amphtml-screen-reader~.i-amphtml-screen-reader~.i-amphtml-screen-reader{left:16px!important}.i-amphtml-unresolved{position:relative;overflow:hidden!important}.i-amphtml-select-disabled{-webkit-user-select:none!important;-moz-user-select:none!important;-ms-user-select:none!important;user-select:none!important}.i-amphtml-notbuilt,[layout]:not(.i-amphtml-element),[width][height][heights]:not([layout]):not(.i-amphtml-element),[width][height][sizes]:not([layout]):not(.i-amphtml-element){position:relative;overflow:hidden!important;color:transparent!important}.i-amphtml-notbuilt:not(.i-amphtml-layout-container)>*,[layout]:not([layout=container]):not(.i-amphtml-element)>*,[width][height][heights]:not([layout]):not(.i-amphtml-element)>*,[width][height][sizes]:not([layout]):not(.i-amphtml-element)>*{display:none}.i-amphtml-ghost{visibility:hidden!important}.i-amphtml-element>[placeholder],[layout]:not(.i-amphtml-element)>[placeholder],[width][height][heights]:not([layout]):not(.i-amphtml-element)>[placeholder],[width][height][sizes]:not([layout]):not(.i-amphtml-element)>[placeholder]{display:block}.i-amphtml-element>[placeholder].amp-hidden,.i-amphtml-element>[placeholder].hidden{visibility:hidden}.i-amphtml-element:not(.amp-notsupported)>[fallback],.i-amphtml-layout-container>[placeholder].amp-hidden,.i-amphtml-layout-container>[placeholder].hidden{display:none}.i-amphtml-layout-size-defined>[fallback],.i-amphtml-layout-size-defined>[placeholder]{position:absolute!important;top:0!important;left:0!important;right:0!important;bottom:0!important;z-index:1}.i-amphtml-notbuilt>[placeholder]{display:block!important}.i-amphtml-hidden-by-media-query{display:none!important}.i-amphtml-element-error{background:red!important;color:#fff!important;position:relative!important}.i-amphtml-element-error:before{content:attr(error-message)}i-amp-scroll-container,i-amphtml-scroll-container{position:absolute;top:0;left:0;right:0;bottom:0;display:block}i-amp-scroll-container.amp-active,i-amphtml-scroll-container.amp-active{overflow:auto;-webkit-overflow-scrolling:touch}.i-amphtml-loading-container{display:block!important;pointer-events:none;z-index:1}.i-amphtml-notbuilt>.i-amphtml-loading-container{display:block!important}.i-amphtml-loading-container.amp-hidden{visibility:hidden}.i-amphtml-element>[overflow]{cursor:pointer;position:relative;z-index:2;visibility:hidden;display:initial}.i-amphtml-element>[overflow].amp-visible{visibility:visible}template{display:none!important}.amp-border-box,.amp-border-box *,.amp-border-box :after,.amp-border-box :before{box-sizing:border-box}amp-pixel{display:none!important}amp-analytics,amp-story-auto-ads{position:fixed!important;top:0!important;width:1px!important;height:1px!important;overflow:hidden!important;visibility:hidden}html.i-amphtml-fie>amp-analytics{position:initial!important}[visible-when-invalid]:not(.visible),form [submit-error],form [submit-success],form [submitting]{display:none}amp-accordion{display:block!important}amp-accordion>section{float:none!important}amp-accordion>section>*{float:none!important;display:block!important;overflow:hidden!important;position:relative!important}amp-accordion,amp-accordion>section{margin:0}amp-accordion>section>:last-child{display:none!important}amp-accordion>section[expanded]>:last-child{display:block!important} /*# sourceURL=/css/ampshared.css*/ \ No newline at end of file diff --git a/lib/optimizer/tests/spec/end-to-end/body-only/expected_output.valid.html b/lib/optimizer/tests/spec/end-to-end/body-only/expected_output.default.html similarity index 100% rename from lib/optimizer/tests/spec/end-to-end/body-only/expected_output.valid.html rename to lib/optimizer/tests/spec/end-to-end/body-only/expected_output.default.html diff --git a/lib/optimizer/tests/spec/end-to-end/body-only/expected_output.lts.html b/lib/optimizer/tests/spec/end-to-end/body-only/expected_output.lts.html new file mode 100644 index 00000000000..7af28cb3b43 --- /dev/null +++ b/lib/optimizer/tests/spec/end-to-end/body-only/expected_output.lts.html @@ -0,0 +1,17 @@ + + + + + + + + + + + +

Hello, AMP world!

+ + + + + \ No newline at end of file diff --git a/lib/optimizer/tests/spec/end-to-end/body-only/expected_output.html b/lib/optimizer/tests/spec/end-to-end/body-only/expected_output.paired.html similarity index 100% rename from lib/optimizer/tests/spec/end-to-end/body-only/expected_output.html rename to lib/optimizer/tests/spec/end-to-end/body-only/expected_output.paired.html diff --git a/lib/optimizer/tests/spec/end-to-end/hello-world/expected_output.valid.html b/lib/optimizer/tests/spec/end-to-end/hello-world/expected_output.default.html similarity index 100% rename from lib/optimizer/tests/spec/end-to-end/hello-world/expected_output.valid.html rename to lib/optimizer/tests/spec/end-to-end/hello-world/expected_output.default.html diff --git a/lib/optimizer/tests/spec/end-to-end/hello-world/expected_output.lts.html b/lib/optimizer/tests/spec/end-to-end/hello-world/expected_output.lts.html new file mode 100644 index 00000000000..5de31564745 --- /dev/null +++ b/lib/optimizer/tests/spec/end-to-end/hello-world/expected_output.lts.html @@ -0,0 +1,25 @@ + + + + + + + + + + + + + +

Hello, AMP world!

+ + + + + +
+

Your browser doesn't support HTML5 video.

+
+
+ + \ No newline at end of file diff --git a/lib/optimizer/tests/spec/end-to-end/hello-world/expected_output.html b/lib/optimizer/tests/spec/end-to-end/hello-world/expected_output.paired.html similarity index 100% rename from lib/optimizer/tests/spec/end-to-end/hello-world/expected_output.html rename to lib/optimizer/tests/spec/end-to-end/hello-world/expected_output.paired.html diff --git a/lib/optimizer/tests/spec/end-to-end/markdown/expected_output.valid.html b/lib/optimizer/tests/spec/end-to-end/markdown/expected_output.default.html similarity index 100% rename from lib/optimizer/tests/spec/end-to-end/markdown/expected_output.valid.html rename to lib/optimizer/tests/spec/end-to-end/markdown/expected_output.default.html diff --git a/lib/optimizer/tests/spec/end-to-end/markdown/expected_output.lts.html b/lib/optimizer/tests/spec/end-to-end/markdown/expected_output.lts.html new file mode 100644 index 00000000000..c2158be3e30 --- /dev/null +++ b/lib/optimizer/tests/spec/end-to-end/markdown/expected_output.lts.html @@ -0,0 +1,261 @@ + + + + + + + + + + +
+

Advertisement 😃

+ +

You will like those projects!

+
+

h1 Heading 😎

+

h2 Heading

+

h3 Heading

+

h4 Heading

+
h5 Heading
+
h6 Heading
+

Horizontal Rules

+
+
+
+

Typographic replacements

+

Enable typographer option to see result.

+

© © ® ® ™ ™ § § ±

+

test… test… test… test?.. test!..

+

!!! ??? , – —

+

“Smartypants, double quotes” and ‘single quotes’

+

Emphasis

+

This is bold text

+

This is bold text

+

This is italic text

+

This is italic text

+

Strikethrough

+

Blockquotes

+
+

Blockquotes can also be nested…

+
+

…by using additional greater-than signs right next to each other…

+
+

…or with spaces between arrows.

+
+
+
+

Lists

+

Unordered

+ +

Ordered

+
    +
  1. +

    Lorem ipsum dolor sit amet

    +
  2. +
  3. +

    Consectetur adipiscing elit

    +
  4. +
  5. +

    Integer molestie lorem at massa

    +
  6. +
  7. +

    You can use sequential numbers…

    +
  8. +
  9. +

    …or keep all the numbers as 1.

    +
  10. +
+

Start numbering with offset:

+
    +
  1. foo
  2. +
  3. bar
  4. +
+

Code

+

Inline code

+

Indented code

+
// Some comments
+line 1 of code
+line 2 of code
+line 3 of code
+
+

Block code “fences”

+
Sample text here...
+
+

Syntax highlighting

+
var foo = function (bar) {
+  return bar++;
+};
+
+console.log(foo(5));
+
+

Tables

+ + + + + + + + + + + + + + + + + + + + + +
OptionDescription
data path to data files to supply the data that will be passed into templates.
engine engine to be used for processing templates. Handlebars is the default.
extextension to be used for dest files.
+

Right aligned columns

+ + + + + + + + + + + + + + + + + + + + + +
OptionDescription
data path to data files to supply the data that will be passed into templates.
engine engine to be used for processing templates. Handlebars is the default.
extextension to be used for dest files.
+

Links

+

link text

+

link with title +

+

Autoconverted link https://github.com/nodeca/pica (enable linkify to see) +

+

Images

+

+ + + + + + +

+

Like links, Images also have a footnote style syntax

+

+ + + +

+

With a reference later in the document defining the URL location:

+

Plugins

+

The killer feature of markdown-it is very effective support of syntax plugins. +

+

Emojies

+
+

Classic markup: 😉 :crush: 😢 :tear: 😆 😋

+

Shortcuts (emoticons): 😃 😦 😎 😉

+
+

see how to change output with twemoji. +

+

Subscript / Superscript +

+ +

<ins> +

+

Inserted text

+

<mark> +

+

Marked text

+

Footnotes +

+

Footnote 1 link[1]. +

+

Footnote 2 link[2]. +

+

Inline footnote[3] definition. +

+

Duplicated footnote reference[2:1]. +

+

Definition lists +

+
+
Term 1
+
+

Definition 1 with lazy continuation.

+
+
Term 2 with inline markup
+
+

Definition 2

+
  { some code, part of Definition 2 }
+
+

Third paragraph of definition 2.

+
+
+

Compact style:

+
+
Term 1
+
Definition 1
+
Term 2
+
Definition 2a
+
Definition 2b
+
+

Abbreviations +

+

This is HTML abbreviation example. +

+

It converts “HTML”, but keep intact partial entries like “xxxHTMLyyy” and so on. +

+

Custom containers +

+
+

here be dragons

+
+
+
+
    +
  1. +

    Footnote can have markup

    +

    and multiple paragraphs. ↩︎

    +
  2. +
  3. +

    Footnote text. ↩︎ ↩︎

    +
  4. +
  5. +

    Text of inline footnote ↩︎

    +
  6. +
+
+ + \ No newline at end of file diff --git a/lib/optimizer/tests/spec/end-to-end/markdown/expected_output.html b/lib/optimizer/tests/spec/end-to-end/markdown/expected_output.paired.html similarity index 100% rename from lib/optimizer/tests/spec/end-to-end/markdown/expected_output.html rename to lib/optimizer/tests/spec/end-to-end/markdown/expected_output.paired.html diff --git a/lib/optimizer/tests/spec/transformers/valid/OptimizeImages/adds_srcset/expected_output.html b/lib/optimizer/tests/spec/transformers/valid/OptimizeImages/adds_srcset/expected_output.html new file mode 100644 index 00000000000..23649cc1d64 --- /dev/null +++ b/lib/optimizer/tests/spec/transformers/valid/OptimizeImages/adds_srcset/expected_output.html @@ -0,0 +1,13 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/optimizer/tests/spec/transformers/valid/OptimizeImages/adds_srcset/input.html b/lib/optimizer/tests/spec/transformers/valid/OptimizeImages/adds_srcset/input.html new file mode 100644 index 00000000000..6c0bddb1d0d --- /dev/null +++ b/lib/optimizer/tests/spec/transformers/valid/OptimizeImages/adds_srcset/input.html @@ -0,0 +1,13 @@ + + + + + + + + + + + + diff --git a/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_data_uris_amp-iframe/expected_output.html b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_data_uris_amp-iframe/expected_output.html new file mode 100644 index 00000000000..cbc2a3f59df --- /dev/null +++ b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_data_uris_amp-iframe/expected_output.html @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_data_uris_amp-iframe/input.html b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_data_uris_amp-iframe/input.html new file mode 100644 index 00000000000..b6d68c1a173 --- /dev/null +++ b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_data_uris_amp-iframe/input.html @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_data_uris_amp-img/expected_output.html b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_data_uris_amp-img/expected_output.html new file mode 100644 index 00000000000..76a988c0340 --- /dev/null +++ b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_data_uris_amp-img/expected_output.html @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_data_uris_amp-img/input.html b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_data_uris_amp-img/input.html new file mode 100644 index 00000000000..aba1350b786 --- /dev/null +++ b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_data_uris_amp-img/input.html @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_data_uris_amp-video/expected_output.html b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_data_uris_amp-video/expected_output.html new file mode 100644 index 00000000000..357da32daa9 --- /dev/null +++ b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_data_uris_amp-video/expected_output.html @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_data_uris_amp-video/input.html b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_data_uris_amp-video/input.html new file mode 100644 index 00000000000..92a05df15cd --- /dev/null +++ b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_data_uris_amp-video/input.html @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_tiny_images_intrinsic/expected_output.html b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_tiny_images_intrinsic/expected_output.html new file mode 100644 index 00000000000..01759de3ab9 --- /dev/null +++ b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_tiny_images_intrinsic/expected_output.html @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_tiny_images_intrinsic/input.html b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_tiny_images_intrinsic/input.html new file mode 100644 index 00000000000..58e7f5e1eff --- /dev/null +++ b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_tiny_images_intrinsic/input.html @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_tiny_images_responsive/expected_output.html b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_tiny_images_responsive/expected_output.html new file mode 100644 index 00000000000..50fe16573b4 --- /dev/null +++ b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_tiny_images_responsive/expected_output.html @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_tiny_images_responsive/input.html b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_tiny_images_responsive/input.html new file mode 100644 index 00000000000..a8bf9458708 --- /dev/null +++ b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/ignores_tiny_images_responsive/input.html @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/boilerplate_then_noscript_not_removed_due_to_attribute/expected_output.html b/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/boilerplate_then_noscript_not_removed_due_to_attribute/expected_output.html deleted file mode 100644 index a8108b1cf2d..00000000000 --- a/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/boilerplate_then_noscript_not_removed_due_to_attribute/expected_output.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_heights_attribute_to_css/expected_output.html b/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_heights_attribute_to_css/expected_output.html new file mode 100644 index 00000000000..2a2c65910a3 --- /dev/null +++ b/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_heights_attribute_to_css/expected_output.html @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/boilerplate_then_noscript_not_removed_due_to_attribute/input.html b/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_heights_attribute_to_css/input.html similarity index 76% rename from lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/boilerplate_then_noscript_not_removed_due_to_attribute/input.html rename to lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_heights_attribute_to_css/input.html index 63a06b22f3e..bd8e92ebfeb 100644 --- a/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/boilerplate_then_noscript_not_removed_due_to_attribute/input.html +++ b/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_heights_attribute_to_css/input.html @@ -3,18 +3,11 @@ - +-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes-amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes-amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes-amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes-amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}} - - + + + height=300 + layout=responsive + heights="(min-width: 320px), 100vw" + src=https://acme.org/image1.png + width=400> diff --git a/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_media_attribute_to_css/expected_output.html b/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_media_attribute_to_css/expected_output.html new file mode 100644 index 00000000000..5e776924f8b --- /dev/null +++ b/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_media_attribute_to_css/expected_output.html @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_media_attribute_to_css/input.html b/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_media_attribute_to_css/input.html new file mode 100644 index 00000000000..8d0aa6ea4d0 --- /dev/null +++ b/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_media_attribute_to_css/input.html @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_sizes_attribute_to_css/expected_output.html b/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_sizes_attribute_to_css/expected_output.html new file mode 100644 index 00000000000..31b4dc3f99f --- /dev/null +++ b/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_sizes_attribute_to_css/expected_output.html @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/noscript_then_boilerplate_not_removed_due_to_attribute/input.html b/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_sizes_attribute_to_css/input.html similarity index 76% rename from lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/noscript_then_boilerplate_not_removed_due_to_attribute/input.html rename to lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_sizes_attribute_to_css/input.html index 97e56a60224..0a17aa066cc 100644 --- a/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/noscript_then_boilerplate_not_removed_due_to_attribute/input.html +++ b/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_sizes_attribute_to_css/input.html @@ -8,6 +8,7 @@ + + + width=400> + + height=300 + layout=responsive + sizes="(min-width: 320px), 100vw" + srcset="img-480w.jpg 480w,img-800w.jpg 800w" + src=https://acme.org/image1.png + width=400> diff --git a/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/noscript_then_boilerplate_not_removed_due_to_attribute/expected_output.html b/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/noscript_then_boilerplate_not_removed_due_to_attribute/expected_output.html deleted file mode 100644 index 413f4f58d29..00000000000 --- a/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/noscript_then_boilerplate_not_removed_due_to_attribute/expected_output.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file From 92a30a1088b4b7ef3c877357d1ae283772c578dd Mon Sep 17 00:00:00 2001 From: Alain Schlesser Date: Fri, 29 May 2020 09:40:06 +0200 Subject: [PATCH 02/18] Remove superfluous spec test exceptions --- lib/optimizer/tests/SpecTest.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/optimizer/tests/SpecTest.php b/lib/optimizer/tests/SpecTest.php index 453b103fcee..8d417ea6078 100644 --- a/lib/optimizer/tests/SpecTest.php +++ b/lib/optimizer/tests/SpecTest.php @@ -30,9 +30,6 @@ final class SpecTest extends TestCase 'ReorderHead - reorders_head_a4a' => 'see https://github.com/ampproject/amp-toolbox/issues/583', 'ReorderHead - reorders_head_amphtml' => 'see https://github.com/ampproject/amp-toolbox/issues/583', 'ReorderHead - preserves_amp_custom_style_order' => 'see https://github.com/ampproject/amp-toolbox/issues/604', - - 'ServerSideRendering - noscript_then_boilerplate_not_removed_due_to_attribute' => 'see https://github.com/ampproject/amp-wp/issues/4439', - 'ServerSideRendering - boilerplate_then_noscript_not_removed_due_to_attribute' => 'see https://github.com/ampproject/amp-wp/issues/4439', ]; const CLASS_SKIP_TEST = '__SKIP__'; From 97f44773ea0ca7d195dca852732e844aa1684507 Mon Sep 17 00:00:00 2001 From: Alain Schlesser Date: Fri, 29 May 2020 09:42:48 +0200 Subject: [PATCH 03/18] Change default ID prefix to match amp-toolbox --- lib/common/src/Dom/Document.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/common/src/Dom/Document.php b/lib/common/src/Dom/Document.php index cca66d5b478..1417ce3e7a7 100644 --- a/lib/common/src/Dom/Document.php +++ b/lib/common/src/Dom/Document.php @@ -1492,7 +1492,7 @@ public function isValidHeadNode(DOMNode $node) * @param string $prefix Optional. The prefix to use (should not have a trailing dash). Defaults to 'i-amp-id'. * @return string ID to use. */ - public function getElementId(DOMElement $element, $prefix = 'i-amp-id') + public function getElementId(DOMElement $element, $prefix = 'i-amp') { if ($element->hasAttribute('id')) { return $element->getAttribute('id'); From 3431a4de3c6b90777683d17f230988a0fa538ef6 Mon Sep 17 00:00:00 2001 From: Alain Schlesser Date: Fri, 29 May 2020 09:58:38 +0200 Subject: [PATCH 04/18] Match indexing behavior from amp-toolbox --- lib/common/src/Dom/Document.php | 6 +++--- lib/common/tests/Dom/DocumentTest.php | 26 +++++++++++++------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/lib/common/src/Dom/Document.php b/lib/common/src/Dom/Document.php index 1417ce3e7a7..58ccf710fab 100644 --- a/lib/common/src/Dom/Document.php +++ b/lib/common/src/Dom/Document.php @@ -1500,12 +1500,12 @@ public function getElementId(DOMElement $element, $prefix = 'i-amp') if (array_key_exists($prefix, $this->indexCounter)) { ++$this->indexCounter[$prefix]; - $id = "{$prefix}-{$this->indexCounter[ $prefix ]}"; } else { - $id = $prefix; - $this->indexCounter[$prefix] = 1; + $this->indexCounter[$prefix] = 0; } + $id = "{$prefix}-{$this->indexCounter[ $prefix ]}"; + while ($this->getElementById($id) instanceof DOMElement) { ++$this->indexCounter[$prefix]; $id = "{$prefix}-{$this->indexCounter[ $prefix ]}"; diff --git a/lib/common/tests/Dom/DocumentTest.php b/lib/common/tests/Dom/DocumentTest.php index d367b6e42fd..4f8ae686f5d 100644 --- a/lib/common/tests/Dom/DocumentTest.php +++ b/lib/common/tests/Dom/DocumentTest.php @@ -734,35 +734,35 @@ public function getGetElementIdData() 'single check without existing ID' => [ [ - [ $elementFactory, null, 'some-prefix', 'some-prefix' ], + [ $elementFactory, null, 'some-prefix', 'some-prefix-0' ], ], ], 'consecutive checks count upwards' => [ [ - [ $elementFactory, null, 'some-prefix', 'some-prefix' ], - [ $elementFactory, null, 'some-prefix', 'some-prefix-2' ], + [ $elementFactory, null, 'some-prefix', 'some-prefix-0' ], + [ $elementFactory, null, 'some-prefix', 'some-prefix-1' ], ], ], 'consecutive checks for same element return same ID' => [ [ - [ $elementFactory, null, 'some-prefix', 'some-prefix' ], - [ null, null, 'some-prefix', 'some-prefix' ], + [ $elementFactory, null, 'some-prefix', 'some-prefix-0' ], + [ null, null, 'some-prefix', 'some-prefix-0' ], ], ], 'mixing prefixes keeps counts separate' => [ [ [ $elementFactory, 'my-id', 'some-prefix', 'my-id' ], - [ $elementFactory, null, 'some-prefix', 'some-prefix' ], + [ $elementFactory, null, 'some-prefix', 'some-prefix-0' ], + [ $elementFactory, null, 'some-prefix', 'some-prefix-1' ], + [ $elementFactory, null, 'other-prefix', 'other-prefix-0' ], + [ $elementFactory, null, 'other-prefix', 'other-prefix-1' ], [ $elementFactory, null, 'some-prefix', 'some-prefix-2' ], - [ $elementFactory, null, 'other-prefix', 'other-prefix' ], - [ $elementFactory, null, 'other-prefix', 'other-prefix-2' ], - [ $elementFactory, null, 'some-prefix', 'some-prefix-3' ], [ $elementFactory, 'another-id', 'some-prefix', 'another-id' ], - [ $elementFactory, null, 'some-prefix', 'some-prefix-4' ], - [ null, null, 'some-prefix', 'some-prefix-4' ], + [ $elementFactory, null, 'some-prefix', 'some-prefix-3' ], + [ null, null, 'some-prefix', 'some-prefix-3' ], ], ], ]; @@ -798,12 +798,12 @@ public function testGetElementId($checks) public function testGetElementIdOnPreexistingIds() { $dom = Document::fromHtml( - '
' + '
' ); $element = $dom->createElement('div'); $dom->body->appendChild($element); - $this->assertEquals('some-prefix-4', $dom->getElementId($element, 'some-prefix')); + $this->assertEquals('some-prefix-3', $dom->getElementId($element, 'some-prefix')); } } From 7c534e7a50c26951c627e4055e830049efabb389 Mon Sep 17 00:00:00 2001 From: Alain Schlesser Date: Fri, 29 May 2020 10:02:11 +0200 Subject: [PATCH 05/18] Adapt tests to new ID indexing behavior --- .../Transformer/ServerSideRenderingTest.php | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/lib/optimizer/tests/Transformer/ServerSideRenderingTest.php b/lib/optimizer/tests/Transformer/ServerSideRenderingTest.php index 0f6f816b563..a580f5bdb53 100644 --- a/lib/optimizer/tests/Transformer/ServerSideRenderingTest.php +++ b/lib/optimizer/tests/Transformer/ServerSideRenderingTest.php @@ -172,8 +172,8 @@ public function dataTransform() 'sizes attribute without amp-custom' => [ $input(''), $expectWithoutBoilerplate( - '', - '' + '', + '' ), [], ], @@ -184,8 +184,8 @@ public function dataTransform() '' ), $expectWithoutBoilerplate( - '', - '' + '', + '' ), [], ], @@ -235,8 +235,8 @@ public function dataTransform() 'heights attribute without amp-custom' => [ $input(''), $expectWithoutBoilerplate( - '', - '' + '', + '' ), [], ], @@ -247,8 +247,8 @@ public function dataTransform() '' ), $expectWithoutBoilerplate( - '', - '' + '', + '' ), [], ], @@ -256,7 +256,7 @@ public function dataTransform() 'bad heights attribute' => [ $input(''), // This adds an ID as it stores the CSS to inline before the actual error is detected. - $expectWithBoilerplate(''), + $expectWithBoilerplate(''), [ Error\CannotRemoveBoilerplate::fromAttributeThrowingException( InvalidHtmlAttribute::fromAttribute( @@ -284,8 +284,8 @@ public function dataTransform() 'media attribute without amp-custom' => [ $input(''), $expectWithoutBoilerplate( - '', - '' + '', + '' ), [], ], @@ -296,8 +296,8 @@ public function dataTransform() '' ), $expectWithoutBoilerplate( - '', - '' + '', + '' ), [], ], @@ -305,8 +305,8 @@ public function dataTransform() 'media attribute with type condition' => [ $input(''), $expectWithoutBoilerplate( - '', - '' + '', + '' ), [], ], From a5c664d402ed64f4652f704aadcc66c482aa543e Mon Sep 17 00:00:00 2001 From: Alain Schlesser Date: Fri, 29 May 2020 10:07:24 +0200 Subject: [PATCH 06/18] Skip tests where an unused ID is added by amp-toolbox --- lib/optimizer/tests/SpecTest.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/optimizer/tests/SpecTest.php b/lib/optimizer/tests/SpecTest.php index 8d417ea6078..54e6b669dc5 100644 --- a/lib/optimizer/tests/SpecTest.php +++ b/lib/optimizer/tests/SpecTest.php @@ -30,6 +30,11 @@ final class SpecTest extends TestCase 'ReorderHead - reorders_head_a4a' => 'see https://github.com/ampproject/amp-toolbox/issues/583', 'ReorderHead - reorders_head_amphtml' => 'see https://github.com/ampproject/amp-toolbox/issues/583', 'ReorderHead - preserves_amp_custom_style_order' => 'see https://github.com/ampproject/amp-toolbox/issues/604', + + 'ServerSideRendering - converts_sizes_attribute_to_css' => 'see https://github.com/ampproject/amp-toolbox/issues/809', + 'ServerSideRendering - converts_heights_attribute_to_css' => 'see https://github.com/ampproject/amp-toolbox/issues/809', + 'ServerSideRendering - converts_media_attribute_to_css' => 'see https://github.com/ampproject/amp-toolbox/issues/809', + ]; const CLASS_SKIP_TEST = '__SKIP__'; From 77c9e6f23df506b532c59baf142aa19321d3756d Mon Sep 17 00:00:00 2001 From: Alain Schlesser Date: Fri, 29 May 2020 11:36:57 +0200 Subject: [PATCH 07/18] Adapt tests for AMP_DOM_Utils::get_element_id() --- tests/php/test-class-amp-dom-utils.php | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/php/test-class-amp-dom-utils.php b/tests/php/test-class-amp-dom-utils.php index d6d3ff74aa8..ddfeefa6a1b 100644 --- a/tests/php/test-class-amp-dom-utils.php +++ b/tests/php/test-class-amp-dom-utils.php @@ -370,35 +370,35 @@ public function get_get_element_id_data() { 'single check without existing ID' => [ [ - [ $element_factory, null, 'some-prefix', 'some-prefix' ], + [ $element_factory, null, 'some-prefix', 'some-prefix-0' ], ], ], 'consecutive checks count upwards' => [ [ - [ $element_factory, null, 'some-prefix', 'some-prefix' ], - [ $element_factory, null, 'some-prefix', 'some-prefix-2' ], + [ $element_factory, null, 'some-prefix', 'some-prefix-0' ], + [ $element_factory, null, 'some-prefix', 'some-prefix-1' ], ], ], 'consecutive checks for same element return same ID' => [ [ - [ $element_factory, null, 'some-prefix', 'some-prefix' ], - [ null, null, 'some-prefix', 'some-prefix' ], + [ $element_factory, null, 'some-prefix', 'some-prefix-0' ], + [ null, null, 'some-prefix', 'some-prefix-0' ], ], ], 'mixing prefixes keeps counts separate' => [ [ [ $element_factory, 'my-id', 'some-prefix', 'my-id' ], - [ $element_factory, null, 'some-prefix', 'some-prefix' ], + [ $element_factory, null, 'some-prefix', 'some-prefix-0' ], + [ $element_factory, null, 'some-prefix', 'some-prefix-1' ], + [ $element_factory, null, 'other-prefix', 'other-prefix-0' ], + [ $element_factory, null, 'other-prefix', 'other-prefix-1' ], [ $element_factory, null, 'some-prefix', 'some-prefix-2' ], - [ $element_factory, null, 'other-prefix', 'other-prefix' ], - [ $element_factory, null, 'other-prefix', 'other-prefix-2' ], - [ $element_factory, null, 'some-prefix', 'some-prefix-3' ], [ $element_factory, 'another-id', 'some-prefix', 'another-id' ], - [ $element_factory, null, 'some-prefix', 'some-prefix-4' ], - [ null, null, 'some-prefix', 'some-prefix-4' ], + [ $element_factory, null, 'some-prefix', 'some-prefix-3' ], + [ null, null, 'some-prefix', 'some-prefix-3' ], ], ], ]; From 4d756f8c4095653daff5087d4fde3fcd80ad7e45 Mon Sep 17 00:00:00 2001 From: Alain Schlesser Date: Fri, 29 May 2020 11:54:09 +0200 Subject: [PATCH 08/18] Revert "Skip tests where an unused ID is added by amp-toolbox" This reverts commit a5c664d402ed64f4652f704aadcc66c482aa543e. --- lib/optimizer/tests/SpecTest.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib/optimizer/tests/SpecTest.php b/lib/optimizer/tests/SpecTest.php index 54e6b669dc5..8d417ea6078 100644 --- a/lib/optimizer/tests/SpecTest.php +++ b/lib/optimizer/tests/SpecTest.php @@ -30,11 +30,6 @@ final class SpecTest extends TestCase 'ReorderHead - reorders_head_a4a' => 'see https://github.com/ampproject/amp-toolbox/issues/583', 'ReorderHead - reorders_head_amphtml' => 'see https://github.com/ampproject/amp-toolbox/issues/583', 'ReorderHead - preserves_amp_custom_style_order' => 'see https://github.com/ampproject/amp-toolbox/issues/604', - - 'ServerSideRendering - converts_sizes_attribute_to_css' => 'see https://github.com/ampproject/amp-toolbox/issues/809', - 'ServerSideRendering - converts_heights_attribute_to_css' => 'see https://github.com/ampproject/amp-toolbox/issues/809', - 'ServerSideRendering - converts_media_attribute_to_css' => 'see https://github.com/ampproject/amp-toolbox/issues/809', - ]; const CLASS_SKIP_TEST = '__SKIP__'; From 401748a9c9b7091ccb83d4100ace8227a6548ace Mon Sep 17 00:00:00 2001 From: Alain Schlesser Date: Fri, 29 May 2020 14:19:23 +0200 Subject: [PATCH 09/18] Update spec tests --- .../expected_output.html | 0 .../input.html | 0 .../expected_output.html | 0 .../input.html | 0 .../expected_output.html | 11 +++++++++++ .../media_attribute_amp-iframe/input.html | 10 ++++++++++ .../expected_output.html | 9 +++++++++ .../media_attribute_amp-img/input.html | 8 ++++++++ .../expected_output.html | 11 +++++++++++ .../input.html | 10 ++++++++++ .../expected_output.html | 10 ++++++++++ .../media_attribute_amp-video/input.html | 8 ++++++++ .../expected_output.html | 2 +- .../expected_output.html | 18 +++++++++--------- .../expected_output.html | 8 ++++---- 15 files changed, 91 insertions(+), 14 deletions(-) rename lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/{preloads_hero_image => amp-img}/expected_output.html (100%) rename lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/{preloads_hero_image => amp-img}/input.html (100%) rename lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/{video_posters => amp-video_with_poster}/expected_output.html (100%) rename lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/{video_posters => amp-video_with_poster}/input.html (100%) create mode 100644 lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/media_attribute_amp-iframe/expected_output.html create mode 100644 lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/media_attribute_amp-iframe/input.html create mode 100644 lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/media_attribute_amp-img/expected_output.html create mode 100644 lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/media_attribute_amp-img/input.html create mode 100644 lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/media_attribute_amp-video-iframe/expected_output.html create mode 100644 lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/media_attribute_amp-video-iframe/input.html create mode 100644 lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/media_attribute_amp-video/expected_output.html create mode 100644 lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/media_attribute_amp-video/input.html diff --git a/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/preloads_hero_image/expected_output.html b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/amp-img/expected_output.html similarity index 100% rename from lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/preloads_hero_image/expected_output.html rename to lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/amp-img/expected_output.html diff --git a/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/preloads_hero_image/input.html b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/amp-img/input.html similarity index 100% rename from lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/preloads_hero_image/input.html rename to lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/amp-img/input.html diff --git a/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/video_posters/expected_output.html b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/amp-video_with_poster/expected_output.html similarity index 100% rename from lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/video_posters/expected_output.html rename to lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/amp-video_with_poster/expected_output.html diff --git a/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/video_posters/input.html b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/amp-video_with_poster/input.html similarity index 100% rename from lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/video_posters/input.html rename to lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/amp-video_with_poster/input.html diff --git a/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/media_attribute_amp-iframe/expected_output.html b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/media_attribute_amp-iframe/expected_output.html new file mode 100644 index 00000000000..1e9424f24b2 --- /dev/null +++ b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/media_attribute_amp-iframe/expected_output.html @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/media_attribute_amp-iframe/input.html b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/media_attribute_amp-iframe/input.html new file mode 100644 index 00000000000..4fcaa2f0e1c --- /dev/null +++ b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/media_attribute_amp-iframe/input.html @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/media_attribute_amp-img/expected_output.html b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/media_attribute_amp-img/expected_output.html new file mode 100644 index 00000000000..3fa43d7a6ba --- /dev/null +++ b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/media_attribute_amp-img/expected_output.html @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/media_attribute_amp-img/input.html b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/media_attribute_amp-img/input.html new file mode 100644 index 00000000000..40607266b6d --- /dev/null +++ b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/media_attribute_amp-img/input.html @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/media_attribute_amp-video-iframe/expected_output.html b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/media_attribute_amp-video-iframe/expected_output.html new file mode 100644 index 00000000000..fabc95bdedb --- /dev/null +++ b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/media_attribute_amp-video-iframe/expected_output.html @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/media_attribute_amp-video-iframe/input.html b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/media_attribute_amp-video-iframe/input.html new file mode 100644 index 00000000000..f6775792203 --- /dev/null +++ b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/media_attribute_amp-video-iframe/input.html @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/media_attribute_amp-video/expected_output.html b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/media_attribute_amp-video/expected_output.html new file mode 100644 index 00000000000..dfb51dd5dd0 --- /dev/null +++ b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/media_attribute_amp-video/expected_output.html @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/media_attribute_amp-video/input.html b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/media_attribute_amp-video/input.html new file mode 100644 index 00000000000..c95551681ce --- /dev/null +++ b/lib/optimizer/tests/spec/transformers/valid/PreloadHeroImage/media_attribute_amp-video/input.html @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_heights_attribute_to_css/expected_output.html b/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_heights_attribute_to_css/expected_output.html index 2a2c65910a3..902e025f9a4 100644 --- a/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_heights_attribute_to_css/expected_output.html +++ b/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_heights_attribute_to_css/expected_output.html @@ -4,7 +4,7 @@ - + diff --git a/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_media_attribute_to_css/expected_output.html b/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_media_attribute_to_css/expected_output.html index 5e776924f8b..54d1392aca4 100644 --- a/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_media_attribute_to_css/expected_output.html +++ b/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_media_attribute_to_css/expected_output.html @@ -5,23 +5,23 @@ - + - + - + - + - + - - - + + + - + diff --git a/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_sizes_attribute_to_css/expected_output.html b/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_sizes_attribute_to_css/expected_output.html index 31b4dc3f99f..dd61b06b725 100644 --- a/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_sizes_attribute_to_css/expected_output.html +++ b/lib/optimizer/tests/spec/transformers/valid/ServerSideRendering/converts_sizes_attribute_to_css/expected_output.html @@ -5,19 +5,19 @@ - + - + - + - + From 42710d7d28c29604f54c54b6ac7d91647ed04bca Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Fri, 29 May 2020 13:42:45 -0700 Subject: [PATCH 10/18] Normalize start tag attributes by sorting and squashing whitespace --- lib/optimizer/tests/src/MarkupComparison.php | 24 ++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/lib/optimizer/tests/src/MarkupComparison.php b/lib/optimizer/tests/src/MarkupComparison.php index 7c24883170a..36916650dc3 100644 --- a/lib/optimizer/tests/src/MarkupComparison.php +++ b/lib/optimizer/tests/src/MarkupComparison.php @@ -23,10 +23,26 @@ protected function assertEqualMarkup($expected, $actual) $actual = preg_replace('/(?<=>)\s+(?=<)/', '', trim($actual)); $expected = preg_replace('/(?<=>)\s+(?=<)/', '', trim($expected)); - $this->assertEquals( - array_filter(preg_split('#(<[^>]+>|[^<>]+)#', $expected, -1, PREG_SPLIT_DELIM_CAPTURE)), - array_filter(preg_split('#(<[^>]+>|[^<>]+)#', $actual, -1, PREG_SPLIT_DELIM_CAPTURE)) - ); + $normalize_attributes = static function( $token ) { + if ( preg_match( '#^(<[a-z0-9-]+)(\s[^>]+)#is', $token, $matches ) ) { + $token = $matches[1]; + + $attrs = array_map( 'trim', array_filter( preg_split( '#(\s+[^"\'\s=]+(?:=(?:"[^"]+"|\'[^\']+\'|[^"\'\s]+))?)#', $matches[2], -1, PREG_SPLIT_DELIM_CAPTURE ) ) ); + sort( $attrs ); + $attrs = array_map( + static function( $attr ) { + return ' ' . $attr; + }, + $attrs + ); + } + return $token; + }; + + $expected_tokens = array_map( $normalize_attributes, array_filter( preg_split( '#(<[^>]+>|[^<>]+)#', $expected, -1, PREG_SPLIT_DELIM_CAPTURE ) ) ); + $actual_tokens = array_map( $normalize_attributes, array_filter( preg_split( '#(<[^>]+>|[^<>]+)#', $actual, -1, PREG_SPLIT_DELIM_CAPTURE ) ) ); + + $this->assertEquals( $expected_tokens, $actual_tokens ); } /** From 78dbb131d40283ec5635c8e100f8431e246982c3 Mon Sep 17 00:00:00 2001 From: Alain Schlesser Date: Mon, 1 Jun 2020 18:55:43 +0200 Subject: [PATCH 11/18] Move attribute-order-agnostic comparison to assertSimilarMarkup() --- lib/optimizer/tests/src/MarkupComparison.php | 50 ++++++++++++-------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/lib/optimizer/tests/src/MarkupComparison.php b/lib/optimizer/tests/src/MarkupComparison.php index 36916650dc3..ad27c918f41 100644 --- a/lib/optimizer/tests/src/MarkupComparison.php +++ b/lib/optimizer/tests/src/MarkupComparison.php @@ -23,26 +23,10 @@ protected function assertEqualMarkup($expected, $actual) $actual = preg_replace('/(?<=>)\s+(?=<)/', '', trim($actual)); $expected = preg_replace('/(?<=>)\s+(?=<)/', '', trim($expected)); - $normalize_attributes = static function( $token ) { - if ( preg_match( '#^(<[a-z0-9-]+)(\s[^>]+)#is', $token, $matches ) ) { - $token = $matches[1]; - - $attrs = array_map( 'trim', array_filter( preg_split( '#(\s+[^"\'\s=]+(?:=(?:"[^"]+"|\'[^\']+\'|[^"\'\s]+))?)#', $matches[2], -1, PREG_SPLIT_DELIM_CAPTURE ) ) ); - sort( $attrs ); - $attrs = array_map( - static function( $attr ) { - return ' ' . $attr; - }, - $attrs - ); - } - return $token; - }; - - $expected_tokens = array_map( $normalize_attributes, array_filter( preg_split( '#(<[^>]+>|[^<>]+)#', $expected, -1, PREG_SPLIT_DELIM_CAPTURE ) ) ); - $actual_tokens = array_map( $normalize_attributes, array_filter( preg_split( '#(<[^>]+>|[^<>]+)#', $actual, -1, PREG_SPLIT_DELIM_CAPTURE ) ) ); - - $this->assertEquals( $expected_tokens, $actual_tokens ); + $this->assertEquals( + array_filter(preg_split('#(<[^>]+>|[^<>]+)#', $expected, -1, PREG_SPLIT_DELIM_CAPTURE)), + array_filter(preg_split('#(<[^>]+>|[^<>]+)#', $actual, -1, PREG_SPLIT_DELIM_CAPTURE)) + ); } /** @@ -62,6 +46,30 @@ protected function assertSimilarMarkup($expected, $actual) $actual = preg_replace('/>\s*{\s*}\s*{}<', $actual); $expected = preg_replace('/>\s*{\s*}\s*{}<', $expected); - $this->assertEqualMarkup($expected, $actual); + $actual = preg_replace('/\s+/', ' ', $actual); + $expected = preg_replace('/\s+/', ' ', $expected); + $actual = preg_replace('/(?<=>)\s+(?=<)/', '', trim($actual)); + $expected = preg_replace('/(?<=>)\s+(?=<)/', '', trim($expected)); + + $normalize_attributes = static function( $token ) { + if ( preg_match( '#^(<[a-z0-9-]+)(\s[^>]+)#i', $token, $matches ) ) { + $token = $matches[1]; + + $attrs = array_map( 'trim', array_filter( preg_split( '#(\s+[^"\'\s=]+(?:=(?:"[^"]+"|\'[^\']+\'|[^"\'\s]+))?)#', $matches[2], -1, PREG_SPLIT_DELIM_CAPTURE ) ) ); + sort( $attrs ); + $attrs = array_map( + static function( $attr ) { + return ' ' . $attr; + }, + $attrs + ); + } + return $token; + }; + + $expected_tokens = array_map( $normalize_attributes, array_filter( preg_split( '#(<[^>]+>|[^<>]+)#', $expected, -1, PREG_SPLIT_DELIM_CAPTURE ) ) ); + $actual_tokens = array_map( $normalize_attributes, array_filter( preg_split( '#(<[^>]+>|[^<>]+)#', $actual, -1, PREG_SPLIT_DELIM_CAPTURE ) ) ); + + $this->assertEquals( $expected_tokens, $actual_tokens ); } } From 95e43f7249cb086386a41df1808cf228dcb35633 Mon Sep 17 00:00:00 2001 From: Alain Schlesser Date: Tue, 2 Jun 2020 07:05:54 +0200 Subject: [PATCH 12/18] Add CssRule class and tests --- lib/optimizer/src/CssRule.php | 319 ++++++++++++++++++++++++++++ lib/optimizer/tests/CssRuleTest.php | 174 +++++++++++++++ 2 files changed, 493 insertions(+) create mode 100644 lib/optimizer/src/CssRule.php create mode 100644 lib/optimizer/tests/CssRuleTest.php diff --git a/lib/optimizer/src/CssRule.php b/lib/optimizer/src/CssRule.php new file mode 100644 index 00000000000..0d614ae18c5 --- /dev/null +++ b/lib/optimizer/src/CssRule.php @@ -0,0 +1,319 @@ +selectors = array_unique(array_filter(array_map([$this, 'normalizeSelector'], $this->separateSelectors($selectors)))); + $this->properties = array_unique(array_filter(array_map([$this, 'normalizeProperty'], $this->separateProperties($properties)))); + + sort($this->selectors); + sort($this->properties); + } + + /** + * Create a new CSS rule that is wrapped in a media query. + * + * @param string $mediaQuery Media query to wrap the CSS rule in. + * @param string|string[] $selectors One or more selectors to use. + * @param string|string[] $properties One or more properties to apply to the selector(s). + * @return self CSS rule wrapped in a media query. + */ + public static function withMediaQuery($mediaQuery, $selectors, $properties) + { + $cssRule = new self($selectors, $properties); + $cssRule->mediaQuery = $mediaQuery; + return $cssRule; + } + + /** + * Get the selector(s) for this CSS rule. + * + * @return string[] Selector(s) of the CSS rule. + */ + public function getSelectors() + { + return $this->selectors; + } + + /** + * Get the properties for this CSS rule. + * + * @return string[] Properties of the CSS rule. + */ + public function getProperties() + { + return $this->properties; + } + + /** + * Get the media query for this CSS rule. + * + * @return string Media query for the CSS rule or an empty string if none is set. + */ + public function getMediaQuery() + { + return $this->mediaQuery; + } + + /** + * Get the CSS for this CSS rule. + * + * @return string CSS for this CSS rule. + */ + public function getCss() + { + if ($this->renderedCss === null) { + $selectors = implode(',', $this->selectors); + + $properties = implode( + ';', + array_map( + static function ($property) { + return trim($property, " \t\n\r\0\x0B;"); + }, + $this->properties + ) + ); + + if (empty($selectors) || empty($properties)) { + $this->renderedCss = ''; + } else { + $this->renderedCss = "{$selectors}{{$properties}}"; + + if (! empty($this->mediaQuery)) { + $this->renderedCss = "{$this->mediaQuery}{{$this->renderedCss}}"; + } + } + } + + return $this->renderedCss; + } + + /** + * Apply the provided ID across all ID placeholders. + * + * @param string $id ID to apply. + * @return self + */ + public function applyID($id) + { + $replacement_callback = static function ($css) use ($id) { + return str_replace(self::ID_PLACEHOLDER, $id, $css); + }; + + $this->selectors = array_map($replacement_callback, $this->selectors); + $this->properties = array_map($replacement_callback, $this->properties); + + // Reset caches so they will need to be rebuilt. + $this->renderedCss = null; + $this->byteCount = null; + + return $this; + } + + /** + * Check if the CSS rule can be merged with another provided CSS rule. + * + * @param CssRule $that CSS rule to check against. + * @return bool Whether the two CSS rules can be merged. + */ + public function canBeMerged(CssRule $that) + { + if ($this->mediaQuery !== $that->mediaQuery) { + return false; + } + + if ( + count($this->properties) !== count($that->properties) + || array_diff($this->properties, $that->properties) + ) { + return false; + } + + return true; + } + + /** + * Merge this CSS rule with another CSS rule. + * + * This should only be done to same-properties rules within the same media query, + * as the result will be wild otherwise. + * + * @param CssRule $that CSS rule to merge the current one with. + * @return CssRule Merged Css rule. + */ + public function mergeWith(CssRule $that) + { + $cssRule = new self( + array_merge($this->selectors, $that->selectors), + array_merge($this->properties, $that->properties) + ); + + $cssRule->mediaQuery = $this->mediaQuery; + + return $cssRule; + } + + /** + * Get the byte count for the CSS rule. + * + * @return int Byte count of the CSS rule. + */ + public function getByteCount() + { + if ($this->byteCount === null) { + $this->byteCount = strlen($this->getCss()); + } + + return $this->byteCount; + } + + /** + * Normalize a single selector. + * + * @param string $selector Selector to normalize. + * @return string Normalized selector. + */ + private function normalizeSelector($selector) + { + // Turn all series of whitespace into single spaces. + $selector = preg_replace('/\s+/', ' ', $selector); + + // Remove spaces around selector qualifiers to keep properties compact. + $selector = preg_replace('/ ?([>+~]) ?/', '$1', $selector); + + // Remove leading and trailing whitespace and commas. + $selector = trim($selector, " \t\n\r\0\x0B;"); + + return $selector; + } + + /** + * Normalize single property. + * + * @param string $property Property to normalize. + * @return string Normalized property. + */ + private function normalizeProperty($property) + { + // Turn all series of whitespace into single spaces. + $property = preg_replace('/\s+/', ' ', $property); + + // Remove spaces around colons and semicolons to keep properties compact. + $property = preg_replace('/ ?([:;]) ?/', '$1', $property); + + // Deduplicate semicolons. + $property = preg_replace('/([;]+)/', ';', $property); + + // Remove leading and trailing whitespace and semicolons. + $property = trim($property, " \t\n\r\0\x0B;"); + + return $property; + } + + /** + * Separate selectors into individual values. + * + * @param string|string[]|array[] $selectors Selectors to separate. + * @return string[] Separated selectors. + */ + private function separateSelectors($selectors) + { + $separatedSelectors = []; + + foreach ((array)$selectors as $selectorString) { + if (is_array($selectorString)) { + $separatedSelectors = array_merge($separatedSelectors, $this->separateSelectors($selectorString)); + } else { + $separatedSelectors = array_merge($separatedSelectors, explode(',', $selectorString)); + } + } + + return $separatedSelectors; + } + + /** + * Separate properties into individual values. + * + * @param string|string[]|array[] $properties Properties to separate. + * @return string[] Separated properties. + */ + private function separateProperties($properties) + { + $separatedProperties = []; + + foreach ((array)$properties as $propertyString) { + if (is_array($propertyString)) { + $separatedProperties = array_merge($separatedProperties, $this->separateProperties($propertyString)); + } else { + $separatedProperties = array_merge($separatedProperties, explode(';', $propertyString)); + } + } + + return $separatedProperties; + } +} diff --git a/lib/optimizer/tests/CssRuleTest.php b/lib/optimizer/tests/CssRuleTest.php new file mode 100644 index 00000000000..e4e58399616 --- /dev/null +++ b/lib/optimizer/tests/CssRuleTest.php @@ -0,0 +1,174 @@ + [null, null, ''], + 'selector with null' => ['h1', null, ''], + 'null with property' => [null, 'color:red', ''], + + 'empty strings' => ['', '', ''], + 'selector with empty string' => ['h1', '', ''], + 'empty string with property' => ['', 'color:red', ''], + + 'single string selector, single string property' => ['h1', 'color:red', 'h1{color:red}'], + 'single array selector, single array property' => [['h1'], ['color:red'], 'h1{color:red}'], + + 'single string selector, multiple properties in string' => ['h1', 'color:red;background-color:green;font-weight:bold', 'h1{background-color:green;color:red;font-weight:bold}'], + 'single string selector, multiple properties in array' => ['h1', ['color:red', 'background-color:green', 'font-weight:bold'], 'h1{background-color:green;color:red;font-weight:bold}'], + 'single array selector, multiple properties in string' => [['h1'], 'color:red;background-color:green;font-weight:bold', 'h1{background-color:green;color:red;font-weight:bold}'], + 'single array selector, multiple properties in array' => [['h1'], ['color:red', 'background-color:green', 'font-weight:bold'], 'h1{background-color:green;color:red;font-weight:bold}'], + + 'multiple selectors in string, single string property' => ['h1,h2,h3', 'color:red', 'h1,h2,h3{color:red}'], + 'multiple selectors in array, single string property' => [['h1', 'h2', 'h3'], 'color:red', 'h1,h2,h3{color:red}'], + 'multiple selectors in string, single array property' => ['h1,h2,h3', ['color:red'], 'h1,h2,h3{color:red}'], + 'multiple selectors in array, single array property' => [['h1', 'h2', 'h3'], ['color:red'], 'h1,h2,h3{color:red}'], + + 'multiple selectors in string, multiple properties in string' => ['h1,h2,h3', 'color:red;background-color:green;font-weight:bold', 'h1,h2,h3{background-color:green;color:red;font-weight:bold}'], + 'multiple selectors in array, multiple properties in string' => [['h1', 'h2', 'h3'], 'color:red;background-color:green;font-weight:bold', 'h1,h2,h3{background-color:green;color:red;font-weight:bold}'], + 'multiple selectors in string, multiple properties in array' => ['h1,h2,h3', ['color:red', 'background-color:green', 'font-weight:bold'], 'h1,h2,h3{background-color:green;color:red;font-weight:bold}'], + 'multiple selectors in array, multiple properties in array' => [['h1', 'h2', 'h3'], ['color:red', 'background-color:green', 'font-weight:bold'], 'h1,h2,h3{background-color:green;color:red;font-weight:bold}'], + + 'id in selector' => [ '#__ID__', 'color:red', '#i-amp-42{color:red}'], + 'multiple ids in selector' => [ '#__ID__.__ID__-button', 'color:red', '#i-amp-42.i-amp-42-button{color:red}'], + + 'normalizes selectors and properties' => [ + " \t\t , #some-id \n \n\n > \t .some-class \t \n .another-class \t \n + element ~ another-element \n \t , ,, #another-id \n .with-class \n \t , ", + " \t\t ; color \n \t : \n \t\n red ;;; ; \n ; \t \n background-color:white;; \t \n ; ", + '#another-id .with-class,#some-id>.some-class .another-class+element~another-element{background-color:white;color:red}' + ], + ]; + } + + /** + * Test CssRule output. + * + * @dataProvider dataCssRuleOutput + * + * @covers CssRule::__construct() + * @covers CssRule::applyID() + * @covers CssRule::getCss() + */ + public function testCssRuleOutput($selectors, $properties, $expected) + { + $cssRule = new CssRule($selectors, $properties); + $css = $cssRule + ->applyID('i-amp-42') + ->getCss(); + $this->assertEquals($expected, $css); + } + + public function dataCssRuleMerging() + { + return [ + 'different single property' => [['.class1', 'color:red'], ['.class2', 'color:blue'], false], + 'same single property' => [['.class1', 'color:red'], ['.class2', 'color:red'], true, ['', ['.class1', '.class2'], ['color:red']]], + + 'different multiple properties' => [['.class1', 'color:red;background-color:green'], ['.class2', 'color:red;background-color:blue'], false], + 'same multiple properties' => [['.class1', 'color:red;background-color:green'], ['.class2', 'color:red;background-color:green'], true, ['', ['.class1', '.class2'], ['background-color:green', 'color:red']]], + + 'multiple selectors with different single property' => [['.class1,.class2', 'color:red'], ['.class3,.class4', 'color:blue'], false], + 'multiple selectors with same single property' => [['.class1,.class2', 'color:red'], ['.class3,.class4', 'color:red'], true, ['', ['.class1', '.class2', '.class3', '.class4'], ['color:red']]], + + 'multiple selectors with different multiple properties' => [['.class1,.class2', 'color:red;background-color:green'], ['.class3,.class4', 'color:red;background-color:blue'], false], + 'multiple selectors with same multiple properties' => [['.class1,.class2', 'color:red;background-color:green'], ['.class3,.class4', 'color:red;background-color:green'], true, ['', ['.class1', '.class2', '.class3', '.class4'], ['background-color:green', 'color:red']]], + + 'overlap in selectors' => [['.class1,.class2', 'color:red'], ['.class2,.class3', 'color:red'], true, ['', ['.class1', '.class2', '.class3'], ['color:red']]], + + 'same media query - different single property' => [['@media not all and (min-width: 650px)', '.class1', 'color:red'], ['@media not all and (min-width: 650px)', '.class2', 'color:blue'], false], + 'same media query - same single property' => [['@media not all and (min-width: 650px)', '.class1', 'color:red'], ['@media not all and (min-width: 650px)', '.class2', 'color:red'], true, ['@media not all and (min-width: 650px)', ['.class1', '.class2'], ['color:red']]], + + 'same media query - different multiple properties' => [['@media not all and (min-width: 650px)', '.class1', 'color:red;background-color:green'], ['@media not all and (min-width: 650px)', '.class2', 'color:red;background-color:blue'], false], + 'same media query - same multiple properties' => [['@media not all and (min-width: 650px)', '.class1', 'color:red;background-color:green'], ['@media not all and (min-width: 650px)', '.class2', 'color:red;background-color:green'], true, ['@media not all and (min-width: 650px)', ['.class1', '.class2'], ['background-color:green', 'color:red']]], + + 'same media query - multiple selectors with different single property' => [['@media not all and (min-width: 650px)', '.class1,.class2', 'color:red'], ['@media not all and (min-width: 650px)', '.class3,.class4', 'color:blue'], false], + 'same media query - multiple selectors with same single property' => [['@media not all and (min-width: 650px)', '.class1,.class2', 'color:red'], ['@media not all and (min-width: 650px)', '.class3,.class4', 'color:red'], true, ['@media not all and (min-width: 650px)', ['.class1', '.class2', '.class3', '.class4'], ['color:red']]], + + 'same media query - multiple selectors with different multiple properties' => [['@media not all and (min-width: 650px)', '.class1,.class2', 'color:red;background-color:green'], ['@media not all and (min-width: 650px)', '.class3,.class4', 'color:red;background-color:blue'], false], + 'same media query - multiple selectors with same multiple properties' => [['@media not all and (min-width: 650px)', '.class1,.class2', 'color:red;background-color:green'], ['@media not all and (min-width: 650px)', '.class3,.class4', 'color:red;background-color:green'], true, ['@media not all and (min-width: 650px)', ['.class1', '.class2', '.class3', '.class4'], ['background-color:green', 'color:red']]], + + 'same media query - overlap in selectors' => [['@media not all and (min-width: 650px)', '.class1,.class2', 'color:red'], ['@media not all and (min-width: 650px)', '.class2,.class3', 'color:red'], true, ['@media not all and (min-width: 650px)', ['.class1', '.class2', '.class3'], ['color:red']]], + + 'different media query - different single property' => [['@media not all and (min-width: 650px)', '.class1', 'color:red'], ['@media not all and (min-width: 950px)', '.class2', 'color:blue'], false], + 'different media query - same single property' => [['@media not all and (min-width: 650px)', '.class1', 'color:red'], ['@media not all and (min-width: 950px)', '.class2', 'color:red'], false], + + 'different media query - different multiple properties' => [['@media not all and (min-width: 650px)', '.class1', 'color:red;background-color:green'], ['@media not all and (min-width: 950px)', '.class2', 'color:red;background-color:blue'], false], + 'different media query - same multiple properties' => [['@media not all and (min-width: 650px)', '.class1', 'color:red;background-color:green'], ['@media not all and (min-width: 950px)', '.class2', 'color:red;background-color:green'], false], + + 'different media query - multiple selectors with different single property' => [['@media not all and (min-width: 650px)', '.class1,.class2', 'color:red'], ['@media not all and (min-width: 950px)', '.class3,.class4', 'color:blue'], false], + 'different media query - multiple selectors with same single property' => [['@media not all and (min-width: 650px)', '.class1,.class2', 'color:red'], ['@media not all and (min-width: 950px)', '.class3,.class4', 'color:red'], false], + + 'different media query - multiple selectors with different multiple properties' => [['@media not all and (min-width: 650px)', '.class1,.class2', 'color:red;background-color:green'], ['@media not all and (min-width: 950px)', '.class3,.class4', 'color:red;background-color:blue'], false], + 'different media query - multiple selectors with same multiple properties' => [['@media not all and (min-width: 650px)', '.class1,.class2', 'color:red;background-color:green'], ['@media not all and (min-width: 950px)', '.class3,.class4', 'color:red;background-color:green'], false], + + 'different media query - overlap in selectors' => [['@media not all and (min-width: 650px)', '.class1,.class2', 'color:red'], ['@media not all and (min-width: 950px)', '.class2,.class3', 'color:red'], false], + + 'single-sided media query - different single property' => [['@media not all and (min-width: 650px)', '.class1', 'color:red'], ['.class2', 'color:blue'], false], + 'single-sided media query - same single property' => [['@media not all and (min-width: 650px)', '.class1', 'color:red'], ['.class2', 'color:red'], false], + + 'single-sided media query - different multiple properties' => [['@media not all and (min-width: 650px)', '.class1', 'color:red;background-color:green'], ['.class2', 'color:red;background-color:blue'], false], + 'single-sided media query - same multiple properties' => [['@media not all and (min-width: 650px)', '.class1', 'color:red;background-color:green'], ['.class2', 'color:red;background-color:green'], false], + + 'single-sided media query - multiple selectors with different single property' => [['@media not all and (min-width: 650px)', '.class1,.class2', 'color:red'], ['.class3,.class4', 'color:blue'], false], + 'single-sided media query - multiple selectors with same single property' => [['@media not all and (min-width: 650px)', '.class1,.class2', 'color:red'], ['.class3,.class4', 'color:red'], false], + + 'single-sided media query - multiple selectors with different multiple properties' => [['@media not all and (min-width: 650px)', '.class1,.class2', 'color:red;background-color:green'], ['.class3,.class4', 'color:red;background-color:blue'], false], + 'single-sided media query - multiple selectors with same multiple properties' => [['@media not all and (min-width: 650px)', '.class1,.class2', 'color:red;background-color:green'], ['.class3,.class4', 'color:red;background-color:green'], false], + + 'single-sided media query - overlap in selectors' => [['@media not all and (min-width: 650px)', '.class1,.class2', 'color:red'], ['.class2,.class3', 'color:red'], false], + ]; + } + + /** + * Test CssRule merging. + * + * @dataProvider dataCssRuleMerging + * + * @covers CssRule::__construct() + * @covers CssRule::withMediaQuery() + * @covers CssRule::canBeMerged() + * @covers CssRule::mergeWith() + */ + public function testCssRulesCanBeMerged($ruleAValues, $ruleBValues, $expectedCanBeMerged, $expectedMergedRuleValues = []) + { + $ruleA = count($ruleAValues) > 2 + ? CssRule::withMediaQuery($ruleAValues[0], $ruleAValues[1], $ruleAValues[2]) + : new CssRule($ruleAValues[0], $ruleAValues[1]); + + $ruleB = count($ruleBValues) > 2 + ? CssRule::withMediaQuery($ruleBValues[0], $ruleBValues[1], $ruleBValues[2]) + : new CssRule($ruleBValues[0], $ruleBValues[1]); + + $this->assertEquals($expectedCanBeMerged, $ruleA->canBeMerged($ruleB)); + $this->assertEquals($expectedCanBeMerged, $ruleB->canBeMerged($ruleA)); + + if ($expectedCanBeMerged) { + $mergedRuleFromA = $ruleA->mergeWith($ruleB); + $mergedRuleFromB = $ruleB->mergeWith($ruleA); + + $this->assertEquals($expectedMergedRuleValues[0], $mergedRuleFromA->getMediaQuery()); + $this->assertEquals($expectedMergedRuleValues[0], $mergedRuleFromB->getMediaQuery()); + + $this->assertEquals($expectedMergedRuleValues[1], $mergedRuleFromA->getSelectors()); + $this->assertEquals($expectedMergedRuleValues[1], $mergedRuleFromB->getSelectors()); + + $this->assertEquals($expectedMergedRuleValues[2], $mergedRuleFromA->getProperties()); + $this->assertEquals($expectedMergedRuleValues[2], $mergedRuleFromB->getProperties()); + } + } +} From 34e795b58fd3fb5f1e938bd8d39b3137f17550d4 Mon Sep 17 00:00:00 2001 From: Alain Schlesser Date: Tue, 2 Jun 2020 07:06:15 +0200 Subject: [PATCH 13/18] Add CssRules collection class and tests --- lib/optimizer/src/CssRules.php | 140 +++++++++++++++++++++++++++ lib/optimizer/tests/CssRulesTest.php | 62 ++++++++++++ 2 files changed, 202 insertions(+) create mode 100644 lib/optimizer/src/CssRules.php create mode 100644 lib/optimizer/tests/CssRulesTest.php diff --git a/lib/optimizer/src/CssRules.php b/lib/optimizer/src/CssRules.php new file mode 100644 index 00000000000..97cc9db63c7 --- /dev/null +++ b/lib/optimizer/src/CssRules.php @@ -0,0 +1,140 @@ +add($cssRule); + } + ); + + return $cssRules; + } + + /** + * Add a CSS rule to the collection. + * + * @param CssRule $cssRule + * @return CssRules Adapted collection with the added CSS rule. + */ + public function add(CssRule $cssRule) + { + $clone = clone $this; + + if (empty($clone->cssRules)) { + $clone->cssRules = [$cssRule]; + + return $clone; + } + + foreach ($clone->cssRules as $index => $existingCssRule) { + if ($cssRule->canBeMerged($existingCssRule)) { + $clone->cssRules[$index] = $cssRule->mergeWith($existingCssRule); + // Rendered CSS and byte count need to be rebuilt, as some previously rendered CSS rule has changed. + $clone->renderedCss = null; + $clone->byteCount = null; + + return $clone; + } + } + + $clone->cssRules[] = $cssRule; + + if ($clone->renderedCss !== null) { + // As we didn't merge, we can save rerendering and just concat the single rule. + $clone->renderedCss .= $cssRule->getCss(); + } + + if ($clone->byteCount !== null) { + // As we didn't merge, we can save recounting and just add the bytes of the single rule. + $clone->byteCount += $cssRule->getByteCount(); + } + + return $clone; + } + + /** + * Get the CSS for the entire collection of CSS rules. + * + * @return string String representation of the collection of CSS rules. + */ + public function getCss() + { + if ($this->renderedCss === null) { + $this->renderedCss = array_reduce( + $this->cssRules, + static function ($css, CssRule $cssRule) { + return $css . $cssRule->getCss(); + }, + '' + ); + } + + return $this->renderedCss; + } + + /** + * Get the byte count for the entire collection of CSS rules. + * + * @return int Byte count of the collection of CSS rules. + */ + public function getByteCount() + { + if ($this->byteCount === null) { + $this->byteCount = array_reduce( + $this->cssRules, + static function ($byteCount, CssRule $cssRule) { + return $byteCount + $cssRule->getByteCount(); + }, + 0 + ); + } + + return $this->byteCount; + } +} diff --git a/lib/optimizer/tests/CssRulesTest.php b/lib/optimizer/tests/CssRulesTest.php new file mode 100644 index 00000000000..dff33db6c3b --- /dev/null +++ b/lib/optimizer/tests/CssRulesTest.php @@ -0,0 +1,62 @@ +assertEquals('', $cssRules->getCss()); + } + + public function testSingleRule() + { + $cssRules = (new CssRules()) + ->add(new CssRule('h1', 'color:red')); + $this->assertEquals('h1{color:red}', $cssRules->getCss()); + } + + public function testMultipleRules() + { + $cssRules = (new CssRules()) + ->add(new CssRule('h1', 'color:red')) + ->add(new CssRule('h2', 'color:green')) + ->add(new CssRule('h3', 'color:blue')); + $this->assertEquals('h1{color:red}h2{color:green}h3{color:blue}', $cssRules->getCss()); + } + + public function testMultipleRulesWithOverlap() + { + $cssRules = (new CssRules()) + ->add(new CssRule('h1', 'color:red')) + ->add(new CssRule('h2', 'color:green')) + ->add(new CssRule('h3', 'color:red')) + ->add(new CssRule('h4', 'color:green')) + ->add(new CssRule('h5', 'color:red')); + $this->assertEquals('h1,h3,h5{color:red}h2,h4{color:green}', $cssRules->getCss()); + } + + public function testNamedConstructor() + { + $cssRules = CssRules::fromCssRuleArray( + [ + new CssRule('h1', 'color:red'), + new CssRule('h2', 'color:green'), + new CssRule('h3', 'color:red'), + new CssRule('h4', 'color:green'), + new CssRule('h5', 'color:red'), + ] + ); + $this->assertEquals('h1,h3,h5{color:red}h2,h4{color:green}', $cssRules->getCss()); + } +} From 6a978e7251c658c2025d4cee35be9e3f77abe5ca Mon Sep 17 00:00:00 2001 From: Alain Schlesser Date: Tue, 2 Jun 2020 07:06:51 +0200 Subject: [PATCH 14/18] Adapt ServerSideRendering transformer to make use of CssRule(s) --- .../src/Transformer/ServerSideRendering.php | 139 +++++++++++++----- 1 file changed, 100 insertions(+), 39 deletions(-) diff --git a/lib/optimizer/src/Transformer/ServerSideRendering.php b/lib/optimizer/src/Transformer/ServerSideRendering.php index dad7e2ece10..99c17cad9d3 100644 --- a/lib/optimizer/src/Transformer/ServerSideRendering.php +++ b/lib/optimizer/src/Transformer/ServerSideRendering.php @@ -9,6 +9,8 @@ use AmpProject\CssLength; use AmpProject\Extension; use AmpProject\Layout; +use AmpProject\Optimizer\CssRule; +use AmpProject\Optimizer\CssRules; use AmpProject\Optimizer\Error; use AmpProject\Optimizer\ErrorCollection; use AmpProject\Optimizer\Exception\InvalidArgument; @@ -105,7 +107,7 @@ final class ServerSideRendering implements Transformer /** * The