From 2be2d2844d9a611c018ecef462339f1e998ca0b5 Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Tue, 19 Mar 2019 11:05:15 +0000 Subject: [PATCH 01/46] Add homepage --- composer.json | 3 +- composer.lock | 162 ++++++++++-------- config/bundles.php | 2 +- config/packages/dev/content_page.yaml | 8 - config/packages/dev/libero_page.yaml | 13 ++ ...efaults.yaml => libero_page_defaults.yaml} | 2 +- config/packages/test/content_page.yaml | 8 - config/packages/test/libero_page.yaml | 10 ++ config/routes.yaml | 4 +- symfony.lock | 9 +- vendor-extra/ContentPageBundle/composer.json | 46 ----- .../src/Controller/ContentController.php | 72 -------- .../ContentPageExtension.php | 65 ------- .../src/Event/CreateContentPageEvent.php | 59 ------- .../src/EventListener/NamespaceListener.php | 24 --- .../src/Resources/config/services.xml | 26 --- vendor-extra/JatsContentBundle/composer.json | 2 +- .../src/EventListener/BodyListener.php | 10 +- .../EventListener/ContentHeaderListener.php | 10 +- .../src/EventListener/ItemTagsListener.php | 10 +- .../src/Resources/config/services.xml | 10 +- .../tests/EventListener/BodyListenerTest.php | 10 +- .../ContentHeaderListenerTest.php | 12 +- .../EventListener/ItemTagsListenerTest.php | 10 +- .../tests/ViewConverter/BoldVisitorTest.php | 4 +- ...ntArticleTitleContentHeaderVisitorTest.php | 4 +- .../FrontItemTagsVisitorTest.php | 4 +- ...ntSubjectGroupContentHeaderVisitorTest.php | 4 +- .../ViewConverter/HeadingVisitorTest.php | 4 +- .../tests/ViewConverter/ItalicVisitorTest.php | 4 +- .../KeywordGroupTagListVisitorTest.php | 4 +- .../tests/ViewConverter/LinkVisitorTest.php | 4 +- .../ViewConverter/ParagraphVisitorTest.php | 4 +- .../ViewConverter/SectionVisitorTest.php | 4 +- .../tests/ViewConverter/SubVisitorTest.php | 4 +- .../tests/ViewConverter/SupVisitorTest.php | 4 +- .../LiberoContentBundle/composer.json | 2 +- .../EventListener/ContentHeaderListener.php | 10 +- .../src/Resources/config/services.xml | 2 +- .../ContentHeaderListenerTest.php | 12 +- .../tests/ViewConverter/BoldVisitorTest.php | 4 +- .../FrontContentHeaderVisitorTest.php | 4 +- .../tests/ViewConverter/ItalicVisitorTest.php | 4 +- .../tests/ViewConverter/SubVisitorTest.php | 4 +- .../tests/ViewConverter/SupVisitorTest.php | 4 +- .../ViewConverter/TitleHeadingVisitorTest.php | 4 +- vendor-extra/LiberoPageBundle/composer.json | 33 ++++ .../src/Controller/PageController.php | 57 ++++++ .../LiberoPageConfiguration.php} | 23 ++- .../LiberoPageExtension.php | 52 ++++++ .../src/Event/CreatePageEvent.php | 83 +++++++++ .../src/Event/LoadPageEvent.php | 50 ++++++ .../src/EventListener/ContentItemListener.php | 48 ++++++ .../HomepageContentHeaderListener.php | 35 ++++ .../src/EventListener/LiberoPageListener.php | 40 +++++ .../src/EventListener/NamespaceListener.php | 26 +++ .../src/EventListener/TitleListener.php | 31 ++++ .../src/LiberoPageBundle.php} | 4 +- .../src/Resources/config/services.xml | 59 +++++++ .../translations/messages+intl-icu.en.xlf | 19 ++ .../src/Routing/PageRouteLoader.php} | 14 +- .../src/functions.php | 2 +- .../Controller/ContentControllerTest.php | 14 +- .../tests/GuzzleTestCase.php | 2 +- .../tests/TextDirectionTest.php | 4 +- .../tests/TwigTestCase.php | 2 +- .../tests/ViewConvertingTestCase.php | 2 +- .../tests/XmlTestCase.php | 2 +- .../tests/ViewConverter/LangVisitorTest.php | 2 +- .../tests/Views/ViewConverterRegistryTest.php | 2 +- 70 files changed, 797 insertions(+), 494 deletions(-) delete mode 100644 config/packages/dev/content_page.yaml create mode 100644 config/packages/dev/libero_page.yaml rename config/packages/{content_page_defaults.yaml => libero_page_defaults.yaml} (84%) delete mode 100644 config/packages/test/content_page.yaml create mode 100644 config/packages/test/libero_page.yaml delete mode 100644 vendor-extra/ContentPageBundle/composer.json delete mode 100644 vendor-extra/ContentPageBundle/src/Controller/ContentController.php delete mode 100644 vendor-extra/ContentPageBundle/src/DependencyInjection/ContentPageExtension.php delete mode 100644 vendor-extra/ContentPageBundle/src/Event/CreateContentPageEvent.php delete mode 100644 vendor-extra/ContentPageBundle/src/EventListener/NamespaceListener.php delete mode 100644 vendor-extra/ContentPageBundle/src/Resources/config/services.xml create mode 100644 vendor-extra/LiberoPageBundle/composer.json create mode 100644 vendor-extra/LiberoPageBundle/src/Controller/PageController.php rename vendor-extra/{ContentPageBundle/src/DependencyInjection/ContentPageConfiguration.php => LiberoPageBundle/src/DependencyInjection/LiberoPageConfiguration.php} (61%) create mode 100644 vendor-extra/LiberoPageBundle/src/DependencyInjection/LiberoPageExtension.php create mode 100644 vendor-extra/LiberoPageBundle/src/Event/CreatePageEvent.php create mode 100644 vendor-extra/LiberoPageBundle/src/Event/LoadPageEvent.php create mode 100644 vendor-extra/LiberoPageBundle/src/EventListener/ContentItemListener.php create mode 100644 vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentHeaderListener.php create mode 100644 vendor-extra/LiberoPageBundle/src/EventListener/LiberoPageListener.php create mode 100644 vendor-extra/LiberoPageBundle/src/EventListener/NamespaceListener.php create mode 100644 vendor-extra/LiberoPageBundle/src/EventListener/TitleListener.php rename vendor-extra/{ContentPageBundle/src/ContentPageBundle.php => LiberoPageBundle/src/LiberoPageBundle.php} (51%) create mode 100644 vendor-extra/LiberoPageBundle/src/Resources/config/services.xml create mode 100644 vendor-extra/LiberoPageBundle/src/Resources/translations/messages+intl-icu.en.xlf rename vendor-extra/{ContentPageBundle/src/Routing/ContentPageRouteLoader.php => LiberoPageBundle/src/Routing/PageRouteLoader.php} (57%) rename vendor-extra/{ContentPageBundle => LiberoPageBundle}/src/functions.php (92%) rename vendor-extra/{ContentPageBundle => LiberoPageBundle}/tests/Controller/ContentControllerTest.php (91%) rename vendor-extra/{ContentPageBundle => LiberoPageBundle}/tests/GuzzleTestCase.php (96%) rename vendor-extra/{ContentPageBundle => LiberoPageBundle}/tests/TextDirectionTest.php (90%) rename vendor-extra/{ContentPageBundle => LiberoPageBundle}/tests/TwigTestCase.php (96%) rename vendor-extra/{ContentPageBundle => LiberoPageBundle}/tests/ViewConvertingTestCase.php (95%) rename vendor-extra/{ContentPageBundle => LiberoPageBundle}/tests/XmlTestCase.php (92%) diff --git a/composer.json b/composer.json index d90a7a9..e0ba746 100644 --- a/composer.json +++ b/composer.json @@ -14,6 +14,7 @@ "tests\\Libero\\ContentPageBundle\\": "vendor-extra/ContentPageBundle/tests/", "tests\\Libero\\JatsContentBundle\\": "vendor-extra/JatsContentBundle/tests/", "tests\\Libero\\LiberoContentBundle\\": "vendor-extra/LiberoContentBundle/tests/", + "tests\\Libero\\LiberoPageBundle\\": "vendor-extra/LiberoPageBundle/tests/", "tests\\Libero\\ViewsBundle\\": "vendor-extra/ViewsBundle/tests/" } }, @@ -23,9 +24,9 @@ "ext-intl": "*", "ext-mbstring": "*", "csa/guzzle-bundle": "^3.1", - "libero/content-page-bundle": "^1.0@dev", "libero/jats-content-bundle": "^1.0@dev", "libero/libero-content-bundle": "^1.0@dev", + "libero/page-bundle": "^1.0@dev", "libero/patterns-bundle": "^1.0@dev", "libero/views-bundle": "^1.0@dev", "symfony/asset": "^4.1", diff --git a/composer.lock b/composer.lock index 9747e40..af9a214 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c950d2b50b4e9b03a940dbbc21374e2c", + "content-hash": "49447afa5630481ed04c6cc25f234464", "packages": [ { "name": "csa/guzzle-bundle", @@ -390,32 +390,33 @@ }, { "name": "guzzlehttp/psr7", - "version": "1.4.2", + "version": "1.5.2", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c" + "reference": "9f83dded91781a01c63574e387eaa769be769115" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c", - "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/9f83dded91781a01c63574e387eaa769be769115", + "reference": "9f83dded91781a01c63574e387eaa769be769115", "shasum": "" }, "require": { "php": ">=5.4.0", - "psr/http-message": "~1.0" + "psr/http-message": "~1.0", + "ralouphie/getallheaders": "^2.0.5" }, "provide": { "psr/http-message-implementation": "1.0" }, "require-dev": { - "phpunit/phpunit": "~4.0" + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-master": "1.5-dev" } }, "autoload": { @@ -445,46 +446,37 @@ "keywords": [ "http", "message", + "psr-7", "request", "response", "stream", "uri", "url" ], - "time": "2017-03-20T17:10:46+00:00" + "time": "2018-12-04T20:46:45+00:00" }, { - "name": "libero/content-page-bundle", + "name": "libero/jats-content-bundle", "version": "dev-master", "dist": { "type": "path", - "url": "./vendor-extra/ContentPageBundle", - "reference": "25ce8ce5fa06cc34b3ee6bb25bd8eeefd69ee7ad", - "shasum": null + "url": "./vendor-extra/JatsContentBundle", + "reference": "72cb43052a8e012ca574e9d9b3e03059ca56e7f5" }, "require": { + "ext-dom": "*", "fluentdom/fluentdom": "^7.0", - "guzzlehttp/guzzle": "^6.3", - "libero/patterns-bundle": "^1.0@dev", + "libero/page-bundle": "^1.0@dev", "libero/views-bundle": "^1.0@dev", "php": "^7.2", - "psr/http-message": "^1.0", - "punic/punic": "^3.3", "symfony/config": "^4.1", + "symfony/contracts": "^1.0", "symfony/dependency-injection": "^4.1", "symfony/event-dispatcher": "^4.1", - "symfony/http-foundation": "^4.1", - "symfony/http-kernel": "^4.1", - "symfony/routing": "^4.1", - "twig/twig": "^2.5" + "symfony/http-kernel": "^4.1" }, "require-dev": { - "csa/guzzle-cache-middleware": "^1.0", - "guzzlehttp/psr7": "^1.4", - "php-vfs/php-vfs": "^1.4", - "phpunit/phpunit": "^7.3", - "symfony/css-selector": "^4.1", - "symfony/dom-crawler": "^4.1" + "phpunit/phpunit": "^7.3" }, "type": "symfony-bundle", "extra": { @@ -494,34 +486,28 @@ }, "autoload": { "psr-4": { - "Libero\\ContentPageBundle\\": "src/" - }, - "files": [ - "src/functions.php" - ] + "Libero\\JatsContentBundle\\": "src/" + } }, "license": [ "MIT" ], - "description": "A Libero content page" + "description": "JATS content handler" }, { - "name": "libero/jats-content-bundle", + "name": "libero/libero-content-bundle", "version": "dev-master", "dist": { "type": "path", - "url": "./vendor-extra/JatsContentBundle", - "reference": "72d2bdc182dad6e2d47ca6aabcbfabe0af73cc83", - "shasum": null + "url": "./vendor-extra/LiberoContentBundle", + "reference": "9f13b48431cc730a3516ddcb7123890c5f2f4c95" }, "require": { - "ext-dom": "*", "fluentdom/fluentdom": "^7.0", - "libero/content-page-bundle": "^1.0@dev", + "libero/page-bundle": "^1.0@dev", "libero/views-bundle": "^1.0@dev", "php": "^7.2", "symfony/config": "^4.1", - "symfony/contracts": "^1.0", "symfony/dependency-injection": "^4.1", "symfony/event-dispatcher": "^4.1", "symfony/http-kernel": "^4.1" @@ -537,35 +523,31 @@ }, "autoload": { "psr-4": { - "Libero\\JatsContentBundle\\": "src/" + "Libero\\LiberoContentBundle\\": "src/" } }, "license": [ "MIT" ], - "description": "JATS content handler" + "description": "Libero content handler" }, { - "name": "libero/libero-content-bundle", + "name": "libero/page-bundle", "version": "dev-master", "dist": { "type": "path", - "url": "./vendor-extra/LiberoContentBundle", - "reference": "b834d04beca9847ee625a5c8016c2c0d4bd17f05", - "shasum": null + "url": "./vendor-extra/LiberoPageBundle", + "reference": "404a7a39bdd8bd5d48fe6e55248274dea6caf574" }, "require": { "fluentdom/fluentdom": "^7.0", - "libero/content-page-bundle": "^1.0@dev", - "libero/views-bundle": "^1.0@dev", + "guzzlehttp/promises": "^1.0", "php": "^7.2", - "symfony/config": "^4.1", - "symfony/dependency-injection": "^4.1", + "punic/punic": "^3.3", "symfony/event-dispatcher": "^4.1", - "symfony/http-kernel": "^4.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.3" + "symfony/http-foundation": "^4.1", + "symfony/http-kernel": "^4.1", + "twig/twig": "^2.5" }, "type": "symfony-bundle", "extra": { @@ -575,13 +557,16 @@ }, "autoload": { "psr-4": { - "Libero\\LiberoContentBundle\\": "src/" - } + "Libero\\LiberoPageBundle\\": "src/" + }, + "files": [ + "src/functions.php" + ] }, "license": [ "MIT" ], - "description": "Libero content handler" + "description": "Libero page" }, { "name": "libero/patterns-bundle", @@ -589,8 +574,7 @@ "dist": { "type": "path", "url": "./vendor-extra/LiberoPatternsBundle", - "reference": "f4f95e5e60168b7c4c252d53c5d28d1bdd76ef69", - "shasum": null + "reference": "f4f95e5e60168b7c4c252d53c5d28d1bdd76ef69" }, "require": { "php": "^7.2", @@ -618,8 +602,7 @@ "dist": { "type": "path", "url": "./vendor-extra/ViewsBundle", - "reference": "8f169b7bf3b964e8c8c73bfb587929b70287e692", - "shasum": null + "reference": "8f169b7bf3b964e8c8c73bfb587929b70287e692" }, "require": { "fluentdom/fluentdom": "^7.0", @@ -1039,6 +1022,46 @@ ], "time": "2018-12-07T16:55:52+00:00" }, + { + "name": "ralouphie/getallheaders", + "version": "2.0.5", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/5601c8a83fbba7ef674a7369456d12f1e0d0eafa", + "reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "require-dev": { + "phpunit/phpunit": "~3.7.0", + "satooshi/php-coveralls": ">=1.0" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "time": "2016-02-11T07:05:27+00:00" + }, { "name": "symfony/asset", "version": "v4.2.1", @@ -1492,20 +1515,21 @@ }, { "name": "symfony/event-dispatcher", - "version": "v4.1.7", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "552541dad078c85d9414b09c041ede488b456cd5" + "reference": "3354d2e6af986dd71f68b4e5cf4a933ab58697fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/552541dad078c85d9414b09c041ede488b456cd5", - "reference": "552541dad078c85d9414b09c041ede488b456cd5", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/3354d2e6af986dd71f68b4e5cf4a933ab58697fb", + "reference": "3354d2e6af986dd71f68b4e5cf4a933ab58697fb", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": "^7.1.3", + "symfony/contracts": "^1.0" }, "conflict": { "symfony/dependency-injection": "<3.4" @@ -1524,7 +1548,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -1551,7 +1575,7 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2018-10-10T13:52:42+00:00" + "time": "2019-02-23T15:17:42+00:00" }, { "name": "symfony/filesystem", @@ -5455,9 +5479,9 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { - "libero/content-page-bundle": 20, "libero/jats-content-bundle": 20, "libero/libero-content-bundle": 20, + "libero/page-bundle": 20, "libero/patterns-bundle": 20, "libero/views-bundle": 20 }, diff --git a/config/bundles.php b/config/bundles.php index ce97f49..8a31f74 100644 --- a/config/bundles.php +++ b/config/bundles.php @@ -4,9 +4,9 @@ return [ Csa\Bundle\GuzzleBundle\CsaGuzzleBundle::class => ['all' => true], - Libero\ContentPageBundle\ContentPageBundle::class => ['all' => true], Libero\JatsContentBundle\JatsContentBundle::class => ['all' => true], Libero\LiberoContentBundle\LiberoContentBundle::class => ['all' => true], + Libero\LiberoPageBundle\LiberoPageBundle::class => ['all' => true], Libero\LiberoPatternsBundle\LiberoPatternsBundle::class => ['all' => true], Libero\ViewsBundle\ViewsBundle::class => ['all' => true], Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true], diff --git a/config/packages/dev/content_page.yaml b/config/packages/dev/content_page.yaml deleted file mode 100644 index 817e397..0000000 --- a/config/packages/dev/content_page.yaml +++ /dev/null @@ -1,8 +0,0 @@ -content_page: - pages: - blog_article: - path: '/blog/{id}' - service: 'blog-articles' - scholarly_article: - path: '/articles/{id}' - service: 'scholarly-articles' diff --git a/config/packages/dev/libero_page.yaml b/config/packages/dev/libero_page.yaml new file mode 100644 index 0000000..d2109ca --- /dev/null +++ b/config/packages/dev/libero_page.yaml @@ -0,0 +1,13 @@ +libero_page: + pages: + homepage: + type: homepage + path: '/' + blog_article: + type: content + path: '/blog/{id}' + content_service: 'blog-articles' + scholarly_article: + type: content + path: '/articles/{id}' + content_service: 'scholarly-articles' diff --git a/config/packages/content_page_defaults.yaml b/config/packages/libero_page_defaults.yaml similarity index 84% rename from config/packages/content_page_defaults.yaml rename to config/packages/libero_page_defaults.yaml index 4fd73cc..85e54d9 100644 --- a/config/packages/content_page_defaults.yaml +++ b/config/packages/libero_page_defaults.yaml @@ -1,3 +1,3 @@ -content_page: +libero_page: client: 'csa_guzzle.client.libero_api' page_template: 'page.html.twig' diff --git a/config/packages/test/content_page.yaml b/config/packages/test/content_page.yaml deleted file mode 100644 index 817e397..0000000 --- a/config/packages/test/content_page.yaml +++ /dev/null @@ -1,8 +0,0 @@ -content_page: - pages: - blog_article: - path: '/blog/{id}' - service: 'blog-articles' - scholarly_article: - path: '/articles/{id}' - service: 'scholarly-articles' diff --git a/config/packages/test/libero_page.yaml b/config/packages/test/libero_page.yaml new file mode 100644 index 0000000..d2ab311 --- /dev/null +++ b/config/packages/test/libero_page.yaml @@ -0,0 +1,10 @@ +libero_page: + pages: + blog_article: + type: content + path: '/blog/{id}' + content_service: 'blog-articles' + scholarly_article: + type: content + path: '/articles/{id}' + content_service: 'scholarly-articles' diff --git a/config/routes.yaml b/config/routes.yaml index f56494a..a52f729 100644 --- a/config/routes.yaml +++ b/config/routes.yaml @@ -1,3 +1,3 @@ -content_page: +libero_page: resource: . - type: content_page + type: libero_page diff --git a/symfony.lock b/symfony.lock index 0eaf788..965762f 100644 --- a/symfony.lock +++ b/symfony.lock @@ -44,15 +44,15 @@ "libero/coding-standard": { "version": "v0.3.0" }, - "libero/content-page-bundle": { - "version": "1.0.x-dev" - }, "libero/jats-content-bundle": { "version": "1.0.x-dev" }, "libero/libero-content-bundle": { "version": "1.0.x-dev" }, + "libero/page-bundle": { + "version": "1.0.x-dev" + }, "libero/patterns-bundle": { "version": "1.0.x-dev" }, @@ -167,6 +167,9 @@ "punic/punic": { "version": "3.3.1" }, + "ralouphie/getallheaders": { + "version": "2.0.5" + }, "sebastian/code-unit-reverse-lookup": { "version": "1.0.1" }, diff --git a/vendor-extra/ContentPageBundle/composer.json b/vendor-extra/ContentPageBundle/composer.json deleted file mode 100644 index 5ad7736..0000000 --- a/vendor-extra/ContentPageBundle/composer.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "name": "libero/content-page-bundle", - "description": "A Libero content page", - "type": "symfony-bundle", - "license": "MIT", - "autoload": { - "psr-4": { - "Libero\\ContentPageBundle\\": "src/" - }, - "files": [ - "src/functions.php" - ] - }, - "require": { - "php": "^7.2", - "fluentdom/fluentdom": "^7.0", - "guzzlehttp/guzzle": "^6.3", - "libero/patterns-bundle": "^1.0@dev", - "libero/views-bundle": "^1.0@dev", - "psr/http-message": "^1.0", - "punic/punic": "^3.3", - "symfony/config": "^4.1", - "symfony/dependency-injection": "^4.1", - "symfony/event-dispatcher": "^4.1", - "symfony/http-foundation": "^4.1", - "symfony/http-kernel": "^4.1", - "symfony/routing": "^4.1", - "twig/twig": "^2.5" - }, - "require-dev": { - "csa/guzzle-cache-middleware": "^1.0", - "guzzlehttp/psr7": "^1.4", - "php-vfs/php-vfs": "^1.4", - "phpunit/phpunit": "^7.3", - "symfony/css-selector": "^4.1", - "symfony/dom-crawler": "^4.1" - }, - "config": { - "sort-packages": true - }, - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - } -} diff --git a/vendor-extra/ContentPageBundle/src/Controller/ContentController.php b/vendor-extra/ContentPageBundle/src/Controller/ContentController.php deleted file mode 100644 index 8d2402e..0000000 --- a/vendor-extra/ContentPageBundle/src/Controller/ContentController.php +++ /dev/null @@ -1,72 +0,0 @@ -client = $client; - $this->service = $service; - $this->twig = $twig; - $this->template = $template; - $this->dispatcher = $dispatcher; - } - - public function __invoke(Request $request, string $id) : Response - { - return $this->client - ->requestAsync( - 'GET', - "{$this->service}/items/{$id}/versions/latest", - [ - 'headers' => ['Accept' => 'application/xml'], - 'http_errors' => true, - ] - ) - ->then( - function (ResponseInterface $response) use ($request) : Response { - $document = FluentDOM::load((string) $response->getBody()); - - $context = [ - 'lang' => $request->getLocale(), - 'dir' => text_direction($request->getLocale()), - ]; - - $event = new CreateContentPageEvent($document, $context); - $this->dispatcher->dispatch($event::NAME, $event); - - return new Response( - $this->twig->render( - $this->template, - $event->getContext() + ['title' => $event->getTitle(), 'content' => $event->getContent()] - ) - ); - } - ) - ->wait(); - } -} diff --git a/vendor-extra/ContentPageBundle/src/DependencyInjection/ContentPageExtension.php b/vendor-extra/ContentPageBundle/src/DependencyInjection/ContentPageExtension.php deleted file mode 100644 index a2f2446..0000000 --- a/vendor-extra/ContentPageBundle/src/DependencyInjection/ContentPageExtension.php +++ /dev/null @@ -1,65 +0,0 @@ -load('services.xml'); - - $config = $this->processConfiguration($this->getConfiguration($configs, $container), $configs); - - foreach ($config['pages'] as $name => $page) { - $config['pages'][$name]['name'] = $name; - $page['client'] = $config['client']; - $page['page_template'] = $config['page_template']; - - $this->addPage($name, $page, $container); - } - - $container->findDefinition(ContentPageRouteLoader::class)->setArgument(0, $config['pages']); - } - - private function addPage(string $name, array $config, ContainerBuilder $container) : void - { - $id = sprintf(self::CONTENT_CONTROLLER_ID, $name); - $definition = new Definition(ContentController::class); - - $definition->setArgument(0, new Reference($config['client'])); - $definition->setArgument(1, $config['service']); - $definition->setArgument(2, new Reference('twig')); - $definition->setArgument(3, $config['page_template']); - $definition->setArgument(4, new Reference(EventDispatcherInterface::class)); - $definition->addTag('controller.service_arguments'); - - $container->setDefinition($id, $definition); - } - - public function getConfiguration(array $config, ContainerBuilder $container) : ConfigurationInterface - { - return new ContentPageConfiguration($this->getAlias()); - } - - public function getAlias() : string - { - return 'content_page'; - } -} diff --git a/vendor-extra/ContentPageBundle/src/Event/CreateContentPageEvent.php b/vendor-extra/ContentPageBundle/src/Event/CreateContentPageEvent.php deleted file mode 100644 index 2782fec..0000000 --- a/vendor-extra/ContentPageBundle/src/Event/CreateContentPageEvent.php +++ /dev/null @@ -1,59 +0,0 @@ -item = $item; - $this->context = $context; - } - - public function getContent() : array - { - return $this->content; - } - - public function addContent($content) : void - { - $this->content[] = $content; - } - - public function getContext() : array - { - return $this->context; - } - - public function setContext(string $key, $value) : void - { - $this->context[$key] = $value; - } - - public function getItem() : Document - { - return $this->item; - } - - public function getTitle() : ?string - { - return $this->title; - } - - public function setTitle(string $title) : void - { - $this->title = $title; - } -} diff --git a/vendor-extra/ContentPageBundle/src/EventListener/NamespaceListener.php b/vendor-extra/ContentPageBundle/src/EventListener/NamespaceListener.php deleted file mode 100644 index da924b2..0000000 --- a/vendor-extra/ContentPageBundle/src/EventListener/NamespaceListener.php +++ /dev/null @@ -1,24 +0,0 @@ -prefix = $prefix; - $this->uri = $uri; - } - - public function onCreatePage(CreateContentPageEvent $event) : void - { - $event->getItem()->registerNamespace($this->prefix, $this->uri); - } -} diff --git a/vendor-extra/ContentPageBundle/src/Resources/config/services.xml b/vendor-extra/ContentPageBundle/src/Resources/config/services.xml deleted file mode 100644 index 3e5ed30..0000000 --- a/vendor-extra/ContentPageBundle/src/Resources/config/services.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - libero - http://libero.pub - - - - - - - - - - - diff --git a/vendor-extra/JatsContentBundle/composer.json b/vendor-extra/JatsContentBundle/composer.json index 9efde00..2a79425 100644 --- a/vendor-extra/JatsContentBundle/composer.json +++ b/vendor-extra/JatsContentBundle/composer.json @@ -12,7 +12,7 @@ "php": "^7.2", "ext-dom": "*", "fluentdom/fluentdom": "^7.0", - "libero/content-page-bundle": "^1.0@dev", + "libero/page-bundle": "^1.0@dev", "libero/views-bundle": "^1.0@dev", "symfony/config": "^4.1", "symfony/contracts": "^1.0", diff --git a/vendor-extra/JatsContentBundle/src/EventListener/BodyListener.php b/vendor-extra/JatsContentBundle/src/EventListener/BodyListener.php index 2c8d284..7fa0831 100644 --- a/vendor-extra/JatsContentBundle/src/EventListener/BodyListener.php +++ b/vendor-extra/JatsContentBundle/src/EventListener/BodyListener.php @@ -5,7 +5,7 @@ namespace Libero\JatsContentBundle\EventListener; use FluentDOM\DOM\Element; -use Libero\ContentPageBundle\Event\CreateContentPageEvent; +use Libero\LiberoPageBundle\Event\CreatePageEvent; use Libero\ViewsBundle\Views\ConvertsChildren; use Libero\ViewsBundle\Views\View; use Libero\ViewsBundle\Views\ViewConverter; @@ -21,9 +21,13 @@ public function __construct(ViewConverter $converter) $this->converter = $converter; } - public function onCreatePage(CreateContentPageEvent $event) : void + public function onCreatePage(CreatePageEvent $event) : void { - $xpath = $event->getItem()->xpath(); + if ('content' !== $event->getRequest()->attributes->get('libero_page')['type']) { + return; + } + + $xpath = $event->getDocument('content_item')->xpath(); $body = $xpath->firstOf('/libero:item/jats:article/jats:body'); diff --git a/vendor-extra/JatsContentBundle/src/EventListener/ContentHeaderListener.php b/vendor-extra/JatsContentBundle/src/EventListener/ContentHeaderListener.php index 589aca6..444e61b 100644 --- a/vendor-extra/JatsContentBundle/src/EventListener/ContentHeaderListener.php +++ b/vendor-extra/JatsContentBundle/src/EventListener/ContentHeaderListener.php @@ -5,7 +5,7 @@ namespace Libero\JatsContentBundle\EventListener; use FluentDOM\DOM\Element; -use Libero\ContentPageBundle\Event\CreateContentPageEvent; +use Libero\LiberoPageBundle\Event\CreatePageEvent; use Libero\ViewsBundle\Views\ViewConverter; use function is_string; @@ -18,9 +18,13 @@ public function __construct(ViewConverter $converter) $this->converter = $converter; } - public function onCreatePage(CreateContentPageEvent $event) : void + public function onCreatePage(CreatePageEvent $event) : void { - $xpath = $event->getItem()->xpath(); + if ('content' !== $event->getRequest()->attributes->get('libero_page')['type']) { + return; + } + + $xpath = $event->getDocument('content_item')->xpath(); $front = $xpath->firstOf('/libero:item/jats:article/jats:front'); diff --git a/vendor-extra/JatsContentBundle/src/EventListener/ItemTagsListener.php b/vendor-extra/JatsContentBundle/src/EventListener/ItemTagsListener.php index ae0eb7c..36e5fe8 100644 --- a/vendor-extra/JatsContentBundle/src/EventListener/ItemTagsListener.php +++ b/vendor-extra/JatsContentBundle/src/EventListener/ItemTagsListener.php @@ -5,7 +5,7 @@ namespace Libero\JatsContentBundle\EventListener; use FluentDOM\DOM\Element; -use Libero\ContentPageBundle\Event\CreateContentPageEvent; +use Libero\LiberoPageBundle\Event\CreatePageEvent; use Libero\ViewsBundle\Views\ConvertsLists; use Libero\ViewsBundle\Views\View; use Libero\ViewsBundle\Views\ViewConverter; @@ -20,9 +20,13 @@ public function __construct(ViewConverter $converter) $this->converter = $converter; } - public function onCreatePage(CreateContentPageEvent $event) : void + public function onCreatePage(CreatePageEvent $event) : void { - $front = $event->getItem()->xpath()->firstOf('/libero:item/jats:article/jats:front'); + if ('content' !== $event->getRequest()->attributes->get('libero_page')['type']) { + return; + } + + $front = $event->getDocument('content_item')->xpath()->firstOf('/libero:item/jats:article/jats:front'); if (!$front instanceof Element) { return; diff --git a/vendor-extra/JatsContentBundle/src/Resources/config/services.xml b/vendor-extra/JatsContentBundle/src/Resources/config/services.xml index bbc7751..4c64476 100644 --- a/vendor-extra/JatsContentBundle/src/Resources/config/services.xml +++ b/vendor-extra/JatsContentBundle/src/Resources/config/services.xml @@ -11,26 +11,26 @@ - + - + - + + class="Libero\LiberoPageBundle\EventListener\NamespaceListener"> jats http://jats.nlm.nih.gov - + onCreatePage($event); @@ -54,7 +54,7 @@ public function it_adds_the_body_content(string $xml, array $context, array $exp $document = $this->loadDocument($xml); - $event = new CreateContentPageEvent($document, $context); + $event = new CreatePageEvent($document, $context); $listener->onCreatePage($event); $this->assertEquals( diff --git a/vendor-extra/JatsContentBundle/tests/EventListener/ContentHeaderListenerTest.php b/vendor-extra/JatsContentBundle/tests/EventListener/ContentHeaderListenerTest.php index b2b5833..db83b3b 100644 --- a/vendor-extra/JatsContentBundle/tests/EventListener/ContentHeaderListenerTest.php +++ b/vendor-extra/JatsContentBundle/tests/EventListener/ContentHeaderListenerTest.php @@ -4,12 +4,12 @@ namespace tests\Libero\JatsContentBundle\EventListener; -use Libero\ContentPageBundle\Event\CreateContentPageEvent; use Libero\JatsContentBundle\EventListener\ContentHeaderListener; +use Libero\LiberoPageBundle\Event\CreatePageEvent; use Libero\ViewsBundle\Views\View; use PHPUnit\Framework\TestCase; -use tests\Libero\ContentPageBundle\ViewConvertingTestCase; -use tests\Libero\ContentPageBundle\XmlTestCase; +use tests\Libero\LiberoPageBundle\ViewConvertingTestCase; +use tests\Libero\LiberoPageBundle\XmlTestCase; final class ContentHeaderListenerTest extends TestCase { @@ -35,7 +35,7 @@ public function it_does_nothing_if_it_does_not_find_the_front() : void XML ); - $event = new CreateContentPageEvent($document); + $event = new CreatePageEvent($document); $originalEvent = clone $event; $listener->onCreatePage($event); @@ -55,7 +55,7 @@ public function it_sets_the_title_and_adds_a_content_header( ) : void { $listener = new ContentHeaderListener($this->createDumpingConverter()); - $event = new CreateContentPageEvent($this->loadDocument($xml), $context); + $event = new CreatePageEvent($this->loadDocument($xml), $context); $listener->onCreatePage($event); $this->assertSame($expectedTitle, $event->getTitle()); @@ -222,7 +222,7 @@ public function it_does_not_replace_an_existing_title() : void XML ); - $event = new CreateContentPageEvent($document); + $event = new CreatePageEvent($document); $event->setTitle('Existing Title'); $listener->onCreatePage($event); diff --git a/vendor-extra/JatsContentBundle/tests/EventListener/ItemTagsListenerTest.php b/vendor-extra/JatsContentBundle/tests/EventListener/ItemTagsListenerTest.php index c123455..c2601b7 100644 --- a/vendor-extra/JatsContentBundle/tests/EventListener/ItemTagsListenerTest.php +++ b/vendor-extra/JatsContentBundle/tests/EventListener/ItemTagsListenerTest.php @@ -4,12 +4,12 @@ namespace tests\Libero\JatsContentBundle\EventListener; -use Libero\ContentPageBundle\Event\CreateContentPageEvent; use Libero\JatsContentBundle\EventListener\ItemTagsListener; +use Libero\LiberoPageBundle\Event\CreatePageEvent; use Libero\ViewsBundle\Views\View; use PHPUnit\Framework\TestCase; -use tests\Libero\ContentPageBundle\ViewConvertingTestCase; -use tests\Libero\ContentPageBundle\XmlTestCase; +use tests\Libero\LiberoPageBundle\ViewConvertingTestCase; +use tests\Libero\LiberoPageBundle\XmlTestCase; final class ItemTagsListenerTest extends TestCase { @@ -35,7 +35,7 @@ public function it_does_nothing_if_it_does_not_find_the_front() : void XML ); - $event = new CreateContentPageEvent($document); + $event = new CreatePageEvent($document); $originalEvent = clone $event; $listener->onCreatePage($event); @@ -56,7 +56,7 @@ public function it_adds_item_tags( $document = $this->loadDocument($xml); - $event = new CreateContentPageEvent($document, $context); + $event = new CreatePageEvent($document, $context); $listener->onCreatePage($event); $this->assertEquals( diff --git a/vendor-extra/JatsContentBundle/tests/ViewConverter/BoldVisitorTest.php b/vendor-extra/JatsContentBundle/tests/ViewConverter/BoldVisitorTest.php index c33e3f6..981f0b4 100644 --- a/vendor-extra/JatsContentBundle/tests/ViewConverter/BoldVisitorTest.php +++ b/vendor-extra/JatsContentBundle/tests/ViewConverter/BoldVisitorTest.php @@ -7,8 +7,8 @@ use Libero\JatsContentBundle\ViewConverter\BoldVisitor; use Libero\ViewsBundle\Views\View; use PHPUnit\Framework\TestCase; -use tests\Libero\ContentPageBundle\ViewConvertingTestCase; -use tests\Libero\ContentPageBundle\XmlTestCase; +use tests\Libero\LiberoPageBundle\ViewConvertingTestCase; +use tests\Libero\LiberoPageBundle\XmlTestCase; final class BoldVisitorTest extends TestCase { diff --git a/vendor-extra/JatsContentBundle/tests/ViewConverter/FrontArticleTitleContentHeaderVisitorTest.php b/vendor-extra/JatsContentBundle/tests/ViewConverter/FrontArticleTitleContentHeaderVisitorTest.php index 6484657..f93fd23 100644 --- a/vendor-extra/JatsContentBundle/tests/ViewConverter/FrontArticleTitleContentHeaderVisitorTest.php +++ b/vendor-extra/JatsContentBundle/tests/ViewConverter/FrontArticleTitleContentHeaderVisitorTest.php @@ -7,8 +7,8 @@ use Libero\JatsContentBundle\ViewConverter\FrontArticleTitleContentHeaderVisitor; use Libero\ViewsBundle\Views\View; use PHPUnit\Framework\TestCase; -use tests\Libero\ContentPageBundle\ViewConvertingTestCase; -use tests\Libero\ContentPageBundle\XmlTestCase; +use tests\Libero\LiberoPageBundle\ViewConvertingTestCase; +use tests\Libero\LiberoPageBundle\XmlTestCase; final class FrontArticleTitleContentHeaderVisitorTest extends TestCase { diff --git a/vendor-extra/JatsContentBundle/tests/ViewConverter/FrontItemTagsVisitorTest.php b/vendor-extra/JatsContentBundle/tests/ViewConverter/FrontItemTagsVisitorTest.php index b7a2671..833fa23 100644 --- a/vendor-extra/JatsContentBundle/tests/ViewConverter/FrontItemTagsVisitorTest.php +++ b/vendor-extra/JatsContentBundle/tests/ViewConverter/FrontItemTagsVisitorTest.php @@ -7,8 +7,8 @@ use Libero\JatsContentBundle\ViewConverter\FrontItemTagsVisitor; use Libero\ViewsBundle\Views\View; use PHPUnit\Framework\TestCase; -use tests\Libero\ContentPageBundle\ViewConvertingTestCase; -use tests\Libero\ContentPageBundle\XmlTestCase; +use tests\Libero\LiberoPageBundle\ViewConvertingTestCase; +use tests\Libero\LiberoPageBundle\XmlTestCase; final class FrontItemTagsVisitorTest extends TestCase { diff --git a/vendor-extra/JatsContentBundle/tests/ViewConverter/FrontSubjectGroupContentHeaderVisitorTest.php b/vendor-extra/JatsContentBundle/tests/ViewConverter/FrontSubjectGroupContentHeaderVisitorTest.php index 7cbb8e1..c4fca55 100644 --- a/vendor-extra/JatsContentBundle/tests/ViewConverter/FrontSubjectGroupContentHeaderVisitorTest.php +++ b/vendor-extra/JatsContentBundle/tests/ViewConverter/FrontSubjectGroupContentHeaderVisitorTest.php @@ -10,8 +10,8 @@ use Symfony\Component\Translation\IdentityTranslator; use Symfony\Component\Translation\Loader\ArrayLoader; use Symfony\Component\Translation\Translator; -use tests\Libero\ContentPageBundle\ViewConvertingTestCase; -use tests\Libero\ContentPageBundle\XmlTestCase; +use tests\Libero\LiberoPageBundle\ViewConvertingTestCase; +use tests\Libero\LiberoPageBundle\XmlTestCase; final class FrontSubjectGroupContentHeaderVisitorTest extends TestCase { diff --git a/vendor-extra/JatsContentBundle/tests/ViewConverter/HeadingVisitorTest.php b/vendor-extra/JatsContentBundle/tests/ViewConverter/HeadingVisitorTest.php index 77749bb..0210a43 100644 --- a/vendor-extra/JatsContentBundle/tests/ViewConverter/HeadingVisitorTest.php +++ b/vendor-extra/JatsContentBundle/tests/ViewConverter/HeadingVisitorTest.php @@ -7,8 +7,8 @@ use Libero\JatsContentBundle\ViewConverter\HeadingVisitor; use Libero\ViewsBundle\Views\View; use PHPUnit\Framework\TestCase; -use tests\Libero\ContentPageBundle\ViewConvertingTestCase; -use tests\Libero\ContentPageBundle\XmlTestCase; +use tests\Libero\LiberoPageBundle\ViewConvertingTestCase; +use tests\Libero\LiberoPageBundle\XmlTestCase; final class HeadingVisitorTest extends TestCase { diff --git a/vendor-extra/JatsContentBundle/tests/ViewConverter/ItalicVisitorTest.php b/vendor-extra/JatsContentBundle/tests/ViewConverter/ItalicVisitorTest.php index 98a960c..78866f9 100644 --- a/vendor-extra/JatsContentBundle/tests/ViewConverter/ItalicVisitorTest.php +++ b/vendor-extra/JatsContentBundle/tests/ViewConverter/ItalicVisitorTest.php @@ -7,8 +7,8 @@ use Libero\JatsContentBundle\ViewConverter\ItalicVisitor; use Libero\ViewsBundle\Views\View; use PHPUnit\Framework\TestCase; -use tests\Libero\ContentPageBundle\ViewConvertingTestCase; -use tests\Libero\ContentPageBundle\XmlTestCase; +use tests\Libero\LiberoPageBundle\ViewConvertingTestCase; +use tests\Libero\LiberoPageBundle\XmlTestCase; final class ItalicVisitorTest extends TestCase { diff --git a/vendor-extra/JatsContentBundle/tests/ViewConverter/KeywordGroupTagListVisitorTest.php b/vendor-extra/JatsContentBundle/tests/ViewConverter/KeywordGroupTagListVisitorTest.php index e515109..ec35e32 100644 --- a/vendor-extra/JatsContentBundle/tests/ViewConverter/KeywordGroupTagListVisitorTest.php +++ b/vendor-extra/JatsContentBundle/tests/ViewConverter/KeywordGroupTagListVisitorTest.php @@ -10,8 +10,8 @@ use Symfony\Component\Translation\IdentityTranslator; use Symfony\Component\Translation\Loader\ArrayLoader; use Symfony\Component\Translation\Translator; -use tests\Libero\ContentPageBundle\ViewConvertingTestCase; -use tests\Libero\ContentPageBundle\XmlTestCase; +use tests\Libero\LiberoPageBundle\ViewConvertingTestCase; +use tests\Libero\LiberoPageBundle\XmlTestCase; final class KeywordGroupTagListVisitorTest extends TestCase { diff --git a/vendor-extra/JatsContentBundle/tests/ViewConverter/LinkVisitorTest.php b/vendor-extra/JatsContentBundle/tests/ViewConverter/LinkVisitorTest.php index d7e3264..21f1746 100644 --- a/vendor-extra/JatsContentBundle/tests/ViewConverter/LinkVisitorTest.php +++ b/vendor-extra/JatsContentBundle/tests/ViewConverter/LinkVisitorTest.php @@ -7,8 +7,8 @@ use Libero\JatsContentBundle\ViewConverter\LinkVisitor; use Libero\ViewsBundle\Views\View; use PHPUnit\Framework\TestCase; -use tests\Libero\ContentPageBundle\ViewConvertingTestCase; -use tests\Libero\ContentPageBundle\XmlTestCase; +use tests\Libero\LiberoPageBundle\ViewConvertingTestCase; +use tests\Libero\LiberoPageBundle\XmlTestCase; final class LinkVisitorTest extends TestCase { diff --git a/vendor-extra/JatsContentBundle/tests/ViewConverter/ParagraphVisitorTest.php b/vendor-extra/JatsContentBundle/tests/ViewConverter/ParagraphVisitorTest.php index cd7f7ff..e848050 100644 --- a/vendor-extra/JatsContentBundle/tests/ViewConverter/ParagraphVisitorTest.php +++ b/vendor-extra/JatsContentBundle/tests/ViewConverter/ParagraphVisitorTest.php @@ -7,8 +7,8 @@ use Libero\JatsContentBundle\ViewConverter\ParagraphVisitor; use Libero\ViewsBundle\Views\View; use PHPUnit\Framework\TestCase; -use tests\Libero\ContentPageBundle\ViewConvertingTestCase; -use tests\Libero\ContentPageBundle\XmlTestCase; +use tests\Libero\LiberoPageBundle\ViewConvertingTestCase; +use tests\Libero\LiberoPageBundle\XmlTestCase; final class ParagraphVisitorTest extends TestCase { diff --git a/vendor-extra/JatsContentBundle/tests/ViewConverter/SectionVisitorTest.php b/vendor-extra/JatsContentBundle/tests/ViewConverter/SectionVisitorTest.php index 5a4adf7..bfd3be4 100644 --- a/vendor-extra/JatsContentBundle/tests/ViewConverter/SectionVisitorTest.php +++ b/vendor-extra/JatsContentBundle/tests/ViewConverter/SectionVisitorTest.php @@ -7,8 +7,8 @@ use Libero\JatsContentBundle\ViewConverter\SectionVisitor; use Libero\ViewsBundle\Views\View; use PHPUnit\Framework\TestCase; -use tests\Libero\ContentPageBundle\ViewConvertingTestCase; -use tests\Libero\ContentPageBundle\XmlTestCase; +use tests\Libero\LiberoPageBundle\ViewConvertingTestCase; +use tests\Libero\LiberoPageBundle\XmlTestCase; final class SectionVisitorTest extends TestCase { diff --git a/vendor-extra/JatsContentBundle/tests/ViewConverter/SubVisitorTest.php b/vendor-extra/JatsContentBundle/tests/ViewConverter/SubVisitorTest.php index 2bab09e..dd29445 100644 --- a/vendor-extra/JatsContentBundle/tests/ViewConverter/SubVisitorTest.php +++ b/vendor-extra/JatsContentBundle/tests/ViewConverter/SubVisitorTest.php @@ -7,8 +7,8 @@ use Libero\JatsContentBundle\ViewConverter\SubVisitor; use Libero\ViewsBundle\Views\View; use PHPUnit\Framework\TestCase; -use tests\Libero\ContentPageBundle\ViewConvertingTestCase; -use tests\Libero\ContentPageBundle\XmlTestCase; +use tests\Libero\LiberoPageBundle\ViewConvertingTestCase; +use tests\Libero\LiberoPageBundle\XmlTestCase; final class SubVisitorTest extends TestCase { diff --git a/vendor-extra/JatsContentBundle/tests/ViewConverter/SupVisitorTest.php b/vendor-extra/JatsContentBundle/tests/ViewConverter/SupVisitorTest.php index afa6061..a0e34af 100644 --- a/vendor-extra/JatsContentBundle/tests/ViewConverter/SupVisitorTest.php +++ b/vendor-extra/JatsContentBundle/tests/ViewConverter/SupVisitorTest.php @@ -7,8 +7,8 @@ use Libero\JatsContentBundle\ViewConverter\SupVisitor; use Libero\ViewsBundle\Views\View; use PHPUnit\Framework\TestCase; -use tests\Libero\ContentPageBundle\ViewConvertingTestCase; -use tests\Libero\ContentPageBundle\XmlTestCase; +use tests\Libero\LiberoPageBundle\ViewConvertingTestCase; +use tests\Libero\LiberoPageBundle\XmlTestCase; final class SupVisitorTest extends TestCase { diff --git a/vendor-extra/LiberoContentBundle/composer.json b/vendor-extra/LiberoContentBundle/composer.json index 2e959d2..108063e 100644 --- a/vendor-extra/LiberoContentBundle/composer.json +++ b/vendor-extra/LiberoContentBundle/composer.json @@ -11,7 +11,7 @@ "require": { "php": "^7.2", "fluentdom/fluentdom": "^7.0", - "libero/content-page-bundle": "^1.0@dev", + "libero/page-bundle": "^1.0@dev", "libero/views-bundle": "^1.0@dev", "symfony/config": "^4.1", "symfony/dependency-injection": "^4.1", diff --git a/vendor-extra/LiberoContentBundle/src/EventListener/ContentHeaderListener.php b/vendor-extra/LiberoContentBundle/src/EventListener/ContentHeaderListener.php index 6e6fc12..5eb1153 100644 --- a/vendor-extra/LiberoContentBundle/src/EventListener/ContentHeaderListener.php +++ b/vendor-extra/LiberoContentBundle/src/EventListener/ContentHeaderListener.php @@ -5,7 +5,7 @@ namespace Libero\LiberoContentBundle\EventListener; use FluentDOM\DOM\Element; -use Libero\ContentPageBundle\Event\CreateContentPageEvent; +use Libero\LiberoPageBundle\Event\CreatePageEvent; use Libero\ViewsBundle\Views\ViewConverter; use function is_string; @@ -18,9 +18,13 @@ public function __construct(ViewConverter $converter) $this->converter = $converter; } - public function onCreatePage(CreateContentPageEvent $event) : void + public function onCreatePage(CreatePageEvent $event) : void { - $xpath = $event->getItem()->xpath(); + if ('content' !== $event->getRequest()->attributes->get('libero_page')['type']) { + return; + } + + $xpath = $event->getDocument('content_item')->xpath(); $front = $xpath->firstOf('/libero:item/libero:front'); diff --git a/vendor-extra/LiberoContentBundle/src/Resources/config/services.xml b/vendor-extra/LiberoContentBundle/src/Resources/config/services.xml index 4de40e1..2a6801f 100644 --- a/vendor-extra/LiberoContentBundle/src/Resources/config/services.xml +++ b/vendor-extra/LiberoContentBundle/src/Resources/config/services.xml @@ -11,7 +11,7 @@ - + onCreatePage($event); @@ -54,7 +54,7 @@ public function it_sets_the_title_and_adds_a_content_header( ) : void { $listener = new ContentHeaderListener($this->createDumpingConverter()); - $event = new CreateContentPageEvent($this->loadDocument($xml), $context); + $event = new CreatePageEvent($this->loadDocument($xml), $context); $listener->onCreatePage($event); $this->assertSame($expectedTitle, $event->getTitle()); @@ -195,7 +195,7 @@ public function it_does_not_replace_an_existing_title() : void XML ); - $event = new CreateContentPageEvent($document); + $event = new CreatePageEvent($document); $event->setTitle('Existing Title'); $listener->onCreatePage($event); diff --git a/vendor-extra/LiberoContentBundle/tests/ViewConverter/BoldVisitorTest.php b/vendor-extra/LiberoContentBundle/tests/ViewConverter/BoldVisitorTest.php index 248f8a6..234e409 100644 --- a/vendor-extra/LiberoContentBundle/tests/ViewConverter/BoldVisitorTest.php +++ b/vendor-extra/LiberoContentBundle/tests/ViewConverter/BoldVisitorTest.php @@ -7,8 +7,8 @@ use Libero\LiberoContentBundle\ViewConverter\BoldVisitor; use Libero\ViewsBundle\Views\View; use PHPUnit\Framework\TestCase; -use tests\Libero\ContentPageBundle\ViewConvertingTestCase; -use tests\Libero\ContentPageBundle\XmlTestCase; +use tests\Libero\LiberoPageBundle\ViewConvertingTestCase; +use tests\Libero\LiberoPageBundle\XmlTestCase; final class BoldVisitorTest extends TestCase { diff --git a/vendor-extra/LiberoContentBundle/tests/ViewConverter/FrontContentHeaderVisitorTest.php b/vendor-extra/LiberoContentBundle/tests/ViewConverter/FrontContentHeaderVisitorTest.php index eaf2c6b..2737b97 100644 --- a/vendor-extra/LiberoContentBundle/tests/ViewConverter/FrontContentHeaderVisitorTest.php +++ b/vendor-extra/LiberoContentBundle/tests/ViewConverter/FrontContentHeaderVisitorTest.php @@ -7,8 +7,8 @@ use Libero\LiberoContentBundle\ViewConverter\FrontContentHeaderVisitor; use Libero\ViewsBundle\Views\View; use PHPUnit\Framework\TestCase; -use tests\Libero\ContentPageBundle\ViewConvertingTestCase; -use tests\Libero\ContentPageBundle\XmlTestCase; +use tests\Libero\LiberoPageBundle\ViewConvertingTestCase; +use tests\Libero\LiberoPageBundle\XmlTestCase; final class FrontContentHeaderVisitorTest extends TestCase { diff --git a/vendor-extra/LiberoContentBundle/tests/ViewConverter/ItalicVisitorTest.php b/vendor-extra/LiberoContentBundle/tests/ViewConverter/ItalicVisitorTest.php index 6b8bffa..859c91b 100644 --- a/vendor-extra/LiberoContentBundle/tests/ViewConverter/ItalicVisitorTest.php +++ b/vendor-extra/LiberoContentBundle/tests/ViewConverter/ItalicVisitorTest.php @@ -7,8 +7,8 @@ use Libero\LiberoContentBundle\ViewConverter\ItalicVisitor; use Libero\ViewsBundle\Views\View; use PHPUnit\Framework\TestCase; -use tests\Libero\ContentPageBundle\ViewConvertingTestCase; -use tests\Libero\ContentPageBundle\XmlTestCase; +use tests\Libero\LiberoPageBundle\ViewConvertingTestCase; +use tests\Libero\LiberoPageBundle\XmlTestCase; final class ItalicVisitorTest extends TestCase { diff --git a/vendor-extra/LiberoContentBundle/tests/ViewConverter/SubVisitorTest.php b/vendor-extra/LiberoContentBundle/tests/ViewConverter/SubVisitorTest.php index 6069c00..5fd4600 100644 --- a/vendor-extra/LiberoContentBundle/tests/ViewConverter/SubVisitorTest.php +++ b/vendor-extra/LiberoContentBundle/tests/ViewConverter/SubVisitorTest.php @@ -7,8 +7,8 @@ use Libero\LiberoContentBundle\ViewConverter\SubVisitor; use Libero\ViewsBundle\Views\View; use PHPUnit\Framework\TestCase; -use tests\Libero\ContentPageBundle\ViewConvertingTestCase; -use tests\Libero\ContentPageBundle\XmlTestCase; +use tests\Libero\LiberoPageBundle\ViewConvertingTestCase; +use tests\Libero\LiberoPageBundle\XmlTestCase; final class SubVisitorTest extends TestCase { diff --git a/vendor-extra/LiberoContentBundle/tests/ViewConverter/SupVisitorTest.php b/vendor-extra/LiberoContentBundle/tests/ViewConverter/SupVisitorTest.php index 280cbef..b9cf855 100644 --- a/vendor-extra/LiberoContentBundle/tests/ViewConverter/SupVisitorTest.php +++ b/vendor-extra/LiberoContentBundle/tests/ViewConverter/SupVisitorTest.php @@ -7,8 +7,8 @@ use Libero\LiberoContentBundle\ViewConverter\SupVisitor; use Libero\ViewsBundle\Views\View; use PHPUnit\Framework\TestCase; -use tests\Libero\ContentPageBundle\ViewConvertingTestCase; -use tests\Libero\ContentPageBundle\XmlTestCase; +use tests\Libero\LiberoPageBundle\ViewConvertingTestCase; +use tests\Libero\LiberoPageBundle\XmlTestCase; final class SupVisitorTest extends TestCase { diff --git a/vendor-extra/LiberoContentBundle/tests/ViewConverter/TitleHeadingVisitorTest.php b/vendor-extra/LiberoContentBundle/tests/ViewConverter/TitleHeadingVisitorTest.php index 9a0d1d3..cbdb3ec 100644 --- a/vendor-extra/LiberoContentBundle/tests/ViewConverter/TitleHeadingVisitorTest.php +++ b/vendor-extra/LiberoContentBundle/tests/ViewConverter/TitleHeadingVisitorTest.php @@ -7,8 +7,8 @@ use Libero\LiberoContentBundle\ViewConverter\TitleHeadingVisitor; use Libero\ViewsBundle\Views\View; use PHPUnit\Framework\TestCase; -use tests\Libero\ContentPageBundle\ViewConvertingTestCase; -use tests\Libero\ContentPageBundle\XmlTestCase; +use tests\Libero\LiberoPageBundle\ViewConvertingTestCase; +use tests\Libero\LiberoPageBundle\XmlTestCase; final class TitleHeadingVisitorTest extends TestCase { diff --git a/vendor-extra/LiberoPageBundle/composer.json b/vendor-extra/LiberoPageBundle/composer.json new file mode 100644 index 0000000..5026cf0 --- /dev/null +++ b/vendor-extra/LiberoPageBundle/composer.json @@ -0,0 +1,33 @@ +{ + "name": "libero/page-bundle", + "description": "Libero page", + "type": "symfony-bundle", + "license": "MIT", + "autoload": { + "psr-4": { + "Libero\\LiberoPageBundle\\": "src/" + }, + "files": [ + "src/functions.php" + ] + }, + "require": { + "php": "^7.2", + "fluentdom/fluentdom": "^7.0", + "guzzlehttp/promises": "^1.0", + "punic/punic": "^3.3", + "symfony/contracts": "^1.0", + "symfony/event-dispatcher": "^4.1", + "symfony/http-foundation": "^4.1", + "symfony/http-kernel": "^4.1", + "twig/twig": "^2.5" + }, + "config": { + "sort-packages": true + }, + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + } +} diff --git a/vendor-extra/LiberoPageBundle/src/Controller/PageController.php b/vendor-extra/LiberoPageBundle/src/Controller/PageController.php new file mode 100644 index 0000000..01c5525 --- /dev/null +++ b/vendor-extra/LiberoPageBundle/src/Controller/PageController.php @@ -0,0 +1,57 @@ +twig = $twig; + $this->template = $template; + $this->dispatcher = $dispatcher; + } + + public function __invoke(Request $request) : Response + { + $context = [ + 'lang' => $request->getLocale(), + 'dir' => text_direction($request->getLocale()), + ]; + + $loadEvent = new LoadPageEvent($request, $context); + $this->dispatcher->dispatch($loadEvent::NAME, $loadEvent); + + $createEvent = new CreatePageEvent($request, $loadEvent->getDocuments()->wait(), $loadEvent->getContext()); + $this->dispatcher->dispatch($createEvent::NAME, $createEvent); + + if (0 === count($createEvent->getContent())) { + throw new InvalidArgumentException('No content'); + } + + return new Response( + $this->twig->render( + $this->template, + $createEvent->getContext() + [ + 'title' => $createEvent->getTitle(), + 'content' => $createEvent->getContent(), + ] + ) + ); + } +} diff --git a/vendor-extra/ContentPageBundle/src/DependencyInjection/ContentPageConfiguration.php b/vendor-extra/LiberoPageBundle/src/DependencyInjection/LiberoPageConfiguration.php similarity index 61% rename from vendor-extra/ContentPageBundle/src/DependencyInjection/ContentPageConfiguration.php rename to vendor-extra/LiberoPageBundle/src/DependencyInjection/LiberoPageConfiguration.php index 6d21efc..e869bc5 100644 --- a/vendor-extra/ContentPageBundle/src/DependencyInjection/ContentPageConfiguration.php +++ b/vendor-extra/LiberoPageBundle/src/DependencyInjection/LiberoPageConfiguration.php @@ -2,13 +2,13 @@ declare(strict_types=1); -namespace Libero\ContentPageBundle\DependencyInjection; +namespace Libero\LiberoPageBundle\DependencyInjection; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; -final class ContentPageConfiguration implements ConfigurationInterface +final class LiberoPageConfiguration implements ConfigurationInterface { private $rootName; @@ -45,12 +45,27 @@ private function getPagesDefinition() : ArrayNodeDefinition $pagesNode ->arrayPrototype() ->children() - ->scalarNode('path') + ->enumNode('type') + ->values(['content', 'homepage']) ->isRequired() ->end() - ->scalarNode('service') + ->scalarNode('path') ->isRequired() ->end() + ->scalarNode('content_service') + ->end() + ->end() + ->validate() + ->ifTrue(function (array $values) : bool { + return 'content' === $values['type'] && !isset($values['content_service']); + }) + ->thenInvalid('Content pages require a content_service') + ->end() + ->validate() + ->ifTrue(function (array $values) : bool { + return 'content' !== $values['type'] && isset($values['content_service']); + }) + ->thenInvalid('Non-content pages cannot have a content_service') ->end() ->end() ; diff --git a/vendor-extra/LiberoPageBundle/src/DependencyInjection/LiberoPageExtension.php b/vendor-extra/LiberoPageBundle/src/DependencyInjection/LiberoPageExtension.php new file mode 100644 index 0000000..d4affa2 --- /dev/null +++ b/vendor-extra/LiberoPageBundle/src/DependencyInjection/LiberoPageExtension.php @@ -0,0 +1,52 @@ +load('services.xml'); + + $config = $this->processConfiguration($this->getConfiguration($configs, $container), $configs); + + $container->setAlias('libero.client', $config['client']); + $container->setParameter('libero.page_template', $config['page_template']); + + foreach (array_keys($config['pages']) as $name) { + $config['pages'][$name]['name'] = $name; + $config['pages'][$name]['controller'] = PageController::class; + $config['pages'][$name]['route'] = "libero.page.{$config['pages'][$name]['type']}.{$name}"; + } + + $container->findDefinition(PageRouteLoader::class) + ->setArgument(0, $config['pages']); + + $container->findDefinition(LiberoPageListener::class) + ->setArgument(0, array_column($config['pages'], null, 'route')); + } + + public function getConfiguration(array $config, ContainerBuilder $container) : ConfigurationInterface + { + return new LiberoPageConfiguration($this->getAlias()); + } + + public function getAlias() : string + { + return 'libero_page'; + } +} diff --git a/vendor-extra/LiberoPageBundle/src/Event/CreatePageEvent.php b/vendor-extra/LiberoPageBundle/src/Event/CreatePageEvent.php new file mode 100644 index 0000000..f8087af --- /dev/null +++ b/vendor-extra/LiberoPageBundle/src/Event/CreatePageEvent.php @@ -0,0 +1,83 @@ + $documents + */ + public function __construct(Request $request, array $documents, array $context = []) + { + $this->request = $request; + $this->documents = $documents; + $this->context = $context; + } + + public function getRequest() : Request + { + return $this->request; + } + + public function getContent() : array + { + return $this->content; + } + + public function addContent($content) : void + { + $this->content[] = $content; + } + + public function getContext() : array + { + return $this->context; + } + + public function setContext(string $key, $value) : void + { + $this->context[$key] = $value; + } + + public function getDocument(string $key) : Document + { + if (!isset($this->documents[$key])) { + throw new InvalidArgumentException("Unknown document '{$key}'"); + } + + return $this->documents[$key]; + } + + /** + * @return array + */ + public function getDocuments() : array + { + return $this->documents; + } + + public function getTitle() : ?string + { + return $this->title; + } + + public function setTitle(string $title) : void + { + $this->title = $title; + } +} diff --git a/vendor-extra/LiberoPageBundle/src/Event/LoadPageEvent.php b/vendor-extra/LiberoPageBundle/src/Event/LoadPageEvent.php new file mode 100644 index 0000000..b1b5fd5 --- /dev/null +++ b/vendor-extra/LiberoPageBundle/src/Event/LoadPageEvent.php @@ -0,0 +1,50 @@ +request = $request; + $this->context = $context; + } + + public function getRequest() : Request + { + return $this->request; + } + + public function addDocument(string $key, PromiseInterface $promise) : void + { + $this->documents[$key] = $promise; + } + + public function getDocuments() : PromiseInterface + { + return all($this->documents); + } + + public function getContext() : array + { + return $this->context; + } + + public function setContext(string $key, $value) : void + { + $this->context[$key] = $value; + } +} diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/ContentItemListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/ContentItemListener.php new file mode 100644 index 0000000..a26c81d --- /dev/null +++ b/vendor-extra/LiberoPageBundle/src/EventListener/ContentItemListener.php @@ -0,0 +1,48 @@ +client = $client; + } + + public function onLoadPage(LoadPageEvent $event) : void + { + $request = $event->getRequest(); + $page = $request->attributes->get('libero_page', ['type' => '']); + + if ('content' !== $page['type']) { + return; + } + + $event->addDocument( + 'content_item', + $this->client->requestAsync( + 'GET', + "{$page['content_service']}/items/{$page['content_id']}/versions/latest", + [ + 'headers' => ['Accept' => 'application/xml'], + 'http_errors' => true, + ] + ) + ->then( + function (ResponseInterface $response) : Document { + return FluentDOM::load((string) $response->getBody()); + } + ) + ); + } +} diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentHeaderListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentHeaderListener.php new file mode 100644 index 0000000..0a2d90c --- /dev/null +++ b/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentHeaderListener.php @@ -0,0 +1,35 @@ +translator = $translator; + } + + public function onCreatePage(CreatePageEvent $event) : void + { + if ('homepage' !== $event->getRequest()->attributes->get('libero_page')['type']) { + return; + } + + $event->addContent( + new View( + '@LiberoPatterns/content-header.html.twig', + ['contentTitle' => ['text' => $this->translate('libero.page.site_name', $event->getContext())]], + $event->getContext() + ) + ); + } +} diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/LiberoPageListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/LiberoPageListener.php new file mode 100644 index 0000000..e5f26a5 --- /dev/null +++ b/vendor-extra/LiberoPageBundle/src/EventListener/LiberoPageListener.php @@ -0,0 +1,40 @@ + $routes + */ + public function __construct(array $routes) + { + $this->routes = $routes; + } + + public function onKernelRequest(GetResponseEvent $event) + { + $request = $event->getRequest(); + $route = $request->attributes->get('_route'); + + if (!isset($this->routes[$route])) { + $request->attributes->set('libero_page', ['type' => '']); + + return; + } + + $page = $this->routes[$route]; + + if ('content' === $page['type']) { + $page['content_id'] = $request->attributes->get('id'); + } + + $request->attributes->set('libero_page', $page); + } +} diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/NamespaceListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/NamespaceListener.php new file mode 100644 index 0000000..a439ab0 --- /dev/null +++ b/vendor-extra/LiberoPageBundle/src/EventListener/NamespaceListener.php @@ -0,0 +1,26 @@ +prefix = $prefix; + $this->uri = $uri; + } + + public function onCreatePage(CreatePageEvent $event) : void + { + foreach ($event->getDocuments() as $document) { + $document->registerNamespace($this->prefix, $this->uri); + } + } +} diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/TitleListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/TitleListener.php new file mode 100644 index 0000000..a1a365f --- /dev/null +++ b/vendor-extra/LiberoPageBundle/src/EventListener/TitleListener.php @@ -0,0 +1,31 @@ +translator = $translator; + } + + public function onCreatePage(CreatePageEvent $event) : void + { + $title = $event->getTitle(); + + if (is_string($title)) { + $title .= ' | '; + } + + $event->setTitle($title.$this->translate('libero.page.site_name', $event->getContext())); + } +} diff --git a/vendor-extra/ContentPageBundle/src/ContentPageBundle.php b/vendor-extra/LiberoPageBundle/src/LiberoPageBundle.php similarity index 51% rename from vendor-extra/ContentPageBundle/src/ContentPageBundle.php rename to vendor-extra/LiberoPageBundle/src/LiberoPageBundle.php index 7f0cc34..277d1b4 100644 --- a/vendor-extra/ContentPageBundle/src/ContentPageBundle.php +++ b/vendor-extra/LiberoPageBundle/src/LiberoPageBundle.php @@ -2,10 +2,10 @@ declare(strict_types=1); -namespace Libero\ContentPageBundle; +namespace Libero\LiberoPageBundle; use Symfony\Component\HttpKernel\Bundle\Bundle; -final class ContentPageBundle extends Bundle +final class LiberoPageBundle extends Bundle { } diff --git a/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml b/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml new file mode 100644 index 0000000..53a646e --- /dev/null +++ b/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + %libero.page_template% + + + + + + + + + + + + + + + + + + + + + libero + http://libero.pub + + + + + + + + + + + + + + + + + diff --git a/vendor-extra/LiberoPageBundle/src/Resources/translations/messages+intl-icu.en.xlf b/vendor-extra/LiberoPageBundle/src/Resources/translations/messages+intl-icu.en.xlf new file mode 100644 index 0000000..98a9145 --- /dev/null +++ b/vendor-extra/LiberoPageBundle/src/Resources/translations/messages+intl-icu.en.xlf @@ -0,0 +1,19 @@ + + + + + + + + + + Site Name + + + + + + + diff --git a/vendor-extra/ContentPageBundle/src/Routing/ContentPageRouteLoader.php b/vendor-extra/LiberoPageBundle/src/Routing/PageRouteLoader.php similarity index 57% rename from vendor-extra/ContentPageBundle/src/Routing/ContentPageRouteLoader.php rename to vendor-extra/LiberoPageBundle/src/Routing/PageRouteLoader.php index 1e96812..65fca72 100644 --- a/vendor-extra/ContentPageBundle/src/Routing/ContentPageRouteLoader.php +++ b/vendor-extra/LiberoPageBundle/src/Routing/PageRouteLoader.php @@ -2,13 +2,13 @@ declare(strict_types=1); -namespace Libero\ContentPageBundle\Routing; +namespace Libero\LiberoPageBundle\Routing; use Symfony\Component\Config\Loader\Loader; use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\RouteCollectionBuilder; -final class ContentPageRouteLoader extends Loader +final class PageRouteLoader extends Loader { private $pages; @@ -21,12 +21,8 @@ public function load($resource, $type = null) : RouteCollection { $routes = new RouteCollectionBuilder(); - foreach ($this->pages as $name => $config) { - $routes->add( - $config['path'], - "libero.content_page.controller.content.{$config['name']}", - "libero.content.{$config['name']}.item" - ); + foreach ($this->pages as $config) { + $routes->add($config['path'], $config['controller'], $config['route']); } return $routes->build(); @@ -34,6 +30,6 @@ public function load($resource, $type = null) : RouteCollection public function supports($resource, $type = null) : bool { - return 'content_page' === $type; + return 'libero_page' === $type; } } diff --git a/vendor-extra/ContentPageBundle/src/functions.php b/vendor-extra/LiberoPageBundle/src/functions.php similarity index 92% rename from vendor-extra/ContentPageBundle/src/functions.php rename to vendor-extra/LiberoPageBundle/src/functions.php index e789d03..8446bc0 100644 --- a/vendor-extra/ContentPageBundle/src/functions.php +++ b/vendor-extra/LiberoPageBundle/src/functions.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Libero\ContentPageBundle; +namespace Libero\LiberoPageBundle; use InvalidArgumentException; use Punic\Exception\InvalidLocale; diff --git a/vendor-extra/ContentPageBundle/tests/Controller/ContentControllerTest.php b/vendor-extra/LiberoPageBundle/tests/Controller/ContentControllerTest.php similarity index 91% rename from vendor-extra/ContentPageBundle/tests/Controller/ContentControllerTest.php rename to vendor-extra/LiberoPageBundle/tests/Controller/ContentControllerTest.php index 0360b2d..684d818 100644 --- a/vendor-extra/ContentPageBundle/tests/Controller/ContentControllerTest.php +++ b/vendor-extra/LiberoPageBundle/tests/Controller/ContentControllerTest.php @@ -2,18 +2,18 @@ declare(strict_types=1); -namespace tests\Libero\ContentPageBundle\Controller; +namespace tests\Libero\LiberoPageBundle\Controller; use GuzzleHttp\Exception\ClientException; use GuzzleHttp\Psr7\Request as Psr7Request; use GuzzleHttp\Psr7\Response as Psr7Response; -use Libero\ContentPageBundle\Controller\ContentController; -use Libero\ContentPageBundle\Event\CreateContentPageEvent; +use Libero\LiberoPageBundle\Controller\ContentController; +use Libero\LiberoPageBundle\Event\CreatePageEvent; use PHPUnit\Framework\TestCase; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\HttpFoundation\Request; -use tests\Libero\ContentPageBundle\GuzzleTestCase; -use tests\Libero\ContentPageBundle\TwigTestCase; +use tests\Libero\LiberoPageBundle\GuzzleTestCase; +use tests\Libero\LiberoPageBundle\TwigTestCase; final class ContentControllerTest extends TestCase { @@ -146,8 +146,8 @@ private function createContentController( ) : ContentController { $dispatcher = new EventDispatcher(); $dispatcher->addListener( - CreateContentPageEvent::NAME, - function (CreateContentPageEvent $event) : void { + CreatePageEvent::NAME, + function (CreatePageEvent $event) : void { $event->setContext('context', $event->getContext()); $event->setTitle('title'); $event->addContent('content'); diff --git a/vendor-extra/ContentPageBundle/tests/GuzzleTestCase.php b/vendor-extra/LiberoPageBundle/tests/GuzzleTestCase.php similarity index 96% rename from vendor-extra/ContentPageBundle/tests/GuzzleTestCase.php rename to vendor-extra/LiberoPageBundle/tests/GuzzleTestCase.php index 8966e41..9beb2f4 100644 --- a/vendor-extra/ContentPageBundle/tests/GuzzleTestCase.php +++ b/vendor-extra/LiberoPageBundle/tests/GuzzleTestCase.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace tests\Libero\ContentPageBundle; +namespace tests\Libero\LiberoPageBundle; use Csa\GuzzleHttp\Middleware\Cache\Adapter\MockStorageAdapter; use Csa\GuzzleHttp\Middleware\Cache\Adapter\StorageAdapterInterface; diff --git a/vendor-extra/ContentPageBundle/tests/TextDirectionTest.php b/vendor-extra/LiberoPageBundle/tests/TextDirectionTest.php similarity index 90% rename from vendor-extra/ContentPageBundle/tests/TextDirectionTest.php rename to vendor-extra/LiberoPageBundle/tests/TextDirectionTest.php index 3ef4af9..2a18ad4 100644 --- a/vendor-extra/ContentPageBundle/tests/TextDirectionTest.php +++ b/vendor-extra/LiberoPageBundle/tests/TextDirectionTest.php @@ -2,11 +2,11 @@ declare(strict_types=1); -namespace tests\Libero\ContentPageBundle; +namespace tests\Libero\LiberoPageBundle; use InvalidArgumentException; use PHPUnit\Framework\TestCase; -use function Libero\ContentPageBundle\text_direction; +use function Libero\LiberoPageBundle\text_direction; final class TextDirectionTest extends TestCase { diff --git a/vendor-extra/ContentPageBundle/tests/TwigTestCase.php b/vendor-extra/LiberoPageBundle/tests/TwigTestCase.php similarity index 96% rename from vendor-extra/ContentPageBundle/tests/TwigTestCase.php rename to vendor-extra/LiberoPageBundle/tests/TwigTestCase.php index ab758e5..9b3e877 100644 --- a/vendor-extra/ContentPageBundle/tests/TwigTestCase.php +++ b/vendor-extra/LiberoPageBundle/tests/TwigTestCase.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace tests\Libero\ContentPageBundle; +namespace tests\Libero\LiberoPageBundle; use PHPUnit\Framework\MockObject\MockObject; use Symfony\Component\DomCrawler\Crawler; diff --git a/vendor-extra/ContentPageBundle/tests/ViewConvertingTestCase.php b/vendor-extra/LiberoPageBundle/tests/ViewConvertingTestCase.php similarity index 95% rename from vendor-extra/ContentPageBundle/tests/ViewConvertingTestCase.php rename to vendor-extra/LiberoPageBundle/tests/ViewConvertingTestCase.php index 26ce564..09528e7 100644 --- a/vendor-extra/ContentPageBundle/tests/ViewConvertingTestCase.php +++ b/vendor-extra/LiberoPageBundle/tests/ViewConvertingTestCase.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace tests\Libero\ContentPageBundle; +namespace tests\Libero\LiberoPageBundle; use FluentDOM\DOM\Node\NonDocumentTypeChildNode; use Libero\ViewsBundle\Views\CallbackViewConverter; diff --git a/vendor-extra/ContentPageBundle/tests/XmlTestCase.php b/vendor-extra/LiberoPageBundle/tests/XmlTestCase.php similarity index 92% rename from vendor-extra/ContentPageBundle/tests/XmlTestCase.php rename to vendor-extra/LiberoPageBundle/tests/XmlTestCase.php index 4a0cdfd..8fd721f 100644 --- a/vendor-extra/ContentPageBundle/tests/XmlTestCase.php +++ b/vendor-extra/LiberoPageBundle/tests/XmlTestCase.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace tests\Libero\ContentPageBundle; +namespace tests\Libero\LiberoPageBundle; use FluentDOM; use FluentDOM\DOM\Document; diff --git a/vendor-extra/ViewsBundle/tests/ViewConverter/LangVisitorTest.php b/vendor-extra/ViewsBundle/tests/ViewConverter/LangVisitorTest.php index 3b20b8e..8ddd3e4 100644 --- a/vendor-extra/ViewsBundle/tests/ViewConverter/LangVisitorTest.php +++ b/vendor-extra/ViewsBundle/tests/ViewConverter/LangVisitorTest.php @@ -8,7 +8,7 @@ use Libero\ViewsBundle\ViewConverter\LangVisitor; use Libero\ViewsBundle\Views\View; use PHPUnit\Framework\TestCase; -use tests\Libero\ContentPageBundle\XmlTestCase; +use tests\Libero\LiberoPageBundle\XmlTestCase; final class LangVisitorTest extends TestCase { diff --git a/vendor-extra/ViewsBundle/tests/Views/ViewConverterRegistryTest.php b/vendor-extra/ViewsBundle/tests/Views/ViewConverterRegistryTest.php index 467412b..054055f 100644 --- a/vendor-extra/ViewsBundle/tests/Views/ViewConverterRegistryTest.php +++ b/vendor-extra/ViewsBundle/tests/Views/ViewConverterRegistryTest.php @@ -12,7 +12,7 @@ use Libero\ViewsBundle\Views\ViewConverterRegistry; use LogicException; use PHPUnit\Framework\TestCase; -use tests\Libero\ContentPageBundle\XmlTestCase; +use tests\Libero\LiberoPageBundle\XmlTestCase; final class ViewConverterRegistryTest extends TestCase { From 2350dfcd4d981a671db9a48d7d49aaffe76a2730 Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Tue, 19 Mar 2019 11:06:25 +0000 Subject: [PATCH 02/46] Not there anymore --- composer.json | 1 - composer.lock | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index e0ba746..c034f08 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,6 @@ "autoload-dev": { "psr-4": { "tests\\Libero\\Browser\\": "tests/", - "tests\\Libero\\ContentPageBundle\\": "vendor-extra/ContentPageBundle/tests/", "tests\\Libero\\JatsContentBundle\\": "vendor-extra/JatsContentBundle/tests/", "tests\\Libero\\LiberoContentBundle\\": "vendor-extra/LiberoContentBundle/tests/", "tests\\Libero\\LiberoPageBundle\\": "vendor-extra/LiberoPageBundle/tests/", diff --git a/composer.lock b/composer.lock index af9a214..56ac33b 100644 --- a/composer.lock +++ b/composer.lock @@ -537,13 +537,14 @@ "dist": { "type": "path", "url": "./vendor-extra/LiberoPageBundle", - "reference": "404a7a39bdd8bd5d48fe6e55248274dea6caf574" + "reference": "2cfff9d16f9065f381db01dcf08b76c56f9f2d33" }, "require": { "fluentdom/fluentdom": "^7.0", "guzzlehttp/promises": "^1.0", "php": "^7.2", "punic/punic": "^3.3", + "symfony/contracts": "^1.0", "symfony/event-dispatcher": "^4.1", "symfony/http-foundation": "^4.1", "symfony/http-kernel": "^4.1", From 75b044d97fb95d7fb32d25c9152b9a84c384d86c Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Tue, 19 Mar 2019 16:02:46 +0000 Subject: [PATCH 03/46] Update existing tests --- .../tests/EventListener/BodyListenerTest.php | 41 ++++++- .../ContentHeaderListenerTest.php | 47 +++++++- .../EventListener/ItemTagsListenerTest.php | 47 +++++++- .../ContentHeaderListenerTest.php | 41 ++++++- ...trollerTest.php => PageControllerTest.php} | 113 ++++++------------ .../LiberoPageBundle/tests/PageTestCase.php | 18 +++ 6 files changed, 221 insertions(+), 86 deletions(-) rename vendor-extra/LiberoPageBundle/tests/Controller/{ContentControllerTest.php => PageControllerTest.php} (52%) create mode 100644 vendor-extra/LiberoPageBundle/tests/PageTestCase.php diff --git a/vendor-extra/JatsContentBundle/tests/EventListener/BodyListenerTest.php b/vendor-extra/JatsContentBundle/tests/EventListener/BodyListenerTest.php index 2207678..20988d0 100644 --- a/vendor-extra/JatsContentBundle/tests/EventListener/BodyListenerTest.php +++ b/vendor-extra/JatsContentBundle/tests/EventListener/BodyListenerTest.php @@ -8,15 +8,52 @@ use Libero\LiberoPageBundle\Event\CreatePageEvent; use Libero\ViewsBundle\Views\View; use PHPUnit\Framework\TestCase; +use tests\Libero\LiberoPageBundle\PageTestCase; use tests\Libero\LiberoPageBundle\ViewConvertingTestCase; use tests\Libero\LiberoPageBundle\XmlTestCase; use function array_map; final class BodyListenerTest extends TestCase { + use PageTestCase; use ViewConvertingTestCase; use XmlTestCase; + /** + * @test + */ + public function it_does_nothing_if_it_is_not_a_content_page() : void + { + $listener = new BodyListener($this->createFailingConverter()); + + $document = $this->loadDocument( + << + + + id + + + + Paragraph 1 + + Section 1 + + Paragraph 2 + + + +XML + ); + + $event = new CreatePageEvent($this->createRequest('foo'), ['content_item' => $document]); + $originalEvent = clone $event; + + $listener->onCreatePage($event); + + $this->assertEquals($originalEvent, $event); + } + /** * @test */ @@ -36,7 +73,7 @@ public function it_does_nothing_if_it_does_not_find_the_body() : void XML ); - $event = new CreatePageEvent($document); + $event = new CreatePageEvent($this->createRequest('content'), ['content_item' => $document]); $originalEvent = clone $event; $listener->onCreatePage($event); @@ -54,7 +91,7 @@ public function it_adds_the_body_content(string $xml, array $context, array $exp $document = $this->loadDocument($xml); - $event = new CreatePageEvent($document, $context); + $event = new CreatePageEvent($this->createRequest('content'), ['content_item' => $document], $context); $listener->onCreatePage($event); $this->assertEquals( diff --git a/vendor-extra/JatsContentBundle/tests/EventListener/ContentHeaderListenerTest.php b/vendor-extra/JatsContentBundle/tests/EventListener/ContentHeaderListenerTest.php index db83b3b..0282386 100644 --- a/vendor-extra/JatsContentBundle/tests/EventListener/ContentHeaderListenerTest.php +++ b/vendor-extra/JatsContentBundle/tests/EventListener/ContentHeaderListenerTest.php @@ -8,14 +8,51 @@ use Libero\LiberoPageBundle\Event\CreatePageEvent; use Libero\ViewsBundle\Views\View; use PHPUnit\Framework\TestCase; +use tests\Libero\LiberoPageBundle\PageTestCase; use tests\Libero\LiberoPageBundle\ViewConvertingTestCase; use tests\Libero\LiberoPageBundle\XmlTestCase; final class ContentHeaderListenerTest extends TestCase { + use PageTestCase; use ViewConvertingTestCase; use XmlTestCase; + /** + * @test + */ + public function it_does_nothing_if_it_is_not_a_content_page() : void + { + $listener = new ContentHeaderListener($this->createFailingConverter()); + + $document = $this->loadDocument( + << + + + id + + + + + + Title + + + + + +XML + ); + + $event = new CreatePageEvent($this->createRequest('foo'), ['content_item' => $document]); + $originalEvent = clone $event; + + $listener->onCreatePage($event); + + $this->assertEquals($originalEvent, $event); + } + /** * @test */ @@ -35,7 +72,7 @@ public function it_does_nothing_if_it_does_not_find_the_front() : void XML ); - $event = new CreatePageEvent($document); + $event = new CreatePageEvent($this->createRequest('content'), ['content_item' => $document]); $originalEvent = clone $event; $listener->onCreatePage($event); @@ -55,7 +92,11 @@ public function it_sets_the_title_and_adds_a_content_header( ) : void { $listener = new ContentHeaderListener($this->createDumpingConverter()); - $event = new CreatePageEvent($this->loadDocument($xml), $context); + $event = new CreatePageEvent( + $this->createRequest('content'), + ['content_item' => $this->loadDocument($xml)], + $context + ); $listener->onCreatePage($event); $this->assertSame($expectedTitle, $event->getTitle()); @@ -222,7 +263,7 @@ public function it_does_not_replace_an_existing_title() : void XML ); - $event = new CreatePageEvent($document); + $event = new CreatePageEvent($this->createRequest('content'), ['content_item' => $document]); $event->setTitle('Existing Title'); $listener->onCreatePage($event); diff --git a/vendor-extra/JatsContentBundle/tests/EventListener/ItemTagsListenerTest.php b/vendor-extra/JatsContentBundle/tests/EventListener/ItemTagsListenerTest.php index c2601b7..a90f5c4 100644 --- a/vendor-extra/JatsContentBundle/tests/EventListener/ItemTagsListenerTest.php +++ b/vendor-extra/JatsContentBundle/tests/EventListener/ItemTagsListenerTest.php @@ -8,14 +8,57 @@ use Libero\LiberoPageBundle\Event\CreatePageEvent; use Libero\ViewsBundle\Views\View; use PHPUnit\Framework\TestCase; +use tests\Libero\LiberoPageBundle\PageTestCase; use tests\Libero\LiberoPageBundle\ViewConvertingTestCase; use tests\Libero\LiberoPageBundle\XmlTestCase; final class ItemTagsListenerTest extends TestCase { + use PageTestCase; use ViewConvertingTestCase; use XmlTestCase; + /** + * @test + */ + public function it_does_nothing_if_it_is_not_a_content_page() : void + { + $listener = new ItemTagsListener($this->createFailingConverter()); + + $document = $this->loadDocument( + << + + + id + + + + + + foo + + + bar + + + baz + + + + + +XML + ); + + $event = new CreatePageEvent($this->createRequest('foo'), ['content_item' => $document]); + $originalEvent = clone $event; + + $listener->onCreatePage($event); + + $this->assertEquals($originalEvent, $event); + } + /** * @test */ @@ -35,7 +78,7 @@ public function it_does_nothing_if_it_does_not_find_the_front() : void XML ); - $event = new CreatePageEvent($document); + $event = new CreatePageEvent($this->createRequest('content'), ['content_item' => $document]); $originalEvent = clone $event; $listener->onCreatePage($event); @@ -56,7 +99,7 @@ public function it_adds_item_tags( $document = $this->loadDocument($xml); - $event = new CreatePageEvent($document, $context); + $event = new CreatePageEvent($this->createRequest('content'), ['content_item' => $document], $context); $listener->onCreatePage($event); $this->assertEquals( diff --git a/vendor-extra/LiberoContentBundle/tests/EventListener/ContentHeaderListenerTest.php b/vendor-extra/LiberoContentBundle/tests/EventListener/ContentHeaderListenerTest.php index 82310e7..4794bc5 100644 --- a/vendor-extra/LiberoContentBundle/tests/EventListener/ContentHeaderListenerTest.php +++ b/vendor-extra/LiberoContentBundle/tests/EventListener/ContentHeaderListenerTest.php @@ -8,14 +8,45 @@ use Libero\LiberoPageBundle\Event\CreatePageEvent; use Libero\ViewsBundle\Views\View; use PHPUnit\Framework\TestCase; +use tests\Libero\LiberoPageBundle\PageTestCase; use tests\Libero\LiberoPageBundle\ViewConvertingTestCase; use tests\Libero\LiberoPageBundle\XmlTestCase; final class ContentHeaderListenerTest extends TestCase { + use PageTestCase; use ViewConvertingTestCase; use XmlTestCase; + /** + * @test + */ + public function it_does_nothing_if_it_is_not_a_content_page() : void + { + $listener = new ContentHeaderListener($this->createFailingConverter()); + + $document = $this->loadDocument( + << + + + id + + + Title + + +XML + ); + + $event = new CreatePageEvent($this->createRequest('foo'), ['content_item' => $document]); + $originalEvent = clone $event; + + $listener->onCreatePage($event); + + $this->assertEquals($originalEvent, $event); + } + /** * @test */ @@ -34,7 +65,7 @@ public function it_does_nothing_if_it_does_not_find_the_front() : void XML ); - $event = new CreatePageEvent($document); + $event = new CreatePageEvent($this->createRequest('content'), ['content_item' => $document]); $originalEvent = clone $event; $listener->onCreatePage($event); @@ -54,7 +85,11 @@ public function it_sets_the_title_and_adds_a_content_header( ) : void { $listener = new ContentHeaderListener($this->createDumpingConverter()); - $event = new CreatePageEvent($this->loadDocument($xml), $context); + $event = new CreatePageEvent( + $this->createRequest('content'), + ['content_item' => $this->loadDocument($xml)], + $context + ); $listener->onCreatePage($event); $this->assertSame($expectedTitle, $event->getTitle()); @@ -195,7 +230,7 @@ public function it_does_not_replace_an_existing_title() : void XML ); - $event = new CreatePageEvent($document); + $event = new CreatePageEvent($this->createRequest('content'), ['content_item' => $document]); $event->setTitle('Existing Title'); $listener->onCreatePage($event); diff --git a/vendor-extra/LiberoPageBundle/tests/Controller/ContentControllerTest.php b/vendor-extra/LiberoPageBundle/tests/Controller/PageControllerTest.php similarity index 52% rename from vendor-extra/LiberoPageBundle/tests/Controller/ContentControllerTest.php rename to vendor-extra/LiberoPageBundle/tests/Controller/PageControllerTest.php index 684d818..ff96e9e 100644 --- a/vendor-extra/LiberoPageBundle/tests/Controller/ContentControllerTest.php +++ b/vendor-extra/LiberoPageBundle/tests/Controller/PageControllerTest.php @@ -4,21 +4,21 @@ namespace tests\Libero\LiberoPageBundle\Controller; -use GuzzleHttp\Exception\ClientException; -use GuzzleHttp\Psr7\Request as Psr7Request; -use GuzzleHttp\Psr7\Response as Psr7Response; -use Libero\LiberoPageBundle\Controller\ContentController; +use InvalidArgumentException; +use Libero\LiberoPageBundle\Controller\PageController; use Libero\LiberoPageBundle\Event\CreatePageEvent; +use Libero\LiberoPageBundle\Event\LoadPageEvent; use PHPUnit\Framework\TestCase; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\HttpFoundation\Request; -use tests\Libero\LiberoPageBundle\GuzzleTestCase; use tests\Libero\LiberoPageBundle\TwigTestCase; +use tests\Libero\LiberoPageBundle\XmlTestCase; +use function GuzzleHttp\Promise\promise_for; -final class ContentControllerTest extends TestCase +final class PageControllerTest extends TestCase { - use GuzzleTestCase; use TwigTestCase; + use XmlTestCase; /** * @test @@ -26,30 +26,21 @@ final class ContentControllerTest extends TestCase */ public function it_returns_the_title(Request $request, array $twigContext) : void { - $controller = $this->createContentController(); - - $this->mock->save( - new Psr7Request( - 'GET', - 'service/items/id/versions/latest', - ['Accept' => 'application/xml'] - ), - new Psr7Response( - 200, - [], - << - - - id - Title - - -XML - ) - ); - - $response = $controller($request, 'id'); + $listeners = [ + LoadPageEvent::NAME => function (LoadPageEvent $event) : void { + $document = $this->loadDocument('content'); + $event->addDocument('foo', promise_for($document)); + }, + CreatePageEvent::NAME => function (CreatePageEvent $event) : void { + $event->setContext('context', $event->getContext()); + $event->setTitle('title'); + $event->addContent($event->getDocument('foo')->textContent); + }, + ]; + + $controller = $this->createPageController($listeners); + + $response = $controller($request); $response->prepare($request); $this->assertSame(200, $response->getStatusCode()); @@ -111,55 +102,25 @@ public function pageProvider() : iterable /** * @test */ - public function it_throws_http_errors() : void + public function it_throws_an_error_if_no_content_is_produced() : void { - $controller = $this->createContentController(); - - $this->mock->save( - new Psr7Request( - 'GET', - 'service/items/id/versions/latest', - ['Accept' => 'application/xml'] - ), - new Psr7Response( - 404, - [], - << - - 404 - Not Found - -XML - ) - ); - - $this->expectException(ClientException::class); - $this->expectExceptionMessageRegExp('/404 Not Found/'); - - $controller(new Request(), 'id'); + $controller = $this->createPageController(); + + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessageRegExp('/No content/'); + + $controller(new Request()); } - private function createContentController( - string $service = 'service', + private function createPageController( + array $listeners = [], string $template = 'template.html.twig' - ) : ContentController { + ) : PageController { $dispatcher = new EventDispatcher(); - $dispatcher->addListener( - CreatePageEvent::NAME, - function (CreatePageEvent $event) : void { - $event->setContext('context', $event->getContext()); - $event->setTitle('title'); - $event->addContent('content'); - } - ); - - return new ContentController( - $this->client, - $service, - $this->createTwig(), - $template, - $dispatcher - ); + foreach ($listeners as $eventName => $listener) { + $dispatcher->addListener($eventName, $listener); + } + + return new PageController($this->createTwig(), $template, $dispatcher); } } diff --git a/vendor-extra/LiberoPageBundle/tests/PageTestCase.php b/vendor-extra/LiberoPageBundle/tests/PageTestCase.php new file mode 100644 index 0000000..10f03f7 --- /dev/null +++ b/vendor-extra/LiberoPageBundle/tests/PageTestCase.php @@ -0,0 +1,18 @@ +attributes->set('libero_page', ['type' => $type]); + + return $request; + } +} From ab67c944c1f62b4c816e25383601080386c83fad Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Tue, 19 Mar 2019 16:10:34 +0000 Subject: [PATCH 04/46] Use specific exception --- .../src/Controller/PageController.php | 4 ++-- .../src/Exception/NoContentSet.php | 21 +++++++++++++++++++ .../tests/Controller/PageControllerTest.php | 16 +++++++------- .../LiberoPageBundle/tests/PageTestCase.php | 4 ++-- 4 files changed, 34 insertions(+), 11 deletions(-) create mode 100644 vendor-extra/LiberoPageBundle/src/Exception/NoContentSet.php diff --git a/vendor-extra/LiberoPageBundle/src/Controller/PageController.php b/vendor-extra/LiberoPageBundle/src/Controller/PageController.php index 01c5525..7ab7e2d 100644 --- a/vendor-extra/LiberoPageBundle/src/Controller/PageController.php +++ b/vendor-extra/LiberoPageBundle/src/Controller/PageController.php @@ -4,9 +4,9 @@ namespace Libero\LiberoPageBundle\Controller; -use InvalidArgumentException; use Libero\LiberoPageBundle\Event\CreatePageEvent; use Libero\LiberoPageBundle\Event\LoadPageEvent; +use Libero\LiberoPageBundle\Exception\NoContentSet; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -41,7 +41,7 @@ public function __invoke(Request $request) : Response $this->dispatcher->dispatch($createEvent::NAME, $createEvent); if (0 === count($createEvent->getContent())) { - throw new InvalidArgumentException('No content'); + throw NoContentSet::forPage($request->attributes->get('libero_page')); } return new Response( diff --git a/vendor-extra/LiberoPageBundle/src/Exception/NoContentSet.php b/vendor-extra/LiberoPageBundle/src/Exception/NoContentSet.php new file mode 100644 index 0000000..f1c1f98 --- /dev/null +++ b/vendor-extra/LiberoPageBundle/src/Exception/NoContentSet.php @@ -0,0 +1,21 @@ + [ - new Request(), + $this->createRequest('type'), [ 'lang' => 'en', 'dir' => 'ltr', @@ -64,7 +66,7 @@ public function pageProvider() : iterable ], ]; - $frenchRequest = new Request(); + $frenchRequest = $this->createRequest('type'); $frenchRequest->setLocale('fr'); yield 'fr request' => [ @@ -81,7 +83,7 @@ public function pageProvider() : iterable ], ]; - $arabicRequest = new Request(); + $arabicRequest = $this->createRequest('type'); $arabicRequest->setLocale('ar-EG'); yield 'ar-EG request' => [ @@ -106,10 +108,10 @@ public function it_throws_an_error_if_no_content_is_produced() : void { $controller = $this->createPageController(); - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessageRegExp('/No content/'); + $this->expectException(NoContentSet::class); + $this->expectExceptionMessage("No content has been added to type page 'name'"); - $controller(new Request()); + $controller($this->createRequest('type', 'name')); } private function createPageController( diff --git a/vendor-extra/LiberoPageBundle/tests/PageTestCase.php b/vendor-extra/LiberoPageBundle/tests/PageTestCase.php index 10f03f7..6d01f8c 100644 --- a/vendor-extra/LiberoPageBundle/tests/PageTestCase.php +++ b/vendor-extra/LiberoPageBundle/tests/PageTestCase.php @@ -8,10 +8,10 @@ trait PageTestCase { - final protected function createRequest(string $type) : Request + final protected function createRequest(string $type, ?string $name = null) : Request { $request = new Request(); - $request->attributes->set('libero_page', ['type' => $type]); + $request->attributes->set('libero_page', ['type' => $type, 'name' => $name ?? $type]); return $request; } From 2a92d143f9745d71dad978ecb30dff4ceabfdc51 Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Fri, 22 Mar 2019 13:45:50 +0000 Subject: [PATCH 05/46] Merge fixes --- .../ContentHeaderListenerTest.php | 28 ---------------- .../EventListener/ContentHeaderListener.php | 1 - .../src/Resources/config/services.xml | 6 ++++ .../ContentHeaderListenerTest.php | 33 ++----------------- 4 files changed, 8 insertions(+), 60 deletions(-) diff --git a/vendor-extra/JatsContentBundle/tests/EventListener/ContentHeaderListenerTest.php b/vendor-extra/JatsContentBundle/tests/EventListener/ContentHeaderListenerTest.php index b759301..d9cbff6 100644 --- a/vendor-extra/JatsContentBundle/tests/EventListener/ContentHeaderListenerTest.php +++ b/vendor-extra/JatsContentBundle/tests/EventListener/ContentHeaderListenerTest.php @@ -135,34 +135,6 @@ public function pageProvider() : iterable ], ]; - yield 'en request no title' => [ - << - - - id - - - - - -XML - , - [ - 'lang' => 'en', - 'dir' => 'ltr', - ], - [ - 'node' => '/libero:item/jats:article/jats:front', - 'template' => '@LiberoPatterns/content-header.html.twig', - 'context' => [ - 'lang' => 'en', - 'dir' => 'ltr', - 'area' => null, - ], - ], - ]; - yield 'fr request' => [ << diff --git a/vendor-extra/LiberoContentBundle/src/EventListener/ContentHeaderListener.php b/vendor-extra/LiberoContentBundle/src/EventListener/ContentHeaderListener.php index 39f9713..70cb81a 100644 --- a/vendor-extra/LiberoContentBundle/src/EventListener/ContentHeaderListener.php +++ b/vendor-extra/LiberoContentBundle/src/EventListener/ContentHeaderListener.php @@ -12,7 +12,6 @@ final class ContentHeaderListener { private const FRONT_PATH = '/libero:item/libero:front'; - private $converter; public function __construct(ViewConverter $converter) diff --git a/vendor-extra/LiberoContentBundle/src/Resources/config/services.xml b/vendor-extra/LiberoContentBundle/src/Resources/config/services.xml index a1d80b5..54ca234 100644 --- a/vendor-extra/LiberoContentBundle/src/Resources/config/services.xml +++ b/vendor-extra/LiberoContentBundle/src/Resources/config/services.xml @@ -14,6 +14,12 @@ + + + + + diff --git a/vendor-extra/LiberoContentBundle/tests/EventListener/ContentHeaderListenerTest.php b/vendor-extra/LiberoContentBundle/tests/EventListener/ContentHeaderListenerTest.php index ebb2793..51fa50a 100644 --- a/vendor-extra/LiberoContentBundle/tests/EventListener/ContentHeaderListenerTest.php +++ b/vendor-extra/LiberoContentBundle/tests/EventListener/ContentHeaderListenerTest.php @@ -77,11 +77,8 @@ public function it_does_nothing_if_it_does_not_find_the_front() : void * @test * @dataProvider pageProvider */ - public function it_adds_a_content_header( - string $xml, - array $context, - array $expectedContentHeader - ) : void { + public function it_adds_a_content_header(string $xml, array $context, array $expectedContentHeader) : void + { $listener = new ContentHeaderListener($this->createDumpingConverter()); $event = new CreatePagePartEvent( @@ -125,32 +122,6 @@ public function pageProvider() : iterable ], ]; - yield 'en request no title' => [ - << - - - id - - - -XML - , - [ - 'lang' => 'en', - 'dir' => 'ltr', - ], - [ - 'node' => '/libero:item/libero:front', - 'template' => '@LiberoPatterns/content-header.html.twig', - 'context' => [ - 'lang' => 'en', - 'dir' => 'ltr', - 'area' => null, - ], - ], - ]; - yield 'fr request' => [ << From ace03abb20e5ceb58bc5721276d0371461ce4611 Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Fri, 22 Mar 2019 13:56:14 +0000 Subject: [PATCH 06/46] Set HTML title using translations --- .../src/EventListener/TitleListener.php | 16 ++++++++++++---- .../translations/messages+intl-icu.en.xlf | 4 ++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/TitleListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/TitleListener.php index a1a365f..43a5c4d 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/TitleListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/TitleListener.php @@ -20,12 +20,20 @@ public function __construct(TranslatorInterface $translator) public function onCreatePage(CreatePageEvent $event) : void { - $title = $event->getTitle(); + $siteName = $this->translate('libero.page.site_name', $event->getContext()); - if (is_string($title)) { - $title .= ' | '; + $pageTitle = $event->getTitle(); + + if (!is_string($pageTitle)) { + $event->setTitle($siteName); } - $event->setTitle($title.$this->translate('libero.page.site_name', $event->getContext())); + $event->setTitle( + $this->translate( + 'libero.page.page_title', + $event->getContext(), + ['page_title' => $pageTitle, 'site_name' => $siteName] + ) + ); } } diff --git a/vendor-extra/LiberoPageBundle/src/Resources/translations/messages+intl-icu.en.xlf b/vendor-extra/LiberoPageBundle/src/Resources/translations/messages+intl-icu.en.xlf index 98a9145..65e0996 100644 --- a/vendor-extra/LiberoPageBundle/src/Resources/translations/messages+intl-icu.en.xlf +++ b/vendor-extra/LiberoPageBundle/src/Resources/translations/messages+intl-icu.en.xlf @@ -12,6 +12,10 @@ Site Name + + {page_title} | {site_name} + + From 3f35854d624eaa8534eab64dab4ae0b9e7cdce84 Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Fri, 22 Mar 2019 14:06:22 +0000 Subject: [PATCH 07/46] Add homepage to integration tests --- config/packages/test/libero_page.yaml | 3 +++ tests/WebTest.php | 15 +++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/config/packages/test/libero_page.yaml b/config/packages/test/libero_page.yaml index d2ab311..d2109ca 100644 --- a/config/packages/test/libero_page.yaml +++ b/config/packages/test/libero_page.yaml @@ -1,5 +1,8 @@ libero_page: pages: + homepage: + type: homepage + path: '/' blog_article: type: content path: '/blog/{id}' diff --git a/tests/WebTest.php b/tests/WebTest.php index f805c73..8259676 100644 --- a/tests/WebTest.php +++ b/tests/WebTest.php @@ -10,6 +10,21 @@ final class WebTest extends WebTestCase { + /** + * @test + */ + public function it_has_a_homepage() : void + { + $client = static::createClient(); + + $crawler = $client->request('GET', '/'); + $response = $client->getResponse(); + + $this->assertSame(200, $response->getStatusCode()); + $this->assertSame('text/html; charset=UTF-8', $response->headers->get('Content-Type')); + $this->assertSame('Site Name', trim($crawler->filter('.content-header__title')->text())); + } + /** * @test * @dataProvider idProvider From 087a021715a25f01d7e5004849996d1cd417f23e Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Fri, 22 Mar 2019 14:39:06 +0000 Subject: [PATCH 08/46] Fix and test title --- .../src/EventListener/TitleListener.php | 4 +- .../tests/EventListener/TitleListenerTest.php | 63 +++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 vendor-extra/LiberoPageBundle/tests/EventListener/TitleListenerTest.php diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/TitleListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/TitleListener.php index 43a5c4d..35dafda 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/TitleListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/TitleListener.php @@ -26,13 +26,15 @@ public function onCreatePage(CreatePageEvent $event) : void if (!is_string($pageTitle)) { $event->setTitle($siteName); + + return; } $event->setTitle( $this->translate( 'libero.page.page_title', $event->getContext(), - ['page_title' => $pageTitle, 'site_name' => $siteName] + ['{page_title}' => $pageTitle, '{site_name}' => $siteName] ) ); } diff --git a/vendor-extra/LiberoPageBundle/tests/EventListener/TitleListenerTest.php b/vendor-extra/LiberoPageBundle/tests/EventListener/TitleListenerTest.php new file mode 100644 index 0000000..c1c2d92 --- /dev/null +++ b/vendor-extra/LiberoPageBundle/tests/EventListener/TitleListenerTest.php @@ -0,0 +1,63 @@ +addLoader('array', new ArrayLoader()); + $translator->addResource('array', ['libero.page.site_name' => 'Site Name'], 'en'); + + $mainListener = new TitleListener($translator); + + $event = new CreatePageEvent($this->createRequest('page')); + + $mainListener->onCreatePage($event); + + $this->assertSame('Site Name', $event->getTitle()); + } + + /** + * @test + */ + public function it_updates_the_title() : void + { + $translator = new Translator('en'); + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource( + 'array', + [ + 'libero.page.site_name' => 'Site Name', + 'libero.page.page_title' => "page_title: '{page_title}'; site_name: '{site_name}'", + ], + 'en' + ); + + $mainListener = new TitleListener($translator); + + $event = new CreatePageEvent($this->createRequest('page')); + $event->setTitle('Page Title'); + + $mainListener->onCreatePage($event); + + $this->assertSame("page_title: 'Page Title'; site_name: 'Site Name'", $event->getTitle()); + } +} From 7222c0c56e27ff2b2f03203ec32cdd1f51e72241 Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Thu, 28 Mar 2019 13:54:22 +0000 Subject: [PATCH 09/46] Extract PageEvent --- .../src/Event/CreatePageEvent.php | 19 ++--------- .../src/Event/CreatePagePartEvent.php | 19 ++--------- .../src/Event/LoadPageEvent.php | 19 ++--------- .../LiberoPageBundle/src/Event/PageEvent.php | 33 +++++++++++++++++++ .../src/EventListener/ContentItemListener.php | 7 ++-- .../HomepageContentHeaderListener.php | 2 +- .../tests/Event/CreatePageEventTest.php | 11 +++++++ .../tests/Event/CreatePagePartEventTest.php | 11 +++++++ 8 files changed, 65 insertions(+), 56 deletions(-) create mode 100644 vendor-extra/LiberoPageBundle/src/Event/PageEvent.php diff --git a/vendor-extra/LiberoPageBundle/src/Event/CreatePageEvent.php b/vendor-extra/LiberoPageBundle/src/Event/CreatePageEvent.php index dc96eb2..05a2a45 100644 --- a/vendor-extra/LiberoPageBundle/src/Event/CreatePageEvent.php +++ b/vendor-extra/LiberoPageBundle/src/Event/CreatePageEvent.php @@ -12,12 +12,12 @@ final class CreatePageEvent extends Event { + use PageEvent; + public const NAME = 'libero.page.create'; private $content = []; - private $context; private $documents; - private $request; private $title; /** @@ -30,11 +30,6 @@ public function __construct(Request $request, array $documents = [], array $cont $this->context = $context; } - public function getRequest() : Request - { - return $this->request; - } - public function getContent() : array { return $this->content; @@ -45,16 +40,6 @@ public function setContent(string $area, View $view) : void $this->content[$area] = $view; } - public function getContext() : array - { - return $this->context; - } - - public function setContext(string $key, $value) : void - { - $this->context[$key] = $value; - } - public function getDocument(string $key) : Document { if (!isset($this->documents[$key])) { diff --git a/vendor-extra/LiberoPageBundle/src/Event/CreatePagePartEvent.php b/vendor-extra/LiberoPageBundle/src/Event/CreatePagePartEvent.php index 189ea51..9fb272a 100644 --- a/vendor-extra/LiberoPageBundle/src/Event/CreatePagePartEvent.php +++ b/vendor-extra/LiberoPageBundle/src/Event/CreatePagePartEvent.php @@ -16,10 +16,10 @@ final class CreatePagePartEvent extends Event { + use PageEvent; + private $content = []; - private $context; private $documents; - private $request; private $template; public static function name(string $part) : string @@ -66,16 +66,6 @@ public function addContent(View ...$views) : void } } - public function getContext() : array - { - return $this->context; - } - - public function setContext(string $key, $value) : void - { - $this->context[$key] = $value; - } - public function getDocument(string $key) : Document { if (!isset($this->documents[$key])) { @@ -93,11 +83,6 @@ public function getDocuments() : array return $this->documents; } - public function getRequest() : Request - { - return $this->request; - } - public function getTemplate() : string { return $this->template; diff --git a/vendor-extra/LiberoPageBundle/src/Event/LoadPageEvent.php b/vendor-extra/LiberoPageBundle/src/Event/LoadPageEvent.php index b1b5fd5..75c6580 100644 --- a/vendor-extra/LiberoPageBundle/src/Event/LoadPageEvent.php +++ b/vendor-extra/LiberoPageBundle/src/Event/LoadPageEvent.php @@ -11,11 +11,11 @@ final class LoadPageEvent extends Event { + use PageEvent; + public const NAME = 'libero.page.load'; - private $context; private $documents = []; - private $request; public function __construct(Request $request, array $context = []) { @@ -23,11 +23,6 @@ public function __construct(Request $request, array $context = []) $this->context = $context; } - public function getRequest() : Request - { - return $this->request; - } - public function addDocument(string $key, PromiseInterface $promise) : void { $this->documents[$key] = $promise; @@ -37,14 +32,4 @@ public function getDocuments() : PromiseInterface { return all($this->documents); } - - public function getContext() : array - { - return $this->context; - } - - public function setContext(string $key, $value) : void - { - $this->context[$key] = $value; - } } diff --git a/vendor-extra/LiberoPageBundle/src/Event/PageEvent.php b/vendor-extra/LiberoPageBundle/src/Event/PageEvent.php new file mode 100644 index 0000000..ea0f86d --- /dev/null +++ b/vendor-extra/LiberoPageBundle/src/Event/PageEvent.php @@ -0,0 +1,33 @@ +request->attributes->get('libero_page')['type'] ?? null); + } + + final public function getContext() : array + { + return $this->context; + } + + final public function setContext(string $key, $value) : void + { + $this->context[$key] = $value; + } + + final public function getRequest() : Request + { + return $this->request; + } +} diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/ContentItemListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/ContentItemListener.php index a26c81d..d084fac 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/ContentItemListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/ContentItemListener.php @@ -21,13 +21,12 @@ public function __construct(ClientInterface $client) public function onLoadPage(LoadPageEvent $event) : void { - $request = $event->getRequest(); - $page = $request->attributes->get('libero_page', ['type' => '']); - - if ('content' !== $page['type']) { + if (!$event->isFor('content')) { return; } + $page = $event->getRequest()->attributes->get('libero_page'); + $event->addDocument( 'content_item', $this->client->requestAsync( diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentHeaderListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentHeaderListener.php index e5595fd..80272d9 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentHeaderListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentHeaderListener.php @@ -20,7 +20,7 @@ public function __construct(TranslatorInterface $translator) public function onCreatePagePart(CreatePagePartEvent $event) : void { - if ('homepage' !== $event->getRequest()->attributes->get('libero_page')['type']) { + if (!$event->isFor('homepage')) { return; } diff --git a/vendor-extra/LiberoPageBundle/tests/Event/CreatePageEventTest.php b/vendor-extra/LiberoPageBundle/tests/Event/CreatePageEventTest.php index 39bfe9a..e613360 100644 --- a/vendor-extra/LiberoPageBundle/tests/Event/CreatePageEventTest.php +++ b/vendor-extra/LiberoPageBundle/tests/Event/CreatePageEventTest.php @@ -119,4 +119,15 @@ public function it_has_a_title() : void $this->assertSame('foo', $event->getTitle()); } + + /** + * @test + */ + public function it_is_for_a_page() : void + { + $event = new CreatePageEvent($this->createRequest('page')); + + $this->assertTrue($event->isFor('page')); + $this->assertFalse($event->isFor('other-page')); + } } diff --git a/vendor-extra/LiberoPageBundle/tests/Event/CreatePagePartEventTest.php b/vendor-extra/LiberoPageBundle/tests/Event/CreatePagePartEventTest.php index c4fda1d..1d8e0fc 100644 --- a/vendor-extra/LiberoPageBundle/tests/Event/CreatePagePartEventTest.php +++ b/vendor-extra/LiberoPageBundle/tests/Event/CreatePagePartEventTest.php @@ -109,4 +109,15 @@ public function it_has_a_template() : void $this->assertSame('template', $event->getTemplate()); } + + /** + * @test + */ + public function it_is_for_a_page() : void + { + $event = new CreatePagePartEvent('template', $this->createRequest('page')); + + $this->assertTrue($event->isFor('page')); + $this->assertFalse($event->isFor('other-page')); + } } From 9b8a2044544c23e646dc967c867c995ee1f0bc9c Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Thu, 28 Mar 2019 15:17:48 +0000 Subject: [PATCH 10/46] Missed some cases --- .../JatsContentBundle/src/EventListener/BodyListener.php | 2 +- .../src/EventListener/ContentHeaderListener.php | 2 +- .../JatsContentBundle/src/EventListener/ItemTagsListener.php | 2 +- .../JatsContentBundle/src/EventListener/TitleListener.php | 2 +- .../src/EventListener/ContentHeaderListener.php | 2 +- .../LiberoContentBundle/src/EventListener/TitleListener.php | 2 +- .../src/EventListener/HomepageContentHeaderListener.php | 4 ++-- .../LiberoPageBundle/src/EventListener/TitleListener.php | 4 ++-- .../tests/Views/EventDispatchingViewConverterTest.php | 2 +- 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/vendor-extra/JatsContentBundle/src/EventListener/BodyListener.php b/vendor-extra/JatsContentBundle/src/EventListener/BodyListener.php index f4744d1..1a43a2f 100644 --- a/vendor-extra/JatsContentBundle/src/EventListener/BodyListener.php +++ b/vendor-extra/JatsContentBundle/src/EventListener/BodyListener.php @@ -25,7 +25,7 @@ public function __construct(ViewConverter $converter) public function onCreatePagePart(CreatePagePartEvent $event) : void { - if ('content' !== $event->getRequest()->attributes->get('libero_page')['type']) { + if (!$event->isFor('content')) { return; } diff --git a/vendor-extra/JatsContentBundle/src/EventListener/ContentHeaderListener.php b/vendor-extra/JatsContentBundle/src/EventListener/ContentHeaderListener.php index 89a94d4..db853d3 100644 --- a/vendor-extra/JatsContentBundle/src/EventListener/ContentHeaderListener.php +++ b/vendor-extra/JatsContentBundle/src/EventListener/ContentHeaderListener.php @@ -21,7 +21,7 @@ public function __construct(ViewConverter $converter) public function onCreatePagePart(CreatePagePartEvent $event) : void { - if ('content' !== $event->getRequest()->attributes->get('libero_page')['type']) { + if (!$event->isFor('content')) { return; } diff --git a/vendor-extra/JatsContentBundle/src/EventListener/ItemTagsListener.php b/vendor-extra/JatsContentBundle/src/EventListener/ItemTagsListener.php index e117674..53481fd 100644 --- a/vendor-extra/JatsContentBundle/src/EventListener/ItemTagsListener.php +++ b/vendor-extra/JatsContentBundle/src/EventListener/ItemTagsListener.php @@ -22,7 +22,7 @@ public function __construct(ViewConverter $converter) public function onCreatePagePart(CreatePagePartEvent $event) : void { - if ('content' !== $event->getRequest()->attributes->get('libero_page')['type']) { + if (!$event->isFor('content')) { return; } diff --git a/vendor-extra/JatsContentBundle/src/EventListener/TitleListener.php b/vendor-extra/JatsContentBundle/src/EventListener/TitleListener.php index 60e5c5c..865b1f6 100644 --- a/vendor-extra/JatsContentBundle/src/EventListener/TitleListener.php +++ b/vendor-extra/JatsContentBundle/src/EventListener/TitleListener.php @@ -15,7 +15,7 @@ final class TitleListener public function onCreatePage(CreatePageEvent $event) : void { - if ('content' !== $event->getRequest()->attributes->get('libero_page')['type']) { + if (!$event->isFor('content')) { return; } diff --git a/vendor-extra/LiberoContentBundle/src/EventListener/ContentHeaderListener.php b/vendor-extra/LiberoContentBundle/src/EventListener/ContentHeaderListener.php index 70cb81a..40295ca 100644 --- a/vendor-extra/LiberoContentBundle/src/EventListener/ContentHeaderListener.php +++ b/vendor-extra/LiberoContentBundle/src/EventListener/ContentHeaderListener.php @@ -21,7 +21,7 @@ public function __construct(ViewConverter $converter) public function onCreatePagePart(CreatePagePartEvent $event) : void { - if ('content' !== $event->getRequest()->attributes->get('libero_page')['type']) { + if (!$event->isFor('content')) { return; } diff --git a/vendor-extra/LiberoContentBundle/src/EventListener/TitleListener.php b/vendor-extra/LiberoContentBundle/src/EventListener/TitleListener.php index adcbc04..96c4285 100644 --- a/vendor-extra/LiberoContentBundle/src/EventListener/TitleListener.php +++ b/vendor-extra/LiberoContentBundle/src/EventListener/TitleListener.php @@ -14,7 +14,7 @@ final class TitleListener public function onCreatePage(CreatePageEvent $event) : void { - if ('content' !== $event->getRequest()->attributes->get('libero_page')['type']) { + if (!$event->isFor('content')) { return; } diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentHeaderListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentHeaderListener.php index 80272d9..e10a046 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentHeaderListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentHeaderListener.php @@ -5,13 +5,13 @@ namespace Libero\LiberoPageBundle\EventListener; use Libero\LiberoPageBundle\Event\CreatePagePartEvent; -use Libero\ViewsBundle\Views\TranslatingVisitor; +use Libero\ViewsBundle\Views\ContextAwareTranslation; use Libero\ViewsBundle\Views\View; use Symfony\Contracts\Translation\TranslatorInterface; final class HomepageContentHeaderListener { - use TranslatingVisitor; + use ContextAwareTranslation; public function __construct(TranslatorInterface $translator) { diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/TitleListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/TitleListener.php index 35dafda..bd9d5a3 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/TitleListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/TitleListener.php @@ -5,13 +5,13 @@ namespace Libero\LiberoPageBundle\EventListener; use Libero\LiberoPageBundle\Event\CreatePageEvent; -use Libero\ViewsBundle\Views\TranslatingVisitor; +use Libero\ViewsBundle\Views\ContextAwareTranslation; use Symfony\Contracts\Translation\TranslatorInterface; use function is_string; final class TitleListener { - use TranslatingVisitor; + use ContextAwareTranslation; public function __construct(TranslatorInterface $translator) { diff --git a/vendor-extra/ViewsBundle/tests/Views/EventDispatchingViewConverterTest.php b/vendor-extra/ViewsBundle/tests/Views/EventDispatchingViewConverterTest.php index 4f08db6..f77ea24 100644 --- a/vendor-extra/ViewsBundle/tests/Views/EventDispatchingViewConverterTest.php +++ b/vendor-extra/ViewsBundle/tests/Views/EventDispatchingViewConverterTest.php @@ -13,7 +13,7 @@ use LogicException; use PHPUnit\Framework\TestCase; use Symfony\Component\EventDispatcher\EventDispatcher; -use tests\Libero\ContentPageBundle\XmlTestCase; +use tests\Libero\LiberoPageBundle\XmlTestCase; final class EventDispatchingViewConverterTest extends TestCase { From 737ff95cc09012a64cc86a65ef562bf435373158 Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Fri, 29 Mar 2019 08:02:50 +0000 Subject: [PATCH 11/46] Return type --- .../LiberoPageBundle/src/EventListener/LiberoPageListener.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/LiberoPageListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/LiberoPageListener.php index e5f26a5..afc15e5 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/LiberoPageListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/LiberoPageListener.php @@ -18,7 +18,7 @@ public function __construct(array $routes) $this->routes = $routes; } - public function onKernelRequest(GetResponseEvent $event) + public function onKernelRequest(GetResponseEvent $event) : void { $request = $event->getRequest(); $route = $request->attributes->get('_route'); From 9880898bdb27786ef7f91b020ce1c196996c8a4e Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Fri, 29 Mar 2019 09:23:55 +0000 Subject: [PATCH 12/46] Tweak configuration --- .gitignore | 2 +- README.md | 25 ++++++---- config/packages/dev/libero_page.yaml | 16 +++---- config/packages/test/libero_page.yaml | 16 +++---- phpstan.neon.dist | 2 +- .../LiberoPageConfiguration.php | 46 ++++++++++++------- .../LiberoPageExtension.php | 24 +++++++--- .../src/EventListener/LiberoPageListener.php | 2 +- 8 files changed, 81 insertions(+), 52 deletions(-) diff --git a/.gitignore b/.gitignore index a97439d..46bd339 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -/config/packages/content_page.yaml +/config/packages/libero_page.yaml ###> phpunit/phpunit ### /phpunit.xml diff --git a/README.md b/README.md index 6ea763c..3d6283c 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,13 @@ Serve content read from a Libero API to the public. Getting started --------------- +To run Browser in the `dev` environment: + 1. Run `docker-compose down --volumes --remove-orphans && docker-compose up --build`. -2. Open http://localhost:8080/articles/article1 to see the scholarly article `article1` in the `dev` environment. +2. Open http://localhost:8080/ to see the homepage. + +3. Open http://localhost:8080/articles/article1 to see the scholarly article `article1`. ### Configuration @@ -25,17 +29,20 @@ To run an image reading from two content services (`blog-articles` and `scholarl - Set the `API_URI` environment variable to be the root of the Libero API. -- Create `config/packages/content_page.yaml` (either by extending the image or mounting a file): +- Create `config/packages/libero_page.yaml` (either by extending the image or mounting a file): ```yaml - content_page: + libero_page: pages: - blog_article: - path: '/blog/{id}' - service: 'blog-articles' - scholarly_article: - path: '/articles/{id}' - service: 'scholarly-articles' + homepage: + path: '/' + content: + blog_article: + path: '/blog/{id}' + content_service: 'blog-articles' + scholarly_article: + path: '/articles/{id}' + content_service: 'scholarly-articles' ``` Getting help diff --git a/config/packages/dev/libero_page.yaml b/config/packages/dev/libero_page.yaml index d2109ca..9f5a218 100644 --- a/config/packages/dev/libero_page.yaml +++ b/config/packages/dev/libero_page.yaml @@ -1,13 +1,11 @@ libero_page: pages: homepage: - type: homepage path: '/' - blog_article: - type: content - path: '/blog/{id}' - content_service: 'blog-articles' - scholarly_article: - type: content - path: '/articles/{id}' - content_service: 'scholarly-articles' + content: + blog_article: + path: '/blog/{id}' + content_service: 'blog-articles' + scholarly_article: + path: '/articles/{id}' + content_service: 'scholarly-articles' diff --git a/config/packages/test/libero_page.yaml b/config/packages/test/libero_page.yaml index d2109ca..9f5a218 100644 --- a/config/packages/test/libero_page.yaml +++ b/config/packages/test/libero_page.yaml @@ -1,13 +1,11 @@ libero_page: pages: homepage: - type: homepage path: '/' - blog_article: - type: content - path: '/blog/{id}' - content_service: 'blog-articles' - scholarly_article: - type: content - path: '/articles/{id}' - content_service: 'scholarly-articles' + content: + blog_article: + path: '/blog/{id}' + content_service: 'blog-articles' + scholarly_article: + path: '/articles/{id}' + content_service: 'scholarly-articles' diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 6286c9f..06897b2 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -2,7 +2,7 @@ parameters: ignoreErrors: - '~^Call to an undefined method FluentDOM\\DOM\\Node\\.+?::getNodePath\(\)\.$~' - '~^Cannot cast FluentDOM\\DOM\\Node\\.+? to string\.$~' - - '~^Cannot call method ([a-z]+)Node\(\) on Symfony\\Component\\Config\\Definition\\Builder\\NodeParentInterface\|null\.$~' + - '~^Cannot call method (end|([a-z]+)Node)\(\) on Symfony\\Component\\Config\\Definition\\Builder\\NodeParentInterface\|null\.$~' - '~^Service "csa_guzzle\.mock\.storage" is not registered in the container\.$~' level: max paths: diff --git a/vendor-extra/LiberoPageBundle/src/DependencyInjection/LiberoPageConfiguration.php b/vendor-extra/LiberoPageBundle/src/DependencyInjection/LiberoPageConfiguration.php index e869bc5..ea69e3b 100644 --- a/vendor-extra/LiberoPageBundle/src/DependencyInjection/LiberoPageConfiguration.php +++ b/vendor-extra/LiberoPageBundle/src/DependencyInjection/LiberoPageConfiguration.php @@ -42,31 +42,45 @@ private function getPagesDefinition() : ArrayNodeDefinition $builder = new TreeBuilder(); /** @var ArrayNodeDefinition $pagesNode */ $pagesNode = $builder->root('pages'); + $pagesNode + ->children() + ->append($this->getHomepageDefinition()) + ->append($this->getContentPagesDefinition()) + ->end() + ; + return $pagesNode; + } + + private function getHomepageDefinition() : ArrayNodeDefinition + { + $builder = new TreeBuilder(); + /** @var ArrayNodeDefinition $pagesNode */ + $pagesNode = $builder->root('homepage'); + $pagesNode + ->children() + ->scalarNode('path') + ->isRequired() + ->end() + ->end() + ; + return $pagesNode; + } + + private function getContentPagesDefinition() : ArrayNodeDefinition + { + $builder = new TreeBuilder(); + /** @var ArrayNodeDefinition $pagesNode */ + $pagesNode = $builder->root('content'); $pagesNode ->arrayPrototype() ->children() - ->enumNode('type') - ->values(['content', 'homepage']) - ->isRequired() - ->end() ->scalarNode('path') ->isRequired() ->end() ->scalarNode('content_service') + ->isRequired() ->end() ->end() - ->validate() - ->ifTrue(function (array $values) : bool { - return 'content' === $values['type'] && !isset($values['content_service']); - }) - ->thenInvalid('Content pages require a content_service') - ->end() - ->validate() - ->ifTrue(function (array $values) : bool { - return 'content' !== $values['type'] && isset($values['content_service']); - }) - ->thenInvalid('Non-content pages cannot have a content_service') - ->end() ->end() ; return $pagesNode; diff --git a/vendor-extra/LiberoPageBundle/src/DependencyInjection/LiberoPageExtension.php b/vendor-extra/LiberoPageBundle/src/DependencyInjection/LiberoPageExtension.php index d4affa2..422d590 100644 --- a/vendor-extra/LiberoPageBundle/src/DependencyInjection/LiberoPageExtension.php +++ b/vendor-extra/LiberoPageBundle/src/DependencyInjection/LiberoPageExtension.php @@ -27,17 +27,29 @@ public function load(array $configs, ContainerBuilder $container) : void $container->setAlias('libero.client', $config['client']); $container->setParameter('libero.page_template', $config['page_template']); - foreach (array_keys($config['pages']) as $name) { - $config['pages'][$name]['name'] = $name; - $config['pages'][$name]['controller'] = PageController::class; - $config['pages'][$name]['route'] = "libero.page.{$config['pages'][$name]['type']}.{$name}"; + $config['pages']['homepage'] = ['homepage' => $config['pages']['homepage']]; + + $pages = []; + foreach (array_keys($config['pages'] ?? []) as $type) { + foreach (array_keys($config['pages'][$type]) as $name) { + $page = $config['pages'][$type][$name]; + $page['name'] = $name; + $page['type'] = $type; + $page['controller'] = PageController::class; + if ($name === $type) { + $page['route'] = "libero.page.{$type}"; + } else { + $page['route'] = "libero.page.{$type}.{$name}"; + } + $pages[] = $page; + } } $container->findDefinition(PageRouteLoader::class) - ->setArgument(0, $config['pages']); + ->setArgument(0, $pages); $container->findDefinition(LiberoPageListener::class) - ->setArgument(0, array_column($config['pages'], null, 'route')); + ->setArgument(0, array_column($pages, null, 'route')); } public function getConfiguration(array $config, ContainerBuilder $container) : ConfigurationInterface diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/LiberoPageListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/LiberoPageListener.php index afc15e5..26074f8 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/LiberoPageListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/LiberoPageListener.php @@ -24,7 +24,7 @@ public function onKernelRequest(GetResponseEvent $event) : void $route = $request->attributes->get('_route'); if (!isset($this->routes[$route])) { - $request->attributes->set('libero_page', ['type' => '']); + $request->attributes->set('libero_page', ['name' => 'unknown', 'type' => 'unknown']); return; } From 1bc13dc32ccf32480a15cdd97b73a35c15c043a5 Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Fri, 29 Mar 2019 10:29:25 +0000 Subject: [PATCH 13/46] Improve name --- .../LiberoPageBundle/src/Controller/PageController.php | 4 ++-- .../src/Event/{LoadPageEvent.php => LoadPageDataEvent.php} | 2 +- .../src/EventListener/ContentItemListener.php | 4 ++-- .../LiberoPageBundle/src/Resources/config/services.xml | 2 +- .../LiberoPageBundle/tests/Controller/PageControllerTest.php | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) rename vendor-extra/LiberoPageBundle/src/Event/{LoadPageEvent.php => LoadPageDataEvent.php} (94%) diff --git a/vendor-extra/LiberoPageBundle/src/Controller/PageController.php b/vendor-extra/LiberoPageBundle/src/Controller/PageController.php index 7ab7e2d..4735113 100644 --- a/vendor-extra/LiberoPageBundle/src/Controller/PageController.php +++ b/vendor-extra/LiberoPageBundle/src/Controller/PageController.php @@ -5,7 +5,7 @@ namespace Libero\LiberoPageBundle\Controller; use Libero\LiberoPageBundle\Event\CreatePageEvent; -use Libero\LiberoPageBundle\Event\LoadPageEvent; +use Libero\LiberoPageBundle\Event\LoadPageDataEvent; use Libero\LiberoPageBundle\Exception\NoContentSet; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpFoundation\Request; @@ -34,7 +34,7 @@ public function __invoke(Request $request) : Response 'dir' => text_direction($request->getLocale()), ]; - $loadEvent = new LoadPageEvent($request, $context); + $loadEvent = new LoadPageDataEvent($request, $context); $this->dispatcher->dispatch($loadEvent::NAME, $loadEvent); $createEvent = new CreatePageEvent($request, $loadEvent->getDocuments()->wait(), $loadEvent->getContext()); diff --git a/vendor-extra/LiberoPageBundle/src/Event/LoadPageEvent.php b/vendor-extra/LiberoPageBundle/src/Event/LoadPageDataEvent.php similarity index 94% rename from vendor-extra/LiberoPageBundle/src/Event/LoadPageEvent.php rename to vendor-extra/LiberoPageBundle/src/Event/LoadPageDataEvent.php index 75c6580..bf73824 100644 --- a/vendor-extra/LiberoPageBundle/src/Event/LoadPageEvent.php +++ b/vendor-extra/LiberoPageBundle/src/Event/LoadPageDataEvent.php @@ -9,7 +9,7 @@ use Symfony\Component\HttpFoundation\Request; use function GuzzleHttp\Promise\all; -final class LoadPageEvent extends Event +final class LoadPageDataEvent extends Event { use PageEvent; diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/ContentItemListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/ContentItemListener.php index d084fac..3ac2465 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/ContentItemListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/ContentItemListener.php @@ -7,7 +7,7 @@ use FluentDOM; use FluentDOM\DOM\Document; use GuzzleHttp\ClientInterface; -use Libero\LiberoPageBundle\Event\LoadPageEvent; +use Libero\LiberoPageBundle\Event\LoadPageDataEvent; use Psr\Http\Message\ResponseInterface; final class ContentItemListener @@ -19,7 +19,7 @@ public function __construct(ClientInterface $client) $this->client = $client; } - public function onLoadPage(LoadPageEvent $event) : void + public function onLoadPageData(LoadPageDataEvent $event) : void { if (!$event->isFor('content')) { return; diff --git a/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml b/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml index 93c10cb..e902f6d 100644 --- a/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml +++ b/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml @@ -31,7 +31,7 @@ - + function (LoadPageEvent $event) : void { + LoadPageDataEvent::NAME => function (LoadPageDataEvent $event) : void { $document = $this->loadDocument('content'); $event->addDocument('foo', promise_for($document)); }, From f125fbb5688bd12dfe824ebaaaf4d034a4424b3a Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Fri, 29 Mar 2019 13:18:17 +0000 Subject: [PATCH 14/46] Changes --- .../data/scholarly-articles/article2/1.xml | 152 ++++++++++++++++++ config/packages/dev/libero_page.yaml | 1 + config/packages/test/libero_page.yaml | 1 + .../BuildView/ItemParagraphListener.php | 59 +++++++ .../src/Resources/config/services.xml | 6 + .../LiberoPageConfiguration.php | 3 + .../src/Event/CreatePageEvent.php | 7 +- .../src/Event/CreatePagePartEvent.php | 25 +-- .../BuildView/ItemListListener.php | 58 +++++++ .../BuildView/ItemRefParagraphListener.php | 68 ++++++++ .../HomepageContentListListener.php | 68 ++++++++ .../src/Resources/config/services.xml | 21 +++ .../Views/EventDispatchingViewConverter.php | 4 + vendor-extra/ViewsBundle/src/Views/View.php | 48 ++++++ 14 files changed, 510 insertions(+), 11 deletions(-) create mode 100644 .docker/api/data/scholarly-articles/article2/1.xml create mode 100644 vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemParagraphListener.php create mode 100644 vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php create mode 100644 vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefParagraphListener.php create mode 100644 vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php diff --git a/.docker/api/data/scholarly-articles/article2/1.xml b/.docker/api/data/scholarly-articles/article2/1.xml new file mode 100644 index 0000000..ed35a8a --- /dev/null +++ b/.docker/api/data/scholarly-articles/article2/1.xml @@ -0,0 +1,152 @@ + + + + + + + article2 + + + + + + + + + + + + + Article 2 y'all + + + + + + + Evolutionary Biology + + + + + XML + Housestyle + eLife + formatting + + + + Research organism + Human + Machine + + + + + + + + + + + Introduction + + Fossil hominins were first recognized in the Dinaledi Chamber in the Rising Star cave system in + October 2013. During a relatively short excavation, our team recovered an extensive collection of + 1550 hominin specimens, representing nearly every element of the skeleton multiple times (Figure + 1), including many complete elements and morphologically informative fragments, some in + articulation, as well as smaller fragments many of which could be refit into more complete + elements. The collection is a morphologically homogeneous sample that can be attributed to no + previously-known hominin species. Here we describe this new species, Homo + naledi. We have not defined H. naledi narrowly based on a + single jaw or skull because the entire body of material has informed our understanding of its + biology. + + + Order Primates LINNAEUS 1758 + + Suborder Anthropoidea MIVART 1864 + + Superfamily Hominoidea GRAY 1825 + + Family Hominidae GRAY 1825 + + Tribe Hominini GRAY 1825 + + Genus Homo LINNAEUS 1758 + + Homo naledi sp. nov. + urn:lsid:zoobank.org:pub:00D1E81A-6E08-4A01-BD98-79A2CEAE2411 + + + + + Etymology + + The word naledi means ‘star’ in the Sotho language and refers to + the Dinaledi Chamber's location within the Rising Star cave system. + + + + + + + Locality + + The Dinaledi chamber is located approximately 30 meters underground, within the Rising Star + cave system at about 26°1′13′′ S; 27°42′43′′ E. The system lies within the Malmani dolomites, + approximately 800 meters southwest of the well-known site of Swartkrans in the Cradle of + Humankind World Heritage Site, Gauteng Province, South Africa. + + + + + + + Horizon and associations + + The present sample of skeletal material from the Dinaledi Chamber was recovered during two + field expeditions, in November 2013 and March 2014. + + + Six specimens from an ex situ context can be identified as bird bones, and few fragmentary + rodent remains have been recovered within the excavation area. Neither of these faunal + constituents can presently be associated with the hominin fossil collection (Dirks et al., + 2015). + + + Aside from these limited faunal materials, the Dinaledi collection is entirely composed of + hominin skeletal and dental remains. The collection so far comprises 1550 fossil hominin + specimens, this number includes 1413 bone specimens and 137 isolated dental specimens; an + additional 53 teeth are present in mandibular or maxillary bone specimens. Aside from the + fragmentary rodent teeth, all dental crowns (n = 179) are hominin, recovered both from surface + collection and excavation. Likewise, aside from the few bird elements, all morphologically + informative bone specimens are clearly hominin. In all cases where elements are repeated in the + sample, they are morphologically homogeneous, with variation consistent with body size and sex + differences within a single population. These remains represent a minimum of 15 hominin + individuals, as indicated by the repetition and presence of deciduous and adult dental + elements. + + + The geological age of the fossils is not yet known. Excavations have thus far recovered + hominin material from Unit 2 and Unit 3 in the chamber (Dirks et al., 2015). Surface-collected + hominin material from the present top of Unit 3, which includes material derived from both Unit + 2 and Unit 3, represents a minority of the assemblage, and is morphologically indistinguishable + from material excavated from in situ within Unit 3. In addition to general morphological + homogeneity including cranial shape, distinctive morphological configurations of all the + recovered first metacarpals, femora, molars, lower premolars and lower canines, are identical + in both surface-collected and excavated specimens (see Figure 14 later in the text). These + include traits not found in any other hominin species yet described. These considerations + strongly indicate that this material represents a single species, and not a commingled + assemblage. + + + + + + + + + + + diff --git a/config/packages/dev/libero_page.yaml b/config/packages/dev/libero_page.yaml index 9f5a218..98a9cb6 100644 --- a/config/packages/dev/libero_page.yaml +++ b/config/packages/dev/libero_page.yaml @@ -2,6 +2,7 @@ libero_page: pages: homepage: path: '/' + search_service: 'scholarly-articles' content: blog_article: path: '/blog/{id}' diff --git a/config/packages/test/libero_page.yaml b/config/packages/test/libero_page.yaml index 9f5a218..98a9cb6 100644 --- a/config/packages/test/libero_page.yaml +++ b/config/packages/test/libero_page.yaml @@ -2,6 +2,7 @@ libero_page: pages: homepage: path: '/' + search_service: 'scholarly-articles' content: blog_article: path: '/blog/{id}' diff --git a/vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemParagraphListener.php b/vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemParagraphListener.php new file mode 100644 index 0000000..9cdb0ef --- /dev/null +++ b/vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemParagraphListener.php @@ -0,0 +1,59 @@ +converter = $converter; + } + + protected function handle(Element $object, View $view) : View + { + $title = $object->ownerDocument->xpath() + ->firstOf( + '/libero:item/jats:article/jats:front/jats:article-meta/jats:title-group/jats:article-title', + $object + ); + + if (!$title instanceof Element) { + return $view; + } + + return $view->withArguments( + $this->converter->convert( + $title, + '@LiberoPatterns/heading.html.twig', + $view->getContext() + )->getArguments() + ); + } + + protected function canHandleTemplate(?string $template) : bool + { + return '@LiberoPatterns/paragraph.html.twig' === $template; + } + + protected function canHandleElement(string $element) : bool + { + return '{http://libero.pub}item' === $element; + } + + protected function canHandleArguments(array $arguments) : bool + { + return !array_has_key($arguments, 'text'); + } +} diff --git a/vendor-extra/JatsContentBundle/src/Resources/config/services.xml b/vendor-extra/JatsContentBundle/src/Resources/config/services.xml index f0adfef..1706405 100644 --- a/vendor-extra/JatsContentBundle/src/Resources/config/services.xml +++ b/vendor-extra/JatsContentBundle/src/Resources/config/services.xml @@ -100,6 +100,12 @@ + + + + + diff --git a/vendor-extra/LiberoPageBundle/src/DependencyInjection/LiberoPageConfiguration.php b/vendor-extra/LiberoPageBundle/src/DependencyInjection/LiberoPageConfiguration.php index ea69e3b..cd6c2de 100644 --- a/vendor-extra/LiberoPageBundle/src/DependencyInjection/LiberoPageConfiguration.php +++ b/vendor-extra/LiberoPageBundle/src/DependencyInjection/LiberoPageConfiguration.php @@ -61,6 +61,9 @@ private function getHomepageDefinition() : ArrayNodeDefinition ->scalarNode('path') ->isRequired() ->end() + ->scalarNode('search_service') + ->isRequired() + ->end() ->end() ; return $pagesNode; diff --git a/vendor-extra/LiberoPageBundle/src/Event/CreatePageEvent.php b/vendor-extra/LiberoPageBundle/src/Event/CreatePageEvent.php index 05a2a45..99a6267 100644 --- a/vendor-extra/LiberoPageBundle/src/Event/CreatePageEvent.php +++ b/vendor-extra/LiberoPageBundle/src/Event/CreatePageEvent.php @@ -9,6 +9,8 @@ use Libero\ViewsBundle\Views\View; use Symfony\Component\EventDispatcher\Event; use Symfony\Component\HttpFoundation\Request; +use function array_keys; +use function implode; final class CreatePageEvent extends Event { @@ -43,7 +45,10 @@ public function setContent(string $area, View $view) : void public function getDocument(string $key) : Document { if (!isset($this->documents[$key])) { - throw new InvalidArgumentException("Unknown document '{$key}'"); + throw new InvalidArgumentException("Unknown document '{$key}'; known keys are: '".implode( + "', '", + array_keys($this->documents) + )."'"); } return $this->documents[$key]; diff --git a/vendor-extra/LiberoPageBundle/src/Event/CreatePagePartEvent.php b/vendor-extra/LiberoPageBundle/src/Event/CreatePagePartEvent.php index 9fb272a..c271235 100644 --- a/vendor-extra/LiberoPageBundle/src/Event/CreatePagePartEvent.php +++ b/vendor-extra/LiberoPageBundle/src/Event/CreatePagePartEvent.php @@ -9,6 +9,7 @@ use Libero\ViewsBundle\Views\View; use Symfony\Component\EventDispatcher\Event; use Symfony\Component\HttpFoundation\Request; +use function array_merge; use function end; use function is_array; use function is_string; @@ -40,30 +41,34 @@ public function __construct(string $template, Request $request, array $documents public function getContent() : array { - return $this->content; - } + $content = []; - public function addContent(View ...$views) : void - { - foreach ($views as $view) { + foreach ($this->content as $view) { $area = $view->getContext('area'); if (!is_string($area)) { - $this->content[] = $view; + $content[] = $view; continue; } - $last = end($this->content); + $last = end($content); if (is_array($last) && $area === $last['area']) { - $key = key($this->content); - $this->content[$key]['content'][] = $view; + $key = key($content); + $content[$key]['content'][] = $view; continue; } - $this->content[] = ['area' => $area, 'content' => [$view]]; + $content[] = ['area' => $area, 'content' => [$view]]; } + + return $content; + } + + public function addContent(View ...$views) : void + { + $this->content = array_merge($this->content, $views); } public function getDocument(string $key) : Document diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php new file mode 100644 index 0000000..cd1bbe0 --- /dev/null +++ b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php @@ -0,0 +1,58 @@ +converter = $converter; + } + + protected function handle(Element $object, View $view) : View + { + return $view->withArgument( + 'nodes', + array_map( + function (NonDocumentTypeChildNode $child) use ($view) : View { + return $this->converter->convert( + $child, + '@LiberoPatterns/paragraph.html.twig', + $view->getContext() + ); + }, + iterator_to_array($object->getElementsByTagNameNS('http://libero.pub', 'item-ref')) + ) + ); + } + + protected function canHandleTemplate(string $template) : bool + { + return '@LiberoPatterns/text.html.twig' === $template; + } + + protected function canHandleElement(string $element) : bool + { + return '{http://libero.pub}item-list' === $element; + } + + protected function canHandleArguments(array $arguments) : bool + { + return !array_has_key($arguments, 'nodes'); + } +} diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefParagraphListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefParagraphListener.php new file mode 100644 index 0000000..89bbc38 --- /dev/null +++ b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefParagraphListener.php @@ -0,0 +1,68 @@ +client = $client; + $this->converter = $converter; + } + + public function onBuildView(BuildViewEvent $event) : void + { + $object = $event->getObject(); + $view = $event->getView(); + + if (!$this->canHandleTemplate($view->getTemplate())) { + return; + } + + if (!$this->canHandleElement(sprintf('{%s}%s', $object->namespaceURI, $object->localName))) { + return; + } + + $new = $this->client + ->requestAsync( + 'GET', + "{$object->getAttribute('service')}/items/{$object->getAttribute('id')}/versions/latest" + ) + ->then( + function (ResponseInterface $response) use ($object, $view) : View { + $item = FluentDOM::load((string) $response->getBody()); + $item->namespaces($object->ownerDocument->namespaces()); + + return $this->converter->convert($item->documentElement, $view->getTemplate(), $view->getContext()); + } + ); + + $view = View::lazy([$new, 'wait']); + + $event->setView($view); + $event->stopPropagation(); + } + + protected function canHandleTemplate(string $template) : bool + { + return '@LiberoPatterns/paragraph.html.twig' === $template; + } + + protected function canHandleElement(string $element) : bool + { + return '{http://libero.pub}item-ref' === $element; + } +} diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php new file mode 100644 index 0000000..1aed177 --- /dev/null +++ b/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php @@ -0,0 +1,68 @@ +client = $client; + $this->converter = $converter; + } + + public function onLoadPageData(LoadPageDataEvent $event) : void + { + if (!$event->isFor('homepage')) { + return; + } + + $page = $event->getRequest()->attributes->get('libero_page'); + + $list = $this->client + ->requestAsync( + 'GET', + "{$page['search_service']}/items", + [ + 'headers' => ['Accept' => 'application/xml'], + 'http_errors' => true, + ] + ) + ->then( + function (ResponseInterface $response) : Document { + return $this->responseToDocument($response); + } + ); + + $event->addDocument('content_list', $list); + } + + public function onCreatePagePart(CreatePagePartEvent $event) : void + { + if ('homepage' !== $event->getRequest()->attributes->get('libero_page')['type']) { + return; + } + + $list = $event->getDocument('content_list'); + $event->addContent( + $this->converter->convert($list->documentElement, '@LiberoPatterns/text.html.twig', $event->getContext()) + ); + } + + public function responseToDocument(ResponseInterface $response) : Document + { + return FluentDOM::load((string) $response->getBody()); + } +} diff --git a/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml b/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml index e902f6d..ee699fe 100644 --- a/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml +++ b/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml @@ -22,6 +22,14 @@ + + + + + + + @@ -34,6 +42,19 @@ + + + + + + + + + + + libero diff --git a/vendor-extra/ViewsBundle/src/Views/EventDispatchingViewConverter.php b/vendor-extra/ViewsBundle/src/Views/EventDispatchingViewConverter.php index 4879035..293c93f 100644 --- a/vendor-extra/ViewsBundle/src/Views/EventDispatchingViewConverter.php +++ b/vendor-extra/ViewsBundle/src/Views/EventDispatchingViewConverter.php @@ -38,6 +38,10 @@ public function convert(NonDocumentTypeChildNode $node, ?string $template = null $view = $event->getView(); + if ($event->isPropagationStopped()) { + return $view; + } + if (!$view->getTemplate()) { return new View('@LiberoPatterns/text.html.twig', ['nodes' => (string) $node], $context); } diff --git a/vendor-extra/ViewsBundle/src/Views/View.php b/vendor-extra/ViewsBundle/src/Views/View.php index 231c6fa..f358934 100644 --- a/vendor-extra/ViewsBundle/src/Views/View.php +++ b/vendor-extra/ViewsBundle/src/Views/View.php @@ -9,11 +9,14 @@ use JsonSerializable; use Traversable; use function array_replace_recursive; +use function call_user_func; +use function is_callable; use function is_string; final class View implements JsonSerializable, IteratorAggregate { private $arguments; + private $callback; private $context; private $template; @@ -24,33 +27,53 @@ public function __construct(?string $template, array $arguments = [], array $con $this->context = $context; } + public static function lazy(callable $callback) : View + { + $view = new View(null); + $view->callback = $callback; + + return $view; + } + public function hasArgument(string $key) : bool { + $this->initialize(); + return isset($this->arguments[$key]); } public function getArgument(string $key) { + $this->initialize(); + return $this->arguments[$key] ?? null; } public function getArguments() : array { + $this->initialize(); + return $this->arguments; } public function getTemplate() : ?string { + $this->initialize(); + return $this->template; } public function hasContext(string $key) : bool { + $this->initialize(); + return isset($this->context[$key]); } public function getContext(?string $key = null) { + $this->initialize(); + if (is_string($key)) { return $this->context[$key] ?? null; } @@ -60,11 +83,15 @@ public function getContext(?string $key = null) public function withArgument(string $key, $value) : View { + $this->initialize(); + return $this->withArguments([$key => $value]); } public function withArguments(array $arguments) : View { + $this->initialize(); + if ($arguments === $this->arguments || !$arguments) { return $this; } @@ -78,6 +105,8 @@ public function withArguments(array $arguments) : View public function withTemplate(string $template) : View { + $this->initialize(); + if ($template === $this->template) { return $this; } @@ -91,6 +120,8 @@ public function withTemplate(string $template) : View public function withContext(array $context) : View { + $this->initialize(); + $view = clone $this; $view->context = array_replace_recursive($view->context, $context); @@ -100,6 +131,8 @@ public function withContext(array $context) : View public function jsonSerialize() : array { + $this->initialize(); + return [ 'template' => $this->template, 'arguments' => $this->arguments, @@ -110,4 +143,19 @@ public function getIterator() : Traversable { return new ArrayIterator($this->jsonSerialize()); } + + private function initialize() : void + { + if (!is_callable($this->callback)) { + return; + } + + $view = call_user_func($this->callback); + + $this->template = $view->template; + $this->arguments = $view->arguments; + $this->context = $view->context; + + $this->callback = null; + } } From e6587092a13291db6a20269ced5f10f975d879dd Mon Sep 17 00:00:00 2001 From: nlisgo Date: Tue, 2 Apr 2019 16:11:15 +0100 Subject: [PATCH 15/46] Introduce pattern library teaser templates --- .../src/Resources/public/css/all.css | 3 -- .../src/Resources/public/css/all.css.map | 1 - .../src/Resources/views/heading.html.twig | 18 ++++++- .../src/Resources/views/teaser-list.html.twig | 54 +++++++++++++++++++ .../src/Resources/views/teaser.html.twig | 27 ++++++++++ 5 files changed, 98 insertions(+), 5 deletions(-) delete mode 100644 vendor-extra/LiberoPatternsBundle/src/Resources/public/css/all.css delete mode 100644 vendor-extra/LiberoPatternsBundle/src/Resources/public/css/all.css.map create mode 100644 vendor-extra/LiberoPatternsBundle/src/Resources/views/teaser-list.html.twig create mode 100644 vendor-extra/LiberoPatternsBundle/src/Resources/views/teaser.html.twig diff --git a/vendor-extra/LiberoPatternsBundle/src/Resources/public/css/all.css b/vendor-extra/LiberoPatternsBundle/src/Resources/public/css/all.css deleted file mode 100644 index 55a339c..0000000 --- a/vendor-extra/LiberoPatternsBundle/src/Resources/public/css/all.css +++ /dev/null @@ -1,3 +0,0 @@ -@font-face{font-display:fallback;font-family:"Noto Sans";src:url("../fonts/NotoSans-Regular-webfont-custom-2-subsetting.woff2") format("woff2")}@font-face{font-display:fallback;font-family:"Noto Sans";src:url("../fonts/NotoSans-SemiBold-webfont-custom-2-subsetting.woff2") format("woff2");font-weight:600}@font-face{font-display:fallback;font-family:"Noto Serif";src:url("../fonts/NotoSerif-Regular-webfont-custom-2-subsetting.woff2") format("woff2")}@font-face{font-display:fallback;font-family:"Noto Serif";src:url("../fonts/NotoSerif-Bold-webfont-basic-latin-subsetting.woff2") format("woff2");font-weight:bold}/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:0.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace, monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace, monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}button,[type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:0.35em 0.75em 0.625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}*,*:before,*:after{box-sizing:border-box}html,body{height:100%;block-size:100%}body{background-color:#fff;color:#212121;text-rendering:optimizeLegibility;font-family:"Noto Serif",serif;font-size:16px;font-size:1rem;line-height:1.5;font-weight:normal}h1{font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:600;font-size:36px;font-size:2.25rem;line-height:1.33333;margin:0}h2{font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:600;font-size:26px;font-size:1.625rem;line-height:1.15385;margin:0;padding-bottom:21px;padding-bottom:1.3125rem;padding-block-end:1.3125rem;padding-top:21px;padding-top:1.3125rem;padding-block-start:1.3125rem}h3{font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:600;font-size:22px;font-size:1.375rem;line-height:1.09091;margin:0;padding-top:12px;padding-top:.75rem;padding-block-start:.75rem;padding-bottom:12px;padding-bottom:.75rem;padding-block-end:.75rem}h4{font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:600;font-size:20px;font-size:1.25rem;line-height:1.2;margin:0;padding-top:12px;padding-top:.75rem;padding-block-start:.75rem;padding-bottom:12px;padding-bottom:.75rem;padding-block-end:.75rem}h5{font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:600;font-size:18px;font-size:1.125rem;line-height:1.33333;margin:0;padding-top:12px;padding-top:.75rem;padding-block-start:.75rem;padding-bottom:12px;padding-bottom:.75rem;padding-block-end:.75rem}h6{font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:600;font-size:16px;font-size:1rem;line-height:1.5;margin:0;padding-top:10px;padding-top:.625rem;padding-block-start:.625rem;padding-bottom:14px;padding-bottom:.875rem;padding-block-end:.875rem}p{font-family:"Noto Serif",serif;font-size:16px;font-size:1rem;line-height:1.5;font-weight:normal;margin:0;margin-bottom:24px;margin-bottom:1.5rem;margin-block-end:1.5rem}a{color:#0288d1;text-decoration:none}ul,ol{margin-bottom:24px;margin-bottom:1.5rem;margin-block-end:1.5rem;margin-top:0;margin-block-start:0}dl{margin-bottom:24px;margin-bottom:1.5rem;margin-block-end:1.5rem;margin-top:0;margin-block-start:0}li,dt,dd{font-family:"Noto Serif",serif;font-size:16px;font-size:1rem;line-height:1.5;font-weight:normal}dt{font-weight:bold}dd+dt{margin-top:24px;margin-top:1.5rem;margin-block-start:1.5rem}html[dir="ltr"] dd:not([dir]),dd[dir="ltr"]{margin-left:0}html[dir="rtl"] dd:not([dir]),dd[dir="rtl"]{margin-right:0}html[dir][dir] dd{margin-inline-start:0}small{font-family:"Noto Serif",serif;font-style:normal;font-size:11px;font-size:.6875rem;line-height:2.18182;padding-bottom:24px;padding-bottom:1.5rem;padding-block-end:1.5rem}sub{font-size:75%;line-height:0;position:relative;vertical-align:baseline;bottom:-0.25em}@supports (font-variant-position: sub){sub{font-size:inherit;font-variant-position:sub;position:static}}sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;top:-0.5em}@supports (font-variant-position: super){sup{font-size:inherit;font-variant-position:super;position:static}}address{font-family:"Noto Serif",serif;font-style:normal;font-size:11px;font-size:.6875rem;line-height:2.18182;padding-bottom:24px;padding-bottom:1.5rem;padding-block-end:1.5rem}img{max-height:100%;max-block-size:100%;max-width:100%;max-inline-size:100%}h1 img,h2 img,h3 img,h4 img,h5 img,h6 img,p img{margin-bottom:.1em;margin-block-end:.1em;max-height:1em;max-block-size:1em;vertical-align:middle}em:lang(ja){font-style:normal;text-emphasis-style:open sesame;text‑emphasis‑position:over right}strong:lang(ja){font-style:normal;text-emphasis-style:filled sesame;text‑emphasis‑position:over right}u:lang(ja){text-underline-position:right}em:lang(ko){font-style:normal;text-decoration:underline;text-underline-position:under right}strong:lang(ko){font-style:normal;text-emphasis-style:filled dot;text‑emphasis‑position:over right}em:lang(zh){font-style:normal;text-emphasis-style:open dot;text‑emphasis‑position:under right}strong:lang(zh){font-style:normal;text-emphasis-style:filled dot;text‑emphasis‑position:under right}cite:lang(zh){font-style:normal;text-decoration:underline;text-underline-style:wavy}em:lang(zh-Hant){text‑emphasis‑position:over right}strong:lang(zh-Hant){text‑emphasis‑position:over right}:root{--GRID-COLUMN-GAP: 1.6%;--GRID-EDGE-SPACE: 7vw;--GRID-COLUMN-WIDTH: calc((100% - (var(--GRID-EDGE-SPACE) * 2) - (var(--GRID-COLUMN-GAP) * 11)) / 12);min-width:320px;min-inline-size:320px}@media (min-width: 45.625em){:root{--GRID-EDGE-SPACE: 14vw}}@media (min-width: 75em){:root{--GRID-COLUMN-GAP: 17.824px;--GRID-COLUMN-WIDTH: calc((1114px - (var(--GRID-COLUMN-GAP) * 11)) / 12)}}.content-meta{overflow:auto;margin:0;margin-bottom:24px;margin-bottom:1.5rem;margin-block-end:1.5rem}html[dir="ltr"] .content-meta:not([dir]),.content-meta[dir="ltr"]{padding-left:0}html[dir="rtl"] .content-meta:not([dir]),.content-meta[dir="rtl"]{padding-right:0}html[dir][dir] .content-meta{padding-inline-start:0}.content-meta__item{display:inline-block;color:#888;font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:normal;font-size:11px;font-size:.6875rem;line-height:2.18182;letter-spacing:.5px;text-transform:uppercase}.content-meta__item:after{content:"\a0\2022\a0"}.content-meta__item:last-child:after{content:""}.content-meta__link{color:inherit;text-decoration:inherit;all:inherit;cursor:pointer}.content-meta__link:hover{color:#0277bd}.section__body{margin:0;margin-bottom:24px;margin-bottom:1.5rem;margin-block-end:1.5rem}.tag-list{margin-bottom:24px;margin-bottom:1.5rem;margin-block-end:1.5rem}.tag-list__title{color:#888;font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:normal;font-size:11px;font-size:.6875rem;line-height:2.18182;letter-spacing:.5px;text-transform:uppercase;padding-top:0;padding-bottom:0;padding-block:0}.tag-list__list{overflow:auto;margin-bottom:24px;margin-bottom:1.5rem;margin-block-end:1.5rem}html[dir="ltr"] .tag-list__list:not([dir]),.tag-list__list[dir="ltr"]{padding-left:0}html[dir="rtl"] .tag-list__list:not([dir]),.tag-list__list[dir="rtl"]{padding-right:0}html[dir][dir] .tag-list__list{padding-inline-start:0}.tag-list__list--single-line{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tag-list__list--single-line:lang(zh-Hant-HK){text-overflow:"⋯"}.tag-list__item{display:inline-block;color:#0288d1;font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:normal;font-size:11px;font-size:.6875rem;line-height:2.18182;letter-spacing:.5px;text-transform:uppercase}.tag-list__item:after{display:inline;content:",\a0"}.tag-list__item:lang(ar):after{content:"،\a0"}.tag-list__item:lang(ja):after{content:"、"}.tag-list__item:last-child:after{content:""}.tag-list__link{color:inherit;text-decoration:inherit;all:inherit;cursor:pointer}.tag-list__link:hover{color:#0277bd}.content-header{color:#212121;text-align:center;margin-top:48px;margin-top:3rem;margin-block-start:3rem;margin-bottom:24px;margin-bottom:1.5rem;margin-block-end:1.5rem;border-bottom:1px solid #e0e0e0;border-block-end:1px solid #e0e0e0}.content-header__title{margin-top:0;margin-block-start:0;margin-bottom:24px;margin-bottom:1.5rem;margin-block-end:1.5rem}.content-header__title:last-child{margin-bottom:48px;margin-bottom:3rem;margin-block-end:3rem}.content-header__title--xx-short{font-size:46px;font-size:2.875rem}@media (min-width: 30em){.content-header__title--xx-short{font-size:52px;font-size:3.25rem}}.content-header__title--x-short{font-size:41px;font-size:2.5625rem}@media (min-width: 45.625em){.content-header__title--x-short{font-size:46px;font-size:2.875rem}}@media (min-width: 56.25em){.content-header__title--x-short{font-size:52px;font-size:3.25rem}}.content-header__title--short{font-size:30px;font-size:1.875rem}@media (min-width: 30em){.content-header__title--short{font-size:36px;font-size:2.25rem}}@media (min-width: 45.625em){.content-header__title--short{font-size:41px;font-size:2.5625rem}}@media (min-width: 56.25em){.content-header__title--short{font-size:46px;font-size:2.875rem}}@media (min-width: 75em){.content-header__title--short{font-size:52px;font-size:3.25rem}}.content-header__title--medium{font-size:26px;font-size:1.625rem}@media (min-width: 30em){.content-header__title--medium{font-size:30px;font-size:1.875rem}}@media (min-width: 45.625em){.content-header__title--medium{font-size:36px;font-size:2.25rem}}@media (min-width: 56.25em){.content-header__title--medium{font-size:41px;font-size:2.5625rem}}@media (min-width: 75em){.content-header__title--medium{font-size:52px;font-size:3.25rem}}.content-header__title--long{font-size:20px;font-size:1.25rem}@media (min-width: 30em){.content-header__title--long{font-size:26px;font-size:1.625rem}}@media (min-width: 45.625em){.content-header__title--long{font-size:36px;font-size:2.25rem}}@media (min-width: 75em){.content-header__title--long{font-size:41px;font-size:2.5625rem}}.content-header__title--x-long{font-size:20px;font-size:1.25rem}@media (min-width: 45.625em){.content-header__title--x-long{font-size:26px;font-size:1.625rem}}@media (min-width: 56.25em){.content-header__title--x-long{font-size:26px;font-size:1.625rem}}@media (min-width: 75em){.content-header__title--x-long{font-size:30px;font-size:1.875rem}}.content-header__title--xx-long{font-size:18px;font-size:1.125rem}@media (min-width: 30em){.content-header__title--xx-long{font-size:20px;font-size:1.25rem}}@media (min-width: 56.25em){.content-header__title--xx-long{font-size:26px;font-size:1.625rem}}.item-tags{padding-top:48px;padding-top:3rem;padding-block-start:3rem;text-align:center}@media (min-width: 45.625em){.item-tags{text-align:initial}}.content-grid{--primary-column-width: calc((12 * var(--GRID-COLUMN-WIDTH)) + (11 * var(--GRID-COLUMN-GAP)));max-width:1114px;max-width:69.625rem;max-inline-size:69.625rem;margin-left:auto;margin-right:auto;margin-inline:auto;padding-left:1.6%;padding-right:1.6%;padding-inline:1.6%;box-sizing:content-box;grid-template-areas:". menu ." ". primary .";grid-template-columns:[full-start] 1fr [main-start] var(--primary-column-width) [main-end] 1fr [full-end];grid-column-gap:var(--GRID-COLUMN-GAP)}@supports (display: grid) and (--custom: property){.content-grid{display:grid;max-width:unset;max-inline-size:unset;margin-left:unset;margin-right:unset;margin-inline:unset;padding-left:unset;padding-right:unset;padding-inline:unset;box-sizing:border-box}}@media (min-width: 56.25em){.content-grid{--primary-column-width: calc((10 * var(--GRID-COLUMN-WIDTH)) + (9 * var(--GRID-COLUMN-GAP)));--secondary-column-width: calc((1 * var(--GRID-COLUMN-WIDTH)) + (0 * var(--GRID-COLUMN-GAP)));--menu-column-width: calc((1 * var(--GRID-COLUMN-WIDTH)) + (0 * var(--GRID-COLUMN-GAP)));grid-template-areas:". . menu . ." ". . primary . .";grid-template-columns:[full-start] 1fr [main-start] var(--menu-column-width) var(--primary-column-width) var(--secondary-column-width) [main-end] 1fr [full-end]}}@media (min-width: 75em){.content-grid{--primary-column-width: calc((8 * var(--GRID-COLUMN-WIDTH)) + (7 * var(--GRID-COLUMN-GAP)));--secondary-column-width: calc((2 * var(--GRID-COLUMN-WIDTH)) + (1 * var(--GRID-COLUMN-GAP)));--menu-column-width: calc((2 * var(--GRID-COLUMN-WIDTH)) + (1 * var(--GRID-COLUMN-GAP)));grid-template-areas:". menu primary . ."}}.content-grid--has-secondary{grid-template-areas:". menu ." ". primary ." ". secondary ."}@media (min-width: 56.25em){.content-grid--has-secondary{--primary-column-width: calc((8 * var(--GRID-COLUMN-WIDTH)) + (7 * var(--GRID-COLUMN-GAP)));--secondary-column-width: calc((4 * var(--GRID-COLUMN-WIDTH)) + (3 * var(--GRID-COLUMN-GAP)));grid-template-areas:". menu menu ." ". primary secondary .";grid-template-columns:[full-start] 1fr [main-start] var(--primary-column-width) var(--secondary-column-width) [main-end] 1fr [full-end]}}@media (min-width: 75em){.content-grid--has-secondary{--primary-column-width: calc((7 * var(--GRID-COLUMN-WIDTH)) + (6 * var(--GRID-COLUMN-GAP)));--secondary-column-width: calc((3 * var(--GRID-COLUMN-WIDTH)) + (2 * var(--GRID-COLUMN-GAP)));--menu-column-width: calc((2 * var(--GRID-COLUMN-WIDTH)) + (1 * var(--GRID-COLUMN-GAP)));grid-template-areas:". menu primary secondary .";grid-template-columns:[full-start] 1fr [main-start] var(--menu-column-width) var(--primary-column-width) var(--secondary-column-width) [main-end] 1fr [full-end]}}.content-grid__item,.content-grid__item--main{grid-column:main}.content-grid__item--full{grid-column:full}.content-grid__item--primary{grid-column:primary}.content-grid__item--secondary{grid-column:secondary}.content-grid__item--menu{grid-column:menu}.page-grid{max-width:1114px;max-width:69.625rem;max-inline-size:69.625rem;margin-left:auto;margin-right:auto;margin-inline:auto;padding-left:1.6%;padding-right:1.6%;padding-inline:1.6%;box-sizing:content-box;grid-template-areas:"start" "main" "end"}@supports (display: grid) and (--custom: property){.page-grid{display:grid;max-width:unset;max-inline-size:unset;margin-left:unset;margin-right:unset;margin-inline:unset;padding-left:unset;padding-right:unset;padding-inline:unset;box-sizing:border-box}}.page-grid__start{grid-row:start;border-bottom:1px solid #e0e0e0;border-block-end:1px solid #e0e0e0}.page-grid__main{grid-row:main}.page-grid__end{grid-row:end;border-top:1px solid #e0e0e0;border-block-start:1px solid #e0e0e0} - -/*# sourceMappingURL=all.css.map */ diff --git a/vendor-extra/LiberoPatternsBundle/src/Resources/public/css/all.css.map b/vendor-extra/LiberoPatternsBundle/src/Resources/public/css/all.css.map deleted file mode 100644 index e8bcb6b..0000000 --- a/vendor-extra/LiberoPatternsBundle/src/Resources/public/css/all.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"all.css","sources":["base.scss","_fonts.scss","_normalize.scss","mixins/_spacing.scss","mixins/_logical-properties.scss","mixins/_types.scss","variables/_font.scss","vendor/sass-rem/_rem.scss","mixins/_validation.scss","functions/_validation.scss","mixins/_sizes.scss","mixins/_media-query.scss","variables/_breakpoint.scss","vendor/sass-mq/_mq.scss","variables/_baselinegrid.scss","variables/_grid.scss","mixins/_typography.scss","variables/_color.scss","mixins/_utilities.scss","vendor/normalize.css/normalize.css","_grid.scss","patterns/molecules/content-meta.scss","patterns/molecules/section.scss","patterns/molecules/tag-list.scss","patterns/organisms/content-header.scss","variables/_content_header.scss","functions/_types.scss","mixins/_decorations.scss","patterns/organisms/item-tags.scss","patterns/templates/content-grid.scss","functions/_grid.scss","mixins/_grid.scss","patterns/templates/page-grid.scss"],"sourcesContent":["@import \"fonts\";\n@import \"normalize\";\n@import \"grid\";\n@import \"patterns/molecules/content-meta.scss\";\n@import \"patterns/molecules/section.scss\";\n@import \"patterns/molecules/tag-list.scss\";\n@import \"patterns/organisms/content-header.scss\";\n@import \"patterns/organisms/item-tags.scss\";\n@import \"patterns/templates/content-grid.scss\";\n@import \"patterns/templates/page-grid.scss\";\n","@font-face {\n font-display: fallback;\n font-family: \"Noto Sans\";\n src: url(\"../../fonts/NotoSans-Regular-webfont-custom-2-subsetting.woff2\") format(\"woff2\");\n}\n\n@font-face {\n font-display: fallback;\n font-family: \"Noto Sans\";\n src: url(\"../../fonts/NotoSans-SemiBold-webfont-custom-2-subsetting.woff2\") format(\"woff2\");\n font-weight: 600;\n}\n\n@font-face {\n font-display: fallback;\n font-family: \"Noto Serif\";\n src: url(\"../../fonts/NotoSerif-Regular-webfont-custom-2-subsetting.woff2\") format(\"woff2\");\n}\n\n@font-face {\n font-display: fallback;\n font-family: \"Noto Serif\";\n src: url(\"../../fonts/NotoSerif-Bold-webfont-basic-latin-subsetting.woff2\") format(\"woff2\");\n font-weight: bold;\n}\n","@import \"mixins/spacing\";\n@import \"mixins/typography\";\n@import \"variables/color\";\n@import \"vendor/normalize.css/normalize\";\n\n*,\n*:before,\n*:after {\n box-sizing: border-box;\n}\n\nhtml,\nbody {\n @include block-size(100%);\n}\n\nbody {\n background-color: $color-background;\n color: $color-text-normal;\n text-rendering: optimizeLegibility;\n @include body-typography();\n}\n\nh1 {\n @include h1-typography();\n @include h1-spacing();\n}\n\nh2 {\n @include h2-typography();\n @include h2-spacing();\n}\n\nh3 {\n @include h3-typography();\n @include h3-spacing();\n}\n\nh4 {\n @include h4-typography();\n @include h4-spacing();\n}\n\nh5 {\n @include h5-typography();\n @include h5-spacing();\n}\n\nh6 {\n @include h6-typography();\n @include h6-spacing();\n}\n\np {\n @include body-para();\n}\n\na {\n color: $color-primary-normal;\n text-decoration: none;\n}\n\nul,\nol {\n @include blg-spacing(\"block-end\", \"small\", \"margin\");\n @include margin(0, \"block-start\");\n}\n\ndl {\n @include blg-spacing(\"block-end\", \"small\", \"margin\");\n @include margin(0, \"block-start\");\n}\n\nli,\ndt,\ndd {\n @include body-typography();\n}\n\ndt {\n font-weight: bold;\n\n dd + & {\n @include blg-spacing(\"block-start\", \"small\", \"margin\");\n }\n}\n\ndd {\n @include margin(0, \"inline-start\");\n}\n\nsmall {\n @include small-typography();\n @include small-spacing();\n}\n\nsub {\n @include font-variant-position(sub);\n}\n\nsup {\n @include font-variant-position(super);\n}\n\naddress {\n @include small-typography();\n @include small-spacing();\n}\n\nimg {\n @include max-block-size(100%);\n @include max-inline-size(100%);\n}\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\np {\n img {\n @include inline-image();\n }\n}\n\n:lang(ja) {\n @at-root {\n em#{&} {\n font-style: normal;\n text-emphasis-style: open sesame;\n text‑emphasis‑position: over right;\n }\n\n strong#{&} {\n font-style: normal;\n text-emphasis-style: filled sesame;\n text‑emphasis‑position: over right;\n }\n\n u#{&} {\n text-underline-position: right;\n }\n }\n}\n\n:lang(ko) {\n @at-root {\n em#{&} {\n font-style: normal;\n text-decoration: underline;\n text-underline-position: under right;\n }\n\n strong#{&} {\n font-style: normal;\n text-emphasis-style: filled dot;\n text‑emphasis‑position: over right;\n }\n }\n}\n\n:lang(zh) {\n @at-root {\n em#{&} {\n font-style: normal;\n text-emphasis-style: open dot;\n text‑emphasis‑position: under right;\n }\n\n strong#{&} {\n font-style: normal;\n text-emphasis-style: filled dot;\n text‑emphasis‑position: under right;\n }\n\n cite#{&} {\n font-style: normal;\n text-decoration: underline;\n text-underline-style: wavy;\n }\n }\n}\n\n:lang(zh-Hant) {\n @at-root {\n em#{&} {\n text‑emphasis‑position: over right;\n }\n\n strong#{&} {\n text‑emphasis‑position: over right;\n }\n }\n}\n","@import \"logical-properties\";\n@import \"validation\";\n@import \"sizes\";\n@import \"types\";\n@import \"../functions/validation\";\n@import \"../mixins/media-query\";\n@import \"../variables/baselinegrid\";\n@import \"../variables/breakpoint\";\n@import \"../variables/grid\";\n\n// Fallbacks for CSS logical properties contained within this mixin require the following treatment of HTML dir attributes:\n// - document level: always specified, via the HTML element\n// - block level: specified on every element within a block describing a direction switch.\n//\n// For example:\n// \n// ...\n//
\n// Doesn't need a dir attribute. Most cases will be like this.\n//
\n//\n//
\n//\n// This block changes the text direction. Every descendant element must have its own dir attribute....\n//\n//
... even if the direction doesn't change.
\n//\n//
But obviously also when it does.
\n//\n//
\n@mixin _spacing($sizes, $space-type, $dimension: \"\") {\n\n @if $dimension == \"\" {\n\n @include _expect_at_most($sizes, 4, \"More than four sizes supplied when no dimension\") {\n @include rem($space-type, $sizes);\n }\n\n } @else if $dimension == \"inline\" {\n\n @include _expect_at_most($sizes, 2, \"More than two sizes supplied with 'inline' dimension\") {\n @include logical-property($space-type, $dimension, $sizes);\n }\n\n } @else if $dimension == \"inline-start\" {\n\n @include _expect_single_value($sizes, \"More than one size supplied with 'inline-start' dimension\") {\n @include logical-property($space-type, $dimension, $sizes);\n }\n\n } @else if $dimension == \"inline-end\" {\n\n @include _expect_single_value($sizes, \"More than one size supplied with 'inline-end' dimension\") {\n @include logical-property($space-type, $dimension, $sizes);\n }\n\n } @else if $dimension == \"block\" {\n\n @include _expect_at_most($sizes, 2, \"More than two sizes supplied with 'block' dimension\") {\n @include logical-property($space-type, $dimension, $sizes);\n }\n\n } @else if $dimension == \"block-start\" {\n\n @include _expect_single_value($sizes, \"More than one size supplied with 'block-start' dimension\") {\n @include logical-property($space-type, $dimension, $sizes);\n }\n\n } @else if $dimension == \"block-end\" {\n\n @include _expect_single_value($sizes, \"More than one size supplied with 'block-end' dimension\") {\n @include logical-property($space-type, $dimension, $sizes);\n }\n\n } @else if index((\"top\", \"bottom\", \"left\", \"right\"), $dimension) {\n @include _error(\"'#{$dimension}' is a physical dimension, use its logical equivilant\");\n } @else {\n @include _error(\"Unknown dimension '#{$dimension}'\");\n }\n\n}\n\n@mixin padding($sizes, $dimension: \"\") {\n @include _spacing($sizes, padding, $dimension);\n}\n\n@mixin margin($sizes, $dimension: \"\") {\n @include _spacing($sizes, margin, $dimension);\n}\n\n@mixin nospace($dimension: \"\") {\n @include margin(0, $dimension);\n @include padding(0, $dimension);\n}\n\n// blg stands for \"baseline grid\"\n\n@mixin blg-spacing($dimension, $level, $type: \"padding\") {\n @if $type == \"padding\" {\n @if $level == \"extra-small\" {\n @include padding($baselinegrid-space-extra-small, $dimension);\n } @else if $level == \"small\" {\n @include padding($baselinegrid-space-small, $dimension);\n } @else if $level == \"smallish\" {\n @include padding($baselinegrid-space-smallish, $dimension);\n } @else if $level == \"medium\" {\n @include padding($baselinegrid-space-medium, $dimension);\n } @else if $level == \"large\" {\n @include padding($baselinegrid-space-large, $dimension);\n }\n } @else if $type == \"margin\" {\n @if $level == \"extra-small\" {\n @include margin($baselinegrid-space-extra-small, $dimension);\n } @else if $level == \"small\" {\n @include margin($baselinegrid-space-small, $dimension);\n } @else if $level == \"smallish\" {\n @include margin($baselinegrid-space-smallish, $dimension);\n } @else if $level == \"medium\" {\n @include margin($baselinegrid-space-medium, $dimension);\n } @else if $level == \"large\" {\n @include margin($baselinegrid-space-large, $dimension);\n }\n }\n}\n\n@mixin blg-pad-top--small-to-medium {\n\n @include blg-spacing(\"block-start\", \"small\");\n\n @include mq($from: medium) {\n @include blg-spacing(\"block-start\", \"medium\");\n }\n\n}\n\n@mixin blg-pad-bottom--small-to-medium {\n\n @include blg-spacing(\"block-end\", \"small\");\n\n @include mq($from: medium) {\n @include blg-spacing(\"block-end\", \"medium\");\n }\n\n}\n\n@mixin blg-pad-top--large-to-extra-large {\n\n @include blg-spacing(\"block-start\", \"large\");\n\n @include mq($from: medium) {\n @include blg-spacing(\"block-start\", \"extra-large\");\n }\n\n}\n\n@mixin blg-pad-bottom--large-to-extra-large {\n\n @include blg-spacing(\"block-end\", \"large\");\n\n @include mq($from: medium) {\n @include blg-spacing(\"block-end\", \"extra-large\");\n }\n\n}\n\n@mixin blg-pad-vertical-small-to-medium {\n @include blg-pad-top--small-to-medium();\n @include blg-pad-bottom--small-to-medium();\n}\n\n@mixin blg-pad-vertical-large-to-extra-large {\n @include blg-pad-top--large-to-extra-large();\n @include blg-pad-bottom--large-to-extra-large();\n}\n\n@mixin blg-margin-bottom--medium-to-large {\n\n @include blg-spacing(\"block-end\", \"medium\", \"margin\");\n\n @include mq($from: medium) {\n @include blg-spacing(\"block-end\", \"large\", \"margin\");\n }\n\n}\n\n@mixin blg-margin-bottom--small-to-medium {\n\n @include blg-spacing(\"block-end\", \"small\", \"margin\");\n\n @include mq($from: medium) {\n @include blg-spacing(\"block-end\", \"medium\", \"margin\");\n }\n\n}\n\n@mixin blg-column-container() {\n @include blg-margin-bottom--medium-to-large();\n}\n\n@mixin h1-spacing() {\n margin: 0;\n}\n\n@mixin h2-spacing() {\n margin: 0;\n @include padding(21px, \"block-end\");\n @include padding(21px, \"block-start\");\n}\n\n@mixin h3-spacing() {\n margin: 0;\n @include blg-spacing(\"block-start\", \"extra-small\");\n @include blg-spacing(\"block-end\", \"extra-small\");\n}\n\n@mixin h4-spacing() {\n margin: 0;\n @include blg-spacing(\"block-start\", \"extra-small\");\n @include blg-spacing(\"block-end\", \"extra-small\");\n}\n\n@mixin h5-spacing() {\n margin: 0;\n @include blg-spacing(\"block-start\", \"extra-small\");\n @include blg-spacing(\"block-end\", \"extra-small\");\n}\n\n@mixin h6-spacing() {\n margin: 0;\n @include padding(10px, \"block-start\");\n @include padding(14px, \"block-end\");\n}\n\n@mixin body-spacing() {\n margin: 0;\n @include blg-spacing(\"block-end\", \"small\", \"margin\");\n}\n\n@mixin small-spacing() {\n @include blg-spacing(\"block-end\", \"small\");\n}\n","@import \"types\";\n@import \"validation\";\n\n@mixin _when-left-to-right {\n html[dir=\"ltr\"] &:not([dir]),\n &[dir=\"ltr\"] {\n @content;\n }\n}\n\n@mixin _when-right-to-left {\n html[dir=\"rtl\"] &:not([dir]),\n &[dir=\"rtl\"] {\n @content;\n }\n}\n\n@mixin _when-logical {\n html[dir][dir] & {\n @content;\n }\n}\n\n@mixin _maybe-rem($to-rem, $properties, $values: ()) {\n @if ($to-rem == false) {\n @if type-of($properties) == \"map\" {\n @each $property in map-keys($properties) {\n @include _maybe-rem($to-rem, $property, map-get($properties, $property));\n }\n } @else {\n @each $property in $properties {\n #{$property}: $values;\n }\n }\n } @else {\n @include rem($properties, $values...);\n }\n}\n\n@function _maybe-rem($to-rem, $values) {\n @if ($to-rem == false) {\n @return $values;\n } @else {\n @return rem($values...);\n }\n}\n\n@function _property-name($parts, $dimension) {\n @if (length($parts) == 0 or $parts == \"\") {\n @return $dimension;\n }\n\n @if (length($parts) == 1) {\n @return \"#{$parts}-#{$dimension}\";\n }\n\n @return \"#{nth($parts, 1)}-#{$dimension}-#{nth($parts, 2)}\";\n}\n\n@mixin logical-property($property-name, $dimension, $arguments, $to-rem: true) {\n\n @if length($property-name) > 2 {\n @include _error(\"Expected at most two property name parts\");\n } @else if $dimension == inline {\n\n @if type-of($arguments) == \"list\" and length($arguments) > 1 {\n\n @include _expect_at_most($arguments, 2, \"More than two arguments supplied with 'inline' dimension\") {\n\n $firstArgument: nth($arguments, 1);\n $secondArgument: nth($arguments, 2);\n\n @if $firstArgument == $secondArgument {\n\n @include _maybe-rem($to-rem, (\n #{_property-name($property-name, left)}: $firstArgument,\n #{_property-name($property-name, right)}: $firstArgument,\n ));\n #{_property-name($property-name, inline)}: _maybe-rem($to-rem, $firstArgument);\n\n } @else {\n\n @include _when-left-to-right() {\n @include _maybe-rem($to-rem, _property-name($property-name, left), $firstArgument);\n @include _maybe-rem($to-rem, _property-name($property-name, right), $secondArgument);\n }\n\n @include _when-right-to-left() {\n @include _maybe-rem($to-rem, _property-name($property-name, right), $firstArgument);\n @include _maybe-rem($to-rem, _property-name($property-name, left), $secondArgument);\n }\n\n @include _when-logical() {\n #{_property-name($property-name, inline-start)}: _maybe-rem($to-rem, $firstArgument);\n #{_property-name($property-name, inline-end)}: _maybe-rem($to-rem, $secondArgument);\n }\n\n }\n\n }\n\n } @else {\n\n @include _maybe-rem($to-rem, (\n #{_property-name($property-name, left)}: $arguments,\n #{_property-name($property-name, right)}: $arguments,\n ));\n #{_property-name($property-name, inline)}: _maybe-rem($to-rem, $arguments);\n\n }\n\n } @else if $dimension == inline-start {\n\n @include _when-left-to-right() {\n @include _maybe-rem($to-rem, _property-name($property-name, left), $arguments);\n }\n\n @include _when-right-to-left() {\n @include _maybe-rem($to-rem, _property-name($property-name, right), $arguments);\n }\n\n @include _when_logical() {\n #{_property-name($property-name, inline-start)}: _maybe-rem($to-rem, $arguments);\n }\n\n } @else if $dimension == inline-end {\n\n @include _when-left-to-right() {\n @include _maybe-rem($to-rem, _property-name($property-name, right), $arguments);\n }\n\n @include _when-right-to-left() {\n @include _maybe-rem($to-rem, _property-name($property-name, left), $arguments);\n }\n\n @include _when_logical() {\n #{_property-name($property-name, inline-end)}: _maybe-rem($to-rem, $arguments);\n }\n\n } @else if $dimension == inline-size {\n\n @include _maybe-rem($to-rem, _property-name($property-name, width), $arguments);\n #{_property-name($property-name, inline-size)}: _maybe-rem($to-rem, $arguments);\n\n } @else if $dimension == block {\n\n @if type-of($arguments) == \"list\" and length($arguments) > 1 {\n\n @include _expect_at_most($arguments, 2, \"More than two arguments supplied with 'block' dimension\") {\n\n $firstArgument: nth($arguments, 1);\n $secondArgument: nth($arguments, 2);\n\n @if $firstArgument == $secondArgument {\n\n @include _maybe-rem($to-rem, (\n #{_property-name($property-name, top)}: $firstArgument,\n #{_property-name($property-name, bottom)}: $firstArgument,\n ));\n #{_property-name($property-name, block)}: _maybe-rem($to-rem, $firstArgument);\n\n } @else {\n\n @include _maybe-rem($to-rem, (\n #{_property-name($property-name, top)}: $firstArgument,\n #{_property-name($property-name, bottom)}: $secondArgument,\n ));\n #{_property-name($property-name, block-start)}: _maybe-rem($to-rem, $firstArgument);\n #{_property-name($property-name, block-end)}: _maybe-rem($to-rem, $secondArgument);\n\n }\n\n }\n\n } @else {\n\n @include _maybe-rem($to-rem, (\n #{_property-name($property-name, top)}: $arguments,\n #{_property-name($property-name, bottom)}: $arguments,\n ));\n #{_property-name($property-name, block)}: _maybe-rem($to-rem, $arguments);\n\n }\n\n } @else if $dimension == block-start {\n\n @include _maybe-rem($to-rem, _property-name($property-name, top), $arguments);\n #{_property-name($property-name, block-start)}: _maybe-rem($to-rem, $arguments);\n\n } @else if $dimension == block-end {\n\n @include _maybe-rem($to-rem, _property-name($property-name, bottom), $arguments);\n #{_property-name($property-name, block-end)}: _maybe-rem($to-rem, $arguments);\n\n } @else if $dimension == block-size {\n\n @include _maybe-rem($to-rem, _property-name($property-name, height), $arguments);\n #{_property-name($property-name, block-size)}: _maybe-rem($to-rem, $arguments);\n\n } @else if index((top, bottom, left, right, width, height), $dimension) {\n @include _error(\"'#{$dimension}' is a physical dimension, use its logical equivilant\");\n } @else {\n @include _error(\"Unknown dimension '#{$dimension}'\");\n }\n\n}\n","@import \"../variables/font\";\n@import \"../vendor/sass-rem/rem\";\n\n$rem-baseline: $font-size-base;\n$rem-fallback: true;\n\n// Overridden to apply https://github.com/pierreburel/sass-rem/pull/12\n@mixin rem($properties, $values...) {\n\n @if type-of($properties) == \"map\" {\n\n @each $property in map-keys($properties) {\n @include rem($property, map-get($properties, $property));\n }\n\n } @else {\n\n $convert: false;\n @each $valueList in $values {\n @each $value in $valueList {\n @if type-of($value) == \"number\" and index((rem, px), unit($value)) {\n $convert: true;\n }\n }\n }\n\n @each $property in $properties {\n @if $convert == true {\n @if $rem-fallback or $rem-px-only {\n #{$property}: rem-convert(px, $values...);\n }\n @if not $rem-px-only {\n #{$property}: rem-convert(rem, $values...);\n }\n } @else if $rem-px-only {\n #{$property}: rem-convert(px, $values...);\n } @else {\n #{$property}: $values;\n }\n }\n\n }\n\n}\n","$font-size-base: 16px;\n$font-size-h1: 36px;\n$font-size-h2: 26px;\n$font-size-h3: 22px;\n$font-size-h4: 20px;\n$font-size-h5: 18px;\n$font-size-h6: 16px;\n$font-size-caption: 13px;\n$font-size-label: 11px;\n$font-letterspacing-label: 0.5px;\n$font-primary: \"Noto Serif\", serif;\n$font-secondary: \"Noto Sans\", Arial, Helvetica, sans-serif;\n$font-monospace: \"Courier 10 Pitch\", Courier, monospace;\n","$rem-baseline: 16px !default;\n$rem-fallback: false !default;\n$rem-px-only: false !default;\n\n@function rem-separator($list, $separator: false) {\n @if $separator == \"comma\" or $separator == \"space\" {\n @return append($list, null, $separator);\n } \n \n @if function-exists(\"list-separator\") == true {\n @return list-separator($list);\n }\n\n // list-separator polyfill by Hugo Giraudel (https://sass-compatibility.github.io/#list_separator_function)\n $test-list: ();\n @each $item in $list {\n $test-list: append($test-list, $item, space);\n }\n\n @return if($test-list == $list, space, comma);\n}\n\n@mixin rem-baseline($zoom: 100%) {\n font-size: $zoom / 16px * $rem-baseline;\n}\n\n@function rem-convert($to, $values...) {\n $result: ();\n $separator: rem-separator($values);\n \n @each $value in $values {\n @if type-of($value) == \"number\" and unit($value) == \"rem\" and $to == \"px\" {\n $result: append($result, $value / 1rem * $rem-baseline, $separator);\n } @else if type-of($value) == \"number\" and unit($value) == \"px\" and $to == \"rem\" {\n $result: append($result, $value / $rem-baseline * 1rem, $separator);\n } @else if type-of($value) == \"list\" {\n $value-separator: rem-separator($value);\n $value: rem-convert($to, $value...);\n $value: rem-separator($value, $value-separator);\n $result: append($result, $value, $separator);\n } @else {\n $result: append($result, $value, $separator);\n }\n }\n\n @return if(length($result) == 1, nth($result, 1), $result);\n}\n\n@function rem($values...) {\n @if $rem-px-only {\n @return rem-convert(px, $values...);\n } @else {\n @return rem-convert(rem, $values...);\n }\n}\n\n@mixin rem($properties, $values...) {\n @if type-of($properties) == \"map\" {\n @each $property in map-keys($properties) {\n @include rem($property, map-get($properties, $property));\n }\n } @else {\n @each $property in $properties {\n @if $rem-fallback or $rem-px-only {\n #{$property}: rem-convert(px, $values...);\n }\n @if not $rem-px-only {\n #{$property}: rem-convert(rem, $values...);\n }\n }\n }\n}\n","@import \"../functions/validation\";\n\n@mixin _error($message) {\n _error: _error($message);\n}\n\n@mixin _expect_at_most($value, $maxLength, $message: \"Expected at most #{$maxLength} values\") {\n\n @if length($value) > $maxLength {\n @include _error($message);\n } @else {\n @content;\n }\n\n}\n\n@mixin _expect_single_value($value, $message: \"Expected a single value\") {\n\n @include _expect_at_most($value, 1, $message) {\n @content;\n }\n\n}\n","$_is-test: false !default;\n\n@function _error($message, $capture: $_is-test) {\n @if $capture {\n @return $message;\n }\n\n @error $message;\n}\n","@import \"logical-properties\";\n@import \"types\";\n@import \"validation\";\n\n@mixin block-size($size) {\n @include _expect_single_value($size) {\n @include logical-property(\"\", block-size, ($size));\n }\n}\n\n@mixin inline-size($size) {\n @include _expect_single_value($size) {\n @include logical-property(\"\", inline-size, ($size));\n }\n}\n\n@mixin _constrain-block-size($size, $extreme) {\n @include logical-property($extreme, block-size, ($size));\n}\n\n@mixin _constrain-inline-size($size, $extreme) {\n @include logical-property($extreme, inline-size, ($size));\n}\n\n@mixin max-block-size($size) {\n @include _expect_single_value($size) {\n @include _constrain-block-size($size, max);\n }\n}\n\n@mixin min-block-size($size) {\n @include _expect_single_value($size) {\n @include _constrain-block-size($size, min);\n }\n}\n\n@mixin max-inline-size($size) {\n @include _expect_single_value($size) {\n @include _constrain-inline-size($size, max);\n }\n}\n\n@mixin min-inline-size($size) {\n @include _expect_single_value($size) {\n @include _constrain-inline-size($size, min);\n }\n}\n\n@mixin truncate-with-ellipsis() {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n\n &:lang(zh-Hant-HK) {\n text-overflow: \"⋯\";\n }\n}\n","@import \"../variables/breakpoint\";\n@import \"../variables/font\";\n\n$mq-base-font-size: $font-size-base;\n\n$mq-breakpoints: (\n x-small: $breakpoint-site-x_small,\n small: $breakpoint-site-small,\n medium: $breakpoint-site-medium,\n wide: $breakpoint-site-wide,\n x-wide: $breakpoint-site-x_wide,\n);\n\n@import \"../vendor/sass-mq/_mq\";\n","$breakpoint-site-x_small: 320px;\n$breakpoint-site-small: 480px;\n$breakpoint-site-medium: 730px;\n$breakpoint-site-wide: 900px;\n$breakpoint-site-x_wide: 1200px;\n","@charset \"UTF-8\"; // Fixes an issue where Ruby locale is not set properly\n // See https://github.com/sass-mq/sass-mq/pull/10\n\n/// Base font size on the `` element\n/// @type Number (unit)\n$mq-base-font-size: 16px !default;\n\n/// Responsive mode\n///\n/// Set to `false` to enable support for browsers that do not support @media queries,\n/// (IE <= 8, Firefox <= 3, Opera <= 9)\n///\n/// You could create a stylesheet served exclusively to older browsers,\n/// where @media queries are rasterized\n///\n/// @example scss\n/// // old-ie.scss\n/// $mq-responsive: false;\n/// @import 'main'; // @media queries in this file will be rasterized up to $mq-static-breakpoint\n/// // larger breakpoints will be ignored\n///\n/// @type Boolean\n/// @link https://github.com/sass-mq/sass-mq#responsive-mode-off Disabled responsive mode documentation\n$mq-responsive: true !default;\n\n/// Breakpoint list\n///\n/// Name your breakpoints in a way that creates a ubiquitous language\n/// across team members. It will improve communication between\n/// stakeholders, designers, developers, and testers.\n///\n/// @type Map\n/// @link https://github.com/sass-mq/sass-mq#seeing-the-currently-active-breakpoint Full documentation and examples\n$mq-breakpoints: (\n mobile: 320px,\n tablet: 740px,\n desktop: 980px,\n wide: 1300px\n) !default;\n\n/// Static breakpoint (for fixed-width layouts)\n///\n/// Define the breakpoint from $mq-breakpoints that should\n/// be used as the target width for the fixed-width layout\n/// (i.e. when $mq-responsive is set to 'false') in a old-ie.scss\n///\n/// @example scss\n/// // tablet-only.scss\n/// //\n/// // Ignore all styles above tablet breakpoint,\n/// // and fix the styles (e.g. layout) at tablet width\n/// $mq-responsive: false;\n/// $mq-static-breakpoint: tablet;\n/// @import 'main'; // @media queries in this file will be rasterized up to tablet\n/// // larger breakpoints will be ignored\n///\n/// @type String\n/// @link https://github.com/sass-mq/sass-mq#adding-custom-breakpoints Full documentation and examples\n$mq-static-breakpoint: desktop !default;\n\n/// Show breakpoints in the top right corner\n///\n/// If you want to display the currently active breakpoint in the top\n/// right corner of your site during development, add the breakpoints\n/// to this list, ordered by width, e.g. (mobile, tablet, desktop).\n///\n/// @type map\n$mq-show-breakpoints: () !default;\n\n/// Customize the media type (e.g. `@media screen` or `@media print`)\n/// By default sass-mq uses an \"all\" media type (`@media all and …`)\n///\n/// @type String\n/// @link https://github.com/sass-mq/sass-mq#changing-media-type Full documentation and examples\n$mq-media-type: all !default;\n\n/// Convert pixels to ems\n///\n/// @param {Number} $px - value to convert\n/// @param {Number} $base-font-size ($mq-base-font-size) - `` font size\n///\n/// @example scss\n/// $font-size-in-ems: mq-px2em(16px);\n/// p { font-size: mq-px2em(16px); }\n///\n/// @requires $mq-base-font-size\n/// @returns {Number}\n@function mq-px2em($px, $base-font-size: $mq-base-font-size) {\n @if unitless($px) {\n @warn \"Assuming #{$px} to be in pixels, attempting to convert it into pixels.\";\n @return mq-px2em($px * 1px, $base-font-size);\n } @else if unit($px) == em {\n @return $px;\n }\n @return ($px / $base-font-size) * 1em;\n}\n\n/// Get a breakpoint's width\n///\n/// @param {String} $name - Name of the breakpoint. One of $mq-breakpoints\n///\n/// @example scss\n/// $tablet-width: mq-get-breakpoint-width(tablet);\n/// @media (min-width: mq-get-breakpoint-width(desktop)) {}\n///\n/// @requires {Variable} $mq-breakpoints\n///\n/// @returns {Number} Value in pixels\n@function mq-get-breakpoint-width($name, $breakpoints: $mq-breakpoints) {\n @if map-has-key($breakpoints, $name) {\n @return map-get($breakpoints, $name);\n } @else {\n @warn \"Breakpoint #{$name} wasn't found in $breakpoints.\";\n }\n}\n\n/// Media Query mixin\n///\n/// @param {String | Boolean} $from (false) - One of $mq-breakpoints\n/// @param {String | Boolean} $until (false) - One of $mq-breakpoints\n/// @param {String | Boolean} $and (false) - Additional media query parameters\n/// @param {String} $media-type ($mq-media-type) - Media type: screen, print…\n///\n/// @ignore Undocumented API, for advanced use only:\n/// @ignore @param {Map} $breakpoints ($mq-breakpoints)\n/// @ignore @param {String} $static-breakpoint ($mq-static-breakpoint)\n///\n/// @content styling rules, wrapped into a @media query when $responsive is true\n///\n/// @requires {Variable} $mq-media-type\n/// @requires {Variable} $mq-breakpoints\n/// @requires {Variable} $mq-static-breakpoint\n/// @requires {function} mq-px2em\n/// @requires {function} mq-get-breakpoint-width\n///\n/// @link https://github.com/sass-mq/sass-mq#responsive-mode-on-default Full documentation and examples\n///\n/// @example scss\n/// .element {\n/// @include mq($from: mobile) {\n/// color: red;\n/// }\n/// @include mq($until: tablet) {\n/// color: blue;\n/// }\n/// @include mq(mobile, tablet) {\n/// color: green;\n/// }\n/// @include mq($from: tablet, $and: '(orientation: landscape)') {\n/// color: teal;\n/// }\n/// @include mq(950px) {\n/// color: hotpink;\n/// }\n/// @include mq(tablet, $media-type: screen) {\n/// color: hotpink;\n/// }\n/// // Advanced use:\n/// $my-breakpoints: (L: 900px, XL: 1200px);\n/// @include mq(L, $breakpoints: $my-breakpoints, $static-breakpoint: L) {\n/// color: hotpink;\n/// }\n/// }\n@mixin mq(\n $from: false,\n $until: false,\n $and: false,\n $media-type: $mq-media-type,\n $breakpoints: $mq-breakpoints,\n $responsive: $mq-responsive,\n $static-breakpoint: $mq-static-breakpoint\n) {\n $min-width: 0;\n $max-width: 0;\n $media-query: '';\n\n // From: this breakpoint (inclusive)\n @if $from {\n @if type-of($from) == number {\n $min-width: mq-px2em($from);\n } @else {\n $min-width: mq-px2em(mq-get-breakpoint-width($from, $breakpoints));\n }\n }\n\n // Until: that breakpoint (exclusive)\n @if $until {\n @if type-of($until) == number {\n $max-width: mq-px2em($until);\n } @else {\n $max-width: mq-px2em(mq-get-breakpoint-width($until, $breakpoints)) - .01em;\n }\n }\n\n // Responsive support is disabled, rasterize the output outside @media blocks\n // The browser will rely on the cascade itself.\n @if $responsive == false {\n $static-breakpoint-width: mq-get-breakpoint-width($static-breakpoint, $breakpoints);\n $target-width: mq-px2em($static-breakpoint-width);\n\n // Output only rules that start at or span our target width\n @if (\n $and == false\n and $min-width <= $target-width\n and (\n $until == false or $max-width >= $target-width\n )\n and $media-type != 'print'\n ) {\n @content;\n }\n }\n\n // Responsive support is enabled, output rules inside @media queries\n @else {\n @if $min-width != 0 { $media-query: '#{$media-query} and (min-width: #{$min-width})'; }\n @if $max-width != 0 { $media-query: '#{$media-query} and (max-width: #{$max-width})'; }\n @if $and { $media-query: '#{$media-query} and #{$and}'; }\n\n // Remove unnecessary media query prefix 'all and '\n @if ($media-type == 'all' and $media-query != '') {\n $media-type: '';\n $media-query: str-slice(unquote($media-query), 6);\n }\n\n @media #{$media-type + $media-query} {\n @content;\n }\n }\n}\n\n/// Quick sort\n///\n/// @author Sam Richards\n/// @access private\n/// @param {List} $list - List to sort\n/// @returns {List} Sorted List\n@function _mq-quick-sort($list) {\n $less: ();\n $equal: ();\n $large: ();\n\n @if length($list) > 1 {\n $seed: nth($list, ceil(length($list) / 2));\n\n @each $item in $list {\n @if ($item == $seed) {\n $equal: append($equal, $item);\n } @else if ($item < $seed) {\n $less: append($less, $item);\n } @else if ($item > $seed) {\n $large: append($large, $item);\n }\n }\n\n @return join(join(_mq-quick-sort($less), $equal), _mq-quick-sort($large));\n }\n\n @return $list;\n}\n\n/// Sort a map by values (works with numbers only)\n///\n/// @access private\n/// @param {Map} $map - Map to sort\n/// @returns {Map} Map sorted by value\n@function _mq-map-sort-by-value($map) {\n $map-sorted: ();\n $map-keys: map-keys($map);\n $map-values: map-values($map);\n $map-values-sorted: _mq-quick-sort($map-values);\n\n // Reorder key/value pairs based on key values\n @each $value in $map-values-sorted {\n $index: index($map-values, $value);\n $key: nth($map-keys, $index);\n $map-sorted: map-merge($map-sorted, ($key: $value));\n\n // Unset the value in $map-values to prevent the loop\n // from finding the same index twice\n $map-values: set-nth($map-values, $index, 0);\n }\n\n @return $map-sorted;\n}\n\n/// Add a breakpoint\n///\n/// @param {String} $name - Name of the breakpoint\n/// @param {Number} $width - Width of the breakpoint\n///\n/// @requires {Variable} $mq-breakpoints\n///\n/// @example scss\n/// @include mq-add-breakpoint(tvscreen, 1920px);\n/// @include mq(tvscreen) {}\n@mixin mq-add-breakpoint($name, $width) {\n $new-breakpoint: ($name: $width);\n $mq-breakpoints: map-merge($mq-breakpoints, $new-breakpoint) !global;\n $mq-breakpoints: _mq-map-sort-by-value($mq-breakpoints) !global;\n}\n\n/// Show the active breakpoint in the top right corner of the viewport\n/// @link https://github.com/sass-mq/sass-mq#seeing-the-currently-active-breakpoint\n///\n/// @param {List} $show-breakpoints ($mq-show-breakpoints) - List of breakpoints to show in the top right corner\n/// @param {Map} $breakpoints ($mq-breakpoints) - Breakpoint names and sizes\n///\n/// @requires {Variable} $mq-breakpoints\n/// @requires {Variable} $mq-show-breakpoints\n///\n/// @example scss\n/// // Show breakpoints using global settings\n/// @include mq-show-breakpoints;\n///\n/// // Show breakpoints using custom settings\n/// @include mq-show-breakpoints((L, XL), (S: 300px, L: 800px, XL: 1200px));\n@mixin mq-show-breakpoints($show-breakpoints: $mq-show-breakpoints, $breakpoints: $mq-breakpoints) {\n body:before {\n background-color: #FCF8E3;\n border-bottom: 1px solid #FBEED5;\n border-left: 1px solid #FBEED5;\n color: #C09853;\n font: small-caption;\n padding: 3px 6px;\n pointer-events: none;\n position: fixed;\n right: 0;\n top: 0;\n z-index: 100;\n\n // Loop through the breakpoints that should be shown\n @each $show-breakpoint in $show-breakpoints {\n $width: mq-get-breakpoint-width($show-breakpoint, $breakpoints);\n @include mq($show-breakpoint, $breakpoints: $breakpoints) {\n content: \"#{$show-breakpoint} ≥ #{$width} (#{mq-px2em($width)})\";\n }\n }\n }\n}\n\n@if length($mq-show-breakpoints) > 0 {\n @include mq-show-breakpoints;\n}\n","$baselinegrid-space-extra_small: 12px;\n$baselinegrid-space-small: 24px;\n$baselinegrid-space-smallish: 36px;\n$baselinegrid-space-medium: 48px;\n$baselinegrid-space-large: 72px;\n$baselinegrid-space-extra_large: 120px;\n","$grid-edge_space-medium: 7vw;\n$grid-edge_space-large: 14vw;\n$grid-min_width: 320px;\n$grid-max_width: 1114px;\n$grid-main_column_count: 12;\n$grid-column_gap: 1.6%;\n","@import \"../mixins/types\";\n@import \"../variables/baselinegrid\";\n@import \"../variables/color\";\n@import \"../variables/font\";\n@import \"spacing\";\n@import \"utilities\";\n\n@mixin set-font-size-and-line-height($font-size, $block-size: $baselinegrid-space-small) {\n @include rem(font-size, $font-size);\n line-height: $block-size / $font-size;\n}\n\n@mixin _heading-base-typography() {\n font-family: $font-secondary;\n font-weight: 600;\n}\n\n@mixin h1-typography() {\n @include _heading-base-typography();\n @include set-font-size-and-line-height($font-size-h1, 48px);\n}\n\n@mixin h2-typography() {\n @include _heading-base-typography();\n @include set-font-size-and-line-height($font-size-h2, 30px);\n}\n\n@mixin h3-typography() {\n @include _heading-base-typography();\n @include set-font-size-and-line-height($font-size-h3);\n}\n\n@mixin h4-typography() {\n @include _heading-base-typography();\n @include set-font-size-and-line-height($font-size-h4);\n}\n\n@mixin h5-typography() {\n @include _heading-base-typography();\n @include set-font-size-and-line-height($font-size-h5);\n}\n\n@mixin h6-typography() {\n @include _heading-base-typography();\n @include set-font-size-and-line-height($font-size-h6);\n}\n\n@mixin body-typography() {\n font-family: $font-primary;\n @include set-font-size-and-line-height($font-size-base);\n font-weight: normal;\n}\n\n@mixin small-typography() {\n font-family: $font-primary;\n font-style: normal;\n @include set-font-size-and-line-height(11px);\n}\n\n@mixin body-para {\n @include body-typography();\n @include body-spacing();\n}\n\n@mixin inline-image {\n @include margin(0.1em, \"block-end\");\n @include max-block-size(1em);\n vertical-align: middle;\n}\n\n@mixin _base-font-variant-position($position) {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n @supports (font-variant-position: #{$position}) {\n font-size: inherit;\n font-variant-position: $position;\n position: static;\n }\n}\n\n@mixin font-variant-position($position) {\n @if $position == sub {\n @include _base_font-variant-position($position);\n bottom: -0.25em; // stylelint-disable-line csstools/use-logical\n } @else if $position == super {\n @include _base_font-variant-position($position);\n top: -0.5em; // stylelint-disable-line csstools/use-logical\n } @else {\n @include _error(\"Unknown position '#{$position}'\");\n }\n}\n\n@mixin _label-typography($color, $uppercase: true) {\n color: $color;\n font-family: $font-secondary;\n font-weight: normal;\n @include set-font-size-and-line-height($font-size-label);\n letter-spacing: $font-letterspacing-label;\n @if $uppercase {\n text-transform: uppercase;\n }\n}\n\n@mixin label-content-typography($color: $color-text-secondary, $uppercase: true) {\n @include _label-typography($color, $uppercase);\n}\n\n@mixin label-tag-typography() {\n @include _label-typography($color-primary-normal);\n}\n\n@mixin covert-link($hover-color: $color-primary-dark) {\n @include inherit-all($ensure: color text-decoration);\n cursor: pointer;\n\n &:hover {\n color: $hover-color;\n }\n}\n\n@mixin list-style-none() {\n @include padding(0, inline-start);\n // Overflow auto is so the bullet will be still read from a screen reader and will push the bullet off screen\n overflow: auto;\n}\n","$color-primary-normal: rgb(2, 136, 209);\n$color-primary-light: rgb(179, 229, 252);\n$color-primary-dark: rgb(2, 119, 189);\n$color-text-normal: rgb(33, 33, 33);\n$color-text-reverse: rgb(255, 255, 255);\n$color-text-secondary: rgb(136, 136, 136);\n$color-text-secondary__reverse: rgb(158, 158, 158);\n$color-text-placeholder: rgb(189, 189, 189);\n$color-text-dividers: rgb(224, 224, 224);\n$color-text-dividers__reverse: rgb(97, 97, 97);\n$color-text-ui_background: rgb(255, 255, 255);\n$color-text-ui_background_hue: rgb(245, 245, 245);\n$color-text-ui_code: rgb(247, 247, 247);\n$color-text-ui_background__reverse: rgb(33, 33, 33);\n$color-text-ui_background_hue__reverse: rgb(51, 51, 51);\n$color-background: rgb(255, 255, 255);\n$color-information: rgb(2, 136, 209);\n$color-success: rgb(98, 159, 67);\n$color-success_dark: rgb(86, 144, 55);\n$color-attention: rgb(207, 12, 78);\n$color-warning: rgb(230, 81, 0);\n","@mixin inherit-all($ensure: ()) {\n @each $property in $ensure {\n #{$property}: inherit;\n }\n\n all: inherit;\n}\n","/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */\n\n/* Document\n ========================================================================== */\n\n/**\n * 1. Correct the line height in all browsers.\n * 2. Prevent adjustments of font size after orientation changes in iOS.\n */\n\nhtml {\n line-height: 1.15; /* 1 */\n -webkit-text-size-adjust: 100%; /* 2 */\n}\n\n/* Sections\n ========================================================================== */\n\n/**\n * Remove the margin in all browsers.\n */\n\nbody {\n margin: 0;\n}\n\n/**\n * Render the `main` element consistently in IE.\n */\n\nmain {\n display: block;\n}\n\n/**\n * Correct the font size and margin on `h1` elements within `section` and\n * `article` contexts in Chrome, Firefox, and Safari.\n */\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n/* Grouping content\n ========================================================================== */\n\n/**\n * 1. Add the correct box sizing in Firefox.\n * 2. Show the overflow in Edge and IE.\n */\n\nhr {\n box-sizing: content-box; /* 1 */\n height: 0; /* 1 */\n overflow: visible; /* 2 */\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\npre {\n font-family: monospace, monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/* Text-level semantics\n ========================================================================== */\n\n/**\n * Remove the gray background on active links in IE 10.\n */\n\na {\n background-color: transparent;\n}\n\n/**\n * 1. Remove the bottom border in Chrome 57-\n * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n */\n\nabbr[title] {\n border-bottom: none; /* 1 */\n text-decoration: underline; /* 2 */\n text-decoration: underline dotted; /* 2 */\n}\n\n/**\n * Add the correct font weight in Chrome, Edge, and Safari.\n */\n\nb,\nstrong {\n font-weight: bolder;\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\ncode,\nkbd,\nsamp {\n font-family: monospace, monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/**\n * Add the correct font size in all browsers.\n */\n\nsmall {\n font-size: 80%;\n}\n\n/**\n * Prevent `sub` and `sup` elements from affecting the line height in\n * all browsers.\n */\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -0.25em;\n}\n\nsup {\n top: -0.5em;\n}\n\n/* Embedded content\n ========================================================================== */\n\n/**\n * Remove the border on images inside links in IE 10.\n */\n\nimg {\n border-style: none;\n}\n\n/* Forms\n ========================================================================== */\n\n/**\n * 1. Change the font styles in all browsers.\n * 2. Remove the margin in Firefox and Safari.\n */\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n font-family: inherit; /* 1 */\n font-size: 100%; /* 1 */\n line-height: 1.15; /* 1 */\n margin: 0; /* 2 */\n}\n\n/**\n * Show the overflow in IE.\n * 1. Show the overflow in Edge.\n */\n\nbutton,\ninput { /* 1 */\n overflow: visible;\n}\n\n/**\n * Remove the inheritance of text transform in Edge, Firefox, and IE.\n * 1. Remove the inheritance of text transform in Firefox.\n */\n\nbutton,\nselect { /* 1 */\n text-transform: none;\n}\n\n/**\n * Correct the inability to style clickable types in iOS and Safari.\n */\n\nbutton,\n[type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\n/**\n * Remove the inner border and padding in Firefox.\n */\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n border-style: none;\n padding: 0;\n}\n\n/**\n * Restore the focus styles unset by the previous rule.\n */\n\nbutton:-moz-focusring,\n[type=\"button\"]:-moz-focusring,\n[type=\"reset\"]:-moz-focusring,\n[type=\"submit\"]:-moz-focusring {\n outline: 1px dotted ButtonText;\n}\n\n/**\n * Correct the padding in Firefox.\n */\n\nfieldset {\n padding: 0.35em 0.75em 0.625em;\n}\n\n/**\n * 1. Correct the text wrapping in Edge and IE.\n * 2. Correct the color inheritance from `fieldset` elements in IE.\n * 3. Remove the padding so developers are not caught out when they zero out\n * `fieldset` elements in all browsers.\n */\n\nlegend {\n box-sizing: border-box; /* 1 */\n color: inherit; /* 2 */\n display: table; /* 1 */\n max-width: 100%; /* 1 */\n padding: 0; /* 3 */\n white-space: normal; /* 1 */\n}\n\n/**\n * Add the correct vertical alignment in Chrome, Firefox, and Opera.\n */\n\nprogress {\n vertical-align: baseline;\n}\n\n/**\n * Remove the default vertical scrollbar in IE 10+.\n */\n\ntextarea {\n overflow: auto;\n}\n\n/**\n * 1. Add the correct box sizing in IE 10.\n * 2. Remove the padding in IE 10.\n */\n\n[type=\"checkbox\"],\n[type=\"radio\"] {\n box-sizing: border-box; /* 1 */\n padding: 0; /* 2 */\n}\n\n/**\n * Correct the cursor style of increment and decrement buttons in Chrome.\n */\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n/**\n * 1. Correct the odd appearance in Chrome and Safari.\n * 2. Correct the outline style in Safari.\n */\n\n[type=\"search\"] {\n -webkit-appearance: textfield; /* 1 */\n outline-offset: -2px; /* 2 */\n}\n\n/**\n * Remove the inner padding in Chrome and Safari on macOS.\n */\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n/**\n * 1. Correct the inability to style clickable types in iOS and Safari.\n * 2. Change font properties to `inherit` in Safari.\n */\n\n::-webkit-file-upload-button {\n -webkit-appearance: button; /* 1 */\n font: inherit; /* 2 */\n}\n\n/* Interactive\n ========================================================================== */\n\n/*\n * Add the correct display in Edge, IE 10+, and Firefox.\n */\n\ndetails {\n display: block;\n}\n\n/*\n * Add the correct display in all browsers.\n */\n\nsummary {\n display: list-item;\n}\n\n/* Misc\n ========================================================================== */\n\n/**\n * Add the correct display in IE 10+.\n */\n\ntemplate {\n display: none;\n}\n\n/**\n * Add the correct display in IE 10.\n */\n\n[hidden] {\n display: none;\n}\n","@import \"mixins/logical-properties\";\n@import \"mixins/media-query\";\n@import \"variables/grid\";\n\n:root {\n --GRID-COLUMN-GAP: #{$grid-column_gap};\n --GRID-EDGE-SPACE: #{$grid-edge_space-medium};\n --GRID-COLUMN-WIDTH: calc((100% - (var(--GRID-EDGE-SPACE) * 2) - (var(--GRID-COLUMN-GAP) * #{$grid-main_column_count - 1})) / #{$grid-main_column_count});\n\n @include mq($from: medium) {\n --GRID-EDGE-SPACE: #{$grid-edge_space-large};\n }\n\n @include mq($from: x-wide) {\n --GRID-COLUMN-GAP: #{($grid-max_width * $grid-column_gap) / 100%};\n --GRID-COLUMN-WIDTH: calc((#{$grid-max_width} - (var(--GRID-COLUMN-GAP) * #{$grid-main_column_count - 1})) / #{$grid-main_column_count});\n }\n\n @include logical-property(min, inline-size, $grid-min_width, $to-rem: false);\n}\n","@import \"../../mixins/spacing\";\n@import \"../../mixins/typography\";\n\n.content-meta {\n @include list-style-none();\n @include body-spacing();\n}\n\n.content-meta__item {\n display: inline-block;\n @include label-content-typography();\n\n &:after {\n content: \"\\a0\\2022\\a0\";\n }\n\n &:last-child:after {\n content: \"\";\n }\n}\n\n.content-meta__link {\n @include covert-link();\n}\n","@import \"../../mixins/spacing\";\n\n.section__body {\n @include body-spacing();\n}\n","@import \"../../mixins/sizes\";\n@import \"../../mixins/typography\";\n\n.tag-list {\n @include blg-spacing(\"block-end\", \"small\", \"margin\");\n}\n\n.tag-list__title {\n @include label-content-typography();\n @include padding(0, \"block\");\n}\n\n.tag-list__list {\n @include list-style-none();\n @include blg-spacing(\"block-end\", \"small\", \"margin\");\n}\n\n.tag-list__list--single-line {\n @include truncate-with-ellipsis();\n}\n\n.tag-list__item {\n display: inline-block;\n @include label-tag-typography();\n\n &:after {\n display: inline;\n content: \",\\a0\";\n }\n\n &:lang(ar):after {\n content: \"،\\a0\";\n }\n\n &:lang(ja):after {\n content: \"、\";\n }\n\n &:last-child:after {\n content: \"\";\n }\n}\n\n.tag-list__link {\n @include covert-link();\n}\n","@import \"../../variables/baselinegrid\";\n@import \"../../variables/color\";\n@import \"../../variables/content_header\";\n@import \"../../functions/types\";\n@import \"../../mixins/decorations\";\n@import \"../../mixins/media-query\";\n@import \"../../mixins/spacing\";\n@import \"../../mixins/typography\";\n\n.content-header {\n color: $color-text-normal;\n text-align: center;\n @include blg-spacing(\"block-start\", \"medium\", \"margin\");\n @include blg-spacing(\"block-end\", \"small\", \"margin\");\n @include divider(\"block-end\");\n}\n\n.content-header__title {\n @include margin(0, \"block-start\");\n @include blg-spacing(\"block-end\", \"small\", \"margin\");\n\n &:last-child {\n @include blg-spacing(\"block-end\", \"medium\", \"margin\");\n }\n}\n\n.content-header__title--xx-short {\n @include rem(font-size, $content_header-title-size-xx_large);\n\n @include mq($from: small) {\n @include rem(font-size, $content_header-title-size-xxx_large);\n }\n}\n\n.content-header__title--x-short {\n @include rem(font-size, $content_header-title-size-x_large);\n\n @include mq($from: medium) {\n @include rem(font-size, $content_header-title-size-xx_large);\n }\n\n @include mq($from: wide) {\n @include rem(font-size, $content_header-title-size-xxx_large);\n }\n}\n\n.content-header__title--short {\n @include rem(font-size, $content_header-title-size-medium);\n\n @include mq($from: small) {\n @include rem(font-size, $content_header-title-size-large);\n }\n\n @include mq($from: medium) {\n @include rem(font-size, $content_header-title-size-x_large);\n }\n\n @include mq($from: wide) {\n @include rem(font-size, $content_header-title-size-xx_large);\n }\n\n @include mq($from: x-wide) {\n @include rem(font-size, $content_header-title-size-xxx_large);\n }\n}\n\n.content-header__title--medium {\n @include rem(font-size, $content_header-title-size-small);\n\n @include mq($from: small) {\n @include rem(font-size, $content_header-title-size-medium);\n }\n\n @include mq($from: medium) {\n @include rem(font-size, $content_header-title-size-large);\n }\n\n @include mq($from: wide) {\n @include rem(font-size, $content_header-title-size-x_large);\n }\n\n @include mq($from: x-wide) {\n @include rem(font-size, $content_header-title-size-xxx_large);\n }\n}\n\n.content-header__title--long {\n @include rem(font-size, $content_header-title-size-x_small);\n\n @include mq($from: small) {\n @include rem(font-size, $content_header-title-size-small);\n }\n\n @include mq($from: medium) {\n @include rem(font-size, $content_header-title-size-large);\n }\n\n @include mq($from: x-wide) {\n @include rem(font-size, $content_header-title-size-x_large);\n }\n\n}\n\n.content-header__title--x-long {\n @include rem(font-size, $content_header-title-size-x_small);\n\n @include mq($from: medium) {\n @include rem(font-size, $content_header-title-size-small);\n }\n\n @include mq($from: wide) {\n @include rem(font-size, $content_header-title-size-small);\n }\n\n @include mq($from: x-wide) {\n @include rem(font-size, $content_header-title-size-medium);\n }\n}\n\n.content-header__title--xx-long {\n @include rem(font-size, $content_header-title-size-xx_small);\n\n @include mq($from: small) {\n @include rem(font-size, $content_header-title-size-x_small);\n }\n\n @include mq($from: wide) {\n @include rem(font-size, $content_header-title-size-small);\n }\n}\n","$content_header-title-size-xx_small: 18px;\n$content_header-title-size-x_small: 20px;\n$content_header-title-size-small: 26px;\n$content_header-title-size-medium: 30px;\n$content_header-title-size-large: 36px;\n$content_header-title-size-x_large: 41px;\n$content_header-title-size-xx_large: 46px;\n$content_header-title-size-xxx_large: 52px;\n","@import \"../mixins/types\";\n@import \"../variables/font\";\n\n$rem-baseline: $font-size-base;\n$rem-fallback: true;\n","@import \"../mixins/logical-properties\";\n@import \"../variables/color\";\n\n@mixin divider($dimension) {\n\n @if index((\"inline\", \"inline-start\", \"inline-end\", \"block\", \"block-start\", \"block-end\"), $dimension) {\n @include logical-property(border, $dimension, (1px solid $color-text-dividers,), $to-rem: false);\n } @else if index((\"top\", \"bottom\", \"left\", \"right\"), $dimension) {\n @include _error(\"'#{$dimension}' is a physical dimension, use its logical equivilant\");\n } @else {\n @include _error(\"Unknown dimension '#{$dimension}'\");\n }\n\n}\n","@import \"../../mixins/media-query\";\n@import \"../../mixins/spacing\";\n@import \"../../mixins/types\";\n@import \"../../mixins/typography\";\n@import \"../../variables/color\";\n\n.item-tags {\n @include blg-spacing(\"block-start\", \"medium\", \"padding\");\n text-align: center;\n\n @include mq($from: medium) {\n text-align: initial;\n }\n}\n","@import \"../../functions/grid\";\n@import \"../../mixins/grid\";\n@import \"../../mixins/media-query\";\n@import \"../../variables/grid\";\n\n.content-grid {\n --primary-column-width: #{get-overall-width($grid-main_column_count)};\n\n @include base-grid($grid-max_width);\n grid-template-areas:\n \". menu .\"\n \". primary .\";\n grid-template-columns: [full-start] 1fr [main-start] var(--primary-column-width) [main-end] 1fr [full-end];\n grid-column-gap: var(--GRID-COLUMN-GAP);\n\n @include mq($from: wide) {\n $primary-column-count: $grid-main_column_count - 2;\n $secondary-column-count: floor(($grid-main_column_count - $primary-column-count) / 2);\n $menu-column-count: $grid-main_column_count - $primary-column-count - $secondary-column-count;\n --primary-column-width: #{get-overall-width($primary-column-count)};\n --secondary-column-width: #{get-overall-width($secondary-column-count)};\n --menu-column-width: #{get-overall-width($menu-column-count)};\n grid-template-areas:\n \". . menu . .\"\n \". . primary . .\";\n grid-template-columns: [full-start] 1fr [main-start] var(--menu-column-width) var(--primary-column-width) var(--secondary-column-width) [main-end] 1fr [full-end];\n }\n\n @include mq($from: x-wide) {\n $primary-column-count: floor($grid-main_column_count * 0.7);\n $secondary-column-count: floor(($grid-main_column_count - $primary-column-count) / 2);\n $menu-column-count: $grid-main_column_count - $primary-column-count - $secondary-column-count;\n --primary-column-width: #{get-overall-width($primary-column-count)};\n --secondary-column-width: #{get-overall-width($secondary-column-count)};\n --menu-column-width: #{get-overall-width($menu-column-count)};\n grid-template-areas: \". menu primary . .\";\n }\n}\n\n.content-grid--has-secondary {\n grid-template-areas:\n \". menu .\"\n \". primary .\"\n \". secondary .\";\n\n @include mq($from: wide) {\n $primary-column-count: floor($grid-main_column_count * 0.7);\n $secondary-column-count: $grid-main_column_count - $primary-column-count;\n --primary-column-width: #{get-overall-width($primary-column-count)};\n --secondary-column-width: #{get-overall-width($secondary-column-count)};\n grid-template-areas:\n \". menu menu .\"\n \". primary secondary .\";\n grid-template-columns: [full-start] 1fr [main-start] var(--primary-column-width) var(--secondary-column-width) [main-end] 1fr [full-end];\n }\n\n @include mq($from: x-wide) {\n $primary-column-count: floor($grid-main_column_count * 0.6);\n $secondary-column-count: floor($grid-main_column_count * 0.25);\n $menu-column-count: $grid-main_column_count - $primary-column-count - $secondary-column-count;\n --primary-column-width: #{get-overall-width($primary-column-count)};\n --secondary-column-width: #{get-overall-width($secondary-column-count)};\n --menu-column-width: #{get-overall-width($menu-column-count)};\n grid-template-areas: \". menu primary secondary .\";\n grid-template-columns: [full-start] 1fr [main-start] var(--menu-column-width) var(--primary-column-width) var(--secondary-column-width) [main-end] 1fr [full-end];\n }\n}\n\n.content-grid__item,\n.content-grid__item--main {\n grid-column: main;\n}\n\n.content-grid__item--full {\n grid-column: full;\n}\n\n.content-grid__item--primary {\n grid-column: primary;\n}\n\n.content-grid__item--secondary {\n grid-column: secondary;\n}\n\n.content-grid__item--menu {\n grid-column: menu;\n}\n","@function get-overall-width($columns) {\n @return calc((#{$columns} * var(--GRID-COLUMN-WIDTH)) + (#{$columns - 1} * var(--GRID-COLUMN-GAP)));\n}\n","@import \"spacing\";\n@import \"types\";\n@import \"../functions/grid\";\n\n@mixin base-grid($max-inline-size) {\n @include max-inline-size($max-inline-size);\n @include margin(auto, inline);\n @include padding($grid-column_gap, inline);\n box-sizing: content-box;\n\n @supports (display: grid) and (--custom: property) {\n display: grid;\n @include max-inline-size(unset);\n @include margin(unset, inline);\n @include padding(unset, inline);\n box-sizing: border-box;\n }\n}\n","@import \"../../mixins/decorations\";\n@import \"../../mixins/grid\";\n@import \"../../variables/grid\";\n\n.page-grid {\n @include base-grid($grid-max_width);\n grid-template-areas:\n \"start\"\n \"main\"\n \"end\";\n}\n\n.page-grid__start {\n grid-row: start;\n @include divider(block-end);\n}\n\n.page-grid__main {\n grid-row: main;\n}\n\n.page-grid__end {\n grid-row: end;\n @include divider(block-start);\n}\n"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/vendor-extra/LiberoPatternsBundle/src/Resources/views/heading.html.twig b/vendor-extra/LiberoPatternsBundle/src/Resources/views/heading.html.twig index e71a095..3aa1f8f 100644 --- a/vendor-extra/LiberoPatternsBundle/src/Resources/views/heading.html.twig +++ b/vendor-extra/LiberoPatternsBundle/src/Resources/views/heading.html.twig @@ -1,5 +1,21 @@ +{%- set attributes = attributes|default({})|merge({class: attributes.class|default([])|merge(['heading']) }) -%} + - {%- include '@LiberoPatterns/text.html.twig' with {nodes: text} only -%} + {%- if text.text is not defined -%} + {%- set text = {text: text} -%} + {%- endif -%} + + {%- with text only -%} + {%- block text -%} + + {%- if attributes.href is defined -%} + {%- set attributes = attributes|default({})|merge({class: attributes.class|default([])|merge(['heading__link']) }) -%} + {%- endif -%} + + {%- include '@LiberoPatterns/link.html.twig' -%} + + {%- endblock -%} + {%- endwith -%} diff --git a/vendor-extra/LiberoPatternsBundle/src/Resources/views/teaser-list.html.twig b/vendor-extra/LiberoPatternsBundle/src/Resources/views/teaser-list.html.twig new file mode 100644 index 0000000..e0e1299 --- /dev/null +++ b/vendor-extra/LiberoPatternsBundle/src/Resources/views/teaser-list.html.twig @@ -0,0 +1,54 @@ +{%- set attributes = attributes|default({})|merge({class: attributes.class|default([])|merge(['teaser-list']) }) -%} + +
+ + {%- with title|default({}) only -%} + {%- block title -%} + + {% if text is defined %} + + {%- set attributes = attributes|default({})|merge({class: attributes.class|default([])|merge(['teaser-list__title']) }) -%} + {%- include '@LiberoPatterns/heading.html.twig' with {level: level|default(4)} -%} + + {% endif %} + + {%- endblock title -%} + {%- endwith -%} + + {%- with list only -%} + {%- block list -%} + + {%- set attributes = attributes|default({})|merge({class: attributes.class|default([])|merge(['teaser-list__list']) }) -%} + +
    + + {%- for item in items -%} + + {%- with item only -%} + {%- block item -%} + + {%- set attributes = attributes|default({})|merge({class: attributes.class|default([])|merge(['teaser-list__item']) }) -%} + +
  1. + + {%- with content only -%} + {%- block content -%} + + {%- include('@LiberoPatterns/teaser.html.twig') -%} + + {%- endblock content -%} + {%- endwith -%} + +
  2. + + {%- endblock item -%} + {%- endwith -%} + + {%- endfor -%} + +
+ + {%- endblock list -%} + {%- endwith -%} + +
diff --git a/vendor-extra/LiberoPatternsBundle/src/Resources/views/teaser.html.twig b/vendor-extra/LiberoPatternsBundle/src/Resources/views/teaser.html.twig new file mode 100644 index 0000000..dd53cfb --- /dev/null +++ b/vendor-extra/LiberoPatternsBundle/src/Resources/views/teaser.html.twig @@ -0,0 +1,27 @@ +{%- set attributes = attributes|default({})|merge({class: attributes.class|default([])|merge(['teaser']) }) -%} + +
+ + {%- with {attributes: {class: []}} -%} + {%- block header -%} + + {%- set attributes = attributes|merge({class: attributes.class|merge(['teaser__header']) }) -%} +
+ + {%- with heading|merge({text: {attributes: {href: href}, text: heading.text} }) only -%} + {%- block heading -%} + + {%- set attributes = attributes|default({})|merge({class: attributes.class|default([])|merge(['teaser__heading']) }) -%} + {%- set level = level|default(4) -%} + + {%- include '@LiberoPatterns/heading.html.twig' -%} + + {%- endblock heading -%} + {%- endwith -%} + +
+ + {%- endblock header -%} + {%- endwith -%} + +
From ee06b3ff780b93920171634e4b4debfa8b95705f Mon Sep 17 00:00:00 2001 From: nlisgo Date: Tue, 2 Apr 2019 16:11:29 +0100 Subject: [PATCH 16/46] Introduce teaser pattern --- ...aphListener.php => ItemTeaserListener.php} | 25 ++++++++++--------- .../src/Resources/config/services.xml | 4 +-- .../BuildView/ItemListListener.php | 4 +-- ...Listener.php => ItemRefTeaserListener.php} | 4 +-- .../src/Resources/config/services.xml | 4 +-- 5 files changed, 21 insertions(+), 20 deletions(-) rename vendor-extra/JatsContentBundle/src/EventListener/BuildView/{ItemParagraphListener.php => ItemTeaserListener.php} (66%) rename vendor-extra/LiberoPageBundle/src/EventListener/BuildView/{ItemRefParagraphListener.php => ItemRefTeaserListener.php} (94%) diff --git a/vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemParagraphListener.php b/vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemTeaserListener.php similarity index 66% rename from vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemParagraphListener.php rename to vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemTeaserListener.php index 9cdb0ef..1cf1a31 100644 --- a/vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemParagraphListener.php +++ b/vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemTeaserListener.php @@ -10,7 +10,7 @@ use Libero\ViewsBundle\Views\ViewConverter; use function Libero\ViewsBundle\array_has_key; -final class ItemParagraphListener +final class ItemTeaserListener { use SimplifiedViewConverterListener; @@ -23,28 +23,29 @@ public function __construct(ViewConverter $converter) protected function handle(Element $object, View $view) : View { - $title = $object->ownerDocument->xpath() + $heading = $object->ownerDocument->xpath() ->firstOf( '/libero:item/jats:article/jats:front/jats:article-meta/jats:title-group/jats:article-title', $object ); - if (!$title instanceof Element) { + if (!$heading instanceof Element) { return $view; } - return $view->withArguments( - $this->converter->convert( - $title, - '@LiberoPatterns/heading.html.twig', - $view->getContext() - )->getArguments() - ); + return $view + ->withArgument('href', '#') + ->withArgument( + 'heading', + $this->converter + ->convert($heading, '@LiberoPatterns/heading.html.twig', $view->getContext()) + ->getArguments() + ); } protected function canHandleTemplate(?string $template) : bool { - return '@LiberoPatterns/paragraph.html.twig' === $template; + return '@LiberoPatterns/teaser.html.twig' === $template; } protected function canHandleElement(string $element) : bool @@ -54,6 +55,6 @@ protected function canHandleElement(string $element) : bool protected function canHandleArguments(array $arguments) : bool { - return !array_has_key($arguments, 'text'); + return !array_has_key($arguments, 'heading'); } } diff --git a/vendor-extra/JatsContentBundle/src/Resources/config/services.xml b/vendor-extra/JatsContentBundle/src/Resources/config/services.xml index ff3d251..b7c7083 100644 --- a/vendor-extra/JatsContentBundle/src/Resources/config/services.xml +++ b/vendor-extra/JatsContentBundle/src/Resources/config/services.xml @@ -124,8 +124,8 @@
- + diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php index cd1bbe0..210a320 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php @@ -32,7 +32,7 @@ protected function handle(Element $object, View $view) : View function (NonDocumentTypeChildNode $child) use ($view) : View { return $this->converter->convert( $child, - '@LiberoPatterns/paragraph.html.twig', + '@LiberoPatterns/teaser.html.twig', $view->getContext() ); }, @@ -53,6 +53,6 @@ protected function canHandleElement(string $element) : bool protected function canHandleArguments(array $arguments) : bool { - return !array_has_key($arguments, 'nodes'); + return !array_has_key($arguments, 'list'); } } diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefParagraphListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefTeaserListener.php similarity index 94% rename from vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefParagraphListener.php rename to vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefTeaserListener.php index 89bbc38..e5f3470 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefParagraphListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefTeaserListener.php @@ -12,7 +12,7 @@ use Psr\Http\Message\ResponseInterface; use function sprintf; -final class ItemRefParagraphListener +final class ItemRefTeaserListener { private $client; private $converter; @@ -58,7 +58,7 @@ function (ResponseInterface $response) use ($object, $view) : View { protected function canHandleTemplate(string $template) : bool { - return '@LiberoPatterns/paragraph.html.twig' === $template; + return '@LiberoPatterns/teaser.html.twig' === $template; } protected function canHandleElement(string $element) : bool diff --git a/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml b/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml index ee699fe..ed2fe48 100644 --- a/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml +++ b/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml @@ -48,8 +48,8 @@ - + From 95516a41cc5731f4cdc4af417272b670eaad7fd8 Mon Sep 17 00:00:00 2001 From: nlisgo Date: Tue, 2 Apr 2019 16:12:15 +0100 Subject: [PATCH 17/46] Note to set route to content --- .../src/EventListener/BuildView/ItemTeaserListener.php | 1 + 1 file changed, 1 insertion(+) diff --git a/vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemTeaserListener.php b/vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemTeaserListener.php index 1cf1a31..e975ee9 100644 --- a/vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemTeaserListener.php +++ b/vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemTeaserListener.php @@ -34,6 +34,7 @@ protected function handle(Element $object, View $view) : View } return $view + // @todo - set route to content. ->withArgument('href', '#') ->withArgument( 'heading', From d8a1bb2515df56f13ea458e4ce336acba896402d Mon Sep 17 00:00:00 2001 From: nlisgo Date: Tue, 2 Apr 2019 21:02:12 +0100 Subject: [PATCH 18/46] Adjust arguments handled --- .../src/EventListener/BuildView/ItemListListener.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php index 210a320..655aef1 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php @@ -53,6 +53,6 @@ protected function canHandleElement(string $element) : bool protected function canHandleArguments(array $arguments) : bool { - return !array_has_key($arguments, 'list'); + return !array_has_key($arguments, 'nodes'); } } From 84a422845e268b542a265bdc40dd9c7dfce83aea Mon Sep 17 00:00:00 2001 From: nlisgo Date: Wed, 3 Apr 2019 10:00:04 +0100 Subject: [PATCH 19/46] Use teaser-list template --- .../BuildView/ItemListListener.php | 30 +++++++++++-------- .../HomepageContentListListener.php | 2 +- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php index 655aef1..d89a38e 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php @@ -27,23 +27,27 @@ public function __construct(ViewConverter $converter) protected function handle(Element $object, View $view) : View { return $view->withArgument( - 'nodes', - array_map( - function (NonDocumentTypeChildNode $child) use ($view) : View { - return $this->converter->convert( - $child, - '@LiberoPatterns/teaser.html.twig', - $view->getContext() - ); - }, - iterator_to_array($object->getElementsByTagNameNS('http://libero.pub', 'item-ref')) - ) + 'list', + [ + 'items' => array_map( + function (NonDocumentTypeChildNode $child) use ($view) : array { + return [ + 'content' => $this->converter->convert( + $child, + '@LiberoPatterns/teaser.html.twig', + $view->getContext() + ) + ]; + }, + iterator_to_array($object->getElementsByTagNameNS('http://libero.pub', 'item-ref')) + ) + ] ); } protected function canHandleTemplate(string $template) : bool { - return '@LiberoPatterns/text.html.twig' === $template; + return '@LiberoPatterns/teaser-list.html.twig' === $template; } protected function canHandleElement(string $element) : bool @@ -53,6 +57,6 @@ protected function canHandleElement(string $element) : bool protected function canHandleArguments(array $arguments) : bool { - return !array_has_key($arguments, 'nodes'); + return !array_has_key($arguments, 'list'); } } diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php index 1aed177..c67346b 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php @@ -57,7 +57,7 @@ public function onCreatePagePart(CreatePagePartEvent $event) : void $list = $event->getDocument('content_list'); $event->addContent( - $this->converter->convert($list->documentElement, '@LiberoPatterns/text.html.twig', $event->getContext()) + $this->converter->convert($list->documentElement, '@LiberoPatterns/teaser-list.html.twig', $event->getContext()) ); } From 029a20136526946ce13e2a7b01549368191ea4f7 Mon Sep 17 00:00:00 2001 From: nlisgo Date: Wed, 3 Apr 2019 11:38:33 +0100 Subject: [PATCH 20/46] cs --- .../src/EventListener/HomepageContentListListener.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php index c67346b..2246211 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php @@ -57,7 +57,11 @@ public function onCreatePagePart(CreatePagePartEvent $event) : void $list = $event->getDocument('content_list'); $event->addContent( - $this->converter->convert($list->documentElement, '@LiberoPatterns/teaser-list.html.twig', $event->getContext()) + $this->converter->convert( + $list->documentElement, + '@LiberoPatterns/teaser-list.html.twig', + $event->getContext() + ) ); } From 91d628be6a13a9e510b5643214e7ce4bfb8739d8 Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Wed, 3 Apr 2019 11:41:52 +0100 Subject: [PATCH 21/46] Update vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php Co-Authored-By: nlisgo --- .../src/EventListener/BuildView/ItemListListener.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php index d89a38e..702e725 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php @@ -36,7 +36,7 @@ function (NonDocumentTypeChildNode $child) use ($view) : array { $child, '@LiberoPatterns/teaser.html.twig', $view->getContext() - ) + )->getArguments() ]; }, iterator_to_array($object->getElementsByTagNameNS('http://libero.pub', 'item-ref')) From 137582fa1f021ede7ed22c6075178eab604ede9a Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Wed, 3 Apr 2019 13:25:36 +0100 Subject: [PATCH 22/46] Add in paths --- .docker/api/data/blog-articles/post1/1.xml | 1 + .../data/scholarly-articles/article1/1.xml | 1 + .../data/scholarly-articles/article2/1.xml | 1 + README.md | 6 +- config/packages/dev/libero_page.yaml | 6 +- config/packages/test/libero_page.yaml | 6 +- ...php => ItemArticleTitleTeaserListener.php} | 4 +- .../src/Resources/config/services.xml | 4 +- .../LiberoPageConfiguration.php | 4 +- .../BuildView/ItemTeaserHrefListener.php | 57 +++++++++++++++++++ .../src/EventListener/ContentItemListener.php | 2 +- .../src/Resources/config/services.xml | 6 ++ 12 files changed, 77 insertions(+), 21 deletions(-) rename vendor-extra/JatsContentBundle/src/EventListener/BuildView/{ItemTeaserListener.php => ItemArticleTitleTeaserListener.php} (93%) create mode 100644 vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemTeaserHrefListener.php diff --git a/.docker/api/data/blog-articles/post1/1.xml b/.docker/api/data/blog-articles/post1/1.xml index d02fb8d..fd7b00d 100644 --- a/.docker/api/data/blog-articles/post1/1.xml +++ b/.docker/api/data/blog-articles/post1/1.xml @@ -5,6 +5,7 @@ post1 + blog-articles diff --git a/.docker/api/data/scholarly-articles/article1/1.xml b/.docker/api/data/scholarly-articles/article1/1.xml index 42857e8..5226d84 100644 --- a/.docker/api/data/scholarly-articles/article1/1.xml +++ b/.docker/api/data/scholarly-articles/article1/1.xml @@ -5,6 +5,7 @@ article1 + scholarly-articles diff --git a/.docker/api/data/scholarly-articles/article2/1.xml b/.docker/api/data/scholarly-articles/article2/1.xml index ed35a8a..470d74e 100644 --- a/.docker/api/data/scholarly-articles/article2/1.xml +++ b/.docker/api/data/scholarly-articles/article2/1.xml @@ -5,6 +5,7 @@ article2 + scholarly-articles diff --git a/README.md b/README.md index 3d6283c..011aaca 100644 --- a/README.md +++ b/README.md @@ -37,12 +37,10 @@ To run an image reading from two content services (`blog-articles` and `scholarl homepage: path: '/' content: - blog_article: + blog-articles: path: '/blog/{id}' - content_service: 'blog-articles' - scholarly_article: + scholarly-articles: path: '/articles/{id}' - content_service: 'scholarly-articles' ``` Getting help diff --git a/config/packages/dev/libero_page.yaml b/config/packages/dev/libero_page.yaml index 98a9cb6..7f8b72c 100644 --- a/config/packages/dev/libero_page.yaml +++ b/config/packages/dev/libero_page.yaml @@ -4,9 +4,7 @@ libero_page: path: '/' search_service: 'scholarly-articles' content: - blog_article: + blog-articles: path: '/blog/{id}' - content_service: 'blog-articles' - scholarly_article: + scholarly-articles: path: '/articles/{id}' - content_service: 'scholarly-articles' diff --git a/config/packages/test/libero_page.yaml b/config/packages/test/libero_page.yaml index 98a9cb6..7f8b72c 100644 --- a/config/packages/test/libero_page.yaml +++ b/config/packages/test/libero_page.yaml @@ -4,9 +4,7 @@ libero_page: path: '/' search_service: 'scholarly-articles' content: - blog_article: + blog-articles: path: '/blog/{id}' - content_service: 'blog-articles' - scholarly_article: + scholarly-articles: path: '/articles/{id}' - content_service: 'scholarly-articles' diff --git a/vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemTeaserListener.php b/vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemArticleTitleTeaserListener.php similarity index 93% rename from vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemTeaserListener.php rename to vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemArticleTitleTeaserListener.php index e975ee9..33506f6 100644 --- a/vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemTeaserListener.php +++ b/vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemArticleTitleTeaserListener.php @@ -10,7 +10,7 @@ use Libero\ViewsBundle\Views\ViewConverter; use function Libero\ViewsBundle\array_has_key; -final class ItemTeaserListener +final class ItemArticleTitleTeaserListener { use SimplifiedViewConverterListener; @@ -34,8 +34,6 @@ protected function handle(Element $object, View $view) : View } return $view - // @todo - set route to content. - ->withArgument('href', '#') ->withArgument( 'heading', $this->converter diff --git a/vendor-extra/JatsContentBundle/src/Resources/config/services.xml b/vendor-extra/JatsContentBundle/src/Resources/config/services.xml index b7c7083..fc4e5c3 100644 --- a/vendor-extra/JatsContentBundle/src/Resources/config/services.xml +++ b/vendor-extra/JatsContentBundle/src/Resources/config/services.xml @@ -124,8 +124,8 @@ - + diff --git a/vendor-extra/LiberoPageBundle/src/DependencyInjection/LiberoPageConfiguration.php b/vendor-extra/LiberoPageBundle/src/DependencyInjection/LiberoPageConfiguration.php index cd6c2de..6f64dc0 100644 --- a/vendor-extra/LiberoPageBundle/src/DependencyInjection/LiberoPageConfiguration.php +++ b/vendor-extra/LiberoPageBundle/src/DependencyInjection/LiberoPageConfiguration.php @@ -75,14 +75,12 @@ private function getContentPagesDefinition() : ArrayNodeDefinition /** @var ArrayNodeDefinition $pagesNode */ $pagesNode = $builder->root('content'); $pagesNode + ->normalizeKeys(false) ->arrayPrototype() ->children() ->scalarNode('path') ->isRequired() ->end() - ->scalarNode('content_service') - ->isRequired() - ->end() ->end() ->end() ; diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemTeaserHrefListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemTeaserHrefListener.php new file mode 100644 index 0000000..1955be5 --- /dev/null +++ b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemTeaserHrefListener.php @@ -0,0 +1,57 @@ +urlGenerator = $urlGenerator; + } + + protected function handle(Element $object, View $view) : View + { + $xpath = $object->ownerDocument->xpath(); + + /** @var string $id */ + $id = $xpath->evaluate('string(/libero:item/libero:meta/libero:id)'); + /** @var string $service */ + $service = $xpath->evaluate('string(/libero:item/libero:meta/libero:service)'); + + if ('' === $id || '' === $service) { + return $view; + } + + return $view->withArgument( + 'href', + $this->urlGenerator->generate("libero.page.content.{$service}", ['id' => $id]) + ); + } + + protected function canHandleTemplate(?string $template) : bool + { + return '@LiberoPatterns/teaser.html.twig' === $template; + } + + protected function canHandleElement(string $element) : bool + { + return '{http://libero.pub}item' === $element; + } + + protected function canHandleArguments(array $arguments) : bool + { + return !array_has_key($arguments, 'href'); + } +} diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/ContentItemListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/ContentItemListener.php index 3ac2465..2e8c2c2 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/ContentItemListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/ContentItemListener.php @@ -31,7 +31,7 @@ public function onLoadPageData(LoadPageDataEvent $event) : void 'content_item', $this->client->requestAsync( 'GET', - "{$page['content_service']}/items/{$page['content_id']}/versions/latest", + "{$page['name']}/items/{$page['content_id']}/versions/latest", [ 'headers' => ['Accept' => 'application/xml'], 'http_errors' => true, diff --git a/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml b/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml index ed2fe48..f549c76 100644 --- a/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml +++ b/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml @@ -48,6 +48,12 @@ + + + + + From abba688b97e1d52eec297586908f348ac24eeca1 Mon Sep 17 00:00:00 2001 From: nlisgo Date: Thu, 4 Apr 2019 10:15:15 +0100 Subject: [PATCH 23/46] Make canHandleTemplate parameter optional --- .../src/EventListener/BuildView/ItemListListener.php | 2 +- .../src/EventListener/BuildView/ItemRefTeaserListener.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php index 702e725..ef661ec 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php @@ -45,7 +45,7 @@ function (NonDocumentTypeChildNode $child) use ($view) : array { ); } - protected function canHandleTemplate(string $template) : bool + protected function canHandleTemplate(?string $template) : bool { return '@LiberoPatterns/teaser-list.html.twig' === $template; } diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefTeaserListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefTeaserListener.php index e5f3470..d567fbf 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefTeaserListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefTeaserListener.php @@ -56,7 +56,7 @@ function (ResponseInterface $response) use ($object, $view) : View { $event->stopPropagation(); } - protected function canHandleTemplate(string $template) : bool + protected function canHandleTemplate(?string $template) : bool { return '@LiberoPatterns/teaser.html.twig' === $template; } From ef374e7fe6440ef9407b8f264ed564588a5d01d2 Mon Sep 17 00:00:00 2001 From: nlisgo Date: Thu, 4 Apr 2019 17:43:59 +0100 Subject: [PATCH 24/46] Get teaser list working --- .docker/api/data/blog-articles/post1/1.xml | 1 + .../data/scholarly-articles/article1/1.xml | 1 + .../data/scholarly-articles/article2/1.xml | 153 ++++++++++++++++++ config/packages/dev/libero_page.yaml | 1 + config/packages/test/libero_page.yaml | 1 + .../ItemArticleTitleTeaserListener.php | 60 +++++++ .../src/Resources/config/services.xml | 6 + .../LiberoPageConfiguration.php | 3 + .../BuildView/ItemListListener.php | 63 ++++++++ .../BuildView/ItemRefTeaserListener.php | 55 +++++++ .../BuildView/ItemTeaserHrefListener.php | 58 +++++++ .../HomepageContentListListener.php | 72 +++++++++ .../src/Resources/config/services.xml | 27 ++++ .../src/Resources/public/css/all.css | 3 - .../src/Resources/public/css/all.css.map | 1 - .../src/Resources/views/heading.html.twig | 18 ++- .../src/Resources/views/teaser-list.html.twig | 54 +++++++ .../src/Resources/views/teaser.html.twig | 27 ++++ 18 files changed, 599 insertions(+), 5 deletions(-) create mode 100644 .docker/api/data/scholarly-articles/article2/1.xml create mode 100644 vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemArticleTitleTeaserListener.php create mode 100644 vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php create mode 100644 vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefTeaserListener.php create mode 100644 vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemTeaserHrefListener.php create mode 100644 vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php delete mode 100644 vendor-extra/LiberoPatternsBundle/src/Resources/public/css/all.css delete mode 100644 vendor-extra/LiberoPatternsBundle/src/Resources/public/css/all.css.map create mode 100644 vendor-extra/LiberoPatternsBundle/src/Resources/views/teaser-list.html.twig create mode 100644 vendor-extra/LiberoPatternsBundle/src/Resources/views/teaser.html.twig diff --git a/.docker/api/data/blog-articles/post1/1.xml b/.docker/api/data/blog-articles/post1/1.xml index d02fb8d..fd7b00d 100644 --- a/.docker/api/data/blog-articles/post1/1.xml +++ b/.docker/api/data/blog-articles/post1/1.xml @@ -5,6 +5,7 @@ post1 + blog-articles diff --git a/.docker/api/data/scholarly-articles/article1/1.xml b/.docker/api/data/scholarly-articles/article1/1.xml index 42857e8..67b9ee1 100644 --- a/.docker/api/data/scholarly-articles/article1/1.xml +++ b/.docker/api/data/scholarly-articles/article1/1.xml @@ -5,6 +5,7 @@ article1 + blog-articles diff --git a/.docker/api/data/scholarly-articles/article2/1.xml b/.docker/api/data/scholarly-articles/article2/1.xml new file mode 100644 index 0000000..d7c29cb --- /dev/null +++ b/.docker/api/data/scholarly-articles/article2/1.xml @@ -0,0 +1,153 @@ + + + + + + + article2 + scholarly-articles + + + + + + + + + + + + + Article 2 y'all + + + + + + + Evolutionary Biology + + + + + XML + Housestyle + eLife + formatting + + + + Research organism + Human + Machine + + + + + + + + + + + Introduction + + Fossil hominins were first recognized in the Dinaledi Chamber in the Rising Star cave system in + October 2013. During a relatively short excavation, our team recovered an extensive collection of + 1550 hominin specimens, representing nearly every element of the skeleton multiple times (Figure + 1), including many complete elements and morphologically informative fragments, some in + articulation, as well as smaller fragments many of which could be refit into more complete + elements. The collection is a morphologically homogeneous sample that can be attributed to no + previously-known hominin species. Here we describe this new species, Homo + naledi. We have not defined H. naledi narrowly based on a + single jaw or skull because the entire body of material has informed our understanding of its + biology. + + + Order Primates LINNAEUS 1758 + + Suborder Anthropoidea MIVART 1864 + + Superfamily Hominoidea GRAY 1825 + + Family Hominidae GRAY 1825 + + Tribe Hominini GRAY 1825 + + Genus Homo LINNAEUS 1758 + + Homo naledi sp. nov. + urn:lsid:zoobank.org:pub:00D1E81A-6E08-4A01-BD98-79A2CEAE2411 + + + + + Etymology + + The word naledi means ‘star’ in the Sotho language and refers to + the Dinaledi Chamber's location within the Rising Star cave system. + + + + + + + Locality + + The Dinaledi chamber is located approximately 30 meters underground, within the Rising Star + cave system at about 26°1′13′′ S; 27°42′43′′ E. The system lies within the Malmani dolomites, + approximately 800 meters southwest of the well-known site of Swartkrans in the Cradle of + Humankind World Heritage Site, Gauteng Province, South Africa. + + + + + + + Horizon and associations + + The present sample of skeletal material from the Dinaledi Chamber was recovered during two + field expeditions, in November 2013 and March 2014. + + + Six specimens from an ex situ context can be identified as bird bones, and few fragmentary + rodent remains have been recovered within the excavation area. Neither of these faunal + constituents can presently be associated with the hominin fossil collection (Dirks et al., + 2015). + + + Aside from these limited faunal materials, the Dinaledi collection is entirely composed of + hominin skeletal and dental remains. The collection so far comprises 1550 fossil hominin + specimens, this number includes 1413 bone specimens and 137 isolated dental specimens; an + additional 53 teeth are present in mandibular or maxillary bone specimens. Aside from the + fragmentary rodent teeth, all dental crowns (n = 179) are hominin, recovered both from surface + collection and excavation. Likewise, aside from the few bird elements, all morphologically + informative bone specimens are clearly hominin. In all cases where elements are repeated in the + sample, they are morphologically homogeneous, with variation consistent with body size and sex + differences within a single population. These remains represent a minimum of 15 hominin + individuals, as indicated by the repetition and presence of deciduous and adult dental + elements. + + + The geological age of the fossils is not yet known. Excavations have thus far recovered + hominin material from Unit 2 and Unit 3 in the chamber (Dirks et al., 2015). Surface-collected + hominin material from the present top of Unit 3, which includes material derived from both Unit + 2 and Unit 3, represents a minority of the assemblage, and is morphologically indistinguishable + from material excavated from in situ within Unit 3. In addition to general morphological + homogeneity including cranial shape, distinctive morphological configurations of all the + recovered first metacarpals, femora, molars, lower premolars and lower canines, are identical + in both surface-collected and excavated specimens (see Figure 14 later in the text). These + include traits not found in any other hominin species yet described. These considerations + strongly indicate that this material represents a single species, and not a commingled + assemblage. + + + + + + + + + + + diff --git a/config/packages/dev/libero_page.yaml b/config/packages/dev/libero_page.yaml index 62eb72f..7f8b72c 100644 --- a/config/packages/dev/libero_page.yaml +++ b/config/packages/dev/libero_page.yaml @@ -2,6 +2,7 @@ libero_page: pages: homepage: path: '/' + search_service: 'scholarly-articles' content: blog-articles: path: '/blog/{id}' diff --git a/config/packages/test/libero_page.yaml b/config/packages/test/libero_page.yaml index 62eb72f..7f8b72c 100644 --- a/config/packages/test/libero_page.yaml +++ b/config/packages/test/libero_page.yaml @@ -2,6 +2,7 @@ libero_page: pages: homepage: path: '/' + search_service: 'scholarly-articles' content: blog-articles: path: '/blog/{id}' diff --git a/vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemArticleTitleTeaserListener.php b/vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemArticleTitleTeaserListener.php new file mode 100644 index 0000000..6de1098 --- /dev/null +++ b/vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemArticleTitleTeaserListener.php @@ -0,0 +1,60 @@ +converter = $converter; + } + + protected function handle(Element $object, TemplateView $view) : View + { + $heading = $object->ownerDocument->xpath() + ->firstOf( + '/libero:item/jats:article/jats:front/jats:article-meta/jats:title-group/jats:article-title', + $object + ); + + if (!$heading instanceof Element) { + return $view; + } + + return $view + ->withArgument( + 'heading', + $this->converter + ->convert($heading, '@LiberoPatterns/heading.html.twig', $view->getContext()) + ->getArguments() + ); + } + + protected function canHandleTemplate(?string $template) : bool + { + return '@LiberoPatterns/teaser.html.twig' === $template; + } + + protected function canHandleElement(string $element) : bool + { + return '{http://libero.pub}item' === $element; + } + + protected function canHandleArguments(array $arguments) : bool + { + return !array_has_key($arguments, 'heading'); + } +} \ No newline at end of file diff --git a/vendor-extra/JatsContentBundle/src/Resources/config/services.xml b/vendor-extra/JatsContentBundle/src/Resources/config/services.xml index 06b0236..b27a45b 100644 --- a/vendor-extra/JatsContentBundle/src/Resources/config/services.xml +++ b/vendor-extra/JatsContentBundle/src/Resources/config/services.xml @@ -124,6 +124,12 @@ + + + + + diff --git a/vendor-extra/LiberoPageBundle/src/DependencyInjection/LiberoPageConfiguration.php b/vendor-extra/LiberoPageBundle/src/DependencyInjection/LiberoPageConfiguration.php index 4763358..6f64dc0 100644 --- a/vendor-extra/LiberoPageBundle/src/DependencyInjection/LiberoPageConfiguration.php +++ b/vendor-extra/LiberoPageBundle/src/DependencyInjection/LiberoPageConfiguration.php @@ -61,6 +61,9 @@ private function getHomepageDefinition() : ArrayNodeDefinition ->scalarNode('path') ->isRequired() ->end() + ->scalarNode('search_service') + ->isRequired() + ->end() ->end() ; return $pagesNode; diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php new file mode 100644 index 0000000..99c5a53 --- /dev/null +++ b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php @@ -0,0 +1,63 @@ +converter = $converter; + } + + protected function handle(Element $object, TemplateView $view) : View + { + return $view->withArgument( + 'list', + [ + 'items' => array_map( + function (NonDocumentTypeChildNode $child) use ($view) : array { + return [ + 'content' => $this->converter->convert( + $child, + '@LiberoPatterns/teaser.html.twig', + $view->getContext() + )->getArguments() + ]; + }, + iterator_to_array($object->getElementsByTagNameNS('http://libero.pub', 'item-ref')) + ) + ] + ); + } + + protected function canHandleTemplate(?string $template) : bool + { + return '@LiberoPatterns/teaser-list.html.twig' === $template; + } + + protected function canHandleElement(string $element) : bool + { + return '{http://libero.pub}item-list' === $element; + } + + protected function canHandleArguments(array $arguments) : bool + { + return !array_has_key($arguments, 'list'); + } +} diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefTeaserListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefTeaserListener.php new file mode 100644 index 0000000..433a13f --- /dev/null +++ b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefTeaserListener.php @@ -0,0 +1,55 @@ +client = $client; + $this->converter = $converter; + } + + protected function handle(Element $object, TemplateView $view) : View + { + return $this->client + ->requestAsync( + 'GET', + "{$object->getAttribute('service')}/items/{$object->getAttribute('id')}/versions/latest" + ) + ->then( + function (ResponseInterface $response) use ($object, $view) : View { + $item = FluentDOM::load((string) $response->getBody()); + $item->namespaces($object->ownerDocument->namespaces()); + + return $this->converter->convert($item->documentElement, $view->getTemplate(), $view->getContext()); + } + )->wait(); + } + + protected function canHandleTemplate(?string $template) : bool + { + return '@LiberoPatterns/teaser.html.twig' === $template; + } + + protected function canHandleElement(string $element) : bool + { + return '{http://libero.pub}item-ref' === $element; + } +} diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemTeaserHrefListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemTeaserHrefListener.php new file mode 100644 index 0000000..07f5b36 --- /dev/null +++ b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemTeaserHrefListener.php @@ -0,0 +1,58 @@ +urlGenerator = $urlGenerator; + } + + protected function handle(Element $object, TemplateView $view) : View + { + $xpath = $object->ownerDocument->xpath(); + + /** @var string $id */ + $id = $xpath->evaluate('string(/libero:item/libero:meta/libero:id)'); + /** @var string $service */ + $service = $xpath->evaluate('string(/libero:item/libero:meta/libero:service)'); + + if ('' === $id || '' === $service) { + return $view; + } + + return $view->withArgument( + 'href', + $this->urlGenerator->generate("libero.page.content.{$service}", ['id' => $id]) + ); + } + + protected function canHandleTemplate(?string $template) : bool + { + return '@LiberoPatterns/teaser.html.twig' === $template; + } + + protected function canHandleElement(string $element) : bool + { + return '{http://libero.pub}item' === $element; + } + + protected function canHandleArguments(array $arguments) : bool + { + return !array_has_key($arguments, 'href'); + } +} diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php new file mode 100644 index 0000000..2246211 --- /dev/null +++ b/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php @@ -0,0 +1,72 @@ +client = $client; + $this->converter = $converter; + } + + public function onLoadPageData(LoadPageDataEvent $event) : void + { + if (!$event->isFor('homepage')) { + return; + } + + $page = $event->getRequest()->attributes->get('libero_page'); + + $list = $this->client + ->requestAsync( + 'GET', + "{$page['search_service']}/items", + [ + 'headers' => ['Accept' => 'application/xml'], + 'http_errors' => true, + ] + ) + ->then( + function (ResponseInterface $response) : Document { + return $this->responseToDocument($response); + } + ); + + $event->addDocument('content_list', $list); + } + + public function onCreatePagePart(CreatePagePartEvent $event) : void + { + if ('homepage' !== $event->getRequest()->attributes->get('libero_page')['type']) { + return; + } + + $list = $event->getDocument('content_list'); + $event->addContent( + $this->converter->convert( + $list->documentElement, + '@LiberoPatterns/teaser-list.html.twig', + $event->getContext() + ) + ); + } + + public function responseToDocument(ResponseInterface $response) : Document + { + return FluentDOM::load((string) $response->getBody()); + } +} diff --git a/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml b/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml index e902f6d..105f107 100644 --- a/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml +++ b/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml @@ -22,6 +22,14 @@ + + + + + + + @@ -34,6 +42,25 @@ + + + + + + + + + + + + + + + + libero diff --git a/vendor-extra/LiberoPatternsBundle/src/Resources/public/css/all.css b/vendor-extra/LiberoPatternsBundle/src/Resources/public/css/all.css deleted file mode 100644 index 55a339c..0000000 --- a/vendor-extra/LiberoPatternsBundle/src/Resources/public/css/all.css +++ /dev/null @@ -1,3 +0,0 @@ -@font-face{font-display:fallback;font-family:"Noto Sans";src:url("../fonts/NotoSans-Regular-webfont-custom-2-subsetting.woff2") format("woff2")}@font-face{font-display:fallback;font-family:"Noto Sans";src:url("../fonts/NotoSans-SemiBold-webfont-custom-2-subsetting.woff2") format("woff2");font-weight:600}@font-face{font-display:fallback;font-family:"Noto Serif";src:url("../fonts/NotoSerif-Regular-webfont-custom-2-subsetting.woff2") format("woff2")}@font-face{font-display:fallback;font-family:"Noto Serif";src:url("../fonts/NotoSerif-Bold-webfont-basic-latin-subsetting.woff2") format("woff2");font-weight:bold}/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:0.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace, monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace, monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}button,[type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:0.35em 0.75em 0.625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}*,*:before,*:after{box-sizing:border-box}html,body{height:100%;block-size:100%}body{background-color:#fff;color:#212121;text-rendering:optimizeLegibility;font-family:"Noto Serif",serif;font-size:16px;font-size:1rem;line-height:1.5;font-weight:normal}h1{font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:600;font-size:36px;font-size:2.25rem;line-height:1.33333;margin:0}h2{font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:600;font-size:26px;font-size:1.625rem;line-height:1.15385;margin:0;padding-bottom:21px;padding-bottom:1.3125rem;padding-block-end:1.3125rem;padding-top:21px;padding-top:1.3125rem;padding-block-start:1.3125rem}h3{font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:600;font-size:22px;font-size:1.375rem;line-height:1.09091;margin:0;padding-top:12px;padding-top:.75rem;padding-block-start:.75rem;padding-bottom:12px;padding-bottom:.75rem;padding-block-end:.75rem}h4{font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:600;font-size:20px;font-size:1.25rem;line-height:1.2;margin:0;padding-top:12px;padding-top:.75rem;padding-block-start:.75rem;padding-bottom:12px;padding-bottom:.75rem;padding-block-end:.75rem}h5{font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:600;font-size:18px;font-size:1.125rem;line-height:1.33333;margin:0;padding-top:12px;padding-top:.75rem;padding-block-start:.75rem;padding-bottom:12px;padding-bottom:.75rem;padding-block-end:.75rem}h6{font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:600;font-size:16px;font-size:1rem;line-height:1.5;margin:0;padding-top:10px;padding-top:.625rem;padding-block-start:.625rem;padding-bottom:14px;padding-bottom:.875rem;padding-block-end:.875rem}p{font-family:"Noto Serif",serif;font-size:16px;font-size:1rem;line-height:1.5;font-weight:normal;margin:0;margin-bottom:24px;margin-bottom:1.5rem;margin-block-end:1.5rem}a{color:#0288d1;text-decoration:none}ul,ol{margin-bottom:24px;margin-bottom:1.5rem;margin-block-end:1.5rem;margin-top:0;margin-block-start:0}dl{margin-bottom:24px;margin-bottom:1.5rem;margin-block-end:1.5rem;margin-top:0;margin-block-start:0}li,dt,dd{font-family:"Noto Serif",serif;font-size:16px;font-size:1rem;line-height:1.5;font-weight:normal}dt{font-weight:bold}dd+dt{margin-top:24px;margin-top:1.5rem;margin-block-start:1.5rem}html[dir="ltr"] dd:not([dir]),dd[dir="ltr"]{margin-left:0}html[dir="rtl"] dd:not([dir]),dd[dir="rtl"]{margin-right:0}html[dir][dir] dd{margin-inline-start:0}small{font-family:"Noto Serif",serif;font-style:normal;font-size:11px;font-size:.6875rem;line-height:2.18182;padding-bottom:24px;padding-bottom:1.5rem;padding-block-end:1.5rem}sub{font-size:75%;line-height:0;position:relative;vertical-align:baseline;bottom:-0.25em}@supports (font-variant-position: sub){sub{font-size:inherit;font-variant-position:sub;position:static}}sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;top:-0.5em}@supports (font-variant-position: super){sup{font-size:inherit;font-variant-position:super;position:static}}address{font-family:"Noto Serif",serif;font-style:normal;font-size:11px;font-size:.6875rem;line-height:2.18182;padding-bottom:24px;padding-bottom:1.5rem;padding-block-end:1.5rem}img{max-height:100%;max-block-size:100%;max-width:100%;max-inline-size:100%}h1 img,h2 img,h3 img,h4 img,h5 img,h6 img,p img{margin-bottom:.1em;margin-block-end:.1em;max-height:1em;max-block-size:1em;vertical-align:middle}em:lang(ja){font-style:normal;text-emphasis-style:open sesame;text‑emphasis‑position:over right}strong:lang(ja){font-style:normal;text-emphasis-style:filled sesame;text‑emphasis‑position:over right}u:lang(ja){text-underline-position:right}em:lang(ko){font-style:normal;text-decoration:underline;text-underline-position:under right}strong:lang(ko){font-style:normal;text-emphasis-style:filled dot;text‑emphasis‑position:over right}em:lang(zh){font-style:normal;text-emphasis-style:open dot;text‑emphasis‑position:under right}strong:lang(zh){font-style:normal;text-emphasis-style:filled dot;text‑emphasis‑position:under right}cite:lang(zh){font-style:normal;text-decoration:underline;text-underline-style:wavy}em:lang(zh-Hant){text‑emphasis‑position:over right}strong:lang(zh-Hant){text‑emphasis‑position:over right}:root{--GRID-COLUMN-GAP: 1.6%;--GRID-EDGE-SPACE: 7vw;--GRID-COLUMN-WIDTH: calc((100% - (var(--GRID-EDGE-SPACE) * 2) - (var(--GRID-COLUMN-GAP) * 11)) / 12);min-width:320px;min-inline-size:320px}@media (min-width: 45.625em){:root{--GRID-EDGE-SPACE: 14vw}}@media (min-width: 75em){:root{--GRID-COLUMN-GAP: 17.824px;--GRID-COLUMN-WIDTH: calc((1114px - (var(--GRID-COLUMN-GAP) * 11)) / 12)}}.content-meta{overflow:auto;margin:0;margin-bottom:24px;margin-bottom:1.5rem;margin-block-end:1.5rem}html[dir="ltr"] .content-meta:not([dir]),.content-meta[dir="ltr"]{padding-left:0}html[dir="rtl"] .content-meta:not([dir]),.content-meta[dir="rtl"]{padding-right:0}html[dir][dir] .content-meta{padding-inline-start:0}.content-meta__item{display:inline-block;color:#888;font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:normal;font-size:11px;font-size:.6875rem;line-height:2.18182;letter-spacing:.5px;text-transform:uppercase}.content-meta__item:after{content:"\a0\2022\a0"}.content-meta__item:last-child:after{content:""}.content-meta__link{color:inherit;text-decoration:inherit;all:inherit;cursor:pointer}.content-meta__link:hover{color:#0277bd}.section__body{margin:0;margin-bottom:24px;margin-bottom:1.5rem;margin-block-end:1.5rem}.tag-list{margin-bottom:24px;margin-bottom:1.5rem;margin-block-end:1.5rem}.tag-list__title{color:#888;font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:normal;font-size:11px;font-size:.6875rem;line-height:2.18182;letter-spacing:.5px;text-transform:uppercase;padding-top:0;padding-bottom:0;padding-block:0}.tag-list__list{overflow:auto;margin-bottom:24px;margin-bottom:1.5rem;margin-block-end:1.5rem}html[dir="ltr"] .tag-list__list:not([dir]),.tag-list__list[dir="ltr"]{padding-left:0}html[dir="rtl"] .tag-list__list:not([dir]),.tag-list__list[dir="rtl"]{padding-right:0}html[dir][dir] .tag-list__list{padding-inline-start:0}.tag-list__list--single-line{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tag-list__list--single-line:lang(zh-Hant-HK){text-overflow:"⋯"}.tag-list__item{display:inline-block;color:#0288d1;font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:normal;font-size:11px;font-size:.6875rem;line-height:2.18182;letter-spacing:.5px;text-transform:uppercase}.tag-list__item:after{display:inline;content:",\a0"}.tag-list__item:lang(ar):after{content:"،\a0"}.tag-list__item:lang(ja):after{content:"、"}.tag-list__item:last-child:after{content:""}.tag-list__link{color:inherit;text-decoration:inherit;all:inherit;cursor:pointer}.tag-list__link:hover{color:#0277bd}.content-header{color:#212121;text-align:center;margin-top:48px;margin-top:3rem;margin-block-start:3rem;margin-bottom:24px;margin-bottom:1.5rem;margin-block-end:1.5rem;border-bottom:1px solid #e0e0e0;border-block-end:1px solid #e0e0e0}.content-header__title{margin-top:0;margin-block-start:0;margin-bottom:24px;margin-bottom:1.5rem;margin-block-end:1.5rem}.content-header__title:last-child{margin-bottom:48px;margin-bottom:3rem;margin-block-end:3rem}.content-header__title--xx-short{font-size:46px;font-size:2.875rem}@media (min-width: 30em){.content-header__title--xx-short{font-size:52px;font-size:3.25rem}}.content-header__title--x-short{font-size:41px;font-size:2.5625rem}@media (min-width: 45.625em){.content-header__title--x-short{font-size:46px;font-size:2.875rem}}@media (min-width: 56.25em){.content-header__title--x-short{font-size:52px;font-size:3.25rem}}.content-header__title--short{font-size:30px;font-size:1.875rem}@media (min-width: 30em){.content-header__title--short{font-size:36px;font-size:2.25rem}}@media (min-width: 45.625em){.content-header__title--short{font-size:41px;font-size:2.5625rem}}@media (min-width: 56.25em){.content-header__title--short{font-size:46px;font-size:2.875rem}}@media (min-width: 75em){.content-header__title--short{font-size:52px;font-size:3.25rem}}.content-header__title--medium{font-size:26px;font-size:1.625rem}@media (min-width: 30em){.content-header__title--medium{font-size:30px;font-size:1.875rem}}@media (min-width: 45.625em){.content-header__title--medium{font-size:36px;font-size:2.25rem}}@media (min-width: 56.25em){.content-header__title--medium{font-size:41px;font-size:2.5625rem}}@media (min-width: 75em){.content-header__title--medium{font-size:52px;font-size:3.25rem}}.content-header__title--long{font-size:20px;font-size:1.25rem}@media (min-width: 30em){.content-header__title--long{font-size:26px;font-size:1.625rem}}@media (min-width: 45.625em){.content-header__title--long{font-size:36px;font-size:2.25rem}}@media (min-width: 75em){.content-header__title--long{font-size:41px;font-size:2.5625rem}}.content-header__title--x-long{font-size:20px;font-size:1.25rem}@media (min-width: 45.625em){.content-header__title--x-long{font-size:26px;font-size:1.625rem}}@media (min-width: 56.25em){.content-header__title--x-long{font-size:26px;font-size:1.625rem}}@media (min-width: 75em){.content-header__title--x-long{font-size:30px;font-size:1.875rem}}.content-header__title--xx-long{font-size:18px;font-size:1.125rem}@media (min-width: 30em){.content-header__title--xx-long{font-size:20px;font-size:1.25rem}}@media (min-width: 56.25em){.content-header__title--xx-long{font-size:26px;font-size:1.625rem}}.item-tags{padding-top:48px;padding-top:3rem;padding-block-start:3rem;text-align:center}@media (min-width: 45.625em){.item-tags{text-align:initial}}.content-grid{--primary-column-width: calc((12 * var(--GRID-COLUMN-WIDTH)) + (11 * var(--GRID-COLUMN-GAP)));max-width:1114px;max-width:69.625rem;max-inline-size:69.625rem;margin-left:auto;margin-right:auto;margin-inline:auto;padding-left:1.6%;padding-right:1.6%;padding-inline:1.6%;box-sizing:content-box;grid-template-areas:". menu ." ". primary .";grid-template-columns:[full-start] 1fr [main-start] var(--primary-column-width) [main-end] 1fr [full-end];grid-column-gap:var(--GRID-COLUMN-GAP)}@supports (display: grid) and (--custom: property){.content-grid{display:grid;max-width:unset;max-inline-size:unset;margin-left:unset;margin-right:unset;margin-inline:unset;padding-left:unset;padding-right:unset;padding-inline:unset;box-sizing:border-box}}@media (min-width: 56.25em){.content-grid{--primary-column-width: calc((10 * var(--GRID-COLUMN-WIDTH)) + (9 * var(--GRID-COLUMN-GAP)));--secondary-column-width: calc((1 * var(--GRID-COLUMN-WIDTH)) + (0 * var(--GRID-COLUMN-GAP)));--menu-column-width: calc((1 * var(--GRID-COLUMN-WIDTH)) + (0 * var(--GRID-COLUMN-GAP)));grid-template-areas:". . menu . ." ". . primary . .";grid-template-columns:[full-start] 1fr [main-start] var(--menu-column-width) var(--primary-column-width) var(--secondary-column-width) [main-end] 1fr [full-end]}}@media (min-width: 75em){.content-grid{--primary-column-width: calc((8 * var(--GRID-COLUMN-WIDTH)) + (7 * var(--GRID-COLUMN-GAP)));--secondary-column-width: calc((2 * var(--GRID-COLUMN-WIDTH)) + (1 * var(--GRID-COLUMN-GAP)));--menu-column-width: calc((2 * var(--GRID-COLUMN-WIDTH)) + (1 * var(--GRID-COLUMN-GAP)));grid-template-areas:". menu primary . ."}}.content-grid--has-secondary{grid-template-areas:". menu ." ". primary ." ". secondary ."}@media (min-width: 56.25em){.content-grid--has-secondary{--primary-column-width: calc((8 * var(--GRID-COLUMN-WIDTH)) + (7 * var(--GRID-COLUMN-GAP)));--secondary-column-width: calc((4 * var(--GRID-COLUMN-WIDTH)) + (3 * var(--GRID-COLUMN-GAP)));grid-template-areas:". menu menu ." ". primary secondary .";grid-template-columns:[full-start] 1fr [main-start] var(--primary-column-width) var(--secondary-column-width) [main-end] 1fr [full-end]}}@media (min-width: 75em){.content-grid--has-secondary{--primary-column-width: calc((7 * var(--GRID-COLUMN-WIDTH)) + (6 * var(--GRID-COLUMN-GAP)));--secondary-column-width: calc((3 * var(--GRID-COLUMN-WIDTH)) + (2 * var(--GRID-COLUMN-GAP)));--menu-column-width: calc((2 * var(--GRID-COLUMN-WIDTH)) + (1 * var(--GRID-COLUMN-GAP)));grid-template-areas:". menu primary secondary .";grid-template-columns:[full-start] 1fr [main-start] var(--menu-column-width) var(--primary-column-width) var(--secondary-column-width) [main-end] 1fr [full-end]}}.content-grid__item,.content-grid__item--main{grid-column:main}.content-grid__item--full{grid-column:full}.content-grid__item--primary{grid-column:primary}.content-grid__item--secondary{grid-column:secondary}.content-grid__item--menu{grid-column:menu}.page-grid{max-width:1114px;max-width:69.625rem;max-inline-size:69.625rem;margin-left:auto;margin-right:auto;margin-inline:auto;padding-left:1.6%;padding-right:1.6%;padding-inline:1.6%;box-sizing:content-box;grid-template-areas:"start" "main" "end"}@supports (display: grid) and (--custom: property){.page-grid{display:grid;max-width:unset;max-inline-size:unset;margin-left:unset;margin-right:unset;margin-inline:unset;padding-left:unset;padding-right:unset;padding-inline:unset;box-sizing:border-box}}.page-grid__start{grid-row:start;border-bottom:1px solid #e0e0e0;border-block-end:1px solid #e0e0e0}.page-grid__main{grid-row:main}.page-grid__end{grid-row:end;border-top:1px solid #e0e0e0;border-block-start:1px solid #e0e0e0} - -/*# sourceMappingURL=all.css.map */ diff --git a/vendor-extra/LiberoPatternsBundle/src/Resources/public/css/all.css.map b/vendor-extra/LiberoPatternsBundle/src/Resources/public/css/all.css.map deleted file mode 100644 index e8bcb6b..0000000 --- a/vendor-extra/LiberoPatternsBundle/src/Resources/public/css/all.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"all.css","sources":["base.scss","_fonts.scss","_normalize.scss","mixins/_spacing.scss","mixins/_logical-properties.scss","mixins/_types.scss","variables/_font.scss","vendor/sass-rem/_rem.scss","mixins/_validation.scss","functions/_validation.scss","mixins/_sizes.scss","mixins/_media-query.scss","variables/_breakpoint.scss","vendor/sass-mq/_mq.scss","variables/_baselinegrid.scss","variables/_grid.scss","mixins/_typography.scss","variables/_color.scss","mixins/_utilities.scss","vendor/normalize.css/normalize.css","_grid.scss","patterns/molecules/content-meta.scss","patterns/molecules/section.scss","patterns/molecules/tag-list.scss","patterns/organisms/content-header.scss","variables/_content_header.scss","functions/_types.scss","mixins/_decorations.scss","patterns/organisms/item-tags.scss","patterns/templates/content-grid.scss","functions/_grid.scss","mixins/_grid.scss","patterns/templates/page-grid.scss"],"sourcesContent":["@import \"fonts\";\n@import \"normalize\";\n@import \"grid\";\n@import \"patterns/molecules/content-meta.scss\";\n@import \"patterns/molecules/section.scss\";\n@import \"patterns/molecules/tag-list.scss\";\n@import \"patterns/organisms/content-header.scss\";\n@import \"patterns/organisms/item-tags.scss\";\n@import \"patterns/templates/content-grid.scss\";\n@import \"patterns/templates/page-grid.scss\";\n","@font-face {\n font-display: fallback;\n font-family: \"Noto Sans\";\n src: url(\"../../fonts/NotoSans-Regular-webfont-custom-2-subsetting.woff2\") format(\"woff2\");\n}\n\n@font-face {\n font-display: fallback;\n font-family: \"Noto Sans\";\n src: url(\"../../fonts/NotoSans-SemiBold-webfont-custom-2-subsetting.woff2\") format(\"woff2\");\n font-weight: 600;\n}\n\n@font-face {\n font-display: fallback;\n font-family: \"Noto Serif\";\n src: url(\"../../fonts/NotoSerif-Regular-webfont-custom-2-subsetting.woff2\") format(\"woff2\");\n}\n\n@font-face {\n font-display: fallback;\n font-family: \"Noto Serif\";\n src: url(\"../../fonts/NotoSerif-Bold-webfont-basic-latin-subsetting.woff2\") format(\"woff2\");\n font-weight: bold;\n}\n","@import \"mixins/spacing\";\n@import \"mixins/typography\";\n@import \"variables/color\";\n@import \"vendor/normalize.css/normalize\";\n\n*,\n*:before,\n*:after {\n box-sizing: border-box;\n}\n\nhtml,\nbody {\n @include block-size(100%);\n}\n\nbody {\n background-color: $color-background;\n color: $color-text-normal;\n text-rendering: optimizeLegibility;\n @include body-typography();\n}\n\nh1 {\n @include h1-typography();\n @include h1-spacing();\n}\n\nh2 {\n @include h2-typography();\n @include h2-spacing();\n}\n\nh3 {\n @include h3-typography();\n @include h3-spacing();\n}\n\nh4 {\n @include h4-typography();\n @include h4-spacing();\n}\n\nh5 {\n @include h5-typography();\n @include h5-spacing();\n}\n\nh6 {\n @include h6-typography();\n @include h6-spacing();\n}\n\np {\n @include body-para();\n}\n\na {\n color: $color-primary-normal;\n text-decoration: none;\n}\n\nul,\nol {\n @include blg-spacing(\"block-end\", \"small\", \"margin\");\n @include margin(0, \"block-start\");\n}\n\ndl {\n @include blg-spacing(\"block-end\", \"small\", \"margin\");\n @include margin(0, \"block-start\");\n}\n\nli,\ndt,\ndd {\n @include body-typography();\n}\n\ndt {\n font-weight: bold;\n\n dd + & {\n @include blg-spacing(\"block-start\", \"small\", \"margin\");\n }\n}\n\ndd {\n @include margin(0, \"inline-start\");\n}\n\nsmall {\n @include small-typography();\n @include small-spacing();\n}\n\nsub {\n @include font-variant-position(sub);\n}\n\nsup {\n @include font-variant-position(super);\n}\n\naddress {\n @include small-typography();\n @include small-spacing();\n}\n\nimg {\n @include max-block-size(100%);\n @include max-inline-size(100%);\n}\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\np {\n img {\n @include inline-image();\n }\n}\n\n:lang(ja) {\n @at-root {\n em#{&} {\n font-style: normal;\n text-emphasis-style: open sesame;\n text‑emphasis‑position: over right;\n }\n\n strong#{&} {\n font-style: normal;\n text-emphasis-style: filled sesame;\n text‑emphasis‑position: over right;\n }\n\n u#{&} {\n text-underline-position: right;\n }\n }\n}\n\n:lang(ko) {\n @at-root {\n em#{&} {\n font-style: normal;\n text-decoration: underline;\n text-underline-position: under right;\n }\n\n strong#{&} {\n font-style: normal;\n text-emphasis-style: filled dot;\n text‑emphasis‑position: over right;\n }\n }\n}\n\n:lang(zh) {\n @at-root {\n em#{&} {\n font-style: normal;\n text-emphasis-style: open dot;\n text‑emphasis‑position: under right;\n }\n\n strong#{&} {\n font-style: normal;\n text-emphasis-style: filled dot;\n text‑emphasis‑position: under right;\n }\n\n cite#{&} {\n font-style: normal;\n text-decoration: underline;\n text-underline-style: wavy;\n }\n }\n}\n\n:lang(zh-Hant) {\n @at-root {\n em#{&} {\n text‑emphasis‑position: over right;\n }\n\n strong#{&} {\n text‑emphasis‑position: over right;\n }\n }\n}\n","@import \"logical-properties\";\n@import \"validation\";\n@import \"sizes\";\n@import \"types\";\n@import \"../functions/validation\";\n@import \"../mixins/media-query\";\n@import \"../variables/baselinegrid\";\n@import \"../variables/breakpoint\";\n@import \"../variables/grid\";\n\n// Fallbacks for CSS logical properties contained within this mixin require the following treatment of HTML dir attributes:\n// - document level: always specified, via the HTML element\n// - block level: specified on every element within a block describing a direction switch.\n//\n// For example:\n// \n// ...\n//
\n// Doesn't need a dir attribute. Most cases will be like this.\n//
\n//\n//
\n//\n// This block changes the text direction. Every descendant element must have its own dir attribute....\n//\n//
... even if the direction doesn't change.
\n//\n//
But obviously also when it does.
\n//\n//
\n@mixin _spacing($sizes, $space-type, $dimension: \"\") {\n\n @if $dimension == \"\" {\n\n @include _expect_at_most($sizes, 4, \"More than four sizes supplied when no dimension\") {\n @include rem($space-type, $sizes);\n }\n\n } @else if $dimension == \"inline\" {\n\n @include _expect_at_most($sizes, 2, \"More than two sizes supplied with 'inline' dimension\") {\n @include logical-property($space-type, $dimension, $sizes);\n }\n\n } @else if $dimension == \"inline-start\" {\n\n @include _expect_single_value($sizes, \"More than one size supplied with 'inline-start' dimension\") {\n @include logical-property($space-type, $dimension, $sizes);\n }\n\n } @else if $dimension == \"inline-end\" {\n\n @include _expect_single_value($sizes, \"More than one size supplied with 'inline-end' dimension\") {\n @include logical-property($space-type, $dimension, $sizes);\n }\n\n } @else if $dimension == \"block\" {\n\n @include _expect_at_most($sizes, 2, \"More than two sizes supplied with 'block' dimension\") {\n @include logical-property($space-type, $dimension, $sizes);\n }\n\n } @else if $dimension == \"block-start\" {\n\n @include _expect_single_value($sizes, \"More than one size supplied with 'block-start' dimension\") {\n @include logical-property($space-type, $dimension, $sizes);\n }\n\n } @else if $dimension == \"block-end\" {\n\n @include _expect_single_value($sizes, \"More than one size supplied with 'block-end' dimension\") {\n @include logical-property($space-type, $dimension, $sizes);\n }\n\n } @else if index((\"top\", \"bottom\", \"left\", \"right\"), $dimension) {\n @include _error(\"'#{$dimension}' is a physical dimension, use its logical equivilant\");\n } @else {\n @include _error(\"Unknown dimension '#{$dimension}'\");\n }\n\n}\n\n@mixin padding($sizes, $dimension: \"\") {\n @include _spacing($sizes, padding, $dimension);\n}\n\n@mixin margin($sizes, $dimension: \"\") {\n @include _spacing($sizes, margin, $dimension);\n}\n\n@mixin nospace($dimension: \"\") {\n @include margin(0, $dimension);\n @include padding(0, $dimension);\n}\n\n// blg stands for \"baseline grid\"\n\n@mixin blg-spacing($dimension, $level, $type: \"padding\") {\n @if $type == \"padding\" {\n @if $level == \"extra-small\" {\n @include padding($baselinegrid-space-extra-small, $dimension);\n } @else if $level == \"small\" {\n @include padding($baselinegrid-space-small, $dimension);\n } @else if $level == \"smallish\" {\n @include padding($baselinegrid-space-smallish, $dimension);\n } @else if $level == \"medium\" {\n @include padding($baselinegrid-space-medium, $dimension);\n } @else if $level == \"large\" {\n @include padding($baselinegrid-space-large, $dimension);\n }\n } @else if $type == \"margin\" {\n @if $level == \"extra-small\" {\n @include margin($baselinegrid-space-extra-small, $dimension);\n } @else if $level == \"small\" {\n @include margin($baselinegrid-space-small, $dimension);\n } @else if $level == \"smallish\" {\n @include margin($baselinegrid-space-smallish, $dimension);\n } @else if $level == \"medium\" {\n @include margin($baselinegrid-space-medium, $dimension);\n } @else if $level == \"large\" {\n @include margin($baselinegrid-space-large, $dimension);\n }\n }\n}\n\n@mixin blg-pad-top--small-to-medium {\n\n @include blg-spacing(\"block-start\", \"small\");\n\n @include mq($from: medium) {\n @include blg-spacing(\"block-start\", \"medium\");\n }\n\n}\n\n@mixin blg-pad-bottom--small-to-medium {\n\n @include blg-spacing(\"block-end\", \"small\");\n\n @include mq($from: medium) {\n @include blg-spacing(\"block-end\", \"medium\");\n }\n\n}\n\n@mixin blg-pad-top--large-to-extra-large {\n\n @include blg-spacing(\"block-start\", \"large\");\n\n @include mq($from: medium) {\n @include blg-spacing(\"block-start\", \"extra-large\");\n }\n\n}\n\n@mixin blg-pad-bottom--large-to-extra-large {\n\n @include blg-spacing(\"block-end\", \"large\");\n\n @include mq($from: medium) {\n @include blg-spacing(\"block-end\", \"extra-large\");\n }\n\n}\n\n@mixin blg-pad-vertical-small-to-medium {\n @include blg-pad-top--small-to-medium();\n @include blg-pad-bottom--small-to-medium();\n}\n\n@mixin blg-pad-vertical-large-to-extra-large {\n @include blg-pad-top--large-to-extra-large();\n @include blg-pad-bottom--large-to-extra-large();\n}\n\n@mixin blg-margin-bottom--medium-to-large {\n\n @include blg-spacing(\"block-end\", \"medium\", \"margin\");\n\n @include mq($from: medium) {\n @include blg-spacing(\"block-end\", \"large\", \"margin\");\n }\n\n}\n\n@mixin blg-margin-bottom--small-to-medium {\n\n @include blg-spacing(\"block-end\", \"small\", \"margin\");\n\n @include mq($from: medium) {\n @include blg-spacing(\"block-end\", \"medium\", \"margin\");\n }\n\n}\n\n@mixin blg-column-container() {\n @include blg-margin-bottom--medium-to-large();\n}\n\n@mixin h1-spacing() {\n margin: 0;\n}\n\n@mixin h2-spacing() {\n margin: 0;\n @include padding(21px, \"block-end\");\n @include padding(21px, \"block-start\");\n}\n\n@mixin h3-spacing() {\n margin: 0;\n @include blg-spacing(\"block-start\", \"extra-small\");\n @include blg-spacing(\"block-end\", \"extra-small\");\n}\n\n@mixin h4-spacing() {\n margin: 0;\n @include blg-spacing(\"block-start\", \"extra-small\");\n @include blg-spacing(\"block-end\", \"extra-small\");\n}\n\n@mixin h5-spacing() {\n margin: 0;\n @include blg-spacing(\"block-start\", \"extra-small\");\n @include blg-spacing(\"block-end\", \"extra-small\");\n}\n\n@mixin h6-spacing() {\n margin: 0;\n @include padding(10px, \"block-start\");\n @include padding(14px, \"block-end\");\n}\n\n@mixin body-spacing() {\n margin: 0;\n @include blg-spacing(\"block-end\", \"small\", \"margin\");\n}\n\n@mixin small-spacing() {\n @include blg-spacing(\"block-end\", \"small\");\n}\n","@import \"types\";\n@import \"validation\";\n\n@mixin _when-left-to-right {\n html[dir=\"ltr\"] &:not([dir]),\n &[dir=\"ltr\"] {\n @content;\n }\n}\n\n@mixin _when-right-to-left {\n html[dir=\"rtl\"] &:not([dir]),\n &[dir=\"rtl\"] {\n @content;\n }\n}\n\n@mixin _when-logical {\n html[dir][dir] & {\n @content;\n }\n}\n\n@mixin _maybe-rem($to-rem, $properties, $values: ()) {\n @if ($to-rem == false) {\n @if type-of($properties) == \"map\" {\n @each $property in map-keys($properties) {\n @include _maybe-rem($to-rem, $property, map-get($properties, $property));\n }\n } @else {\n @each $property in $properties {\n #{$property}: $values;\n }\n }\n } @else {\n @include rem($properties, $values...);\n }\n}\n\n@function _maybe-rem($to-rem, $values) {\n @if ($to-rem == false) {\n @return $values;\n } @else {\n @return rem($values...);\n }\n}\n\n@function _property-name($parts, $dimension) {\n @if (length($parts) == 0 or $parts == \"\") {\n @return $dimension;\n }\n\n @if (length($parts) == 1) {\n @return \"#{$parts}-#{$dimension}\";\n }\n\n @return \"#{nth($parts, 1)}-#{$dimension}-#{nth($parts, 2)}\";\n}\n\n@mixin logical-property($property-name, $dimension, $arguments, $to-rem: true) {\n\n @if length($property-name) > 2 {\n @include _error(\"Expected at most two property name parts\");\n } @else if $dimension == inline {\n\n @if type-of($arguments) == \"list\" and length($arguments) > 1 {\n\n @include _expect_at_most($arguments, 2, \"More than two arguments supplied with 'inline' dimension\") {\n\n $firstArgument: nth($arguments, 1);\n $secondArgument: nth($arguments, 2);\n\n @if $firstArgument == $secondArgument {\n\n @include _maybe-rem($to-rem, (\n #{_property-name($property-name, left)}: $firstArgument,\n #{_property-name($property-name, right)}: $firstArgument,\n ));\n #{_property-name($property-name, inline)}: _maybe-rem($to-rem, $firstArgument);\n\n } @else {\n\n @include _when-left-to-right() {\n @include _maybe-rem($to-rem, _property-name($property-name, left), $firstArgument);\n @include _maybe-rem($to-rem, _property-name($property-name, right), $secondArgument);\n }\n\n @include _when-right-to-left() {\n @include _maybe-rem($to-rem, _property-name($property-name, right), $firstArgument);\n @include _maybe-rem($to-rem, _property-name($property-name, left), $secondArgument);\n }\n\n @include _when-logical() {\n #{_property-name($property-name, inline-start)}: _maybe-rem($to-rem, $firstArgument);\n #{_property-name($property-name, inline-end)}: _maybe-rem($to-rem, $secondArgument);\n }\n\n }\n\n }\n\n } @else {\n\n @include _maybe-rem($to-rem, (\n #{_property-name($property-name, left)}: $arguments,\n #{_property-name($property-name, right)}: $arguments,\n ));\n #{_property-name($property-name, inline)}: _maybe-rem($to-rem, $arguments);\n\n }\n\n } @else if $dimension == inline-start {\n\n @include _when-left-to-right() {\n @include _maybe-rem($to-rem, _property-name($property-name, left), $arguments);\n }\n\n @include _when-right-to-left() {\n @include _maybe-rem($to-rem, _property-name($property-name, right), $arguments);\n }\n\n @include _when_logical() {\n #{_property-name($property-name, inline-start)}: _maybe-rem($to-rem, $arguments);\n }\n\n } @else if $dimension == inline-end {\n\n @include _when-left-to-right() {\n @include _maybe-rem($to-rem, _property-name($property-name, right), $arguments);\n }\n\n @include _when-right-to-left() {\n @include _maybe-rem($to-rem, _property-name($property-name, left), $arguments);\n }\n\n @include _when_logical() {\n #{_property-name($property-name, inline-end)}: _maybe-rem($to-rem, $arguments);\n }\n\n } @else if $dimension == inline-size {\n\n @include _maybe-rem($to-rem, _property-name($property-name, width), $arguments);\n #{_property-name($property-name, inline-size)}: _maybe-rem($to-rem, $arguments);\n\n } @else if $dimension == block {\n\n @if type-of($arguments) == \"list\" and length($arguments) > 1 {\n\n @include _expect_at_most($arguments, 2, \"More than two arguments supplied with 'block' dimension\") {\n\n $firstArgument: nth($arguments, 1);\n $secondArgument: nth($arguments, 2);\n\n @if $firstArgument == $secondArgument {\n\n @include _maybe-rem($to-rem, (\n #{_property-name($property-name, top)}: $firstArgument,\n #{_property-name($property-name, bottom)}: $firstArgument,\n ));\n #{_property-name($property-name, block)}: _maybe-rem($to-rem, $firstArgument);\n\n } @else {\n\n @include _maybe-rem($to-rem, (\n #{_property-name($property-name, top)}: $firstArgument,\n #{_property-name($property-name, bottom)}: $secondArgument,\n ));\n #{_property-name($property-name, block-start)}: _maybe-rem($to-rem, $firstArgument);\n #{_property-name($property-name, block-end)}: _maybe-rem($to-rem, $secondArgument);\n\n }\n\n }\n\n } @else {\n\n @include _maybe-rem($to-rem, (\n #{_property-name($property-name, top)}: $arguments,\n #{_property-name($property-name, bottom)}: $arguments,\n ));\n #{_property-name($property-name, block)}: _maybe-rem($to-rem, $arguments);\n\n }\n\n } @else if $dimension == block-start {\n\n @include _maybe-rem($to-rem, _property-name($property-name, top), $arguments);\n #{_property-name($property-name, block-start)}: _maybe-rem($to-rem, $arguments);\n\n } @else if $dimension == block-end {\n\n @include _maybe-rem($to-rem, _property-name($property-name, bottom), $arguments);\n #{_property-name($property-name, block-end)}: _maybe-rem($to-rem, $arguments);\n\n } @else if $dimension == block-size {\n\n @include _maybe-rem($to-rem, _property-name($property-name, height), $arguments);\n #{_property-name($property-name, block-size)}: _maybe-rem($to-rem, $arguments);\n\n } @else if index((top, bottom, left, right, width, height), $dimension) {\n @include _error(\"'#{$dimension}' is a physical dimension, use its logical equivilant\");\n } @else {\n @include _error(\"Unknown dimension '#{$dimension}'\");\n }\n\n}\n","@import \"../variables/font\";\n@import \"../vendor/sass-rem/rem\";\n\n$rem-baseline: $font-size-base;\n$rem-fallback: true;\n\n// Overridden to apply https://github.com/pierreburel/sass-rem/pull/12\n@mixin rem($properties, $values...) {\n\n @if type-of($properties) == \"map\" {\n\n @each $property in map-keys($properties) {\n @include rem($property, map-get($properties, $property));\n }\n\n } @else {\n\n $convert: false;\n @each $valueList in $values {\n @each $value in $valueList {\n @if type-of($value) == \"number\" and index((rem, px), unit($value)) {\n $convert: true;\n }\n }\n }\n\n @each $property in $properties {\n @if $convert == true {\n @if $rem-fallback or $rem-px-only {\n #{$property}: rem-convert(px, $values...);\n }\n @if not $rem-px-only {\n #{$property}: rem-convert(rem, $values...);\n }\n } @else if $rem-px-only {\n #{$property}: rem-convert(px, $values...);\n } @else {\n #{$property}: $values;\n }\n }\n\n }\n\n}\n","$font-size-base: 16px;\n$font-size-h1: 36px;\n$font-size-h2: 26px;\n$font-size-h3: 22px;\n$font-size-h4: 20px;\n$font-size-h5: 18px;\n$font-size-h6: 16px;\n$font-size-caption: 13px;\n$font-size-label: 11px;\n$font-letterspacing-label: 0.5px;\n$font-primary: \"Noto Serif\", serif;\n$font-secondary: \"Noto Sans\", Arial, Helvetica, sans-serif;\n$font-monospace: \"Courier 10 Pitch\", Courier, monospace;\n","$rem-baseline: 16px !default;\n$rem-fallback: false !default;\n$rem-px-only: false !default;\n\n@function rem-separator($list, $separator: false) {\n @if $separator == \"comma\" or $separator == \"space\" {\n @return append($list, null, $separator);\n } \n \n @if function-exists(\"list-separator\") == true {\n @return list-separator($list);\n }\n\n // list-separator polyfill by Hugo Giraudel (https://sass-compatibility.github.io/#list_separator_function)\n $test-list: ();\n @each $item in $list {\n $test-list: append($test-list, $item, space);\n }\n\n @return if($test-list == $list, space, comma);\n}\n\n@mixin rem-baseline($zoom: 100%) {\n font-size: $zoom / 16px * $rem-baseline;\n}\n\n@function rem-convert($to, $values...) {\n $result: ();\n $separator: rem-separator($values);\n \n @each $value in $values {\n @if type-of($value) == \"number\" and unit($value) == \"rem\" and $to == \"px\" {\n $result: append($result, $value / 1rem * $rem-baseline, $separator);\n } @else if type-of($value) == \"number\" and unit($value) == \"px\" and $to == \"rem\" {\n $result: append($result, $value / $rem-baseline * 1rem, $separator);\n } @else if type-of($value) == \"list\" {\n $value-separator: rem-separator($value);\n $value: rem-convert($to, $value...);\n $value: rem-separator($value, $value-separator);\n $result: append($result, $value, $separator);\n } @else {\n $result: append($result, $value, $separator);\n }\n }\n\n @return if(length($result) == 1, nth($result, 1), $result);\n}\n\n@function rem($values...) {\n @if $rem-px-only {\n @return rem-convert(px, $values...);\n } @else {\n @return rem-convert(rem, $values...);\n }\n}\n\n@mixin rem($properties, $values...) {\n @if type-of($properties) == \"map\" {\n @each $property in map-keys($properties) {\n @include rem($property, map-get($properties, $property));\n }\n } @else {\n @each $property in $properties {\n @if $rem-fallback or $rem-px-only {\n #{$property}: rem-convert(px, $values...);\n }\n @if not $rem-px-only {\n #{$property}: rem-convert(rem, $values...);\n }\n }\n }\n}\n","@import \"../functions/validation\";\n\n@mixin _error($message) {\n _error: _error($message);\n}\n\n@mixin _expect_at_most($value, $maxLength, $message: \"Expected at most #{$maxLength} values\") {\n\n @if length($value) > $maxLength {\n @include _error($message);\n } @else {\n @content;\n }\n\n}\n\n@mixin _expect_single_value($value, $message: \"Expected a single value\") {\n\n @include _expect_at_most($value, 1, $message) {\n @content;\n }\n\n}\n","$_is-test: false !default;\n\n@function _error($message, $capture: $_is-test) {\n @if $capture {\n @return $message;\n }\n\n @error $message;\n}\n","@import \"logical-properties\";\n@import \"types\";\n@import \"validation\";\n\n@mixin block-size($size) {\n @include _expect_single_value($size) {\n @include logical-property(\"\", block-size, ($size));\n }\n}\n\n@mixin inline-size($size) {\n @include _expect_single_value($size) {\n @include logical-property(\"\", inline-size, ($size));\n }\n}\n\n@mixin _constrain-block-size($size, $extreme) {\n @include logical-property($extreme, block-size, ($size));\n}\n\n@mixin _constrain-inline-size($size, $extreme) {\n @include logical-property($extreme, inline-size, ($size));\n}\n\n@mixin max-block-size($size) {\n @include _expect_single_value($size) {\n @include _constrain-block-size($size, max);\n }\n}\n\n@mixin min-block-size($size) {\n @include _expect_single_value($size) {\n @include _constrain-block-size($size, min);\n }\n}\n\n@mixin max-inline-size($size) {\n @include _expect_single_value($size) {\n @include _constrain-inline-size($size, max);\n }\n}\n\n@mixin min-inline-size($size) {\n @include _expect_single_value($size) {\n @include _constrain-inline-size($size, min);\n }\n}\n\n@mixin truncate-with-ellipsis() {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n\n &:lang(zh-Hant-HK) {\n text-overflow: \"⋯\";\n }\n}\n","@import \"../variables/breakpoint\";\n@import \"../variables/font\";\n\n$mq-base-font-size: $font-size-base;\n\n$mq-breakpoints: (\n x-small: $breakpoint-site-x_small,\n small: $breakpoint-site-small,\n medium: $breakpoint-site-medium,\n wide: $breakpoint-site-wide,\n x-wide: $breakpoint-site-x_wide,\n);\n\n@import \"../vendor/sass-mq/_mq\";\n","$breakpoint-site-x_small: 320px;\n$breakpoint-site-small: 480px;\n$breakpoint-site-medium: 730px;\n$breakpoint-site-wide: 900px;\n$breakpoint-site-x_wide: 1200px;\n","@charset \"UTF-8\"; // Fixes an issue where Ruby locale is not set properly\n // See https://github.com/sass-mq/sass-mq/pull/10\n\n/// Base font size on the `` element\n/// @type Number (unit)\n$mq-base-font-size: 16px !default;\n\n/// Responsive mode\n///\n/// Set to `false` to enable support for browsers that do not support @media queries,\n/// (IE <= 8, Firefox <= 3, Opera <= 9)\n///\n/// You could create a stylesheet served exclusively to older browsers,\n/// where @media queries are rasterized\n///\n/// @example scss\n/// // old-ie.scss\n/// $mq-responsive: false;\n/// @import 'main'; // @media queries in this file will be rasterized up to $mq-static-breakpoint\n/// // larger breakpoints will be ignored\n///\n/// @type Boolean\n/// @link https://github.com/sass-mq/sass-mq#responsive-mode-off Disabled responsive mode documentation\n$mq-responsive: true !default;\n\n/// Breakpoint list\n///\n/// Name your breakpoints in a way that creates a ubiquitous language\n/// across team members. It will improve communication between\n/// stakeholders, designers, developers, and testers.\n///\n/// @type Map\n/// @link https://github.com/sass-mq/sass-mq#seeing-the-currently-active-breakpoint Full documentation and examples\n$mq-breakpoints: (\n mobile: 320px,\n tablet: 740px,\n desktop: 980px,\n wide: 1300px\n) !default;\n\n/// Static breakpoint (for fixed-width layouts)\n///\n/// Define the breakpoint from $mq-breakpoints that should\n/// be used as the target width for the fixed-width layout\n/// (i.e. when $mq-responsive is set to 'false') in a old-ie.scss\n///\n/// @example scss\n/// // tablet-only.scss\n/// //\n/// // Ignore all styles above tablet breakpoint,\n/// // and fix the styles (e.g. layout) at tablet width\n/// $mq-responsive: false;\n/// $mq-static-breakpoint: tablet;\n/// @import 'main'; // @media queries in this file will be rasterized up to tablet\n/// // larger breakpoints will be ignored\n///\n/// @type String\n/// @link https://github.com/sass-mq/sass-mq#adding-custom-breakpoints Full documentation and examples\n$mq-static-breakpoint: desktop !default;\n\n/// Show breakpoints in the top right corner\n///\n/// If you want to display the currently active breakpoint in the top\n/// right corner of your site during development, add the breakpoints\n/// to this list, ordered by width, e.g. (mobile, tablet, desktop).\n///\n/// @type map\n$mq-show-breakpoints: () !default;\n\n/// Customize the media type (e.g. `@media screen` or `@media print`)\n/// By default sass-mq uses an \"all\" media type (`@media all and …`)\n///\n/// @type String\n/// @link https://github.com/sass-mq/sass-mq#changing-media-type Full documentation and examples\n$mq-media-type: all !default;\n\n/// Convert pixels to ems\n///\n/// @param {Number} $px - value to convert\n/// @param {Number} $base-font-size ($mq-base-font-size) - `` font size\n///\n/// @example scss\n/// $font-size-in-ems: mq-px2em(16px);\n/// p { font-size: mq-px2em(16px); }\n///\n/// @requires $mq-base-font-size\n/// @returns {Number}\n@function mq-px2em($px, $base-font-size: $mq-base-font-size) {\n @if unitless($px) {\n @warn \"Assuming #{$px} to be in pixels, attempting to convert it into pixels.\";\n @return mq-px2em($px * 1px, $base-font-size);\n } @else if unit($px) == em {\n @return $px;\n }\n @return ($px / $base-font-size) * 1em;\n}\n\n/// Get a breakpoint's width\n///\n/// @param {String} $name - Name of the breakpoint. One of $mq-breakpoints\n///\n/// @example scss\n/// $tablet-width: mq-get-breakpoint-width(tablet);\n/// @media (min-width: mq-get-breakpoint-width(desktop)) {}\n///\n/// @requires {Variable} $mq-breakpoints\n///\n/// @returns {Number} Value in pixels\n@function mq-get-breakpoint-width($name, $breakpoints: $mq-breakpoints) {\n @if map-has-key($breakpoints, $name) {\n @return map-get($breakpoints, $name);\n } @else {\n @warn \"Breakpoint #{$name} wasn't found in $breakpoints.\";\n }\n}\n\n/// Media Query mixin\n///\n/// @param {String | Boolean} $from (false) - One of $mq-breakpoints\n/// @param {String | Boolean} $until (false) - One of $mq-breakpoints\n/// @param {String | Boolean} $and (false) - Additional media query parameters\n/// @param {String} $media-type ($mq-media-type) - Media type: screen, print…\n///\n/// @ignore Undocumented API, for advanced use only:\n/// @ignore @param {Map} $breakpoints ($mq-breakpoints)\n/// @ignore @param {String} $static-breakpoint ($mq-static-breakpoint)\n///\n/// @content styling rules, wrapped into a @media query when $responsive is true\n///\n/// @requires {Variable} $mq-media-type\n/// @requires {Variable} $mq-breakpoints\n/// @requires {Variable} $mq-static-breakpoint\n/// @requires {function} mq-px2em\n/// @requires {function} mq-get-breakpoint-width\n///\n/// @link https://github.com/sass-mq/sass-mq#responsive-mode-on-default Full documentation and examples\n///\n/// @example scss\n/// .element {\n/// @include mq($from: mobile) {\n/// color: red;\n/// }\n/// @include mq($until: tablet) {\n/// color: blue;\n/// }\n/// @include mq(mobile, tablet) {\n/// color: green;\n/// }\n/// @include mq($from: tablet, $and: '(orientation: landscape)') {\n/// color: teal;\n/// }\n/// @include mq(950px) {\n/// color: hotpink;\n/// }\n/// @include mq(tablet, $media-type: screen) {\n/// color: hotpink;\n/// }\n/// // Advanced use:\n/// $my-breakpoints: (L: 900px, XL: 1200px);\n/// @include mq(L, $breakpoints: $my-breakpoints, $static-breakpoint: L) {\n/// color: hotpink;\n/// }\n/// }\n@mixin mq(\n $from: false,\n $until: false,\n $and: false,\n $media-type: $mq-media-type,\n $breakpoints: $mq-breakpoints,\n $responsive: $mq-responsive,\n $static-breakpoint: $mq-static-breakpoint\n) {\n $min-width: 0;\n $max-width: 0;\n $media-query: '';\n\n // From: this breakpoint (inclusive)\n @if $from {\n @if type-of($from) == number {\n $min-width: mq-px2em($from);\n } @else {\n $min-width: mq-px2em(mq-get-breakpoint-width($from, $breakpoints));\n }\n }\n\n // Until: that breakpoint (exclusive)\n @if $until {\n @if type-of($until) == number {\n $max-width: mq-px2em($until);\n } @else {\n $max-width: mq-px2em(mq-get-breakpoint-width($until, $breakpoints)) - .01em;\n }\n }\n\n // Responsive support is disabled, rasterize the output outside @media blocks\n // The browser will rely on the cascade itself.\n @if $responsive == false {\n $static-breakpoint-width: mq-get-breakpoint-width($static-breakpoint, $breakpoints);\n $target-width: mq-px2em($static-breakpoint-width);\n\n // Output only rules that start at or span our target width\n @if (\n $and == false\n and $min-width <= $target-width\n and (\n $until == false or $max-width >= $target-width\n )\n and $media-type != 'print'\n ) {\n @content;\n }\n }\n\n // Responsive support is enabled, output rules inside @media queries\n @else {\n @if $min-width != 0 { $media-query: '#{$media-query} and (min-width: #{$min-width})'; }\n @if $max-width != 0 { $media-query: '#{$media-query} and (max-width: #{$max-width})'; }\n @if $and { $media-query: '#{$media-query} and #{$and}'; }\n\n // Remove unnecessary media query prefix 'all and '\n @if ($media-type == 'all' and $media-query != '') {\n $media-type: '';\n $media-query: str-slice(unquote($media-query), 6);\n }\n\n @media #{$media-type + $media-query} {\n @content;\n }\n }\n}\n\n/// Quick sort\n///\n/// @author Sam Richards\n/// @access private\n/// @param {List} $list - List to sort\n/// @returns {List} Sorted List\n@function _mq-quick-sort($list) {\n $less: ();\n $equal: ();\n $large: ();\n\n @if length($list) > 1 {\n $seed: nth($list, ceil(length($list) / 2));\n\n @each $item in $list {\n @if ($item == $seed) {\n $equal: append($equal, $item);\n } @else if ($item < $seed) {\n $less: append($less, $item);\n } @else if ($item > $seed) {\n $large: append($large, $item);\n }\n }\n\n @return join(join(_mq-quick-sort($less), $equal), _mq-quick-sort($large));\n }\n\n @return $list;\n}\n\n/// Sort a map by values (works with numbers only)\n///\n/// @access private\n/// @param {Map} $map - Map to sort\n/// @returns {Map} Map sorted by value\n@function _mq-map-sort-by-value($map) {\n $map-sorted: ();\n $map-keys: map-keys($map);\n $map-values: map-values($map);\n $map-values-sorted: _mq-quick-sort($map-values);\n\n // Reorder key/value pairs based on key values\n @each $value in $map-values-sorted {\n $index: index($map-values, $value);\n $key: nth($map-keys, $index);\n $map-sorted: map-merge($map-sorted, ($key: $value));\n\n // Unset the value in $map-values to prevent the loop\n // from finding the same index twice\n $map-values: set-nth($map-values, $index, 0);\n }\n\n @return $map-sorted;\n}\n\n/// Add a breakpoint\n///\n/// @param {String} $name - Name of the breakpoint\n/// @param {Number} $width - Width of the breakpoint\n///\n/// @requires {Variable} $mq-breakpoints\n///\n/// @example scss\n/// @include mq-add-breakpoint(tvscreen, 1920px);\n/// @include mq(tvscreen) {}\n@mixin mq-add-breakpoint($name, $width) {\n $new-breakpoint: ($name: $width);\n $mq-breakpoints: map-merge($mq-breakpoints, $new-breakpoint) !global;\n $mq-breakpoints: _mq-map-sort-by-value($mq-breakpoints) !global;\n}\n\n/// Show the active breakpoint in the top right corner of the viewport\n/// @link https://github.com/sass-mq/sass-mq#seeing-the-currently-active-breakpoint\n///\n/// @param {List} $show-breakpoints ($mq-show-breakpoints) - List of breakpoints to show in the top right corner\n/// @param {Map} $breakpoints ($mq-breakpoints) - Breakpoint names and sizes\n///\n/// @requires {Variable} $mq-breakpoints\n/// @requires {Variable} $mq-show-breakpoints\n///\n/// @example scss\n/// // Show breakpoints using global settings\n/// @include mq-show-breakpoints;\n///\n/// // Show breakpoints using custom settings\n/// @include mq-show-breakpoints((L, XL), (S: 300px, L: 800px, XL: 1200px));\n@mixin mq-show-breakpoints($show-breakpoints: $mq-show-breakpoints, $breakpoints: $mq-breakpoints) {\n body:before {\n background-color: #FCF8E3;\n border-bottom: 1px solid #FBEED5;\n border-left: 1px solid #FBEED5;\n color: #C09853;\n font: small-caption;\n padding: 3px 6px;\n pointer-events: none;\n position: fixed;\n right: 0;\n top: 0;\n z-index: 100;\n\n // Loop through the breakpoints that should be shown\n @each $show-breakpoint in $show-breakpoints {\n $width: mq-get-breakpoint-width($show-breakpoint, $breakpoints);\n @include mq($show-breakpoint, $breakpoints: $breakpoints) {\n content: \"#{$show-breakpoint} ≥ #{$width} (#{mq-px2em($width)})\";\n }\n }\n }\n}\n\n@if length($mq-show-breakpoints) > 0 {\n @include mq-show-breakpoints;\n}\n","$baselinegrid-space-extra_small: 12px;\n$baselinegrid-space-small: 24px;\n$baselinegrid-space-smallish: 36px;\n$baselinegrid-space-medium: 48px;\n$baselinegrid-space-large: 72px;\n$baselinegrid-space-extra_large: 120px;\n","$grid-edge_space-medium: 7vw;\n$grid-edge_space-large: 14vw;\n$grid-min_width: 320px;\n$grid-max_width: 1114px;\n$grid-main_column_count: 12;\n$grid-column_gap: 1.6%;\n","@import \"../mixins/types\";\n@import \"../variables/baselinegrid\";\n@import \"../variables/color\";\n@import \"../variables/font\";\n@import \"spacing\";\n@import \"utilities\";\n\n@mixin set-font-size-and-line-height($font-size, $block-size: $baselinegrid-space-small) {\n @include rem(font-size, $font-size);\n line-height: $block-size / $font-size;\n}\n\n@mixin _heading-base-typography() {\n font-family: $font-secondary;\n font-weight: 600;\n}\n\n@mixin h1-typography() {\n @include _heading-base-typography();\n @include set-font-size-and-line-height($font-size-h1, 48px);\n}\n\n@mixin h2-typography() {\n @include _heading-base-typography();\n @include set-font-size-and-line-height($font-size-h2, 30px);\n}\n\n@mixin h3-typography() {\n @include _heading-base-typography();\n @include set-font-size-and-line-height($font-size-h3);\n}\n\n@mixin h4-typography() {\n @include _heading-base-typography();\n @include set-font-size-and-line-height($font-size-h4);\n}\n\n@mixin h5-typography() {\n @include _heading-base-typography();\n @include set-font-size-and-line-height($font-size-h5);\n}\n\n@mixin h6-typography() {\n @include _heading-base-typography();\n @include set-font-size-and-line-height($font-size-h6);\n}\n\n@mixin body-typography() {\n font-family: $font-primary;\n @include set-font-size-and-line-height($font-size-base);\n font-weight: normal;\n}\n\n@mixin small-typography() {\n font-family: $font-primary;\n font-style: normal;\n @include set-font-size-and-line-height(11px);\n}\n\n@mixin body-para {\n @include body-typography();\n @include body-spacing();\n}\n\n@mixin inline-image {\n @include margin(0.1em, \"block-end\");\n @include max-block-size(1em);\n vertical-align: middle;\n}\n\n@mixin _base-font-variant-position($position) {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n @supports (font-variant-position: #{$position}) {\n font-size: inherit;\n font-variant-position: $position;\n position: static;\n }\n}\n\n@mixin font-variant-position($position) {\n @if $position == sub {\n @include _base_font-variant-position($position);\n bottom: -0.25em; // stylelint-disable-line csstools/use-logical\n } @else if $position == super {\n @include _base_font-variant-position($position);\n top: -0.5em; // stylelint-disable-line csstools/use-logical\n } @else {\n @include _error(\"Unknown position '#{$position}'\");\n }\n}\n\n@mixin _label-typography($color, $uppercase: true) {\n color: $color;\n font-family: $font-secondary;\n font-weight: normal;\n @include set-font-size-and-line-height($font-size-label);\n letter-spacing: $font-letterspacing-label;\n @if $uppercase {\n text-transform: uppercase;\n }\n}\n\n@mixin label-content-typography($color: $color-text-secondary, $uppercase: true) {\n @include _label-typography($color, $uppercase);\n}\n\n@mixin label-tag-typography() {\n @include _label-typography($color-primary-normal);\n}\n\n@mixin covert-link($hover-color: $color-primary-dark) {\n @include inherit-all($ensure: color text-decoration);\n cursor: pointer;\n\n &:hover {\n color: $hover-color;\n }\n}\n\n@mixin list-style-none() {\n @include padding(0, inline-start);\n // Overflow auto is so the bullet will be still read from a screen reader and will push the bullet off screen\n overflow: auto;\n}\n","$color-primary-normal: rgb(2, 136, 209);\n$color-primary-light: rgb(179, 229, 252);\n$color-primary-dark: rgb(2, 119, 189);\n$color-text-normal: rgb(33, 33, 33);\n$color-text-reverse: rgb(255, 255, 255);\n$color-text-secondary: rgb(136, 136, 136);\n$color-text-secondary__reverse: rgb(158, 158, 158);\n$color-text-placeholder: rgb(189, 189, 189);\n$color-text-dividers: rgb(224, 224, 224);\n$color-text-dividers__reverse: rgb(97, 97, 97);\n$color-text-ui_background: rgb(255, 255, 255);\n$color-text-ui_background_hue: rgb(245, 245, 245);\n$color-text-ui_code: rgb(247, 247, 247);\n$color-text-ui_background__reverse: rgb(33, 33, 33);\n$color-text-ui_background_hue__reverse: rgb(51, 51, 51);\n$color-background: rgb(255, 255, 255);\n$color-information: rgb(2, 136, 209);\n$color-success: rgb(98, 159, 67);\n$color-success_dark: rgb(86, 144, 55);\n$color-attention: rgb(207, 12, 78);\n$color-warning: rgb(230, 81, 0);\n","@mixin inherit-all($ensure: ()) {\n @each $property in $ensure {\n #{$property}: inherit;\n }\n\n all: inherit;\n}\n","/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */\n\n/* Document\n ========================================================================== */\n\n/**\n * 1. Correct the line height in all browsers.\n * 2. Prevent adjustments of font size after orientation changes in iOS.\n */\n\nhtml {\n line-height: 1.15; /* 1 */\n -webkit-text-size-adjust: 100%; /* 2 */\n}\n\n/* Sections\n ========================================================================== */\n\n/**\n * Remove the margin in all browsers.\n */\n\nbody {\n margin: 0;\n}\n\n/**\n * Render the `main` element consistently in IE.\n */\n\nmain {\n display: block;\n}\n\n/**\n * Correct the font size and margin on `h1` elements within `section` and\n * `article` contexts in Chrome, Firefox, and Safari.\n */\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n/* Grouping content\n ========================================================================== */\n\n/**\n * 1. Add the correct box sizing in Firefox.\n * 2. Show the overflow in Edge and IE.\n */\n\nhr {\n box-sizing: content-box; /* 1 */\n height: 0; /* 1 */\n overflow: visible; /* 2 */\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\npre {\n font-family: monospace, monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/* Text-level semantics\n ========================================================================== */\n\n/**\n * Remove the gray background on active links in IE 10.\n */\n\na {\n background-color: transparent;\n}\n\n/**\n * 1. Remove the bottom border in Chrome 57-\n * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n */\n\nabbr[title] {\n border-bottom: none; /* 1 */\n text-decoration: underline; /* 2 */\n text-decoration: underline dotted; /* 2 */\n}\n\n/**\n * Add the correct font weight in Chrome, Edge, and Safari.\n */\n\nb,\nstrong {\n font-weight: bolder;\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\ncode,\nkbd,\nsamp {\n font-family: monospace, monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/**\n * Add the correct font size in all browsers.\n */\n\nsmall {\n font-size: 80%;\n}\n\n/**\n * Prevent `sub` and `sup` elements from affecting the line height in\n * all browsers.\n */\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -0.25em;\n}\n\nsup {\n top: -0.5em;\n}\n\n/* Embedded content\n ========================================================================== */\n\n/**\n * Remove the border on images inside links in IE 10.\n */\n\nimg {\n border-style: none;\n}\n\n/* Forms\n ========================================================================== */\n\n/**\n * 1. Change the font styles in all browsers.\n * 2. Remove the margin in Firefox and Safari.\n */\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n font-family: inherit; /* 1 */\n font-size: 100%; /* 1 */\n line-height: 1.15; /* 1 */\n margin: 0; /* 2 */\n}\n\n/**\n * Show the overflow in IE.\n * 1. Show the overflow in Edge.\n */\n\nbutton,\ninput { /* 1 */\n overflow: visible;\n}\n\n/**\n * Remove the inheritance of text transform in Edge, Firefox, and IE.\n * 1. Remove the inheritance of text transform in Firefox.\n */\n\nbutton,\nselect { /* 1 */\n text-transform: none;\n}\n\n/**\n * Correct the inability to style clickable types in iOS and Safari.\n */\n\nbutton,\n[type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\n/**\n * Remove the inner border and padding in Firefox.\n */\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n border-style: none;\n padding: 0;\n}\n\n/**\n * Restore the focus styles unset by the previous rule.\n */\n\nbutton:-moz-focusring,\n[type=\"button\"]:-moz-focusring,\n[type=\"reset\"]:-moz-focusring,\n[type=\"submit\"]:-moz-focusring {\n outline: 1px dotted ButtonText;\n}\n\n/**\n * Correct the padding in Firefox.\n */\n\nfieldset {\n padding: 0.35em 0.75em 0.625em;\n}\n\n/**\n * 1. Correct the text wrapping in Edge and IE.\n * 2. Correct the color inheritance from `fieldset` elements in IE.\n * 3. Remove the padding so developers are not caught out when they zero out\n * `fieldset` elements in all browsers.\n */\n\nlegend {\n box-sizing: border-box; /* 1 */\n color: inherit; /* 2 */\n display: table; /* 1 */\n max-width: 100%; /* 1 */\n padding: 0; /* 3 */\n white-space: normal; /* 1 */\n}\n\n/**\n * Add the correct vertical alignment in Chrome, Firefox, and Opera.\n */\n\nprogress {\n vertical-align: baseline;\n}\n\n/**\n * Remove the default vertical scrollbar in IE 10+.\n */\n\ntextarea {\n overflow: auto;\n}\n\n/**\n * 1. Add the correct box sizing in IE 10.\n * 2. Remove the padding in IE 10.\n */\n\n[type=\"checkbox\"],\n[type=\"radio\"] {\n box-sizing: border-box; /* 1 */\n padding: 0; /* 2 */\n}\n\n/**\n * Correct the cursor style of increment and decrement buttons in Chrome.\n */\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n/**\n * 1. Correct the odd appearance in Chrome and Safari.\n * 2. Correct the outline style in Safari.\n */\n\n[type=\"search\"] {\n -webkit-appearance: textfield; /* 1 */\n outline-offset: -2px; /* 2 */\n}\n\n/**\n * Remove the inner padding in Chrome and Safari on macOS.\n */\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n/**\n * 1. Correct the inability to style clickable types in iOS and Safari.\n * 2. Change font properties to `inherit` in Safari.\n */\n\n::-webkit-file-upload-button {\n -webkit-appearance: button; /* 1 */\n font: inherit; /* 2 */\n}\n\n/* Interactive\n ========================================================================== */\n\n/*\n * Add the correct display in Edge, IE 10+, and Firefox.\n */\n\ndetails {\n display: block;\n}\n\n/*\n * Add the correct display in all browsers.\n */\n\nsummary {\n display: list-item;\n}\n\n/* Misc\n ========================================================================== */\n\n/**\n * Add the correct display in IE 10+.\n */\n\ntemplate {\n display: none;\n}\n\n/**\n * Add the correct display in IE 10.\n */\n\n[hidden] {\n display: none;\n}\n","@import \"mixins/logical-properties\";\n@import \"mixins/media-query\";\n@import \"variables/grid\";\n\n:root {\n --GRID-COLUMN-GAP: #{$grid-column_gap};\n --GRID-EDGE-SPACE: #{$grid-edge_space-medium};\n --GRID-COLUMN-WIDTH: calc((100% - (var(--GRID-EDGE-SPACE) * 2) - (var(--GRID-COLUMN-GAP) * #{$grid-main_column_count - 1})) / #{$grid-main_column_count});\n\n @include mq($from: medium) {\n --GRID-EDGE-SPACE: #{$grid-edge_space-large};\n }\n\n @include mq($from: x-wide) {\n --GRID-COLUMN-GAP: #{($grid-max_width * $grid-column_gap) / 100%};\n --GRID-COLUMN-WIDTH: calc((#{$grid-max_width} - (var(--GRID-COLUMN-GAP) * #{$grid-main_column_count - 1})) / #{$grid-main_column_count});\n }\n\n @include logical-property(min, inline-size, $grid-min_width, $to-rem: false);\n}\n","@import \"../../mixins/spacing\";\n@import \"../../mixins/typography\";\n\n.content-meta {\n @include list-style-none();\n @include body-spacing();\n}\n\n.content-meta__item {\n display: inline-block;\n @include label-content-typography();\n\n &:after {\n content: \"\\a0\\2022\\a0\";\n }\n\n &:last-child:after {\n content: \"\";\n }\n}\n\n.content-meta__link {\n @include covert-link();\n}\n","@import \"../../mixins/spacing\";\n\n.section__body {\n @include body-spacing();\n}\n","@import \"../../mixins/sizes\";\n@import \"../../mixins/typography\";\n\n.tag-list {\n @include blg-spacing(\"block-end\", \"small\", \"margin\");\n}\n\n.tag-list__title {\n @include label-content-typography();\n @include padding(0, \"block\");\n}\n\n.tag-list__list {\n @include list-style-none();\n @include blg-spacing(\"block-end\", \"small\", \"margin\");\n}\n\n.tag-list__list--single-line {\n @include truncate-with-ellipsis();\n}\n\n.tag-list__item {\n display: inline-block;\n @include label-tag-typography();\n\n &:after {\n display: inline;\n content: \",\\a0\";\n }\n\n &:lang(ar):after {\n content: \"،\\a0\";\n }\n\n &:lang(ja):after {\n content: \"、\";\n }\n\n &:last-child:after {\n content: \"\";\n }\n}\n\n.tag-list__link {\n @include covert-link();\n}\n","@import \"../../variables/baselinegrid\";\n@import \"../../variables/color\";\n@import \"../../variables/content_header\";\n@import \"../../functions/types\";\n@import \"../../mixins/decorations\";\n@import \"../../mixins/media-query\";\n@import \"../../mixins/spacing\";\n@import \"../../mixins/typography\";\n\n.content-header {\n color: $color-text-normal;\n text-align: center;\n @include blg-spacing(\"block-start\", \"medium\", \"margin\");\n @include blg-spacing(\"block-end\", \"small\", \"margin\");\n @include divider(\"block-end\");\n}\n\n.content-header__title {\n @include margin(0, \"block-start\");\n @include blg-spacing(\"block-end\", \"small\", \"margin\");\n\n &:last-child {\n @include blg-spacing(\"block-end\", \"medium\", \"margin\");\n }\n}\n\n.content-header__title--xx-short {\n @include rem(font-size, $content_header-title-size-xx_large);\n\n @include mq($from: small) {\n @include rem(font-size, $content_header-title-size-xxx_large);\n }\n}\n\n.content-header__title--x-short {\n @include rem(font-size, $content_header-title-size-x_large);\n\n @include mq($from: medium) {\n @include rem(font-size, $content_header-title-size-xx_large);\n }\n\n @include mq($from: wide) {\n @include rem(font-size, $content_header-title-size-xxx_large);\n }\n}\n\n.content-header__title--short {\n @include rem(font-size, $content_header-title-size-medium);\n\n @include mq($from: small) {\n @include rem(font-size, $content_header-title-size-large);\n }\n\n @include mq($from: medium) {\n @include rem(font-size, $content_header-title-size-x_large);\n }\n\n @include mq($from: wide) {\n @include rem(font-size, $content_header-title-size-xx_large);\n }\n\n @include mq($from: x-wide) {\n @include rem(font-size, $content_header-title-size-xxx_large);\n }\n}\n\n.content-header__title--medium {\n @include rem(font-size, $content_header-title-size-small);\n\n @include mq($from: small) {\n @include rem(font-size, $content_header-title-size-medium);\n }\n\n @include mq($from: medium) {\n @include rem(font-size, $content_header-title-size-large);\n }\n\n @include mq($from: wide) {\n @include rem(font-size, $content_header-title-size-x_large);\n }\n\n @include mq($from: x-wide) {\n @include rem(font-size, $content_header-title-size-xxx_large);\n }\n}\n\n.content-header__title--long {\n @include rem(font-size, $content_header-title-size-x_small);\n\n @include mq($from: small) {\n @include rem(font-size, $content_header-title-size-small);\n }\n\n @include mq($from: medium) {\n @include rem(font-size, $content_header-title-size-large);\n }\n\n @include mq($from: x-wide) {\n @include rem(font-size, $content_header-title-size-x_large);\n }\n\n}\n\n.content-header__title--x-long {\n @include rem(font-size, $content_header-title-size-x_small);\n\n @include mq($from: medium) {\n @include rem(font-size, $content_header-title-size-small);\n }\n\n @include mq($from: wide) {\n @include rem(font-size, $content_header-title-size-small);\n }\n\n @include mq($from: x-wide) {\n @include rem(font-size, $content_header-title-size-medium);\n }\n}\n\n.content-header__title--xx-long {\n @include rem(font-size, $content_header-title-size-xx_small);\n\n @include mq($from: small) {\n @include rem(font-size, $content_header-title-size-x_small);\n }\n\n @include mq($from: wide) {\n @include rem(font-size, $content_header-title-size-small);\n }\n}\n","$content_header-title-size-xx_small: 18px;\n$content_header-title-size-x_small: 20px;\n$content_header-title-size-small: 26px;\n$content_header-title-size-medium: 30px;\n$content_header-title-size-large: 36px;\n$content_header-title-size-x_large: 41px;\n$content_header-title-size-xx_large: 46px;\n$content_header-title-size-xxx_large: 52px;\n","@import \"../mixins/types\";\n@import \"../variables/font\";\n\n$rem-baseline: $font-size-base;\n$rem-fallback: true;\n","@import \"../mixins/logical-properties\";\n@import \"../variables/color\";\n\n@mixin divider($dimension) {\n\n @if index((\"inline\", \"inline-start\", \"inline-end\", \"block\", \"block-start\", \"block-end\"), $dimension) {\n @include logical-property(border, $dimension, (1px solid $color-text-dividers,), $to-rem: false);\n } @else if index((\"top\", \"bottom\", \"left\", \"right\"), $dimension) {\n @include _error(\"'#{$dimension}' is a physical dimension, use its logical equivilant\");\n } @else {\n @include _error(\"Unknown dimension '#{$dimension}'\");\n }\n\n}\n","@import \"../../mixins/media-query\";\n@import \"../../mixins/spacing\";\n@import \"../../mixins/types\";\n@import \"../../mixins/typography\";\n@import \"../../variables/color\";\n\n.item-tags {\n @include blg-spacing(\"block-start\", \"medium\", \"padding\");\n text-align: center;\n\n @include mq($from: medium) {\n text-align: initial;\n }\n}\n","@import \"../../functions/grid\";\n@import \"../../mixins/grid\";\n@import \"../../mixins/media-query\";\n@import \"../../variables/grid\";\n\n.content-grid {\n --primary-column-width: #{get-overall-width($grid-main_column_count)};\n\n @include base-grid($grid-max_width);\n grid-template-areas:\n \". menu .\"\n \". primary .\";\n grid-template-columns: [full-start] 1fr [main-start] var(--primary-column-width) [main-end] 1fr [full-end];\n grid-column-gap: var(--GRID-COLUMN-GAP);\n\n @include mq($from: wide) {\n $primary-column-count: $grid-main_column_count - 2;\n $secondary-column-count: floor(($grid-main_column_count - $primary-column-count) / 2);\n $menu-column-count: $grid-main_column_count - $primary-column-count - $secondary-column-count;\n --primary-column-width: #{get-overall-width($primary-column-count)};\n --secondary-column-width: #{get-overall-width($secondary-column-count)};\n --menu-column-width: #{get-overall-width($menu-column-count)};\n grid-template-areas:\n \". . menu . .\"\n \". . primary . .\";\n grid-template-columns: [full-start] 1fr [main-start] var(--menu-column-width) var(--primary-column-width) var(--secondary-column-width) [main-end] 1fr [full-end];\n }\n\n @include mq($from: x-wide) {\n $primary-column-count: floor($grid-main_column_count * 0.7);\n $secondary-column-count: floor(($grid-main_column_count - $primary-column-count) / 2);\n $menu-column-count: $grid-main_column_count - $primary-column-count - $secondary-column-count;\n --primary-column-width: #{get-overall-width($primary-column-count)};\n --secondary-column-width: #{get-overall-width($secondary-column-count)};\n --menu-column-width: #{get-overall-width($menu-column-count)};\n grid-template-areas: \". menu primary . .\";\n }\n}\n\n.content-grid--has-secondary {\n grid-template-areas:\n \". menu .\"\n \". primary .\"\n \". secondary .\";\n\n @include mq($from: wide) {\n $primary-column-count: floor($grid-main_column_count * 0.7);\n $secondary-column-count: $grid-main_column_count - $primary-column-count;\n --primary-column-width: #{get-overall-width($primary-column-count)};\n --secondary-column-width: #{get-overall-width($secondary-column-count)};\n grid-template-areas:\n \". menu menu .\"\n \". primary secondary .\";\n grid-template-columns: [full-start] 1fr [main-start] var(--primary-column-width) var(--secondary-column-width) [main-end] 1fr [full-end];\n }\n\n @include mq($from: x-wide) {\n $primary-column-count: floor($grid-main_column_count * 0.6);\n $secondary-column-count: floor($grid-main_column_count * 0.25);\n $menu-column-count: $grid-main_column_count - $primary-column-count - $secondary-column-count;\n --primary-column-width: #{get-overall-width($primary-column-count)};\n --secondary-column-width: #{get-overall-width($secondary-column-count)};\n --menu-column-width: #{get-overall-width($menu-column-count)};\n grid-template-areas: \". menu primary secondary .\";\n grid-template-columns: [full-start] 1fr [main-start] var(--menu-column-width) var(--primary-column-width) var(--secondary-column-width) [main-end] 1fr [full-end];\n }\n}\n\n.content-grid__item,\n.content-grid__item--main {\n grid-column: main;\n}\n\n.content-grid__item--full {\n grid-column: full;\n}\n\n.content-grid__item--primary {\n grid-column: primary;\n}\n\n.content-grid__item--secondary {\n grid-column: secondary;\n}\n\n.content-grid__item--menu {\n grid-column: menu;\n}\n","@function get-overall-width($columns) {\n @return calc((#{$columns} * var(--GRID-COLUMN-WIDTH)) + (#{$columns - 1} * var(--GRID-COLUMN-GAP)));\n}\n","@import \"spacing\";\n@import \"types\";\n@import \"../functions/grid\";\n\n@mixin base-grid($max-inline-size) {\n @include max-inline-size($max-inline-size);\n @include margin(auto, inline);\n @include padding($grid-column_gap, inline);\n box-sizing: content-box;\n\n @supports (display: grid) and (--custom: property) {\n display: grid;\n @include max-inline-size(unset);\n @include margin(unset, inline);\n @include padding(unset, inline);\n box-sizing: border-box;\n }\n}\n","@import \"../../mixins/decorations\";\n@import \"../../mixins/grid\";\n@import \"../../variables/grid\";\n\n.page-grid {\n @include base-grid($grid-max_width);\n grid-template-areas:\n \"start\"\n \"main\"\n \"end\";\n}\n\n.page-grid__start {\n grid-row: start;\n @include divider(block-end);\n}\n\n.page-grid__main {\n grid-row: main;\n}\n\n.page-grid__end {\n grid-row: end;\n @include divider(block-start);\n}\n"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/vendor-extra/LiberoPatternsBundle/src/Resources/views/heading.html.twig b/vendor-extra/LiberoPatternsBundle/src/Resources/views/heading.html.twig index e71a095..3aa1f8f 100644 --- a/vendor-extra/LiberoPatternsBundle/src/Resources/views/heading.html.twig +++ b/vendor-extra/LiberoPatternsBundle/src/Resources/views/heading.html.twig @@ -1,5 +1,21 @@ +{%- set attributes = attributes|default({})|merge({class: attributes.class|default([])|merge(['heading']) }) -%} + - {%- include '@LiberoPatterns/text.html.twig' with {nodes: text} only -%} + {%- if text.text is not defined -%} + {%- set text = {text: text} -%} + {%- endif -%} + + {%- with text only -%} + {%- block text -%} + + {%- if attributes.href is defined -%} + {%- set attributes = attributes|default({})|merge({class: attributes.class|default([])|merge(['heading__link']) }) -%} + {%- endif -%} + + {%- include '@LiberoPatterns/link.html.twig' -%} + + {%- endblock -%} + {%- endwith -%} diff --git a/vendor-extra/LiberoPatternsBundle/src/Resources/views/teaser-list.html.twig b/vendor-extra/LiberoPatternsBundle/src/Resources/views/teaser-list.html.twig new file mode 100644 index 0000000..e0e1299 --- /dev/null +++ b/vendor-extra/LiberoPatternsBundle/src/Resources/views/teaser-list.html.twig @@ -0,0 +1,54 @@ +{%- set attributes = attributes|default({})|merge({class: attributes.class|default([])|merge(['teaser-list']) }) -%} + +
+ + {%- with title|default({}) only -%} + {%- block title -%} + + {% if text is defined %} + + {%- set attributes = attributes|default({})|merge({class: attributes.class|default([])|merge(['teaser-list__title']) }) -%} + {%- include '@LiberoPatterns/heading.html.twig' with {level: level|default(4)} -%} + + {% endif %} + + {%- endblock title -%} + {%- endwith -%} + + {%- with list only -%} + {%- block list -%} + + {%- set attributes = attributes|default({})|merge({class: attributes.class|default([])|merge(['teaser-list__list']) }) -%} + +
    + + {%- for item in items -%} + + {%- with item only -%} + {%- block item -%} + + {%- set attributes = attributes|default({})|merge({class: attributes.class|default([])|merge(['teaser-list__item']) }) -%} + +
  1. + + {%- with content only -%} + {%- block content -%} + + {%- include('@LiberoPatterns/teaser.html.twig') -%} + + {%- endblock content -%} + {%- endwith -%} + +
  2. + + {%- endblock item -%} + {%- endwith -%} + + {%- endfor -%} + +
+ + {%- endblock list -%} + {%- endwith -%} + +
diff --git a/vendor-extra/LiberoPatternsBundle/src/Resources/views/teaser.html.twig b/vendor-extra/LiberoPatternsBundle/src/Resources/views/teaser.html.twig new file mode 100644 index 0000000..dd53cfb --- /dev/null +++ b/vendor-extra/LiberoPatternsBundle/src/Resources/views/teaser.html.twig @@ -0,0 +1,27 @@ +{%- set attributes = attributes|default({})|merge({class: attributes.class|default([])|merge(['teaser']) }) -%} + +
+ + {%- with {attributes: {class: []}} -%} + {%- block header -%} + + {%- set attributes = attributes|merge({class: attributes.class|merge(['teaser__header']) }) -%} +
+ + {%- with heading|merge({text: {attributes: {href: href}, text: heading.text} }) only -%} + {%- block heading -%} + + {%- set attributes = attributes|default({})|merge({class: attributes.class|default([])|merge(['teaser__heading']) }) -%} + {%- set level = level|default(4) -%} + + {%- include '@LiberoPatterns/heading.html.twig' -%} + + {%- endblock heading -%} + {%- endwith -%} + +
+ + {%- endblock header -%} + {%- endwith -%} + +
From 8bbaabccdab6bb653d31b2db6efdd919d203ed60 Mon Sep 17 00:00:00 2001 From: nlisgo Date: Fri, 5 Apr 2019 13:40:21 +0100 Subject: [PATCH 25/46] Re-introduce lazy view --- .../BuildView/ItemListListener.php | 40 +++++++++++-------- .../BuildView/ItemRefTeaserListener.php | 7 +++- .../ViewsBundle/src/Views/LazyView.php | 39 ++++++++++++++++++ 3 files changed, 68 insertions(+), 18 deletions(-) create mode 100644 vendor-extra/ViewsBundle/src/Views/LazyView.php diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php index 99c5a53..a2e4228 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php @@ -6,6 +6,7 @@ use FluentDOM\DOM\Element; use FluentDOM\DOM\Node\NonDocumentTypeChildNode; +use Libero\ViewsBundle\Views\LazyView; use Libero\ViewsBundle\Views\SimplifiedViewConverterListener; use Libero\ViewsBundle\Views\TemplateView; use Libero\ViewsBundle\Views\View; @@ -27,23 +28,30 @@ public function __construct(ViewConverter $converter) protected function handle(Element $object, TemplateView $view) : View { - return $view->withArgument( - 'list', - [ - 'items' => array_map( - function (NonDocumentTypeChildNode $child) use ($view) : array { - return [ - 'content' => $this->converter->convert( - $child, - '@LiberoPatterns/teaser.html.twig', - $view->getContext() - )->getArguments() - ]; - }, - iterator_to_array($object->getElementsByTagNameNS('http://libero.pub', 'item-ref')) - ) - ] + $items = array_map( + function (NonDocumentTypeChildNode $child) use ($view) : View { + return $this->converter->convert( + $child, + '@LiberoPatterns/teaser.html.twig', + $view->getContext() + ); + }, + iterator_to_array($object->getElementsByTagNameNS('http://libero.pub', 'item-ref')) ); + + return new LazyView(function () use ($view, $items) { + return $view->withArgument( + 'list', + [ + 'items' => array_map( + function (View $view) { + return ['content' => $view['arguments']]; + }, + $items + ), + ] + ); + }, $view->getContext()); } protected function canHandleTemplate(?string $template) : bool diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefTeaserListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefTeaserListener.php index 433a13f..0b8650d 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefTeaserListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefTeaserListener.php @@ -7,6 +7,7 @@ use FluentDOM; use FluentDOM\DOM\Element; use GuzzleHttp\ClientInterface; +use Libero\ViewsBundle\Views\LazyView; use Libero\ViewsBundle\Views\SimplifiedViewConverterListener; use Libero\ViewsBundle\Views\TemplateView; use Libero\ViewsBundle\Views\View; @@ -28,7 +29,7 @@ public function __construct(ClientInterface $client, ViewConverter $converter) protected function handle(Element $object, TemplateView $view) : View { - return $this->client + $new = $this->client ->requestAsync( 'GET', "{$object->getAttribute('service')}/items/{$object->getAttribute('id')}/versions/latest" @@ -40,7 +41,9 @@ function (ResponseInterface $response) use ($object, $view) : View { return $this->converter->convert($item->documentElement, $view->getTemplate(), $view->getContext()); } - )->wait(); + ); + + return new LazyView([$new, 'wait'], $view->getContext()); } protected function canHandleTemplate(?string $template) : bool diff --git a/vendor-extra/ViewsBundle/src/Views/LazyView.php b/vendor-extra/ViewsBundle/src/Views/LazyView.php new file mode 100644 index 0000000..81d9f47 --- /dev/null +++ b/vendor-extra/ViewsBundle/src/Views/LazyView.php @@ -0,0 +1,39 @@ +callback = $callback; + $this->context = $context; + } + + public function getIterator() + { + return $this->resolve(); + } + + private function resolve() : TemplateView + { + if (isset($this->callback)) { + $this->view = call_user_func($this->callback); + $this->callback = null; + } + + return $this->view; + } +} From 1a0c5fa6fe8659b4922b018bc3ac7f1be7479637 Mon Sep 17 00:00:00 2001 From: nlisgo Date: Fri, 5 Apr 2019 14:03:37 +0100 Subject: [PATCH 26/46] cs --- .../EventListener/BuildView/ItemArticleTitleTeaserListener.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemArticleTitleTeaserListener.php b/vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemArticleTitleTeaserListener.php index 6de1098..04933d3 100644 --- a/vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemArticleTitleTeaserListener.php +++ b/vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemArticleTitleTeaserListener.php @@ -57,4 +57,4 @@ protected function canHandleArguments(array $arguments) : bool { return !array_has_key($arguments, 'heading'); } -} \ No newline at end of file +} From b67c520c7ff4301cac9b7c17079c9d58df972597 Mon Sep 17 00:00:00 2001 From: nlisgo Date: Fri, 5 Apr 2019 14:10:12 +0100 Subject: [PATCH 27/46] cs --- .../src/EventListener/BuildView/ItemListListener.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php index a2e4228..44b3c90 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php @@ -31,10 +31,10 @@ protected function handle(Element $object, TemplateView $view) : View $items = array_map( function (NonDocumentTypeChildNode $child) use ($view) : View { return $this->converter->convert( - $child, - '@LiberoPatterns/teaser.html.twig', - $view->getContext() - ); + $child, + '@LiberoPatterns/teaser.html.twig', + $view->getContext() + ); }, iterator_to_array($object->getElementsByTagNameNS('http://libero.pub', 'item-ref')) ); From 2666132fb278b69ab841a2f2abae305f9d809651 Mon Sep 17 00:00:00 2001 From: nlisgo Date: Fri, 5 Apr 2019 16:14:57 +0100 Subject: [PATCH 28/46] Pass only front for teaser listeners in JatsContentBundle --- ...hp => FrontArticleTitleTeaserListener.php} | 6 +- .../BuildView/ItemTeaserListener.php | 64 +++++++++++++++++++ .../src/Resources/config/services.xml | 10 ++- .../BuildView/ItemTeaserHrefListener.php | 2 +- 4 files changed, 76 insertions(+), 6 deletions(-) rename vendor-extra/JatsContentBundle/src/EventListener/BuildView/{ItemArticleTitleTeaserListener.php => FrontArticleTitleTeaserListener.php} (87%) create mode 100644 vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemTeaserListener.php diff --git a/vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemArticleTitleTeaserListener.php b/vendor-extra/JatsContentBundle/src/EventListener/BuildView/FrontArticleTitleTeaserListener.php similarity index 87% rename from vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemArticleTitleTeaserListener.php rename to vendor-extra/JatsContentBundle/src/EventListener/BuildView/FrontArticleTitleTeaserListener.php index 04933d3..22eba7a 100644 --- a/vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemArticleTitleTeaserListener.php +++ b/vendor-extra/JatsContentBundle/src/EventListener/BuildView/FrontArticleTitleTeaserListener.php @@ -11,7 +11,7 @@ use Libero\ViewsBundle\Views\ViewConverter; use function Libero\ViewsBundle\array_has_key; -final class ItemArticleTitleTeaserListener +final class FrontArticleTitleTeaserListener { use SimplifiedViewConverterListener; @@ -26,7 +26,7 @@ protected function handle(Element $object, TemplateView $view) : View { $heading = $object->ownerDocument->xpath() ->firstOf( - '/libero:item/jats:article/jats:front/jats:article-meta/jats:title-group/jats:article-title', + 'jats:article-meta/jats:title-group/jats:article-title', $object ); @@ -50,7 +50,7 @@ protected function canHandleTemplate(?string $template) : bool protected function canHandleElement(string $element) : bool { - return '{http://libero.pub}item' === $element; + return '{http://jats.nlm.nih.gov}front' === $element; } protected function canHandleArguments(array $arguments) : bool diff --git a/vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemTeaserListener.php b/vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemTeaserListener.php new file mode 100644 index 0000000..19cd293 --- /dev/null +++ b/vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemTeaserListener.php @@ -0,0 +1,64 @@ +converter = $converter; + } + + public function onBuildView(BuildViewEvent $event) : void + { + $object = $event->getObject(); + $view = $event->getView(); + + if (!$view instanceof TemplateView || !$this->canHandleTemplate($view->getTemplate())) { + return; + } + + if (!$this->canHandleElement(sprintf('{%s}%s', $object->namespaceURI, $object->localName))) { + return; + } + + $event->setView($this->handle($object, $view)); + + $event->stopPropagation(); + } + + protected function handle(Element $object, TemplateView $view) : View + { + $front = $object->ownerDocument->xpath() + ->firstOf( + '/libero:item/jats:article/jats:front', + $object + ); + + if (!$front instanceof Element) { + return $view; + } + + return $this->converter->convert($front, $view->getTemplate(), $view->getContext()); + } + + protected function canHandleTemplate(?string $template) : bool + { + return '@LiberoPatterns/teaser.html.twig' === $template; + } + + protected function canHandleElement(string $element) : bool + { + return '{http://libero.pub}item' === $element; + } +} diff --git a/vendor-extra/JatsContentBundle/src/Resources/config/services.xml b/vendor-extra/JatsContentBundle/src/Resources/config/services.xml index fc4e5c3..c175b4a 100644 --- a/vendor-extra/JatsContentBundle/src/Resources/config/services.xml +++ b/vendor-extra/JatsContentBundle/src/Resources/config/services.xml @@ -124,8 +124,14 @@
- + + + + + + diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemTeaserHrefListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemTeaserHrefListener.php index 07f5b36..4478911 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemTeaserHrefListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemTeaserHrefListener.php @@ -48,7 +48,7 @@ protected function canHandleTemplate(?string $template) : bool protected function canHandleElement(string $element) : bool { - return '{http://libero.pub}item' === $element; + return true; } protected function canHandleArguments(array $arguments) : bool From 942b30ef4544af7512e59345a6046c9f50b1b498 Mon Sep 17 00:00:00 2001 From: nlisgo Date: Fri, 5 Apr 2019 16:21:18 +0100 Subject: [PATCH 29/46] Add tests for FrontArticleTitleTeaserListener --- .../FrontArticleTitleTeaserListenerTest.php | 170 ++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 vendor-extra/JatsContentBundle/tests/EventListener/BuildView/FrontArticleTitleTeaserListenerTest.php diff --git a/vendor-extra/JatsContentBundle/tests/EventListener/BuildView/FrontArticleTitleTeaserListenerTest.php b/vendor-extra/JatsContentBundle/tests/EventListener/BuildView/FrontArticleTitleTeaserListenerTest.php new file mode 100644 index 0000000..c4240a0 --- /dev/null +++ b/vendor-extra/JatsContentBundle/tests/EventListener/BuildView/FrontArticleTitleTeaserListenerTest.php @@ -0,0 +1,170 @@ +createFailingConverter()); + + $element = $this->loadElement($xml); + + $event = new BuildViewEvent($element, new TemplateView('@LiberoPatterns/teaser.html.twig')); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('@LiberoPatterns/teaser.html.twig', $view->getTemplate()); + $this->assertEmpty($view->getArguments()); + $this->assertEmpty($view->getContext()); + } + + public function nodeProvider() : iterable + { + yield 'different namespace' => ['foo']; + yield 'different element' => ['foo']; + } + + /** + * @test + */ + public function it_does_nothing_if_is_not_the_teaser_template() : void + { + $listener = new FrontArticleTitleTeaserListener($this->createFailingConverter()); + + $element = $this->loadElement( + << + + + + foo + + + +XML + ); + + $event = new BuildViewEvent($element, new TemplateView('template')); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('template', $view->getTemplate()); + $this->assertEmpty($view->getArguments()); + $this->assertEmpty($view->getContext()); + } + + /** + * @test + */ + public function it_does_nothing_if_there_is_no_title_group() : void + { + $listener = new FrontArticleTitleTeaserListener($this->createFailingConverter()); + + $element = $this->loadElement(''); + + $event = new BuildViewEvent($element, new TemplateView('@LiberoPatterns/teaser.html.twig')); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('@LiberoPatterns/teaser.html.twig', $view->getTemplate()); + $this->assertEmpty($view->getArguments()); + $this->assertEmpty($view->getContext()); + } + + /** + * @test + */ + public function it_does_nothing_if_there_is_already_a_teaser_title_set() : void + { + $listener = new FrontArticleTitleTeaserListener($this->createFailingConverter()); + + $element = $this->loadElement( + << + + + + foo + + + +XML + ); + + $event = new BuildViewEvent( + $element, + new TemplateView('@LiberoPatterns/teaser.html.twig', ['heading' => 'bar']) + ); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('@LiberoPatterns/teaser.html.twig', $view->getTemplate()); + $this->assertSame(['heading' => 'bar'], $view->getArguments()); + $this->assertEmpty($view->getContext()); + } + + /** + * @test + */ + public function it_sets_the_text_argument() : void + { + $listener = new FrontArticleTitleTeaserListener($this->createDumpingConverter()); + + $element = $this->loadElement( + << + + + + foo + + + +XML + ); + + $context = ['bar' => 'baz']; + + $event = new BuildViewEvent( + $element, + new TemplateView('@LiberoPatterns/teaser.html.twig', [], $context) + ); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('@LiberoPatterns/teaser.html.twig', $view->getTemplate()); + $this->assertEquals( + [ + 'heading' => [ + 'node' => '/jats:front/jats:article-meta/jats:title-group/jats:article-title', + 'template' => '@LiberoPatterns/heading.html.twig', + 'context' => ['bar' => 'baz'], + ], + ], + $view->getArguments() + ); + $this->assertSame(['bar' => 'baz'], $view->getContext()); + } +} From 57280e9a89b112c807a655acd867abacdc29d68b Mon Sep 17 00:00:00 2001 From: nlisgo Date: Fri, 5 Apr 2019 18:27:26 +0100 Subject: [PATCH 30/46] Add tests for ItemTeaserListener --- .../BuildView/ItemTeaserListenerTest.php | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 vendor-extra/JatsContentBundle/tests/EventListener/BuildView/ItemTeaserListenerTest.php diff --git a/vendor-extra/JatsContentBundle/tests/EventListener/BuildView/ItemTeaserListenerTest.php b/vendor-extra/JatsContentBundle/tests/EventListener/BuildView/ItemTeaserListenerTest.php new file mode 100644 index 0000000..12e227c --- /dev/null +++ b/vendor-extra/JatsContentBundle/tests/EventListener/BuildView/ItemTeaserListenerTest.php @@ -0,0 +1,94 @@ +createFailingConverter()); + + $element = $this->loadElement($xml); + + $event = new BuildViewEvent($element, new TemplateView('@LiberoPatterns/teaser.html.twig')); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('@LiberoPatterns/teaser.html.twig', $view->getTemplate()); + $this->assertEmpty($view->getArguments()); + $this->assertEmpty($view->getContext()); + } + + public function nodeProvider() : iterable + { + yield 'different namespace' => ['foo']; + yield 'different element' => ['foo']; + } + + /** + * @test + */ + public function it_does_nothing_if_is_not_the_teaser_template() : void + { + $listener = new ItemTeaserListener($this->createFailingConverter()); + + $element = $this->loadElement( + << + + + + article1 + scholarly-articles + + + +XML + ); + + $event = new BuildViewEvent($element, new TemplateView('template')); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('template', $view->getTemplate()); + $this->assertEmpty($view->getArguments()); + $this->assertEmpty($view->getContext()); + } + + /** + * @test + */ + public function it_does_nothing_if_there_is_no_front_group() : void + { + $listener = new ItemTeaserListener($this->createFailingConverter()); + + $element = $this->loadElement(''); + + $event = new BuildViewEvent($element, new TemplateView('@LiberoPatterns/teaser.html.twig')); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('@LiberoPatterns/teaser.html.twig', $view->getTemplate()); + $this->assertEmpty($view->getArguments()); + $this->assertEmpty($view->getContext()); + } +} From 6fa6615581d383c478e8d35c857e0422c533ec2a Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Mon, 8 Apr 2019 14:48:07 +0100 Subject: [PATCH 31/46] Update homepage test and support Libero content --- config/packages/test/libero_page.yaml | 2 +- tests/WebTest.php | 53 +++++++++++++- .../BuildView/ItemTeaserListener.php | 13 +++- .../src/Resources/config/services.xml | 2 +- .../BuildView/FrontTitleTeaserListener.php | 56 +++++++++++++++ .../BuildView/ItemTeaserListener.php | 71 +++++++++++++++++++ .../src/Resources/config/services.xml | 12 ++++ .../BuildView/ItemListListener.php | 36 ++++++---- .../BuildView/ItemRefTeaserListener.php | 20 ++++-- 9 files changed, 239 insertions(+), 26 deletions(-) create mode 100644 vendor-extra/LiberoContentBundle/src/EventListener/BuildView/FrontTitleTeaserListener.php create mode 100644 vendor-extra/LiberoContentBundle/src/EventListener/BuildView/ItemTeaserListener.php diff --git a/config/packages/test/libero_page.yaml b/config/packages/test/libero_page.yaml index 7f8b72c..7675578 100644 --- a/config/packages/test/libero_page.yaml +++ b/config/packages/test/libero_page.yaml @@ -2,7 +2,7 @@ libero_page: pages: homepage: path: '/' - search_service: 'scholarly-articles' + search_service: 'search' content: blog-articles: path: '/blog/{id}' diff --git a/tests/WebTest.php b/tests/WebTest.php index 8259676..b448b68 100644 --- a/tests/WebTest.php +++ b/tests/WebTest.php @@ -17,6 +17,49 @@ public function it_has_a_homepage() : void { $client = static::createClient(); + self::mockApiResponse( + new Request( + 'GET', + 'http://localhost/search/items', + ['Accept' => 'application/xml'] + ), + new Response( + 200, + [], + << + + + +XML + ) + ); + + self::mockApiResponse( + new Request( + 'GET', + 'http://localhost/scholarly-articles/items/article1/versions/latest', + ['Accept' => 'application/xml'] + ), + new Response( + 200, + [], + << + + + article1 + scholarly-articles + + + article1 + Scholarly article 1 + + +XML + ) + ); + $crawler = $client->request('GET', '/'); $response = $client->getResponse(); @@ -45,8 +88,11 @@ public function it_shows_scholarly_articles(string $id) : void << - + {$id} + scholarly-articles + + Scholarly article {$id} @@ -82,8 +128,11 @@ public function it_shows_blog_articles(string $id) : void << + + {$id} + scholarly-articles + - ${id} Blog article ${id} diff --git a/vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemTeaserListener.php b/vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemTeaserListener.php index 19cd293..31a9cc0 100644 --- a/vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemTeaserListener.php +++ b/vendor-extra/JatsContentBundle/src/EventListener/BuildView/ItemTeaserListener.php @@ -9,6 +9,7 @@ use Libero\ViewsBundle\Views\TemplateView; use Libero\ViewsBundle\Views\View; use Libero\ViewsBundle\Views\ViewConverter; +use function sprintf; final class ItemTeaserListener { @@ -32,12 +33,18 @@ public function onBuildView(BuildViewEvent $event) : void return; } - $event->setView($this->handle($object, $view)); + $handled = $this->handle($object, $view); + + if (!$handled instanceof View) { + return; + } + + $event->setView($handled); $event->stopPropagation(); } - protected function handle(Element $object, TemplateView $view) : View + protected function handle(Element $object, TemplateView $view) : ?View { $front = $object->ownerDocument->xpath() ->firstOf( @@ -46,7 +53,7 @@ protected function handle(Element $object, TemplateView $view) : View ); if (!$front instanceof Element) { - return $view; + return null; } return $this->converter->convert($front, $view->getTemplate(), $view->getContext()); diff --git a/vendor-extra/JatsContentBundle/src/Resources/config/services.xml b/vendor-extra/JatsContentBundle/src/Resources/config/services.xml index e44b33e..7b82820 100644 --- a/vendor-extra/JatsContentBundle/src/Resources/config/services.xml +++ b/vendor-extra/JatsContentBundle/src/Resources/config/services.xml @@ -149,7 +149,7 @@ - + converter = $converter; + } + + protected function handle(Element $object, TemplateView $view) : View + { + $title = $object->ownerDocument->xpath() + ->firstOf('libero:title[1]', $object); + + if (!$title instanceof Element) { + return $view; + } + + return $view->withArgument( + 'heading', + $this->converter + ->convert($title, '@LiberoPatterns/heading.html.twig', $view->getContext()) + ->getArguments() + ); + } + + protected function canHandleTemplate(?string $template) : bool + { + return '@LiberoPatterns/teaser.html.twig' === $template; + } + + protected function canHandleElement(string $element) : bool + { + return '{http://libero.pub}front' === $element; + } + + protected function canHandleArguments(array $arguments) : bool + { + return !array_has_key($arguments, 'heading'); + } +} diff --git a/vendor-extra/LiberoContentBundle/src/EventListener/BuildView/ItemTeaserListener.php b/vendor-extra/LiberoContentBundle/src/EventListener/BuildView/ItemTeaserListener.php new file mode 100644 index 0000000..15cb2c9 --- /dev/null +++ b/vendor-extra/LiberoContentBundle/src/EventListener/BuildView/ItemTeaserListener.php @@ -0,0 +1,71 @@ +converter = $converter; + } + + public function onBuildView(BuildViewEvent $event) : void + { + $object = $event->getObject(); + $view = $event->getView(); + + if (!$view instanceof TemplateView || !$this->canHandleTemplate($view->getTemplate())) { + return; + } + + if (!$this->canHandleElement(sprintf('{%s}%s', $object->namespaceURI, $object->localName))) { + return; + } + + $handled = $this->handle($object, $view); + + if (!$handled instanceof View) { + return; + } + + $event->setView($handled); + + $event->stopPropagation(); + } + + protected function handle(Element $object, TemplateView $view) : ?View + { + $front = $object->ownerDocument->xpath() + ->firstOf( + '/libero:item/libero:front', + $object + ); + + if (!$front instanceof Element) { + return null; + } + + return $this->converter->convert($front, $view->getTemplate(), $view->getContext()); + } + + protected function canHandleTemplate(?string $template) : bool + { + return '@LiberoPatterns/teaser.html.twig' === $template; + } + + protected function canHandleElement(string $element) : bool + { + return '{http://libero.pub}item' === $element; + } +} diff --git a/vendor-extra/LiberoContentBundle/src/Resources/config/services.xml b/vendor-extra/LiberoContentBundle/src/Resources/config/services.xml index 393d636..6243e1c 100644 --- a/vendor-extra/LiberoContentBundle/src/Resources/config/services.xml +++ b/vendor-extra/LiberoContentBundle/src/Resources/config/services.xml @@ -26,12 +26,24 @@ + + + + + + + + + + diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php index 44b3c90..3ce2df6 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php @@ -11,6 +11,7 @@ use Libero\ViewsBundle\Views\TemplateView; use Libero\ViewsBundle\Views\View; use Libero\ViewsBundle\Views\ViewConverter; +use function array_filter; use function array_map; use function iterator_to_array; use function Libero\ViewsBundle\array_has_key; @@ -39,19 +40,28 @@ function (NonDocumentTypeChildNode $child) use ($view) : View { iterator_to_array($object->getElementsByTagNameNS('http://libero.pub', 'item-ref')) ); - return new LazyView(function () use ($view, $items) { - return $view->withArgument( - 'list', - [ - 'items' => array_map( - function (View $view) { - return ['content' => $view['arguments']]; - }, - $items - ), - ] - ); - }, $view->getContext()); + return new LazyView( + function () use ($view, $items) { + return $view->withArgument( + 'list', + [ + 'items' => array_filter( + array_map( + function (View $view) { + if (!$view instanceof TemplateView) { + return []; + } + + return ['content' => $view->getArguments()]; + }, + $items + ) + ), + ] + ); + }, + $view->getContext() + ); } protected function canHandleTemplate(?string $template) : bool diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefTeaserListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefTeaserListener.php index 0b8650d..9b25009 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefTeaserListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefTeaserListener.php @@ -29,11 +29,14 @@ public function __construct(ClientInterface $client, ViewConverter $converter) protected function handle(Element $object, TemplateView $view) : View { - $new = $this->client - ->requestAsync( - 'GET', - "{$object->getAttribute('service')}/items/{$object->getAttribute('id')}/versions/latest" - ) + $itemTeaser = $this->client->requestAsync( + 'GET', + "{$object->getAttribute('service')}/items/{$object->getAttribute('id')}/versions/latest", + [ + 'headers' => ['Accept' => 'application/xml'], + 'http_errors' => true, + ] + ) ->then( function (ResponseInterface $response) use ($object, $view) : View { $item = FluentDOM::load((string) $response->getBody()); @@ -43,7 +46,12 @@ function (ResponseInterface $response) use ($object, $view) : View { } ); - return new LazyView([$new, 'wait'], $view->getContext()); + return new LazyView( + function () use ($itemTeaser) : TemplateView { + return $itemTeaser->wait(); + }, + $view->getContext() + ); } protected function canHandleTemplate(?string $template) : bool From abd30d3be40c78beb29e445f6edfc4c1f0940d34 Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Mon, 8 Apr 2019 15:49:02 +0100 Subject: [PATCH 32/46] Fix list and add test --- tests/WebTest.php | 1 + .../src/EventListener/BuildView/ItemListListener.php | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/WebTest.php b/tests/WebTest.php index b448b68..6d09778 100644 --- a/tests/WebTest.php +++ b/tests/WebTest.php @@ -66,6 +66,7 @@ public function it_has_a_homepage() : void $this->assertSame(200, $response->getStatusCode()); $this->assertSame('text/html; charset=UTF-8', $response->headers->get('Content-Type')); $this->assertSame('Site Name', trim($crawler->filter('.content-header__title')->text())); + $this->assertSame('Scholarly article 1', trim($crawler->filter('.teaser__heading')->text())); } /** diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php index 3ce2df6..7c9f860 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php @@ -4,6 +4,7 @@ namespace Libero\LiberoPageBundle\EventListener\BuildView; +use ArrayAccess; use FluentDOM\DOM\Element; use FluentDOM\DOM\Node\NonDocumentTypeChildNode; use Libero\ViewsBundle\Views\LazyView; @@ -48,11 +49,11 @@ function () use ($view, $items) { 'items' => array_filter( array_map( function (View $view) { - if (!$view instanceof TemplateView) { + if (!$view instanceof ArrayAccess) { return []; } - return ['content' => $view->getArguments()]; + return ['content' => $view['arguments']]; }, $items ) From 922cf53cb8f5898fbfca8d530e5be1348bbe4241 Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Tue, 9 Apr 2019 08:43:40 +0100 Subject: [PATCH 33/46] Add tests --- composer.json | 1 + composer.lock | 60 ++++++- phpunit.xml.dist | 18 +- symfony.lock | 3 + .../BuildView/ItemTeaserListenerTest.php | 72 +++++++- .../FrontTitleTeaserListenerTest.php | 143 ++++++++++++++++ .../BuildView/ItemTeaserListenerTest.php | 146 ++++++++++++++++ .../BuildView/ItemListListener.php | 20 +-- ...ener.php => ItemRefTeaserHrefListener.php} | 10 +- .../BuildView/ItemRefTeaserListener.php | 21 ++- .../src/Resources/config/services.xml | 7 +- .../BuildView/ItemListListenerTest.php | 118 +++++++++++++ .../ItemRefTeaserHrefListenerTest.php | 123 ++++++++++++++ .../BuildView/ItemRefTeaserListenerTest.php | 156 ++++++++++++++++++ .../LiberoPageBundle/tests/TwigTestCase.php | 3 +- .../tests/UrlGeneratorTestCase.php | 33 ++++ .../ViewsBundle/tests/Views/LazyViewTest.php | 128 ++++++++++++++ 17 files changed, 1018 insertions(+), 44 deletions(-) create mode 100644 vendor-extra/LiberoContentBundle/tests/EventListener/BuildView/FrontTitleTeaserListenerTest.php create mode 100644 vendor-extra/LiberoContentBundle/tests/EventListener/BuildView/ItemTeaserListenerTest.php rename vendor-extra/LiberoPageBundle/src/EventListener/BuildView/{ItemTeaserHrefListener.php => ItemRefTeaserHrefListener.php} (82%) create mode 100644 vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListListenerTest.php create mode 100644 vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemRefTeaserHrefListenerTest.php create mode 100644 vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemRefTeaserListenerTest.php create mode 100644 vendor-extra/LiberoPageBundle/tests/UrlGeneratorTestCase.php create mode 100644 vendor-extra/ViewsBundle/tests/Views/LazyViewTest.php diff --git a/composer.json b/composer.json index 6c84818..ee0b05e 100644 --- a/composer.json +++ b/composer.json @@ -45,6 +45,7 @@ }, "require-dev": { "csa/guzzle-cache-middleware": "^1.0", + "dusank/knapsack": "^10.0", "libero/coding-standard": "^0.4", "php-vfs/php-vfs": "^1.4", "phpstan/phpstan": "^0.11", diff --git a/composer.lock b/composer.lock index 3787ccd..7d2beb0 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "855d900355244020254c69ba7fd32af3", + "content-hash": "267569c2b3aec1f927ea42be3c381a8d", "packages": [ { "name": "csa/guzzle-bundle", @@ -2731,6 +2731,64 @@ ], "time": "2017-07-22T11:58:36+00:00" }, + { + "name": "dusank/knapsack", + "version": "10.0.0", + "source": { + "type": "git", + "url": "https://github.com/DusanKasan/Knapsack.git", + "reference": "cc29a0bbaadbfcb958b98aa4fd69a4ad7d173bba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/DusanKasan/Knapsack/zipball/cc29a0bbaadbfcb958b98aa4fd69a4ad7d173bba", + "reference": "cc29a0bbaadbfcb958b98aa4fd69a4ad7d173bba", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "require-dev": { + "ciaranmcnulty/phpspec-typehintedmethods": "^1.0", + "henrikbjorn/phpspec-code-coverage": "^2.0", + "phpmd/phpmd": "^2.0", + "phpspec/phpspec": "^2.0", + "phpunit/phpunit": "^5.0", + "squizlabs/php_codesniffer": "^2.0", + "symfony/console": "^2.7" + }, + "type": "library", + "autoload": { + "files": [ + "src/collection_functions.php", + "src/utility_functions.php" + ], + "psr-4": { + "DusanKasan\\Knapsack\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dusan Kasan", + "email": "dusan@kasan.sk", + "homepage": "http://kasan.sk", + "role": "Developer" + } + ], + "description": "Collection library for PHP", + "homepage": "https://github.com/DusanKasan/Knapsack", + "keywords": [ + "collections", + "map", + "reduce", + "sequences" + ], + "time": "2017-04-24T22:52:29+00:00" + }, { "name": "jean85/pretty-package-versions", "version": "1.2", diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 081511b..468fcc6 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -15,27 +15,15 @@ tests - - vendor-extra/ContentPageBundle/tests - - - vendor-extra/JatsContentBundle/tests - - - vendor-extra/LiberoContentBundle/tests - - - vendor-extra/ViewsBundle/tests + + vendor-extra/*/tests src - vendor-extra/ContentPageBundle/src - vendor-extra/JatsContentBundle/src - vendor-extra/LiberoContentBundle/src - vendor-extra/ViewsBundle/src + vendor-extra/*/src diff --git a/symfony.lock b/symfony.lock index 965762f..f22ee34 100644 --- a/symfony.lock +++ b/symfony.lock @@ -26,6 +26,9 @@ "doctrine/instantiator": { "version": "1.1.0" }, + "dusank/knapsack": { + "version": "10.0.0" + }, "fluentdom/fluentdom": { "version": "7.1.0" }, diff --git a/vendor-extra/JatsContentBundle/tests/EventListener/BuildView/ItemTeaserListenerTest.php b/vendor-extra/JatsContentBundle/tests/EventListener/BuildView/ItemTeaserListenerTest.php index 12e227c..9ec6774 100644 --- a/vendor-extra/JatsContentBundle/tests/EventListener/BuildView/ItemTeaserListenerTest.php +++ b/vendor-extra/JatsContentBundle/tests/EventListener/BuildView/ItemTeaserListenerTest.php @@ -54,11 +54,18 @@ public function it_does_nothing_if_is_not_the_teaser_template() : void - article1 scholarly-articles - +
+ + + + foo + + + +
XML ); @@ -76,11 +83,21 @@ public function it_does_nothing_if_is_not_the_teaser_template() : void /** * @test */ - public function it_does_nothing_if_there_is_no_front_group() : void + public function it_does_nothing_if_there_is_no_jats_front() : void { $listener = new ItemTeaserListener($this->createFailingConverter()); - $element = $this->loadElement(''); + $element = $this->loadElement( + << + + + article1 + scholarly-articles + + +XML + ); $event = new BuildViewEvent($element, new TemplateView('@LiberoPatterns/teaser.html.twig')); $listener->onBuildView($event); @@ -91,4 +108,51 @@ public function it_does_nothing_if_there_is_no_front_group() : void $this->assertEmpty($view->getArguments()); $this->assertEmpty($view->getContext()); } + + /** + * @test + */ + public function it_converts_a_jats_front_into_a_teaser() : void + { + $listener = new ItemTeaserListener($this->createDumpingConverter()); + + $element = $this->loadElement( + << + + + article1 + scholarly-articles + + + + + + foo + + + + + +XML + ); + + $event = new BuildViewEvent( + $element, + new TemplateView('@LiberoPatterns/teaser.html.twig', [], ['con' => 'text']) + ); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame( + [ + 'node' => '/libero:item/jats:article/jats:front', + 'template' => '@LiberoPatterns/teaser.html.twig', + 'context' => ['con' => 'text'], + ], + $view->getArguments() + ); + $this->assertTrue($event->isPropagationStopped()); + } } diff --git a/vendor-extra/LiberoContentBundle/tests/EventListener/BuildView/FrontTitleTeaserListenerTest.php b/vendor-extra/LiberoContentBundle/tests/EventListener/BuildView/FrontTitleTeaserListenerTest.php new file mode 100644 index 0000000..25e04cd --- /dev/null +++ b/vendor-extra/LiberoContentBundle/tests/EventListener/BuildView/FrontTitleTeaserListenerTest.php @@ -0,0 +1,143 @@ +createFailingConverter()); + + $element = $this->loadElement($xml); + + $event = new BuildViewEvent($element, new TemplateView('@LiberoPatterns/teaser.html.twig')); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('@LiberoPatterns/teaser.html.twig', $view->getTemplate()); + $this->assertEmpty($view->getArguments()); + $this->assertEmpty($view->getContext()); + } + + public function nodeProvider() : iterable + { + yield 'different namespace' => ['foo']; + yield 'different element' => ['foo']; + } + + /** + * @test + */ + public function it_does_nothing_if_is_not_the_teaser_template() : void + { + $listener = new FrontTitleTeaserListener($this->createFailingConverter()); + + $element = $this->loadElement('foo'); + + $event = new BuildViewEvent($element, new TemplateView('template')); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('template', $view->getTemplate()); + $this->assertEmpty($view->getArguments()); + $this->assertEmpty($view->getContext()); + } + + /** + * @test + */ + public function it_does_nothing_if_there_is_no_title() : void + { + $listener = new FrontTitleTeaserListener($this->createFailingConverter()); + + $element = $this->loadElement('foo'); + + $event = new BuildViewEvent($element, new TemplateView('@LiberoPatterns/teaser.html.twig')); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('@LiberoPatterns/teaser.html.twig', $view->getTemplate()); + $this->assertEmpty($view->getArguments()); + $this->assertEmpty($view->getContext()); + } + + /** + * @test + */ + public function it_does_nothing_if_there_is_already_a_teaser_title_set() : void + { + $listener = new FrontTitleTeaserListener($this->createFailingConverter()); + + $element = $this->loadElement('foo'); + + $event = new BuildViewEvent( + $element, + new TemplateView('@LiberoPatterns/teaser.html.twig', ['heading' => 'bar']) + ); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('@LiberoPatterns/teaser.html.twig', $view->getTemplate()); + $this->assertSame(['heading' => 'bar'], $view->getArguments()); + $this->assertEmpty($view->getContext()); + } + + /** + * @test + */ + public function it_sets_the_text_argument() : void + { + $listener = new FrontTitleTeaserListener($this->createDumpingConverter()); + + $element = $this->loadElement( + << + foo + +XML + ); + + $context = ['bar' => 'baz']; + + $event = new BuildViewEvent( + $element, + new TemplateView('@LiberoPatterns/teaser.html.twig', [], $context) + ); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('@LiberoPatterns/teaser.html.twig', $view->getTemplate()); + $this->assertEquals( + [ + 'heading' => [ + 'node' => '/libero:front/libero:title', + 'template' => '@LiberoPatterns/heading.html.twig', + 'context' => ['bar' => 'baz'], + ], + ], + $view->getArguments() + ); + $this->assertSame(['bar' => 'baz'], $view->getContext()); + } +} diff --git a/vendor-extra/LiberoContentBundle/tests/EventListener/BuildView/ItemTeaserListenerTest.php b/vendor-extra/LiberoContentBundle/tests/EventListener/BuildView/ItemTeaserListenerTest.php new file mode 100644 index 0000000..ffcbcfa --- /dev/null +++ b/vendor-extra/LiberoContentBundle/tests/EventListener/BuildView/ItemTeaserListenerTest.php @@ -0,0 +1,146 @@ +createFailingConverter()); + + $element = $this->loadElement($xml); + + $event = new BuildViewEvent($element, new TemplateView('@LiberoPatterns/teaser.html.twig')); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('@LiberoPatterns/teaser.html.twig', $view->getTemplate()); + $this->assertEmpty($view->getArguments()); + $this->assertEmpty($view->getContext()); + } + + public function nodeProvider() : iterable + { + yield 'different namespace' => ['foo']; + yield 'different element' => ['foo']; + } + + /** + * @test + */ + public function it_does_nothing_if_is_not_the_teaser_template() : void + { + $listener = new ItemTeaserListener($this->createFailingConverter()); + + $element = $this->loadElement( + << + + + article1 + scholarly-articles + + + foo + + +XML + ); + + $event = new BuildViewEvent($element, new TemplateView('template')); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('template', $view->getTemplate()); + $this->assertEmpty($view->getArguments()); + $this->assertEmpty($view->getContext()); + } + + /** + * @test + */ + public function it_does_nothing_if_there_is_no_libero_front() : void + { + $listener = new ItemTeaserListener($this->createFailingConverter()); + + $element = $this->loadElement( + << + + + article1 + scholarly-articles + + +XML + ); + + $event = new BuildViewEvent($element, new TemplateView('@LiberoPatterns/teaser.html.twig')); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('@LiberoPatterns/teaser.html.twig', $view->getTemplate()); + $this->assertEmpty($view->getArguments()); + $this->assertEmpty($view->getContext()); + } + + /** + * @test + */ + public function it_converts_a_libero_front_into_a_teaser() : void + { + $listener = new ItemTeaserListener($this->createDumpingConverter()); + + $element = $this->loadElement( + << + + + article1 + scholarly-articles + + + foo + + +XML + ); + + $event = new BuildViewEvent( + $element, + new TemplateView('@LiberoPatterns/teaser.html.twig', [], ['con' => 'text']) + ); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame( + [ + 'node' => '/libero:item/libero:front', + 'template' => '@LiberoPatterns/teaser.html.twig', + 'context' => ['con' => 'text'], + ], + $view->getArguments() + ); + $this->assertTrue($event->isPropagationStopped()); + } +} diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php index 7c9f860..9131f06 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php @@ -5,8 +5,8 @@ namespace Libero\LiberoPageBundle\EventListener\BuildView; use ArrayAccess; +use DOMNodeList; use FluentDOM\DOM\Element; -use FluentDOM\DOM\Node\NonDocumentTypeChildNode; use Libero\ViewsBundle\Views\LazyView; use Libero\ViewsBundle\Views\SimplifiedViewConverterListener; use Libero\ViewsBundle\Views\TemplateView; @@ -14,7 +14,6 @@ use Libero\ViewsBundle\Views\ViewConverter; use function array_filter; use function array_map; -use function iterator_to_array; use function Libero\ViewsBundle\array_has_key; final class ItemListListener @@ -30,16 +29,13 @@ public function __construct(ViewConverter $converter) protected function handle(Element $object, TemplateView $view) : View { - $items = array_map( - function (NonDocumentTypeChildNode $child) use ($view) : View { - return $this->converter->convert( - $child, - '@LiberoPatterns/teaser.html.twig', - $view->getContext() - ); - }, - iterator_to_array($object->getElementsByTagNameNS('http://libero.pub', 'item-ref')) - ); + /** @var DOMNodeList $itemRefs */ + $itemRefs = $object('libero:item-ref'); + + $items = []; + foreach ($itemRefs as $itemRef) { + $items[] = $this->converter->convert($itemRef, '@LiberoPatterns/teaser.html.twig', $view->getContext()); + } return new LazyView( function () use ($view, $items) { diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemTeaserHrefListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefTeaserHrefListener.php similarity index 82% rename from vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemTeaserHrefListener.php rename to vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefTeaserHrefListener.php index 4478911..f594f6b 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemTeaserHrefListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefTeaserHrefListener.php @@ -11,7 +11,7 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use function Libero\ViewsBundle\array_has_key; -final class ItemTeaserHrefListener +final class ItemRefTeaserHrefListener { use SimplifiedViewConverterListener; @@ -24,12 +24,10 @@ public function __construct(UrlGeneratorInterface $urlGenerator) protected function handle(Element $object, TemplateView $view) : View { - $xpath = $object->ownerDocument->xpath(); - /** @var string $id */ - $id = $xpath->evaluate('string(/libero:item/libero:meta/libero:id)'); + $id = $object->getAttribute('id'); /** @var string $service */ - $service = $xpath->evaluate('string(/libero:item/libero:meta/libero:service)'); + $service = $object->getAttribute('service'); if ('' === $id || '' === $service) { return $view; @@ -48,7 +46,7 @@ protected function canHandleTemplate(?string $template) : bool protected function canHandleElement(string $element) : bool { - return true; + return '{http://libero.pub}item-ref' === $element; } protected function canHandleArguments(array $arguments) : bool diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefTeaserListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefTeaserListener.php index 9b25009..e8dc669 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefTeaserListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemRefTeaserListener.php @@ -29,9 +29,16 @@ public function __construct(ClientInterface $client, ViewConverter $converter) protected function handle(Element $object, TemplateView $view) : View { + $service = $object->getAttribute('service'); + $id = $object->getAttribute('id'); + + if (!$service || !$id) { + return $view; + } + $itemTeaser = $this->client->requestAsync( 'GET', - "{$object->getAttribute('service')}/items/{$object->getAttribute('id')}/versions/latest", + "{$service}/items/{$id}/versions/latest", [ 'headers' => ['Accept' => 'application/xml'], 'http_errors' => true, @@ -42,7 +49,17 @@ function (ResponseInterface $response) use ($object, $view) : View { $item = FluentDOM::load((string) $response->getBody()); $item->namespaces($object->ownerDocument->namespaces()); - return $this->converter->convert($item->documentElement, $view->getTemplate(), $view->getContext()); + $itemTeaser = $this->converter->convert( + $item->documentElement, + $view->getTemplate(), + $view->getContext() + ); + + if (!$itemTeaser instanceof TemplateView) { + return $itemTeaser; + } + + return $view->withArguments($itemTeaser['arguments'])->withContext($itemTeaser->getContext()); } ); diff --git a/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml b/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml index f549c76..e9c7186 100644 --- a/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml +++ b/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml @@ -48,10 +48,11 @@
- + - + + createFailingConverter()); + + $element = $this->loadElement($xml); + + $event = new BuildViewEvent($element, new TemplateView('@LiberoPatterns/teaser-list.html.twig')); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('@LiberoPatterns/teaser-list.html.twig', $view->getTemplate()); + $this->assertEmpty($view->getArguments()); + $this->assertEmpty($view->getContext()); + } + + public function nodeProvider() : iterable + { + yield 'different namespace' => ['']; + yield 'different element' => ['']; + } + + /** + * @test + */ + public function it_does_nothing_if_is_not_the_teaser_list_template() : void + { + $listener = new ItemListListener($this->createFailingConverter()); + + $element = $this->loadElement(''); + + $event = new BuildViewEvent($element, new TemplateView('template')); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('template', $view->getTemplate()); + $this->assertEmpty($view->getArguments()); + $this->assertEmpty($view->getContext()); + } + + /** + * @test + */ + public function it_sets_the_list_items_argument() : void + { + $listener = new ItemListListener($this->createDumpingConverter()); + + $element = $this->loadElement( + << + + + + +XML + ); + + $event = new BuildViewEvent( + $element, + new TemplateView('@LiberoPatterns/teaser-list.html.twig', [], ['con' => 'text']) + ); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(LazyView::class, $view); + $this->assertSame( + [ + 'list' => [ + 'items' => [ + [ + 'content' => [ + 'node' => '/libero:item-list/libero:item-ref[1]', + 'template' => '@LiberoPatterns/teaser.html.twig', + 'context' => [ + 'con' => 'text', + ], + ], + ], + [ + 'content' => [ + 'node' => '/libero:item-list/libero:item-ref[2]', + 'template' => '@LiberoPatterns/teaser.html.twig', + 'context' => [ + 'con' => 'text', + ], + ], + ], + ], + ], + ], + $view['arguments'] + ); + } +} diff --git a/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemRefTeaserHrefListenerTest.php b/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemRefTeaserHrefListenerTest.php new file mode 100644 index 0000000..f405867 --- /dev/null +++ b/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemRefTeaserHrefListenerTest.php @@ -0,0 +1,123 @@ +createFailingUrlGenerator()); + + $element = $this->loadElement($xml); + + $event = new BuildViewEvent($element, new TemplateView('@LiberoPatterns/teaser.html.twig')); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('@LiberoPatterns/teaser.html.twig', $view->getTemplate()); + $this->assertEmpty($view->getArguments()); + $this->assertEmpty($view->getContext()); + } + + public function nodeProvider() : iterable + { + yield 'different namespace' => ['']; + yield 'different element' => ['']; + } + + /** + * @test + */ + public function it_does_nothing_if_is_not_the_teaser_template() : void + { + $listener = new ItemRefTeaserHrefListener($this->createFailingUrlGenerator()); + + $element = $this->loadElement(''); + + $event = new BuildViewEvent($element, new TemplateView('template')); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('template', $view->getTemplate()); + $this->assertEmpty($view->getArguments()); + $this->assertEmpty($view->getContext()); + } + + /** + * @test + */ + public function it_does_nothing_if_there_is_no_id() : void + { + $listener = new ItemRefTeaserHrefListener($this->createFailingUrlGenerator()); + + $element = $this->loadElement(''); + + $event = new BuildViewEvent($element, new TemplateView('@LiberoPatterns/teaser.html.twig')); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('@LiberoPatterns/teaser.html.twig', $view->getTemplate()); + $this->assertEmpty($view->getArguments()); + $this->assertEmpty($view->getContext()); + } + + /** + * @test + */ + public function it_does_nothing_if_there_is_no_service() : void + { + $listener = new ItemRefTeaserHrefListener($this->createFailingUrlGenerator()); + + $element = $this->loadElement(''); + + $event = new BuildViewEvent($element, new TemplateView('@LiberoPatterns/teaser.html.twig')); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('@LiberoPatterns/teaser.html.twig', $view->getTemplate()); + $this->assertEmpty($view->getArguments()); + $this->assertEmpty($view->getContext()); + } + + /** + * @test + */ + public function it_sets_the_href_argument() : void + { + $listener = new ItemRefTeaserHrefListener($this->createDumpingUrlGenerator()); + + $element = $this->loadElement(''); + + $event = new BuildViewEvent( + $element, + new TemplateView('@LiberoPatterns/teaser.html.twig', [], ['con' => 'text']) + ); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame(['href' => 'libero.page.content.service/{"id":"id"}'], $view->getArguments()); + } +} diff --git a/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemRefTeaserListenerTest.php b/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemRefTeaserListenerTest.php new file mode 100644 index 0000000..dc26bc3 --- /dev/null +++ b/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemRefTeaserListenerTest.php @@ -0,0 +1,156 @@ +client, $this->createFailingConverter()); + + $element = $this->loadElement($xml); + + $event = new BuildViewEvent($element, new TemplateView('@LiberoPatterns/teaser.html.twig')); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('@LiberoPatterns/teaser.html.twig', $view->getTemplate()); + $this->assertEmpty($view->getArguments()); + $this->assertEmpty($view->getContext()); + } + + public function nodeProvider() : iterable + { + yield 'different namespace' => ['']; + yield 'different element' => ['']; + } + + /** + * @test + */ + public function it_does_nothing_if_is_not_the_teaser_template() : void + { + $listener = new ItemRefTeaserListener($this->client, $this->createFailingConverter()); + + $element = $this->loadElement(''); + + $event = new BuildViewEvent($element, new TemplateView('template')); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('template', $view->getTemplate()); + $this->assertEmpty($view->getArguments()); + $this->assertEmpty($view->getContext()); + } + + /** + * @test + */ + public function it_does_nothing_if_there_is_no_id() : void + { + $listener = new ItemRefTeaserListener($this->client, $this->createFailingConverter()); + + $element = $this->loadElement(''); + + $event = new BuildViewEvent($element, new TemplateView('@LiberoPatterns/teaser.html.twig')); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('@LiberoPatterns/teaser.html.twig', $view->getTemplate()); + $this->assertEmpty($view->getArguments()); + $this->assertEmpty($view->getContext()); + } + + /** + * @test + */ + public function it_does_nothing_if_there_is_no_service() : void + { + $listener = new ItemRefTeaserListener($this->client, $this->createFailingConverter()); + + $element = $this->loadElement(''); + + $event = new BuildViewEvent($element, new TemplateView('@LiberoPatterns/teaser.html.twig')); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('@LiberoPatterns/teaser.html.twig', $view->getTemplate()); + $this->assertEmpty($view->getArguments()); + $this->assertEmpty($view->getContext()); + } + + /** + * @test + */ + public function it_loads_the_item_and_converts_to_a_teaser() : void + { + $listener = new ItemRefTeaserListener($this->client, $this->createDumpingConverter()); + + $element = $this->loadElement(''); + + $this->mock->save( + new Request( + 'GET', + 'service/items/id/versions/latest', + ['Accept' => 'application/xml'] + ), + new Response( + 200, + [], + << + + + id + service + + +XML + ) + ); + + $event = new BuildViewEvent( + $element, + new TemplateView('@LiberoPatterns/teaser.html.twig', ['arg' => 'ument'], ['con' => 'text']) + ); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(LazyView::class, $view); + $this->assertSame( + [ + 'arg' => 'ument', + 'node' => '/libero:item', + 'template' => '@LiberoPatterns/teaser.html.twig', + 'context' => ['con' => 'text'], + ], + $view['arguments'] + ); + $this->assertSame(['con' => 'text'], $view->getContext()); + } +} diff --git a/vendor-extra/LiberoPageBundle/tests/TwigTestCase.php b/vendor-extra/LiberoPageBundle/tests/TwigTestCase.php index 9b3e877..37d4efb 100644 --- a/vendor-extra/LiberoPageBundle/tests/TwigTestCase.php +++ b/vendor-extra/LiberoPageBundle/tests/TwigTestCase.php @@ -7,6 +7,7 @@ use PHPUnit\Framework\MockObject\MockObject; use Symfony\Component\DomCrawler\Crawler; use Twig\Environment; +use function DusanKasan\Knapsack\dump; use function GuzzleHttp\json_encode; trait TwigTestCase @@ -21,7 +22,7 @@ final public function createTwig() : Environment $twig->method('render') ->willReturnCallback( function (...$arguments) : string { - return ''.json_encode($arguments).''; + return ''.json_encode(dump($arguments)).''; } ); diff --git a/vendor-extra/LiberoPageBundle/tests/UrlGeneratorTestCase.php b/vendor-extra/LiberoPageBundle/tests/UrlGeneratorTestCase.php new file mode 100644 index 0000000..e703f6c --- /dev/null +++ b/vendor-extra/LiberoPageBundle/tests/UrlGeneratorTestCase.php @@ -0,0 +1,33 @@ +createMock(UrlGeneratorInterface::class); + + $urlGenerator->method('generate')->willReturnCallback( + function (string $name, array $parameters) : string { + return "{$name}/".json_encode($parameters); + } + ); + + return $urlGenerator; + } + + final protected function createFailingUrlGenerator() : UrlGeneratorInterface + { + $urlGenerator = $this->createMock(UrlGeneratorInterface::class); + + $urlGenerator->expects($this->never())->method($this->anything()); + + return $urlGenerator; + } +} diff --git a/vendor-extra/ViewsBundle/tests/Views/LazyViewTest.php b/vendor-extra/ViewsBundle/tests/Views/LazyViewTest.php new file mode 100644 index 0000000..d2c149d --- /dev/null +++ b/vendor-extra/ViewsBundle/tests/Views/LazyViewTest.php @@ -0,0 +1,128 @@ +assertInstanceOf(View::class, $view); + } + + /** + * @test + */ + public function it_has_context() : void + { + $view = new LazyView( + function () : TemplateView { + throw new LogicException(); + }, + ['foo' => 'bar'] + ); + + $this->assertTrue($view->hasContext('foo')); + $this->assertFalse($view->hasContext('bar')); + + $this->assertSame('bar', $view->getContext('foo')); + $this->assertNull($view->getContext('bar')); + $this->assertEquals(['foo' => 'bar'], $view->getContext()); + } + + /** + * @test + */ + public function it_is_array_accessible() : void + { + $view = new LazyView( + function () : TemplateView { + return new TemplateView('template', ['foo' => 'bar', 'baz' => ['qux']]); + } + ); + + $this->assertInstanceOf(ArrayAccess::class, $view); + + $this->assertArrayHasKey('template', $view); + $this->assertSame('template', $view['template']); + $this->assertArrayHasKey('arguments', $view); + $this->assertSame(['foo' => 'bar', 'baz' => ['qux']], $view['arguments']); + $this->assertArrayNotHasKey('quux', $view); + $this->assertNull($view['quux']); + } + + /** + * @test + * @dataProvider immutableProvider + */ + public function it_is_immutable(callable $action) : void + { + $view = new LazyView( + function () : TemplateView { + throw new LogicException(); + } + ); + + $this->expectException(BadMethodCallException::class); + + $action($view); + } + + public function immutableProvider() : iterable + { + yield 'set' => [ + function (LazyView $view) : void { + $view['foo'] = 'bar'; + }, + ]; + yield 'unset' => [ + function (LazyView $view) : void { + unset($view['foo']); + }, + ]; + } + + /** + * @test + */ + public function it_is_traversable() : void + { + $view = new LazyView( + function () : TemplateView { + return new TemplateView('template', ['foo' => 'bar', 'baz' => ['qux']]); + } + ); + + $this->assertInstanceOf(Traversable::class, $view); + + $expected = [ + 'template' => 'template', + 'arguments' => [ + 'foo' => 'bar', + 'baz' => ['qux'], + ], + ]; + + $this->assertSame($expected, iterator_to_array($view)); + } +} From 30d382dabb2c158610c5bf59ac918e41e579c47b Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Tue, 9 Apr 2019 08:48:49 +0100 Subject: [PATCH 34/46] Update config --- README.md | 1 + config/packages/dev/libero_page.yaml | 2 +- config/packages/test/libero_page.yaml | 2 +- tests/WebTest.php | 2 +- .../src/DependencyInjection/LiberoPageConfiguration.php | 2 +- .../src/EventListener/HomepageContentListListener.php | 2 +- 6 files changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 011aaca..ef47dff 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ To run an image reading from two content services (`blog-articles` and `scholarl pages: homepage: path: '/' + primary_listing: 'scholarly-articles/items' content: blog-articles: path: '/blog/{id}' diff --git a/config/packages/dev/libero_page.yaml b/config/packages/dev/libero_page.yaml index 7f8b72c..ea475b1 100644 --- a/config/packages/dev/libero_page.yaml +++ b/config/packages/dev/libero_page.yaml @@ -2,7 +2,7 @@ libero_page: pages: homepage: path: '/' - search_service: 'scholarly-articles' + primary_listing: 'scholarly-articles/items' content: blog-articles: path: '/blog/{id}' diff --git a/config/packages/test/libero_page.yaml b/config/packages/test/libero_page.yaml index 7675578..2266d80 100644 --- a/config/packages/test/libero_page.yaml +++ b/config/packages/test/libero_page.yaml @@ -2,7 +2,7 @@ libero_page: pages: homepage: path: '/' - search_service: 'search' + primary_listing: 'search' content: blog-articles: path: '/blog/{id}' diff --git a/tests/WebTest.php b/tests/WebTest.php index 6d09778..abf4a0f 100644 --- a/tests/WebTest.php +++ b/tests/WebTest.php @@ -20,7 +20,7 @@ public function it_has_a_homepage() : void self::mockApiResponse( new Request( 'GET', - 'http://localhost/search/items', + 'http://localhost/search', ['Accept' => 'application/xml'] ), new Response( diff --git a/vendor-extra/LiberoPageBundle/src/DependencyInjection/LiberoPageConfiguration.php b/vendor-extra/LiberoPageBundle/src/DependencyInjection/LiberoPageConfiguration.php index 6f64dc0..0793fc8 100644 --- a/vendor-extra/LiberoPageBundle/src/DependencyInjection/LiberoPageConfiguration.php +++ b/vendor-extra/LiberoPageBundle/src/DependencyInjection/LiberoPageConfiguration.php @@ -61,7 +61,7 @@ private function getHomepageDefinition() : ArrayNodeDefinition ->scalarNode('path') ->isRequired() ->end() - ->scalarNode('search_service') + ->scalarNode('primary_listing') ->isRequired() ->end() ->end() diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php index 2246211..385eb08 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php @@ -34,7 +34,7 @@ public function onLoadPageData(LoadPageDataEvent $event) : void $list = $this->client ->requestAsync( 'GET', - "{$page['search_service']}/items", + $page['primary_listing'], [ 'headers' => ['Accept' => 'application/xml'], 'http_errors' => true, From f3b6e6c9944f24e04b9ca8210b7bb73522d78a6e Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Tue, 9 Apr 2019 09:00:23 +0100 Subject: [PATCH 35/46] Tidy --- .../src/EventListener/HomepageContentListListener.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php index 385eb08..f89829a 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php @@ -42,7 +42,7 @@ public function onLoadPageData(LoadPageDataEvent $event) : void ) ->then( function (ResponseInterface $response) : Document { - return $this->responseToDocument($response); + return FluentDOM::load((string) $response->getBody()); } ); @@ -64,9 +64,4 @@ public function onCreatePagePart(CreatePagePartEvent $event) : void ) ); } - - public function responseToDocument(ResponseInterface $response) : Document - { - return FluentDOM::load((string) $response->getBody()); - } } From 7c2310e2f9c126b0026c8d210ae30ddb3a19406c Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Tue, 9 Apr 2019 09:02:08 +0100 Subject: [PATCH 36/46] Not needed here --- .docker/api/data/blog-articles/post1/1.xml | 1 - .../data/scholarly-articles/article1/1.xml | 1 - .../data/scholarly-articles/article2/1.xml | 153 ------------------ 3 files changed, 155 deletions(-) delete mode 100644 .docker/api/data/scholarly-articles/article2/1.xml diff --git a/.docker/api/data/blog-articles/post1/1.xml b/.docker/api/data/blog-articles/post1/1.xml index fd7b00d..d02fb8d 100644 --- a/.docker/api/data/blog-articles/post1/1.xml +++ b/.docker/api/data/blog-articles/post1/1.xml @@ -5,7 +5,6 @@ post1 - blog-articles diff --git a/.docker/api/data/scholarly-articles/article1/1.xml b/.docker/api/data/scholarly-articles/article1/1.xml index 70e0556..7c78701 100644 --- a/.docker/api/data/scholarly-articles/article1/1.xml +++ b/.docker/api/data/scholarly-articles/article1/1.xml @@ -5,7 +5,6 @@ article1 - scholarly-articles diff --git a/.docker/api/data/scholarly-articles/article2/1.xml b/.docker/api/data/scholarly-articles/article2/1.xml deleted file mode 100644 index 470d74e..0000000 --- a/.docker/api/data/scholarly-articles/article2/1.xml +++ /dev/null @@ -1,153 +0,0 @@ - - - - - - - article2 - scholarly-articles - - - - - - - - - - - - - Article 2 y'all - - - - - - - Evolutionary Biology - - - - - XML - Housestyle - eLife - formatting - - - - Research organism - Human - Machine - - - - - - - - - - - Introduction - - Fossil hominins were first recognized in the Dinaledi Chamber in the Rising Star cave system in - October 2013. During a relatively short excavation, our team recovered an extensive collection of - 1550 hominin specimens, representing nearly every element of the skeleton multiple times (Figure - 1), including many complete elements and morphologically informative fragments, some in - articulation, as well as smaller fragments many of which could be refit into more complete - elements. The collection is a morphologically homogeneous sample that can be attributed to no - previously-known hominin species. Here we describe this new species, Homo - naledi. We have not defined H. naledi narrowly based on a - single jaw or skull because the entire body of material has informed our understanding of its - biology. - - - Order Primates LINNAEUS 1758 - - Suborder Anthropoidea MIVART 1864 - - Superfamily Hominoidea GRAY 1825 - - Family Hominidae GRAY 1825 - - Tribe Hominini GRAY 1825 - - Genus Homo LINNAEUS 1758 - - Homo naledi sp. nov. - urn:lsid:zoobank.org:pub:00D1E81A-6E08-4A01-BD98-79A2CEAE2411 - - - - - Etymology - - The word naledi means ‘star’ in the Sotho language and refers to - the Dinaledi Chamber's location within the Rising Star cave system. - - - - - - - Locality - - The Dinaledi chamber is located approximately 30 meters underground, within the Rising Star - cave system at about 26°1′13′′ S; 27°42′43′′ E. The system lies within the Malmani dolomites, - approximately 800 meters southwest of the well-known site of Swartkrans in the Cradle of - Humankind World Heritage Site, Gauteng Province, South Africa. - - - - - - - Horizon and associations - - The present sample of skeletal material from the Dinaledi Chamber was recovered during two - field expeditions, in November 2013 and March 2014. - - - Six specimens from an ex situ context can be identified as bird bones, and few fragmentary - rodent remains have been recovered within the excavation area. Neither of these faunal - constituents can presently be associated with the hominin fossil collection (Dirks et al., - 2015). - - - Aside from these limited faunal materials, the Dinaledi collection is entirely composed of - hominin skeletal and dental remains. The collection so far comprises 1550 fossil hominin - specimens, this number includes 1413 bone specimens and 137 isolated dental specimens; an - additional 53 teeth are present in mandibular or maxillary bone specimens. Aside from the - fragmentary rodent teeth, all dental crowns (n = 179) are hominin, recovered both from surface - collection and excavation. Likewise, aside from the few bird elements, all morphologically - informative bone specimens are clearly hominin. In all cases where elements are repeated in the - sample, they are morphologically homogeneous, with variation consistent with body size and sex - differences within a single population. These remains represent a minimum of 15 hominin - individuals, as indicated by the repetition and presence of deciduous and adult dental - elements. - - - The geological age of the fossils is not yet known. Excavations have thus far recovered - hominin material from Unit 2 and Unit 3 in the chamber (Dirks et al., 2015). Surface-collected - hominin material from the present top of Unit 3, which includes material derived from both Unit - 2 and Unit 3, represents a minority of the assemblage, and is morphologically indistinguishable - from material excavated from in situ within Unit 3. In addition to general morphological - homogeneity including cranial shape, distinctive morphological configurations of all the - recovered first metacarpals, femora, molars, lower premolars and lower canines, are identical - in both surface-collected and excavated specimens (see Figure 14 later in the text). These - include traits not found in any other hominin species yet described. These considerations - strongly indicate that this material represents a single species, and not a commingled - assemblage. - - - - - - - - - - - From 0cdb625236d04cf1216564b293346ed7c8b20660 Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Tue, 9 Apr 2019 09:18:20 +0100 Subject: [PATCH 37/46] Add title --- .../BuildView/ItemListListener.php | 13 ++++- .../HomepageContentListListener.php | 2 +- .../src/Resources/config/services.xml | 2 + .../translations/messages+intl-icu.en.xlf | 4 ++ .../BuildView/ItemListListenerTest.php | 49 +++++++++++++++++-- 5 files changed, 65 insertions(+), 5 deletions(-) diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php index 9131f06..68b4383 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php @@ -7,24 +7,28 @@ use ArrayAccess; use DOMNodeList; use FluentDOM\DOM\Element; +use Libero\ViewsBundle\Views\ContextAwareTranslation; use Libero\ViewsBundle\Views\LazyView; use Libero\ViewsBundle\Views\SimplifiedViewConverterListener; use Libero\ViewsBundle\Views\TemplateView; use Libero\ViewsBundle\Views\View; use Libero\ViewsBundle\Views\ViewConverter; +use Symfony\Contracts\Translation\TranslatorInterface; use function array_filter; use function array_map; use function Libero\ViewsBundle\array_has_key; final class ItemListListener { + use ContextAwareTranslation; use SimplifiedViewConverterListener; private $converter; - public function __construct(ViewConverter $converter) + public function __construct(ViewConverter $converter, TranslatorInterface $translator) { $this->converter = $converter; + $this->translator = $translator; } protected function handle(Element $object, TemplateView $view) : View @@ -39,6 +43,13 @@ protected function handle(Element $object, TemplateView $view) : View return new LazyView( function () use ($view, $items) { + if ($view->hasContext('list_title')) { + $view = $view->withArgument( + 'title', + ['text' => $this->translate($view->getContext('list_title'), $view->getContext())] + ); + } + return $view->withArgument( 'list', [ diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php index f89829a..15fd29a 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php @@ -60,7 +60,7 @@ public function onCreatePagePart(CreatePagePartEvent $event) : void $this->converter->convert( $list->documentElement, '@LiberoPatterns/teaser-list.html.twig', - $event->getContext() + $event->getContext() + ['list_title' => 'libero.page.homepage.primary_listing.title'] ) ); } diff --git a/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml b/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml index e9c7186..2364e16 100644 --- a/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml +++ b/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml @@ -26,6 +26,7 @@ class="Libero\LiberoPageBundle\EventListener\HomepageContentListListener"> + @@ -45,6 +46,7 @@ + diff --git a/vendor-extra/LiberoPageBundle/src/Resources/translations/messages+intl-icu.en.xlf b/vendor-extra/LiberoPageBundle/src/Resources/translations/messages+intl-icu.en.xlf index 65e0996..5cce599 100644 --- a/vendor-extra/LiberoPageBundle/src/Resources/translations/messages+intl-icu.en.xlf +++ b/vendor-extra/LiberoPageBundle/src/Resources/translations/messages+intl-icu.en.xlf @@ -16,6 +16,10 @@ {page_title} | {site_name} + + Content + + diff --git a/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListListenerTest.php b/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListListenerTest.php index 7ea301a..7a267df 100644 --- a/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListListenerTest.php +++ b/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListListenerTest.php @@ -9,6 +9,9 @@ use Libero\ViewsBundle\Views\LazyView; use Libero\ViewsBundle\Views\TemplateView; use PHPUnit\Framework\TestCase; +use Symfony\Component\Translation\IdentityTranslator; +use Symfony\Component\Translation\Loader\ArrayLoader; +use Symfony\Component\Translation\Translator; use tests\Libero\LiberoPageBundle\ViewConvertingTestCase; use tests\Libero\LiberoPageBundle\XmlTestCase; @@ -23,7 +26,7 @@ final class ItemListListenerTest extends TestCase */ public function it_does_nothing_if_it_is_not_a_libero_item_list_element(string $xml) : void { - $listener = new ItemListListener($this->createFailingConverter()); + $listener = new ItemListListener($this->createFailingConverter(), new IdentityTranslator()); $element = $this->loadElement($xml); @@ -48,7 +51,7 @@ public function nodeProvider() : iterable */ public function it_does_nothing_if_is_not_the_teaser_list_template() : void { - $listener = new ItemListListener($this->createFailingConverter()); + $listener = new ItemListListener($this->createFailingConverter(), new IdentityTranslator()); $element = $this->loadElement(''); @@ -67,7 +70,7 @@ public function it_does_nothing_if_is_not_the_teaser_list_template() : void */ public function it_sets_the_list_items_argument() : void { - $listener = new ItemListListener($this->createDumpingConverter()); + $listener = new ItemListListener($this->createDumpingConverter(), new IdentityTranslator()); $element = $this->loadElement( <<addLoader('array', new ArrayLoader()); + $translator->addResource( + 'array', + ['title_key' => 'title_key in es'], + 'es', + 'messages' + ); + + $listener = new ItemListListener($this->createDumpingConverter(), $translator); + + $element = $this->loadElement(''); + + $event = new BuildViewEvent( + $element, + new TemplateView('@LiberoPatterns/teaser-list.html.twig', [], ['lang' => 'es', 'list_title' => 'title_key']) + ); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(LazyView::class, $view); + $this->assertSame( + [ + 'title' => [ + 'text' => 'title_key in es', + ], + 'list' => [ + 'items' => [ + ], + ], + ], + $view['arguments'] + ); + } } From 5868bdb21205fe53ffa8bf8b42f8e33cdb35f778 Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Tue, 9 Apr 2019 10:23:04 +0100 Subject: [PATCH 38/46] Set levels --- .../BuildView/ItemListListener.php | 15 ++++-- .../BuildView/ItemListListenerTest.php | 11 +++- .../src/Resources/views/teaser-list.html.twig | 52 ++++++++++++------- .../src/Resources/views/teaser.html.twig | 6 +-- 4 files changed, 57 insertions(+), 27 deletions(-) diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php index 68b4383..9109641 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php @@ -36,17 +36,26 @@ protected function handle(Element $object, TemplateView $view) : View /** @var DOMNodeList $itemRefs */ $itemRefs = $object('libero:item-ref'); + $level = ($view->getContext()['level'] ?? 1) + 1; + $items = []; foreach ($itemRefs as $itemRef) { - $items[] = $this->converter->convert($itemRef, '@LiberoPatterns/teaser.html.twig', $view->getContext()); + $items[] = $this->converter->convert( + $itemRef, + '@LiberoPatterns/teaser.html.twig', + ['level' => $level + 1] + $view->getContext() + ); } return new LazyView( - function () use ($view, $items) { + function () use ($level, $view, $items) { if ($view->hasContext('list_title')) { $view = $view->withArgument( 'title', - ['text' => $this->translate($view->getContext('list_title'), $view->getContext())] + [ + 'level' => $level, + 'text' => $this->translate($view->getContext('list_title'), $view->getContext()), + ] ); } diff --git a/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListListenerTest.php b/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListListenerTest.php index 7a267df..54e6767 100644 --- a/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListListenerTest.php +++ b/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListListenerTest.php @@ -84,7 +84,7 @@ public function it_sets_the_list_items_argument() : void $event = new BuildViewEvent( $element, - new TemplateView('@LiberoPatterns/teaser-list.html.twig', [], ['con' => 'text']) + new TemplateView('@LiberoPatterns/teaser-list.html.twig', [], ['level' => 2, 'con' => 'text']) ); $listener->onBuildView($event); $view = $event->getView(); @@ -99,6 +99,7 @@ public function it_sets_the_list_items_argument() : void 'node' => '/libero:item-list/libero:item-ref[1]', 'template' => '@LiberoPatterns/teaser.html.twig', 'context' => [ + 'level' => 4, 'con' => 'text', ], ], @@ -108,6 +109,7 @@ public function it_sets_the_list_items_argument() : void 'node' => '/libero:item-list/libero:item-ref[2]', 'template' => '@LiberoPatterns/teaser.html.twig', 'context' => [ + 'level' => 4, 'con' => 'text', ], ], @@ -139,7 +141,11 @@ public function it_sets_the_title_argument() : void $event = new BuildViewEvent( $element, - new TemplateView('@LiberoPatterns/teaser-list.html.twig', [], ['lang' => 'es', 'list_title' => 'title_key']) + new TemplateView( + '@LiberoPatterns/teaser-list.html.twig', + [], + ['lang' => 'es', 'level' => 5, 'list_title' => 'title_key'] + ) ); $listener->onBuildView($event); $view = $event->getView(); @@ -148,6 +154,7 @@ public function it_sets_the_title_argument() : void $this->assertSame( [ 'title' => [ + 'level' => 6, 'text' => 'title_key in es', ], 'list' => [ diff --git a/vendor-extra/LiberoPatternsBundle/src/Resources/views/teaser-list.html.twig b/vendor-extra/LiberoPatternsBundle/src/Resources/views/teaser-list.html.twig index e0e1299..d37b0d8 100644 --- a/vendor-extra/LiberoPatternsBundle/src/Resources/views/teaser-list.html.twig +++ b/vendor-extra/LiberoPatternsBundle/src/Resources/views/teaser-list.html.twig @@ -1,6 +1,6 @@ {%- set attributes = attributes|default({})|merge({class: attributes.class|default([])|merge(['teaser-list']) }) -%} -
+
{%- with title|default({}) only -%} {%- block title -%} @@ -8,7 +8,7 @@ {% if text is defined %} {%- set attributes = attributes|default({})|merge({class: attributes.class|default([])|merge(['teaser-list__title']) }) -%} - {%- include '@LiberoPatterns/heading.html.twig' with {level: level|default(4)} -%} + {%- include '@LiberoPatterns/heading.html.twig' with {level: level|default(2)} -%} {% endif %} @@ -18,35 +18,49 @@ {%- with list only -%} {%- block list -%} - {%- set attributes = attributes|default({})|merge({class: attributes.class|default([])|merge(['teaser-list__list']) }) -%} + {%- if items|default([])|length -%} -
    + {%- set attributes = attributes|default({})|merge({class: attributes.class|default([])|merge(['teaser-list__list']) }) -%} - {%- for item in items -%} +
      - {%- with item only -%} - {%- block item -%} + {%- for item in items -%} - {%- set attributes = attributes|default({})|merge({class: attributes.class|default([])|merge(['teaser-list__item']) }) -%} + {%- with item only -%} + {%- block item -%} -
    1. + {%- set attributes = attributes|default({})|merge({class: attributes.class|default([])|merge(['teaser-list__item']) }) -%} - {%- with content only -%} - {%- block content -%} +
    2. - {%- include('@LiberoPatterns/teaser.html.twig') -%} + {%- with content only -%} + {%- block content -%} - {%- endblock content -%} - {%- endwith -%} + {%- include '@LiberoPatterns/teaser.html.twig' -%} -
    3. + {%- endblock content -%} + {%- endwith -%} - {%- endblock item -%} - {%- endwith -%} + - {%- endfor -%} + {%- endblock item -%} + {%- endwith -%} -
    + {%- endfor -%} + +
+ + {%- else -%} + + {%- with {empty: empty} only -%} + {%- block empty -%} + + {%- include '@LiberoPatterns/text.html.twig' with {nodes: empty} only -%} + + {%- endblock empty -%} + {%- endwith -%} + + {%- endif -%} {%- endblock list -%} {%- endwith -%} diff --git a/vendor-extra/LiberoPatternsBundle/src/Resources/views/teaser.html.twig b/vendor-extra/LiberoPatternsBundle/src/Resources/views/teaser.html.twig index dd53cfb..8a74d02 100644 --- a/vendor-extra/LiberoPatternsBundle/src/Resources/views/teaser.html.twig +++ b/vendor-extra/LiberoPatternsBundle/src/Resources/views/teaser.html.twig @@ -1,18 +1,18 @@ {%- set attributes = attributes|default({})|merge({class: attributes.class|default([])|merge(['teaser']) }) -%} -
+
{%- with {attributes: {class: []}} -%} {%- block header -%} {%- set attributes = attributes|merge({class: attributes.class|merge(['teaser__header']) }) -%} -
+
{%- with heading|merge({text: {attributes: {href: href}, text: heading.text} }) only -%} {%- block heading -%} {%- set attributes = attributes|default({})|merge({class: attributes.class|default([])|merge(['teaser__heading']) }) -%} - {%- set level = level|default(4) -%} + {%- set level = level|default(3) -%} {%- include '@LiberoPatterns/heading.html.twig' -%} From 39edf124fbd5496dc19f90b0136e864ab0377315 Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Tue, 9 Apr 2019 10:32:55 +0100 Subject: [PATCH 39/46] Put in grid and fix levels --- .../EventListener/BuildView/ItemListListener.php | 11 +++++++---- .../EventListener/HomepageContentListListener.php | 13 ++++++++----- .../BuildView/ItemListListenerTest.php | 14 +++++--------- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php index 9109641..7742f59 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php @@ -36,24 +36,27 @@ protected function handle(Element $object, TemplateView $view) : View /** @var DOMNodeList $itemRefs */ $itemRefs = $object('libero:item-ref'); - $level = ($view->getContext()['level'] ?? 1) + 1; + $level = $view->getContext()['level'] ?? 1; + if ($view->hasContext('list_title')) { + $level++; + } $items = []; foreach ($itemRefs as $itemRef) { $items[] = $this->converter->convert( $itemRef, '@LiberoPatterns/teaser.html.twig', - ['level' => $level + 1] + $view->getContext() + ['level' => $level] + $view->getContext() ); } return new LazyView( - function () use ($level, $view, $items) { + function () use ($view, $items) { if ($view->hasContext('list_title')) { $view = $view->withArgument( 'title', [ - 'level' => $level, + 'level' => $view->getContext()['level'] ?? 1, 'text' => $this->translate($view->getContext('list_title'), $view->getContext()), ] ); diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php index 15fd29a..aa95dd4 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php @@ -11,6 +11,7 @@ use Libero\LiberoPageBundle\Event\LoadPageDataEvent; use Libero\ViewsBundle\Views\ViewConverter; use Psr\Http\Message\ResponseInterface; +use const Libero\LiberoPatternsBundle\CONTENT_GRID_PRIMARY; final class HomepageContentListListener { @@ -55,13 +56,15 @@ public function onCreatePagePart(CreatePagePartEvent $event) : void return; } + $context = [ + 'area' => CONTENT_GRID_PRIMARY, + 'level' => ($event->getContext()['level'] ?? 1) + 1, + 'list_title' => 'libero.page.homepage.primary_listing.title', + ] + $event->getContext(); + $list = $event->getDocument('content_list'); $event->addContent( - $this->converter->convert( - $list->documentElement, - '@LiberoPatterns/teaser-list.html.twig', - $event->getContext() + ['list_title' => 'libero.page.homepage.primary_listing.title'] - ) + $this->converter->convert($list->documentElement, '@LiberoPatterns/teaser-list.html.twig', $context) ); } } diff --git a/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListListenerTest.php b/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListListenerTest.php index 54e6767..a917ea3 100644 --- a/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListListenerTest.php +++ b/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListListenerTest.php @@ -84,7 +84,7 @@ public function it_sets_the_list_items_argument() : void $event = new BuildViewEvent( $element, - new TemplateView('@LiberoPatterns/teaser-list.html.twig', [], ['level' => 2, 'con' => 'text']) + new TemplateView('@LiberoPatterns/teaser-list.html.twig', [], ['con' => 'text']) ); $listener->onBuildView($event); $view = $event->getView(); @@ -99,7 +99,7 @@ public function it_sets_the_list_items_argument() : void 'node' => '/libero:item-list/libero:item-ref[1]', 'template' => '@LiberoPatterns/teaser.html.twig', 'context' => [ - 'level' => 4, + 'level' => 1, 'con' => 'text', ], ], @@ -109,7 +109,7 @@ public function it_sets_the_list_items_argument() : void 'node' => '/libero:item-list/libero:item-ref[2]', 'template' => '@LiberoPatterns/teaser.html.twig', 'context' => [ - 'level' => 4, + 'level' => 1, 'con' => 'text', ], ], @@ -141,11 +141,7 @@ public function it_sets_the_title_argument() : void $event = new BuildViewEvent( $element, - new TemplateView( - '@LiberoPatterns/teaser-list.html.twig', - [], - ['lang' => 'es', 'level' => 5, 'list_title' => 'title_key'] - ) + new TemplateView('@LiberoPatterns/teaser-list.html.twig', [], ['lang' => 'es', 'list_title' => 'title_key']) ); $listener->onBuildView($event); $view = $event->getView(); @@ -154,7 +150,7 @@ public function it_sets_the_title_argument() : void $this->assertSame( [ 'title' => [ - 'level' => 6, + 'level' => 1, 'text' => 'title_key in es', ], 'list' => [ From 61e5820a7c981606097e708e99d69706852b8e48 Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Tue, 9 Apr 2019 11:06:19 +0100 Subject: [PATCH 40/46] Set empty text --- .../BuildView/ItemListListener.php | 29 ++++++++----- .../HomepageContentListListener.php | 1 + .../translations/messages+intl-icu.en.xlf | 4 ++ .../BuildView/ItemListListenerTest.php | 43 ++++++++++++++----- .../src/Resources/views/teaser-list.html.twig | 4 ++ 5 files changed, 61 insertions(+), 20 deletions(-) diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php index 7742f59..cb8d9d6 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php @@ -16,6 +16,7 @@ use Symfony\Contracts\Translation\TranslatorInterface; use function array_filter; use function array_map; +use function count; use function Libero\ViewsBundle\array_has_key; final class ItemListListener @@ -39,6 +40,24 @@ protected function handle(Element $object, TemplateView $view) : View $level = $view->getContext()['level'] ?? 1; if ($view->hasContext('list_title')) { $level++; + $view = $view->withArgument( + 'title', + [ + 'level' => $view->getContext()['level'] ?? 1, + 'text' => $this->translate($view->getContext('list_title'), $view->getContext()), + ] + ); + } + + if (0 === count($itemRefs)) { + if (!$view->hasContext('list_empty')) { + return $view->withArgument('list', []); + } + + return $view->withArgument( + 'list', + ['empty' => $this->translate($view->getContext('list_empty'), $view->getContext())] + ); } $items = []; @@ -52,16 +71,6 @@ protected function handle(Element $object, TemplateView $view) : View return new LazyView( function () use ($view, $items) { - if ($view->hasContext('list_title')) { - $view = $view->withArgument( - 'title', - [ - 'level' => $view->getContext()['level'] ?? 1, - 'text' => $this->translate($view->getContext('list_title'), $view->getContext()), - ] - ); - } - return $view->withArgument( 'list', [ diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php index aa95dd4..5296add 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/HomepageContentListListener.php @@ -59,6 +59,7 @@ public function onCreatePagePart(CreatePagePartEvent $event) : void $context = [ 'area' => CONTENT_GRID_PRIMARY, 'level' => ($event->getContext()['level'] ?? 1) + 1, + 'list_empty' => 'libero.page.homepage.primary_listing.empty', 'list_title' => 'libero.page.homepage.primary_listing.title', ] + $event->getContext(); diff --git a/vendor-extra/LiberoPageBundle/src/Resources/translations/messages+intl-icu.en.xlf b/vendor-extra/LiberoPageBundle/src/Resources/translations/messages+intl-icu.en.xlf index 5cce599..6bf3d46 100644 --- a/vendor-extra/LiberoPageBundle/src/Resources/translations/messages+intl-icu.en.xlf +++ b/vendor-extra/LiberoPageBundle/src/Resources/translations/messages+intl-icu.en.xlf @@ -20,6 +20,10 @@ Content + + No items available. + + diff --git a/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListListenerTest.php b/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListListenerTest.php index a917ea3..3c393a7 100644 --- a/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListListenerTest.php +++ b/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListListenerTest.php @@ -146,19 +146,42 @@ public function it_sets_the_title_argument() : void $listener->onBuildView($event); $view = $event->getView(); - $this->assertInstanceOf(LazyView::class, $view); + $this->assertInstanceOf(TemplateView::class, $view); $this->assertSame( [ - 'title' => [ - 'level' => 1, - 'text' => 'title_key in es', - ], - 'list' => [ - 'items' => [ - ], - ], + 'title' => ['level' => 1, 'text' => 'title_key in es'], + 'list' => [], ], - $view['arguments'] + $view->getArguments() ); } + + /** + * @test + */ + public function it_handles_empty_lists() : void + { + $translator = new Translator('es'); + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource( + 'array', + ['empty_key' => 'empty_key in es'], + 'es', + 'messages' + ); + + $listener = new ItemListListener($this->createDumpingConverter(), $translator); + + $element = $this->loadElement(''); + + $event = new BuildViewEvent( + $element, + new TemplateView('@LiberoPatterns/teaser-list.html.twig', [], ['lang' => 'es', 'list_empty' => 'empty_key']) + ); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame(['list' => ['empty' => 'empty_key in es']], $view->getArguments()); + } } diff --git a/vendor-extra/LiberoPatternsBundle/src/Resources/views/teaser-list.html.twig b/vendor-extra/LiberoPatternsBundle/src/Resources/views/teaser-list.html.twig index d37b0d8..b615a5e 100644 --- a/vendor-extra/LiberoPatternsBundle/src/Resources/views/teaser-list.html.twig +++ b/vendor-extra/LiberoPatternsBundle/src/Resources/views/teaser-list.html.twig @@ -52,6 +52,10 @@ {%- else -%} + {%- if empty is not iterable -%} + {%- set empty = [{template: '@LiberoPatterns/paragraph.html.twig', arguments: {text: empty}}] -%} + {%- endif -%} + {%- with {empty: empty} only -%} {%- block empty -%} From 10177c5b6fe6b7e675228f853b21284a1c0b8a90 Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Tue, 9 Apr 2019 11:14:53 +0100 Subject: [PATCH 41/46] Update --- .../LiberoPatternsBundle/src/Resources/public/css/all.css | 2 +- .../LiberoPatternsBundle/src/Resources/public/css/all.css.map | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/vendor-extra/LiberoPatternsBundle/src/Resources/public/css/all.css b/vendor-extra/LiberoPatternsBundle/src/Resources/public/css/all.css index c099df0..bf28f7d 100644 --- a/vendor-extra/LiberoPatternsBundle/src/Resources/public/css/all.css +++ b/vendor-extra/LiberoPatternsBundle/src/Resources/public/css/all.css @@ -1,3 +1,3 @@ -@font-face{font-display:fallback;font-family:"Noto Sans";src:url("../fonts/NotoSans-Regular-webfont-custom-2-subsetting.woff2") format("woff2")}@font-face{font-display:fallback;font-family:"Noto Sans";src:url("../fonts/NotoSans-SemiBold-webfont-custom-2-subsetting.woff2") format("woff2");font-weight:600}@font-face{font-display:fallback;font-family:"Noto Serif";src:url("../fonts/NotoSerif-Regular-webfont-custom-2-subsetting.woff2") format("woff2")}@font-face{font-display:fallback;font-family:"Noto Serif";src:url("../fonts/NotoSerif-Bold-webfont-basic-latin-subsetting.woff2") format("woff2");font-weight:bold}/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:0.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace, monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace, monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}button,[type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:0.35em 0.75em 0.625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}*,*:before,*:after{box-sizing:border-box}html{font-size:100%}html,body{min-height:100%;min-block-size:100%}body{background-color:#fff;color:#212121;text-rendering:optimizeLegibility;font-family:"Noto Serif",serif;font-size:16px;font-size:1rem;line-height:1.5;font-weight:normal}h1{font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:600;font-size:36px;font-size:2.25rem;line-height:1.33333;margin-top:0;margin-bottom:24px;margin-bottom:1.5rem;margin-block-start:0;margin-block-end:1.5rem}h2{font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:600;font-size:26px;font-size:1.625rem;line-height:1.15385;margin-top:0;margin-bottom:18px;margin-bottom:1.125rem;margin-block-start:0;margin-block-end:1.125rem}h3{font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:600;font-size:23px;font-size:1.4375rem;line-height:1.04348;margin-top:0;margin-bottom:24px;margin-bottom:1.5rem;margin-block-start:0;margin-block-end:1.5rem}h4{font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:600;font-size:20px;font-size:1.25rem;line-height:1.2;margin-top:0;margin-bottom:24px;margin-bottom:1.5rem;margin-block-start:0;margin-block-end:1.5rem}h5{font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:600;font-size:18px;font-size:1.125rem;line-height:1.33333;margin-top:0;margin-bottom:24px;margin-bottom:1.5rem;margin-block-start:0;margin-block-end:1.5rem}h6{font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:600;font-size:16px;font-size:1rem;line-height:1.5;margin-top:0;margin-bottom:24px;margin-bottom:1.5rem;margin-block-start:0;margin-block-end:1.5rem}address,article,aside,blockquote,caption,details,dl,fieldset,figcaption,figure,footer,form,header,hr,main,nav,ol,p,pre,section,table,ul{margin-top:0;margin-bottom:24px;margin-bottom:1.5rem;margin-block-start:0;margin-block-end:1.5rem}b,code,kbd,strong{line-height:1}hr{border:0;border-bottom:1px solid #e0e0e0;border-block-end:1px solid #e0e0e0;margin-top:0;margin-bottom:23px;margin-bottom:1.4375rem;margin-block-start:0;margin-block-end:1.4375rem}figure{margin-left:0;margin-right:0;margin-inline:0}dd>dl,li>dl,dd>ol,li>ol,dd>ul,li>ul{margin-top:0;margin-bottom:0;margin-block:0}a{color:#0288d1;text-decoration:none}dt{font-weight:bold}dd+dt{margin-top:24px;margin-top:1.5rem;margin-bottom:0;margin-block-start:1.5rem;margin-block-end:0}html[dir="ltr"] dd:not([dir]),dd[dir="ltr"]{margin-left:0}html[dir="rtl"] dd:not([dir]),dd[dir="rtl"]{margin-right:0}html[dir][dir] dd{margin-inline-start:0}address{font-size:11px;font-size:.6875rem;line-height:2.18182}small{font-size:11px;font-size:.6875rem}sub{font-size:75%;line-height:0;position:relative;vertical-align:baseline;bottom:-0.25em}@supports (font-variant-position: sub){sub{font-size:inherit;font-variant-position:sub;position:static}}sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;top:-0.5em}@supports (font-variant-position: super){sup{font-size:inherit;font-variant-position:super;position:static}}img{max-height:100%;max-block-size:100%;max-width:100%;max-inline-size:100%}h1 img,h2 img,h3 img,h4 img,h5 img,h6 img,p img{margin-bottom:.1em;margin-block-end:.1em;max-height:1em;max-block-size:1em;vertical-align:middle}em:lang(ja){font-style:normal;text-emphasis-style:open sesame;text‑emphasis‑position:over right}strong:lang(ja){font-style:normal;text-emphasis-style:filled sesame;text‑emphasis‑position:over right}u:lang(ja){text-underline-position:right}em:lang(ko){font-style:normal;text-decoration:underline;text-underline-position:under right}strong:lang(ko){font-style:normal;text-emphasis-style:filled dot;text‑emphasis‑position:over right}em:lang(zh){font-style:normal;text-emphasis-style:open dot;text‑emphasis‑position:under right}strong:lang(zh){font-style:normal;text-emphasis-style:filled dot;text‑emphasis‑position:under right}cite:lang(zh){font-style:normal;text-decoration:underline;text-underline-style:wavy}em:lang(zh-Hant){text‑emphasis‑position:over right}strong:lang(zh-Hant){text‑emphasis‑position:over right}:root{--GRID-COLUMN-GAP: 1.6%;--GRID-EDGE-SPACE: 7vw;--GRID-COLUMN-WIDTH: calc((100% - (var(--GRID-EDGE-SPACE) * 2) - (var(--GRID-COLUMN-GAP) * 11)) / 12);min-width:320px;min-inline-size:320px}@media (min-width: 45.625em){:root{--GRID-EDGE-SPACE: 14vw}}@media (min-width: 75em){:root{--GRID-COLUMN-GAP: 17.824px;--GRID-COLUMN-WIDTH: calc((1114px - (var(--GRID-COLUMN-GAP) * 11)) / 12)}}.heading__link{color:inherit;text-decoration:inherit;all:inherit;cursor:pointer}.heading__link:hover{color:#0277bd}.content-meta{overflow:auto;margin-top:0;margin-bottom:24px;margin-bottom:1.5rem;margin-block-start:0;margin-block-end:1.5rem}html[dir="ltr"] .content-meta:not([dir]),.content-meta[dir="ltr"]{padding-left:0}html[dir="rtl"] .content-meta:not([dir]),.content-meta[dir="rtl"]{padding-right:0}html[dir][dir] .content-meta{padding-inline-start:0}.content-meta__item{display:inline-block;color:#888;font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:normal;font-size:11px;font-size:.6875rem;line-height:2.18182;letter-spacing:1px;text-transform:uppercase}.content-meta__item:after{content:"\a0\2022\a0"}.content-meta__item:last-child:after{content:""}.content-meta__link{color:inherit;text-decoration:inherit;all:inherit;cursor:pointer}.content-meta__link:hover{color:#0277bd}.section__body{margin-top:0;margin-bottom:48px;margin-bottom:3rem;margin-block-start:0;margin-block-end:3rem}.tag-list{margin-top:0;margin-bottom:24px;margin-bottom:1.5rem;margin-block-start:0;margin-block-end:1.5rem}.tag-list__title{color:#888;font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:normal;font-size:11px;font-size:.6875rem;line-height:2.18182;letter-spacing:1px;text-transform:uppercase;margin-top:0;margin-bottom:0;margin-block:0}.tag-list__list{overflow:auto;color:#0288d1;font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:normal;font-size:11px;font-size:.6875rem;line-height:2.18182;letter-spacing:1px;text-transform:uppercase}html[dir="ltr"] .tag-list__list:not([dir]),.tag-list__list[dir="ltr"]{padding-left:0}html[dir="rtl"] .tag-list__list:not([dir]),.tag-list__list[dir="rtl"]{padding-right:0}html[dir][dir] .tag-list__list{padding-inline-start:0}.tag-list__list--single-line{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tag-list__list--single-line:lang(zh-Hant-HK){text-overflow:"⋯"}.tag-list__item{display:inline-block;color:#0288d1;font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:normal;font-size:11px;font-size:.6875rem;line-height:2.18182;letter-spacing:1px;text-transform:uppercase}.tag-list__item:after{display:inline;content:",\a0"}.tag-list__item:lang(ar):after{content:"،\a0"}.tag-list__item:lang(ja):after{content:"、"}.tag-list__item:last-child:after{content:""}.tag-list__link{color:inherit;text-decoration:inherit;all:inherit;cursor:pointer}.tag-list__link:hover{color:#0277bd}.teaser__heading{font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:600;font-size:20px;font-size:1.25rem;line-height:1.2;margin-top:24px;margin-top:1.5rem;margin-bottom:24px;margin-bottom:1.5rem;margin-block:1.5rem}.content-header{text-align:center;padding-top:48px;padding-top:3rem;padding-block-start:3rem;margin-top:0;margin-bottom:47px;margin-bottom:2.9375rem;margin-block-start:0;margin-block-end:2.9375rem;border-bottom:1px solid #e0e0e0;border-block-end:1px solid #e0e0e0}.content-header__title{margin-top:0;margin-bottom:24px;margin-bottom:1.5rem;margin-block-start:0;margin-block-end:1.5rem}.content-header__title:last-child{margin-top:0;margin-bottom:48px;margin-bottom:3rem;margin-block-start:0;margin-block-end:3rem}.content-header__title--xx-short{font-size:46px;font-size:2.875rem}@media (min-width: 30em){.content-header__title--xx-short{font-size:52px;font-size:3.25rem}}.content-header__title--x-short{font-size:41px;font-size:2.5625rem}@media (min-width: 45.625em){.content-header__title--x-short{font-size:46px;font-size:2.875rem}}@media (min-width: 56.25em){.content-header__title--x-short{font-size:52px;font-size:3.25rem}}.content-header__title--short{font-size:32px;font-size:2rem}@media (min-width: 30em){.content-header__title--short{font-size:36px;font-size:2.25rem}}@media (min-width: 45.625em){.content-header__title--short{font-size:41px;font-size:2.5625rem}}@media (min-width: 56.25em){.content-header__title--short{font-size:46px;font-size:2.875rem}}@media (min-width: 75em){.content-header__title--short{font-size:52px;font-size:3.25rem}}.content-header__title--medium{font-size:26px;font-size:1.625rem}@media (min-width: 30em){.content-header__title--medium{font-size:32px;font-size:2rem}}@media (min-width: 45.625em){.content-header__title--medium{font-size:36px;font-size:2.25rem}}@media (min-width: 56.25em){.content-header__title--medium{font-size:41px;font-size:2.5625rem}}@media (min-width: 75em){.content-header__title--medium{font-size:52px;font-size:3.25rem}}.content-header__title--long{font-size:20px;font-size:1.25rem}@media (min-width: 30em){.content-header__title--long{font-size:26px;font-size:1.625rem}}@media (min-width: 45.625em){.content-header__title--long{font-size:36px;font-size:2.25rem}}@media (min-width: 75em){.content-header__title--long{font-size:41px;font-size:2.5625rem}}.content-header__title--x-long{font-size:20px;font-size:1.25rem}@media (min-width: 45.625em){.content-header__title--x-long{font-size:26px;font-size:1.625rem}}@media (min-width: 56.25em){.content-header__title--x-long{font-size:26px;font-size:1.625rem}}@media (min-width: 75em){.content-header__title--x-long{font-size:32px;font-size:2rem}}.content-header__title--xx-long{font-size:18px;font-size:1.125rem}@media (min-width: 30em){.content-header__title--xx-long{font-size:20px;font-size:1.25rem}}@media (min-width: 56.25em){.content-header__title--xx-long{font-size:26px;font-size:1.625rem}}.item-tags{padding-top:47px;padding-top:2.9375rem;padding-block-start:2.9375rem;margin-top:0;margin-bottom:48px;margin-bottom:3rem;margin-block-start:0;margin-block-end:3rem;border-top:1px solid #e0e0e0;border-block-start:1px solid #e0e0e0;text-align:center}@media (min-width: 45.625em){.item-tags{text-align:initial}}.content-grid{--primary-column-width: calc((12 * var(--GRID-COLUMN-WIDTH)) + (11 * var(--GRID-COLUMN-GAP)));max-width:1114px;max-width:69.625rem;max-inline-size:69.625rem;margin-top:0;margin-bottom:0;margin-block:0;margin-left:auto;margin-right:auto;margin-inline:auto;padding-left:1.6%;padding-right:1.6%;padding-inline:1.6%;box-sizing:content-box;grid-template-areas:". menu ." ". primary .";grid-template-columns:[full-start] 1fr [main-start] var(--primary-column-width) [main-end] 1fr [full-end];grid-column-gap:var(--GRID-COLUMN-GAP)}@supports (display: grid) and (--custom: property){.content-grid{display:grid;max-width:unset;max-inline-size:unset;margin-left:unset;margin-right:unset;margin-inline:unset;padding-left:unset;padding-right:unset;padding-inline:unset;box-sizing:border-box}}@media (min-width: 56.25em){.content-grid{--primary-column-width: calc((10 * var(--GRID-COLUMN-WIDTH)) + (9 * var(--GRID-COLUMN-GAP)));--secondary-column-width: calc((1 * var(--GRID-COLUMN-WIDTH)) + (0 * var(--GRID-COLUMN-GAP)));--menu-column-width: calc((1 * var(--GRID-COLUMN-WIDTH)) + (0 * var(--GRID-COLUMN-GAP)));grid-template-areas:". . menu . ." ". . primary . .";grid-template-columns:[full-start] 1fr [main-start] var(--menu-column-width) var(--primary-column-width) var(--secondary-column-width) [main-end] 1fr [full-end]}}@media (min-width: 75em){.content-grid{--primary-column-width: calc((8 * var(--GRID-COLUMN-WIDTH)) + (7 * var(--GRID-COLUMN-GAP)));--secondary-column-width: calc((2 * var(--GRID-COLUMN-WIDTH)) + (1 * var(--GRID-COLUMN-GAP)));--menu-column-width: calc((2 * var(--GRID-COLUMN-WIDTH)) + (1 * var(--GRID-COLUMN-GAP)));grid-template-areas:". menu primary . ."}}.content-grid--has-secondary{grid-template-areas:". menu ." ". primary ." ". secondary ."}@media (min-width: 56.25em){.content-grid--has-secondary{--primary-column-width: calc((8 * var(--GRID-COLUMN-WIDTH)) + (7 * var(--GRID-COLUMN-GAP)));--secondary-column-width: calc((4 * var(--GRID-COLUMN-WIDTH)) + (3 * var(--GRID-COLUMN-GAP)));grid-template-areas:". menu menu ." ". primary secondary .";grid-template-columns:[full-start] 1fr [main-start] var(--primary-column-width) var(--secondary-column-width) [main-end] 1fr [full-end]}}@media (min-width: 75em){.content-grid--has-secondary{--primary-column-width: calc((7 * var(--GRID-COLUMN-WIDTH)) + (6 * var(--GRID-COLUMN-GAP)));--secondary-column-width: calc((3 * var(--GRID-COLUMN-WIDTH)) + (2 * var(--GRID-COLUMN-GAP)));--menu-column-width: calc((2 * var(--GRID-COLUMN-WIDTH)) + (1 * var(--GRID-COLUMN-GAP)));grid-template-areas:". menu primary secondary .";grid-template-columns:[full-start] 1fr [main-start] var(--menu-column-width) var(--primary-column-width) var(--secondary-column-width) [main-end] 1fr [full-end]}}.content-grid__item,.content-grid__item--main{grid-column:main}.content-grid__item--full{grid-column:full}.content-grid__item--primary{grid-column:primary}.content-grid__item--secondary{grid-column:secondary}.content-grid__item--menu{grid-column:menu}.page-grid{max-width:1114px;max-width:69.625rem;max-inline-size:69.625rem;margin-top:0;margin-bottom:0;margin-block:0;margin-left:auto;margin-right:auto;margin-inline:auto;padding-left:1.6%;padding-right:1.6%;padding-inline:1.6%;box-sizing:content-box;grid-template-areas:"start" "main" "end"}@supports (display: grid) and (--custom: property){.page-grid{display:grid;max-width:unset;max-inline-size:unset;margin-left:unset;margin-right:unset;margin-inline:unset;padding-left:unset;padding-right:unset;padding-inline:unset;box-sizing:border-box}}.page-grid__start{grid-row:start;border-bottom:1px solid #e0e0e0;border-block-end:1px solid #e0e0e0}.page-grid__main{grid-row:main}.page-grid__end{grid-row:end;border-top:1px solid #e0e0e0;border-block-start:1px solid #e0e0e0} +@font-face{font-display:fallback;font-family:"Noto Sans";src:url("../fonts/NotoSans-Regular-webfont-custom-2-subsetting.woff2") format("woff2")}@font-face{font-display:fallback;font-family:"Noto Sans";src:url("../fonts/NotoSans-SemiBold-webfont-custom-2-subsetting.woff2") format("woff2");font-weight:600}@font-face{font-display:fallback;font-family:"Noto Serif";src:url("../fonts/NotoSerif-Regular-webfont-custom-2-subsetting.woff2") format("woff2")}@font-face{font-display:fallback;font-family:"Noto Serif";src:url("../fonts/NotoSerif-Bold-webfont-basic-latin-subsetting.woff2") format("woff2");font-weight:bold}/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:0.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace, monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace, monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}button,[type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:0.35em 0.75em 0.625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}*,*:before,*:after{box-sizing:border-box}html{font-size:100%}html,body{min-height:100%;min-block-size:100%}body{background-color:#fff;color:#212121;text-rendering:optimizeLegibility;font-family:"Noto Serif",serif;font-size:16px;font-size:1rem;line-height:1.5;font-weight:normal}h1{font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:600;font-size:36px;font-size:2.25rem;line-height:1.33333;margin-top:0;margin-bottom:24px;margin-bottom:1.5rem;margin-block-start:0;margin-block-end:1.5rem}h2{font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:600;font-size:26px;font-size:1.625rem;line-height:1.15385;margin-top:0;margin-bottom:18px;margin-bottom:1.125rem;margin-block-start:0;margin-block-end:1.125rem}h3{font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:600;font-size:23px;font-size:1.4375rem;line-height:1.04348;margin-top:0;margin-bottom:24px;margin-bottom:1.5rem;margin-block-start:0;margin-block-end:1.5rem}h4{font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:600;font-size:20px;font-size:1.25rem;line-height:1.2;margin-top:0;margin-bottom:24px;margin-bottom:1.5rem;margin-block-start:0;margin-block-end:1.5rem}h5{font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:600;font-size:18px;font-size:1.125rem;line-height:1.33333;margin-top:0;margin-bottom:24px;margin-bottom:1.5rem;margin-block-start:0;margin-block-end:1.5rem}h6{font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:600;font-size:16px;font-size:1rem;line-height:1.5;margin-top:0;margin-bottom:24px;margin-bottom:1.5rem;margin-block-start:0;margin-block-end:1.5rem}address,article,aside,blockquote,caption,details,dl,fieldset,figcaption,figure,footer,form,header,hr,main,nav,ol,p,pre,section,table,ul{margin-top:0;margin-bottom:24px;margin-bottom:1.5rem;margin-block-start:0;margin-block-end:1.5rem}b,code,kbd,strong{line-height:1}hr{border:0;border-bottom:1px solid #e0e0e0;border-block-end:1px solid #e0e0e0;margin-top:0;margin-bottom:23px;margin-bottom:1.4375rem;margin-block-start:0;margin-block-end:1.4375rem}figure{margin-left:0;margin-right:0;margin-inline:0}dd>dl,li>dl,dd>ol,li>ol,dd>ul,li>ul{margin-top:0;margin-bottom:0;margin-block:0}a{color:#0288d1;text-decoration:none}dt{font-weight:bold}dd+dt{margin-top:24px;margin-top:1.5rem;margin-bottom:0;margin-block-start:1.5rem;margin-block-end:0}html[dir="ltr"] dd:not([dir]),dd[dir="ltr"]{margin-left:0}html[dir="rtl"] dd:not([dir]),dd[dir="rtl"]{margin-right:0}html[dir][dir] dd{margin-inline-start:0}address{font-size:11px;font-size:.6875rem;line-height:2.18182}small{font-size:11px;font-size:.6875rem}sub{font-size:75%;line-height:0;position:relative;vertical-align:baseline;bottom:-0.25em}@supports (font-variant-position: sub){sub{font-size:inherit;font-variant-position:sub;position:static}}sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;top:-0.5em}@supports (font-variant-position: super){sup{font-size:inherit;font-variant-position:super;position:static}}img{max-height:100%;max-block-size:100%;max-width:100%;max-inline-size:100%}h1 img,h2 img,h3 img,h4 img,h5 img,h6 img,p img{margin-bottom:.1em;margin-block-end:.1em;max-height:1em;max-block-size:1em;vertical-align:middle}em:lang(ja){font-style:normal;text-emphasis-style:open sesame;text‑emphasis‑position:over right}strong:lang(ja){font-style:normal;text-emphasis-style:filled sesame;text‑emphasis‑position:over right}u:lang(ja){text-underline-position:right}em:lang(ko){font-style:normal;text-decoration:underline;text-underline-position:under right}strong:lang(ko){font-style:normal;text-emphasis-style:filled dot;text‑emphasis‑position:over right}em:lang(zh){font-style:normal;text-emphasis-style:open dot;text‑emphasis‑position:under right}strong:lang(zh){font-style:normal;text-emphasis-style:filled dot;text‑emphasis‑position:under right}cite:lang(zh){font-style:normal;text-decoration:underline;text-underline-style:wavy}em:lang(zh-Hant){text‑emphasis‑position:over right}strong:lang(zh-Hant){text‑emphasis‑position:over right}:root{--GRID-COLUMN-GAP: 1.6%;--GRID-EDGE-SPACE: 7vw;--GRID-COLUMN-WIDTH: calc((100% - (var(--GRID-EDGE-SPACE) * 2) - (var(--GRID-COLUMN-GAP) * 11)) / 12);min-width:320px;min-inline-size:320px}@media (min-width: 45.625em){:root{--GRID-EDGE-SPACE: 14vw}}@media (min-width: 75em){:root{--GRID-COLUMN-GAP: 17.824px;--GRID-COLUMN-WIDTH: calc((1114px - (var(--GRID-COLUMN-GAP) * 11)) / 12)}}.heading__link{color:inherit;text-decoration:inherit;all:inherit;cursor:pointer}.heading__link:hover{color:#0277bd}.content-meta{overflow:auto;margin-top:0;margin-bottom:24px;margin-bottom:1.5rem;margin-block-start:0;margin-block-end:1.5rem}html[dir="ltr"] .content-meta:not([dir]),.content-meta[dir="ltr"]{padding-left:0}html[dir="rtl"] .content-meta:not([dir]),.content-meta[dir="rtl"]{padding-right:0}html[dir][dir] .content-meta{padding-inline-start:0}.content-meta__item{display:inline-block;color:#888;font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:normal;font-size:11px;font-size:.6875rem;line-height:2.18182;letter-spacing:1px;text-transform:uppercase}.content-meta__item:after{content:"\a0\2022\a0"}.content-meta__item:last-child:after{content:""}.content-meta__link{color:inherit;text-decoration:inherit;all:inherit;cursor:pointer}.content-meta__link:hover{color:#0277bd}.section__body{margin-top:0;margin-bottom:48px;margin-bottom:3rem;margin-block-start:0;margin-block-end:3rem}.tag-list{margin-top:0;margin-bottom:24px;margin-bottom:1.5rem;margin-block-start:0;margin-block-end:1.5rem}.tag-list__title{color:#888;font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:normal;font-size:11px;font-size:.6875rem;line-height:2.18182;letter-spacing:1px;text-transform:uppercase;margin-top:0;margin-bottom:0;margin-block:0}.tag-list__list{overflow:auto;color:#0288d1;font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:normal;font-size:11px;font-size:.6875rem;line-height:2.18182;letter-spacing:1px;text-transform:uppercase}html[dir="ltr"] .tag-list__list:not([dir]),.tag-list__list[dir="ltr"]{padding-left:0}html[dir="rtl"] .tag-list__list:not([dir]),.tag-list__list[dir="rtl"]{padding-right:0}html[dir][dir] .tag-list__list{padding-inline-start:0}.tag-list__list--single-line{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tag-list__list--single-line:lang(zh-Hant-HK){text-overflow:"⋯"}.tag-list__item{display:inline-block;color:#0288d1;font-family:"Noto Sans",Arial,Helvetica,sans-serif;font-weight:normal;font-size:11px;font-size:.6875rem;line-height:2.18182;letter-spacing:1px;text-transform:uppercase}.tag-list__item:after{display:inline;content:",\a0"}.tag-list__item:lang(ar):after{content:"،\a0"}.tag-list__item:lang(ja):after{content:"、"}.tag-list__item:last-child:after{content:""}.tag-list__link{color:inherit;text-decoration:inherit;all:inherit;cursor:pointer}.tag-list__link:hover{color:#0277bd}.content-header{text-align:center;padding-top:48px;padding-top:3rem;padding-block-start:3rem;margin-top:0;margin-bottom:47px;margin-bottom:2.9375rem;margin-block-start:0;margin-block-end:2.9375rem;border-bottom:1px solid #e0e0e0;border-block-end:1px solid #e0e0e0}.content-header__title{margin-top:0;margin-bottom:24px;margin-bottom:1.5rem;margin-block-start:0;margin-block-end:1.5rem}.content-header__title:last-child{margin-top:0;margin-bottom:48px;margin-bottom:3rem;margin-block-start:0;margin-block-end:3rem}.content-header__title--xx-short{font-size:46px;font-size:2.875rem}@media (min-width: 30em){.content-header__title--xx-short{font-size:52px;font-size:3.25rem}}.content-header__title--x-short{font-size:41px;font-size:2.5625rem}@media (min-width: 45.625em){.content-header__title--x-short{font-size:46px;font-size:2.875rem}}@media (min-width: 56.25em){.content-header__title--x-short{font-size:52px;font-size:3.25rem}}.content-header__title--short{font-size:32px;font-size:2rem}@media (min-width: 30em){.content-header__title--short{font-size:36px;font-size:2.25rem}}@media (min-width: 45.625em){.content-header__title--short{font-size:41px;font-size:2.5625rem}}@media (min-width: 56.25em){.content-header__title--short{font-size:46px;font-size:2.875rem}}@media (min-width: 75em){.content-header__title--short{font-size:52px;font-size:3.25rem}}.content-header__title--medium{font-size:26px;font-size:1.625rem}@media (min-width: 30em){.content-header__title--medium{font-size:32px;font-size:2rem}}@media (min-width: 45.625em){.content-header__title--medium{font-size:36px;font-size:2.25rem}}@media (min-width: 56.25em){.content-header__title--medium{font-size:41px;font-size:2.5625rem}}@media (min-width: 75em){.content-header__title--medium{font-size:52px;font-size:3.25rem}}.content-header__title--long{font-size:20px;font-size:1.25rem}@media (min-width: 30em){.content-header__title--long{font-size:26px;font-size:1.625rem}}@media (min-width: 45.625em){.content-header__title--long{font-size:36px;font-size:2.25rem}}@media (min-width: 75em){.content-header__title--long{font-size:41px;font-size:2.5625rem}}.content-header__title--x-long{font-size:20px;font-size:1.25rem}@media (min-width: 45.625em){.content-header__title--x-long{font-size:26px;font-size:1.625rem}}@media (min-width: 56.25em){.content-header__title--x-long{font-size:26px;font-size:1.625rem}}@media (min-width: 75em){.content-header__title--x-long{font-size:32px;font-size:2rem}}.content-header__title--xx-long{font-size:18px;font-size:1.125rem}@media (min-width: 30em){.content-header__title--xx-long{font-size:20px;font-size:1.25rem}}@media (min-width: 56.25em){.content-header__title--xx-long{font-size:26px;font-size:1.625rem}}.item-tags{padding-top:47px;padding-top:2.9375rem;padding-block-start:2.9375rem;margin-top:0;margin-bottom:48px;margin-bottom:3rem;margin-block-start:0;margin-block-end:3rem;border-top:1px solid #e0e0e0;border-block-start:1px solid #e0e0e0;text-align:center}@media (min-width: 45.625em){.item-tags{text-align:initial}}.content-grid{--primary-column-width: calc((12 * var(--GRID-COLUMN-WIDTH)) + (11 * var(--GRID-COLUMN-GAP)));max-width:1114px;max-width:69.625rem;max-inline-size:69.625rem;margin-top:0;margin-bottom:0;margin-block:0;margin-left:auto;margin-right:auto;margin-inline:auto;padding-left:1.6%;padding-right:1.6%;padding-inline:1.6%;box-sizing:content-box;grid-template-areas:". menu ." ". primary .";grid-template-columns:[full-start] 1fr [main-start] var(--primary-column-width) [main-end] 1fr [full-end];grid-column-gap:var(--GRID-COLUMN-GAP)}@supports (display: grid) and (--custom: property){.content-grid{display:grid;max-width:unset;max-inline-size:unset;margin-left:unset;margin-right:unset;margin-inline:unset;padding-left:unset;padding-right:unset;padding-inline:unset;box-sizing:border-box}}@media (min-width: 56.25em){.content-grid{--primary-column-width: calc((10 * var(--GRID-COLUMN-WIDTH)) + (9 * var(--GRID-COLUMN-GAP)));--secondary-column-width: calc((1 * var(--GRID-COLUMN-WIDTH)) + (0 * var(--GRID-COLUMN-GAP)));--menu-column-width: calc((1 * var(--GRID-COLUMN-WIDTH)) + (0 * var(--GRID-COLUMN-GAP)));grid-template-areas:". . menu . ." ". . primary . .";grid-template-columns:[full-start] 1fr [main-start] var(--menu-column-width) var(--primary-column-width) var(--secondary-column-width) [main-end] 1fr [full-end]}}@media (min-width: 75em){.content-grid{--primary-column-width: calc((8 * var(--GRID-COLUMN-WIDTH)) + (7 * var(--GRID-COLUMN-GAP)));--secondary-column-width: calc((2 * var(--GRID-COLUMN-WIDTH)) + (1 * var(--GRID-COLUMN-GAP)));--menu-column-width: calc((2 * var(--GRID-COLUMN-WIDTH)) + (1 * var(--GRID-COLUMN-GAP)));grid-template-areas:". menu primary . ."}}.content-grid--has-secondary{grid-template-areas:". menu ." ". primary ." ". secondary ."}@media (min-width: 56.25em){.content-grid--has-secondary{--primary-column-width: calc((8 * var(--GRID-COLUMN-WIDTH)) + (7 * var(--GRID-COLUMN-GAP)));--secondary-column-width: calc((4 * var(--GRID-COLUMN-WIDTH)) + (3 * var(--GRID-COLUMN-GAP)));grid-template-areas:". menu menu ." ". primary secondary .";grid-template-columns:[full-start] 1fr [main-start] var(--primary-column-width) var(--secondary-column-width) [main-end] 1fr [full-end]}}@media (min-width: 75em){.content-grid--has-secondary{--primary-column-width: calc((7 * var(--GRID-COLUMN-WIDTH)) + (6 * var(--GRID-COLUMN-GAP)));--secondary-column-width: calc((3 * var(--GRID-COLUMN-WIDTH)) + (2 * var(--GRID-COLUMN-GAP)));--menu-column-width: calc((2 * var(--GRID-COLUMN-WIDTH)) + (1 * var(--GRID-COLUMN-GAP)));grid-template-areas:". menu primary secondary .";grid-template-columns:[full-start] 1fr [main-start] var(--menu-column-width) var(--primary-column-width) var(--secondary-column-width) [main-end] 1fr [full-end]}}.content-grid__item,.content-grid__item--main{grid-column:main}.content-grid__item--full{grid-column:full}.content-grid__item--primary{grid-column:primary}.content-grid__item--secondary{grid-column:secondary}.content-grid__item--menu{grid-column:menu}.page-grid{max-width:1114px;max-width:69.625rem;max-inline-size:69.625rem;margin-top:0;margin-bottom:0;margin-block:0;margin-left:auto;margin-right:auto;margin-inline:auto;padding-left:1.6%;padding-right:1.6%;padding-inline:1.6%;box-sizing:content-box;grid-template-areas:"start" "main" "end"}@supports (display: grid) and (--custom: property){.page-grid{display:grid;max-width:unset;max-inline-size:unset;margin-left:unset;margin-right:unset;margin-inline:unset;padding-left:unset;padding-right:unset;padding-inline:unset;box-sizing:border-box}}.page-grid__start{grid-row:start;border-bottom:1px solid #e0e0e0;border-block-end:1px solid #e0e0e0}.page-grid__main{grid-row:main}.page-grid__end{grid-row:end;border-top:1px solid #e0e0e0;border-block-start:1px solid #e0e0e0} /*# sourceMappingURL=all.css.map */ diff --git a/vendor-extra/LiberoPatternsBundle/src/Resources/public/css/all.css.map b/vendor-extra/LiberoPatternsBundle/src/Resources/public/css/all.css.map index 903b590..f539e64 100644 --- a/vendor-extra/LiberoPatternsBundle/src/Resources/public/css/all.css.map +++ b/vendor-extra/LiberoPatternsBundle/src/Resources/public/css/all.css.map @@ -1 +1 @@ -{"version":3,"file":"all.css","sources":["base.scss","_fonts.scss","_normalize.scss","mixins/_decorations.scss","mixins/_logical-properties.scss","mixins/_types.scss","variables/_font.scss","vendor/sass-rem/_rem.scss","mixins/_validation.scss","functions/_validation.scss","variables/_color.scss","variables/_grid.scss","mixins/_spacing.scss","mixins/_media-query.scss","variables/_breakpoint.scss","vendor/sass-mq/_mq.scss","mixins/_sizes.scss","variables/_baselinegrid.scss","mixins/_typography.scss","mixins/_utilities.scss","mixins/_scale.scss","vendor/modularscale-sass/stylesheets/_modularscale.scss","vendor/modularscale-sass/stylesheets/modularscale/_vars.scss","vendor/modularscale-sass/stylesheets/modularscale/_settings.scss","vendor/modularscale-sass/stylesheets/modularscale/_pow.scss","vendor/modularscale-sass/stylesheets/modularscale/_strip-units.scss","vendor/modularscale-sass/stylesheets/modularscale/_sort.scss","vendor/modularscale-sass/stylesheets/modularscale/_target.scss","vendor/modularscale-sass/stylesheets/modularscale/_function.scss","vendor/modularscale-sass/stylesheets/modularscale/_round-px.scss","vendor/modularscale-sass/stylesheets/modularscale/_respond.scss","vendor/modularscale-sass/stylesheets/modularscale/_sugar.scss","vendor/normalize.css/normalize.css","_grid.scss","patterns/atoms/heading.scss","patterns/molecules/content-meta.scss","patterns/molecules/section.scss","patterns/molecules/tag-list.scss","patterns/molecules/teaser.scss","patterns/organisms/content-header.scss","functions/_types.scss","patterns/organisms/item-tags.scss","patterns/templates/content-grid.scss","functions/_grid.scss","mixins/_grid.scss","patterns/templates/page-grid.scss"],"sourcesContent":["@import \"fonts\";\n@import \"normalize\";\n@import \"grid\";\n@import \"patterns/atoms/heading.scss\";\n@import \"patterns/molecules/content-meta.scss\";\n@import \"patterns/molecules/section.scss\";\n@import \"patterns/molecules/tag-list.scss\";\n@import \"patterns/molecules/teaser.scss\";\n@import \"patterns/organisms/content-header.scss\";\n@import \"patterns/organisms/item-tags.scss\";\n@import \"patterns/templates/content-grid.scss\";\n@import \"patterns/templates/page-grid.scss\";\n","@font-face {\n font-display: fallback;\n font-family: \"Noto Sans\";\n src: url(\"../../fonts/NotoSans-Regular-webfont-custom-2-subsetting.woff2\") format(\"woff2\");\n}\n\n@font-face {\n font-display: fallback;\n font-family: \"Noto Sans\";\n src: url(\"../../fonts/NotoSans-SemiBold-webfont-custom-2-subsetting.woff2\") format(\"woff2\");\n font-weight: 600;\n}\n\n@font-face {\n font-display: fallback;\n font-family: \"Noto Serif\";\n src: url(\"../../fonts/NotoSerif-Regular-webfont-custom-2-subsetting.woff2\") format(\"woff2\");\n}\n\n@font-face {\n font-display: fallback;\n font-family: \"Noto Serif\";\n src: url(\"../../fonts/NotoSerif-Bold-webfont-basic-latin-subsetting.woff2\") format(\"woff2\");\n font-weight: bold;\n}\n","@import \"mixins/decorations\";\n@import \"mixins/spacing\";\n@import \"mixins/typography\";\n@import \"variables/color\";\n@import \"variables/grid\";\n@import \"vendor/normalize.css/normalize\";\n\n*,\n*:before,\n*:after {\n box-sizing: border-box;\n}\n\nhtml {\n font-size: ($font-size / 16px) * 100%;\n}\n\nhtml,\nbody {\n @include min-block-size(100%);\n}\n\nbody {\n background-color: $color-background;\n color: $color-text-normal;\n text-rendering: optimizeLegibility;\n @include body-typography();\n}\n\nh1 {\n @include h1-typography();\n @include h1-spacing();\n}\n\nh2 {\n @include h2-typography();\n @include h2-spacing();\n}\n\nh3 {\n @include h3-typography();\n @include h3-spacing();\n}\n\nh4 {\n @include h4-typography();\n @include h4-spacing();\n}\n\nh5 {\n @include h5-typography();\n @include h5-spacing();\n}\n\nh6 {\n @include h6-typography();\n @include h6-spacing();\n}\n\naddress,\narticle,\naside,\nblockquote,\ncaption,\ndetails,\ndl,\nfieldset,\nfigcaption,\nfigure,\nfooter,\nform,\nheader,\nhr,\nmain,\nnav,\nol,\np,\npre,\nsection,\ntable,\nul {\n @include block-spacing();\n}\n\nb,\ncode,\nkbd,\nstrong {\n line-height: 1;\n}\n\nhr {\n border: 0;\n @include divider(block-end);\n @include block-spacing($end: $baselinegrid-space-small - $grid-divider_size);\n}\n\nfigure {\n @include margin(0, inline);\n}\n\ndl,\nol,\nul {\n dd > &,\n li > & {\n @include block-spacing($end: 0);\n }\n}\n\na {\n color: $color-primary-normal;\n text-decoration: none;\n}\n\ndt {\n font-weight: bold;\n\n dd + & {\n @include block-spacing($baselinegrid-space-small, 0);\n }\n}\n\ndd {\n @include margin(0, inline-start);\n}\n\naddress {\n @include set-font-size-and-line-height(scale(-3));\n}\n\nsmall {\n @include rem(font-size, scale(-3));\n}\n\nsub {\n @include font-variant-position(sub);\n}\n\nsup {\n @include font-variant-position(super);\n}\n\nimg {\n @include max-block-size(100%);\n @include max-inline-size(100%);\n}\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\np {\n img {\n @include inline-image();\n }\n}\n\n:lang(ja) {\n @at-root {\n em#{&} {\n font-style: normal;\n text-emphasis-style: open sesame;\n text‑emphasis‑position: over right;\n }\n\n strong#{&} {\n font-style: normal;\n text-emphasis-style: filled sesame;\n text‑emphasis‑position: over right;\n }\n\n u#{&} {\n text-underline-position: right;\n }\n }\n}\n\n:lang(ko) {\n @at-root {\n em#{&} {\n font-style: normal;\n text-decoration: underline;\n text-underline-position: under right;\n }\n\n strong#{&} {\n font-style: normal;\n text-emphasis-style: filled dot;\n text‑emphasis‑position: over right;\n }\n }\n}\n\n:lang(zh) {\n @at-root {\n em#{&} {\n font-style: normal;\n text-emphasis-style: open dot;\n text‑emphasis‑position: under right;\n }\n\n strong#{&} {\n font-style: normal;\n text-emphasis-style: filled dot;\n text‑emphasis‑position: under right;\n }\n\n cite#{&} {\n font-style: normal;\n text-decoration: underline;\n text-underline-style: wavy;\n }\n }\n}\n\n:lang(zh-Hant) {\n @at-root {\n em#{&} {\n text‑emphasis‑position: over right;\n }\n\n strong#{&} {\n text‑emphasis‑position: over right;\n }\n }\n}\n","@import \"../mixins/logical-properties\";\n@import \"../variables/color\";\n@import \"../variables/grid\";\n\n@mixin divider($dimension) {\n\n @if index((inline, inline-start, inline-end, block, block-start, block-end), $dimension) {\n @include logical-property(border, $dimension, ($grid-divider_size solid $color-text-dividers,), $to-rem: false);\n } @else if index((top, bottom, left, right), $dimension) {\n @include _error(\"'#{$dimension}' is a physical dimension, use its logical equivilant\");\n } @else {\n @include _error(\"Unknown dimension '#{$dimension}'\");\n }\n\n}\n","@import \"types\";\n@import \"validation\";\n\n@mixin _when-left-to-right {\n html[dir=\"ltr\"] &:not([dir]),\n &[dir=\"ltr\"] {\n @content;\n }\n}\n\n@mixin _when-right-to-left {\n html[dir=\"rtl\"] &:not([dir]),\n &[dir=\"rtl\"] {\n @content;\n }\n}\n\n@mixin _when-logical {\n html[dir][dir] & {\n @content;\n }\n}\n\n@mixin _maybe-rem($to-rem, $properties, $values: ()) {\n @if ($to-rem == false) {\n @if type-of($properties) == \"map\" {\n @each $property in map-keys($properties) {\n @include _maybe-rem($to-rem, $property, map-get($properties, $property));\n }\n } @else {\n @each $property in $properties {\n #{$property}: $values;\n }\n }\n } @else {\n @include rem($properties, $values...);\n }\n}\n\n@function _maybe-rem($to-rem, $values) {\n @if ($to-rem == false) {\n @return $values;\n } @else {\n @return rem($values...);\n }\n}\n\n@function _property-name($parts, $dimension) {\n @if (length($parts) == 0 or $parts == \"\") {\n @return $dimension;\n }\n\n @if (length($parts) == 1) {\n @return \"#{$parts}-#{$dimension}\";\n }\n\n @return \"#{nth($parts, 1)}-#{$dimension}-#{nth($parts, 2)}\";\n}\n\n@mixin logical-property($property-name, $dimension, $arguments, $to-rem: true) {\n\n @if length($property-name) > 2 {\n @include _error(\"Expected at most two property name parts\");\n } @else if $dimension == inline {\n\n @if type-of($arguments) == \"list\" and length($arguments) > 1 {\n\n @include _expect_at_most($arguments, 2, \"More than two arguments supplied with 'inline' dimension\") {\n\n $firstArgument: nth($arguments, 1);\n $secondArgument: nth($arguments, 2);\n\n @if $firstArgument == $secondArgument {\n\n @include _maybe-rem($to-rem, (\n #{_property-name($property-name, left)}: $firstArgument,\n #{_property-name($property-name, right)}: $firstArgument,\n ));\n #{_property-name($property-name, inline)}: _maybe-rem($to-rem, $firstArgument);\n\n } @else {\n\n @include _when-left-to-right() {\n @include _maybe-rem($to-rem, _property-name($property-name, left), $firstArgument);\n @include _maybe-rem($to-rem, _property-name($property-name, right), $secondArgument);\n }\n\n @include _when-right-to-left() {\n @include _maybe-rem($to-rem, _property-name($property-name, right), $firstArgument);\n @include _maybe-rem($to-rem, _property-name($property-name, left), $secondArgument);\n }\n\n @include _when-logical() {\n #{_property-name($property-name, inline-start)}: _maybe-rem($to-rem, $firstArgument);\n #{_property-name($property-name, inline-end)}: _maybe-rem($to-rem, $secondArgument);\n }\n\n }\n\n }\n\n } @else {\n\n @include _maybe-rem($to-rem, (\n #{_property-name($property-name, left)}: $arguments,\n #{_property-name($property-name, right)}: $arguments,\n ));\n #{_property-name($property-name, inline)}: _maybe-rem($to-rem, $arguments);\n\n }\n\n } @else if $dimension == inline-start {\n\n @include _when-left-to-right() {\n @include _maybe-rem($to-rem, _property-name($property-name, left), $arguments);\n }\n\n @include _when-right-to-left() {\n @include _maybe-rem($to-rem, _property-name($property-name, right), $arguments);\n }\n\n @include _when_logical() {\n #{_property-name($property-name, inline-start)}: _maybe-rem($to-rem, $arguments);\n }\n\n } @else if $dimension == inline-end {\n\n @include _when-left-to-right() {\n @include _maybe-rem($to-rem, _property-name($property-name, right), $arguments);\n }\n\n @include _when-right-to-left() {\n @include _maybe-rem($to-rem, _property-name($property-name, left), $arguments);\n }\n\n @include _when_logical() {\n #{_property-name($property-name, inline-end)}: _maybe-rem($to-rem, $arguments);\n }\n\n } @else if $dimension == inline-size {\n\n @include _maybe-rem($to-rem, _property-name($property-name, width), $arguments);\n #{_property-name($property-name, inline-size)}: _maybe-rem($to-rem, $arguments);\n\n } @else if $dimension == block {\n\n @if type-of($arguments) == \"list\" and length($arguments) > 1 {\n\n @include _expect_at_most($arguments, 2, \"More than two arguments supplied with 'block' dimension\") {\n\n $firstArgument: nth($arguments, 1);\n $secondArgument: nth($arguments, 2);\n\n @if $firstArgument == $secondArgument {\n\n @include _maybe-rem($to-rem, (\n #{_property-name($property-name, top)}: $firstArgument,\n #{_property-name($property-name, bottom)}: $firstArgument,\n ));\n #{_property-name($property-name, block)}: _maybe-rem($to-rem, $firstArgument);\n\n } @else {\n\n @include _maybe-rem($to-rem, (\n #{_property-name($property-name, top)}: $firstArgument,\n #{_property-name($property-name, bottom)}: $secondArgument,\n ));\n #{_property-name($property-name, block-start)}: _maybe-rem($to-rem, $firstArgument);\n #{_property-name($property-name, block-end)}: _maybe-rem($to-rem, $secondArgument);\n\n }\n\n }\n\n } @else {\n\n @include _maybe-rem($to-rem, (\n #{_property-name($property-name, top)}: $arguments,\n #{_property-name($property-name, bottom)}: $arguments,\n ));\n #{_property-name($property-name, block)}: _maybe-rem($to-rem, $arguments);\n\n }\n\n } @else if $dimension == block-start {\n\n @include _maybe-rem($to-rem, _property-name($property-name, top), $arguments);\n #{_property-name($property-name, block-start)}: _maybe-rem($to-rem, $arguments);\n\n } @else if $dimension == block-end {\n\n @include _maybe-rem($to-rem, _property-name($property-name, bottom), $arguments);\n #{_property-name($property-name, block-end)}: _maybe-rem($to-rem, $arguments);\n\n } @else if $dimension == block-size {\n\n @include _maybe-rem($to-rem, _property-name($property-name, height), $arguments);\n #{_property-name($property-name, block-size)}: _maybe-rem($to-rem, $arguments);\n\n } @else if index((top, bottom, left, right, width, height), $dimension) {\n @include _error(\"'#{$dimension}' is a physical dimension, use its logical equivilant\");\n } @else {\n @include _error(\"Unknown dimension '#{$dimension}'\");\n }\n\n}\n","@import \"../variables/font\";\n@import \"../vendor/sass-rem/rem\";\n\n$rem-baseline: $font-size;\n$rem-fallback: true;\n\n// Overridden to apply https://github.com/pierreburel/sass-rem/pull/12\n@mixin rem($properties, $values...) {\n\n @if type-of($properties) == \"map\" {\n\n @each $property in map-keys($properties) {\n @include rem($property, map-get($properties, $property));\n }\n\n } @else {\n\n $convert: false;\n @each $valueList in $values {\n @each $value in $valueList {\n @if type-of($value) == \"number\" and index((rem, px), unit($value)) {\n $convert: true;\n }\n }\n }\n\n @each $property in $properties {\n @if $convert == true {\n @if $rem-fallback or $rem-px-only {\n #{$property}: rem-convert(px, $values...);\n }\n @if not $rem-px-only {\n #{$property}: rem-convert(rem, $values...);\n }\n } @else if $rem-px-only {\n #{$property}: rem-convert(px, $values...);\n } @else {\n #{$property}: $values;\n }\n }\n\n }\n\n}\n","$font-letterspacing-label: 1px;\n$font-primary: \"Noto Serif\", serif;\n$font-secondary: \"Noto Sans\", Arial, Helvetica, sans-serif;\n$font-monospace: \"Courier 10 Pitch\", Courier, monospace;\n$font-size: 16px;\n","$rem-baseline: 16px !default;\n$rem-fallback: false !default;\n$rem-px-only: false !default;\n\n@function rem-separator($list, $separator: false) {\n @if $separator == \"comma\" or $separator == \"space\" {\n @return append($list, null, $separator);\n } \n \n @if function-exists(\"list-separator\") == true {\n @return list-separator($list);\n }\n\n // list-separator polyfill by Hugo Giraudel (https://sass-compatibility.github.io/#list_separator_function)\n $test-list: ();\n @each $item in $list {\n $test-list: append($test-list, $item, space);\n }\n\n @return if($test-list == $list, space, comma);\n}\n\n@mixin rem-baseline($zoom: 100%) {\n font-size: $zoom / 16px * $rem-baseline;\n}\n\n@function rem-convert($to, $values...) {\n $result: ();\n $separator: rem-separator($values);\n \n @each $value in $values {\n @if type-of($value) == \"number\" and unit($value) == \"rem\" and $to == \"px\" {\n $result: append($result, $value / 1rem * $rem-baseline, $separator);\n } @else if type-of($value) == \"number\" and unit($value) == \"px\" and $to == \"rem\" {\n $result: append($result, $value / $rem-baseline * 1rem, $separator);\n } @else if type-of($value) == \"list\" {\n $value-separator: rem-separator($value);\n $value: rem-convert($to, $value...);\n $value: rem-separator($value, $value-separator);\n $result: append($result, $value, $separator);\n } @else {\n $result: append($result, $value, $separator);\n }\n }\n\n @return if(length($result) == 1, nth($result, 1), $result);\n}\n\n@function rem($values...) {\n @if $rem-px-only {\n @return rem-convert(px, $values...);\n } @else {\n @return rem-convert(rem, $values...);\n }\n}\n\n@mixin rem($properties, $values...) {\n @if type-of($properties) == \"map\" {\n @each $property in map-keys($properties) {\n @include rem($property, map-get($properties, $property));\n }\n } @else {\n @each $property in $properties {\n @if $rem-fallback or $rem-px-only {\n #{$property}: rem-convert(px, $values...);\n }\n @if not $rem-px-only {\n #{$property}: rem-convert(rem, $values...);\n }\n }\n }\n}\n","@import \"../functions/validation\";\n\n@mixin _error($message) {\n _error: _error($message);\n}\n\n@mixin _expect_at_most($value, $maxLength, $message: \"Expected at most #{$maxLength} values\") {\n\n @if length($value) > $maxLength {\n @include _error($message);\n } @else {\n @content;\n }\n\n}\n\n@mixin _expect_single_value($value, $message: \"Expected a single value\") {\n\n @include _expect_at_most($value, 1, $message) {\n @content;\n }\n\n}\n","$_is-test: false !default;\n\n@function _error($message, $capture: $_is-test) {\n @if $capture {\n @return $message;\n }\n\n @error $message;\n}\n","$color-primary-normal: rgb(2, 136, 209);\n$color-primary-light: rgb(179, 229, 252);\n$color-primary-dark: rgb(2, 119, 189);\n$color-text-normal: rgb(33, 33, 33);\n$color-text-reverse: rgb(255, 255, 255);\n$color-text-secondary: rgb(136, 136, 136);\n$color-text-secondary__reverse: rgb(158, 158, 158);\n$color-text-placeholder: rgb(189, 189, 189);\n$color-text-dividers: rgb(224, 224, 224);\n$color-text-dividers__reverse: rgb(97, 97, 97);\n$color-text-ui_background: rgb(255, 255, 255);\n$color-text-ui_background_hue: rgb(245, 245, 245);\n$color-text-ui_code: rgb(247, 247, 247);\n$color-text-ui_background__reverse: rgb(33, 33, 33);\n$color-text-ui_background_hue__reverse: rgb(51, 51, 51);\n$color-background: rgb(255, 255, 255);\n$color-information: rgb(2, 136, 209);\n$color-success: rgb(98, 159, 67);\n$color-success_dark: rgb(86, 144, 55);\n$color-attention: rgb(207, 12, 78);\n$color-warning: rgb(230, 81, 0);\n","$grid-edge_space-medium: 7vw;\n$grid-edge_space-large: 14vw;\n$grid-min_width: 320px;\n$grid-max_width: 1114px;\n$grid-main_column_count: 12;\n$grid-column_gap: 1.6%;\n$grid-divider_size: 1px;\n","@import \"logical-properties\";\n@import \"media-query\";\n@import \"sizes\";\n@import \"types\";\n@import \"validation\";\n@import \"../variables/baselinegrid\";\n\n// Fallbacks for CSS logical properties contained within this mixin require the following treatment of HTML dir attributes:\n// - document level: always specified, via the HTML element\n// - block level: specified on every element within a block describing a direction switch.\n//\n// For example:\n// \n// ...\n//
\n// Doesn't need a dir attribute. Most cases will be like this.\n//
\n//\n//
\n//\n// This block changes the text direction. Every descendant element must have its own dir attribute....\n//\n//
... even if the direction doesn't change.
\n//\n//
But obviously also when it does.
\n//\n//
\n@mixin _spacing($sizes, $space-type, $dimension: \"\") {\n\n @if $dimension == \"\" {\n\n @include _expect_at_most($sizes, 4, \"More than four sizes supplied when no dimension\") {\n @include rem($space-type, $sizes);\n }\n\n } @else if $dimension == inline {\n\n @include _expect_at_most($sizes, 2, \"More than two sizes supplied with 'inline' dimension\") {\n @include logical-property($space-type, $dimension, $sizes);\n }\n\n } @else if $dimension == inline-start {\n\n @include _expect_single_value($sizes, \"More than one size supplied with 'inline-start' dimension\") {\n @include logical-property($space-type, $dimension, $sizes);\n }\n\n } @else if $dimension == inline-end {\n\n @include _expect_single_value($sizes, \"More than one size supplied with 'inline-end' dimension\") {\n @include logical-property($space-type, $dimension, $sizes);\n }\n\n } @else if $dimension == block {\n\n @include _expect_at_most($sizes, 2, \"More than two sizes supplied with 'block' dimension\") {\n @include logical-property($space-type, $dimension, $sizes);\n }\n\n } @else if $dimension == block-start {\n\n @include _expect_single_value($sizes, \"More than one size supplied with 'block-start' dimension\") {\n @include logical-property($space-type, $dimension, $sizes);\n }\n\n } @else if $dimension == block-end {\n\n @include _expect_single_value($sizes, \"More than one size supplied with 'block-end' dimension\") {\n @include logical-property($space-type, $dimension, $sizes);\n }\n\n } @else if index((top, bottom, left, right), $dimension) {\n @include _error(\"'#{$dimension}' is a physical dimension, use its logical equivilant\");\n } @else {\n @include _error(\"Unknown dimension '#{$dimension}'\");\n }\n\n}\n\n@mixin padding($sizes, $dimension: \"\") {\n @include _spacing($sizes, padding, $dimension);\n}\n\n@mixin margin($sizes, $dimension: \"\") {\n @include _spacing($sizes, margin, $dimension);\n}\n\n@mixin nospace($dimension: \"\") {\n @include margin(0, $dimension);\n @include padding(0, $dimension);\n}\n\n@mixin block-spacing($start: 0, $end: $baselinegrid-space-small) {\n @include margin($start $end, block);\n}\n\n@function _calculate-spacing($block-size, $unit-size: $baselinegrid-space-small) {\n $remaining: $unit-size - $block-size;\n\n @if ($remaining > 0) {\n @return $remaining;\n }\n\n @return $unit-size;\n}\n\n@mixin h1-spacing() {\n @include block-spacing($end: _calculate-spacing($baselinegrid-space-medium));\n}\n\n@mixin h2-spacing() {\n @include block-spacing($end: _calculate-spacing(($baselinegrid-space-small + $baselinegrid-space-smallish) / 2, $baselinegrid-space-medium));\n}\n\n@mixin h3-spacing() {\n @include block-spacing($end: _calculate-spacing($baselinegrid-space-small, $baselinegrid-space-medium));\n}\n\n@mixin h4-spacing() {\n @include block-spacing($end: _calculate-spacing($baselinegrid-space-small, $baselinegrid-space-medium));\n}\n\n@mixin h5-spacing() {\n @include block-spacing($end: _calculate-spacing($baselinegrid-space-small, $baselinegrid-space-medium));\n}\n\n@mixin h6-spacing() {\n @include block-spacing($end: _calculate-spacing($baselinegrid-space-small, $baselinegrid-space-medium));\n}\n\n@mixin list-style-none() {\n list-style: none;\n @include padding(0, inline-start);\n}\n","@import \"../variables/breakpoint\";\n@import \"../variables/font\";\n\n$mq-base-font-size: $font-size;\n\n$mq-breakpoints: (\n x-small: $breakpoint-site-x_small,\n small: $breakpoint-site-small,\n medium: $breakpoint-site-medium,\n wide: $breakpoint-site-wide,\n x-wide: $breakpoint-site-x_wide,\n);\n\n@import \"../vendor/sass-mq/_mq\";\n","$breakpoint-site-x_small: 320px;\n$breakpoint-site-small: 480px;\n$breakpoint-site-medium: 730px;\n$breakpoint-site-wide: 900px;\n$breakpoint-site-x_wide: 1200px;\n","@charset \"UTF-8\"; // Fixes an issue where Ruby locale is not set properly\n // See https://github.com/sass-mq/sass-mq/pull/10\n\n/// Base font size on the `` element\n/// @type Number (unit)\n$mq-base-font-size: 16px !default;\n\n/// Responsive mode\n///\n/// Set to `false` to enable support for browsers that do not support @media queries,\n/// (IE <= 8, Firefox <= 3, Opera <= 9)\n///\n/// You could create a stylesheet served exclusively to older browsers,\n/// where @media queries are rasterized\n///\n/// @example scss\n/// // old-ie.scss\n/// $mq-responsive: false;\n/// @import 'main'; // @media queries in this file will be rasterized up to $mq-static-breakpoint\n/// // larger breakpoints will be ignored\n///\n/// @type Boolean\n/// @link https://github.com/sass-mq/sass-mq#responsive-mode-off Disabled responsive mode documentation\n$mq-responsive: true !default;\n\n/// Breakpoint list\n///\n/// Name your breakpoints in a way that creates a ubiquitous language\n/// across team members. It will improve communication between\n/// stakeholders, designers, developers, and testers.\n///\n/// @type Map\n/// @link https://github.com/sass-mq/sass-mq#seeing-the-currently-active-breakpoint Full documentation and examples\n$mq-breakpoints: (\n mobile: 320px,\n tablet: 740px,\n desktop: 980px,\n wide: 1300px\n) !default;\n\n/// Static breakpoint (for fixed-width layouts)\n///\n/// Define the breakpoint from $mq-breakpoints that should\n/// be used as the target width for the fixed-width layout\n/// (i.e. when $mq-responsive is set to 'false') in a old-ie.scss\n///\n/// @example scss\n/// // tablet-only.scss\n/// //\n/// // Ignore all styles above tablet breakpoint,\n/// // and fix the styles (e.g. layout) at tablet width\n/// $mq-responsive: false;\n/// $mq-static-breakpoint: tablet;\n/// @import 'main'; // @media queries in this file will be rasterized up to tablet\n/// // larger breakpoints will be ignored\n///\n/// @type String\n/// @link https://github.com/sass-mq/sass-mq#adding-custom-breakpoints Full documentation and examples\n$mq-static-breakpoint: desktop !default;\n\n/// Show breakpoints in the top right corner\n///\n/// If you want to display the currently active breakpoint in the top\n/// right corner of your site during development, add the breakpoints\n/// to this list, ordered by width, e.g. (mobile, tablet, desktop).\n///\n/// @type map\n$mq-show-breakpoints: () !default;\n\n/// Customize the media type (e.g. `@media screen` or `@media print`)\n/// By default sass-mq uses an \"all\" media type (`@media all and …`)\n///\n/// @type String\n/// @link https://github.com/sass-mq/sass-mq#changing-media-type Full documentation and examples\n$mq-media-type: all !default;\n\n/// Convert pixels to ems\n///\n/// @param {Number} $px - value to convert\n/// @param {Number} $base-font-size ($mq-base-font-size) - `` font size\n///\n/// @example scss\n/// $font-size-in-ems: mq-px2em(16px);\n/// p { font-size: mq-px2em(16px); }\n///\n/// @requires $mq-base-font-size\n/// @returns {Number}\n@function mq-px2em($px, $base-font-size: $mq-base-font-size) {\n @if unitless($px) {\n @warn \"Assuming #{$px} to be in pixels, attempting to convert it into pixels.\";\n @return mq-px2em($px * 1px, $base-font-size);\n } @else if unit($px) == em {\n @return $px;\n }\n @return ($px / $base-font-size) * 1em;\n}\n\n/// Get a breakpoint's width\n///\n/// @param {String} $name - Name of the breakpoint. One of $mq-breakpoints\n///\n/// @example scss\n/// $tablet-width: mq-get-breakpoint-width(tablet);\n/// @media (min-width: mq-get-breakpoint-width(desktop)) {}\n///\n/// @requires {Variable} $mq-breakpoints\n///\n/// @returns {Number} Value in pixels\n@function mq-get-breakpoint-width($name, $breakpoints: $mq-breakpoints) {\n @if map-has-key($breakpoints, $name) {\n @return map-get($breakpoints, $name);\n } @else {\n @warn \"Breakpoint #{$name} wasn't found in $breakpoints.\";\n }\n}\n\n/// Media Query mixin\n///\n/// @param {String | Boolean} $from (false) - One of $mq-breakpoints\n/// @param {String | Boolean} $until (false) - One of $mq-breakpoints\n/// @param {String | Boolean} $and (false) - Additional media query parameters\n/// @param {String} $media-type ($mq-media-type) - Media type: screen, print…\n///\n/// @ignore Undocumented API, for advanced use only:\n/// @ignore @param {Map} $breakpoints ($mq-breakpoints)\n/// @ignore @param {String} $static-breakpoint ($mq-static-breakpoint)\n///\n/// @content styling rules, wrapped into a @media query when $responsive is true\n///\n/// @requires {Variable} $mq-media-type\n/// @requires {Variable} $mq-breakpoints\n/// @requires {Variable} $mq-static-breakpoint\n/// @requires {function} mq-px2em\n/// @requires {function} mq-get-breakpoint-width\n///\n/// @link https://github.com/sass-mq/sass-mq#responsive-mode-on-default Full documentation and examples\n///\n/// @example scss\n/// .element {\n/// @include mq($from: mobile) {\n/// color: red;\n/// }\n/// @include mq($until: tablet) {\n/// color: blue;\n/// }\n/// @include mq(mobile, tablet) {\n/// color: green;\n/// }\n/// @include mq($from: tablet, $and: '(orientation: landscape)') {\n/// color: teal;\n/// }\n/// @include mq(950px) {\n/// color: hotpink;\n/// }\n/// @include mq(tablet, $media-type: screen) {\n/// color: hotpink;\n/// }\n/// // Advanced use:\n/// $my-breakpoints: (L: 900px, XL: 1200px);\n/// @include mq(L, $breakpoints: $my-breakpoints, $static-breakpoint: L) {\n/// color: hotpink;\n/// }\n/// }\n@mixin mq(\n $from: false,\n $until: false,\n $and: false,\n $media-type: $mq-media-type,\n $breakpoints: $mq-breakpoints,\n $responsive: $mq-responsive,\n $static-breakpoint: $mq-static-breakpoint\n) {\n $min-width: 0;\n $max-width: 0;\n $media-query: '';\n\n // From: this breakpoint (inclusive)\n @if $from {\n @if type-of($from) == number {\n $min-width: mq-px2em($from);\n } @else {\n $min-width: mq-px2em(mq-get-breakpoint-width($from, $breakpoints));\n }\n }\n\n // Until: that breakpoint (exclusive)\n @if $until {\n @if type-of($until) == number {\n $max-width: mq-px2em($until);\n } @else {\n $max-width: mq-px2em(mq-get-breakpoint-width($until, $breakpoints)) - .01em;\n }\n }\n\n // Responsive support is disabled, rasterize the output outside @media blocks\n // The browser will rely on the cascade itself.\n @if $responsive == false {\n $static-breakpoint-width: mq-get-breakpoint-width($static-breakpoint, $breakpoints);\n $target-width: mq-px2em($static-breakpoint-width);\n\n // Output only rules that start at or span our target width\n @if (\n $and == false\n and $min-width <= $target-width\n and (\n $until == false or $max-width >= $target-width\n )\n and $media-type != 'print'\n ) {\n @content;\n }\n }\n\n // Responsive support is enabled, output rules inside @media queries\n @else {\n @if $min-width != 0 { $media-query: '#{$media-query} and (min-width: #{$min-width})'; }\n @if $max-width != 0 { $media-query: '#{$media-query} and (max-width: #{$max-width})'; }\n @if $and { $media-query: '#{$media-query} and #{$and}'; }\n\n // Remove unnecessary media query prefix 'all and '\n @if ($media-type == 'all' and $media-query != '') {\n $media-type: '';\n $media-query: str-slice(unquote($media-query), 6);\n }\n\n @media #{$media-type + $media-query} {\n @content;\n }\n }\n}\n\n/// Quick sort\n///\n/// @author Sam Richards\n/// @access private\n/// @param {List} $list - List to sort\n/// @returns {List} Sorted List\n@function _mq-quick-sort($list) {\n $less: ();\n $equal: ();\n $large: ();\n\n @if length($list) > 1 {\n $seed: nth($list, ceil(length($list) / 2));\n\n @each $item in $list {\n @if ($item == $seed) {\n $equal: append($equal, $item);\n } @else if ($item < $seed) {\n $less: append($less, $item);\n } @else if ($item > $seed) {\n $large: append($large, $item);\n }\n }\n\n @return join(join(_mq-quick-sort($less), $equal), _mq-quick-sort($large));\n }\n\n @return $list;\n}\n\n/// Sort a map by values (works with numbers only)\n///\n/// @access private\n/// @param {Map} $map - Map to sort\n/// @returns {Map} Map sorted by value\n@function _mq-map-sort-by-value($map) {\n $map-sorted: ();\n $map-keys: map-keys($map);\n $map-values: map-values($map);\n $map-values-sorted: _mq-quick-sort($map-values);\n\n // Reorder key/value pairs based on key values\n @each $value in $map-values-sorted {\n $index: index($map-values, $value);\n $key: nth($map-keys, $index);\n $map-sorted: map-merge($map-sorted, ($key: $value));\n\n // Unset the value in $map-values to prevent the loop\n // from finding the same index twice\n $map-values: set-nth($map-values, $index, 0);\n }\n\n @return $map-sorted;\n}\n\n/// Add a breakpoint\n///\n/// @param {String} $name - Name of the breakpoint\n/// @param {Number} $width - Width of the breakpoint\n///\n/// @requires {Variable} $mq-breakpoints\n///\n/// @example scss\n/// @include mq-add-breakpoint(tvscreen, 1920px);\n/// @include mq(tvscreen) {}\n@mixin mq-add-breakpoint($name, $width) {\n $new-breakpoint: ($name: $width);\n $mq-breakpoints: map-merge($mq-breakpoints, $new-breakpoint) !global;\n $mq-breakpoints: _mq-map-sort-by-value($mq-breakpoints) !global;\n}\n\n/// Show the active breakpoint in the top right corner of the viewport\n/// @link https://github.com/sass-mq/sass-mq#seeing-the-currently-active-breakpoint\n///\n/// @param {List} $show-breakpoints ($mq-show-breakpoints) - List of breakpoints to show in the top right corner\n/// @param {Map} $breakpoints ($mq-breakpoints) - Breakpoint names and sizes\n///\n/// @requires {Variable} $mq-breakpoints\n/// @requires {Variable} $mq-show-breakpoints\n///\n/// @example scss\n/// // Show breakpoints using global settings\n/// @include mq-show-breakpoints;\n///\n/// // Show breakpoints using custom settings\n/// @include mq-show-breakpoints((L, XL), (S: 300px, L: 800px, XL: 1200px));\n@mixin mq-show-breakpoints($show-breakpoints: $mq-show-breakpoints, $breakpoints: $mq-breakpoints) {\n body:before {\n background-color: #FCF8E3;\n border-bottom: 1px solid #FBEED5;\n border-left: 1px solid #FBEED5;\n color: #C09853;\n font: small-caption;\n padding: 3px 6px;\n pointer-events: none;\n position: fixed;\n right: 0;\n top: 0;\n z-index: 100;\n\n // Loop through the breakpoints that should be shown\n @each $show-breakpoint in $show-breakpoints {\n $width: mq-get-breakpoint-width($show-breakpoint, $breakpoints);\n @include mq($show-breakpoint, $breakpoints: $breakpoints) {\n content: \"#{$show-breakpoint} ≥ #{$width} (#{mq-px2em($width)})\";\n }\n }\n }\n}\n\n@if length($mq-show-breakpoints) > 0 {\n @include mq-show-breakpoints;\n}\n","@import \"logical-properties\";\n@import \"types\";\n@import \"validation\";\n\n@mixin block-size($size) {\n @include _expect_single_value($size) {\n @include logical-property(\"\", block-size, ($size));\n }\n}\n\n@mixin inline-size($size) {\n @include _expect_single_value($size) {\n @include logical-property(\"\", inline-size, ($size));\n }\n}\n\n@mixin _constrain-block-size($size, $extreme) {\n @include logical-property($extreme, block-size, ($size));\n}\n\n@mixin _constrain-inline-size($size, $extreme) {\n @include logical-property($extreme, inline-size, ($size));\n}\n\n@mixin max-block-size($size) {\n @include _expect_single_value($size) {\n @include _constrain-block-size($size, max);\n }\n}\n\n@mixin min-block-size($size) {\n @include _expect_single_value($size) {\n @include _constrain-block-size($size, min);\n }\n}\n\n@mixin max-inline-size($size) {\n @include _expect_single_value($size) {\n @include _constrain-inline-size($size, max);\n }\n}\n\n@mixin min-inline-size($size) {\n @include _expect_single_value($size) {\n @include _constrain-inline-size($size, min);\n }\n}\n\n@mixin truncate-with-ellipsis() {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n\n &:lang(zh-Hant-HK) {\n text-overflow: \"⋯\";\n }\n}\n","$baselinegrid-space-extra_small: 12px;\n$baselinegrid-space-small: 24px;\n$baselinegrid-space-smallish: 36px;\n$baselinegrid-space-medium: 48px;\n$baselinegrid-space-large: 72px;\n$baselinegrid-space-extra_large: 120px;\n","@import \"../mixins/types\";\n@import \"../variables/baselinegrid\";\n@import \"../variables/color\";\n@import \"../variables/font\";\n@import \"spacing\";\n@import \"utilities\";\n@import \"scale\";\n\n@mixin set-font-size-and-line-height($font-size, $block-size: $baselinegrid-space-small) {\n @include rem(font-size, $font-size);\n line-height: $block-size / $font-size;\n}\n\n@mixin _heading-base-typography() {\n font-family: $font-secondary;\n font-weight: 600;\n}\n\n@mixin h1-typography() {\n @include _heading-base-typography();\n @include set-font-size-and-line-height(scale(7), $baselinegrid-space-medium);\n}\n\n@mixin h2-typography() {\n @include _heading-base-typography();\n @include set-font-size-and-line-height(scale(4), ($baselinegrid-space-small + $baselinegrid-space-smallish) / 2);\n}\n\n@mixin h3-typography() {\n @include _heading-base-typography();\n @include set-font-size-and-line-height(scale(3));\n}\n\n@mixin h4-typography() {\n @include _heading-base-typography();\n @include set-font-size-and-line-height(scale(2));\n}\n\n@mixin h5-typography() {\n @include _heading-base-typography();\n @include set-font-size-and-line-height(scale(1));\n}\n\n@mixin h6-typography() {\n @include _heading-base-typography();\n @include set-font-size-and-line-height(scale(0));\n}\n\n@mixin body-typography() {\n font-family: $font-primary;\n @include set-font-size-and-line-height(scale(0));\n font-weight: normal;\n}\n\n@mixin inline-image {\n @include margin(0.1em, block-end);\n @include max-block-size(1em);\n vertical-align: middle;\n}\n\n@mixin _base-font-variant-position($position) {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n @supports (font-variant-position: #{$position}) {\n font-size: inherit;\n font-variant-position: $position;\n position: static;\n }\n}\n\n@mixin font-variant-position($position) {\n @if $position == sub {\n @include _base_font-variant-position($position);\n bottom: -0.25em; // stylelint-disable-line csstools/use-logical\n } @else if $position == super {\n @include _base_font-variant-position($position);\n top: -0.5em; // stylelint-disable-line csstools/use-logical\n } @else {\n @include _error(\"Unknown position '#{$position}'\");\n }\n}\n\n@mixin _label-typography($color, $uppercase: true) {\n color: $color;\n font-family: $font-secondary;\n font-weight: normal;\n @include set-font-size-and-line-height(scale(-3));\n letter-spacing: $font-letterspacing-label;\n @if $uppercase {\n text-transform: uppercase;\n }\n}\n\n@mixin label-content-typography($color: $color-text-secondary, $uppercase: true) {\n @include _label-typography($color, $uppercase);\n}\n\n@mixin label-tag-typography() {\n @include _label-typography($color-primary-normal);\n}\n\n@mixin covert-link($hover-color: $color-primary-dark) {\n @include inherit-all($ensure: color text-decoration);\n cursor: pointer;\n\n &:hover {\n color: $hover-color;\n }\n}\n\n@mixin list-style-none() {\n @include padding(0, inline-start);\n // Overflow auto is so the bullet will be still read from a screen reader and will push the bullet off screen\n overflow: auto;\n}\n","@mixin inherit-all($ensure: ()) {\n @each $property in $ensure {\n #{$property}: inherit;\n }\n\n all: inherit;\n}\n","@import \"../variables/font\";\n@import \"../vendor/modularscale-sass/stylesheets/modularscale\";\n\n@function scale($value: 0) {\n @return round(ms-function($value, $font-size, $major-second));\n}\n","// Defaults and variables\n@import 'modularscale/vars';\n\n// Core functions\n@import 'modularscale/settings';\n@import 'modularscale/pow';\n@import 'modularscale/strip-units';\n@import 'modularscale/sort';\n@import 'modularscale/target';\n@import 'modularscale/function';\n@import 'modularscale/round-px';\n\n// Mixins\n@import 'modularscale/respond';\n\n// Syntax sugar\n@import 'modularscale/sugar';","// Ratios\n$double-octave : 4 ;\n$pi : 3.14159265359 ;\n$major-twelfth : 3 ;\n$major-eleventh : 2.666666667 ;\n$major-tenth : 2.5 ;\n$octave : 2 ;\n$major-seventh : 1.875 ;\n$minor-seventh : 1.777777778 ;\n$major-sixth : 1.666666667 ;\n$phi : 1.618034 ;\n$golden : $phi ;\n$minor-sixth : 1.6 ;\n$fifth : 1.5 ;\n$augmented-fourth : 1.41421 ;\n$fourth : 1.333333333 ;\n$major-third : 1.25 ;\n$minor-third : 1.2 ;\n$major-second : 1.125 ;\n$minor-second : 1.066666667 ;\n\n// Base config\n$ms-base : 1em !default;\n$ms-ratio : $fifth !default;\n$modularscale : () !default;","// Parse settings starting with defaults.\n// Settings should cascade down like you would expect in CSS.\n// More specific overrides previous settings.\n\n@function ms-settings($b: false, $r: false, $t: false, $m: $modularscale) {\n $base: $ms-base;\n $ratio: $ms-ratio;\n $thread: map-get($m, $t);\n\n // Override with user settings\n @if map-get($m, base) {\n $base: map-get($m, base);\n }\n @if map-get($m, ratio) {\n $ratio: map-get($m, ratio);\n }\n\n // Override with thread settings\n @if $thread {\n @if map-get($thread, base) {\n $base: map-get($thread, base);\n }\n @if map-get($thread, ratio) {\n $ratio: map-get($thread, ratio);\n }\n }\n\n // Override with inline settings\n @if $b {\n $base: $b;\n }\n @if $r {\n $ratio: $r;\n }\n\n @return $base $ratio;\n}","// Sass does not have native pow() support so this needs to be added.\n// Compass and other libs implement this more extensively.\n// In order to keep this simple, use those when they are avalible.\n// Issue for pow() support in Sass: https://github.com/sass/sass/issues/684\n\n@function ms-pow($b,$e) {\n\n // Return 1 if exponent is 0\n @if $e == 0 {\n @return 1;\n }\n\n // If pow() exists (compass or mathsass) use that.\n @if function-exists('pow') {\n @return pow($b,$e);\n }\n\n // This does not support non-integer exponents,\n // Check and return an error if a non-integer exponent is passed.\n @if (floor($e) != $e) {\n @error 'Non-integer values are not supported in modularscale by default. Try using mathsass in your project to add non-integer scale support. https://github.com/terkel/mathsass'\n }\n\n // Seed the return.\n $ms-return: $b;\n\n // Multiply or divide by the specified number of times.\n @if $e > 0 {\n @for $i from 1 to $e {\n $ms-return: $ms-return * $b;\n }\n }\n @if $e < 0 {\n @for $i from $e through 0 {\n $ms-return: $ms-return / $b;\n }\n }\n @return $ms-return;\n}","// Stripping units is not a best practice\n// This function should not be used elsewhere\n// It is used here because calc() doesn't do unit logic\n// AND target ratios use units as a hack to get a number.\n@function ms-unitless($val) {\n @return ($val / ($val - $val + 1));\n}","// Basic list sorting\n// Would like to replace with http://sassmeister.com/gist/30e4863bd03ce0e1617c\n// Unfortunately libsass has a bug with passing arguments into the min() funciton.\n\n@function ms-sort($l) {\n\n // loop until the list is confirmed to be sorted\n $sorted: false;\n @while $sorted == false {\n\n // Start with the assumption that the lists are sorted.\n $sorted: true;\n\n // Loop through the list, checking each value with the one next to it.\n // Swap the values if they need to be swapped.\n // Not super fast but simple and modular scale doesn't lean hard on sorting.\n @for $i from 2 through length($l) {\n $n1: nth($l,$i - 1);\n $n2: nth($l,$i);\n\n // If the first value is greater than the 2nd, swap them.\n @if $n1 > $n2 {\n $l: set-nth($l, $i, $n1);\n $l: set-nth($l, $i - 1, $n2);\n\n // The list isn't sorted and needs to be looped through again.\n $sorted: false;\n }\n }\n }\n\n // Return the sorted list.\n @return $l;\n}","// Convert number string to number\n@function ms-to-num($n) {\n $l: str-length($n);\n $r: 0;\n $m: str-index($n,'.');\n @if $m == null {\n $m: $l + 1;\n }\n // Loop through digits and convert to numbers\n @for $i from 1 through $l {\n $v: str-slice($n,$i,$i);\n @if $v == '1' { $v: 1; }\n @else if $v == '2' { $v: 2; }\n @else if $v == '3' { $v: 3; }\n @else if $v == '4' { $v: 4; }\n @else if $v == '5' { $v: 5; }\n @else if $v == '6' { $v: 6; }\n @else if $v == '7' { $v: 7; }\n @else if $v == '8' { $v: 8; }\n @else if $v == '9' { $v: 9; }\n @else if $v == '0' { $v: 0; }\n @else { $v: null; }\n @if $v != null {\n $m: $m - 1;\n $r: $r + ms-pow(10,$m - 1) * $v;\n } @else {\n $l: $l - 1;\n }\n }\n @return $r;\n}\n\n// Find a ratio based on a target value\n@function ms-target($t,$b) {\n // Convert to string\n $t: $t + '';\n // Remove base units to calulate ratio\n $b: ms-unitless(nth($b,1));\n // Find where 'at' is in the string\n $at: str-index($t,'at');\n\n // Slice the value and target out\n // and convert strings to numbers\n $v: ms-to-num(str-slice($t,0,$at - 1));\n $t: ms-to-num(str-slice($t,$at + 2));\n\n // Solve the modular scale function for the ratio.\n @return ms-pow(($v/$b),(1/$t));\n}","@function ms-function($v: 0, $base: false, $ratio: false, $thread: false, $settings: $modularscale) {\n\n // Parse settings\n $ms-settings: ms-settings($base,$ratio,$thread,$settings);\n $base: nth($ms-settings, 1);\n $ratio: nth($ms-settings, 2);\n\n // Render target values from settings.\n @if unit($ratio) != '' {\n $ratio: ms-target($ratio,$base)\n }\n\n // Fast calc if not multi stranded\n @if(length($base) == 1) {\n @return ms-pow($ratio, $v) * $base;\n }\n\n // Create new base array\n $ms-bases: nth($base,1);\n\n // Normalize base values\n @for $i from 2 through length($base) {\n // initial base value\n $ms-base: nth($base,$i);\n // If the base is bigger than the main base\n @if($ms-base > nth($base,1)) {\n // divide the value until it aligns with main base.\n @while($ms-base > nth($base,1)) {\n $ms-base: $ms-base / $ratio;\n }\n $ms-base: $ms-base * $ratio;\n }\n // If the base is smaller than the main base.\n @else if ($ms-base < nth($base,1)) {\n // pump up the value until it aligns with main base.\n @while $ms-base < nth($base,1) {\n $ms-base: $ms-base * $ratio;\n }\n }\n // Push into new array\n $ms-bases: append($ms-bases,$ms-base);\n }\n\n // Sort array from smallest to largest.\n $ms-bases: ms-sort($ms-bases);\n\n // Find step to use in calculation\n $vtep: floor($v / length($ms-bases));\n // Find base to use in calculation\n $ms-base: round(($v / length($ms-bases) - $vtep) * length($ms-bases)) + 1;\n\n @return ms-pow($ratio, $vtep) * nth($ms-bases,$ms-base);\n}","@function ms-round-px($r) {\n @if unit($r) == 'px' {\n @return round($r);\n }\n @warn \"ms-round-px is no longer used by modular scale and will be removed in the 3.1.0 release.\";\n @return $r;\n}","// Generate calc() function\n// based on Mike Riethmuller's Precise control over responsive typography\n// http://madebymike.com.au/writing/precise-control-responsive-typography/\n@function ms-fluid($val1: 1em, $val2: 1em, $break1: 0, $break2: 0) {\n $diff: ms-unitless($val2) - ms-unitless($val1);\n\n // v1 + (v2 - v1) * ( (100vw - b1) / b2 - b1 )\n @return calc( #{$val1} + #{ms-unitless($val2) - ms-unitless($val1)} * ( ( 100vw - #{$break1}) / #{ms-unitless($break2) - ms-unitless($break1)} ) );\n}\n\n// Main responsive mixin\n@mixin ms-respond($prop, $val, $map: $modularscale, $ms-important: false) {\n $base: $ms-base;\n $ratio: $ms-ratio;\n\n $first-write: true;\n $last-break: null;\n\n $important: '';\n\n @if $ms-important == true {\n $important: ' !important';\n }\n\n // loop through all settings with a breakpoint type value\n @each $v, $s in $map {\n @if type-of($v) == number {\n @if unit($v) != '' {\n\n // Write out the first value without a media query.\n @if $first-write {\n #{$prop}: unquote(\"#{ms-function($val, $thread: $v, $settings: $map)}#{$important}\");\n\n // Not the first write anymore, reset to false to move on.\n $first-write: false;\n $last-break: $v;\n }\n\n // Write intermediate breakpoints.\n @else {\n @media (min-width: $last-break) and (max-width: $v) {\n $val1: ms-function($val, $thread: $last-break, $settings: $map);\n $val2: ms-function($val, $thread: $v, $settings: $map);\n #{$prop}: unquote(\"#{ms-fluid($val1,$val2,$last-break,$v)}#{$important}\");\n }\n $last-break: $v;\n }\n }\n }\n }\n\n // Write the last breakpoint.\n @if $last-break {\n @media (min-width: $last-break) {\n #{$prop}: unquote(\"#{ms-function($val, $thread: $last-break, $settings: $map)}#{$important}\");\n }\n }\n}","// To attempt to avoid conflicts with other libraries\n// all funcitons are namespaced with `ms-`.\n// However, to increase usability, a shorthand function is included here.\n\n@function ms($v: 0, $base: false, $ratio: false, $thread: false, $settings: $modularscale) {\n @return ms-function($v, $base, $ratio, $thread, $settings);\n}","/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */\n\n/* Document\n ========================================================================== */\n\n/**\n * 1. Correct the line height in all browsers.\n * 2. Prevent adjustments of font size after orientation changes in iOS.\n */\n\nhtml {\n line-height: 1.15; /* 1 */\n -webkit-text-size-adjust: 100%; /* 2 */\n}\n\n/* Sections\n ========================================================================== */\n\n/**\n * Remove the margin in all browsers.\n */\n\nbody {\n margin: 0;\n}\n\n/**\n * Render the `main` element consistently in IE.\n */\n\nmain {\n display: block;\n}\n\n/**\n * Correct the font size and margin on `h1` elements within `section` and\n * `article` contexts in Chrome, Firefox, and Safari.\n */\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n/* Grouping content\n ========================================================================== */\n\n/**\n * 1. Add the correct box sizing in Firefox.\n * 2. Show the overflow in Edge and IE.\n */\n\nhr {\n box-sizing: content-box; /* 1 */\n height: 0; /* 1 */\n overflow: visible; /* 2 */\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\npre {\n font-family: monospace, monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/* Text-level semantics\n ========================================================================== */\n\n/**\n * Remove the gray background on active links in IE 10.\n */\n\na {\n background-color: transparent;\n}\n\n/**\n * 1. Remove the bottom border in Chrome 57-\n * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n */\n\nabbr[title] {\n border-bottom: none; /* 1 */\n text-decoration: underline; /* 2 */\n text-decoration: underline dotted; /* 2 */\n}\n\n/**\n * Add the correct font weight in Chrome, Edge, and Safari.\n */\n\nb,\nstrong {\n font-weight: bolder;\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\ncode,\nkbd,\nsamp {\n font-family: monospace, monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/**\n * Add the correct font size in all browsers.\n */\n\nsmall {\n font-size: 80%;\n}\n\n/**\n * Prevent `sub` and `sup` elements from affecting the line height in\n * all browsers.\n */\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -0.25em;\n}\n\nsup {\n top: -0.5em;\n}\n\n/* Embedded content\n ========================================================================== */\n\n/**\n * Remove the border on images inside links in IE 10.\n */\n\nimg {\n border-style: none;\n}\n\n/* Forms\n ========================================================================== */\n\n/**\n * 1. Change the font styles in all browsers.\n * 2. Remove the margin in Firefox and Safari.\n */\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n font-family: inherit; /* 1 */\n font-size: 100%; /* 1 */\n line-height: 1.15; /* 1 */\n margin: 0; /* 2 */\n}\n\n/**\n * Show the overflow in IE.\n * 1. Show the overflow in Edge.\n */\n\nbutton,\ninput { /* 1 */\n overflow: visible;\n}\n\n/**\n * Remove the inheritance of text transform in Edge, Firefox, and IE.\n * 1. Remove the inheritance of text transform in Firefox.\n */\n\nbutton,\nselect { /* 1 */\n text-transform: none;\n}\n\n/**\n * Correct the inability to style clickable types in iOS and Safari.\n */\n\nbutton,\n[type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\n/**\n * Remove the inner border and padding in Firefox.\n */\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n border-style: none;\n padding: 0;\n}\n\n/**\n * Restore the focus styles unset by the previous rule.\n */\n\nbutton:-moz-focusring,\n[type=\"button\"]:-moz-focusring,\n[type=\"reset\"]:-moz-focusring,\n[type=\"submit\"]:-moz-focusring {\n outline: 1px dotted ButtonText;\n}\n\n/**\n * Correct the padding in Firefox.\n */\n\nfieldset {\n padding: 0.35em 0.75em 0.625em;\n}\n\n/**\n * 1. Correct the text wrapping in Edge and IE.\n * 2. Correct the color inheritance from `fieldset` elements in IE.\n * 3. Remove the padding so developers are not caught out when they zero out\n * `fieldset` elements in all browsers.\n */\n\nlegend {\n box-sizing: border-box; /* 1 */\n color: inherit; /* 2 */\n display: table; /* 1 */\n max-width: 100%; /* 1 */\n padding: 0; /* 3 */\n white-space: normal; /* 1 */\n}\n\n/**\n * Add the correct vertical alignment in Chrome, Firefox, and Opera.\n */\n\nprogress {\n vertical-align: baseline;\n}\n\n/**\n * Remove the default vertical scrollbar in IE 10+.\n */\n\ntextarea {\n overflow: auto;\n}\n\n/**\n * 1. Add the correct box sizing in IE 10.\n * 2. Remove the padding in IE 10.\n */\n\n[type=\"checkbox\"],\n[type=\"radio\"] {\n box-sizing: border-box; /* 1 */\n padding: 0; /* 2 */\n}\n\n/**\n * Correct the cursor style of increment and decrement buttons in Chrome.\n */\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n/**\n * 1. Correct the odd appearance in Chrome and Safari.\n * 2. Correct the outline style in Safari.\n */\n\n[type=\"search\"] {\n -webkit-appearance: textfield; /* 1 */\n outline-offset: -2px; /* 2 */\n}\n\n/**\n * Remove the inner padding in Chrome and Safari on macOS.\n */\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n/**\n * 1. Correct the inability to style clickable types in iOS and Safari.\n * 2. Change font properties to `inherit` in Safari.\n */\n\n::-webkit-file-upload-button {\n -webkit-appearance: button; /* 1 */\n font: inherit; /* 2 */\n}\n\n/* Interactive\n ========================================================================== */\n\n/*\n * Add the correct display in Edge, IE 10+, and Firefox.\n */\n\ndetails {\n display: block;\n}\n\n/*\n * Add the correct display in all browsers.\n */\n\nsummary {\n display: list-item;\n}\n\n/* Misc\n ========================================================================== */\n\n/**\n * Add the correct display in IE 10+.\n */\n\ntemplate {\n display: none;\n}\n\n/**\n * Add the correct display in IE 10.\n */\n\n[hidden] {\n display: none;\n}\n","@import \"mixins/logical-properties\";\n@import \"mixins/media-query\";\n@import \"variables/grid\";\n\n:root {\n --GRID-COLUMN-GAP: #{$grid-column_gap};\n --GRID-EDGE-SPACE: #{$grid-edge_space-medium};\n --GRID-COLUMN-WIDTH: calc((100% - (var(--GRID-EDGE-SPACE) * 2) - (var(--GRID-COLUMN-GAP) * #{$grid-main_column_count - 1})) / #{$grid-main_column_count});\n\n @include mq($from: medium) {\n --GRID-EDGE-SPACE: #{$grid-edge_space-large};\n }\n\n @include mq($from: x-wide) {\n --GRID-COLUMN-GAP: #{($grid-max_width * $grid-column_gap) / 100%};\n --GRID-COLUMN-WIDTH: calc((#{$grid-max_width} - (var(--GRID-COLUMN-GAP) * #{$grid-main_column_count - 1})) / #{$grid-main_column_count});\n }\n\n @include logical-property(min, inline-size, $grid-min_width, $to-rem: false);\n}\n","@import \"../../mixins/typography\";\n\n.heading__link {\n @include covert-link();\n}\n","@import \"../../mixins/spacing\";\n@import \"../../mixins/typography\";\n\n.content-meta {\n @include list-style-none();\n @include block-spacing();\n}\n\n.content-meta__item {\n display: inline-block;\n @include label-content-typography();\n\n &:after {\n content: \"\\a0\\2022\\a0\";\n }\n\n &:last-child:after {\n content: \"\";\n }\n}\n\n.content-meta__link {\n @include covert-link();\n}\n","@import \"../../mixins/spacing\";\n@import \"../../variables/baselinegrid\";\n\n.section__body {\n @include block-spacing($end: $baselinegrid-space-medium);\n}\n","@import \"../../mixins/sizes\";\n@import \"../../mixins/typography\";\n@import \"../../variables/baselinegrid\";\n\n.tag-list {\n @include block-spacing();\n}\n\n.tag-list__title {\n @include label-content-typography();\n @include block-spacing($end: 0);\n}\n\n.tag-list__list {\n @include list-style-none();\n @include label-tag-typography();\n}\n\n.tag-list__list--single-line {\n @include truncate-with-ellipsis();\n}\n\n.tag-list__item {\n display: inline-block;\n @include label-tag-typography();\n\n &:after {\n display: inline;\n content: \",\\a0\";\n }\n\n &:lang(ar):after {\n content: \"،\\a0\";\n }\n\n &:lang(ja):after {\n content: \"、\";\n }\n\n &:last-child:after {\n content: \"\";\n }\n}\n\n.tag-list__link {\n @include covert-link();\n}\n","@import \"../../mixins/decorations\";\n@import \"../../mixins/spacing\";\n@import \"../../mixins/typography\";\n\n.teaser__heading {\n @include h4-typography();\n @include block-spacing($start:$baselinegrid-space-small, $end: $baselinegrid-space-small);\n}\n","@import \"../../functions/types\";\n@import \"../../mixins/scale\";\n@import \"../../mixins/decorations\";\n@import \"../../mixins/media-query\";\n@import \"../../mixins/spacing\";\n@import \"../../variables/baselinegrid\";\n@import \"../../variables/grid\";\n\n.content-header {\n text-align: center;\n @include padding($baselinegrid-space-medium, block-start);\n @include block-spacing($end: $baselinegrid-space-medium - $grid-divider_size);\n @include divider(block-end);\n}\n\n.content-header__title {\n @include block-spacing($end: $baselinegrid-space-small);\n\n &:last-child {\n @include block-spacing($end: $baselinegrid-space-medium);\n }\n}\n\n.content-header__title--xx-short {\n @include rem(font-size, scale(9));\n\n @include mq($from: small) {\n @include rem(font-size, scale(10));\n }\n}\n\n.content-header__title--x-short {\n @include rem(font-size, scale(8));\n\n @include mq($from: medium) {\n @include rem(font-size, scale(9));\n }\n\n @include mq($from: wide) {\n @include rem(font-size, scale(10));\n }\n}\n\n.content-header__title--short {\n @include rem(font-size, scale(6));\n\n @include mq($from: small) {\n @include rem(font-size, scale(7));\n }\n\n @include mq($from: medium) {\n @include rem(font-size, scale(8));\n }\n\n @include mq($from: wide) {\n @include rem(font-size, scale(9));\n }\n\n @include mq($from: x-wide) {\n @include rem(font-size, scale(10));\n }\n}\n\n.content-header__title--medium {\n @include rem(font-size, scale(4));\n\n @include mq($from: small) {\n @include rem(font-size, scale(6));\n }\n\n @include mq($from: medium) {\n @include rem(font-size, scale(7));\n }\n\n @include mq($from: wide) {\n @include rem(font-size, scale(8));\n }\n\n @include mq($from: x-wide) {\n @include rem(font-size, scale(10));\n }\n}\n\n.content-header__title--long {\n @include rem(font-size, scale(2));\n\n @include mq($from: small) {\n @include rem(font-size, scale(4));\n }\n\n @include mq($from: medium) {\n @include rem(font-size, scale(7));\n }\n\n @include mq($from: x-wide) {\n @include rem(font-size, scale(8));\n }\n\n}\n\n.content-header__title--x-long {\n @include rem(font-size, scale(2));\n\n @include mq($from: medium) {\n @include rem(font-size, scale(4));\n }\n\n @include mq($from: wide) {\n @include rem(font-size, scale(4));\n }\n\n @include mq($from: x-wide) {\n @include rem(font-size, scale(6));\n }\n}\n\n.content-header__title--xx-long {\n @include rem(font-size, scale(1));\n\n @include mq($from: small) {\n @include rem(font-size, scale(2));\n }\n\n @include mq($from: wide) {\n @include rem(font-size, scale(4));\n }\n}\n","@import \"../mixins/types\";\n@import \"../variables/font\";\n\n$rem-baseline: $font-size;\n$rem-fallback: true;\n","@import \"../../mixins/decorations\";\n@import \"../../mixins/media-query\";\n@import \"../../mixins/spacing\";\n@import \"../../variables/baselinegrid\";\n@import \"../../variables/grid\";\n\n.item-tags {\n @include padding($baselinegrid-space-medium - $grid-divider_size, block-start);\n @include block-spacing($end: $baselinegrid-space-medium);\n @include divider(block-start);\n text-align: center;\n\n @include mq($from: medium) {\n text-align: initial;\n }\n}\n","@import \"../../functions/grid\";\n@import \"../../mixins/grid\";\n@import \"../../mixins/media-query\";\n@import \"../../variables/grid\";\n\n.content-grid {\n --primary-column-width: #{get-overall-width($grid-main_column_count)};\n\n @include base-grid($grid-max_width);\n grid-template-areas:\n \". menu .\"\n \". primary .\";\n grid-template-columns: [full-start] 1fr [main-start] var(--primary-column-width) [main-end] 1fr [full-end];\n grid-column-gap: var(--GRID-COLUMN-GAP);\n\n @include mq($from: wide) {\n $primary-column-count: $grid-main_column_count - 2;\n $secondary-column-count: floor(($grid-main_column_count - $primary-column-count) / 2);\n $menu-column-count: $grid-main_column_count - $primary-column-count - $secondary-column-count;\n --primary-column-width: #{get-overall-width($primary-column-count)};\n --secondary-column-width: #{get-overall-width($secondary-column-count)};\n --menu-column-width: #{get-overall-width($menu-column-count)};\n grid-template-areas:\n \". . menu . .\"\n \". . primary . .\";\n grid-template-columns: [full-start] 1fr [main-start] var(--menu-column-width) var(--primary-column-width) var(--secondary-column-width) [main-end] 1fr [full-end];\n }\n\n @include mq($from: x-wide) {\n $primary-column-count: floor($grid-main_column_count * 0.7);\n $secondary-column-count: floor(($grid-main_column_count - $primary-column-count) / 2);\n $menu-column-count: $grid-main_column_count - $primary-column-count - $secondary-column-count;\n --primary-column-width: #{get-overall-width($primary-column-count)};\n --secondary-column-width: #{get-overall-width($secondary-column-count)};\n --menu-column-width: #{get-overall-width($menu-column-count)};\n grid-template-areas: \". menu primary . .\";\n }\n}\n\n.content-grid--has-secondary {\n grid-template-areas:\n \". menu .\"\n \". primary .\"\n \". secondary .\";\n\n @include mq($from: wide) {\n $primary-column-count: floor($grid-main_column_count * 0.7);\n $secondary-column-count: $grid-main_column_count - $primary-column-count;\n --primary-column-width: #{get-overall-width($primary-column-count)};\n --secondary-column-width: #{get-overall-width($secondary-column-count)};\n grid-template-areas:\n \". menu menu .\"\n \". primary secondary .\";\n grid-template-columns: [full-start] 1fr [main-start] var(--primary-column-width) var(--secondary-column-width) [main-end] 1fr [full-end];\n }\n\n @include mq($from: x-wide) {\n $primary-column-count: floor($grid-main_column_count * 0.6);\n $secondary-column-count: floor($grid-main_column_count * 0.25);\n $menu-column-count: $grid-main_column_count - $primary-column-count - $secondary-column-count;\n --primary-column-width: #{get-overall-width($primary-column-count)};\n --secondary-column-width: #{get-overall-width($secondary-column-count)};\n --menu-column-width: #{get-overall-width($menu-column-count)};\n grid-template-areas: \". menu primary secondary .\";\n grid-template-columns: [full-start] 1fr [main-start] var(--menu-column-width) var(--primary-column-width) var(--secondary-column-width) [main-end] 1fr [full-end];\n }\n}\n\n.content-grid__item,\n.content-grid__item--main {\n grid-column: main;\n}\n\n.content-grid__item--full {\n grid-column: full;\n}\n\n.content-grid__item--primary {\n grid-column: primary;\n}\n\n.content-grid__item--secondary {\n grid-column: secondary;\n}\n\n.content-grid__item--menu {\n grid-column: menu;\n}\n","@function get-overall-width($columns) {\n @return calc((#{$columns} * var(--GRID-COLUMN-WIDTH)) + (#{$columns - 1} * var(--GRID-COLUMN-GAP)));\n}\n","@import \"spacing\";\n@import \"types\";\n@import \"../functions/grid\";\n@import \"../variables/grid\";\n\n@mixin base-grid($max-inline-size) {\n @include max-inline-size($max-inline-size);\n @include block-spacing($end: 0);\n @include margin(auto, inline);\n @include padding($grid-column_gap, inline);\n box-sizing: content-box;\n\n @supports (display: grid) and (--custom: property) {\n display: grid;\n @include max-inline-size(unset);\n @include margin(unset, inline);\n @include padding(unset, inline);\n box-sizing: border-box;\n }\n}\n","@import \"../../mixins/decorations\";\n@import \"../../mixins/grid\";\n@import \"../../variables/grid\";\n\n.page-grid {\n @include base-grid($grid-max_width);\n grid-template-areas:\n \"start\"\n \"main\"\n \"end\";\n}\n\n.page-grid__start {\n grid-row: start;\n @include divider(block-end);\n}\n\n.page-grid__main {\n grid-row: main;\n}\n\n.page-grid__end {\n grid-row: end;\n @include divider(block-start);\n}\n"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"all.css","sources":["base.scss","_fonts.scss","_normalize.scss","mixins/_decorations.scss","mixins/_logical-properties.scss","mixins/_types.scss","variables/_font.scss","vendor/sass-rem/_rem.scss","mixins/_validation.scss","functions/_validation.scss","variables/_color.scss","variables/_grid.scss","mixins/_spacing.scss","mixins/_media-query.scss","variables/_breakpoint.scss","vendor/sass-mq/_mq.scss","mixins/_sizes.scss","variables/_baselinegrid.scss","mixins/_typography.scss","mixins/_utilities.scss","mixins/_scale.scss","vendor/modularscale-sass/stylesheets/_modularscale.scss","vendor/modularscale-sass/stylesheets/modularscale/_vars.scss","vendor/modularscale-sass/stylesheets/modularscale/_settings.scss","vendor/modularscale-sass/stylesheets/modularscale/_pow.scss","vendor/modularscale-sass/stylesheets/modularscale/_strip-units.scss","vendor/modularscale-sass/stylesheets/modularscale/_sort.scss","vendor/modularscale-sass/stylesheets/modularscale/_target.scss","vendor/modularscale-sass/stylesheets/modularscale/_function.scss","vendor/modularscale-sass/stylesheets/modularscale/_round-px.scss","vendor/modularscale-sass/stylesheets/modularscale/_respond.scss","vendor/modularscale-sass/stylesheets/modularscale/_sugar.scss","vendor/normalize.css/normalize.css","_grid.scss","patterns/atoms/heading.scss","patterns/molecules/content-meta.scss","patterns/molecules/section.scss","patterns/molecules/tag-list.scss","patterns/organisms/content-header.scss","functions/_types.scss","patterns/organisms/item-tags.scss","patterns/templates/content-grid.scss","functions/_grid.scss","mixins/_grid.scss","patterns/templates/page-grid.scss"],"sourcesContent":["@import \"fonts\";\n@import \"normalize\";\n@import \"grid\";\n@import \"patterns/atoms/heading.scss\";\n@import \"patterns/molecules/content-meta.scss\";\n@import \"patterns/molecules/section.scss\";\n@import \"patterns/molecules/tag-list.scss\";\n@import \"patterns/organisms/content-header.scss\";\n@import \"patterns/organisms/item-tags.scss\";\n@import \"patterns/templates/content-grid.scss\";\n@import \"patterns/templates/page-grid.scss\";\n","@font-face {\n font-display: fallback;\n font-family: \"Noto Sans\";\n src: url(\"../../fonts/NotoSans-Regular-webfont-custom-2-subsetting.woff2\") format(\"woff2\");\n}\n\n@font-face {\n font-display: fallback;\n font-family: \"Noto Sans\";\n src: url(\"../../fonts/NotoSans-SemiBold-webfont-custom-2-subsetting.woff2\") format(\"woff2\");\n font-weight: 600;\n}\n\n@font-face {\n font-display: fallback;\n font-family: \"Noto Serif\";\n src: url(\"../../fonts/NotoSerif-Regular-webfont-custom-2-subsetting.woff2\") format(\"woff2\");\n}\n\n@font-face {\n font-display: fallback;\n font-family: \"Noto Serif\";\n src: url(\"../../fonts/NotoSerif-Bold-webfont-basic-latin-subsetting.woff2\") format(\"woff2\");\n font-weight: bold;\n}\n","@import \"mixins/decorations\";\n@import \"mixins/spacing\";\n@import \"mixins/typography\";\n@import \"variables/color\";\n@import \"variables/grid\";\n@import \"vendor/normalize.css/normalize\";\n\n*,\n*:before,\n*:after {\n box-sizing: border-box;\n}\n\nhtml {\n font-size: ($font-size / 16px) * 100%;\n}\n\nhtml,\nbody {\n @include min-block-size(100%);\n}\n\nbody {\n background-color: $color-background;\n color: $color-text-normal;\n text-rendering: optimizeLegibility;\n @include body-typography();\n}\n\nh1 {\n @include h1-typography();\n @include h1-spacing();\n}\n\nh2 {\n @include h2-typography();\n @include h2-spacing();\n}\n\nh3 {\n @include h3-typography();\n @include h3-spacing();\n}\n\nh4 {\n @include h4-typography();\n @include h4-spacing();\n}\n\nh5 {\n @include h5-typography();\n @include h5-spacing();\n}\n\nh6 {\n @include h6-typography();\n @include h6-spacing();\n}\n\naddress,\narticle,\naside,\nblockquote,\ncaption,\ndetails,\ndl,\nfieldset,\nfigcaption,\nfigure,\nfooter,\nform,\nheader,\nhr,\nmain,\nnav,\nol,\np,\npre,\nsection,\ntable,\nul {\n @include block-spacing();\n}\n\nb,\ncode,\nkbd,\nstrong {\n line-height: 1;\n}\n\nhr {\n border: 0;\n @include divider(block-end);\n @include block-spacing($end: $baselinegrid-space-small - $grid-divider_size);\n}\n\nfigure {\n @include margin(0, inline);\n}\n\ndl,\nol,\nul {\n dd > &,\n li > & {\n @include block-spacing($end: 0);\n }\n}\n\na {\n color: $color-primary-normal;\n text-decoration: none;\n}\n\ndt {\n font-weight: bold;\n\n dd + & {\n @include block-spacing($baselinegrid-space-small, 0);\n }\n}\n\ndd {\n @include margin(0, inline-start);\n}\n\naddress {\n @include set-font-size-and-line-height(scale(-3));\n}\n\nsmall {\n @include rem(font-size, scale(-3));\n}\n\nsub {\n @include font-variant-position(sub);\n}\n\nsup {\n @include font-variant-position(super);\n}\n\nimg {\n @include max-block-size(100%);\n @include max-inline-size(100%);\n}\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\np {\n img {\n @include inline-image();\n }\n}\n\n:lang(ja) {\n @at-root {\n em#{&} {\n font-style: normal;\n text-emphasis-style: open sesame;\n text‑emphasis‑position: over right;\n }\n\n strong#{&} {\n font-style: normal;\n text-emphasis-style: filled sesame;\n text‑emphasis‑position: over right;\n }\n\n u#{&} {\n text-underline-position: right;\n }\n }\n}\n\n:lang(ko) {\n @at-root {\n em#{&} {\n font-style: normal;\n text-decoration: underline;\n text-underline-position: under right;\n }\n\n strong#{&} {\n font-style: normal;\n text-emphasis-style: filled dot;\n text‑emphasis‑position: over right;\n }\n }\n}\n\n:lang(zh) {\n @at-root {\n em#{&} {\n font-style: normal;\n text-emphasis-style: open dot;\n text‑emphasis‑position: under right;\n }\n\n strong#{&} {\n font-style: normal;\n text-emphasis-style: filled dot;\n text‑emphasis‑position: under right;\n }\n\n cite#{&} {\n font-style: normal;\n text-decoration: underline;\n text-underline-style: wavy;\n }\n }\n}\n\n:lang(zh-Hant) {\n @at-root {\n em#{&} {\n text‑emphasis‑position: over right;\n }\n\n strong#{&} {\n text‑emphasis‑position: over right;\n }\n }\n}\n","@import \"../mixins/logical-properties\";\n@import \"../variables/color\";\n@import \"../variables/grid\";\n\n@mixin divider($dimension) {\n\n @if index((inline, inline-start, inline-end, block, block-start, block-end), $dimension) {\n @include logical-property(border, $dimension, ($grid-divider_size solid $color-text-dividers,), $to-rem: false);\n } @else if index((top, bottom, left, right), $dimension) {\n @include _error(\"'#{$dimension}' is a physical dimension, use its logical equivilant\");\n } @else {\n @include _error(\"Unknown dimension '#{$dimension}'\");\n }\n\n}\n","@import \"types\";\n@import \"validation\";\n\n@mixin _when-left-to-right {\n html[dir=\"ltr\"] &:not([dir]),\n &[dir=\"ltr\"] {\n @content;\n }\n}\n\n@mixin _when-right-to-left {\n html[dir=\"rtl\"] &:not([dir]),\n &[dir=\"rtl\"] {\n @content;\n }\n}\n\n@mixin _when-logical {\n html[dir][dir] & {\n @content;\n }\n}\n\n@mixin _maybe-rem($to-rem, $properties, $values: ()) {\n @if ($to-rem == false) {\n @if type-of($properties) == \"map\" {\n @each $property in map-keys($properties) {\n @include _maybe-rem($to-rem, $property, map-get($properties, $property));\n }\n } @else {\n @each $property in $properties {\n #{$property}: $values;\n }\n }\n } @else {\n @include rem($properties, $values...);\n }\n}\n\n@function _maybe-rem($to-rem, $values) {\n @if ($to-rem == false) {\n @return $values;\n } @else {\n @return rem($values...);\n }\n}\n\n@function _property-name($parts, $dimension) {\n @if (length($parts) == 0 or $parts == \"\") {\n @return $dimension;\n }\n\n @if (length($parts) == 1) {\n @return \"#{$parts}-#{$dimension}\";\n }\n\n @return \"#{nth($parts, 1)}-#{$dimension}-#{nth($parts, 2)}\";\n}\n\n@mixin logical-property($property-name, $dimension, $arguments, $to-rem: true) {\n\n @if length($property-name) > 2 {\n @include _error(\"Expected at most two property name parts\");\n } @else if $dimension == inline {\n\n @if type-of($arguments) == \"list\" and length($arguments) > 1 {\n\n @include _expect_at_most($arguments, 2, \"More than two arguments supplied with 'inline' dimension\") {\n\n $firstArgument: nth($arguments, 1);\n $secondArgument: nth($arguments, 2);\n\n @if $firstArgument == $secondArgument {\n\n @include _maybe-rem($to-rem, (\n #{_property-name($property-name, left)}: $firstArgument,\n #{_property-name($property-name, right)}: $firstArgument,\n ));\n #{_property-name($property-name, inline)}: _maybe-rem($to-rem, $firstArgument);\n\n } @else {\n\n @include _when-left-to-right() {\n @include _maybe-rem($to-rem, _property-name($property-name, left), $firstArgument);\n @include _maybe-rem($to-rem, _property-name($property-name, right), $secondArgument);\n }\n\n @include _when-right-to-left() {\n @include _maybe-rem($to-rem, _property-name($property-name, right), $firstArgument);\n @include _maybe-rem($to-rem, _property-name($property-name, left), $secondArgument);\n }\n\n @include _when-logical() {\n #{_property-name($property-name, inline-start)}: _maybe-rem($to-rem, $firstArgument);\n #{_property-name($property-name, inline-end)}: _maybe-rem($to-rem, $secondArgument);\n }\n\n }\n\n }\n\n } @else {\n\n @include _maybe-rem($to-rem, (\n #{_property-name($property-name, left)}: $arguments,\n #{_property-name($property-name, right)}: $arguments,\n ));\n #{_property-name($property-name, inline)}: _maybe-rem($to-rem, $arguments);\n\n }\n\n } @else if $dimension == inline-start {\n\n @include _when-left-to-right() {\n @include _maybe-rem($to-rem, _property-name($property-name, left), $arguments);\n }\n\n @include _when-right-to-left() {\n @include _maybe-rem($to-rem, _property-name($property-name, right), $arguments);\n }\n\n @include _when_logical() {\n #{_property-name($property-name, inline-start)}: _maybe-rem($to-rem, $arguments);\n }\n\n } @else if $dimension == inline-end {\n\n @include _when-left-to-right() {\n @include _maybe-rem($to-rem, _property-name($property-name, right), $arguments);\n }\n\n @include _when-right-to-left() {\n @include _maybe-rem($to-rem, _property-name($property-name, left), $arguments);\n }\n\n @include _when_logical() {\n #{_property-name($property-name, inline-end)}: _maybe-rem($to-rem, $arguments);\n }\n\n } @else if $dimension == inline-size {\n\n @include _maybe-rem($to-rem, _property-name($property-name, width), $arguments);\n #{_property-name($property-name, inline-size)}: _maybe-rem($to-rem, $arguments);\n\n } @else if $dimension == block {\n\n @if type-of($arguments) == \"list\" and length($arguments) > 1 {\n\n @include _expect_at_most($arguments, 2, \"More than two arguments supplied with 'block' dimension\") {\n\n $firstArgument: nth($arguments, 1);\n $secondArgument: nth($arguments, 2);\n\n @if $firstArgument == $secondArgument {\n\n @include _maybe-rem($to-rem, (\n #{_property-name($property-name, top)}: $firstArgument,\n #{_property-name($property-name, bottom)}: $firstArgument,\n ));\n #{_property-name($property-name, block)}: _maybe-rem($to-rem, $firstArgument);\n\n } @else {\n\n @include _maybe-rem($to-rem, (\n #{_property-name($property-name, top)}: $firstArgument,\n #{_property-name($property-name, bottom)}: $secondArgument,\n ));\n #{_property-name($property-name, block-start)}: _maybe-rem($to-rem, $firstArgument);\n #{_property-name($property-name, block-end)}: _maybe-rem($to-rem, $secondArgument);\n\n }\n\n }\n\n } @else {\n\n @include _maybe-rem($to-rem, (\n #{_property-name($property-name, top)}: $arguments,\n #{_property-name($property-name, bottom)}: $arguments,\n ));\n #{_property-name($property-name, block)}: _maybe-rem($to-rem, $arguments);\n\n }\n\n } @else if $dimension == block-start {\n\n @include _maybe-rem($to-rem, _property-name($property-name, top), $arguments);\n #{_property-name($property-name, block-start)}: _maybe-rem($to-rem, $arguments);\n\n } @else if $dimension == block-end {\n\n @include _maybe-rem($to-rem, _property-name($property-name, bottom), $arguments);\n #{_property-name($property-name, block-end)}: _maybe-rem($to-rem, $arguments);\n\n } @else if $dimension == block-size {\n\n @include _maybe-rem($to-rem, _property-name($property-name, height), $arguments);\n #{_property-name($property-name, block-size)}: _maybe-rem($to-rem, $arguments);\n\n } @else if index((top, bottom, left, right, width, height), $dimension) {\n @include _error(\"'#{$dimension}' is a physical dimension, use its logical equivilant\");\n } @else {\n @include _error(\"Unknown dimension '#{$dimension}'\");\n }\n\n}\n","@import \"../variables/font\";\n@import \"../vendor/sass-rem/rem\";\n\n$rem-baseline: $font-size;\n$rem-fallback: true;\n\n// Overridden to apply https://github.com/pierreburel/sass-rem/pull/12\n@mixin rem($properties, $values...) {\n\n @if type-of($properties) == \"map\" {\n\n @each $property in map-keys($properties) {\n @include rem($property, map-get($properties, $property));\n }\n\n } @else {\n\n $convert: false;\n @each $valueList in $values {\n @each $value in $valueList {\n @if type-of($value) == \"number\" and index((rem, px), unit($value)) {\n $convert: true;\n }\n }\n }\n\n @each $property in $properties {\n @if $convert == true {\n @if $rem-fallback or $rem-px-only {\n #{$property}: rem-convert(px, $values...);\n }\n @if not $rem-px-only {\n #{$property}: rem-convert(rem, $values...);\n }\n } @else if $rem-px-only {\n #{$property}: rem-convert(px, $values...);\n } @else {\n #{$property}: $values;\n }\n }\n\n }\n\n}\n","$font-letterspacing-label: 1px;\n$font-primary: \"Noto Serif\", serif;\n$font-secondary: \"Noto Sans\", Arial, Helvetica, sans-serif;\n$font-monospace: \"Courier 10 Pitch\", Courier, monospace;\n$font-size: 16px;\n","$rem-baseline: 16px !default;\n$rem-fallback: false !default;\n$rem-px-only: false !default;\n\n@function rem-separator($list, $separator: false) {\n @if $separator == \"comma\" or $separator == \"space\" {\n @return append($list, null, $separator);\n } \n \n @if function-exists(\"list-separator\") == true {\n @return list-separator($list);\n }\n\n // list-separator polyfill by Hugo Giraudel (https://sass-compatibility.github.io/#list_separator_function)\n $test-list: ();\n @each $item in $list {\n $test-list: append($test-list, $item, space);\n }\n\n @return if($test-list == $list, space, comma);\n}\n\n@mixin rem-baseline($zoom: 100%) {\n font-size: $zoom / 16px * $rem-baseline;\n}\n\n@function rem-convert($to, $values...) {\n $result: ();\n $separator: rem-separator($values);\n \n @each $value in $values {\n @if type-of($value) == \"number\" and unit($value) == \"rem\" and $to == \"px\" {\n $result: append($result, $value / 1rem * $rem-baseline, $separator);\n } @else if type-of($value) == \"number\" and unit($value) == \"px\" and $to == \"rem\" {\n $result: append($result, $value / $rem-baseline * 1rem, $separator);\n } @else if type-of($value) == \"list\" {\n $value-separator: rem-separator($value);\n $value: rem-convert($to, $value...);\n $value: rem-separator($value, $value-separator);\n $result: append($result, $value, $separator);\n } @else {\n $result: append($result, $value, $separator);\n }\n }\n\n @return if(length($result) == 1, nth($result, 1), $result);\n}\n\n@function rem($values...) {\n @if $rem-px-only {\n @return rem-convert(px, $values...);\n } @else {\n @return rem-convert(rem, $values...);\n }\n}\n\n@mixin rem($properties, $values...) {\n @if type-of($properties) == \"map\" {\n @each $property in map-keys($properties) {\n @include rem($property, map-get($properties, $property));\n }\n } @else {\n @each $property in $properties {\n @if $rem-fallback or $rem-px-only {\n #{$property}: rem-convert(px, $values...);\n }\n @if not $rem-px-only {\n #{$property}: rem-convert(rem, $values...);\n }\n }\n }\n}\n","@import \"../functions/validation\";\n\n@mixin _error($message) {\n _error: _error($message);\n}\n\n@mixin _expect_at_most($value, $maxLength, $message: \"Expected at most #{$maxLength} values\") {\n\n @if length($value) > $maxLength {\n @include _error($message);\n } @else {\n @content;\n }\n\n}\n\n@mixin _expect_single_value($value, $message: \"Expected a single value\") {\n\n @include _expect_at_most($value, 1, $message) {\n @content;\n }\n\n}\n","$_is-test: false !default;\n\n@function _error($message, $capture: $_is-test) {\n @if $capture {\n @return $message;\n }\n\n @error $message;\n}\n","$color-primary-normal: rgb(2, 136, 209);\n$color-primary-light: rgb(179, 229, 252);\n$color-primary-dark: rgb(2, 119, 189);\n$color-text-normal: rgb(33, 33, 33);\n$color-text-reverse: rgb(255, 255, 255);\n$color-text-secondary: rgb(136, 136, 136);\n$color-text-secondary__reverse: rgb(158, 158, 158);\n$color-text-placeholder: rgb(189, 189, 189);\n$color-text-dividers: rgb(224, 224, 224);\n$color-text-dividers__reverse: rgb(97, 97, 97);\n$color-text-ui_background: rgb(255, 255, 255);\n$color-text-ui_background_hue: rgb(245, 245, 245);\n$color-text-ui_code: rgb(247, 247, 247);\n$color-text-ui_background__reverse: rgb(33, 33, 33);\n$color-text-ui_background_hue__reverse: rgb(51, 51, 51);\n$color-background: rgb(255, 255, 255);\n$color-information: rgb(2, 136, 209);\n$color-success: rgb(98, 159, 67);\n$color-success_dark: rgb(86, 144, 55);\n$color-attention: rgb(207, 12, 78);\n$color-warning: rgb(230, 81, 0);\n","$grid-edge_space-medium: 7vw;\n$grid-edge_space-large: 14vw;\n$grid-min_width: 320px;\n$grid-max_width: 1114px;\n$grid-main_column_count: 12;\n$grid-column_gap: 1.6%;\n$grid-divider_size: 1px;\n","@import \"logical-properties\";\n@import \"media-query\";\n@import \"sizes\";\n@import \"types\";\n@import \"validation\";\n@import \"../variables/baselinegrid\";\n\n// Fallbacks for CSS logical properties contained within this mixin require the following treatment of HTML dir attributes:\n// - document level: always specified, via the HTML element\n// - block level: specified on every element within a block describing a direction switch.\n//\n// For example:\n// \n// ...\n//
\n// Doesn't need a dir attribute. Most cases will be like this.\n//
\n//\n//
\n//\n// This block changes the text direction. Every descendant element must have its own dir attribute....\n//\n//
... even if the direction doesn't change.
\n//\n//
But obviously also when it does.
\n//\n//
\n@mixin _spacing($sizes, $space-type, $dimension: \"\") {\n\n @if $dimension == \"\" {\n\n @include _expect_at_most($sizes, 4, \"More than four sizes supplied when no dimension\") {\n @include rem($space-type, $sizes);\n }\n\n } @else if $dimension == inline {\n\n @include _expect_at_most($sizes, 2, \"More than two sizes supplied with 'inline' dimension\") {\n @include logical-property($space-type, $dimension, $sizes);\n }\n\n } @else if $dimension == inline-start {\n\n @include _expect_single_value($sizes, \"More than one size supplied with 'inline-start' dimension\") {\n @include logical-property($space-type, $dimension, $sizes);\n }\n\n } @else if $dimension == inline-end {\n\n @include _expect_single_value($sizes, \"More than one size supplied with 'inline-end' dimension\") {\n @include logical-property($space-type, $dimension, $sizes);\n }\n\n } @else if $dimension == block {\n\n @include _expect_at_most($sizes, 2, \"More than two sizes supplied with 'block' dimension\") {\n @include logical-property($space-type, $dimension, $sizes);\n }\n\n } @else if $dimension == block-start {\n\n @include _expect_single_value($sizes, \"More than one size supplied with 'block-start' dimension\") {\n @include logical-property($space-type, $dimension, $sizes);\n }\n\n } @else if $dimension == block-end {\n\n @include _expect_single_value($sizes, \"More than one size supplied with 'block-end' dimension\") {\n @include logical-property($space-type, $dimension, $sizes);\n }\n\n } @else if index((top, bottom, left, right), $dimension) {\n @include _error(\"'#{$dimension}' is a physical dimension, use its logical equivilant\");\n } @else {\n @include _error(\"Unknown dimension '#{$dimension}'\");\n }\n\n}\n\n@mixin padding($sizes, $dimension: \"\") {\n @include _spacing($sizes, padding, $dimension);\n}\n\n@mixin margin($sizes, $dimension: \"\") {\n @include _spacing($sizes, margin, $dimension);\n}\n\n@mixin nospace($dimension: \"\") {\n @include margin(0, $dimension);\n @include padding(0, $dimension);\n}\n\n@mixin block-spacing($start: 0, $end: $baselinegrid-space-small) {\n @include margin($start $end, block);\n}\n\n@function _calculate-spacing($block-size, $unit-size: $baselinegrid-space-small) {\n $remaining: $unit-size - $block-size;\n\n @if ($remaining > 0) {\n @return $remaining;\n }\n\n @return $unit-size;\n}\n\n@mixin h1-spacing() {\n @include block-spacing($end: _calculate-spacing($baselinegrid-space-medium));\n}\n\n@mixin h2-spacing() {\n @include block-spacing($end: _calculate-spacing(($baselinegrid-space-small + $baselinegrid-space-smallish) / 2, $baselinegrid-space-medium));\n}\n\n@mixin h3-spacing() {\n @include block-spacing($end: _calculate-spacing($baselinegrid-space-small, $baselinegrid-space-medium));\n}\n\n@mixin h4-spacing() {\n @include block-spacing($end: _calculate-spacing($baselinegrid-space-small, $baselinegrid-space-medium));\n}\n\n@mixin h5-spacing() {\n @include block-spacing($end: _calculate-spacing($baselinegrid-space-small, $baselinegrid-space-medium));\n}\n\n@mixin h6-spacing() {\n @include block-spacing($end: _calculate-spacing($baselinegrid-space-small, $baselinegrid-space-medium));\n}\n\n@mixin list-style-none() {\n list-style: none;\n @include padding(0, inline-start);\n}\n","@import \"../variables/breakpoint\";\n@import \"../variables/font\";\n\n$mq-base-font-size: $font-size;\n\n$mq-breakpoints: (\n x-small: $breakpoint-site-x_small,\n small: $breakpoint-site-small,\n medium: $breakpoint-site-medium,\n wide: $breakpoint-site-wide,\n x-wide: $breakpoint-site-x_wide,\n);\n\n@import \"../vendor/sass-mq/_mq\";\n","$breakpoint-site-x_small: 320px;\n$breakpoint-site-small: 480px;\n$breakpoint-site-medium: 730px;\n$breakpoint-site-wide: 900px;\n$breakpoint-site-x_wide: 1200px;\n","@charset \"UTF-8\"; // Fixes an issue where Ruby locale is not set properly\n // See https://github.com/sass-mq/sass-mq/pull/10\n\n/// Base font size on the `` element\n/// @type Number (unit)\n$mq-base-font-size: 16px !default;\n\n/// Responsive mode\n///\n/// Set to `false` to enable support for browsers that do not support @media queries,\n/// (IE <= 8, Firefox <= 3, Opera <= 9)\n///\n/// You could create a stylesheet served exclusively to older browsers,\n/// where @media queries are rasterized\n///\n/// @example scss\n/// // old-ie.scss\n/// $mq-responsive: false;\n/// @import 'main'; // @media queries in this file will be rasterized up to $mq-static-breakpoint\n/// // larger breakpoints will be ignored\n///\n/// @type Boolean\n/// @link https://github.com/sass-mq/sass-mq#responsive-mode-off Disabled responsive mode documentation\n$mq-responsive: true !default;\n\n/// Breakpoint list\n///\n/// Name your breakpoints in a way that creates a ubiquitous language\n/// across team members. It will improve communication between\n/// stakeholders, designers, developers, and testers.\n///\n/// @type Map\n/// @link https://github.com/sass-mq/sass-mq#seeing-the-currently-active-breakpoint Full documentation and examples\n$mq-breakpoints: (\n mobile: 320px,\n tablet: 740px,\n desktop: 980px,\n wide: 1300px\n) !default;\n\n/// Static breakpoint (for fixed-width layouts)\n///\n/// Define the breakpoint from $mq-breakpoints that should\n/// be used as the target width for the fixed-width layout\n/// (i.e. when $mq-responsive is set to 'false') in a old-ie.scss\n///\n/// @example scss\n/// // tablet-only.scss\n/// //\n/// // Ignore all styles above tablet breakpoint,\n/// // and fix the styles (e.g. layout) at tablet width\n/// $mq-responsive: false;\n/// $mq-static-breakpoint: tablet;\n/// @import 'main'; // @media queries in this file will be rasterized up to tablet\n/// // larger breakpoints will be ignored\n///\n/// @type String\n/// @link https://github.com/sass-mq/sass-mq#adding-custom-breakpoints Full documentation and examples\n$mq-static-breakpoint: desktop !default;\n\n/// Show breakpoints in the top right corner\n///\n/// If you want to display the currently active breakpoint in the top\n/// right corner of your site during development, add the breakpoints\n/// to this list, ordered by width, e.g. (mobile, tablet, desktop).\n///\n/// @type map\n$mq-show-breakpoints: () !default;\n\n/// Customize the media type (e.g. `@media screen` or `@media print`)\n/// By default sass-mq uses an \"all\" media type (`@media all and …`)\n///\n/// @type String\n/// @link https://github.com/sass-mq/sass-mq#changing-media-type Full documentation and examples\n$mq-media-type: all !default;\n\n/// Convert pixels to ems\n///\n/// @param {Number} $px - value to convert\n/// @param {Number} $base-font-size ($mq-base-font-size) - `` font size\n///\n/// @example scss\n/// $font-size-in-ems: mq-px2em(16px);\n/// p { font-size: mq-px2em(16px); }\n///\n/// @requires $mq-base-font-size\n/// @returns {Number}\n@function mq-px2em($px, $base-font-size: $mq-base-font-size) {\n @if unitless($px) {\n @warn \"Assuming #{$px} to be in pixels, attempting to convert it into pixels.\";\n @return mq-px2em($px * 1px, $base-font-size);\n } @else if unit($px) == em {\n @return $px;\n }\n @return ($px / $base-font-size) * 1em;\n}\n\n/// Get a breakpoint's width\n///\n/// @param {String} $name - Name of the breakpoint. One of $mq-breakpoints\n///\n/// @example scss\n/// $tablet-width: mq-get-breakpoint-width(tablet);\n/// @media (min-width: mq-get-breakpoint-width(desktop)) {}\n///\n/// @requires {Variable} $mq-breakpoints\n///\n/// @returns {Number} Value in pixels\n@function mq-get-breakpoint-width($name, $breakpoints: $mq-breakpoints) {\n @if map-has-key($breakpoints, $name) {\n @return map-get($breakpoints, $name);\n } @else {\n @warn \"Breakpoint #{$name} wasn't found in $breakpoints.\";\n }\n}\n\n/// Media Query mixin\n///\n/// @param {String | Boolean} $from (false) - One of $mq-breakpoints\n/// @param {String | Boolean} $until (false) - One of $mq-breakpoints\n/// @param {String | Boolean} $and (false) - Additional media query parameters\n/// @param {String} $media-type ($mq-media-type) - Media type: screen, print…\n///\n/// @ignore Undocumented API, for advanced use only:\n/// @ignore @param {Map} $breakpoints ($mq-breakpoints)\n/// @ignore @param {String} $static-breakpoint ($mq-static-breakpoint)\n///\n/// @content styling rules, wrapped into a @media query when $responsive is true\n///\n/// @requires {Variable} $mq-media-type\n/// @requires {Variable} $mq-breakpoints\n/// @requires {Variable} $mq-static-breakpoint\n/// @requires {function} mq-px2em\n/// @requires {function} mq-get-breakpoint-width\n///\n/// @link https://github.com/sass-mq/sass-mq#responsive-mode-on-default Full documentation and examples\n///\n/// @example scss\n/// .element {\n/// @include mq($from: mobile) {\n/// color: red;\n/// }\n/// @include mq($until: tablet) {\n/// color: blue;\n/// }\n/// @include mq(mobile, tablet) {\n/// color: green;\n/// }\n/// @include mq($from: tablet, $and: '(orientation: landscape)') {\n/// color: teal;\n/// }\n/// @include mq(950px) {\n/// color: hotpink;\n/// }\n/// @include mq(tablet, $media-type: screen) {\n/// color: hotpink;\n/// }\n/// // Advanced use:\n/// $my-breakpoints: (L: 900px, XL: 1200px);\n/// @include mq(L, $breakpoints: $my-breakpoints, $static-breakpoint: L) {\n/// color: hotpink;\n/// }\n/// }\n@mixin mq(\n $from: false,\n $until: false,\n $and: false,\n $media-type: $mq-media-type,\n $breakpoints: $mq-breakpoints,\n $responsive: $mq-responsive,\n $static-breakpoint: $mq-static-breakpoint\n) {\n $min-width: 0;\n $max-width: 0;\n $media-query: '';\n\n // From: this breakpoint (inclusive)\n @if $from {\n @if type-of($from) == number {\n $min-width: mq-px2em($from);\n } @else {\n $min-width: mq-px2em(mq-get-breakpoint-width($from, $breakpoints));\n }\n }\n\n // Until: that breakpoint (exclusive)\n @if $until {\n @if type-of($until) == number {\n $max-width: mq-px2em($until);\n } @else {\n $max-width: mq-px2em(mq-get-breakpoint-width($until, $breakpoints)) - .01em;\n }\n }\n\n // Responsive support is disabled, rasterize the output outside @media blocks\n // The browser will rely on the cascade itself.\n @if $responsive == false {\n $static-breakpoint-width: mq-get-breakpoint-width($static-breakpoint, $breakpoints);\n $target-width: mq-px2em($static-breakpoint-width);\n\n // Output only rules that start at or span our target width\n @if (\n $and == false\n and $min-width <= $target-width\n and (\n $until == false or $max-width >= $target-width\n )\n and $media-type != 'print'\n ) {\n @content;\n }\n }\n\n // Responsive support is enabled, output rules inside @media queries\n @else {\n @if $min-width != 0 { $media-query: '#{$media-query} and (min-width: #{$min-width})'; }\n @if $max-width != 0 { $media-query: '#{$media-query} and (max-width: #{$max-width})'; }\n @if $and { $media-query: '#{$media-query} and #{$and}'; }\n\n // Remove unnecessary media query prefix 'all and '\n @if ($media-type == 'all' and $media-query != '') {\n $media-type: '';\n $media-query: str-slice(unquote($media-query), 6);\n }\n\n @media #{$media-type + $media-query} {\n @content;\n }\n }\n}\n\n/// Quick sort\n///\n/// @author Sam Richards\n/// @access private\n/// @param {List} $list - List to sort\n/// @returns {List} Sorted List\n@function _mq-quick-sort($list) {\n $less: ();\n $equal: ();\n $large: ();\n\n @if length($list) > 1 {\n $seed: nth($list, ceil(length($list) / 2));\n\n @each $item in $list {\n @if ($item == $seed) {\n $equal: append($equal, $item);\n } @else if ($item < $seed) {\n $less: append($less, $item);\n } @else if ($item > $seed) {\n $large: append($large, $item);\n }\n }\n\n @return join(join(_mq-quick-sort($less), $equal), _mq-quick-sort($large));\n }\n\n @return $list;\n}\n\n/// Sort a map by values (works with numbers only)\n///\n/// @access private\n/// @param {Map} $map - Map to sort\n/// @returns {Map} Map sorted by value\n@function _mq-map-sort-by-value($map) {\n $map-sorted: ();\n $map-keys: map-keys($map);\n $map-values: map-values($map);\n $map-values-sorted: _mq-quick-sort($map-values);\n\n // Reorder key/value pairs based on key values\n @each $value in $map-values-sorted {\n $index: index($map-values, $value);\n $key: nth($map-keys, $index);\n $map-sorted: map-merge($map-sorted, ($key: $value));\n\n // Unset the value in $map-values to prevent the loop\n // from finding the same index twice\n $map-values: set-nth($map-values, $index, 0);\n }\n\n @return $map-sorted;\n}\n\n/// Add a breakpoint\n///\n/// @param {String} $name - Name of the breakpoint\n/// @param {Number} $width - Width of the breakpoint\n///\n/// @requires {Variable} $mq-breakpoints\n///\n/// @example scss\n/// @include mq-add-breakpoint(tvscreen, 1920px);\n/// @include mq(tvscreen) {}\n@mixin mq-add-breakpoint($name, $width) {\n $new-breakpoint: ($name: $width);\n $mq-breakpoints: map-merge($mq-breakpoints, $new-breakpoint) !global;\n $mq-breakpoints: _mq-map-sort-by-value($mq-breakpoints) !global;\n}\n\n/// Show the active breakpoint in the top right corner of the viewport\n/// @link https://github.com/sass-mq/sass-mq#seeing-the-currently-active-breakpoint\n///\n/// @param {List} $show-breakpoints ($mq-show-breakpoints) - List of breakpoints to show in the top right corner\n/// @param {Map} $breakpoints ($mq-breakpoints) - Breakpoint names and sizes\n///\n/// @requires {Variable} $mq-breakpoints\n/// @requires {Variable} $mq-show-breakpoints\n///\n/// @example scss\n/// // Show breakpoints using global settings\n/// @include mq-show-breakpoints;\n///\n/// // Show breakpoints using custom settings\n/// @include mq-show-breakpoints((L, XL), (S: 300px, L: 800px, XL: 1200px));\n@mixin mq-show-breakpoints($show-breakpoints: $mq-show-breakpoints, $breakpoints: $mq-breakpoints) {\n body:before {\n background-color: #FCF8E3;\n border-bottom: 1px solid #FBEED5;\n border-left: 1px solid #FBEED5;\n color: #C09853;\n font: small-caption;\n padding: 3px 6px;\n pointer-events: none;\n position: fixed;\n right: 0;\n top: 0;\n z-index: 100;\n\n // Loop through the breakpoints that should be shown\n @each $show-breakpoint in $show-breakpoints {\n $width: mq-get-breakpoint-width($show-breakpoint, $breakpoints);\n @include mq($show-breakpoint, $breakpoints: $breakpoints) {\n content: \"#{$show-breakpoint} ≥ #{$width} (#{mq-px2em($width)})\";\n }\n }\n }\n}\n\n@if length($mq-show-breakpoints) > 0 {\n @include mq-show-breakpoints;\n}\n","@import \"logical-properties\";\n@import \"types\";\n@import \"validation\";\n\n@mixin block-size($size) {\n @include _expect_single_value($size) {\n @include logical-property(\"\", block-size, ($size));\n }\n}\n\n@mixin inline-size($size) {\n @include _expect_single_value($size) {\n @include logical-property(\"\", inline-size, ($size));\n }\n}\n\n@mixin _constrain-block-size($size, $extreme) {\n @include logical-property($extreme, block-size, ($size));\n}\n\n@mixin _constrain-inline-size($size, $extreme) {\n @include logical-property($extreme, inline-size, ($size));\n}\n\n@mixin max-block-size($size) {\n @include _expect_single_value($size) {\n @include _constrain-block-size($size, max);\n }\n}\n\n@mixin min-block-size($size) {\n @include _expect_single_value($size) {\n @include _constrain-block-size($size, min);\n }\n}\n\n@mixin max-inline-size($size) {\n @include _expect_single_value($size) {\n @include _constrain-inline-size($size, max);\n }\n}\n\n@mixin min-inline-size($size) {\n @include _expect_single_value($size) {\n @include _constrain-inline-size($size, min);\n }\n}\n\n@mixin truncate-with-ellipsis() {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n\n &:lang(zh-Hant-HK) {\n text-overflow: \"⋯\";\n }\n}\n","$baselinegrid-space-extra_small: 12px;\n$baselinegrid-space-small: 24px;\n$baselinegrid-space-smallish: 36px;\n$baselinegrid-space-medium: 48px;\n$baselinegrid-space-large: 72px;\n$baselinegrid-space-extra_large: 120px;\n","@import \"../mixins/types\";\n@import \"../variables/baselinegrid\";\n@import \"../variables/color\";\n@import \"../variables/font\";\n@import \"spacing\";\n@import \"utilities\";\n@import \"scale\";\n\n@mixin set-font-size-and-line-height($font-size, $block-size: $baselinegrid-space-small) {\n @include rem(font-size, $font-size);\n line-height: $block-size / $font-size;\n}\n\n@mixin _heading-base-typography() {\n font-family: $font-secondary;\n font-weight: 600;\n}\n\n@mixin h1-typography() {\n @include _heading-base-typography();\n @include set-font-size-and-line-height(scale(7), $baselinegrid-space-medium);\n}\n\n@mixin h2-typography() {\n @include _heading-base-typography();\n @include set-font-size-and-line-height(scale(4), ($baselinegrid-space-small + $baselinegrid-space-smallish) / 2);\n}\n\n@mixin h3-typography() {\n @include _heading-base-typography();\n @include set-font-size-and-line-height(scale(3));\n}\n\n@mixin h4-typography() {\n @include _heading-base-typography();\n @include set-font-size-and-line-height(scale(2));\n}\n\n@mixin h5-typography() {\n @include _heading-base-typography();\n @include set-font-size-and-line-height(scale(1));\n}\n\n@mixin h6-typography() {\n @include _heading-base-typography();\n @include set-font-size-and-line-height(scale(0));\n}\n\n@mixin body-typography() {\n font-family: $font-primary;\n @include set-font-size-and-line-height(scale(0));\n font-weight: normal;\n}\n\n@mixin inline-image {\n @include margin(0.1em, block-end);\n @include max-block-size(1em);\n vertical-align: middle;\n}\n\n@mixin _base-font-variant-position($position) {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n @supports (font-variant-position: #{$position}) {\n font-size: inherit;\n font-variant-position: $position;\n position: static;\n }\n}\n\n@mixin font-variant-position($position) {\n @if $position == sub {\n @include _base_font-variant-position($position);\n bottom: -0.25em; // stylelint-disable-line csstools/use-logical\n } @else if $position == super {\n @include _base_font-variant-position($position);\n top: -0.5em; // stylelint-disable-line csstools/use-logical\n } @else {\n @include _error(\"Unknown position '#{$position}'\");\n }\n}\n\n@mixin _label-typography($color, $uppercase: true) {\n color: $color;\n font-family: $font-secondary;\n font-weight: normal;\n @include set-font-size-and-line-height(scale(-3));\n letter-spacing: $font-letterspacing-label;\n @if $uppercase {\n text-transform: uppercase;\n }\n}\n\n@mixin label-content-typography($color: $color-text-secondary, $uppercase: true) {\n @include _label-typography($color, $uppercase);\n}\n\n@mixin label-tag-typography() {\n @include _label-typography($color-primary-normal);\n}\n\n@mixin covert-link($hover-color: $color-primary-dark) {\n @include inherit-all($ensure: color text-decoration);\n cursor: pointer;\n\n &:hover {\n color: $hover-color;\n }\n}\n\n@mixin list-style-none() {\n @include padding(0, inline-start);\n // Overflow auto is so the bullet will be still read from a screen reader and will push the bullet off screen\n overflow: auto;\n}\n","@mixin inherit-all($ensure: ()) {\n @each $property in $ensure {\n #{$property}: inherit;\n }\n\n all: inherit;\n}\n","@import \"../variables/font\";\n@import \"../vendor/modularscale-sass/stylesheets/modularscale\";\n\n@function scale($value: 0) {\n @return round(ms-function($value, $font-size, $major-second));\n}\n","// Defaults and variables\n@import 'modularscale/vars';\n\n// Core functions\n@import 'modularscale/settings';\n@import 'modularscale/pow';\n@import 'modularscale/strip-units';\n@import 'modularscale/sort';\n@import 'modularscale/target';\n@import 'modularscale/function';\n@import 'modularscale/round-px';\n\n// Mixins\n@import 'modularscale/respond';\n\n// Syntax sugar\n@import 'modularscale/sugar';","// Ratios\n$double-octave : 4 ;\n$pi : 3.14159265359 ;\n$major-twelfth : 3 ;\n$major-eleventh : 2.666666667 ;\n$major-tenth : 2.5 ;\n$octave : 2 ;\n$major-seventh : 1.875 ;\n$minor-seventh : 1.777777778 ;\n$major-sixth : 1.666666667 ;\n$phi : 1.618034 ;\n$golden : $phi ;\n$minor-sixth : 1.6 ;\n$fifth : 1.5 ;\n$augmented-fourth : 1.41421 ;\n$fourth : 1.333333333 ;\n$major-third : 1.25 ;\n$minor-third : 1.2 ;\n$major-second : 1.125 ;\n$minor-second : 1.066666667 ;\n\n// Base config\n$ms-base : 1em !default;\n$ms-ratio : $fifth !default;\n$modularscale : () !default;","// Parse settings starting with defaults.\n// Settings should cascade down like you would expect in CSS.\n// More specific overrides previous settings.\n\n@function ms-settings($b: false, $r: false, $t: false, $m: $modularscale) {\n $base: $ms-base;\n $ratio: $ms-ratio;\n $thread: map-get($m, $t);\n\n // Override with user settings\n @if map-get($m, base) {\n $base: map-get($m, base);\n }\n @if map-get($m, ratio) {\n $ratio: map-get($m, ratio);\n }\n\n // Override with thread settings\n @if $thread {\n @if map-get($thread, base) {\n $base: map-get($thread, base);\n }\n @if map-get($thread, ratio) {\n $ratio: map-get($thread, ratio);\n }\n }\n\n // Override with inline settings\n @if $b {\n $base: $b;\n }\n @if $r {\n $ratio: $r;\n }\n\n @return $base $ratio;\n}","// Sass does not have native pow() support so this needs to be added.\n// Compass and other libs implement this more extensively.\n// In order to keep this simple, use those when they are avalible.\n// Issue for pow() support in Sass: https://github.com/sass/sass/issues/684\n\n@function ms-pow($b,$e) {\n\n // Return 1 if exponent is 0\n @if $e == 0 {\n @return 1;\n }\n\n // If pow() exists (compass or mathsass) use that.\n @if function-exists('pow') {\n @return pow($b,$e);\n }\n\n // This does not support non-integer exponents,\n // Check and return an error if a non-integer exponent is passed.\n @if (floor($e) != $e) {\n @error 'Non-integer values are not supported in modularscale by default. Try using mathsass in your project to add non-integer scale support. https://github.com/terkel/mathsass'\n }\n\n // Seed the return.\n $ms-return: $b;\n\n // Multiply or divide by the specified number of times.\n @if $e > 0 {\n @for $i from 1 to $e {\n $ms-return: $ms-return * $b;\n }\n }\n @if $e < 0 {\n @for $i from $e through 0 {\n $ms-return: $ms-return / $b;\n }\n }\n @return $ms-return;\n}","// Stripping units is not a best practice\n// This function should not be used elsewhere\n// It is used here because calc() doesn't do unit logic\n// AND target ratios use units as a hack to get a number.\n@function ms-unitless($val) {\n @return ($val / ($val - $val + 1));\n}","// Basic list sorting\n// Would like to replace with http://sassmeister.com/gist/30e4863bd03ce0e1617c\n// Unfortunately libsass has a bug with passing arguments into the min() funciton.\n\n@function ms-sort($l) {\n\n // loop until the list is confirmed to be sorted\n $sorted: false;\n @while $sorted == false {\n\n // Start with the assumption that the lists are sorted.\n $sorted: true;\n\n // Loop through the list, checking each value with the one next to it.\n // Swap the values if they need to be swapped.\n // Not super fast but simple and modular scale doesn't lean hard on sorting.\n @for $i from 2 through length($l) {\n $n1: nth($l,$i - 1);\n $n2: nth($l,$i);\n\n // If the first value is greater than the 2nd, swap them.\n @if $n1 > $n2 {\n $l: set-nth($l, $i, $n1);\n $l: set-nth($l, $i - 1, $n2);\n\n // The list isn't sorted and needs to be looped through again.\n $sorted: false;\n }\n }\n }\n\n // Return the sorted list.\n @return $l;\n}","// Convert number string to number\n@function ms-to-num($n) {\n $l: str-length($n);\n $r: 0;\n $m: str-index($n,'.');\n @if $m == null {\n $m: $l + 1;\n }\n // Loop through digits and convert to numbers\n @for $i from 1 through $l {\n $v: str-slice($n,$i,$i);\n @if $v == '1' { $v: 1; }\n @else if $v == '2' { $v: 2; }\n @else if $v == '3' { $v: 3; }\n @else if $v == '4' { $v: 4; }\n @else if $v == '5' { $v: 5; }\n @else if $v == '6' { $v: 6; }\n @else if $v == '7' { $v: 7; }\n @else if $v == '8' { $v: 8; }\n @else if $v == '9' { $v: 9; }\n @else if $v == '0' { $v: 0; }\n @else { $v: null; }\n @if $v != null {\n $m: $m - 1;\n $r: $r + ms-pow(10,$m - 1) * $v;\n } @else {\n $l: $l - 1;\n }\n }\n @return $r;\n}\n\n// Find a ratio based on a target value\n@function ms-target($t,$b) {\n // Convert to string\n $t: $t + '';\n // Remove base units to calulate ratio\n $b: ms-unitless(nth($b,1));\n // Find where 'at' is in the string\n $at: str-index($t,'at');\n\n // Slice the value and target out\n // and convert strings to numbers\n $v: ms-to-num(str-slice($t,0,$at - 1));\n $t: ms-to-num(str-slice($t,$at + 2));\n\n // Solve the modular scale function for the ratio.\n @return ms-pow(($v/$b),(1/$t));\n}","@function ms-function($v: 0, $base: false, $ratio: false, $thread: false, $settings: $modularscale) {\n\n // Parse settings\n $ms-settings: ms-settings($base,$ratio,$thread,$settings);\n $base: nth($ms-settings, 1);\n $ratio: nth($ms-settings, 2);\n\n // Render target values from settings.\n @if unit($ratio) != '' {\n $ratio: ms-target($ratio,$base)\n }\n\n // Fast calc if not multi stranded\n @if(length($base) == 1) {\n @return ms-pow($ratio, $v) * $base;\n }\n\n // Create new base array\n $ms-bases: nth($base,1);\n\n // Normalize base values\n @for $i from 2 through length($base) {\n // initial base value\n $ms-base: nth($base,$i);\n // If the base is bigger than the main base\n @if($ms-base > nth($base,1)) {\n // divide the value until it aligns with main base.\n @while($ms-base > nth($base,1)) {\n $ms-base: $ms-base / $ratio;\n }\n $ms-base: $ms-base * $ratio;\n }\n // If the base is smaller than the main base.\n @else if ($ms-base < nth($base,1)) {\n // pump up the value until it aligns with main base.\n @while $ms-base < nth($base,1) {\n $ms-base: $ms-base * $ratio;\n }\n }\n // Push into new array\n $ms-bases: append($ms-bases,$ms-base);\n }\n\n // Sort array from smallest to largest.\n $ms-bases: ms-sort($ms-bases);\n\n // Find step to use in calculation\n $vtep: floor($v / length($ms-bases));\n // Find base to use in calculation\n $ms-base: round(($v / length($ms-bases) - $vtep) * length($ms-bases)) + 1;\n\n @return ms-pow($ratio, $vtep) * nth($ms-bases,$ms-base);\n}","@function ms-round-px($r) {\n @if unit($r) == 'px' {\n @return round($r);\n }\n @warn \"ms-round-px is no longer used by modular scale and will be removed in the 3.1.0 release.\";\n @return $r;\n}","// Generate calc() function\n// based on Mike Riethmuller's Precise control over responsive typography\n// http://madebymike.com.au/writing/precise-control-responsive-typography/\n@function ms-fluid($val1: 1em, $val2: 1em, $break1: 0, $break2: 0) {\n $diff: ms-unitless($val2) - ms-unitless($val1);\n\n // v1 + (v2 - v1) * ( (100vw - b1) / b2 - b1 )\n @return calc( #{$val1} + #{ms-unitless($val2) - ms-unitless($val1)} * ( ( 100vw - #{$break1}) / #{ms-unitless($break2) - ms-unitless($break1)} ) );\n}\n\n// Main responsive mixin\n@mixin ms-respond($prop, $val, $map: $modularscale, $ms-important: false) {\n $base: $ms-base;\n $ratio: $ms-ratio;\n\n $first-write: true;\n $last-break: null;\n\n $important: '';\n\n @if $ms-important == true {\n $important: ' !important';\n }\n\n // loop through all settings with a breakpoint type value\n @each $v, $s in $map {\n @if type-of($v) == number {\n @if unit($v) != '' {\n\n // Write out the first value without a media query.\n @if $first-write {\n #{$prop}: unquote(\"#{ms-function($val, $thread: $v, $settings: $map)}#{$important}\");\n\n // Not the first write anymore, reset to false to move on.\n $first-write: false;\n $last-break: $v;\n }\n\n // Write intermediate breakpoints.\n @else {\n @media (min-width: $last-break) and (max-width: $v) {\n $val1: ms-function($val, $thread: $last-break, $settings: $map);\n $val2: ms-function($val, $thread: $v, $settings: $map);\n #{$prop}: unquote(\"#{ms-fluid($val1,$val2,$last-break,$v)}#{$important}\");\n }\n $last-break: $v;\n }\n }\n }\n }\n\n // Write the last breakpoint.\n @if $last-break {\n @media (min-width: $last-break) {\n #{$prop}: unquote(\"#{ms-function($val, $thread: $last-break, $settings: $map)}#{$important}\");\n }\n }\n}","// To attempt to avoid conflicts with other libraries\n// all funcitons are namespaced with `ms-`.\n// However, to increase usability, a shorthand function is included here.\n\n@function ms($v: 0, $base: false, $ratio: false, $thread: false, $settings: $modularscale) {\n @return ms-function($v, $base, $ratio, $thread, $settings);\n}","/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */\n\n/* Document\n ========================================================================== */\n\n/**\n * 1. Correct the line height in all browsers.\n * 2. Prevent adjustments of font size after orientation changes in iOS.\n */\n\nhtml {\n line-height: 1.15; /* 1 */\n -webkit-text-size-adjust: 100%; /* 2 */\n}\n\n/* Sections\n ========================================================================== */\n\n/**\n * Remove the margin in all browsers.\n */\n\nbody {\n margin: 0;\n}\n\n/**\n * Render the `main` element consistently in IE.\n */\n\nmain {\n display: block;\n}\n\n/**\n * Correct the font size and margin on `h1` elements within `section` and\n * `article` contexts in Chrome, Firefox, and Safari.\n */\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n/* Grouping content\n ========================================================================== */\n\n/**\n * 1. Add the correct box sizing in Firefox.\n * 2. Show the overflow in Edge and IE.\n */\n\nhr {\n box-sizing: content-box; /* 1 */\n height: 0; /* 1 */\n overflow: visible; /* 2 */\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\npre {\n font-family: monospace, monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/* Text-level semantics\n ========================================================================== */\n\n/**\n * Remove the gray background on active links in IE 10.\n */\n\na {\n background-color: transparent;\n}\n\n/**\n * 1. Remove the bottom border in Chrome 57-\n * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n */\n\nabbr[title] {\n border-bottom: none; /* 1 */\n text-decoration: underline; /* 2 */\n text-decoration: underline dotted; /* 2 */\n}\n\n/**\n * Add the correct font weight in Chrome, Edge, and Safari.\n */\n\nb,\nstrong {\n font-weight: bolder;\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\ncode,\nkbd,\nsamp {\n font-family: monospace, monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/**\n * Add the correct font size in all browsers.\n */\n\nsmall {\n font-size: 80%;\n}\n\n/**\n * Prevent `sub` and `sup` elements from affecting the line height in\n * all browsers.\n */\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -0.25em;\n}\n\nsup {\n top: -0.5em;\n}\n\n/* Embedded content\n ========================================================================== */\n\n/**\n * Remove the border on images inside links in IE 10.\n */\n\nimg {\n border-style: none;\n}\n\n/* Forms\n ========================================================================== */\n\n/**\n * 1. Change the font styles in all browsers.\n * 2. Remove the margin in Firefox and Safari.\n */\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n font-family: inherit; /* 1 */\n font-size: 100%; /* 1 */\n line-height: 1.15; /* 1 */\n margin: 0; /* 2 */\n}\n\n/**\n * Show the overflow in IE.\n * 1. Show the overflow in Edge.\n */\n\nbutton,\ninput { /* 1 */\n overflow: visible;\n}\n\n/**\n * Remove the inheritance of text transform in Edge, Firefox, and IE.\n * 1. Remove the inheritance of text transform in Firefox.\n */\n\nbutton,\nselect { /* 1 */\n text-transform: none;\n}\n\n/**\n * Correct the inability to style clickable types in iOS and Safari.\n */\n\nbutton,\n[type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\n/**\n * Remove the inner border and padding in Firefox.\n */\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n border-style: none;\n padding: 0;\n}\n\n/**\n * Restore the focus styles unset by the previous rule.\n */\n\nbutton:-moz-focusring,\n[type=\"button\"]:-moz-focusring,\n[type=\"reset\"]:-moz-focusring,\n[type=\"submit\"]:-moz-focusring {\n outline: 1px dotted ButtonText;\n}\n\n/**\n * Correct the padding in Firefox.\n */\n\nfieldset {\n padding: 0.35em 0.75em 0.625em;\n}\n\n/**\n * 1. Correct the text wrapping in Edge and IE.\n * 2. Correct the color inheritance from `fieldset` elements in IE.\n * 3. Remove the padding so developers are not caught out when they zero out\n * `fieldset` elements in all browsers.\n */\n\nlegend {\n box-sizing: border-box; /* 1 */\n color: inherit; /* 2 */\n display: table; /* 1 */\n max-width: 100%; /* 1 */\n padding: 0; /* 3 */\n white-space: normal; /* 1 */\n}\n\n/**\n * Add the correct vertical alignment in Chrome, Firefox, and Opera.\n */\n\nprogress {\n vertical-align: baseline;\n}\n\n/**\n * Remove the default vertical scrollbar in IE 10+.\n */\n\ntextarea {\n overflow: auto;\n}\n\n/**\n * 1. Add the correct box sizing in IE 10.\n * 2. Remove the padding in IE 10.\n */\n\n[type=\"checkbox\"],\n[type=\"radio\"] {\n box-sizing: border-box; /* 1 */\n padding: 0; /* 2 */\n}\n\n/**\n * Correct the cursor style of increment and decrement buttons in Chrome.\n */\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n/**\n * 1. Correct the odd appearance in Chrome and Safari.\n * 2. Correct the outline style in Safari.\n */\n\n[type=\"search\"] {\n -webkit-appearance: textfield; /* 1 */\n outline-offset: -2px; /* 2 */\n}\n\n/**\n * Remove the inner padding in Chrome and Safari on macOS.\n */\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n/**\n * 1. Correct the inability to style clickable types in iOS and Safari.\n * 2. Change font properties to `inherit` in Safari.\n */\n\n::-webkit-file-upload-button {\n -webkit-appearance: button; /* 1 */\n font: inherit; /* 2 */\n}\n\n/* Interactive\n ========================================================================== */\n\n/*\n * Add the correct display in Edge, IE 10+, and Firefox.\n */\n\ndetails {\n display: block;\n}\n\n/*\n * Add the correct display in all browsers.\n */\n\nsummary {\n display: list-item;\n}\n\n/* Misc\n ========================================================================== */\n\n/**\n * Add the correct display in IE 10+.\n */\n\ntemplate {\n display: none;\n}\n\n/**\n * Add the correct display in IE 10.\n */\n\n[hidden] {\n display: none;\n}\n","@import \"mixins/logical-properties\";\n@import \"mixins/media-query\";\n@import \"variables/grid\";\n\n:root {\n --GRID-COLUMN-GAP: #{$grid-column_gap};\n --GRID-EDGE-SPACE: #{$grid-edge_space-medium};\n --GRID-COLUMN-WIDTH: calc((100% - (var(--GRID-EDGE-SPACE) * 2) - (var(--GRID-COLUMN-GAP) * #{$grid-main_column_count - 1})) / #{$grid-main_column_count});\n\n @include mq($from: medium) {\n --GRID-EDGE-SPACE: #{$grid-edge_space-large};\n }\n\n @include mq($from: x-wide) {\n --GRID-COLUMN-GAP: #{($grid-max_width * $grid-column_gap) / 100%};\n --GRID-COLUMN-WIDTH: calc((#{$grid-max_width} - (var(--GRID-COLUMN-GAP) * #{$grid-main_column_count - 1})) / #{$grid-main_column_count});\n }\n\n @include logical-property(min, inline-size, $grid-min_width, $to-rem: false);\n}\n","@import \"../../mixins/typography\";\n\n.heading__link {\n @include covert-link();\n}\n","@import \"../../mixins/spacing\";\n@import \"../../mixins/typography\";\n\n.content-meta {\n @include list-style-none();\n @include block-spacing();\n}\n\n.content-meta__item {\n display: inline-block;\n @include label-content-typography();\n\n &:after {\n content: \"\\a0\\2022\\a0\";\n }\n\n &:last-child:after {\n content: \"\";\n }\n}\n\n.content-meta__link {\n @include covert-link();\n}\n","@import \"../../mixins/spacing\";\n@import \"../../variables/baselinegrid\";\n\n.section__body {\n @include block-spacing($end: $baselinegrid-space-medium);\n}\n","@import \"../../mixins/sizes\";\n@import \"../../mixins/typography\";\n@import \"../../variables/baselinegrid\";\n\n.tag-list {\n @include block-spacing();\n}\n\n.tag-list__title {\n @include label-content-typography();\n @include block-spacing($end: 0);\n}\n\n.tag-list__list {\n @include list-style-none();\n @include label-tag-typography();\n}\n\n.tag-list__list--single-line {\n @include truncate-with-ellipsis();\n}\n\n.tag-list__item {\n display: inline-block;\n @include label-tag-typography();\n\n &:after {\n display: inline;\n content: \",\\a0\";\n }\n\n &:lang(ar):after {\n content: \"،\\a0\";\n }\n\n &:lang(ja):after {\n content: \"、\";\n }\n\n &:last-child:after {\n content: \"\";\n }\n}\n\n.tag-list__link {\n @include covert-link();\n}\n","@import \"../../functions/types\";\n@import \"../../mixins/scale\";\n@import \"../../mixins/decorations\";\n@import \"../../mixins/media-query\";\n@import \"../../mixins/spacing\";\n@import \"../../variables/baselinegrid\";\n@import \"../../variables/grid\";\n\n.content-header {\n text-align: center;\n @include padding($baselinegrid-space-medium, block-start);\n @include block-spacing($end: $baselinegrid-space-medium - $grid-divider_size);\n @include divider(block-end);\n}\n\n.content-header__title {\n @include block-spacing($end: $baselinegrid-space-small);\n\n &:last-child {\n @include block-spacing($end: $baselinegrid-space-medium);\n }\n}\n\n.content-header__title--xx-short {\n @include rem(font-size, scale(9));\n\n @include mq($from: small) {\n @include rem(font-size, scale(10));\n }\n}\n\n.content-header__title--x-short {\n @include rem(font-size, scale(8));\n\n @include mq($from: medium) {\n @include rem(font-size, scale(9));\n }\n\n @include mq($from: wide) {\n @include rem(font-size, scale(10));\n }\n}\n\n.content-header__title--short {\n @include rem(font-size, scale(6));\n\n @include mq($from: small) {\n @include rem(font-size, scale(7));\n }\n\n @include mq($from: medium) {\n @include rem(font-size, scale(8));\n }\n\n @include mq($from: wide) {\n @include rem(font-size, scale(9));\n }\n\n @include mq($from: x-wide) {\n @include rem(font-size, scale(10));\n }\n}\n\n.content-header__title--medium {\n @include rem(font-size, scale(4));\n\n @include mq($from: small) {\n @include rem(font-size, scale(6));\n }\n\n @include mq($from: medium) {\n @include rem(font-size, scale(7));\n }\n\n @include mq($from: wide) {\n @include rem(font-size, scale(8));\n }\n\n @include mq($from: x-wide) {\n @include rem(font-size, scale(10));\n }\n}\n\n.content-header__title--long {\n @include rem(font-size, scale(2));\n\n @include mq($from: small) {\n @include rem(font-size, scale(4));\n }\n\n @include mq($from: medium) {\n @include rem(font-size, scale(7));\n }\n\n @include mq($from: x-wide) {\n @include rem(font-size, scale(8));\n }\n\n}\n\n.content-header__title--x-long {\n @include rem(font-size, scale(2));\n\n @include mq($from: medium) {\n @include rem(font-size, scale(4));\n }\n\n @include mq($from: wide) {\n @include rem(font-size, scale(4));\n }\n\n @include mq($from: x-wide) {\n @include rem(font-size, scale(6));\n }\n}\n\n.content-header__title--xx-long {\n @include rem(font-size, scale(1));\n\n @include mq($from: small) {\n @include rem(font-size, scale(2));\n }\n\n @include mq($from: wide) {\n @include rem(font-size, scale(4));\n }\n}\n","@import \"../mixins/types\";\n@import \"../variables/font\";\n\n$rem-baseline: $font-size;\n$rem-fallback: true;\n","@import \"../../mixins/decorations\";\n@import \"../../mixins/media-query\";\n@import \"../../mixins/spacing\";\n@import \"../../variables/baselinegrid\";\n@import \"../../variables/grid\";\n\n.item-tags {\n @include padding($baselinegrid-space-medium - $grid-divider_size, block-start);\n @include block-spacing($end: $baselinegrid-space-medium);\n @include divider(block-start);\n text-align: center;\n\n @include mq($from: medium) {\n text-align: initial;\n }\n}\n","@import \"../../functions/grid\";\n@import \"../../mixins/grid\";\n@import \"../../mixins/media-query\";\n@import \"../../variables/grid\";\n\n.content-grid {\n --primary-column-width: #{get-overall-width($grid-main_column_count)};\n\n @include base-grid($grid-max_width);\n grid-template-areas:\n \". menu .\"\n \". primary .\";\n grid-template-columns: [full-start] 1fr [main-start] var(--primary-column-width) [main-end] 1fr [full-end];\n grid-column-gap: var(--GRID-COLUMN-GAP);\n\n @include mq($from: wide) {\n $primary-column-count: $grid-main_column_count - 2;\n $secondary-column-count: floor(($grid-main_column_count - $primary-column-count) / 2);\n $menu-column-count: $grid-main_column_count - $primary-column-count - $secondary-column-count;\n --primary-column-width: #{get-overall-width($primary-column-count)};\n --secondary-column-width: #{get-overall-width($secondary-column-count)};\n --menu-column-width: #{get-overall-width($menu-column-count)};\n grid-template-areas:\n \". . menu . .\"\n \". . primary . .\";\n grid-template-columns: [full-start] 1fr [main-start] var(--menu-column-width) var(--primary-column-width) var(--secondary-column-width) [main-end] 1fr [full-end];\n }\n\n @include mq($from: x-wide) {\n $primary-column-count: floor($grid-main_column_count * 0.7);\n $secondary-column-count: floor(($grid-main_column_count - $primary-column-count) / 2);\n $menu-column-count: $grid-main_column_count - $primary-column-count - $secondary-column-count;\n --primary-column-width: #{get-overall-width($primary-column-count)};\n --secondary-column-width: #{get-overall-width($secondary-column-count)};\n --menu-column-width: #{get-overall-width($menu-column-count)};\n grid-template-areas: \". menu primary . .\";\n }\n}\n\n.content-grid--has-secondary {\n grid-template-areas:\n \". menu .\"\n \". primary .\"\n \". secondary .\";\n\n @include mq($from: wide) {\n $primary-column-count: floor($grid-main_column_count * 0.7);\n $secondary-column-count: $grid-main_column_count - $primary-column-count;\n --primary-column-width: #{get-overall-width($primary-column-count)};\n --secondary-column-width: #{get-overall-width($secondary-column-count)};\n grid-template-areas:\n \". menu menu .\"\n \". primary secondary .\";\n grid-template-columns: [full-start] 1fr [main-start] var(--primary-column-width) var(--secondary-column-width) [main-end] 1fr [full-end];\n }\n\n @include mq($from: x-wide) {\n $primary-column-count: floor($grid-main_column_count * 0.6);\n $secondary-column-count: floor($grid-main_column_count * 0.25);\n $menu-column-count: $grid-main_column_count - $primary-column-count - $secondary-column-count;\n --primary-column-width: #{get-overall-width($primary-column-count)};\n --secondary-column-width: #{get-overall-width($secondary-column-count)};\n --menu-column-width: #{get-overall-width($menu-column-count)};\n grid-template-areas: \". menu primary secondary .\";\n grid-template-columns: [full-start] 1fr [main-start] var(--menu-column-width) var(--primary-column-width) var(--secondary-column-width) [main-end] 1fr [full-end];\n }\n}\n\n.content-grid__item,\n.content-grid__item--main {\n grid-column: main;\n}\n\n.content-grid__item--full {\n grid-column: full;\n}\n\n.content-grid__item--primary {\n grid-column: primary;\n}\n\n.content-grid__item--secondary {\n grid-column: secondary;\n}\n\n.content-grid__item--menu {\n grid-column: menu;\n}\n","@function get-overall-width($columns) {\n @return calc((#{$columns} * var(--GRID-COLUMN-WIDTH)) + (#{$columns - 1} * var(--GRID-COLUMN-GAP)));\n}\n","@import \"spacing\";\n@import \"types\";\n@import \"../functions/grid\";\n@import \"../variables/grid\";\n\n@mixin base-grid($max-inline-size) {\n @include max-inline-size($max-inline-size);\n @include block-spacing($end: 0);\n @include margin(auto, inline);\n @include padding($grid-column_gap, inline);\n box-sizing: content-box;\n\n @supports (display: grid) and (--custom: property) {\n display: grid;\n @include max-inline-size(unset);\n @include margin(unset, inline);\n @include padding(unset, inline);\n box-sizing: border-box;\n }\n}\n","@import \"../../mixins/decorations\";\n@import \"../../mixins/grid\";\n@import \"../../variables/grid\";\n\n.page-grid {\n @include base-grid($grid-max_width);\n grid-template-areas:\n \"start\"\n \"main\"\n \"end\";\n}\n\n.page-grid__start {\n grid-row: start;\n @include divider(block-end);\n}\n\n.page-grid__main {\n grid-row: main;\n}\n\n.page-grid__end {\n grid-row: end;\n @include divider(block-start);\n}\n"],"names":[],"mappings":"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"} \ No newline at end of file From 3bb139182d3978a26d32ea23e2deffe2bb895585 Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Tue, 9 Apr 2019 11:29:33 +0100 Subject: [PATCH 42/46] Update --- .../src/Resources/views/teaser-list.html.twig | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/vendor-extra/LiberoPatternsBundle/src/Resources/views/teaser-list.html.twig b/vendor-extra/LiberoPatternsBundle/src/Resources/views/teaser-list.html.twig index b615a5e..1ff4b56 100644 --- a/vendor-extra/LiberoPatternsBundle/src/Resources/views/teaser-list.html.twig +++ b/vendor-extra/LiberoPatternsBundle/src/Resources/views/teaser-list.html.twig @@ -1,5 +1,11 @@ {%- set attributes = attributes|default({})|merge({class: attributes.class|default([])|merge(['teaser-list']) }) -%} +{%- if title.text is defined -%} + {%- set title_id = title.attributes.id|default('heading' ~ random()) -%} + {%- set attributes = attributes|merge({'aria-labelledby': title_id}) -%} + {%- set title = title|merge({_id: title_id}) -%} +{%- endif -%} +
{%- with title|default({}) only -%} @@ -7,7 +13,7 @@ {% if text is defined %} - {%- set attributes = attributes|default({})|merge({class: attributes.class|default([])|merge(['teaser-list__title']) }) -%} + {%- set attributes = attributes|default({})|merge({id: _id, class: attributes.class|default([])|merge(['teaser-list__title']) }) -%} {%- include '@LiberoPatterns/heading.html.twig' with {level: level|default(2)} -%} {% endif %} From 56ec6359577b9e7e32d552f79463867e7be0010f Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Tue, 9 Apr 2019 13:01:33 +0100 Subject: [PATCH 43/46] Fix terminology --- .../BuildView/FrontArticleTitleTeaserListenerTest.php | 4 ++-- .../EventListener/BuildView/FrontTitleTeaserListenerTest.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/vendor-extra/JatsContentBundle/tests/EventListener/BuildView/FrontArticleTitleTeaserListenerTest.php b/vendor-extra/JatsContentBundle/tests/EventListener/BuildView/FrontArticleTitleTeaserListenerTest.php index c4240a0..a02a27e 100644 --- a/vendor-extra/JatsContentBundle/tests/EventListener/BuildView/FrontArticleTitleTeaserListenerTest.php +++ b/vendor-extra/JatsContentBundle/tests/EventListener/BuildView/FrontArticleTitleTeaserListenerTest.php @@ -94,7 +94,7 @@ public function it_does_nothing_if_there_is_no_title_group() : void /** * @test */ - public function it_does_nothing_if_there_is_already_a_teaser_title_set() : void + public function it_does_nothing_if_there_is_already_a_teaser_heading_set() : void { $listener = new FrontArticleTitleTeaserListener($this->createFailingConverter()); @@ -127,7 +127,7 @@ public function it_does_nothing_if_there_is_already_a_teaser_title_set() : void /** * @test */ - public function it_sets_the_text_argument() : void + public function it_sets_the_heading_argument() : void { $listener = new FrontArticleTitleTeaserListener($this->createDumpingConverter()); diff --git a/vendor-extra/LiberoContentBundle/tests/EventListener/BuildView/FrontTitleTeaserListenerTest.php b/vendor-extra/LiberoContentBundle/tests/EventListener/BuildView/FrontTitleTeaserListenerTest.php index 25e04cd..bb1c599 100644 --- a/vendor-extra/LiberoContentBundle/tests/EventListener/BuildView/FrontTitleTeaserListenerTest.php +++ b/vendor-extra/LiberoContentBundle/tests/EventListener/BuildView/FrontTitleTeaserListenerTest.php @@ -83,7 +83,7 @@ public function it_does_nothing_if_there_is_no_title() : void /** * @test */ - public function it_does_nothing_if_there_is_already_a_teaser_title_set() : void + public function it_does_nothing_if_there_is_already_a_teaser_heading_set() : void { $listener = new FrontTitleTeaserListener($this->createFailingConverter()); @@ -105,7 +105,7 @@ public function it_does_nothing_if_there_is_already_a_teaser_title_set() : void /** * @test */ - public function it_sets_the_text_argument() : void + public function it_sets_the_heading_argument() : void { $listener = new FrontTitleTeaserListener($this->createDumpingConverter()); From c3d74a4db629689d76a3a6cc92fcbbf6d22df562 Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Tue, 9 Apr 2019 15:11:42 +0100 Subject: [PATCH 44/46] Simplify --- .../BuildView/ItemListListener.php | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php index cb8d9d6..cee016d 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php @@ -14,7 +14,6 @@ use Libero\ViewsBundle\Views\View; use Libero\ViewsBundle\Views\ViewConverter; use Symfony\Contracts\Translation\TranslatorInterface; -use function array_filter; use function array_map; use function count; use function Libero\ViewsBundle\array_has_key; @@ -74,17 +73,11 @@ function () use ($view, $items) { return $view->withArgument( 'list', [ - 'items' => array_filter( - array_map( - function (View $view) { - if (!$view instanceof ArrayAccess) { - return []; - } - - return ['content' => $view['arguments']]; - }, - $items - ) + 'items' => array_map( + function (ArrayAccess $view) { + return ['content' => $view['arguments']]; + }, + $items ), ] ); From 63f41a0b32eeb98eac7452c2425874f168d4c488 Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Tue, 9 Apr 2019 15:54:15 +0100 Subject: [PATCH 45/46] Split into three --- .../BuildView/ItemListEmptyListener.php | 50 ++++++ .../BuildView/ItemListListener.php | 57 ++----- .../BuildView/ItemListTitleListener.php | 55 +++++++ .../src/Resources/config/services.xml | 15 +- .../BuildView/ItemListEmptyListenerTest.php | 150 ++++++++++++++++++ .../BuildView/ItemListListenerTest.php | 132 +++++++-------- .../BuildView/ItemListTitleListenerTest.php | 142 +++++++++++++++++ 7 files changed, 487 insertions(+), 114 deletions(-) create mode 100644 vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListEmptyListener.php create mode 100644 vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListTitleListener.php create mode 100644 vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListEmptyListenerTest.php create mode 100644 vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListTitleListenerTest.php diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListEmptyListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListEmptyListener.php new file mode 100644 index 0000000..dfe01ee --- /dev/null +++ b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListEmptyListener.php @@ -0,0 +1,50 @@ +translator = $translator; + } + + protected function handle(Element $object, TemplateView $view) : View + { + if (!$view->hasContext('list_empty')) { + return $view; + } + + return $view->withArgument( + 'list', + ['empty' => $this->translate($view->getContext('list_empty'), $view->getContext())] + ); + } + + protected function canHandleTemplate(?string $template) : bool + { + return '@LiberoPatterns/teaser-list.html.twig' === $template; + } + + protected function canHandleElement(string $element) : bool + { + return '{http://libero.pub}item-list' === $element; + } + + protected function canHandleArguments(array $arguments) : bool + { + return !isset($arguments['list']['empty']); + } +} diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php index cee016d..d8218c5 100644 --- a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php +++ b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListListener.php @@ -13,10 +13,8 @@ use Libero\ViewsBundle\Views\TemplateView; use Libero\ViewsBundle\Views\View; use Libero\ViewsBundle\Views\ViewConverter; -use Symfony\Contracts\Translation\TranslatorInterface; use function array_map; use function count; -use function Libero\ViewsBundle\array_has_key; final class ItemListListener { @@ -25,10 +23,9 @@ final class ItemListListener private $converter; - public function __construct(ViewConverter $converter, TranslatorInterface $translator) + public function __construct(ViewConverter $converter) { $this->converter = $converter; - $this->translator = $translator; } protected function handle(Element $object, TemplateView $view) : View @@ -36,53 +33,31 @@ protected function handle(Element $object, TemplateView $view) : View /** @var DOMNodeList $itemRefs */ $itemRefs = $object('libero:item-ref'); - $level = $view->getContext()['level'] ?? 1; - if ($view->hasContext('list_title')) { - $level++; - $view = $view->withArgument( - 'title', - [ - 'level' => $view->getContext()['level'] ?? 1, - 'text' => $this->translate($view->getContext('list_title'), $view->getContext()), - ] - ); - } - if (0 === count($itemRefs)) { - if (!$view->hasContext('list_empty')) { - return $view->withArgument('list', []); - } - - return $view->withArgument( - 'list', - ['empty' => $this->translate($view->getContext('list_empty'), $view->getContext())] - ); + return $view; } + $context = $view->getContext(); + unset($context['list_empty']); + $items = []; foreach ($itemRefs as $itemRef) { - $items[] = $this->converter->convert( - $itemRef, - '@LiberoPatterns/teaser.html.twig', - ['level' => $level] + $view->getContext() - ); + $items[] = $this->converter->convert($itemRef, '@LiberoPatterns/teaser.html.twig', $context); } return new LazyView( function () use ($view, $items) { - return $view->withArgument( - 'list', - [ - 'items' => array_map( - function (ArrayAccess $view) { - return ['content' => $view['arguments']]; - }, - $items - ), - ] + $list = $view->getArgument('list') ?? []; + $list['items'] = array_map( + function (ArrayAccess $view) { + return ['content' => $view['arguments']]; + }, + $items ); + + return $view->withArgument('list', $list); }, - $view->getContext() + $context ); } @@ -98,6 +73,6 @@ protected function canHandleElement(string $element) : bool protected function canHandleArguments(array $arguments) : bool { - return !array_has_key($arguments, 'list'); + return !isset($arguments['list']['items']); } } diff --git a/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListTitleListener.php b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListTitleListener.php new file mode 100644 index 0000000..0cefefd --- /dev/null +++ b/vendor-extra/LiberoPageBundle/src/EventListener/BuildView/ItemListTitleListener.php @@ -0,0 +1,55 @@ +translator = $translator; + } + + protected function handle(Element $object, TemplateView $view) : View + { + if (!$view->hasContext('list_title')) { + return $view; + } + + $level = $view->getContext()['level'] ?? 1; + + return $view + ->withArgument( + 'title', + ['level' => $level, 'text' => $this->translate($view->getContext('list_title'), $view->getContext())] + ) + ->withContext(['level' => $level + 1]); + } + + protected function canHandleTemplate(?string $template) : bool + { + return '@LiberoPatterns/teaser-list.html.twig' === $template; + } + + protected function canHandleElement(string $element) : bool + { + return '{http://libero.pub}item-list' === $element; + } + + protected function canHandleArguments(array $arguments) : bool + { + return !array_has_key($arguments, 'title'); + } +} diff --git a/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml b/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml index 2364e16..a346396 100644 --- a/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml +++ b/vendor-extra/LiberoPageBundle/src/Resources/config/services.xml @@ -43,13 +43,26 @@ + + + + + + - + + + + + + diff --git a/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListEmptyListenerTest.php b/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListEmptyListenerTest.php new file mode 100644 index 0000000..665de5d --- /dev/null +++ b/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListEmptyListenerTest.php @@ -0,0 +1,150 @@ +loadElement($xml); + + $event = new BuildViewEvent( + $element, + new TemplateView('@LiberoPatterns/teaser-list.html.twig', [], ['list_empty' => 'empty_key']) + ); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('@LiberoPatterns/teaser-list.html.twig', $view->getTemplate()); + $this->assertEmpty($view->getArguments()); + $this->assertSame(['list_empty' => 'empty_key'], $view->getContext()); + } + + public function nodeProvider() : iterable + { + yield 'different namespace' => ['']; + yield 'different element' => ['']; + } + + /** + * @test + */ + public function it_does_nothing_if_there_is_not_the_teaser_list_template() : void + { + $listener = new ItemListEmptyListener(new IdentityTranslator()); + + $element = $this->loadElement(''); + + $event = new BuildViewEvent( + $element, + new TemplateView('template', [], ['list_empty' => 'empty_key']) + ); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('template', $view->getTemplate()); + $this->assertEmpty($view->getArguments()); + $this->assertSame(['list_empty' => 'empty_key'], $view->getContext()); + } + + /** + * @test + */ + public function it_does_nothing_if_there_is_already_an_empty_list_argument() : void + { + $listener = new ItemListEmptyListener(new IdentityTranslator()); + + $element = $this->loadElement(''); + + $event = new BuildViewEvent( + $element, + new TemplateView( + '@LiberoPatterns/teaser-list.html.twig', + ['list' => ['empty' => 'foo']], + ['list_empty' => 'empty_key',] + ) + ); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('@LiberoPatterns/teaser-list.html.twig', $view->getTemplate()); + $this->assertSame(['list' => ['empty' => 'foo']], $view->getArguments()); + $this->assertSame(['list_empty' => 'empty_key'], $view->getContext()); + } + + /** + * @test + */ + public function it_does_nothing_if_there_is_no_list_empty_context() : void + { + $listener = new ItemListEmptyListener(new IdentityTranslator()); + + $element = $this->loadElement(''); + + $event = new BuildViewEvent($element, new TemplateView('@LiberoPatterns/teaser-list.html.twig')); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('@LiberoPatterns/teaser-list.html.twig', $view->getTemplate()); + $this->assertEmpty($view->getArguments()); + $this->assertEmpty($view->getContext()); + } + + /** + * @test + */ + public function it_sets_the_empty_list_argument() : void + { + $translator = new Translator('es'); + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource( + 'array', + ['empty_key' => 'empty_key in es'], + 'es', + 'messages' + ); + + $listener = new ItemListEmptyListener($translator); + + $element = $this->loadElement(''); + + $event = new BuildViewEvent( + $element, + new TemplateView( + '@LiberoPatterns/teaser-list.html.twig', + ['list' => []], + ['lang' => 'es', 'list_empty' => 'empty_key'] + ) + ); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame(['list' => ['empty' => 'empty_key in es']], $view->getArguments()); + } +} diff --git a/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListListenerTest.php b/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListListenerTest.php index 3c393a7..e08f11a 100644 --- a/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListListenerTest.php +++ b/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListListenerTest.php @@ -9,9 +9,6 @@ use Libero\ViewsBundle\Views\LazyView; use Libero\ViewsBundle\Views\TemplateView; use PHPUnit\Framework\TestCase; -use Symfony\Component\Translation\IdentityTranslator; -use Symfony\Component\Translation\Loader\ArrayLoader; -use Symfony\Component\Translation\Translator; use tests\Libero\LiberoPageBundle\ViewConvertingTestCase; use tests\Libero\LiberoPageBundle\XmlTestCase; @@ -26,7 +23,7 @@ final class ItemListListenerTest extends TestCase */ public function it_does_nothing_if_it_is_not_a_libero_item_list_element(string $xml) : void { - $listener = new ItemListListener($this->createFailingConverter(), new IdentityTranslator()); + $listener = new ItemListListener($this->createFailingConverter()); $element = $this->loadElement($xml); @@ -51,7 +48,7 @@ public function nodeProvider() : iterable */ public function it_does_nothing_if_is_not_the_teaser_list_template() : void { - $listener = new ItemListListener($this->createFailingConverter(), new IdentityTranslator()); + $listener = new ItemListListener($this->createFailingConverter()); $element = $this->loadElement(''); @@ -68,9 +65,9 @@ public function it_does_nothing_if_is_not_the_teaser_list_template() : void /** * @test */ - public function it_sets_the_list_items_argument() : void + public function it_does_nothing_if_there_is_already_a_list_items_argument() : void { - $listener = new ItemListListener($this->createDumpingConverter(), new IdentityTranslator()); + $listener = new ItemListListener($this->createDumpingConverter()); $element = $this->loadElement( << 'text']) + new TemplateView('@LiberoPatterns/teaser-list.html.twig', ['list' => ['items' => 'foo']]) ); $listener->onBuildView($event); $view = $event->getView(); - $this->assertInstanceOf(LazyView::class, $view); - $this->assertSame( - [ - 'list' => [ - 'items' => [ - [ - 'content' => [ - 'node' => '/libero:item-list/libero:item-ref[1]', - 'template' => '@LiberoPatterns/teaser.html.twig', - 'context' => [ - 'level' => 1, - 'con' => 'text', - ], - ], - ], - [ - 'content' => [ - 'node' => '/libero:item-list/libero:item-ref[2]', - 'template' => '@LiberoPatterns/teaser.html.twig', - 'context' => [ - 'level' => 1, - 'con' => 'text', - ], - ], - ], - ], - ], - ], - $view['arguments'] - ); + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('@LiberoPatterns/teaser-list.html.twig', $view->getTemplate()); + $this->assertSame(['list' => ['items' => 'foo']], $view->getArguments()); + $this->assertEmpty($view->getContext()); } /** * @test */ - public function it_sets_the_title_argument() : void + public function it_does_nothing_if_there_are_no_item_refs() : void { - $translator = new Translator('es'); - $translator->addLoader('array', new ArrayLoader()); - $translator->addResource( - 'array', - ['title_key' => 'title_key in es'], - 'es', - 'messages' - ); - - $listener = new ItemListListener($this->createDumpingConverter(), $translator); + $listener = new ItemListListener($this->createDumpingConverter()); $element = $this->loadElement(''); $event = new BuildViewEvent( $element, - new TemplateView('@LiberoPatterns/teaser-list.html.twig', [], ['lang' => 'es', 'list_title' => 'title_key']) + new TemplateView('@LiberoPatterns/teaser-list.html.twig', [], ['list_empty' => 'foo']) ); $listener->onBuildView($event); $view = $event->getView(); $this->assertInstanceOf(TemplateView::class, $view); - $this->assertSame( - [ - 'title' => ['level' => 1, 'text' => 'title_key in es'], - 'list' => [], - ], - $view->getArguments() - ); + $this->assertSame('@LiberoPatterns/teaser-list.html.twig', $view->getTemplate()); + $this->assertEmpty($view->getArguments()); + $this->assertSame(['list_empty' => 'foo'], $view->getContext()); } /** * @test */ - public function it_handles_empty_lists() : void + public function it_sets_the_list_items_argument() : void { - $translator = new Translator('es'); - $translator->addLoader('array', new ArrayLoader()); - $translator->addResource( - 'array', - ['empty_key' => 'empty_key in es'], - 'es', - 'messages' - ); - - $listener = new ItemListListener($this->createDumpingConverter(), $translator); + $listener = new ItemListListener($this->createDumpingConverter()); - $element = $this->loadElement(''); + $element = $this->loadElement( + << + + + + +XML + ); $event = new BuildViewEvent( $element, - new TemplateView('@LiberoPatterns/teaser-list.html.twig', [], ['lang' => 'es', 'list_empty' => 'empty_key']) + new TemplateView( + '@LiberoPatterns/teaser-list.html.twig', + ['list' => []], + ['con' => 'text', 'list_empty' => 'foo'] + ) ); $listener->onBuildView($event); $view = $event->getView(); - $this->assertInstanceOf(TemplateView::class, $view); - $this->assertSame(['list' => ['empty' => 'empty_key in es']], $view->getArguments()); + $this->assertInstanceOf(LazyView::class, $view); + $this->assertSame( + [ + 'list' => [ + 'items' => [ + [ + 'content' => [ + 'node' => '/libero:item-list/libero:item-ref[1]', + 'template' => '@LiberoPatterns/teaser.html.twig', + 'context' => [ + 'con' => 'text', + ], + ], + ], + [ + 'content' => [ + 'node' => '/libero:item-list/libero:item-ref[2]', + 'template' => '@LiberoPatterns/teaser.html.twig', + 'context' => [ + 'con' => 'text', + ], + ], + ], + ], + ], + ], + $view['arguments'] + ); + $this->assertSame(['con' => 'text'], $view->getContext()); } } diff --git a/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListTitleListenerTest.php b/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListTitleListenerTest.php new file mode 100644 index 0000000..c285ab4 --- /dev/null +++ b/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListTitleListenerTest.php @@ -0,0 +1,142 @@ +loadElement($xml); + + $event = new BuildViewEvent( + $element, + new TemplateView('@LiberoPatterns/teaser-list.html.twig', [], ['list_title' => 'title_key']) + ); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('@LiberoPatterns/teaser-list.html.twig', $view->getTemplate()); + $this->assertEmpty($view->getArguments()); + $this->assertSame(['list_title' => 'title_key'], $view->getContext()); + } + + public function nodeProvider() : iterable + { + yield 'different namespace' => ['']; + yield 'different element' => ['']; + } + + /** + * @test + */ + public function it_does_nothing_if_is_not_the_teaser_list_template() : void + { + $listener = new ItemListTitleListener(new IdentityTranslator()); + + $element = $this->loadElement(''); + + $event = new BuildViewEvent( + $element, + new TemplateView('template', [], ['list_title' => 'title_key']) + ); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('template', $view->getTemplate()); + $this->assertEmpty($view->getArguments()); + $this->assertSame(['list_title' => 'title_key'], $view->getContext()); + } + + /** + * @test + */ + public function it_does_nothing_if_there_is_already_a_title_argument() : void + { + $listener = new ItemListTitleListener(new IdentityTranslator()); + + $element = $this->loadElement(''); + + $event = new BuildViewEvent( + $element, + new TemplateView('@LiberoPatterns/teaser-list.html.twig', ['title' => 'foo'], ['list_title' => 'title_key']) + ); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('@LiberoPatterns/teaser-list.html.twig', $view->getTemplate()); + $this->assertSame(['title' => 'foo'], $view->getArguments()); + $this->assertSame(['list_title' => 'title_key'], $view->getContext()); + } + + /** + * @test + */ + public function it_does_nothing_if_there_is_no_list_title_context() : void + { + $listener = new ItemListTitleListener(new IdentityTranslator()); + + $element = $this->loadElement(''); + + $event = new BuildViewEvent($element, new TemplateView('@LiberoPatterns/teaser-list.html.twig')); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame('@LiberoPatterns/teaser-list.html.twig', $view->getTemplate()); + $this->assertEmpty($view->getArguments()); + $this->assertEmpty($view->getContext()); + } + + /** + * @test + */ + public function it_sets_the_title_argument() : void + { + $translator = new Translator('es'); + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource( + 'array', + ['title_key' => 'title_key in es'], + 'es', + 'messages' + ); + + $listener = new ItemListTitleListener($translator); + + $element = $this->loadElement(''); + + $event = new BuildViewEvent( + $element, + new TemplateView('@LiberoPatterns/teaser-list.html.twig', [], ['lang' => 'es', 'list_title' => 'title_key']) + ); + $listener->onBuildView($event); + $view = $event->getView(); + + $this->assertInstanceOf(TemplateView::class, $view); + $this->assertSame(['title' => ['level' => 1, 'text' => 'title_key in es']], $view->getArguments()); + } +} From 9605f3eb20c7398d8c2cb54b82ff2188cb72ca4d Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Tue, 9 Apr 2019 15:55:58 +0100 Subject: [PATCH 46/46] Missing assertion --- .../tests/EventListener/BuildView/ItemListTitleListenerTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListTitleListenerTest.php b/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListTitleListenerTest.php index c285ab4..e011f8b 100644 --- a/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListTitleListenerTest.php +++ b/vendor-extra/LiberoPageBundle/tests/EventListener/BuildView/ItemListTitleListenerTest.php @@ -138,5 +138,6 @@ public function it_sets_the_title_argument() : void $this->assertInstanceOf(TemplateView::class, $view); $this->assertSame(['title' => ['level' => 1, 'text' => 'title_key in es']], $view->getArguments()); + $this->assertSame(['lang' => 'es', 'list_title' => 'title_key', 'level' => 2], $view->getContext()); } }